Post

2 followers Follow
0
Avatar

getItems() response format issue

Hi 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.

Louise Mattsson Answered

Please sign in to leave a comment.

27 comments

0
Avatar

The PHP client decodes the json for you automatically. You can do a var_dump() or a print_r() on the data to see the structure.

Andreas Haugstrup Pedersen 0 votes
0
Avatar

Did you do the print_r() on the return value? You can see the structure clearly there. It's just a matter of walking through the arrays to find what you want.

Andreas Haugstrup Pedersen 0 votes
0
Avatar

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.

Nick Worth 0 votes
0
Avatar

Thanks, that last post actually helped me figure it out. Would be great to have some more tutorials for us beginners. :)

Louise Mattsson 0 votes
0
Avatar

...And now I see what Nick ment with wanting to access the field by name instead of index. Is that possible to do somehow? I have the same problem, empty fields makes my indexing incorrect...

Louise Mattsson 0 votes
0
Avatar

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!

Nick Worth 0 votes
0
Avatar

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 version

Right 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 ).

Andreas Haugstrup Pedersen 0 votes
0
Avatar

Nice work with the PHP3 library Andreas! I actually started to build something similar (although a lot less feature rich) for a project I'm working on. Do you have any idea when this branch will be production ready?

Carl-Fredrik Herö 0 votes
0
Avatar

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 :)

Andreas Haugstrup Pedersen 0 votes
0
Avatar

Downloaded it and tried it but I get an error at:

require_once('podio-podio-php-bdbf7dd/PodioAPI.php');

the one I used before:

require_once('podio-php/PodioAPI.php');

works fine, but not the new one. Anything I need to change?

Louise Mattsson 0 votes
0
Avatar

Sorry.

Fatal error: Call to undefined method Podio::instance()

And I am using 

require_once('podio-podio-php-bdbf7dd/PodioAPI.php');

and then

$api = Podio::instance($client_id, $client_secret);

Louise Mattsson 0 votes
0
Avatar

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);

Andreas Haugstrup Pedersen 0 votes
0
Avatar

hmm yeah I've been trying to figure out how to use the new one but I think I need to wait for some guiding directions... Any information on when that is going to be released?

Louise Mattsson 0 votes
0
Avatar

It's either going to be "soon" or "when it's ready". I'm sorry I can't be more precise than that...

Andreas Haugstrup Pedersen 0 votes
0
Avatar

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.

Louise Mattsson 0 votes
0
Avatar

Hi Louise,

Yes, it's all released now. I'm happy you found the solution yourself. Proves to me that it was worth it to write those examples. :)

All the best,

Andreas 

Andreas Haugstrup Pedersen 0 votes
0
Avatar

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**_ 

Nick Worth 0 votes
0
Avatar

| 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**

Nick Worth 0 votes
0
Avatar

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.

Andreas Haugstrup Pedersen 0 votes
0
Avatar

I was able to upgrade and now those server errors are gone, thanks!

Now back to learning this new version.

Nick Worth 0 votes