getItems() response format issue
AnsweredHi there,
I want to do specific operations, calculations on some of the data in my Podio app and later on pass that calculated data to a javascript that will visualize it on a website
I am using the $items = $api->item->getItems() function with a filter to fetch 5 items in my Podio app. Seems to work fine. But then I want to start working with the data and I get stuck with errors.
What format is $items? I have tried to do a $newarray = json_decode($items, true) but that one doesn't work, it says that $items is not a string.
-
I printed out the array and I see the response in the sandbox perfectly fine, the problem is this structure seems too complicated to handle, especially when trying to pass the response back to JS for a AJAX response.
For example, here is part of my array print out:
Array
(
[0] => Array
(
[status] => active
[external_id] => title
[config] => Array
(
[description] => Donor's full name (used for interacting with other apps)
[settings] => Array
(
[size] => small
)[required] => 1
[mapping] =>
[label] => Title
[visible] => 1
[delta] => 0
)[field_id] => 17703162
[label] => Title
[values] => Array
(
[0] => Array
(
[value] => Nick Worth
))
[type] => text
)[1] => Array .... ...
And my function looks like this:
public function selectDonor(){
$this->PodioConnect();
$donor = $this->getDonor($_POST['id']); //$donor = $this->api->item->getBasic($id);
foreach($donor['fields'] as $i => $d){
$students[$i] = $d;
}
$response = json_encode(
array(
'success' => true,
'title' => $donor['fields'][0]['values'][0]['value'],
'phone' => $donor['fields'][3]['values'][0]['value'],
'email' => $donor['fields'][4]['values'][0]['value'], //need to grab label value
'students' => $students
)
);
// response output
header( "Content-Type: application/json" );
echo $response;
die(); // WP AJAX calls must die
}This works, I get the response I need EXCEPT when the donor has no phone, now the index (3) I hard set is now the email because the array does not keep that value since its empty. This is only a small sample of the issue. I need to be able to call what field I want by name.
Also, the $student array there is my attempt to get an app_reference field, but again it seems impossible to pull the data as needed.
-
I don't think this is the best way by any means because of the multiple calls, but looking through the PodioItem.php I found the getFieldValue(). But in a situation like mine instead of having one call with the getItems() I now had 4, plus a loop of more for each app reference item. Here's the code so you can see what I mean.
$title = $this->api->item->getFieldValue($id,DONOR_TITLE);
** $phone = $this->api->item->getFieldValue($id,DONOR_PHONE);**
** $email = $this->api->item->getFieldValue($id,DONOR_EMAIL);**
** $students = $this->api->item->getFieldValue($id,DONOR_STUDENTS);**
** foreach($students as $i => $student){**
$instance['title'] = $this->api->item->getFieldValue($student['value']['item_id'],STUDENT_TITLE);
$instance['grade'] = $this->api->item->getFieldValue($student['value']['item_id'],STUDENT_GRADE);
$teachers = $this->api->item->getFieldValue($student['value']['item_id'],STUDENT_TEACHER);
foreach($teachers as $teacher){
$instance['teacher'] = $this->api->item->getFieldValue($teacher['value']['item_id'],TEACHER_NAME);
}
$student_str .= $instance['title'][0]['value']."|".$instance['grade'][0]['value'] ['text']."|".$instance['teacher'][0]['value'].","; //I then split() this in JS handler so that I can display as needed
** }**
** $student_str = substr_replace($student_str,"",-1);**
** $response = json_encode( **
array( **
** 'success' => true,
'title' => $title[0]['value'],
'phone' => $phone[0]['value'],
'email' => $email[0]['value'],
'students' => $student_str
) **
** );Hope that helps!
-
getFieldValue will probably make your code run rather slow as you'll have a ton of API calls. It's better to use filterItems (which is like getItems, but with simpler syntax) and then create a helper function that can loop over the fields to find one by name.
As you've both discovered you can't rely on the array indexes as they will change when not all fields have values. The helper function will get around this.
I was going to keep this a secret a bit longer, but since it relates directly to your problems... For the past month I have been working on a replacement for the PHP API client specifically to make the things you want to do easier. Juggling those big arrays gets really annoying.
If you want a sneak peak you can check out the podio-php3 branch at https://github.com/podio/podio-php/tree/podio-php3
Beware that I've no documentation yet so you'll have to read the code to play with it. The main change is moving away from using a singleton instance for the main api object to using static methods for raw API calls (e.g. PodioItem::get() for getting a single item) and then instantiating specific objects for the different types of data that the API returns.
This will allow me to create nice instance methods for e.g. items to avoid having to do all the hard work manually each time. E.g. in this case it would be useful to just do:
$item = PodioItem::get(123);
$field = $item->get_field('teacher'); // Gets field with external_id 'teacher'
print $field->humanized_value(); // humanized_value would be a method that translates the raw value into a print-friendly versionRight now this new version is just as good as the old version. I still need to update all the documentation before I can release it. After that I will start adding convenience methods such as "get field by name". If you have any more wishes for convenience methods let me know (here or via email haugstrup@podio.com ).
-
You can start using it right now for production work. What's there is solid. I just need to add additional stuff (documentation, bring examples up to date and add the first round of instance methods) before I flip the switch and make it the official PHP library.
So you should feel completely safe checking out that branch and working with it. I promise I won't break it :)
-
As I said above the syntax is different in the upcoming version. This includes initialization and authentication which is done slightly different (going away from using a singleton to using static methods). You'll need to be able to read and understand the code -- otherwise you should stick with the old version until I get everything packaged up nicely. Hopefully, I'll get that done soon!
PS. init and authenticate like this (but you'll run into other errors afterwards since the syntax for making api calls also changed):
Podio::setup($client_id, $client_secret);
Podio::authenticate($type, $attributes); -
Hi again! The new version has been released now, right?
You examples on items are great, I am using this type of call to get a bunch of items at once:
$item_collection = PodioItem::filter(YOUR_APP_ID, array(
'filters' => array(5678 => array(1, 2, 3)),
));
I would like to loop through the collection of items and fetch certain field values from all the items. Like this:
foreach ($item_collection['items'] as $i=>$d)
{//Do something with $d, for now just var_dump($d['item_id']);
}
But I can't figure out how to write my code to access the item id and the fields in the proper way. Please give me some guidance here. :)
This is the error message I get: Cannot use object of type PodioItem as array. -
Andreas this looks like great stuff, I just started a project last week with the old way but now before it gets too developed I wanted to implement these changes. One issue I'm having getting started I think is because I'm trying to build my own reusable class. So at the moment I'm making this call:
<?php $events = $podio_api->getEvents(); //modules/events/lib/API-Podio.php ?>
Which that comes from this guy:
class PodioAPI{
public function __construct(){ }
private function PodioConnect($app){
$this->api = Podio::setup(CLIENT_ID, CLIENT_SECRET); **
** $app_id = EVENT_APP_ID;
$app_token = EVENT_APP_TOKEN;
try {
Podio::authenticate('app', array('app_id' => $app_id, 'app_token' => $app_token));
$_SERVER['access_token'] = $api->oauth->access_token; //I don't think these work anymore, your new documentation doesn't show them.
$_SERVER['refresh_token'] = $api->oauth->refresh_token;
}
catch (PodioError $e) {
print "There was an error. The API responded with the error type <b>{$e->body['error']}</b> and the message <b>{$e->body['error_description']}</b><br>";
}
return $this->api;
$api->debug = true;
}public function getEvents(){
** $this->PodioConnect('events');
* $events = PodioItem::filter(EVENT_APP_ID,
* array(
* 'limit' => 500 //Need to review this, 500 seems to be the max amount
* )
*** );*return $events;
}
**}
I was getting different server errors all which stemmed from not including things like the models:
PodioItem.php and then PodioSuperApp.php. Wondering shouldn't those already be included from the PodioAPI.php or something?
And now that I added PodioSuperApp I'm getting some server error like:
_PHP Parse error: syntax error, unexpected T_FUNCTION, expecting ')' in ..Classes/podio/models/PodioSuperApp.php on line 39**_ -
All files should be included automatically. Look at PodioAPI.php -- it's all require-statements so it'll die on you if it can't find the files: https://github.com/podio/podio-php/blob/master/PodioAPI.php
There's another PodioAPI.php file in the lib folder, but you shouldn't include that manually.Also, which version of PHP are you running?
-
| Apache version
| 2.2.23
|
| PHP version
|5.2.17
|
Looked closer at it and I think I was originally calling the other PodioAPI.php, and therefore no includes, now I have the right one but I'm getting a different error now.
../public_html/error_log: **
*#5 ../public_html/wp-load.php(29): require_once('/home5/brushpar...') *
*#6 ../public_html/wp-blog-header.php(12): require_once('/home5/brushpar...') *
**#7 ../public_html/index.php(17): require('/home5/brushpar...')
** #8 {main} thrown in../public_html/wp-content/plugins/DTMP/Classes/podio/PodioAPI.php on line 4** -
There's your problem. :)
Line 4 of PodioAPI.php will give you the answer: "Podio PHP library requires PHP 5.3 or higher."
I had to drop support for PHP version 5.2 and below for many many reasons (specifically late static bindings). There's no way to get things running unless you are on PHP 5.3 or above. You really really really should upgrade regardless. PHP 5.2 received it's last update in 2010 and is no longer supported by the PHP community. It's nothing but a security risk these days.
Please sign in to leave a comment.
Comments
27 comments