<?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;

interface ValueNormalizerInterface {

  /**
   * @param string $key
   * @param string $key_value
   * @return boolean
   */
  public function shouldNormalize($key, $val);

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


<?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 ZipNormalizer implements ValueNormalizerInterface {

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

  /**
   * @param string $key
   * @param string $key_value
   * @return string
   */
  public function normalize($key, $key_value) {
    return explode(
      '-',
      preg_replace('/[ ]/', '', 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\Fields;

use FacebookAds\Enum\AbstractEnum;

abstract class AbstractArchivableCrudObjectFields extends AbstractEnum {

  const CONFIGURED_STATUS = 'configured_status';
  const EFFECTIVE_STATUS = 'effective_status';
}


<?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\Fields;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static AdVideoFields getInstance()
 */
class AdVideoFields extends AbstractEnum {

  const CREATED_TIME = 'created_time';
  const DESCRIPTION = 'description';
  const EMBED_HTML = 'embed_html';
  const EMBEDDABLE = 'embeddable';
  const FILE_URL = 'file_url';
  const FORMAT = 'format';
  const FROM = 'from';
  const ICON = 'icon';
  const ID = 'id';
  const IS_INSTAGRAM_ELIGIBLE = 'is_instagram_eligible';
  const NAME = 'name';
  const PICTURE = 'picture';
  const PUBLISHED = 'published';
  const SLIDESHOW_SPEC = 'slideshow_spec';
  const SOURCE = 'source';
  const THUMBNAILS = 'thumbnails';
  const UPDATED_TIME = 'updated_time';
}


<?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\Fields;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static ClickTrackingTagFields getInstance()
 */
class ClickTrackingTagFields extends AbstractEnum {

  const ID = 'id';
  const ADD_TEMPLATE_PARAM = 'add_template_param';
  const URL = 'url';
  const ADGROUP_ID = 'adgroup_id';
}


<?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\Fields;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static CustomAudienceMultikeySchemaFields getInstance()
 */
class CustomAudienceMultikeySchemaFields extends AbstractEnum {

  const EXTERN_ID = 'EXTERN_ID';
  const EMAIL = 'EMAIL';
  const PHONE = 'PHONE';
  const GENDER = 'GEN';
  const BIRTH_YEAR = 'DOBY';
  const BIRTH_MONTH = 'DOBM';
  const BIRTH_DATE = 'DOBD';
  const LAST_NAME = 'LN';
  const FIRST_NAME = 'FN';
  const FIRST_NAME_INITIAL = 'FI';
  const CITY = 'CT';
  const STATE = 'ST';
  const ZIP = 'ZIP';
  const MADID = 'MADID';
  const COUNTRY = 'COUNTRY';
  const FB_USER_ID = 'APPUID';
  const LOOKALIKE_VALUE = 'LOOKALIKE_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\Fields;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static SystemUserFields getInstance()
 */
class SystemUserFields extends AbstractEnum {

  const ID = 'id';
  const NAME = 'name';
  const PERMISSIONS = 'permissions';
  const ROLE = 'role';
}


<?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\Search;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static DemographicSearchClasses getInstance()
 */
class DemographicSearchClasses extends AbstractEnum {

  const LIFE_EVENTS = 'life_events';
  const POLITICS = 'politics';
  const MARKETS = 'markets';
  const INDUSTRIES = 'industries';
  const INCOME = 'income';
  const NET_WORTH = 'net_worth';
  const HOME_TYPE = 'home_type';
  const HOME_OWNERSHIP = 'home_ownership';
  const HOME_VALUE = 'home_value';
  const ETHNIC_AFFINITY = 'ethnic_affinity';
  const GENERATION = 'generation';
  const HOUSEHOLD_COMPOSITION = 'household_composition';
  const MOMS = 'moms';
  const OFFICE_TYPE = 'office_type';
  const FAMILY_STATUSES = 'family_statuses';
  const DEMOGRAPHICS = 'demographics';
}


<?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\Search;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static TargetingSearchTypes getInstance()
 */
class TargetingSearchTypes extends AbstractEnum {

  const COUNTRY = 'adcountry';
  const EDUCATION = 'adeducationschool';
  const EMPLOYER = 'adworkemployer';
  const GEOLOCATION = 'adgeolocation';
  const GEOLOCATIONMETA = 'adgeolocationmeta';
  const INTEREST = 'adinterest';
  const INTEREST_SUGGESTION = 'adinterestsuggestion';
  const INTEREST_VALIDATE = 'adinterestvalid';
  const KEYWORD = 'adkeyword';
  const LOCALE = 'adlocale';
  const MAJOR = 'adeducationmajor';
  const POSITION = 'adworkposition';
  const RADIUS_SUGGESTION = 'adradiussuggestion';
  const TARGETING_CATEGORY = 'adTargetingCategory';
  const ZIPCODE = 'adzipcode';
}


<?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\Traits;

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

/**
 * @method Api getApi()
 * @method string assureId()
 */
trait AdLabelAwareCrudObjectTrait {

  /**
   * Take ad label ids and format them correctly for the request
   * @param array $adlabel_ids
   * @return array
   */
  protected function formatParams(array $adlabel_ids) {
    foreach ($adlabel_ids as &$adlabel_id) {
      $adlabel_id = array('id' => $adlabel_id);
    }

    return array('adlabels' => $adlabel_ids);
  }

  /**
   * @deprecated use createAdLabel instead
   * @param array $ad_label_ids
   */
  public function addAdLabels(array $ad_label_ids) {
    $this->getApi()->call(
      '/'.$this->assureId().'/adlabels',
      RequestInterface::METHOD_POST,
      $this->formatParams($ad_label_ids));
  }

  /**
   * @deprecated use deleteAdLabels instead
   * @param array $ad_label_ids
   */
  public function removeAdLabels(array $ad_label_ids) {
    $this->getApi()->call(
      '/'.$this->assureId().'/adlabels',
      RequestInterface::METHOD_DELETE,
      $this->formatParams($ad_label_ids));
  }
}


<?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\Traits;

use FacebookAds\Enum\EnumInstanceInterface;

/**
 * @method static EnumInstanceInterface getFieldsEnum()
 */
trait FieldValidation {

  /**
   * @param string $name
   * @param mixed $value
   * @throws \InvalidArgumentException
   * @staticvar array $fields
   */
  public function __set($name, $value) {
    if (static::getFieldsEnum()->isValidValue($name)) {
      parent::__set($name, $value);
    } else {
      throw new \InvalidArgumentException(
        $name.' is not a field of '.get_class($this));
    }
  }
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static AppRoles getInstance()
 */
class AppRoles extends AbstractEnum {

  const ADMINISTRATOR  = 'ADMINISTRATOR';
  const DEVELOPER = 'DEVELOPER';
  const TESTER = 'TESTER';
  const INSIGHTS_USER = 'INSIGHTS_USER';
  const TEST_USER = 'TEST_USER';

}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

class ArchivableCrudObjectEffectiveStatuses extends AbstractEnum {

  const ACTIVE = 'ACTIVE';
  const AD_PAUSED = 'AD_PAUSED';
  const ADSET_PAUSED = 'ADSET_PAUSED';
  const ARCHIVED = 'ARCHIVED';
  const ARCHIVED_IN_DRAFT = 'ARCHIVED_IN_DRAFT';
  const CAMPAIGN_PAUSED = 'CAMPAIGN_PAUSED';
  const DELETED = 'DELETED';
  const DISAPPROVED = 'DISAPPROVED';
  const PAUSED = 'PAUSED';
  const PENDING = 'PENDING';
  const PENDING_BILLING_INFO = 'PENDING_BILLING_INFO';
  const PENDING_REVIEW = 'PENDING_REVIEW';
  const PREAPPROVED = 'PREAPPROVED';
}


<?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\Values;

/**
 * @deprecated use AdSetBillingEventValues instead
 *
 * @method static BillingEvents getInstance()
 */
class BillingEvents extends AdSetBillingEventValues {}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static BusinessRoles getInstance()
 */
class BusinessRoles extends AbstractEnum {

  const ADMIN  = 'ADMIN';
  const EMPLOYEE = 'EMPLOYEE';
  const OWNER = 'OWNER';
  const AGENCY = 'AGENCY';

}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static CampaignBuyingTypeValues getInstance()
 */
class CampaignBuyingTypeValues extends AbstractEnum {

  const AUCTION  = 'AUCTION';
  const RESERVED = 'RESERVED';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static ConnectionObjectTypes getInstance()
 */
class ConnectionObjectTypes extends AbstractEnum {

  const PAGE = 1;
  const APPLICATION = 2;
  const EVENT = 3;
  const PLACE = 6;
  const DOMAIN = 7;
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static CustomAudienceSubtypes getInstance()
 */
class CustomAudienceSubtypes extends AbstractEnum {

  const APP = 'APP';
  const APP_COMBINATION = 'APP_COMBINATION';
  const CUSTOM = 'CUSTOM';
  const LOOKALIKE = 'LOOKALIKE';
  const MANAGED = 'MANAGED';
  const PARTNER = 'PARTNER';
  const VIDEO = 'VIDEO';
  const WEBSITE = 'WEBSITE';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static CustomAudienceTypes getInstance()
 */
class CustomAudienceTypes extends AbstractEnum {

  /**
   * @var string
   */
  const ID = 'UID';

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

  /**
   * @var string
   */
  const EMAIL = 'EMAIL_SHA256';

  /**
   * @var string
   */
  const PHONE = 'PHONE_SHA256';

  /**
   * @var string
   */
  const MOBILE_ADVERTISER_ID = 'MOBILE_ADVERTISER_ID';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static FeedEncoding getInstance()
 */
class FeedEncoding extends AbstractEnum {

  const AUTODETECT  = 'AUTODETECT';
  const ASCII = 'ASCII';
  const UTF_8 = 'UTF_8';
  const UTF_16 = 'UTF_16';
  const LATIN_1 = 'LATIN_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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static InsightsIncrements getInstance()
 */
class InsightsIncrements extends AbstractEnum {

  const MONTHLY = 'monthly';
  const ALL_DAYS = 'all_days';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static InsightsOperators getInstance()
 */
class InsightsOperators extends AbstractEnum {

  const ALL = 'ALL';
  const ANY = 'ANY';
  const CONTAIN = 'CONTAIN';
  const EQUAL = 'EQUAL';
  const GREATER_THAN = 'GREATER_THAN';
  const GREATER_THAN_OR_EQUAL = 'GREATER_THAN_OR_EQUAL';
  const IN = 'IN';
  const IN_RANGE = 'IN_RANGE';
  const LESS_THAN = 'LESS_THAN';
  const LESS_THAN_OR_EQUAL = 'LESS_THAN_OR_EQUAL';
  const NONE = 'NONE';
  const NOT_CONTAIN = 'NOT_CONTAIN';
  const NOT_EQUAL = 'NOT_EQUAL';
  const NOT_IN = 'NOT_IN';
  const NOT_IN_RANGE = 'NOT_IN_RANGE';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static PageRoles getInstance()
 */
class PageRoles extends AbstractEnum {

  const ADVERTISER  = 'ADVERTISER';
  const CONTENT_CREATOR = 'CONTENT_CREATOR';
  const MANAGER = 'MANAGER';
  const MODERATOR = 'MODERATOR';
  const INSIGHTS_ANALYST = 'INSIGHTS_ANALYST';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @deprecated page_types are read-only in v2.7 and to be removed in v2.8
 * @method static PageTypes getInstance()
 */
class PageTypes extends AbstractEnum {

  const DESKTOP_FEED = 'desktopfeed';
  const HOME = 'home';
  const INSTAGRAM_STREAM = 'instagramstream';
  const LEGACY_EXTERNAL = 'legacyexternal';
  const LOGOUT = 'logout';
  const MOBILE_EXTERNAL = 'mobileexternal';
  const MOBILE_FEED = 'mobilefeed';
  const RIGHT_COLUMN = 'rightcolumn';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static ReachFrequencyPredictionStatuses getInstance()
 */
class ReachFrequencyPredictionStatuses extends AbstractEnum {

  const SUCCESS = 1;
  const PENDING = 2;
  const UNREACHABLE_AUDIENCE = 3;
  const CONFIG_INVALID = 4;
  const TARGET_SPEC_INVALID = 5;
  const BUDGET_TOO_LOW = 6;
  const TOO_SHORT_AD_SET_LENGTH = 7;
  const TOO_LONG_AD_SET_LENGTH = 8;
  const END_DATE_TOO_FAR = 9;
  const FREQUENCY_CAP_NOT_SPECIFIED = 10;
  const UNSUPPORTED_PLACEMENT = 11;
  const DATE_ERROR = 12;
  const COUNTRY_NOT_SUPPORTED = 13;
  const BLACKOUT_DAYS = 14;
  const INSUFFICIENT_INVENTORY = 15;
  const REACH_BELOW_1_MILLION = 16;
  const MINIMUM_REACH_NOT_AVAILABLE = 17;
  const INVENTORY_CHANGED = 21;
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static TermsOfService getInstance()
 */
class TermsOfService extends AbstractEnum {

  const CUSTOM_AUDIENCE  = 'custom_audience';
  const WEBSITE_CUSTOM_AUDIENCE = 'website_custom_audience';
  const MOBILE_APP_CUSTOM_AUDIENCE = 'mobile_app_custom_audience';
}


<?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\Values;

use FacebookAds\Enum\AbstractEnum;

/**
 * @method static UserPermissionRoles getInstance()
 */
class UserPermissionRoles extends AbstractEnum {

  const ADMIN  = 'ADMIN';
  const EMPLOYEE  = 'EMPLOYEE';
}


<?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.
 *
 */

return array(

  /**
   * @var string Numeric Facebook app id, espressed as string
   */
  'app_id' => '',

  /**
   * @var string App Secret
   * @see https://developers.facebook.com/apps/<APP_ID>/dashboard/
   */
  'app_secret' => '',

  /**
   * @var string User Access Token
   * @see https://developers.facebook.com/docs/facebook-login/access-tokens/
   */
  'access_token' => '',

  /**
   * @var string Numeric Facebook Business Manager id, espressed as string
   */
  'business_id' => '',

  /**
   * @var string Numeric Facebook id, preceded by 'act_', espressed as string
   * @see https://www.facebook.com/ads/manage/home/
   */
  'act_id' => '',

  /**
   * @var string PHP timezone compatible with the AdAccount timezone, override php.ini config
   * @see http://php.net/manual/en/timezones.php
   */
  'act_timezone' => '',

  /**
   * @var string Numeric Facebook id, espressed as string
   * @see https://www.facebook.com/ads/manage/home/
   */
  'page_id' => '',

  /**
   * @var string Url of your app [Stream post URL security]
   *             Example: 'http://my.domain.com/'
   * @see https://developers.facebook.com/docs/facebook-login/security/#surfacearea
   */
  'app_url' => '',

  /**
   * @var string Numeric Instagram actor id, espressed as string
   */
  'instagram_actor_id' => '',

  // OPTIONAL INTEGRATION TESTS

  'skip_if' => array(

    /**
     * @var bool Skip tests that require an business manager
     * @see https://developers.facebook.com/docs/marketing-api/businessmanager/
     */
    'no_business_manager' => true,

    /**
     * @var bool Skip tests that require an account with a valid payment method
     * @see https://secure.facebook.com/ads/manage/funding.php
     */
    'no_payment_method' => true,

    /**
     * @var bool Skip tests that require parnet categories whitelisting
     * @see https://developers.facebook.com/docs/reference/ads-api/partnercategories
     */
    'no_partner_categories' => true,

    /**
     * @var bool Skip tests that require video upload
     */
    'no_video_upload' => true,

    /**
     * @var bool Skip tests that require reach and frequency whitelisting
     */
    'no_reach_and_frequency_whitelist' => true,

    /**
     * @var bool Skip tests that require polling for async jobs execution
     */
    'no_async_jobs' => true,

    /**
     * @var bool Skip tests that require an instagram actor
     */
    'no_instagram' => true,
  ),

  // OPTIONAL CONFIGURATIONS

  /**
   * @var string Override Facebook graph domain
   *             Example: try hitting beta.facebook.com
   */
  'graph_base_domain' => '',

  /**
   * @var string Disable SSL verification between CA and host
   *             [Security] Do not change this unless you trust your network
   */
  'skip_ssl_verification' => false,

  /**
   * @var string Filepath to which cUrl shell equivalents will be dumped
   *             Tip: access std streams with 'php://stdout' or 'php://stderr'
   */
  'curl_logger' => '',

  // OPTIONAL SECONDARY ENTITIES
  // Do not set the same as primary. May incurr in lost permissions.

  /**
   * @var string Ausiliary Business ID for permissions and sharing testing
   */
  'secondary_business_id' => '',

  /**
   * @var string Ausiliary Account ID for permissions and sharing testing
   */
  'secondary_account_id' => '',

  /**
   * @var string Ausiliary Page ID for permissions and sharing testing
   */
  'secondary_page_id' => '',

  /**
   * @var string Ausiliary Page ID for permissions and sharing testing
   */
  'secondary_app_id' => '',
);


<?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 FacebookAdsTest\Bootstrap;

error_reporting(E_ALL | E_STRICT);
if (!ini_get('date.timezone')) {
  ini_set('date.timezone', 'UTC');
}

require_once __DIR__.'/FacebookAdsTest/Bootstrap/Bootstrap.php';
require_once __DIR__.'/FacebookAdsTest/Bootstrap/IntegrationBootstrap.php';

$bootstrap = new IntegrationBootstrap();
$bootstrap->init();

return $bootstrap;


<?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 FacebookAdsTest\Bootstrap;

error_reporting(E_ALL | E_STRICT);
if (!ini_get('date.timezone')) {
  ini_set('date.timezone', 'UTC');
}
require_once __DIR__.'/FacebookAdsTest/Bootstrap/Bootstrap.php';

$bootstrap = new Bootstrap();
$bootstrap->init();

return $bootstrap;


<?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 FacebookAdsTest;

use FacebookAds\Api;
use FacebookAds\Http\Adapter\CurlAdapter;
use FacebookAds\Http\Client;
use FacebookAds\Http\Exception\RequestException;
use FacebookAds\Logger\CurlLogger;
use FacebookAds\Logger\LoggerInterface;
use FacebookAds\Logger\NullLogger;
use FacebookAds\Session;
use FacebookAdsTest\Exception\PHPUnitRequestExceptionWrapper;

/**
 * Base class for the integration test cases.
 * Provide Network services.
 */
class AbstractIntegrationTestCase extends AbstractTestCase {

  /**
   * @var LoggerInterface
   */
  protected $logger;

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

  /**
   * @var Session
   */
  protected $session;

  /**
   * @var Api
   */
  protected $api;

  /**
   * @return LoggerInterface
   */
  public function getLogger() {
    return $this->logger;
  }

  /**
   * @return Session
   */
  public function getSession() {
    return $this->session;
  }

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

  /**
   * @return Api
   */
  public function getApi() {
    return $this->api;
  }

  protected function setupSession() {
    $this->session = new Session(
      $this->getConfig()->appId,
      $this->getConfig()->appSecret,
      $this->getConfig()->accessToken);
  }

  protected function setupHttpClient() {
    $this->httpClient = new Client();
    if ($this->getConfig()->graphBaseDomain) {
      $this->httpClient->setDefaultGraphBaseDomain(
        $this->getConfig()->graphBaseDomain);
    }
    if ($this->getConfig()->skipSslVerification) {
      /** @var CurlAdapter $adapter */
      $adapter = $this->httpClient->getAdapter();
      $adapter->getOpts()->offsetSet(CURLOPT_SSL_VERIFYHOST, false);
      $adapter->getOpts()->offsetSet(CURLOPT_SSL_VERIFYPEER, false);
    }
  }

  protected function setupLogger() {
    $this->logger = $this->getConfig()->curlLogger
      ? new CurlLogger(fopen($this->getConfig()->curlLogger, "a"))
      : new NullLogger();
  }

  protected function setupApi() {
    $this->api = new Api(
      $this->getHttpClient(),
      $this->getSession());

    $this->api->setLogger($this->getLogger());

    Api::setInstance($this->api);
  }

  public function setup() : void {
    parent::setup();

    $this->getSkippableFeaturesManager()->enforceSkipTest($this);

    $this->setupLogger();
    $this->setupSession();
    $this->setupHttpClient();
    $this->setupApi();
  }

  public function tearDown() : void {
    $this->api = null;
    $this->httpClient = null;
    $this->session = null;
    $this->logger = null;

    parent::tearDown();
  }

  /**
   * This method is called when a test method did not execute successfully.
   *
   * @param \Throwable $e
   * @throws \Throwable
   */
  protected function onNotSuccessfulTest(\Throwable $e) : void {
    if ($e instanceof RequestException) {
      throw new PHPUnitRequestExceptionWrapper($e);
    } else {
      throw $e;
    }
  }
}


<?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 FacebookAdsTest;

use FacebookAdsTest\Config\Config;
use FacebookAdsTest\Config\SkippableFeaturesManager;
use \PHPUnit_Framework_MockObject_Builder_InvocationMocker as Mock;
use PHPUnit\Framework\TestCase;

/**
 * Base class for the unit test cases, providing the functions for AdsAPI
 * initialization etc.
 */
class AbstractTestCase extends TestCase {

  /**
   * @return SkippableFeaturesManager
   */
  public function getSkippableFeaturesManager() {
    return SkippableFeaturesManager::instance();
  }

  /**
   * @param string $key
   * @return bool
   */
  public function shouldSkipTest($key) {
    return $this->getSkippableFeaturesManager()->isSkipKey($key);
  }

  public function skipIf($key) {
    if ($this->shouldSkipTest($key)) {
      $this->markTestSkipped();
    }
  }

  /**
   * @return Config
   */
  public function getConfig() {
    return Config::instance();
  }

  /**
   * @return string
   * @deprecated use getConfig()
   */
  public function getTestRunId() {
    return $this->getConfig()->testRunId;
  }

  /**
   * @return string
   * @deprecated use getConfig()
   */
  public function getTestImagePath() {
    return $this->getConfig()->testImagePath;
  }

  /**
   * @return string
   * @deprecated use getConfig()
   */
  public function getTestZippedImagesPath() {
    return $this->getConfig()->testZippedImagesPath;
  }

  /**
   * @return string
   * @deprecated use getConfig()
   */
  public function getTestVideoPath() {
    return $this->getConfig()->testVideoPath;
  }

  /**
   * @param mixed $mock
   * @param array $data
   */
  protected function makeMockIterable(
    $mock, array $data = array()) {

    /** @var Mock $mock */
    $mock->method('count')->willReturn(count($data));
    $mock->method('getIterator')->willReturn(new \ArrayIterator($data));
    $mock->method('getArrayCopy')->willReturn($data);
    $mock->method('export')->willReturn($data);
  }

  /**
   * @param \Closure $closure
   * @param string $fqn
   */
  protected function assertWillThrow(
    \Closure $closure,
    $fqn = 'Exception') {

    try {
      call_user_func($closure);
    } catch (\Exception $e) {
      $this->assertTrue(
        is_a($e, $fqn),
        'Expected exception of type '.$fqn.': '.get_class($e).' received');

      return;
    }

    $this->fail('Expected exception didn\'t throw: '.$fqn);
  }
}


<?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 FacebookAdsTest;

use FacebookAds\Http\Adapter\AdapterInterface;
use FacebookAds\Http\Adapter\Curl\CurlInterface;
use FacebookAds\Http\Client;
use FacebookAds\Http\Headers;
use FacebookAds\Http\Parameters;
use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;
use FacebookAds\Logger\LoggerInterface;
use FacebookAds\Session;
use PHPUnit_Framework_MockObject_Builder_InvocationMocker as Mocker;
use PHPUnit_Framework_MockObject_MockObject as Mock;

/**
 * @method Mocker|Mock getMock($fqn, $methods = array(), $arguments = array())
 */
abstract class AbstractUnitTestCase extends AbstractTestCase {

  /**
   * @var string
   */
  const FQN_ADAPTER_INTERFACE = '\FacebookAds\Http\Adapter\AdapterInterface';

  /**
   * @var string
   */
  const FQN_CLIENT = '\FacebookAds\Http\Client';

  /**
   * @var string
   */
  const FQN_CURL_INTERFACE = '\FacebookAds\Http\Adapter\Curl\CurlInterface';

  /**
   * @var string
   */
  const FQN_HEADERS = '\FacebookAds\Http\Headers';

  /**
   * @var string
   */
  const FQN_LOGGER_INTERFACE = '\FacebookAds\Logger\LoggerInterface';

  /**
   * @var string
   */
  const FQN_PARAMETERS = '\FacebookAds\Http\Parameters';

  /**
   * @var string
   */
  const FQN_JSON_AWARE_PARAMETERS
    = '\FacebookAds\Logger\CurlLogger\JsonAwareParameters';

  /**
   * @var string
   */
  const FQN_REQUEST_INTERFACE = '\FacebookAds\Http\RequestInterface';

  /**
   * @var string
   */
  const FQN_RESPONSE_INTERFACE = '\FacebookAds\Http\ResponseInterface';

  /**
   * @var string
   */
  const FQN_SESSION = '\FacebookAds\Session';

  /**
   * @var string
   */
  const VALUE_SESSION_APP_ID = '<APP_ID>';

  /**
   * @var string
   */
  const VALUE_SESSION_APP_SECRET = '<APP_SECRET>';

  /**
   * @var string
   */
  const VALUE_SESSION_ACCESS_TOKEN = '<ACCESS_TOKEN>';

  /**
   * @return Mocker|Mock|ResponseInterface
   */
  protected function createResponseMock() {
    return $this->createMock(static::FQN_RESPONSE_INTERFACE);
  }

  /**
   * @return Mocker|Mock|Client
   */
  protected function createClientMock() {
    return $this->createMock(static::FQN_CLIENT);
  }

  /**
   * @return Mocker|Mock|CurlInterface
   */
  protected function createCurlMock() {
    return $this->createMock(static::FQN_CURL_INTERFACE);
  }

  /**
   * @return Mocker|Mock|Headers
   */
  protected function createHeadersMock() {
    return $this->createMock(static::FQN_HEADERS);
  }

  /**
   * @return Mocker|Mock|LoggerInterface
   */
  protected function createLoggerMock() {
    return $this->createMock(static::FQN_LOGGER_INTERFACE);
  }

  /**
   * @return Mocker|Mock|Parameters
   */
  protected function createParametersMock() {
    return $this->createMock(static::FQN_PARAMETERS);
  }

  /**
   * @return Mocker|Mock|Parameters
   */
  protected function createJsonAwareParametersMock() {
    return $this->createMock(static::FQN_JSON_AWARE_PARAMETERS);
  }

  /**
   * @return Mocker|Mock|RequestInterface
   */
  protected function createRequestMock() {
    return $this->createMock(static::FQN_REQUEST_INTERFACE);
  }

  /**
   * @return Mocker|Mock|AdapterInterface
   */
  protected function createAdapterMock() {
    return $this->createMock(static::FQN_ADAPTER_INTERFACE);
  }

  /**
   * @return Mocker|Mock|Session
   */
  protected function createSessionMock() {
    return $this->getMockBuilder(static::FQN_SESSION)
                ->setConstructorArgs(array(
                  static::VALUE_SESSION_APP_ID,
                  static::VALUE_SESSION_APP_SECRET,
                  static::VALUE_SESSION_ACCESS_TOKEN,
                ))
                ->getMock();
  }
}


<?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 FacebookAdsTest;

use FacebookAds\Api;
use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;
use FacebookAds\Logger\NullLogger;

class ApiTest extends AbstractUnitTestCase {

  /**
   * @return Api
   */
  protected function createApi() {
    return new Api($this->createClientMock(), $this->createSessionMock());
  }

  public function testInstance() {
    $this->assertNull(Api::instance());

    $api = $this->createApi();
    Api::setInstance($api);
    $this->assertTrue($api === Api::instance());

    $newApi = $this->createApi();
    Api::setInstance($newApi);
    $this->assertTrue($newApi === Api::instance());
    $this->assertFalse($api === Api::instance());
  }

  public function testInit() {
    $api = Api::init(
      static::VALUE_SESSION_APP_ID,
      static::VALUE_SESSION_APP_SECRET,
      static::VALUE_SESSION_ACCESS_TOKEN,
      false
    );
    $this->assertTrue($api instanceof Api);
    $this->assertTrue($api === Api::instance());
    $this->assertEquals(
      static::VALUE_SESSION_APP_ID, $api->getSession()->getAppId());
    $this->assertEquals(
      static::VALUE_SESSION_APP_SECRET, $api->getSession()->getAppSecret());
    $this->assertEquals(
      static::VALUE_SESSION_ACCESS_TOKEN, $api->getSession()->getAccessToken());
  }

  public function testGetters() {
    $client = $this->createClientMock();
    $session = $this->createSessionMock();
    $api = new Api($client, $session);
    $this->assertTrue($api->getHttpClient() === $client);
    $this->assertTrue($api->getSession() === $session);
  }

  public function testLogger() {
    $api = $this->createApi();
    $logger = $this->createLoggerMock();
    $api->setLogger($logger);
    $this->assertTrue($logger === $api->getLogger());

    // Test default
    $api = $this->createApi();
    $this->assertTrue($api->getLogger() instanceof NullLogger);
  }

  public function testDefaultGraphVersion() {
    $api = $this->createApi();
    $api->setDefaultGraphVersion('<VERSION>');
    $this->assertEquals('<VERSION>', $api->getDefaultGraphVersion());

    // Test default
    $api = $this->createApi();
    $this->assertTrue(is_string($api->getDefaultGraphVersion()));
    $this->assertRegExp('/^\d+\.\d+$/', $api->getDefaultGraphVersion());
  }

  public function testCall() {
    $request = $this->createRequestMock();
    $request->method('execute')->willReturn($this->createResponseMock());
    $request->method('getQueryParams')
      ->willReturn($this->createParametersMock());
    $request->method('getBodyParams')
      ->willReturn($this->createParametersMock());
    $request->expects($this->exactly(2))->method('setMethod')
      ->with($this->logicalOr(
        RequestInterface::METHOD_GET,
        RequestInterface::METHOD_POST));
    $request->expects($this->exactly(2))->method('setGraphVersion')
      ->with($this->equalTo($this->createApi()->getDefaultGraphVersion()));
    $request->expects($this->exactly(2))->method('setPath')
      ->with($this->equalTo('/<PATH>'));

    $client = $this->createClientMock();
    $client->method('createRequest')->willReturn($request);

    $session = $this->createSessionMock();
    $session->method('getAppSecretProof')->willReturn('<APP_SECRET_PROOF>');
    $session->method('getRequestParameters')->willReturn([]);

    $logger = $this->createLoggerMock();
    $logger->expects($this->exactly(2))->method('logRequest');
    $logger->expects($this->exactly(2))->method('logResponse');

    $api = new Api($client, $session);
    $api->setLogger($logger);

    // HTTP GET request
    $request->expects($this->exactly(1))->method('getQueryParams');

    $response = $api->call('/<PATH>');
    $this->assertTrue($response instanceof ResponseInterface);

    // HTTP POST request
    $request->expects($this->exactly(1))->method('getBodyParams');

    $api->call(
      '/<PATH>', RequestInterface::METHOD_POST, array('param' => 'value'));
    $this->assertTrue($response instanceof ResponseInterface);
  }

  public function testBase64UrlEncode() {
    $this->assertEquals('MTIzNDU', Api::base64UrlEncode('12345'));
  }
}


<?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 FacebookAdsTest;

use FacebookAds\Cursor;

class CursorDegradationTest extends CursorTest {

  /**
   * @return string
   */
  protected function getUniquePageId() {
    return (string) (microtime(true) * 1000000);
  }

  /**
   * @return array
   */
  protected function createSampleResponseContent() {
    $url_fmt = $this->createUnparameterizedUrl()
      .'?offset=%s';

    $content = parent::createSampleResponseContent();
    $content['paging'] = array(
      'next' => sprintf($url_fmt, $this->getUniquePageId()),
      'previous' => sprintf($url_fmt, $this->getUniquePageId()),
    );

    return $content;
  }

  public function testRequestParamReset() {
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);
    $params = $cursor->getLastResponse()->getRequest()->getQueryParams();
    $params->offsetSet('offset', $this->getUniquePageId());

    $cursor->fetchAfter();
    $params2 = $cursor->getLastResponse()->getRequest()->getQueryParams();

    $this->assertNotEquals(
      $params->offsetGet('offset'), $params2->offsetGet('offset'));
  }

  public function testGetters() {
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);

    $this->assertTrue($response === $cursor->getResponse());
    $this->assertTrue($response === $cursor->getLastResponse());
    $this->assertNull($cursor->getAfter());
    $this->assertNull($cursor->getBefore());
  }
}


<?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 FacebookAdsTest;

use FacebookAds\Http\Client;
use FacebookAds\Http\Parameters;
use FacebookAds\Http\Request;
use FacebookAds\Http\RequestInterface;
use FacebookAds\Http\ResponseInterface;
use FacebookAds\Object\AbstractCrudObject;
use FacebookAds\Object\AbstractObject;
use FacebookAds\Cursor;
use FacebookAdsTest\Object\EmptyObject;
use \PHPUnit_Framework_MockObject_Builder_InvocationMocker as Mock;

class CursorTest extends AbstractUnitTestCase {
  /**
   * @var EmptyObject
   */
  protected $objectPrototype;

  /**
   * @return array
   */
  protected function createEmptyResponseContent() {
    return array('data' => array());
  }

  /**
   * @return string
   */
  protected function getUniquePageId() {
    return uniqid();
  }

  /**
   * @return array
   */
  protected function createSampleResponseContent() {
    $content = array(
      'paging' => array(
        'cursors' => array(
          'after' => $this->getUniquePageId(),
          'before' => $this->getUniquePageId(),
        ),
      ),
    ) + $this->createEmptyResponseContent();

    $count = rand(2, 5);
    for ($i = 0; $i < $count; $i++) {
      $content['data'][] = array(
        AbstractCrudObject::FIELD_ID => $i,
      );
    }

    return $content;
  }

  /**
   * @return string
   */
  protected function createUnparameterizedUrl() {
    return Request::PROTOCOL_HTTPS
      .Client::DEFAULT_LAST_LEVEL_DOMAIN
      .'.'.Client::DEFAULT_GRAPH_BASE_DOMAIN
      .'/node/edge';
  }

  /**
   * @param int $num_pages
   * @param RequestInterface|null $prev
   * @return Mock|ResponseInterface
   */
  protected function createResponseChainMock(
    $num_pages, RequestInterface $prev = null) {

    $query_params = $prev ? clone $prev->getQueryParams() : new Parameters();
    $sample_content = $this->createSampleResponseContent();

    $request = $this->createRequestMock();
    $request->method('getMethod')->willReturn(RequestInterface::METHOD_GET);
    $request->method('getQueryParams')->willReturn($query_params);

    $response = $this->createResponseMock();
    $response->method('getRequest')->willReturn($request);

    $request->method('execute')->willReturn($response);

    $callback = function() use ($num_pages, $sample_content) {
      return $num_pages > 0
        ? $sample_content
        : $this->createEmptyResponseContent();
    };

    $clone_callback = function() use ($num_pages, $request) {
      return $this->createResponseChainMock(
        $num_pages - 1, $request)->getRequest();
    };

    $url_callback = function() use ($query_params) {
      return $this->createUnparameterizedUrl().'?'
        .http_build_query($query_params->getArrayCopy());
    };

    $response->method('getContent')->willReturnCallback($callback);
    $request->method('createClone')->willReturnCallback($clone_callback);
    $request->method('getUrl')->willReturnCallback($url_callback);

    return $response;
  }

  /**
   * @return Mock|ResponseInterface
   */
  protected function createEmptyResponseMock() {
    $response = $this->createResponseMock();
    $response->method('getContent')->willReturn(array(
      'data' => array(),
    ));

    return $response;
  }

  public function setup(): void {
    parent::setup();
    $this->objectPrototype = new EmptyObject();
  }

  public function tearDown(): void {
    $this->objectPrototype = null;
    parent::tearDown();
  }

  public function testGetters() {
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);

    $this->assertTrue($response === $cursor->getResponse());
    $this->assertTrue($response === $cursor->getLastResponse());
    $this->assertTrue(is_string($cursor->getAfter()));
    $this->assertTrue(is_string($cursor->getBefore()));
    $this->assertNotEquals($cursor->getBefore(), $cursor->getAfter());
  }

  /**
   * @return array
   */
  public function responseDataStructureProvider() {
    return array(
      array(array()),
      array(array('data' => null)),
      array(array('data' => 1)),
    );
  }

  /**
   * @dataProvider responseDataStructureProvider
   * @param mixed $content
   */
  public function testResponseDataStructure($content) {
    $response = $this->createResponseMock();
    $response->method('getContent')->willReturn($content);

    $this->expectException(\InvalidArgumentException::class);

    new Cursor($response, $this->objectPrototype);
  }

  public function testIterator() {
    $cursor = new Cursor(
      $this->createResponseChainMock(1), $this->objectPrototype);

    $this->assertTrue($cursor instanceof \Iterator);

    $k = 0;

    foreach ($cursor as $key => $value) {
      if ($key != $k) {
        $this->fail('iteration count missmatch $key');
      }
      ++$k;
    }

    $this->assertEquals($k, count($cursor));

    $cursor->rewind();

    $this->assertEquals(0, $cursor->key());
    $cursor->next();
    $this->assertEquals(1, $cursor->key());
    $cursor->prev();
    $this->assertEquals(0, $cursor->key());

    $this->assertEquals($cursor->getIndexLeft(), 0);
    $this->assertEquals($cursor->getIndexRight(), count($cursor) - 1);
  }

  public function testCountable() {
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);

    $this->assertTrue($cursor instanceof \Countable);
    $this->assertEquals($cursor->count(), count($cursor));
    $this->assertEquals(
      $cursor->count(), count($response->getContent()['data']));
  }

  public function testArrayAccess() {
    $response = $this->createResponseChainMock(1);
    $test_index = rand(1, count($response->getContent()) - 1);

    $cursor = new Cursor($response, $this->objectPrototype);

    $this->assertTrue($cursor instanceof \arrayaccess);

    $subject = new EmptyObject();
    $subject->setData($response->getContent()['data'][$test_index]);

    // Checking offsetGet
    $this->assertEquals($cursor[$test_index]->getData(), $subject->getData());
    // Checking offsetExists
    $this->assertFalse(isset($cursor[count($cursor)]));
    // Checking offsetUnset
    unset($cursor[$test_index]);
    $this->assertNull($cursor[$test_index]);
    // Checking offsetSet
    $cursor->offsetSet($test_index, $subject);
    $this->assertEquals($cursor[$test_index]->getData(), $subject->getData());
    // Checking offsetSet - append
    $count = count($cursor);
    $cursor->offsetSet(null, new EmptyObject());
    $this->assertEquals(count($cursor), $count + 1);
  }

  public function testUnneededFetch() {
    $response = $this->createEmptyResponseMock();
    $cursor = new Cursor($response, $this->objectPrototype);
    $this->assertNull($cursor->createBeforeRequest());
    $this->assertNull($cursor->createAfterRequest());

    // Reset for proper fetching
    $response = $this->createEmptyResponseMock();
    $cursor = new Cursor($response, $this->objectPrototype);
    $length = $cursor->count();
    $cursor->fetchBefore();
    $this->assertEquals($length, $cursor->count());
    $cursor->fetchAfter();
    $this->assertEquals($length, $cursor->count());
  }

  public function testIterability() {
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);

    $cursor->next();
    $cursor->rewind();
    $this->assertEquals($cursor->getIndexLeft(), $cursor->key());

    $cursor->end();
    $this->assertEquals($cursor->getIndexRight(), $cursor->key());

    $index = rand($cursor->getIndexLeft(), $cursor->getIndexRight());
    $cursor->seekTo($index);
    $this->assertEquals($index, $cursor->key());

    // Fetch after
    $cursor = new Cursor($response, $this->objectPrototype);
    $cursor->fetchAfter();
    $this->assertFalse($response === $cursor->getLastResponse());
  }

  public function testRequestParamReset() {
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);
    $params = $cursor->getLastResponse()->getRequest()->getQueryParams();
    $params->offsetSet('after', $this->getUniquePageId());
    $params->offsetSet('before', $this->getUniquePageId());

    $cursor->fetchAfter();
    $params2 = $cursor->getLastResponse()->getRequest()->getQueryParams();
    $this->assertNotEquals(
      $params->offsetGet('after'), $params2->offsetGet('after'));
  }

  public function testImplicitFetch() {
    // Test setters/getters
    $response = $this->createEmptyResponseMock();
    $cursor = new Cursor($response, $this->objectPrototype);

    $this->assertFalse(Cursor::getDefaultUseImplicitFetch());
    $this->assertFalse($cursor->getUseImplicitFetch());
    $cursor->setUseImplicitFetch(true);
    $this->assertTrue($cursor->getUseImplicitFetch());

    Cursor::setDefaultUseImplicitFetch(true);

    $response = $this->createEmptyResponseMock();
    $cursor = new Cursor($response, $this->objectPrototype);
    $this->assertTrue(Cursor::getDefaultUseImplicitFetch());
    $this->assertTrue($cursor->getUseImplicitFetch());

    // Test ordered iteration
    // f() lower interval * min repetition > upper interval
    // Min repetition > upper interval / lower interval -> f(x): x > 5 / 2 -> 3
    $response = $this->createResponseChainMock(3);
    $cursor = new Cursor($response, $this->objectPrototype);
    while ($cursor->valid()) {
      $cursor->next();
    }

    // Min upper boundary = upper interval + 1 = 5 + 1 = 6
    $this->assertGreaterThanOrEqual(6, $cursor->count());

    // Test rervese iteration
    // same f()
    $response = $this->createResponseChainMock(3);
    $cursor = new Cursor($response, $this->objectPrototype);

    $count = 0;
    while ($cursor->valid()) {
      $cursor->prev();
    }

    $this->assertGreaterThanOrEqual(6, $cursor->count());

    // Force the array out of boundaries
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);
    $cursor->setUseImplicitFetch(false);
    $cursor->prev();

    // Restore static behaviour
    Cursor::setDefaultUseImplicitFetch(false);
  }

  public function testExportability() {
    $response = $this->createResponseChainMock(1);
    $cursor = new Cursor($response, $this->objectPrototype);
    $array_copy = $cursor->getArrayCopy();

    $this->assertTrue(is_array($array_copy));
    $this->assertEquals($cursor->getArrayCopy(), $cursor->getObjects());
    $this->assertEquals(
      count($array_copy), count($response->getContent()['data']));

    foreach ($array_copy as $object) {
      if (!$object instanceof AbstractObject) {
        $this->fail("Wrong instance in array copy");
      }
    }

    $cursor->fetchAfter();
    $cursor->fetchBefore();

    $index = $cursor->getIndexLeft();
    // Test in-memory order while exporting
    foreach ($cursor->getArrayCopy(true) as $key => $object) {
      if ($key < $index) {
        $this->fail("Wrong order in sorted array copy");
      }
    }
  }
}


<?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 FacebookAdsTest;

use FacebookAds\Session;

class SessionTest extends AbstractUnitTestCase {

  /**
   * @return Session
   */
  protected function createSession() {
    return new Session(
      static::VALUE_SESSION_APP_ID,
      static::VALUE_SESSION_APP_SECRET,
      static::VALUE_SESSION_ACCESS_TOKEN);
  }

  public function testGetters() {
    $session = $this->createSession();

    $this->assertEquals(
      static::VALUE_SESSION_APP_ID, $session->getAppId());
    $this->assertEquals(
      static::VALUE_SESSION_APP_SECRET, $session->getAppSecret());
    $this->assertEquals(
      static::VALUE_SESSION_ACCESS_TOKEN, $session->getAccessToken());
  }

  public function testAppSecretProof() {
    $session = $this->createSession();
    $proof = $session->getAppSecretProof();

    // Assert SHA-2 > 256 bits > 64 chars
    $this->assertTrue(strlen($proof) == 64);
  }
}


<?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 FacebookAdsTest\Bootstrap;

use FacebookAdsTest\Config\Config;

class Bootstrap {

  /**
   * @var self
   */
  private static $instance;

  /**
   * @var bool
   */
  private $isIntialized = false;

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

  /**
   * @var Config|null
   */
  protected $config;

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

  /**
   * @throws \LogicException
   */
  final public function __construct() {
    if (self::$instance !== null) {
      throw new \LogicException("Bootstrap already instanciated");
    }

    self::$instance = $this;
  }

  /**
   * @return string
   */
  protected function getComposerAutoloadPath() {
    return __DIR__.'/../../../vendor/autoload.php';
  }

  /**
   * @return mixed
   */
  public function getAutoloader() {
    if ($this->autoloader === null) {
      $autoload_path = $this->getComposerAutoloadPath();
      if (!is_readable($autoload_path)) {
        throw new \RuntimeException("Could not read ".$autoload_path);
      }
      $this->autoloader = include $autoload_path;
      $this->autoloader->addPsr4('FacebookAdsTest\\', __DIR__.'/../');
    }

    return $this->autoloader;
  }

  /**
   * Simplifies the common pattern of checking for an index in an array
   * and selecting a default value if it does not exist
   *
   * @param array $array
   * @param string|int $key
   * @param mixed $default
   * @return mixed
   */
  protected function idx(array $array, $key, $default = null) {
    return array_key_exists($key, $array) && $array[$key] !== ''
      ? $array[$key]
      : $default;
  }

  /**
   * Simplifies the common pattern of checking for an index in an array
   * and throw an exception if not
   *
   * @param array $array
   * @param string|int $key
   * @return mixed
   * @throws \Exception
   */
  protected function idxt(array $array, $key) {
    if (!array_key_exists($key, $array) || !$array[$key]) {
      throw new \Exception("Missing mandatory config '{$key}'");
    }

    return $array[$key];
  }

  /**
   * @return Config
   */
  public function getConfig() {
    if ($this->config === null) {
      $this->config = new Config();
      $this->config->testRunId
        = md5($this->idx($_SERVER, 'LOGNAME', uniqid(true)).microtime(true));
      $this->config->testImagePath = __DIR__.'/../../misc/image.png';
      $this->config->testZippedImagesPath = __DIR__.'/../../misc/images.zip';
      $this->config->testVideoPath = __DIR__.'/../../misc/video.mp4';
    }

    return $this->config;
  }

  /**
   * @throws \LogicException
   */
  public function init() {
    if ($this->isIntialized) {
      throw new \LogicException("Bootstrap already initialized");
    }

    $this->getAutoloader();
    Config::setInstance($this->getConfig());
  }
}


<?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 FacebookAdsTest\Bootstrap;

use FacebookAdsTest\Config\Config;
use FacebookAdsTest\Config\SkippableFeaturesManager;

class IntegrationBootstrap extends Bootstrap {

  /**
   * @param string $file_path
   * @return array
   * @throws \RuntimeException
   */
  protected function loadConfigData($file_path) {
    if (!is_readable($file_path)) {
      throw new \RuntimeException("Could not read {$file_path}");
    }

    $data = require $file_path;
    if (!is_array($data)) {
      throw new \RuntimeException("Invalid config structure");
    }

    return $data;
  }

  /**
   * @return array
   */
  protected function getConfigData() {
    if ($this->configData === null) {
      $this->configData = $this->loadConfigData(__DIR__.'/../../config.php');
    }

    return $this->configData;
  }

  /**
   * @param string|int $key
   * @param mixed $default
   * @return mixed
   */
  protected function confx($key, $default = null) {
    return $this->idx($this->getConfigData(), $key, $default);
  }

  /**
   * @param string|int $key
   * @return mixed
   * @throws \Exception
   */
  protected function confxt($key) {
    return $this->idxt($this->getConfigData(), $key);
  }

  /**
   * @return Config
   */
  protected function getUnitConfig() {
    return parent::getConfig();
  }

  /**
   * @return Config
   */
  public function getConfig() {
    if ($this->config === null) {
      $this->config = parent::getConfig();
      $this->config->appId = $this->confx('app_id');
      $this->config->appSecret = $this->confx('app_secret');
      $this->config->accessToken = $this->confx('access_token');
      $this->config->accountId = $this->confx('act_id');
      $this->config->pageId = $this->confx('page_id');
      $this->config->appUrl = $this->confx('app_url');
      $this->config->businessId = $this->confx('business_id');
      $this->config->instagramActorId = $this->confx('instagram_actor_id');

      // Optionals: Override unit config
      $this->config->testRunId = $this->confx(
        'test_run_id', $this->config->testRunId);
      $this->config->testImagePath = $this->confx(
        'test_image_path', $this->config->testImagePath);
      $this->config->testZippedImagesPath = $this->confx(
        'test_zipped_images_path', $this->config->testZippedImagesPath);
      $this->config->testVideoPath = $this->confx(
        'test_video_path', $this->config->testVideoPath);

      // Optionals
      $this->config->secondaryBusinessId
        = $this->confx('secondary_business_id', '');
      $this->config->secondaryAccountId
        = $this->confx('secondary_account_id', '');
      $this->config->secondaryPageId = $this->confx('secondary_page_id', '');
      $this->config->secondaryAppId = $this->confx('secondary_app_id', '');
      $this->config->graphBaseDomain = $this->confx('graph_base_domain');
      $this->config->skipSslVerification
        = $this->confx('skip_ssl_verification', false);
      $this->config->curlLogger = $this->confx('curl_logger');

      SkippableFeaturesManager::setInstance(
        new SkippableFeaturesManager($this->confx('skip_if', array())));
    }

    return $this->config;
  }
}


<?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 FacebookAdsTest\Config;

final class Config {

  /**
   * @var self
   */
  protected static $instance;

  /**
   * @var string
   */
  public $testRunId;

  /**
   * @var string
   */
  public $testImagePath;

  /**
   * @var string
   */
  public $testZippedImagesPath;

  /**
   * @var string
   */
  public $testVideoPath;

  /**
   * @var string
   */
  public $curlLogger;

  /**
   * @var string
   */
  public $appId;

  /**
   * @var string
   */
  public $appSecret;

  /**
   * @var string
   */
  public $accessToken;

  /**
   * @var string
   */
  public $businessId;

  /**
   * @var string
   */
  public $accountId;

  /**
   * @var string
   */
  public $pageId;

  /**
   * @var string
   */
  public $appUrl;

  /**
   * @var string
   */
  public $instagramActorId;

  /**
   * @var string
   */
  public $secondaryBusinessId;

  /**
   * @var string
   */
  public $secondaryPageId;

  /**
   * @var string
   */
  public $secondaryAccountId;

  /**
   * @var string
   */
  public $secondaryAppId;

  /**
   * @var string
   */
  public $graphBaseDomain;

  /**
   * @var bool
   */
  public $skipSslVerification;

  /**
   * @return Config
   */
  public static function instance() {
    return self::$instance ?: (self::$instance = new self());
  }

  /**
   * @param Config $config
   */
  public static function setInstance(Config $config) {
    self::$instance = $config;
  }

  /**
   * @param string $key
   * @param string $value
   */
  public function __set($key, $value) {
    throw new \RuntimeException("Unsupported key: {$key}");
  }
}


<?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 FacebookAdsTest\Config;

use FacebookAdsTest\AbstractTestCase;

final class SkippableFeaturesManager {

  /**
   * @var SkippableFeaturesManager
   */
  private static $instance;

  /**
   * @var array
   */
  protected $data = array();

  /**
   * @return SkippableFeaturesManager
   */
  public static function instance() {
    return self::$instance ?: (self::$instance = new self());
  }

  /**
   * @param SkippableFeaturesManager $manager
   */
  public static function setInstance(SkippableFeaturesManager $manager) {
    self::$instance = $manager;
  }

  /**
   * @param array $data
   */
  public function __construct(array $data = array()) {
    $this->setData($data);
  }

  public function setData(array $data = array()) {
    $this->data = $data;
  }

  /**
   * @return array
   */
  public function getData() {
    return $this->data;
  }

  /**
   * @param $key
   * @return bool
   */
  public function isSkipKey($key) {
    return array_key_exists($key, $this->data) && $this->data[$key];
  }

  /**
   * @param AbstractTestCase $test
   * @return bool
   */
  public function enforceSkipTest(AbstractTestCase $test) {
    if ($test instanceof SkippableFeatureTestInterface) {
      foreach ($test->skipIfAny() as $key) {
        if ($this->isSkipKey($key)) {
          /** @var AbstractTestCase $test */
          $test->markTestSkipped("Reason: skipped by config '{$key}'");
        }
      }
    }
  }
}


<?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 FacebookAdsTest\Config;

interface SkippableFeatureTestInterface {

  /**
   * @return array
   */
  public function skipIfAny();
}