phpunit data provider - php

I am working on PHPunit tests and so far everything is great. There is one issue, however, and it is with the following setup. Ideally I'd like to select the next value in the sequence (postgreSQL) and pass that into the function so I can validate it against the array returned from my class being tested (new row in database).
The issue is that before the array is returned from the data provider (if I echo it) it is the correct value, but during the test it comes through as blank. Is there a particular series of steps I'm missing in here in terms of what I expect or must I do this a different way?
/**
* #dataProvider testSignupProvider
*/
public function testSignup($a, $b, $c)
{
...stuff is done with $a,$b,$c
}
public function testSignupProvider()
{
$uid = fetchOne(X("SELECT currval('users_id_seq')"));
return array(
array(false, array(), $error4),
array(
'email'=>'stack#overflow.com',
'password'=>'youaintgonnagetit',
$error3
),
array(
array('id'=>$uid,'email'=>'PHPUNIT#gmail.com','username'=>'Guest'),
array('email'=>'PHPUNIT#gmail.com','password'=>'youaintgonnagetit'),
null
)
);
}
Output:
Array
(
- [id] =>
+ [id] => 2
[email] => PHPUNIT#gmail.com
[username] => Guest
)

I've gotten around this by assigning the 'id' array element to '#id' and in the function test I pull the current id in the sequence at that time.
Still will accept an answer to anyone who can tell me why this behavior occurs but hopefully this will help anyone else with this issue.

Related

PHP RETS Open Houses Propertys

Hello i want to find open houses property using PHP RETS script. i have did below code in which i am able to find Open Houses Property details like MLS_Number,From-date,To time but i am not able to get based on MLS_Number find property other details like address,price,room No and other details. what i have tried so far below is code.
$retsFilters['IS_ACTIVE '] = true;
$retsQuery = '';
foreach ($retsFilters as $key => $value) $retsQuery .= ',('.$key.'='.$value.')';
$retsQuery = trim($retsQuery, ',');
$result = $rets->SearchQuery("openhouse", "OpenHouse",$retsQuery,array('Format' => QUERY_FORMAT));
from above code returns only
Array
(
[AdvertOpenHouse] => 1
[Agent_MUI] => 2871
[Description] =>
[FromDate] => 2016-09-01T00:00:00.000
[FromTime] => 1400
[InputDate] =>
[IS_ACTIVE] => 1
[IsDeleted] => 0
[Listing_MUI] => 9985949
[listing_type] => RE
[matrix_unique_ID] => 10268565
[mls_number] => 548766
[ModificationTimestamp] => 2016-01-08T13:31:23.390
[Open_House_Refreshments] =>
[ToTime] => 1600
)
but i want also more property's details like address,streetName,city,price and other details.
this is the my login url http://rets.saskmls.ca/rets/login.ashx
if any one have idea please help thanks in advance.
Well the Openhouse Resource and underlying classes would not contain this kind of information. There should be a Property Resource with many different kinds of property classes within (Residential, Commercial, Land, etc...)
You need to examine the metadata from the RETS server, it will contain XML that describes all the available Resources, Classes and fields.
Note the signature of the SearchQuery method:
SearchQuery ( string $resource, string $class, string $query [, array $options] )
Your resulting query would look something like this:
SearchQuery("Property", "RES", "(Status=|A)")
I am using Paragon as a MLS back-end provider. When I get an "OpenHouse" resource, there's a field called
L_DisplayId
which is present in "Property" resources.
This field makes a relationship between the two resources.
Once you know L_DisplayId value from an open house, you can search for a property sending L_DisplayId as a search parameter.
Hope that can help you.

Laravel 5.2 - adding to existing session array overwrites existing session

