I'm using the facebook-php-ads-sdk version 2.2.4 (the newest at the time of this writing). I've noticed that the Cursor that is returned with calls to $adAccount->getReportStats() is broken with the implicit fetch option. The cursor is expecting to see in the response the following structure:
{
"paging": { "cursor": { "after": "<some_url>" } }
}
However, the /reportstats endpoint returns the paging information structured like this:
{
"paging": { "next": "<some_url>" }
}
I could have sworn it was working as expected a few days ago, so perhaps facebook's API has changed?
Here is an example:
$adAccount = new AdAccount('some_id');
$cursor = $adAccount->getReportStats($someFields, $someParams);
$cursor->setUseImplicitFetch(true);
foreach ($cursor as $item) {
// do stuff
}
// cursor is never advanced to next paged result.
In the meantime, I've resorted to using the following "wrapper". Better alternatives?
<?php namespace PayPerClick\Market\Facebook\Data;
use FacebookAds\Cursor;
/**
* Class ReportCursor
*
* @package PayPerClick\Market\Facebook\Data
*/
class ReportCursor 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);
}
}
Aucun commentaire:
Enregistrer un commentaire