Parsing cybersourse Response in PHP - cybersource

I Need to parse the below array and retrieve values;status,id.
Below is the PHP Array
Array ( [0] => CyberSource\Model\PtsV2PaymentsPost201Response Object ( [container:protected] =>
Array ( [links] => CyberSource\Model\PtsV2PaymentsPost201ResponseLinks Object ( [container:protected] =>
Array ( [self] => CyberSource\Model\PtsV2PaymentsPost201ResponseLinksSelf
Object ( [container:protected] => Array ( [href] => /pts/v2/payments/621258854395 [method] => GET ) )
[reversal] => [capture] => [customer] => [paymentInstrument] => [shippingAddress] => [instrumentIdentifier] => ) )
[id] => 621258854395
[submitTimeUtc] => 2021-05-17T13:40:55Z
[status] => AUTHORIZED
[reconciliationId] => 621258854395
[errorInformation] =>...............
Below is my php code
$parseApiResponse = new CyberSource\Model\PtsV2PaymentsPost201Response($apiResponse);
print_r("Status"." ".$parseApiResponse->getStatus());
Please assist in resolving this.
Want to do a similar thing as I am able to do in java as below
String status = result.getStatus();

I hope this helps someone. It took me a while to figure this out. The original poster was so close. It's just...
print_r("Status"." ".$apiResponse[0]->getStatus());
No need to instantiate a new "PtsV2PaymentsPost201Response()". The response element ([0]) has already done that when you call, "createPayment()", etc.
lib/Model/PtsV2PaymentsPost201Response.php lists all the available getters. getId(), getStatus(), getLinks(),etc.

$parseApiResponse = new CyberSource\Model\PtsV2PaymentsPost201Response($apiResponse);
$result = \GuzzleHttp\json_decode( $parseApiResponse[0] , true );
return = $result['links'];

Related

Laravel cast json to array

The client attribute is a json filed in the database, which I caste as array in my model. However by retuning the Model to an array, the client attribute remains as json string:
$provider = TokenCacheProvider::all([
'name', 'auth_url', 'token_url', 'auth_endpoint', 'client'
])
->keyBy('name')
->toArray();
output:
Array
(
[name] => azure_ad
[auth_url] => /oauth2/v2.0/authorize
[token_url] => /oauth2/v2.0/token
[auth_endpoint] => https://login.microsoftonline.com/
[client] => {"tenant":"some value","client_id":"some value","client_secret":"some value"}
)
I would expect and output like this:
Array
(
[name] => azure_ad
[auth_url] => /oauth2/v2.0/authorize
[token_url] => /oauth2/v2.0/token
[auth_endpoint] => https://login.microsoftonline.com/
[client] => Array
(
[tenant] => 'some value'
[client_id] => 'some value'
[client_secret] => 'some value'
[scope] => 'some value'
)
)
My Model has the corresponding $casts:
protected $casts = [
'client' => 'array',
];
Edit
This comes a little bit closer to what I need, but it returns only the clients attribute 😵‍💫
$provider = TokenCacheProvider::all([
'name', 'auth_url', 'token_url', 'auth_endpoint', 'client'
])
->keyBy('name')
->map(function ($item) {
return json_decode($item->client);
})
->toArray();
Resolved 😎
$provider = TokenCacheProvider::all([
'name', 'auth_url', 'token_url', 'auth_endpoint', 'client'
])
->keyBy('name')
->map(function ($item) {
return collect([
'auth_url' =>$item->auth_url,
'token_url' =>$item->token_url,
'auth_endpoint' =>$item->auth_endpoint,
'client' =>json_decode($item->client,true)
]);
})
->toArray();
Not sure if this is the most beautiful solution but it does exactly what I want.
Output:
Array
(
[auth_url] => /oauth2/v2.0/authorize
[token_url] => /oauth2/v2.0/token
[auth_endpoint] => https://login.microsoftonline.com/
[client] => Array
(
[tenant] => some values
[client_id] => some values
[client_secret] => some values
[scope] => https://graph.microsoft.com/.default
)
)
Feedback and enhancements are highly welcome!
Cheers

How push into array without creating numbered indexes in a multidimensional array in PHP?

I want to use array_push() to add to an array, but it always adds a [0] => Array level. How can I prevent that, or take that out afterwards?
For example, I'm trying to push into the '[addOns] => Array' with this:
$addOnid='gcl1';
$addOnid_arr=array('inheritedFromId' => $addOnid);
array_push($result['addOns'], $addOnid_arr);
The array_push is resulting in this:
Array
(
[addOns] => Array
(
[inheritedFromId] => gcl2
)
[0] => Array
(
[inheritedFromId] => gcl1
)
)
And want to make it:
Array
(
[addOns] => Array
(
[inheritedFromId] => gcl2
)
(
[inheritedFromId] => gcl1
)
)
...basically just getting rid of all the [0] => Array, moving all the subarrays up a level.
Maybe I haven't been using the right queries, but I haven't been able to find out how to do this.
Simple just use this instead:
$addOnid = 'gcl1';
$addOnid_arr['addOns'][] = ['inheritedFromId' => $addOnid];

CakePHP deep (multiple related models) validation?

I have a model structure that is:
Organization belongsTo Address belongsTo CountryCode
So, Organization has foreign keys: mailing_address_id and physical_address_id
Address has foreign key: country_code_id
In the Organization model, relationship is defined as:
public $belongsTo = array(
'MailingAddress' => array('className'=>'Address', 'foreignKey'=>'mailing_address_id')
, 'PhysicalAddress' => array('className'=>'Address', 'foreignKey'=>'physical_address_id')
);
This appears to be working great - validation is functioning properly, etc.
In the Address model, relationship is defined as:
public $belongsTo = array(
'CountryCode' => array('className'=>'CountryCode', 'foreignKey'=>'country_code_id')
);
In my OrganizationsController, in a function to create a new organization, I'm testing validation using this code:
if($this->Organization->saveAll(
$data, array('validate'=>'only')
)) {
// Validates
$this->DBG('Org validated.');
} else {
// does not validate
$this->DBG('Org NOT NOT NOT validated.'.print_r($this->Organization->invalidFields(),true));
}
The $data array looks like this going into validation.
2015-06-08 21:03:38 Debug: Array
(
[Organization] => Array
(
[name] => Test Organization
)
[MailingAddress] => Array
(
[line1] => 100 Main Street
[line2] =>
[city] => Houston
[state] => TX
[postal_code] => 77002
[CountryCode] => Array
(
[name] => United St
)
)
[PhysicalAddress] => Array
(
[line1] => 100 Main Street
[line2] =>
[city] => Houston
[state] => TX
[postal_code] => 77002
[CountryCode] => Array
(
[name] => United St
)
)
)
The country code SHOULD NOT validate with the rules I have set in the CountryCode model:
public $validate = array(
'name' => array(
'nonemptyRule' => array(
'rule' => 'notEmpty'
,'required' => 'create'
,'message' => 'Must be provided.'
)
,'dupeRule' => array(
'rule' => array('isUnique', array('name','code'), false)
,'message' => 'Duplicate'
)
)
,'code' => array(
'rule' => 'notEmpty'
,'required' => 'create'
,'message' => 'Must be provided.'
)
);
However, validation PASSES on Organization->saveAll.
Also, if I attempt to access the CountryCode model from the OrganizationController, it's not loaded.
As in:
$this->Organization->MailingAddress->CountryCode->invalidate('name','Invalid!');
In that case, I get an error that CountryCode is null.
Any ideas why CountryCode wouldn't be validating or loaded?
Is validation supposed to work two steps away?
It turns out, there IS a deep option when validating (and saving). It's documented here with the saveAll options:
http://book.cakephp.org/2.0/en/models/saving-your-data.html
So, the validation block in the question works perfectly well if you include the deep option like so:
if($this->Organization->saveAll(
$data, array('validate'=>'only', 'deep'=>true)
)) {
// Validates
$this->DBG('Org validated.');
} else {
// does not validate
$this->DBG('Org NOT NOT NOT validated.'.print_r($this->Organization->invalidFields(),true));
}

WP_List_Table not properly handling returned data?

So following the WPEngineer guide on WP_List_Table (excellent guide by the way), I managed to put together a basic table for the backend of a plugin I'm working on. Using an 'example' array, it works great. Problem I'm running into is that I can't figure out for the life of me how to replace that sample data with actual data! Adding the query where I thought it was supposed to be results in the query variable having the correct data, but the table still returns no contents. The referenced pastebin is what I have so far... any thoughts?
http://pastebin.com/f0DCacfF
CORRECTION: It IS pulling the data (if I manually add a row to the database, the table count gets updated), but it's displaying a blank table.
NOTE: It seems that the sample data is an array, whereas $wpdb->get_results is returning as a stdClass Object.
Sample data setup:
var $api_key_list = array(
array( 'id' => 1,'userid' => 'Quarter Share', 'key' => 'Nathan Lowell', 'desc' => '978-0982514542' )
);
Sample data return:
Array ( [0] => Array ( [id] => 1 [userid] => 1 [key] => 098f6bcd4621d373cade4e832627b4f6 [desc] => Test API key ) )
Query setup:
$api_key_list_query = "SELECT * from $wpapi_db_table_name";
$this->api_key_list = $wpdb->get_results($api_key_list_query);
Query return:
Array ( [0] => stdClass Object ( [id] => 1 [userid] => 1 [key] => 098f6bcd4621d373cade4e832627b4f6 [desc] => Test API key ) [1] => stdClass Object ( [id] => 2 [userid] => 1 [key] => 098f6bcd4621d373cade4e832627b4f6 [desc] => Test API key 2 ) )
Adding the following solved my problem.
$this->api_key_list = array();
$i = 0;
foreach($api_key_list_return as $obj) {
foreach($obj as $key => $val) {
$this->api_key_list[$i][$key] = $val;
}
$i++;
}

Why are Symfony2 validation propertyPath valus in square brackets?

I am validating some values:
$collectionConstraint = new Collection(array(
'email' => array(
new NotBlank(),
new Email(),
),
'password' => array(
new NotBlank(),
new MinLength(array('limit' => 6)),
new MaxLength(array('limit' => 25)),
),
));
$data = array('email' => $this->getRequest()->get('email'), 'password' => $this->getRequest()->get('password'));
$errors = $this->get('validator')->validateValue($data, $collectionConstraint);
But for some reason the fields (propertyPath) are stored with square brackets - I'd like to understand why Sf does that. I have to manually remove all the brackets which seems absurd so I think I am missing some functionality somewhere.
Dump of $errors:
Symfony\Component\Validator\ConstraintViolationList Object
(
[violations:protected] => Array
(
[0] => Symfony\Component\Validator\ConstraintViolation Object
(
[messageTemplate:protected] => This value should not be blank
[messageParameters:protected] => Array
(
)
[root:protected] => Array
(
[email] =>
[password] =>
)
[propertyPath:protected] => [email]
[invalidValue:protected] =>
)
[1] => Symfony\Component\Validator\ConstraintViolation Object
(
[messageTemplate:protected] => This value should not be blank
[messageParameters:protected] => Array
(
)
[root:protected] => Array
(
[email] =>
[password] =>
)
[propertyPath:protected] => [password]
[invalidValue:protected] =>
)
)
)
Even the toString function is useless.
"[email]: This value should not be blank","[password]: This value should not be blank"
Property paths can map either to properties or to indices. Consider a class OptionBag which implements \ArrayAccess and a method getSize().
The property path size refers to $optionBag->getSize()
The property path [size] refers to $optionBag['size']
In your case, you validate an array. Since array elements are also accessed by index, the resulting property path in the violation contains squared brackets.
Update:
You don't have to manually remove the squared brackets. You can use Symfony's PropertyAccess component to map errors to an array with the same structure as your data, for example:
$collectionConstraint = new Collection(array(
'email' => array(
new NotBlank(),
new Email(),
),
'password' => array(
new NotBlank(),
new MinLength(array('limit' => 6)),
new MaxLength(array('limit' => 25)),
),
));
$data = array(
'email' => $this->getRequest()->get('email'),
'password' => $this->getRequest()->get('password')
);
$violations = $this->get('validator')->validateValue($data, $collectionConstraint);
$errors = array();
$accessor = $this->get('property_accessor');
foreach ($violations as $violation) {
$accessor->setValue($errors, $violation->getPropertyPath(), $violation->getMessage());
}
=> array(
'email' => 'This value should not be blank.',
'password' => 'This value should have 6 characters or more.',
)
This also works with multi-dimensional data arrays. There the property paths will be something like [author][name]. The PropertyAccessor will insert the error messages in the same location in the $errors array, i.e. $errors['author']['name'] = 'Message'.
PropertyAccessor's setValue is no real help because it cannot handle multiple violations for a single field. For instance, a field might be shorter than a constraint length and also contain illegal characters. For this, we would have two error messages.
I had to create my own code:
$messages = [];
foreach ($violations as $violation) {
$field = substr($violation->getPropertyPath(), 1, -1);
$messages[] = [$field => $violation->getMessage()];
}
$output = [
'name' => array_unique(array_column($messages, 'name')),
'email' => array_unique(array_column($messages, 'email')),
];
return $output;
We manually strip the [] characters from the property path and create an
array of arrays of fields and corresponding messages. Later we transform the
array to group the messages by fields.
$session = $request->getSession();
$session->getFlashBag()->setAll($messages);
In the controller, we add the messages to the flash bag.

Resources