I am attempting to store basket data in a session in Laravel 5 via AJAX but each time I try and push an item to the array stored as the value to 'basket', the existing 'basket' array is overwritten.
Below is my controller method:
public function add(Request $request)
{
$success = false;
if ($request->ajax()) {
$ticket = Ticket::find((int) $request->get('ticket_id'));
if ($ticket) {
if (!$request->session()->has('basket')) {
$request->session()->put('basket', []);
}
$item = [
'attraction.name' => $ticket->attraction->name,
'ticket.quantity' => $request->get('quantity'),
'ticket.price' => $ticket->price,
];
$request->session()->push('basket', [$ticket->id => $item]);
$success = true;
}
}
return response()->json(['success' => $success]);
}
An item is set in the basket session array on the first instance, but I am expecting it to add to this array rather than overwrite when I post more item data over to this method.
The end result I'm looking to achieve is this:
Array
(
[basket] => Array
(
[123] => Array
(
[attraction.name] => Attraction 1
[ticket.quantity] => 2
[ticket.price] => 14.5
)
[456] => Array
(
[attraction.name] => Attraction 2
[ticket.quantity] => 3
[ticket.price] => 12
)
)
)
I've tried using the Session facade equivalent methods, but to no avail :(
Any help would be greatly appreciated. Thanks :)
I had tried array_merge() but again my session was being overwritten. So, after putting my debug hat on yet again, I've found the reason why it was happening.
Session data was not persisting after each request. As my session wasn't being remembered, !$request->session()->has('basket') was always evaluating to true therefore my basket session was being set back to an empty array each time.
I needed to return my request as JSON using the below line in order for my session data to persist. Maybe this is because I have dataType: 'json' as a property in my AJAX call?
return response()->json($request);
I also took your advice and grabbed the basket session array, pushed new data to it and put back into session.
Sorted! Thank you both for your help :)
I experienced a similar issue and discovered that after adding values to the session you need to call
session()->save();

PHP 5.3.2 alternative to using $this inside an anonymous function?

