2015-03-12 2 views
2

Я использую версию facebook-php-ads-sdk 2.2.4 (новейшую на момент написания этой статьи). Я заметил, что курсор, который возвращается с вызовами $adAccount->getReportStats(), разбит на неявный выбор. Курсор ожидает увидеть в ответ следующую структуру:FacebookAds SDK Курсор не работает on/reportstats конечная точка

{ 
    "paging": { "cursor": { "after": "<some_url>" } } 
} 

Однако /reportstats конечная точка возвращает информацию пейджинга структурированную, как это:

{ 
    "paging": { "next": "<some_url>" } 
} 

Я мог бы поклясться, что работал ожидается несколько дней назад, так что, возможно, API facebook изменился?

Вот пример:

$adAccount = new AdAccount('some_id'); 

// cursor is an instance of FacebookAds\Cursor. 
$cursor = $adAccount->getReportStats($someFields, $someParams); 
$cursor->setUseImplicitFetch(true); 

foreach ($cursor as $item) { 
    // do stuff 
} 
// cursor is never advanced to next paged result. 

Как вы можете видеть в этом отрезала от FacebookAds \ Cursor, когда неявное выборки устанавливается истина, курсор только проверяет paging.cursor.after|before:

<?php 

namespace FacebookAds; 

use FacebookAds\Http\RequestInterface; 
use FacebookAds\Http\ResponseInterface; 
use FacebookAds\Object\AbstractObject; 

class Cursor implements \Iterator, \Countable, \arrayaccess { 

     // ... 

     /** 
     * @return string|null 
     */ 
     protected function getLastRequestBefore() { 
     $content = $this->getLastResponse()->getContent(); 

     return isset($content['paging']['cursors']['before']) 
      ? $content['paging']['cursors']['before'] 
      : null; 
     } 

     /** 
     * @return string|null 
     */ 
     protected function getLastRequestAfter() { 
     $content = $this->getLastResponse()->getContent(); 

     return isset($content['paging']['cursors']['after']) 
      ? $content['paging']['cursors']['after'] 
      : null; 
     } 

     // ... 
} 

Фактический запрос на скручивание сгенерирует sdk facebook:

curl -G \ 
    -d "data_columns=["time_start","time_stop","spend","impressions","clicks","unique_clicks","social_clicks","unique_social_clicks","cpm","unique_ctr","reach","frequency","cost_per_unique_click","cost_per_action_type","cost_per_total_action","cpp","cpc","ctr","account_id","account_name","campaign_group_id","campaign_group_name","campaign_id","campaign_name"]" \ 
    -d "date_preset=last_90_days" \ 
    -d "time_increment=1" \ 
    -d "access_token=<nice_try_dude>" \ 
    -d "appsecret_proof=<not_getting_this_either>" \ 
    https://graph.facebook.com/v2.2/act_<account_id>/reportstats 

И вот res ponse:

{ 
    "data": [ 
    { 
     "campaign_id": "<campaign_id>", 
     "date_start": "2014-12-18", 
     "date_stop": "2014-12-18", 
     "time_start": 1418878800, 
     "time_stop": 1418965200, 
     "spend": 39.39, 
     "impressions": 5127, 
     "clicks": 65, 
     "unique_clicks": 55, 
     "social_clicks": 31, 
     "unique_social_clicks": 27, 
     "cpm": 7.6828554710357, 
     "unique_ctr": 1.0880316518299, 
     "reach": 5055, 
     "frequency": 1.0142433234421, 
     "cost_per_unique_click": 0.71618181818182, 
     "cost_per_action_type": 0.67913793103448, 
     "cost_per_total_action": 0.67913793103448, 
     "cpp": 7.7922848664688, 
     "cpc": 0.606, 
     "ctr": 1.2677979325141, 
     "account_id": "<account_id>", 
     "account_name": "<account_name>", 
     "campaign_group_id": "<campaign_group_id>", 
     "campaign_group_name": "<campaign_group_name>", 
     "campaign_name": "<campaign_name>" 
    }, 
    { 
     "..." : "x49" 
    } 
    ], 
    "limit": 50, 
    "offset": 0, 
    "paging": { 
    "next": "https://graph.facebook.com/v2.2/act_<account_id>/reportstats?data_columns=%5B%22time_start%22%2C%22time_stop%22%2C%22spend%22%2C%22impressions%22%2C%22clicks%22%2C%22unique_clicks%22%2C%22social_clicks%22%2C%22unique_social_clicks%22%2C%22cpm%22%2C%22unique_ctr%22%2C%22reach%22%2C%22frequency%22%2C%22cost_per_unique_click%22%2C%22cost_per_action_type%22%2C%22cost_per_total_action%22%2C%22cpp%22%2C%22cpc%22%2C%22ctr%22%2C%22account_id%22%2C%22account_name%22%2C%22campaign_group_id%22%2C%22campaign_group_name%22%2C%22campaign_id%22%2C%22campaign_name%22%5D&date_preset=last_90_days&time_increment=1&access_token=<access_token>&appsecret_proof=<appsecret_proof>&offset=50" 
    } 
} 

