/**
  * Handler for the `instagram` Shortcode.
  *
  * @return string|null
  */
 public static function instagramShortcodeHandler($args, $content = null, $parser = null, $tag)
 {
     if (!array_key_exists('username', $args)) {
         return null;
     }
     $instagramAccount = InstagramAccount::get()->filter('Title', $args['username'])->First();
     // Make sure the InstagramAccount is valid and has been authorised.
     if (!$instagramAccount || !$instagramAccount->getField('AccessToken')) {
         return null;
     }
     $controller = Controller::curr();
     $link = $controller->Link();
     // Valid IDs only have digits and an underscore.
     $maxID = preg_replace('/[^\\d_]/', '', $controller->getRequest()->getVar('start'));
     $media = self::getMedia($instagramAccount, $maxID);
     if (!$media) {
         return null;
     }
     // If there are less items returned than the maximum allowed per page,
     // we're on the last page, so don't include a 'next' button.
     //
     // TODO:
     // Handle edge case where it's the last page and exactly "items_per_page" are returned.
     $loadMoreLink = count($media) < Config::inst()->get('InstagramAccount', 'items_per_page') ? null : $link . '?start=' . array_pop(array_slice($media, -1))['id'];
     // Make tags iterable in the template.
     foreach ($media as &$item) {
         $item['tags'] = ArrayList::create(array_map(function ($tag) {
             return ArrayData::create(['name' => $tag]);
         }, $item['tags']));
     }
     $data = ArrayData::create(['loadMoreLink' => $loadMoreLink, 'instagramLink' => "https://www.instagram.com/{$args['username']}"]);
     $data->setField('media', ArrayList::create($media));
     return $data->renderWith('InstagramPage');
 }
 /**
  * OAuth callback handler.
  *
  * @param SS_HTTPRequest $request
  */
 public function OAuth($request)
 {
     $code = $request->getVar('code');
     $state = $request->getVar('state');
     if (!$code || !$state) {
         return Controller::curr()->redirect($this->Link());
     }
     $client = InstagramAccount::getNewInstagramClient();
     $form = $this->getEditForm();
     try {
         $token = $client->getAccessToken($code);
         $instagramAccountID = $this->getInstagramAccountIDFromSession($state);
         // Find the matching InstagramAccount.
         if (!$instagramAccountID || !($instagramAccount = InstagramAccount::get()->byId($instagramAccountID))) {
             return $this->handleOAuthError($form);
         }
         try {
             $instagramAccount->updateAccessToken(Convert::raw2json($token), $state);
             $instagramAccount->write();
             $form->sessionMessage(_t('Instagram.MessageOAuthSuccess', 'Successfully authorised your account.'), 'good');
             return Controller::curr()->redirect($this->Link());
         } catch (Exception $e) {
             return $this->handleOAuthError($form, _t('Instagram.MessageOAuthErrorUserConflict', 'Unable to authorise account. Make sure you are logged out of Instagram and ' . 'your username is spelled correctly.'));
         }
     } catch (InstagramIdentityProviderException $e) {
         return $this->handleOAuthError($form);
     }
 }