getItems() response format issue

Answered

Comments

27 comments

  • Andreas Haugstrup Pedersen

    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.

    0
    Comment actions Permalink
  • Louise Mattsson

    So if I would like to get the title of the first item in my $items, how would I do that?

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

    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.

    0
    Comment actions Permalink
  • Nick Worth

    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.

    0
    Comment actions Permalink
  • Louise Mattsson

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

    0
    Comment actions Permalink
  • Louise Mattsson

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

    0
    Comment actions Permalink
  • Nick Worth

    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!

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

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

    0
    Comment actions Permalink
  • Carl-Fredrik Herö

    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?

    0
    Comment actions Permalink
  • Louise Mattsson

    <3

    Looking forward to it! 

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

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

    0
    Comment actions Permalink
  • Louise Mattsson

    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?

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

    Hard to tell since you are keeping the error message to yourself :)

    0
    Comment actions Permalink
  • Louise Mattsson

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

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

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

    0
    Comment actions Permalink
  • Louise Mattsson

    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?

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

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

    0
    Comment actions Permalink
  • Louise Mattsson

    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.

    0
    Comment actions Permalink
  • Louise Mattsson

    Mohahaha, I got it!

    $d->item_id;

    It wasn't harder than that! :) 

    0
    Comment actions Permalink
  • Louise Mattsson

    I just had to read your examples a little bit more careful... ;)

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

    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 

    0
    Comment actions Permalink
  • Nick Worth

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

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

    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?

    0
    Comment actions Permalink
  • Nick Worth

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

    0
    Comment actions Permalink
  • Nick Worth

    Which I now see I need 5.3 ... hmmmmmm I suppose I could ask host to upgrade?

    0
    Comment actions Permalink
  • Andreas Haugstrup Pedersen

    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.

    0
    Comment actions Permalink
  • Nick Worth

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

    Now back to learning this new version.

    0
    Comment actions Permalink

Please sign in to leave a comment.

Powered by Zendesk