<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http;

class Response implements ResponseInterface {

  /**
   * @var RequestInterface
   */
  protected $request;

  /**
   * @var int
   */
  protected $statusCode;

  /**
   * @var Headers
   */
  protected $headers;

  /**
   * @var string
   */
  protected $body;

  /**
   * @var mixed
   */
  protected $content;

  /**
   * @return RequestInterface
   */
  public function getRequest() {
    return $this->request;
  }

  /**
   * @param RequestInterface $request
   */
  public function setRequest(RequestInterface $request) {
    $this->request = $request;
  }

  /**
   * @return int
   */
  public function getStatusCode() {
    return $this->statusCode;
  }

  /**
   * @param int $status_code
   */
  public function setStatusCode($status_code) {
    $this->statusCode = $status_code;
  }

  /**
   * @return Headers
   */
  public function getHeaders() {
    if ($this->headers === null) {
      $this->headers = new Headers();
    }

    return $this->headers;
  }

  /**
   * @param Headers $headers
   */
  public function setHeaders(Headers $headers) {
    $this->headers = $headers;
  }

  /**
   * @return string
   */
  public function getBody() {
    return $this->body;
  }

  /**
   * @param string $body
   */
  public function setBody($body) {
    $this->body = $body;
    $this->content = null;
  }

