Search code examples
phpjqueryajaxpaginationinstagram-api

Load more instead of going to next page using pagination/API


I am working on a project to display select Instagram photos in an album by hashtag, since the Instagram API limits 35 images per API call I figured out I either had to use AJAX (which I am very poor at) or a mixture of PHP and AJAX. I decided on the latter because I didn't want my access token and user ID made available in the code on my gallery.

    <?PHP
function jsongram($next=null){
    $userid = "xxx";
    $accessToken = "xxx";
    $url = ("https://api.instagram.com/v1/users/{$userid}/media/recent/?access_token={$accessToken}");

    if($url !== null) {
        $url .= '&max_id=' . $next;
    }

    //Also Perhaps you should cache the results as the instagram API is slow
    $cache = './'.sha1($url).'.json';
    //unlink($cache); // Clear the cache file if needed

    if(file_exists($cache) && filemtime($cache) > time() - 60*60){
        // If a cache file exists, and it is newer than 1 hour, use it
        $jsonData = json_decode(file_get_contents($cache));
    }else{
        $jsonData = json_decode((file_get_contents($url)));
        file_put_contents($cache,json_encode($jsonData));
    }


   ?>

<html>
<head>
</head>
<body>

<?php
    $data_array = array(); 
    foreach ($jsonData->data as $data){
      if (stripos($data->caption->text,'egypt') === false) {
      }
      else{
        $data_array[] = $data;
        $data = (str_split($data->caption->text)); 
        $data = (array_filter($data));  

      }
    }
    foreach ($data_array as $data):{
    $igimglow = $data->images->low_resolution->url;
    $igimgstd = $data->images->standard_resolution->url;
    $igimgthumb = $data->images->thumbnail->url;
    $igcaption = str_replace('#', '', (preg_replace('/(?:#[\w-]+\s*)+$/', '', $data->caption->text)));
    $igtime = date("F j, Y", $data->caption->created_time);
    $iglikes = $data->likes->count;
    $igcomments = $data->comments->count;
    $iglong = $data->location->longitude;
    $iglat = $data->location->latitude ;
    $igusername = $data->user->username;
    $igfullname = $data->user->full_name;
    $iglink = $data->link;
    $igfilter = $data->filter;
    $igtags = implode(',',$data->tags);
    ?>
            <img src="<?php echo ($igimglow);}?>">
            <?php endforeach ?>

<?php

    if(isset($jsonData->pagination->next_max_id)) {
        $result .= '<div><a href="?next=' . $jsonData->pagination->next_max_id . '">Next</a></div>';
    }

    return $result;
}
?>
    <div id="container">
        <?=jsongram(@$_GET['next']);?>
        <div id="result"></div>
    </div>
</body>
</html>

Here's a live example of the above code:

http://johnricedesign.com/examples/pn.php

As shown above on the 2nd page photos tagged with "egypt" are displayed. I would like to replace the "Next" link to automatically load on the same page with a "Load More" button - to the best of my knowledge using AJAX is the only way of doing so. However I do not know how to do so, or even where to start. The second obvious problem I have is that even though I am removing the photos that don't contain the caption of "egypt" I am still getting a lot of blank spaces, I presume that will be rather simple to fix once AJAX is being used.

I have been pulling my hair out for the last 5 days trying to do this. You help, advice, wisdom, are much appreciated in advance.


Solution

  • I changed the the api to work with client_id rather than access_token. You can change it back it will have no effect.

    Demo: https://tjay.co/l/instagrampagination

    ajax.php

    <?php
    function jsongram($next = null)
    {
      $userid = "xxx";
      $accessToken = "xxx";
      $url = ("https://api.instagram.com/v1/users/{$userid}/media/recent/?client_id={$accessToken}");
    
      if ( !empty($next) ) {
        $url.= '&max_id=' . $next;
      }
    
      // Also Perhaps you should cache the results as the instagram API is slow
      $cache = './' . sha1($url) . '.json';
    
      // unlink($cache); // Clear the cache file if needed
    
      // If a cache file exists, and it is newer than 1 hour, use it
      if (file_exists($cache) && filemtime($cache) > time() - 60 * 60) {
          $jsonData = json_decode(file_get_contents($cache));
      } else {
        $jsonData = json_decode(file_get_contents($url));
        file_put_contents($cache, json_encode($jsonData));
      }
    
      return $jsonData;
    }
    
    function instaFormat($jsonData)
    {
      $data_array = array();
      $response = array();
    
      foreach($jsonData->data as $data) {
        if ( !empty($data->caption->text) && stripos($data->caption->text, 'egypt') !== false ) { 
            $data_array[] = $data;
            $data = (str_split($data->caption->text));
            $data = (array_filter($data));
          }
      }
    
      $response['next'] = $jsonData->pagination->next_max_id;
    
      foreach($data_array as $data) {
          $igimglow = $data->images->low_resolution->url;
          // $igimgstd = $data->images->standard_resolution->url;
          // $igimgthumb = $data->images->thumbnail->url;
          // $igcaption = str_replace('#', '', (preg_replace('/(?:#[\w-]+\s*)+$/', '', $data->caption->text)));
          // $igtime = date("F j, Y", $data->caption->created_time);
          // $iglikes = $data->likes->count;
          // $igcomments = $data->comments->count;
          // $iglong = $data->location->longitude;
          // $iglat = $data->location->latitude;
          // $igusername = $data->user->username;
          // $igfullname = $data->user->full_name;
          // $iglink = $data->link;
          // $igfilter = $data->filter;
          // $igtags = implode(',', $data->tags);
    
          $response['data'][] = '<img src="'.$igimglow.'">';
      }
    
      return $response;
    }
    
    if ( isset($_POST['next']) ) {
      echo json_encode(instaFormat(jsongram($_POST['next'])));
      die();
    }
    

    index.php

    <!doctype html>
    <html>
      <body>
        <div data-pictures></div>
    
        <div><button type="button" data-get-next>Next</button></div>
    
        <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
        <script>
          jQuery(function($) {
            $(document).on('get-feed', function(e, next_id) {
    
              var data = {
                next: next_id
              };
    
              $.post('ajax.php', data, function(response) {
                var container = $('[data-pictures]');
                response = $.parseJSON(response);
    
                container.html('');
                $('[data-get-next]').attr('data-get-next', response.next);
    
                $.each(response.data, function(i, val) {
                  $(val).appendTo(container);
                });
              });
            });
    
            $('[data-get-next]').click(function() {
              var next_id = $(this).attr('data-get-next');
              $.event.trigger('get-feed', next_id);
            });
    
            $.event.trigger('get-feed', 0);
          });
        </script>
      </body>
    </html>