I am using Laravel 4 and PHP to build a new application. It works fine on my dev server running PHP 5.4.x however my boss insist that it has to run version 5.3.2
I have spent the whole day fixing everything to work with 5.3.2 and almost have everything, so I thought, until I ran into an issue with the code below.
My problems start at this line...
DB::transaction(function($clock_in_webcam_image) use ($clock_in_webcam_image)
I believe this type of code might not work with this version of PHP? If that is the case, what are my options to run this same code or have it doing the same action?
Would appreciate any help with this. Very unfortunate that my boss told me straight out that no he will not allow us to update to a newer PHP so I am stuck in a hard spot right now
// Create a new time card record when a User Clocks In
public function createTimeCard($clock_in_webcam_image) {
// Create both Timecard and timecard record tables in a Transaction
DB::transaction(
function ($clock_in_webcam_image) use ($clock_in_webcam_image) {
$timeCard = DB::table('timeclock_timecard')->insertGetId(
array(
'user_id' => $this->user->user_id,
'clock_in_datetime' => $this->dateTime->format($this->dateFormat),
'clock_in_timestamp' => $this->dateTime->getTimestamp(),
'clock_in_webcam_image' => $clock_in_webcam_image
)
);
$timeCardPunchEntry = DB::table('timeclock_punch_entry')
->insertGetId(
array(
'timecard_id' => $timeCard,
'user_id' => $this->user->user_id,
'created_at_datetime' => $this->dateTime->format($this->dateFormat),
'created_at_timestamp' => $this->dateTime->getTimestamp(),
'clock_type' => 'clock_in',
'webcam_image' => $clock_in_webcam_image
)
);
return $timeCard;
}
);
}
UPDATE
In response to bansi's comment...is this what you mean to do...
DB::transaction(function() use($myModel){
$myModel->updateTable1();
$myModel->updateTable2();
})
Before PHP 5.4.0, you could not use $this inside an anonymous function. There is a simple workaround though where you can use the use construct to pass variables into the functions scope. Also, you are using the use construct incorrectly as $clock_in_webcam_image is not defined in the parent scope.
$user = $this->user;
$dateTime = $this->dateTime;
DB::transaction(function($clock_in_webcam_image) use ($user, $dateTime) {
// snip
array(
'user_id' => $user->user_id,
'clock_in_datetime' => $dateTime->format($this->dateFormat),
'clock_in_timestamp' => $dateTime->getTimestamp(),
'clock_in_webcam_image' => $clock_in_webcam_image
)
// snip
});
try this. please check you don't have another insertTimecard defined.
// Create a new time card record when a User Clocks In
public function createTimeCard($clock_in_webcam_image)
{
// Create both Timecard and timecard record tables in a Transaction
DB::transaction($this->insertTimecard($clock_in_webcam_image));
}
private function insertTimecard($clock_in_webcam_image)
{
$timeCard = DB::table('timeclock_timecard')->insertGetId(
array(
'user_id' => $this->user->user_id,
'clock_in_datetime' => $this->dateTime->format($this->dateFormat),
'clock_in_timestamp' => $this->dateTime->getTimestamp(),
'clock_in_webcam_image' => $clock_in_webcam_image
)
);
$timeCardPunchEntry = DB::table('timeclock_punch_entry')->insertGetId(
array(
'timecard_id' => $timeCard,
'user_id' => $this->user->user_id,
'created_at_datetime' => $this->dateTime->format($this->dateFormat),
'created_at_timestamp' => $this->dateTime->getTimestamp(),
'clock_type' => 'clock_in',
'webcam_image' => $clock_in_webcam_image
)
);
return $timeCard;
}

SQL JOINs with CakePHP

I have an images table and a servers table. images has a server_id field which is a foreign key to the id field in the servers table. The servers table also has a field called name, which is what I want to retrieve.
Here's my controller action code:
$images = $this->Image->find('all', array(
'conditions' => array('Image.user_id' => $this->Auth->user('id')),
'order' => array('Image.uploaded DESC')
));
$this->set('images', $images);
It gets data like this:
Array
(
[0] => Array
(
[Image] => Array
(
[id] => 103
[orig_name] => Untitled-5.jpg
[hash] => MnfWKk
[filename] => MnfWKk.jpg
[uploaded] => 2012-07-12 00:09:08
[views] => 0
[album_id] =>
[user_id] => 15
[server_id] => 1
)
)
)
Instead of server_id, I want to get the name field from the servers table. How can I adapt my find() method to get this? I know it's an SQL join, but I have no idea how to tell Cake to do one in order to get the servers name.
Thanks.
TLDR:
Set up the correct CakePHP associations, and use CakePHP's Containable. (with recursive -1).
Longer Description:
It's best practice to keep your find code in the model itself, so that's what I'll show, but feel free (if you must) to move it back into the controller.
Doing it this way allows you to call the same getImages() function from any controller, and just pass different parameters based on what you want returned. The benefit to coding like this is, you always know if you're looking for code related to queries/database, that you should be looking in the model. It's VERY beneficial when the next person who looks at your code doesn't have to go searching.
Because of the association set up between Image and Server, you can then "contain" the Server info when you query images. But - you can't use "contain" until you specify that you want your model to $actAs = array('Containable');. [ CakePHP Book: Containable ]
Lastly, in your AppModel, it's good practice to set $recursive = -1;. That makes it default to -1 for all models. If for some reason you're against doing that, just make sure to set recursive to -1 any time you use containable. And - once you learn to use containable, you'll never look back - it's awesome. There are a lot more things you can
Code:
//AppModel *******
//...
$recursive = -1;
//...
//Images controller *******
//...
public function whatever() {
$opts = array();
$opts['user'] = $this->Auth->user('id');
$images = $this->Image->getImages($opts);
$this->set(compact('images'));
}
//...
//Image model *******
//...
public $actsAs = array('Containable');
public belongsTo = array('Server');
public function getImages($opts = array()) {
$params = array('condtions'=>array());
//specific user
if(!empty($opts['user'])) {
array_push($params['conditions'], array('Image.user_id'=>$opts['user']);
}
//order
$params['order'] = 'Image.uploaded DESC';
if(!empty($opts['order'])) {
$params['opts'] = $opts['order'];
}
//contain
$params['contain'] = array('Server');
//returns the data to the controller
return $this->find('all', $params);
}
A few other notes
You should also set the association in your Server model.
The code example I gave is written fairly verbosely (is that a word?). Feel free to condense as you see fit
You can also extend the model's getImages() method to accept a lot more parameters like find, limit...etc. Customize this all you want - it's not THE way to do it - just similar to what I usually use.
Per your question, if you only need one field, you can specify in the "contain" what fields you want - see the book for details.
It might seem confusing now, but it's SOO worth learning how to do this stuff right - it will make your life easier.
Cake have a lot of model relationships to achieve this. Check out this page, I think you'll be using the belongsTo relationship
Easy and alternate way for begginers
$images = $this->Image->find('all', array(
'conditions' => array('Image.user_id' => $this->Auth->user('id')),
'joins' => array(
array(
'table' => 'servers',
'alias' => 'Server',
'type' => 'inner', //join of your choice left, right, or inner
'foreignKey' => true,
'conditions' => array('Image.server_id=Server.id')
),
),
'order' => array('Image.uploaded DESC')
));
This is very good in performance

How can I reach an element in an Object?

I'm trying to reach an element in an object array. But I couldn't succeed.
Let's think this as an object called $result
How can I reach maskedNumber?
Braintree_Result_Successful Object
(
[success] => 1
[_returnObjectName:private] => customer
[customer] => Braintree_Customer Object
(
[_attributes:protected] => Array
(
[creditCards] => Array
(
[0] => Braintree_CreditCard Object
(
[_attributes] => Array
(
[maskedNumber] => ***********5897
Since the _attributes property of Braintree_Customer is protected you will need to define an accessor method. The other _attributes property of Braintree_CreditCard also looks like it's supposed to be protected, so I've assumed an identical accessor should exist:
$cards = $object->customer->getAttribute('creditCards');
$number = $cards[0]->getAttribute('maskedNumber');
Accessor method to be placed in both classes:
function getAttribute($attribute) {
return $this->_attributes[$attribute];
}
Edit:
Just to improve upon my original answer a little, I would put some decent error checking in an actual accessor method.
function getAttribute($attribute) {
if (isset($this->_attributes[$attribute])) {
return $this->_attributes[$attribute];
}
return NULL;
}
You could also consider using the magic methods __get() and __set() to act as getters and setters.
I solved the problem by asking braintreepayments. They said that I could retrieve this data after I add user to braintree. But my solution is if I really needed this at the very beginning would be to take it with REGEX. For people who are looking for a great online payment company I suggest you to go with braintree
I know this is old, but this might help some.
Braintree has methods for returning the protected information that's returned from functions like Braintree_Customer::create();
$result = Braintree_Customer::create(array(
'firstName' => $_POST['first_name'],
'lastName' => $_POST['last_name'],
'email' => $_POST['email'],
'creditCard' => array(
'cardholderName' => $_POST['cardholder_name'],
'number' => $_POST['number'],
'expirationMonth' => $_POST['month'],
'expirationYear' => $_POST['year'],
'cvv' => $_POST['cvv'],
'billingAddress' => array(
'postalCode' => $_POST['postal_code']
)
)
));
var_dump($result->customer->__get('id'));
var_dump($result->customer->__get('creditCards'));
The _attributes of customer are protected, but the get function returns them.
This method does not require re-requesting data from Braintree.
try
$Result->customer->_attributes['creditCards'][0]->_attributes['maskedNumber']
with $result->customer you should get the *Braintree_Customer* Object and then in that object you should have methods to retrieve the cards as those methods are protected and cannot be accessed directly. Something like
$customer = $result->customer;
foreach($customer->getCreditCards() as $card)
{
echo $card->getMaskedNumber(); // You will need to create that method too
}
Example of getCreditCards method:
Class Braintree_Customer
{
protected $creditCards;
function getCreditCards()
{
return $creditCards;
}
...
}

Categories