How can I reach an element in an Object? - php

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;
}
...
}

Related

PHP create object from class with public arrays

I have a class for configuration on my script and I implement the config. I then want to use the options as an object reference like the following, but not sure how to get it all the way to the final object field and also how to make it recognize sub arrays too
class Configuration {
public $cookies = array(
"cookie_prefix" => "site_",
"site_settings" => array(
"domain" => "somesite.com",
"https_only" => TRUE
),
"another_item" => "and some data too"
);
}
$config = new Configuration();
echo $config->cookies->cookie_prefix;
echo $config->cookies->site_settings->domain;
Right now it works if I do the following
echo $config->cookies['cookie_prefix'];
echo $config->cookies['site_settings']['domain'];
But I want it to be an object all the way down. Can't wrap my brain around this one for some reason?
I know this is easily done - I am just missing the way how...
I just passed the items in the __construct as json and its working the way I wanted now, duh.
public $cookies = array(
"cookie_prefix" => "site_",
"site_settings" => array(
"domain" => "somesite.com",
"https_only" => TRUE
),
"another_item" => "and some data too"
);
public function __construct() {
$this->cookies = json_decode(json_encode($this->cookies));
}

PHP Array Object to Serialize

I am trying to convert a PHP array object to an JSON.Following is the PHP Array Object;
Array
(
[0] => Project\Man\Model\Branch Object
(
[id:protected] => 123456
[name:protected] => Parent Branch
[type:protected] => services
)
)
I tried Serializing it but its not in a friendly readable object.
I tried the following:
json_encode
serialize
a:1:{i:0;O:23:"Project\Man\Model\Branch ":3:{s:5:"*id";s:36:"123456";s:7:"*name";s:20:"Parent Branch";s:7:"*type";s:8:"services";}}[{}]
I am trying for some solution where i can get JSON. any help.
If you just want json, you should only use json_encode(), not serialize().
Since your object properties are set as protected, they will however not be available when you encode the object whitout some additional help.
This is where the interface JsonSerializable comes into play.
You need to make sure that the object you want to encode implements the interface. Then you need to add a jsonSerialize() method to the class.
class Branch implements \JsonSerializable
{
protected $id;
protected $name;
protected $type;
// ... your class code
public function jsonSerialize()
{
// Return what you want to be encoded
return [
'id' => $this->id,
'name' => $this->name,
'type' => $this->type,
];
}
}
If you now pass this object through json_encode() and you'll get a json string with what our new method returns.

CSV Import in SilverStripe Duplicates and RelationCallbacks

I need to understand the code below, specially how exactly $duplicateChecks and $relationCallbacks work but there is little explanation on the official documentation. Can somebody explain how these work or suggest some other documentation I can look at?
class PlayerCsvBulkLoader extends CsvBulkLoader {
public $columnMap = array(
'Number' => 'PlayerNumber',
'Name' => '->importFirstAndLastName',
'Birthday' => 'Birthday',
'Team' => 'Team.Title',
);
public $duplicateChecks = array(
'Number' => 'PlayerNumber'
);
public $relationCallbacks = array(
'Team.Title' => array(
'relationname' => 'Team',
'callback' => 'getTeamByTitle'
)
);
public static function importFirstAndLastName(&$obj, $val, $record) {
$parts = explode(' ', $val);
if(count($parts) != 2) return false;
$obj->FirstName = $parts[0];
$obj->LastName = $parts[1];
}
public static function getTeamByTitle(&$obj, $val, $record) {
return FootballTeam::get()->filter('Title', $val)->First();
}
}
$duplicateChecks is used by findExistingObject function in the CsvBulkLoader class. It is iterated over to find any object that has a column with the specified value. In that example, it checks the "PlayerNumber" column.
It can also be passed a callback like so:
public $duplicateCheck = array(
'Number' => array(
'callback' => 'checkPlayerNumberFunction'
)
);
The callback specified needs to either exist on an instance of the class specified on the property objectClass or on the CsvBulkLoader itself (which would happen if you extended it). These callbacks are used to do more complex duplicate lookups and return an existing object (if any) found.
$relationCallbacks on the other hand is used by the main processRecord function. The callback works in the same way as the $duplicateCheck callback, it needs to either exist on an instance of the class specified on the proeprty objectClass or on the CsvBulkLoader. These callbacks can return an object that will be related back to a specific object record (new or existing) as a has_one.
There is a little more to it than that though the best way to learn is by a bit of experimentation and jumping through the code of the class itself. I have linked to the various functions etc in my answer.

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 to get the property of Object in Symfony

Hey How Can i get any specific property from the whole object.
I have this query
$portfolios = $this->getDoctrine()
->getRepository('MunichInnovationGroupBundle:PmPortfolios')
->findBy(array('user' => '1'));
foreach ($portfolios as $portfolio){
if($portfolio.isDefault == true){
$default_portfolio = $portfolio;
}
echo $portfolio.name;
}
The complete object looks like this
MunichInnovationGroup\Bundle\Entity\PmPortfolios Object
(
[id:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] => 991654b4-aa73-11e1-bdce-4a7b883b8e17
[portfolioName:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] => Umair Portfolio 1
[description:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] => Thsi is the description for Umairs portfolio 1
[permalink:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] => premalink
[sharingCode:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] => asdbnvg123dg
[shared:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] =>
[sharedPortfolioCalls:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] =>
[isDefault:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] => 1
[user:MunichInnovationGroup\Bundle\Entity\PmPortfolios:private] => Proxies\MunichInnovationGroupBundleEntityUmUsersProxy Object
How can I get the isDefault value ?
Thanks in advance
If you have your entity set up correctly with all generated set/get methods, and isDefault is a private property (as it seems so from the var_dump) you can simply use
if($portfolio->getIsDefault())
For better method naming I would write a method in the entity:
public function isDefault() {
return $this->isDefault;
}
and then use
if($portfolio->isDefault())

Categories