  /**
   * @return array|null
   */
  public function getContent() {
    if ($this->content === null) {
      $this->content = json_decode($this->getBody(), true);
    }

    return $this->content;
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http;

interface ResponseInterface {

  /**
   * @return RequestInterface
   */
  public function getRequest();

  /**
   * @param RequestInterface $request
   */
  public function setRequest(RequestInterface $request);

  /**
   * @return int
   */
  public function getStatusCode();

  /**
   * @param int $status_code
   */
  public function setStatusCode($status_code);

  /**
   * @return Headers
   */
  public function getHeaders();

  /**
   * @param Headers $headers
   */
  public function setHeaders(Headers $headers);

  /**
   * @return string
   */
  public function getBody();

  /**
   * @param string $body
   */
  public function setBody($body);

  /**
   * @return array|null
   */
  public function getContent();
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http;

class SimpleRequest extends Request{

  /**
   * @var string
   */
  const DEFAULT_WWWW_BASE_DOMAIN = 'connect.facebook.net';

  /**
   * @param Client $client
   */
  public function __construct(Client $client) {
    parent::__construct($client);
    //Setting the curl options inside the client to avoid SSL certificates usage
    $client -> getAdapter()->setOpts( new \ArrayObject(array(
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 60,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER => true,
        CURLOPT_SSL_VERIFYPEER => 0)));
  }

  /**
   * @return string
   */
  public function getDomain() {
    if ($this->domain === null) {
      $this->domain = sprintf(
        "%s",
        self::DEFAULT_WWWW_BASE_DOMAIN);
    }

    return $this->domain;
  }

  /**
   * @return string
   */
  public function getUrl() {
    $delimiter = null;
    if ($this->getQueryParams()->count() ) {
      $delimiter = strpos($this->getPath(), '?') ? '&' : '?';
    }
    return $this->getProtocol().$this->getDomain()
        .'/'.$this->getPath()
        .$delimiter
        .http_build_query($this->getQueryParams()->export(), '', '&');
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http;

abstract class Util {

  /**
   * Avoid parse_str() for HHVM compatibility
   * This implementation is not a complete sobstitute, but covers all the
   * requirements of the Facebook Graph Cursor.
   *
   * @see hhvm.hack.disallow_dynamic_var_env_funcs
   * @param $query_string
   * @return array
   */
  public static function parseUrlQuery($query_string) {
    $query = array();
    $pairs = explode('&', $query_string);
    foreach ($pairs as $pair) {
      list($key, $value) = explode('=', $pair);
      $query[$key] = urldecode($value);
    }

    return $query;
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Adapter;

use FacebookAds\Http\Client;

abstract class AbstractAdapter implements AdapterInterface {

  /**
   * @var Client
   */
  protected $client;

  /**
   * @param Client $client
   */
  public function __construct(Client $client) {
    $this->client = $client;
  }

  /**
   * @return Client
   */
  public function getClient() {
    return $this->client;
  }

  /**
   * @return string
   */
  public function getCaBundlePath() {
    return $this->getClient()->getCaBundlePath();
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Adapter;

use FacebookAds\Http\Client;
use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;

interface AdapterInterface {

  /**
   * @param Client $client
   */
  public function __construct(Client $client);

  /**
   * @return Client
   */
  public function getClient();

  /**
   * @return string
   */
  public function getCaBundlePath();

  /**
   * @return \ArrayObject
   */
  public function getOpts();

  /**
   * @param \ArrayObject $opts
   * @return void
   */
  public function setOpts(\ArrayObject $opts);

  /**
   * @param RequestInterface $request
   * @return ResponseInterface
   */
  public function sendRequest(RequestInterface $request);
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Adapter;

use FacebookAds\Exception\Exception;
use FacebookAds\Http\Adapter\Curl\AbstractCurl;
use FacebookAds\Http\Adapter\Curl\Curl;
use FacebookAds\Http\Adapter\Curl\CurlInterface;
use FacebookAds\Http\Client;
use FacebookAds\Http\Headers;
use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;

class CurlAdapter extends AbstractAdapter {

  /**
   * @var CurlInterface
   */
  protected $curl;

  /**
   * @var \ArrayObject
   */
  protected $opts;

  /**
   * @param Client $client
   * @param CurlInterface $curl
   */
  public function __construct(Client $client, CurlInterface $curl = null) {
    parent::__construct($client);
    $this->curl = $curl ?: AbstractCurl::createOptimalVersion();
    $this->curl->init();
  }

  /**
   * @return Curl
   */
  public function getCurl() {
    return $this->curl;
  }

  /**
   * @return \ArrayObject
   */
  public function getOpts() {
    if ($this->opts === null) {
      $this->opts = new \ArrayObject(array(
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 60,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER => true,
        CURLOPT_CAINFO => $this->getCaBundlePath(),
      ));
    }

    return $this->opts;
  }

  /**
   * @param \ArrayObject $opts
   */
  public function setOpts(\ArrayObject $opts) {
    $this->opts = $opts;
  }

  /**
   * @return int
   */
  protected function getheaderSize() {
    return $this->getCurl()->getInfo(CURLINFO_HEADER_SIZE);
  }

  /**
   * Extracts the headers and the body into a two-part array
   * @param string $raw_response
   * @return array
   */
  protected function extractResponseHeadersAndBody($raw_response) {
    $header_size = $this->getheaderSize();

    $raw_headers = mb_substr($raw_response, 0, $header_size);
    $raw_body = mb_substr($raw_response, $header_size);

    return array(trim($raw_headers), trim($raw_body));
  }

  /**
   * @param Headers $headers
   * @param string $raw_headers
   */
  protected function parseHeaders(Headers $headers, $raw_headers) {
    $raw_headers = str_replace("\r\n", "\n", $raw_headers);

    // There will be multiple headers if a 301 was followed
    // or a proxy was followed, etc
    $header_collection = explode("\n\n", trim($raw_headers));
    // We just want the last response (at the end)
    $raw_headers = array_pop($header_collection);

    $header_components = explode("\n", $raw_headers);
    foreach ($header_components as $line) {
      if (strpos($line, ': ') === false) {
        $headers['http_code'] = $line;
      } else {
        list ($key, $value) = explode(': ', $line, 2);
        $headers[$key] = $value;
      }
    }
  }

  /**
   * @param RequestInterface $request
   * @return ResponseInterface
   * @throws Exception
   */
  public function sendRequest(RequestInterface $request) {
    $response = $this->getClient()->createResponse();
    $this->getCurl()->reset();
    $curlopts = array(
      CURLOPT_URL => $request->getUrl(),
    );

    $method = $request->getMethod();
    if ($method !== RequestInterface::METHOD_GET
      && $method !== RequestInterface::METHOD_POST) {
      $curlopts[CURLOPT_CUSTOMREQUEST] = $method;
    }

    $curlopts = $this->getOpts()->getArrayCopy() + $curlopts;

    if ($request->getHeaders()->count()) {
      $headers = array();
      foreach ($request->getHeaders() as $header => $value) {
        $headers[] = "{$header}: {$value}";
      }
      $curlopts[CURLOPT_HTTPHEADER] = $headers;
    }

    $postfields = array();
    if ($method === RequestInterface::METHOD_POST
      && $request->getFileParams()->count()
    ) {
      $postfields = array_merge(
        $postfields,
        array_map(
          array($this->getCurl(), 'preparePostFileField'),
          $request->getFileParams()->getArrayCopy()));
    }
    if ($method !== RequestInterface::METHOD_GET
      && $request->getBodyParams()->count()) {
      $postfields
        = array_merge($postfields, $request->getBodyParams()->export());
    }

    if (!empty($postfields)) {
      $curlopts[CURLOPT_POSTFIELDS] = $postfields;
    }

    $this->getCurl()->setoptArray($curlopts);
    $raw_response = $this->getCurl()->exec();

    $status_code = $this->getCurl()->getInfo(CURLINFO_HTTP_CODE);
    $curl_errno = $this->getCurl()->errno();
    $curl_error = $curl_errno ? $this->getCurl()->error() : null;

    $response_parts = $this->extractResponseHeadersAndBody($raw_response);

    $response->setStatusCode($status_code);
    $this->parseHeaders($response->getHeaders(), $response_parts[0]);
    $response->setBody($response_parts[1]);

    if ($curl_errno) {
      throw new Exception($curl_error, $curl_errno);
    }

    return $response;
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Adapter\Curl;

abstract class AbstractCurl implements CurlInterface {

  /**
   * @var resource
   */
  protected $handle;

  /**
   * @throws \RuntimeException
   */
  public function __construct() {
    if (!extension_loaded('curl')) {
      throw new \RuntimeException("Extension curl not loaded");
    }
  }

  public function __clone() {
    $this->handle = curl_copy_handle($this->handle);
  }

  public function __destruct() {
    if (is_resource($this->handle)) {
      curl_close($this->handle);
    }
  }

  /**
   * @return CurlInterface
   */
  public static function createOptimalVersion() {
    if (version_compare(PHP_VERSION, '5.5.0') >= 0) {
      return new Curl55();
    } else {
      return new Curl();
    }
  }

  /**
   * @return resource
   */
  public function getHandle() {
    return $this->handle;
  }

  /**
   * @return int
   */
  public function errno() {
    return curl_errno($this->handle);
  }

  /**
   * @return string
   */
  public function error() {
    return curl_error($this->handle);
  }

  /**
   * @return mixed
   */
  public function exec() {
    return curl_exec($this->handle);
  }

  /**
   * @param int $opt
   * @return mixed
   */
  public function getInfo($opt = 0) {
    return curl_getinfo($this->handle, $opt);
  }

  /**
   * @return void
   */
  public function init() {
    $this->handle = $this->handle ?: curl_init();
  }

  /**
   * @param array $opts
   */
  public function setoptArray(array $opts) {
    curl_setopt_array($this->handle, $opts);
  }

  /**
   * @param int $option
   * @param mixed $value
   * @return bool
   */
  public function setopt($option, $value) {
    return curl_setopt($this->handle, $option, $value);
  }

  /**
   * @param int $age
   * @return array
   */
  public static function version($age) {
    return curl_version($age);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Adapter\Curl;

use FacebookAds\Http\FileParameter;

class Curl extends AbstractCurl {

  /**
   * @throws \RuntimeException
   */
  public function __construct() {
    parent::__construct();
    if (version_compare(PHP_VERSION, '5.5.0') >= 0) {
      throw new \RuntimeException("Unsupported Curl version");
    }
  }

  /**
   * @param string $string
   * @return string
   */
  public function escape($string) {
    return rawurlencode($string);
  }

  /**
   * @param int $bitmask
   * @return int
   */
  public function pause($bitmask) {
    return 0;
  }

  /**
   * FIXME should introduce v2.10 breaking change:
   * implement abstract support for FileParameter in AdapterInterface
   *
   * @param string|FileParameter $filepath
   * @return string
   */
  public function preparePostFileField($filepath) {
    $mime_type = $name = '';
    if ($filepath instanceof FileParameter) {
      $mime_type = $filepath->getMimeType() !== null
        ? sprintf(';type=%s', $filepath->getMimeType())
        : '';
      $name = $filepath->getName() !== null
        ? sprintf(';filename=%s', $filepath->getName())
        : '';
      $filepath = $filepath->getPath();
    }
    return sprintf('@%s%s%s', $filepath, $mime_type, $name);
  }

  /**
   * @return void
   */
  public function reset() {
    $this->handle && curl_close($this->handle);
    $this->handle = curl_init();
  }

  /**
   * @param int $errornum
   * @return NULL|string
   */
  public static function strerror($errornum) {
    return curl_strerror($errornum);
  }

  /**
   * @param string $string
   * @return bool|string
   */
  public function unescape($string) {
    return curl_unescape($this->handle, $string);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Adapter\Curl;

use FacebookAds\Http\FileParameter;

class Curl55 extends AbstractCurl {

  /**
   * @throws \RuntimeException
   */
  public function __construct() {
    parent::__construct();
    if (version_compare(PHP_VERSION, '5.5.0') < 0) {
      throw new \RuntimeException("Unsupported Curl version");
    }
  }

  /**
   * @param string $string
   * @return bool|string
   */
  public function escape($string) {
    return curl_escape($this->handle, $string);
  }

  /**
   * @param int $bitmask
   * @return int
   */
  public function pause($bitmask) {
    return curl_pause($this->handle, $bitmask);
  }

  /**
   * FIXME should introduce v2.10 breaking change:
   * implement abstract support for FileParameter in AdapterInterface
   *
   * @param string|FileParameter $filepath
   * @return \CURLFile
   */
  public function preparePostFileField($filepath) {
    $mime_type = $name = ''; // can't be null in HHVM
    if ($filepath instanceof FileParameter) {
      $mime_type = $filepath->getMimeType() ?: '';
      $name = $filepath->getName() ?: '';
      $filepath = $filepath->getPath();
    }
    return new \CURLFile($filepath, $mime_type, $name);
  }

  /**
   * @return void
   */
  public function reset() {
    $this->handle && curl_reset($this->handle);
  }

  /**
   * @param int $errornum
   * @return NULL|string
   */
  public static function strerror($errornum) {
    return curl_strerror($errornum);
  }

  /**
   * @param string $string
   * @return bool|string
   */
  public function unescape($string) {
    return curl_unescape($this->handle, $string);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Adapter\Curl;

interface CurlInterface {

  /**
   * @return resource
   */
  public function getHandle();

  /**
   * @return int
   */
  public function errno();

  /**
   * @return string
   */
  public function error();

  /**
   * @param string $string
   * @return bool|string
   */
  public function escape($string);

  /**
   * @return mixed
   */
  public function exec();

  /**
   * @param int $opt
   * @return mixed
   */
  public function getInfo($opt = 0);

  /**
   * @return void
   */
  public function init();

  /**
   * @param int $bitmask
   * @return int
   */
  public function pause($bitmask);

  /**
   * @param $filepath
   * @return string|\CurlFile
   */
  public function preparePostFileField($filepath);

  /**
   * @return void
   */
  public function reset();

  /**
   * @param array $opts
   */
  public function setoptArray(array $opts);

  /**
   * @param int $option
   * @param mixed $value
   * @return bool
   */
  public function setopt($option, $value);

  /**
   * @param $string
   * @return string
   */
  public function unescape($string);

  /**
   * @param int $age
   * @return array
   */
  public static function version($age);
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Exception;

class AuthorizationException extends RequestException {

}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Exception;

class ClientException extends RequestException {

}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Exception;

use FacebookAds\Http\ResponseInterface;

class EmptyResponseException extends RequestException {

  /**
   * @param ResponseInterface $response
   */
  public function __construct(ResponseInterface $response) {
    $content = array(
      'error' => array(
        'message' => 'Empty Response',
      ));
    $response->setBody(json_encode($content));
    parent::__construct($response);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Exception;

class PermissionException extends RequestException {

}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Exception;

use FacebookAds\Exception\Exception;
use FacebookAds\Http\ResponseInterface;

class RequestException extends Exception {

  /**
   * @var ResponseInterface|null
   */
  protected $response;

  /**
   * @var Headers
   */
  protected $headers;

  /**
   * @var int|null
   */
  protected $errorCode;

  /**
   * @var int|null
   */
  protected $errorSubcode;

  /**
   * @var string|null
   */
  protected $errorMessage;

  /**
   * @var string|null
   */
  protected $errorUserTitle;

  /**
   * @var string|null
   */
  protected $errorUserMessage;

  /**
   * @var int|null
   */
  protected $errorType;

  /**
   * @var array|null
   */
  protected $errorBlameFieldSpecs;

  /**
   * @var string|null
   */
  protected $facebookTraceId;

  /**
   * @param ResponseInterface $response
   */
  public function __construct(ResponseInterface $response) {
    $this->headers = $response->getHeaders();
    $this->response = $response;
    $error_data = static::getErrorData($response);

    parent::__construct($error_data['message'], $error_data['code'] ?? 0);

    $this->errorSubcode = $error_data['error_subcode'];
    $this->errorUserTitle = $error_data['error_user_title'];
    $this->errorUserMessage = $error_data['error_user_msg'];
    $this->errorBlameFieldSpecs = $error_data['error_blame_field_specs'];
    $this->facebookTraceId = $error_data['fbtrace_id'];
  }

  /**
   * @return ResponseInterface|null
   */
  public function getResponse() {
    return $this->response;
  }

  /**
   * @param array|string $array
   * @param string|int $key
   * @param mixed $default
   * @return mixed
   */
  protected static function idx($array, $key, $default = null) {
    if (is_string($array)) {
      $array = json_decode($array, true);
    }

    if (is_null($array)) {
      return null;
    }

    return array_key_exists($key, $array)
      ? $array[$key]
      : $default;
  }

  /**
   * @param ResponseInterface $response
   * @return array
   */
  protected static function getErrorData(ResponseInterface $response) {
    $response_data = $response->getContent();
    if (is_null($response_data)) {
      $response_data = array();
    }
    $error_data = static::idx($response_data, 'error', array());

    if (is_string(static::idx($error_data, 'error_data'))) {
      $error_data["error_data"] =
        json_decode(stripslashes(static::idx($error_data, 'error_data')), true);
    }

    if (is_null(static::idx($error_data, 'error_data'))) {
      $error_data["error_data"] = array();
    }

    return array(
      'code' =>
        static::idx($error_data, 'code', static::idx($response_data, 'code')),
      'error_subcode' => static::idx($error_data, 'error_subcode'),
      'message' => static::idx($error_data, 'message'),
      'error_user_title' => static::idx($error_data, 'error_user_title'),
      'error_user_msg' => static::idx($error_data, 'error_user_msg'),
      'error_blame_field_specs' =>
        static::idx(static::idx($error_data, 'error_data', array()),
          'blame_field_specs'),
      'fbtrace_id' => static::idx($error_data, 'fbtrace_id'),
      'type' => static::idx($error_data, 'type'),
    );
  }

  /**
   * Process an error payload from the Graph API and return the appropriate
   * exception subclass.
   * @param ResponseInterface $response
   * @return RequestException
   */
  public static function create(ResponseInterface $response) {
    $error_data = static::getErrorData($response);
    if (in_array(
      $error_data['error_subcode'], array(458, 459, 460, 463, 464, 467))
      || in_array($error_data['code'], array(100, 102, 190))
      || $error_data['type'] === 'OAuthException') {

      return new AuthorizationException($response);
    } elseif (in_array($error_data['code'], array(1, 2))) {

      return new ServerException($response);
    } elseif (in_array($error_data['code'], array(4, 17, 341))) {

      return new ThrottleException($response);
    } elseif ($error_data['code'] == 506) {

      return new ClientException($response);
    } elseif ($error_data['code'] == 10
      || ($error_data['code'] >= 200 && $error_data['code'] <= 299)) {

      return new PermissionException($response);
    } else {

      return new self($response);
    }
  }

  /**
   * @return int
   */
  public function getHttpStatusCode() {
    return $this->response->getStatusCode();
  }

  /**
   * @return int|null
   */
  public function getErrorSubcode() {
    return $this->errorSubcode;
  }

  /**
   * @return string|null
   */
  public function getErrorUserTitle() {
    return $this->errorUserTitle;
  }

  /**
   * @return string|null
   */
  public function getErrorUserMessage() {
    return $this->errorUserMessage;
  }

  /**
   * @return array|null
   */
  public function getErrorBlameFieldSpecs() {
    return $this->errorBlameFieldSpecs;
  }

  /**
   * @return string|null
   */
  public function getFacebookTraceId() {
    return $this->facebookTraceId;
  }

  /**
   * @return bool
   */
  public function isTransient() {
    if ($this->getResponse() !== null) {
      return false;
    }

    $body = $this->getResponse()->getBody();

    return array_key_exists('error', $body)
      && array_key_exists('is_transient', $body['error'])
      && $body['error']['is_transient'];
  }

  /**
   * @return Headers
   */
  public function getHeaders() {
    return $this->headers;
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Exception;

class ServerException extends RequestException {

}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Http\Exception;

class ThrottleException extends RequestException {

}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Logger;

use FacebookAds\Http\FileParameter;
use FacebookAds\Http\Parameters;
use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;
use FacebookAds\Logger\CurlLogger\JsonAwareParameters;

class CurlLogger implements LoggerInterface {

  /**
   * @var string
   */
  const PARAM_DEFAULT_FLAG = 'd';

  /**
   * @var string
   */
  const PARAM_URLENCODE_FLAG = '-data-urlencode';

  /**
   * @var string
   */
  const PARAM_POST_FLAG = 'F';

  /**
   * @var string
   */
  const METHOD_DEFAULT_FLAG = '';

  /**
   * @var string
   */
  const METHOD_GET_FLAG = 'G';

  /**
   * @var string
   */
  const METHOD_PUT_FLAG = 'X PUT';

  /**
   * @var string
   */
  const METHOD_DELETE_FLAG = 'X DELETE';

  /**
   * @var resource
   */
  protected $handle;

  /**
   * @var bool
   */
  protected $jsonPrettyPrint = false;

  /**
   * @param resource $handle
   */
  public function __construct($handle = null) {
    if (!defined('STDOUT')) {
      define('STDOUT', fopen('php://stdout', 'w'));
    }
    $this->handle = is_resource($handle) ? $handle : STDOUT;
  }

  /**
   * @return bool
   */
  public function isJsonPrettyPrint() {
    return $this->jsonPrettyPrint;
  }

  /**
   * @param bool $json_pretty_print
   * @return $this
   */
  public function setJsonPrettyPrint($json_pretty_print) {
    $this->jsonPrettyPrint = $json_pretty_print;
    return $this;
  }

  /**
   * @param string $method
   * @return string
   */
  public static function getMethodFlag($method) {
    switch ($method) {
      case RequestInterface::METHOD_GET:
        return static::METHOD_GET_FLAG;
      case RequestInterface::METHOD_PUT:
        return static::METHOD_PUT_FLAG;
      case RequestInterface::METHOD_DELETE:
        return static::METHOD_DELETE_FLAG;
    }

    return static::METHOD_DEFAULT_FLAG;
  }

  /**
   * @param string $method
   * @param string $value
   * @return string
   */
  public static function getParamFlag($method, $value) {
    return $method === RequestInterface::METHOD_POST
      ? static::PARAM_POST_FLAG
      : (strstr($value, "\n")
        ? static::PARAM_URLENCODE_FLAG
        : static::PARAM_DEFAULT_FLAG);
  }

  /**
   * @param string $string
   * @param int $indent
   * @return string
   */
  protected function indent($string, $indent) {
    return str_replace("\n", " \n".str_repeat(' ', $indent), $string);
  }

  /**
   * @param Parameters $params
   * @param string $method
   * @param bool $is_file
   * @return string
   */
  protected function processParams(Parameters $params, $method, $is_file) {
    $chunks = array();
    if ($this->isJsonPrettyPrint()) {
      $params = new JsonAwareParameters($params);
    }
    foreach ($params->export() as $name => $value) {
      if ($is_file && $params->offsetGet($name) instanceof FileParameter) {
        $value = "@" . $this->normalizeFileParam($params->offsetGet($name));
      } else {
        $value = addcslashes(
          strpos($value, "\n") !== false
            ? $this->indent($value, 2)
            : $value,
          '\'');
      }
      $chunks[$name] = sprintf(
        '-%s \'%s=%s\'',
        $this->getParamFlag($method, $value),
        $name,
        $value);
    }

    return $chunks;
  }

  /**
   * @param FileParameter $file_param
   * @return string
   */
  protected function normalizeFileParam(FileParameter $file_param) {
    return sprintf('%s%s%s%s%s',
      $file_param->getPath(),
      $file_param->getMimeType() != null ? ";type=" : "",
      $file_param->getMimeType(),
      $file_param->getName() != null ? ";name=" : "",
      $file_param->getName());
  }

  /**
   * @param RequestInterface $request
   * @return string
   */
  protected function processUrl(RequestInterface $request) {
    return $request->getProtocol().$request->getDomain()
      .'/v'.$request->getGraphVersion().$request->getPath();
  }

  /**
   * @param string $buffer
   */
  protected function flush($buffer) {
    fwrite($this->handle, $buffer.PHP_EOL.PHP_EOL);
  }

  /**
   * @param mixed $level
   * @param string $message
   * @param array $context
   */
  public function log($level, $message, array $context = array()) {
    // We only care about requests
  }

  /**
   * @param array $array
   * @param mixed $key
   * @return mixed
   */
  protected function removeArrayKey(array &$array, $key) {
    if (array_key_exists($key, $array)) {
      $value = $array[$key];
      unset($array[$key]);
      return $value;
    } else {
      return null;
    }
  }

  /**
   * @param array $params
   * @return array
   */
  protected function sortParams(array $params) {
    $access_token = $this->removeArrayKey($params, 'access_token');
    $appsecret_proof = $this->removeArrayKey($params, 'appsecret_proof');
    $access_token !== null && $params['access_token'] = $access_token;
    $appsecret_proof !== null && $params['appsecret_proof'] = $appsecret_proof;

    return $params;
  }

  /**
   * @param string $level
   * @param RequestInterface $request
   * @param array $context
   */
  public function logRequest(
    $level, RequestInterface $request, array $context = array()) {

    $new_line = ' \\'.PHP_EOL.'  ';
    $method = $request->getMethod();
    $method_flag = static::getMethodFlag($method);
    $params = $this->sortParams(array_merge(
      $this->processParams($request->getQueryParams(), $method, false),
      $this->processParams($request->getBodyParams(), $method, false),
      $this->processParams($request->getFileParams(), $method, true)));

    $buffer = 'curl'.($method_flag ? ' -'.$method_flag : '');
    foreach ($params as $param) {
      $buffer .= $new_line.$param;
    }
    $buffer .= $new_line.$this->processUrl($request);

    $this->flush($buffer);
  }

  /**
   * @param string $level
   * @param ResponseInterface $response
   * @param array $context
   */
  public function logResponse(
    $level, ResponseInterface $response, array $context = array()) {
    // We only care about requests
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Logger;

use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;

interface LoggerInterface {

  /**
   * @param string $level
   * @param string $message
   * @param array $context
   */
  public function log($level, $message, array $context = array());

  /**
   * @param string $level
   * @param RequestInterface $request
   * @param array $context
   */
  public function logRequest(
    $level, RequestInterface $request, array $context = array());

  /**
   * @param string $level
   * @param ResponseInterface $response
   * @param array $context
   */
  public function logResponse(
    $level, ResponseInterface $response, array $context = array());
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Logger;

use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;

class NullLogger implements LoggerInterface {

  /**
   * @param string $level
   * @param string $message
   * @param array $context
   */
  public function log($level, $message, array $context = array()) {

  }

  /**
   * @param string $level
   * @param RequestInterface $request
   * @param array $context
   */
  public function logRequest(
    $level, RequestInterface $request, array $context = array()) {

  }

  /**
   * @param string $level
   * @param ResponseInterface $response
   * @param array $context
   */
  public function logResponse(
    $level, ResponseInterface $response, array $context = array()) {

  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Logger\CurlLogger;

use FacebookAds\Http\Parameters;

class JsonAwareParameters extends Parameters {

  /**
   * @param mixed $value
   * @return string
   */
  protected function exportNonScalar($value) {
    return JsonNode::factory($value)->encode();
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Logger\CurlLogger;

final class JsonNode {

  /**
   * @var int
   */
  const INDENT_UNIT = 2;

  /**
   * @var int
   */
  const EXPLOSION_THRESHOLD = 78;

  /**
   * @var mixed
   */
  protected $value;

  /**
   * @var \ArrayObject
   */
  protected $children;

  /**
   * @param mixed $value
   * @return $this
   * @throws \InvalidArgumentException
   */
  public static function factory($value) {
    $object = new self();
    switch (true) {
      case is_object($value):
        $value = (array) $value;
        // fallthrough
      case is_array($value):
        foreach ($value as $key => $sub) {
          $object->getChildren()->offsetSet($key, self::factory($sub));
        }
        // fallthrough
      case is_null($value) || is_scalar($value):
        $object->setValue($value);
        break;
      default:
        throw new \InvalidArgumentException(
          gettype($value).' can\'t be encoded');
    }

    return $object;
  }

  public function __construct() {
    $this->children = new \ArrayObject();
  }

  /**
   * @return mixed
   */
  public function getValue() {
    return $this->value;
  }

  /**
   * @param mixed $value
   * @return $this
   */
  public function setValue($value) {
    $this->value = $value;

    return $this;
  }

  /**
   * @return \ArrayObject
   */
  public function getChildren() {
    return $this->children;
  }

  /**
   * @return int
   */
  public function getMaxTreeChildrenCount() {
    $max = $this->getChildren()->count();

    /** @var JsonNode $child */
    foreach ($this->getChildren() as $child) {
      $ith = $child->getMaxTreeChildrenCount();
      $max = $ith > $max ? $ith : $max;
    }

    return $max;
  }

  /**
   * @param int $indent
   * @return string
   */
  protected function getPadding($indent) {
    return str_repeat(' ', $indent * self::INDENT_UNIT);
  }

  /**
   * @return mixed
   */
  protected function getLastChildKey() {
    if ($this->getChildren()->count() === 0) {
      return null;
    }

    $copy = $this->getChildren()->getArrayCopy();
    end($copy);

    return key($copy);
  }

  /**
   * @param int $indent
   * @return string
   */
  protected function encodeList($indent) {
    $value = $this->getValue();
    if (empty($value) || (array_keys($value) === range(0, count($value) - 1))) {
      $is_map = false;
    } else {
      $is_map = true;
    }

    ++$indent;
    $last_key = $this->getLastChildKey();

    $buffer = ($is_map ? '{' : '[')."\n";

    /** @var JsonNode $child */
    foreach ($this->getChildren() as $key => $child) {
      $buffer .= sprintf(
        "%s%s%s%s\n",
        $this->getPadding($indent),
        $is_map ? sprintf("%s: ", json_encode($key)) : '',
        $child->encode($indent),
        $key === $last_key ? '' : ',');
    }

    --$indent;
    $buffer .= $this->getPadding($indent).($is_map ? '}' : ']');

    return $buffer;
  }

  /**
   * @param int $indent
   * @return string
   */
  public function encode($indent = 0) {
    $value = $this->getValue();
    if (is_array($value) || is_object($value)) {
      if ($this->getMaxTreeChildrenCount() > 2) {
        return $this->encodeList($indent);
      }

      $ugly = json_encode($value);
      $output_prediction = $this->getPadding($indent).$ugly;
      if (strlen($output_prediction) > self::EXPLOSION_THRESHOLD) {
        return $this->encodeList($indent);
      }

      return $ugly;
    }

    return json_encode($value);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object;

use FacebookAds\Http\RequestInterface;

abstract class AbstractArchivableCrudObject extends AbstractCrudObject {

  /**
   * @var string
   */
  const STATUS_PARAM_NAME = 'status';

  /**
   * @var string
   */
  const STATUS_ACTIVE = 'ACTIVE';

  /**
   * @var string
   */
  const STATUS_PAUSED = 'PAUSED';

  /**
   * @var string
   */
  const STATUS_DELETED = 'DELETED';

  /**
   * @var string
   */
  const STATUS_ARCHIVED = 'ARCHIVED';

  /**
   * @return string
   */
  public function getStatusParamName() {
    return self::STATUS_PARAM_NAME;
  }

  /**
   * Archive this object
   *
   * @deprecated use api_update instead
   * @param array $params
   * @return void
   */
  public function archive(array $params = array()) {
    $this->getApi()->call(
      $this->getNodePath(),
      RequestInterface::METHOD_POST,
      array_merge($params, array(
        $this->getStatusParamName() => static::STATUS_ARCHIVED)));
  }

  /**
   * Delete this object
   *
   * @deprecated use api_update instead
   * @param array $params
   * @return void
   */
  public function delete(array $params = array()) {
    $this->getApi()->call(
      $this->getNodePath(),
      RequestInterface::METHOD_POST,
      array_merge($params, array(
        $this->getStatusParamName() => static::STATUS_DELETED)));
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */
namespace FacebookAds\Object;
use FacebookAds\ApiConfig;
use FacebookAds\TypeChecker;
use FacebookAds\Enum\EmptyEnum;
class AbstractObject {
  /**
   * @var mixed[] set of key value pairs representing data
   */
  protected $data = array();
  protected $_type_checker;

  public function __construct() {
    $this->data = static::getFieldsEnum()->getValuesMap();
    $this->_type_checker = new TypeChecker(
      static::getFieldTypes(), static::getReferencedEnums());
  }

  protected static function getFieldTypes() {
    $fields_enum = static::getFieldsEnum();
    if (method_exists($fields_enum, 'getFieldTypes')) {
      return $fields_enum->getFieldTypes();
    } else {
      return array();
    }
  }

  protected static function getReferencedEnums() {
    return array();
  }

  /**
   * @param string $name
   * @param mixed $value
   */
  public function __set($name, $value) {
    if (ApiConfig::TYPE_CHECKER_STRICT_MODE
      && $this->_type_checker->isValidParam($name)
    ) {
      if ($this->_type_checker->isValidParamPair($name, $value)) {
        $this->data[$name] = $value;
      } else {
        throw new \InvalidArgumentException(
          $name." and ".$this->exportValue($value)
          ." are not a valid type value pair");
      }
    } else {
      $this->data[$name] = $value;
    }
    return $this;
  }

  /**
   * @param string $name
   * @return mixed
   * @throws \InvalidArgumentException
   */
  public function __get($name) {
    if (array_key_exists($name, $this->data)) {
      return $this->data[$name];
    } else {
      throw new \InvalidArgumentException(
        $name.' is not a field of '.get_class($this));
    }
  }
  /**
   * @param string $name
   * @return boolean
   */
  public function __isset($name) {
    return array_key_exists($name, $this->data);
  }
  /**
   * @param array
   * @return $this
   */
  public function setData(array $data) {
    foreach ($data as $key => $value) {
      $this->{$key} = $value;
    }
    // Handle class-specific situations
    if (method_exists($this, 'setDataTrigger')) {
      $this->setDataTrigger($data);
    }

    return $this;
  }
  /**
   * Like setData but will skip field validation
   *
   * @param array
   * @return $this
   */
  public function setDataWithoutValidation(array $data) {
    foreach ($data as $key => $value) {
      $this->data[$key] = $value;
    }
    // Handle class-specific situations
    if (method_exists($this, 'setDataTrigger')) {
      $this->setDataTrigger($data);
    }
    return $this;
  }
  /**
   * @return array
   */
  public function getData() {
    return $this->data;
  }
  /**
   * @param mixed $value
   * @return mixed
   */
  protected function exportValue($value) {
    $result = $value;
    switch (true) {
      case $value === null:
        break;
      case $value instanceof AbstractObject:
        $result = $value->exportData();
        break;
      case is_array($value):
        $result = array();
        foreach ($value as $key => $sub_value) {
          if ($sub_value !== null) {
            $result[$key] = $this->exportValue($sub_value);
          }
        }
        break;
    }
    return $result;
  }
  /**
   * @return array
   */
  public function exportData() {
    return $this->exportValue($this->data);
  }
  /**
   * @return array
   */
  public function exportAllData() {
    return $this->exportValue($this->data);
  }
  /**
   * @return EmptyEnum
   */
  public static function getFieldsEnum() {
    return EmptyEnum::getInstance();
  }
  /**
   * @return array
   */
  public static function getFields() {
    return static::getFieldsEnum()->getValues();
  }
  /**
   * @return string
   */
  public static function className() {
    return get_called_class();
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object;

interface CanRedownloadInterface {

  /**
   * @string
   */
  const PARAM_REDOWNLOAD = 'redownload';
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object;

use FacebookAds\Object\Fields\ClickTrackingTagFields;
use FacebookAds\Http\RequestInterface;

class ClickTrackingTag extends AbstractCrudObject {

  /**
   * @deprecated getEndpoint function is deprecated
   * @return string
   */
  protected function getEndpoint() {
    return 'trackingtag';
  }

  /**
   * @return ClickTrackingTagFields
   */
  public static function getFieldsEnum() {
    return ClickTrackingTagFields::getInstance();
  }

  public function deleteSelf(array $params = array()) {
    $this->getApi()->call(
      '/'.$this->parentId.'/'.$this->getEndpoint(),
      RequestInterface::METHOD_DELETE,
      $params);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object;

use FacebookAds\Object\Fields\AdCreativeObjectStorySpecFields;
use FacebookAds\Object\Traits\FieldValidation;

/**
 * @deprecated use AdCreativeObjectStorySpec instead
 */
class ObjectStorySpec extends AdCreativeObjectStorySpec {
  use FieldValidation;

  /**
   * @return AdCreativeObjectStorySpecFields
   */
  public static function getFieldsEnum() {
    return AdCreativeObjectStorySpecFields::getInstance();
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object;

use FacebookAds\Http\RequestInterface;
use FacebookAds\Object\Fields\SystemUserFields;

class SystemUser extends AbstractCrudObject {

  /**
   * @deprecated getEndpoint function is deprecated
   * @return string
   */
  protected function getEndpoint() {
    return 'system_users';
  }

  /**
   * @return SystemUserFields
   */
  public static function getFieldsEnum() {
    return SystemUserFields::getInstance();
  }

  public function invalidateAccessTokens() {
    $this->getApi()->call(
      '/'.$this->assureId().'/access_tokens',
      RequestInterface::METHOD_DELETE);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object;

use FacebookAds\Api;
use FacebookAds\Cursor;
use FacebookAds\Http\RequestInterface;

class TargetingSearch extends AbstractObject {

  /**
   * @param string $query
   * @param string $type
   * @param string $class
   * @param array $params
   * @param Api $api
   * @return Cursor
   * @throws \InvalidArgumentException
   */
  public static function search(
    $type,
    $class=null,
    $query=null,
    array $params = array(),
    Api $api = null) {

    $api = $api ?: Api::instance();
    if (!$api) {
      throw new \InvalidArgumentException(
        'An Api instance must be provided as argument or '.
        'set as instance in the \FacebookAds\Api');
    }

    $params['type'] = $type;
    $params = array_merge($params, array_filter(array(
      'class' => $class,
      'q' => $query,
    )));

    $response = $api->call('/search', RequestInterface::METHOD_GET, $params);
    return new Cursor($response, new TargetingSearch());
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class BirthYearNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::BIRTH_YEAR;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return preg_replace('/[^0-9]/', '', $key_value);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class CityNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::CITY;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return preg_replace('/[^a-z]/', '', strtolower(trim($key_value)));
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class CountryNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::COUNTRY;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return substr(
      preg_replace('/[^a-z]/', '', strtolower(trim($key_value))),
      0,
      2);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class DateNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return in_array($key, array(
      CustomAudienceMultikeySchemaFields::BIRTH_DATE,
      CustomAudienceMultikeySchemaFields::BIRTH_MONTH
    ));
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return str_pad(
      preg_replace('/[^0-9]/', '', $key_value),
      2,
      '0',
      STR_PAD_LEFT);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class EmailNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::EMAIL;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return trim(strtolower($key_value), " \t\r\n\0\x0B.");
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class FirstNameInitialNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::FIRST_NAME_INITIAL;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return preg_replace(
      '/[^a-z]/',
      '',
      strtolower(trim($key_value)))[0];
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class FirstNameNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::FIRST_NAME;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return preg_replace('/[^a-z]/', '', strtolower(trim($key_value)));
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class GenderNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::GENDER;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return substr($key_value, 0, 1);
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;
use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;

class HashNormalizer implements ValueNormalizerInterface {

    /**
     *  @var string
     */
    const HASH_TYPE_SHA256 = 'sha256';

    /**
     * @param string $key
     * @param string $key_value
     * @return boolean
     */
    public function shouldNormalize($key, $key_value) {
        return $key !== CustomAudienceMultikeySchemaFields::LOOKALIKE_VALUE;
    }

    /**
     * @param string $key
     * @param string $key_value
     * @return string
     */
    public function normalize($key, $key_value) {
        return hash(self::HASH_TYPE_SHA256, $key_value);
    }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class LastNameNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::LAST_NAME;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return preg_replace('/[^a-z]/', '', strtolower(trim($key_value)));
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class MadidNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::MADID;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return strtolower(trim($key_value));
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class PhoneNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::PHONE;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return preg_replace('/[^0-9]/', '', trim($key_value));
  }
}


<?php
/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
 * use, copy, modify, and distribute this software in source code or binary
 * form for use in connection with the web services and APIs provided by
 * Facebook.
 *
 * As with any software that integrates with the Facebook platform, your use
 * of this software is subject to the Facebook Developer Principles and
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

namespace FacebookAds\Object\CustomAudienceNormalizers;

use FacebookAds\Object\Fields\CustomAudienceMultikeySchemaFields;
use FacebookAds\Object\CustomAudienceNormalizers\ValueNormalizerInterface;

class StateNormalizer implements ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $key_value) {
    return $key === CustomAudienceMultikeySchemaFields::STATE;
  }

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return preg_replace('/[^a-z]/', '', strtolower(trim($key_value)));
  }
}