В то же время я прибегал к использованию следующей «обертки». Лучшие альтернативы?

<?php namespace PayPerClick\Market\Facebook\Data; 

use FacebookAds\Cursor; 

/** 
* Class MyReportCursor 
* 
* @package PayPerClick\Market\Facebook\Data 
*/ 
class MyReportCursor implements \Iterator, \Countable, \ArrayAccess { 

    /** 
    * @type int 
    */ 
    protected $position = 0; 

    /** 
    * @type Cursor[] 
    */ 
    protected $cursors = []; 

    /** 
    * @param Cursor $cursor 
    */ 
    public function __construct(Cursor $cursor) { 
     $cursor->setUseImplicitFetch(false); 
     $this->cursors[] = $cursor; 
    } 

    /** 
    * @return Cursor 
    */ 
    public function getCursor() { 
     return $this->cursors[ $this->position ]; 
    } 

    public function current() { 
     return $this->getCursor()->current()->getData(); 
    } 

    public function next() { 
     $this->getCursor()->next(); 
     if ($this->getCursor()->key() === null) { 
      $this->advanceCursors(); 
     } 
    } 

    protected function advanceCursors() { 
     if ($this->hasCursor($this->position+1)) { 
      $this->getCursor()->rewind(); 
      $this->position++; 
     } else if ($this->hasNextPage()) { 
      $this->fetchNext(); 
     } 
    } 

    /** 
    * @return bool 
    */ 
    protected function hasNextPage() { 
     return $this->getNextPage() !== null; 
    } 

    /** 
    * @return string|null 
    */ 
    protected function getNextPage() { 
     $content = $this->getCursor()->getLastResponse()->getContent(); 

     return isset($content['paging']['next']) ? $content['paging']['next'] : null; 
    } 

    /** 
    * @param int $offset 
    * @return bool 
    */ 
    protected function hasCursor($offset) { 
     return isset($this->cursors[ $offset ]); 
    } 

    protected function fetchNext() { 
     parse_str(parse_url($this->getNextPage(), PHP_URL_QUERY), $previousParams); 

     $objectPrototype = clone $this->getCursor()->offsetGet($this->getCursor()->getIndexRight()); 
     $request   = $this->getCursor()->getLastResponse()->getRequest()->createClone(); 

     $request->getQueryParams()->offsetSet('offset', $previousParams['offset']); 

     $this->getCursor()->rewind(); 

     $this->position++; 

     $this->cursors[ $this->position ] = new Cursor($request->execute(), $objectPrototype); 
    } 

    public function key() { 
     return $this->getCursor()->key(); 
    } 

    public function valid() { 
     return $this->getCursor()->valid(); 
    } 

    public function rewind() { 
     $this->position = 0; 
    } 

    public function offsetExists($offset) { 
     return $this->getCursor()->offsetExists($offset); 
    } 

    public function offsetGet($offset) { 
     return $this->getCursor()->offsetGet($offset); 
    } 

    public function offsetSet($offset, $value) { 
     $this->getCursor()->offsetSet($offset, $value); 
    } 

    public function offsetUnset($offset) { 
     $this->getCursor()->offsetUnset($offset); 
    } 

    public function count() { 
     return array_reduce($this->cursors, function ($a, $cursor) { 
      return $a + $cursor->count(); 
     }, 0); 
    } 
} 

ответ

1

То, что вы видите, это ответ, когда это «время на основе Разбивка» https://developers.facebook.com/docs/graph-api/using-graph-api/v2.2#paging

+0

Проблема в том, что конечная точка/reportstats не возвращает эти параметры курсора. Меня смущает то, что SDK предполагает, что это так. – kylehyde215

+0

reportstats - это основанная на времени api, как описано здесь: https://developers.facebook.com/docs/marketing-api/adreportstats/v2.2#params, и здесь: https://developers.facebook.com/docs/ marketing-api/guide/chapter-7-ad-report-stats –

+0

Я понимаю, что API основан на времени. Тем не менее, Facebooks sdk возвращает тот же самый итератор курсора для вызовов в reportstats, как и для других конечных точек. Очевидно, это вызывает проблемы. – kylehyde215

0

Это в основном, вероятно, ошибка в facebook-php-ads-sdk. Даже Facebook API examples показать, как:

use FacebookAds\Object\AdAccount; 

$account = new AdAccount('act_<AD_ACCOUNT_ID>'); 

$params = array(
    'date_preset'=>'last_28_days', 
    'data_columns'=>"['adgroup_id','actions','spend']", 
); 

$stats = $account->getReportsStats(null, $params); 

foreach($stats as $stat) { 
    echo $stat->impressions; 
    echo $stat->actions; 
} 

К сожалению - это, на самом деле, повременной пейджинговой так курсор данные не будут возвращены из него. Это уже заполнены, как вопрос о GitHub - https://github.com/facebook/facebook-php-ads-sdk/issues/76

EDIT: Ах, это ты, заполнивших эту ошибку :)

Смежные вопросы