You are here

class Developer in Apigee Edge 8

Defines the Developer entity class.

@\Drupal\apigee_edge\Annotation\EdgeEntityType( id = "developer", label =

Plugin annotation


@Translation("Developer"),
  label_collection = @Translation("Developers"),
  label_singular = @Translation("developer"),
  label_plural = @Translation("developers"),
  label_count = @PluralTranslation(
    singular = "@count developer",
    plural = "@count developers",
  ),
  handlers = {
    "storage" = "\Drupal\apigee_edge\Entity\Storage\DeveloperStorage",
  },
  query_class = "Drupal\apigee_edge\Entity\Query\DeveloperQuery",
)

Hierarchy

Expanded class hierarchy of Developer

25 files declare their use of Developer
ApigeeEdgeDeveloperIdFieldItem.php in src/Plugin/Field/FieldType/ApigeeEdgeDeveloperIdFieldItem.php
ApigeeEdgeFunctionalTestTrait.php in tests/src/Traits/ApigeeEdgeFunctionalTestTrait.php
ApigeeMockApiClientHelperTrait.php in tests/modules/apigee_mock_api_client/tests/src/Traits/ApigeeMockApiClientHelperTrait.php
apigee_edge.module in ./apigee_edge.module
Copyright 2018 Google Inc.
AppListBuilderTest.php in tests/src/Kernel/Entity/ListBuilder/AppListBuilderTest.php

... See full list

1 string reference to 'Developer'
EdgeEntityEventDeriverBase::getContext in modules/apigee_edge_actions/src/Plugin/RulesEvent/EdgeEntityEventDeriverBase.php
Returns an array of event context.

File

src/Entity/Developer.php, line 52

Namespace

Drupal\apigee_edge\Entity
View source
class Developer extends EdgeEntityBase implements DeveloperInterface {

  /**
   * Developer already exists error code.
   *
   * @var string
   */
  const APIGEE_EDGE_ERROR_CODE_DEVELOPER_ALREADY_EXISTS = 'developer.service.DeveloperAlreadyExists';

  /**
   * Developer does not exists error code.
   *
   * @var string
   */
  const APIGEE_EDGE_ERROR_CODE_DEVELOPER_DOES_NOT_EXISTS = 'developer.service.DeveloperDoesNotExist';

  /**
   * Resource name in the url doesnot match with the name in the request payload.
   *
   * @var string
   */
  const APIGEE_HYBRID_ERROR_CODE_DEVELOPER_EMAIL_MISMATCH = 'rest.interceptor.name_mismatch';

  /**
   * The decorated SDK entity.
   *
   * @var \Apigee\Edge\Api\Management\Entity\Developer
   */
  protected $decorated;

  /**
   * The cached Drupal UID.
   *
   * Use getOwnerId() to return the correct value.
   *
   * @var null|int
   */
  protected $drupalUserId;

  /**
   * The original email address of the developer.
   *
   * @var null|string
   */
  protected $originalEmail;

  /**
   * Caches company names.
   *
   * This does not get saved to the persistent entity cache because it gets
   * calculated only when it is necessary, when getCompanies() gets called.
   *
   * @var \Drupal\apigee_edge\Entity\DeveloperCompaniesCacheInterface
   *
   * @see getCompanies()
   */
  protected $companiesCache;

  /**
   * Developer constructor.
   *
   * @param array $values
   *   An array of values to set, keyed by property name.
   * @param null|string $entity_type
   *   Type of the entity. It is optional because constructor sets its default
   *   value.
   * @param \Apigee\Edge\Entity\EntityInterface|null $decorated
   *   The SDK entity that this Drupal entity decorates.
   */
  public function __construct(array $values, ?string $entity_type = NULL, EdgeEntityInterface $decorated = NULL) {
    $entity_type = $entity_type ?? 'developer';

    // Callers expect that the status is always either 'active' or 'inactive',
    // never null.
    if (!isset($values['status'])) {
      $values['status'] = static::STATUS_ACTIVE;
    }
    parent::__construct($values, $entity_type, $decorated);

    // Property must be initialized here because it is used as entity's
    // primary id in Drupal.
    // @see static::idProperties()
    // @see static::drupalEntityId()
    $this->originalEmail = $this->originalEmail ?? $this->decorated
      ->getEmail();
    $this->companiesCache = \Drupal::service('apigee_edge.controller.cache.developer_companies');

    // If we got a non-empty companies list from the API response then
    // cache it otherwise ignore it. See more details in getCompanies().
    if ($this->decorated
      ->getCompanies()) {
      $this->companiesCache
        ->saveCompanies([
        $this->decorated,
      ]);
    }
  }

  /**
   * {@inheritdoc}
   *
   * We have to override this to make it compatible with the SDK's
   * entity interface that has return type hint.
   */
  public function id() : ?string {
    return parent::id();
  }

  /**
   * {@inheritdoc}
   */
  protected static function decoratedClass() : string {
    return EdgeDeveloper::class;
  }

  /**
   * {@inheritdoc}
   */
  public static function uniqueIdProperties() : array {

    // Parent returns the original email.
    // @see static::idProperty()
    return array_merge(parent::uniqueIdProperties(), [
      // UUID.
      EdgeDeveloper::idProperty(),
    ]);
  }

  /**
   * {@inheritdoc}
   */
  protected function drupalEntityId() : ?string {
    return $this->originalEmail;
  }

  /**
   * {@inheritdoc}
   */
  public function uuid() {
    return $this->decorated
      ->id();
  }

  /**
   * {@inheritdoc}
   */
  public function getAttributes() : AttributesProperty {
    return $this->decorated
      ->getAttributes();
  }

  /**
   * {@inheritdoc}
   */
  public function setAttributes(AttributesProperty $attributes) : void {
    $this->decorated
      ->setAttributes($attributes);
  }

  /**
   * {@inheritdoc}
   */
  public function getAttributeValue(string $attribute) : ?string {
    return $this->decorated
      ->getAttributeValue($attribute);
  }

  /**
   * {@inheritdoc}
   */
  public function setAttribute(string $name, string $value) : void {
    $this->decorated
      ->setAttribute($name, $value);
  }

  /**
   * {@inheritdoc}
   */
  public function hasAttribute(string $name) : bool {
    return $this->decorated
      ->hasAttribute($name);
  }

  /**
   * {@inheritdoc}
   */
  public function deleteAttribute(string $name) : void {
    $this->decorated
      ->deleteAttribute($name);
  }

  /**
   * {@inheritdoc}
   */
  public function getCreatedAt() : ?\DateTimeImmutable {
    return $this->decorated
      ->getCreatedAt();
  }

  /**
   * {@inheritdoc}
   */
  public function getCreatedBy() : ?string {
    return $this->decorated
      ->getCreatedBy();
  }

  /**
   * {@inheritdoc}
   */
  public function getLastModifiedAt() : ?\DateTimeImmutable {
    return $this->decorated
      ->getLastModifiedAt();
  }

  /**
   * {@inheritdoc}
   */
  public function getLastModifiedBy() : ?string {
    return $this->decorated
      ->getLastModifiedBy();
  }

  /**
   * {@inheritdoc}
   */
  public function getApps() : array {
    return $this->decorated
      ->getApps();
  }

  /**
   * {@inheritdoc}
   */
  public function hasApp(string $app_name) : bool {
    return $this->decorated
      ->hasApp($app_name);
  }

  /**
   * {@inheritdoc}
   */
  public function getCompanies() : array {

    // If companies is null it means the original API response that this
    // object constructed did not contain a non-empty company list.
    // One of the reasons of this could be that the entity got loaded
    // by calling the list developers API endpoint that does not return the
    // companies.
    // @see https://apidocs.apigee.com/management/apis/get/organizations/%7Borg_name%7D/developers
    if ($this->companiesCache
      ->getCompanies($this
      ->getDeveloperId()) === NULL) {

      /** @var \Drupal\apigee_edge\Entity\Controller\DeveloperControllerInterface $controller */
      $controller = \Drupal::service('apigee_edge.controller.developer');

      // If controller has an internal cache let's check whether this
      // developer in it and it has a non-empty company list.
      if ($controller instanceof EntityCacheAwareControllerInterface) {

        /** @var \Apigee\Edge\Api\Management\Entity\DeveloperInterface|null $cached_developer */
        $cached_developer = $controller
          ->entityCache()
          ->getEntity($this
          ->getDeveloperId());
        if ($cached_developer && !empty($cached_developer
          ->getCompanies())) {

          // Save it to the local cache so we can serve it from there
          // next time.
          $this->companiesCache
            ->saveCompanies([
            $cached_developer,
          ]);
          return $this->companiesCache
            ->getCompanies($cached_developer
            ->id());
        }
        else {

          // Let's remove the developer from the cache otherwise we get it back
          // with the same empty company list as before (maybe returned by the
          // list developers API endpoint) for this developer.
          $controller
            ->entityCache()
            ->removeEntities([
            $this
              ->getDeveloperId(),
          ]);
        }
      }

      /** @var \Apigee\Edge\Api\Management\Entity\DeveloperInterface $developer */
      try {
        $developer = $controller
          ->load($this
          ->getEmail());

        // Save the list of companies (even if it is actually empty) to this
        // local cache property so we can return this information without
        // calling Apigee Edge next time.
        $this->companiesCache
          ->saveCompanies([
          $developer,
        ]);
      } catch (ApiException $exception) {
        $message = 'Unable to load companies of %developer developer from Apigee Edge. @message %function (line %line of %file). <pre>@backtrace_string</pre>';
        $context = [
          '%developer' => $this
            ->getEmail(),
        ];
        $context += Error::decodeException($exception);
        \Drupal::logger('apigee_edge')
          ->error($message, $context);

        // Return an empty array if the API call fails because this is the
        // safest thing that we can do in this case.
        // Do not change the value of $this->companies because this way we can
        // ensure the this method tries to call the API again next time.
        return [];
      }
    }
    return $this->companiesCache
      ->getCompanies($this
      ->getDeveloperId());
  }

  /**
   * {@inheritdoc}
   */
  public function hasCompany(string $company_name) : bool {
    return in_array($company_name, $this
      ->getCompanies(), TRUE);
  }

  /**
   * {@inheritdoc}
   */
  public function getDeveloperId() : ?string {
    return $this->decorated
      ->getDeveloperId();
  }

  /**
   * {@inheritdoc}
   */
  public function getUserName() : ?string {
    return $this->decorated
      ->getUserName();
  }

  /**
   * {@inheritdoc}
   */
  public function setUserName(string $user_name) : void {
    $this->decorated
      ->setUserName($user_name);
  }

  /**
   * {@inheritdoc}
   */
  public function getEmail() : ?string {
    return $this->decorated
      ->getEmail();
  }

  /**
   * {@inheritdoc}
   */
  public function setEmail(string $email) : void {
    $this->decorated
      ->setEmail($email);
    if ($this->originalEmail === NULL) {
      $this->originalEmail = $email;
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getFirstName() : ?string {
    return $this->decorated
      ->getFirstName();
  }

  /**
   * {@inheritdoc}
   */
  public function setFirstName(string $first_name) : void {
    $this->decorated
      ->setFirstName($first_name);
  }

  /**
   * {@inheritdoc}
   */
  public function getLastName() : ?string {
    return $this->decorated
      ->getLastName();
  }

  /**
   * {@inheritdoc}
   */
  public function setLastName(string $last_name) : void {
    $this->decorated
      ->setLastName($last_name);
  }

  /**
   * {@inheritdoc}
   */
  public static function idProperty() : string {
    return 'originalEmail';
  }

  /**
   * {@inheritdoc}
   */
  public function getOwner() {
    $owner_id = $this
      ->getOwnerId();
    return $owner_id === NULL ? NULL : User::load($owner_id);
  }

  /**
   * {@inheritdoc}
   */
  public function setOwner(UserInterface $account) {
    $this
      ->setOwnerId($account
      ->id());
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getOwnerId() {
    if ($this->drupalUserId === NULL) {
      if ($this
        ->getEmail()) {

        /** @var \Drupal\user\UserInterface $account */
        $account = user_load_by_mail($this
          ->getEmail());
        if ($account) {
          $this->drupalUserId = $account
            ->id();
        }
      }

      // Username is not unique on Apigee Edge so we do not use that here.
    }
    return $this->drupalUserId;
  }

  /**
   * {@inheritdoc}
   */
  public function setOwnerId($uid) {
    $this->drupalUserId = $uid;

    // When a new user is created uid is null.
    if ($uid !== NULL) {
      $account = User::load($uid);
      if ($account !== NULL && $this
        ->getEmail() !== $account
        ->getEmail()) {
        $this
          ->setEmail($account
          ->getEmail());
      }
    }
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function resetOriginalEmail() : void {
    $this->originalEmail = $this->decorated
      ->getEmail();
  }

  /**
   * {@inheritdoc}
   */
  public function setStatus(string $status) : void {
    $this->decorated
      ->setStatus($status);
  }

  /**
   * {@inheritdoc}
   */
  public function getOrganizationName() : ?string {
    return $this->decorated
      ->getOrganizationName();
  }

  /**
   * {@inheritdoc}
   */
  public function getStatus() : ?string {
    return $this->decorated
      ->getStatus();
  }

  /**
   * {@inheritdoc}
   */
  public function getOriginalEmail() : ?string {
    return $this->originalEmail;
  }

  /**
   * {@inheritdoc}
   */
  public function label() {

    // This class does not implement DisplayNamePropertyInterface.
    // It make sense to return this as a default label for a developer entity.
    // (Both fields are mandatory.)
    return "{$this->getFirstName()} {$this->getLastName()}";
  }

  /**
   * {@inheritdoc}
   */
  public static function postDelete(EntityStorageInterface $storage, array $entities) {
    parent::postDelete($storage, $entities);

    /** @var \Drupal\apigee_edge\Entity\DeveloperCompaniesCacheInterface $cache */
    $cache = \Drupal::service('apigee_edge.controller.cache.developer_companies');
    $developer_mail_id_map = array_map(function (Developer $entity) {
      return $entity
        ->getDeveloperId();
    }, $entities);

    // Remove developer->company membership info from the memory cache.
    $cache
      ->remove($developer_mail_id_map);

    // Ensure that even if $storage:delete() got called with developer email
    // addresses, all cache entries that refers to the same developer by
    // its developer id (UUID) also gets invalidated.
    $storage
      ->resetCache($developer_mail_id_map);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CacheableDependencyTrait::$cacheContexts protected property Cache contexts.
CacheableDependencyTrait::$cacheMaxAge protected property Cache max-age.
CacheableDependencyTrait::$cacheTags protected property Cache tags.
CacheableDependencyTrait::setCacheability protected function Sets cacheability; useful for value object constructors.
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function Aliased as: traitSleep 1
DependencySerializationTrait::__wakeup public function 2
Developer::$companiesCache protected property Caches company names.
Developer::$decorated protected property The decorated SDK entity. Overrides EdgeEntityBase::$decorated
Developer::$drupalUserId protected property The cached Drupal UID.
Developer::$originalEmail protected property The original email address of the developer.
Developer::APIGEE_EDGE_ERROR_CODE_DEVELOPER_ALREADY_EXISTS constant Developer already exists error code.
Developer::APIGEE_EDGE_ERROR_CODE_DEVELOPER_DOES_NOT_EXISTS constant Developer does not exists error code.
Developer::APIGEE_HYBRID_ERROR_CODE_DEVELOPER_EMAIL_MISMATCH constant Resource name in the url doesnot match with the name in the request payload.
Developer::decoratedClass protected static function The FQCN of the decorated class from the PHP API Client. Overrides EdgeEntityBase::decoratedClass
Developer::deleteAttribute public function
Developer::drupalEntityId protected function Return the entity id used in Drupal. Overrides EdgeEntityBase::drupalEntityId
Developer::getApps public function
Developer::getAttributes public function
Developer::getAttributeValue public function
Developer::getCompanies public function
Developer::getCreatedAt public function
Developer::getCreatedBy public function
Developer::getDeveloperId public function
Developer::getEmail public function
Developer::getFirstName public function
Developer::getLastModifiedAt public function
Developer::getLastModifiedBy public function
Developer::getLastName public function
Developer::getOrganizationName public function
Developer::getOriginalEmail public function Returns the original (unmodified) email address of a developer. Overrides DeveloperInterface::getOriginalEmail
Developer::getOwner public function Returns the entity owner's user entity. Overrides EntityOwnerInterface::getOwner
Developer::getOwnerId public function Returns the entity owner's user ID. Overrides EntityOwnerInterface::getOwnerId
Developer::getStatus public function
Developer::getUserName public function
Developer::hasApp public function
Developer::hasAttribute public function
Developer::hasCompany public function
Developer::id public function We have to override this to make it compatible with the SDK's entity interface that has return type hint. Overrides EdgeEntityBase::id
Developer::idProperty public static function
Developer::label public function Gets the label of the entity. Overrides EdgeEntityBase::label
Developer::postDelete public static function Acts on deleted entities before the delete hook is invoked. Overrides EntityBase::postDelete
Developer::resetOriginalEmail public function Resets the original email. Overrides DeveloperInterface::resetOriginalEmail
Developer::setAttribute public function
Developer::setAttributes public function
Developer::setEmail public function
Developer::setFirstName public function
Developer::setLastName public function
Developer::setOwner public function Sets the entity owner's user entity. Overrides EntityOwnerInterface::setOwner
Developer::setOwnerId public function Sets the entity owner's user ID. Overrides EntityOwnerInterface::setOwnerId
Developer::setStatus public function Set status of the developer. Overrides DeveloperInterface::setStatus
Developer::setUserName public function
Developer::uniqueIdProperties public static function Returns all unique ids how an entity can be referenced in Apigee Edge. Overrides EdgeEntityBase::uniqueIdProperties
Developer::uuid public function Gets the entity UUID (Universally Unique Identifier). Overrides EntityBase::uuid
Developer::__construct public function Developer constructor. Overrides EdgeEntityBase::__construct
EdgeEntityBase::createFrom public static function Creates a Drupal entity from an SDK Entity. Overrides EdgeEntityInterface::createFrom
EdgeEntityBase::decorated public function Returns the decorated SDK entity. Overrides EdgeEntityInterface::decorated 2
EdgeEntityBase::getTranslation public function
EdgeEntityBase::hasTranslation public function
EdgeEntityBase::isTranslatable public function
EdgeEntityBase::uniqueIds public function List of unique ids how an entity can be referenced in Apigee Edge. Overrides EdgeEntityInterface::uniqueIds
EntityBase::$enforceIsNew protected property Boolean indicating whether the entity should be forced to be new.
EntityBase::$entityTypeId protected property The entity type.
EntityBase::$typedData protected property A typed data object wrapping this entity.
EntityBase::access public function Checks data value access. Overrides AccessibleInterface::access 1
EntityBase::bundle public function Gets the bundle of the entity. Overrides EntityInterface::bundle 1
EntityBase::create public static function Constructs a new entity object, without permanently saving it. Overrides EntityInterface::create
EntityBase::createDuplicate public function Creates a duplicate of the entity. Overrides EntityInterface::createDuplicate 2
EntityBase::delete public function Deletes an entity permanently. Overrides EntityInterface::delete 2
EntityBase::enforceIsNew public function Enforces an entity to be new. Overrides EntityInterface::enforceIsNew
EntityBase::entityManager Deprecated protected function Gets the entity manager.
EntityBase::entityTypeBundleInfo protected function Gets the entity type bundle info service.
EntityBase::entityTypeManager protected function Gets the entity type manager.
EntityBase::getCacheContexts public function The cache contexts associated with this object. Overrides CacheableDependencyTrait::getCacheContexts
EntityBase::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyTrait::getCacheMaxAge
EntityBase::getCacheTags public function The cache tags associated with this object. Overrides CacheableDependencyTrait::getCacheTags
EntityBase::getCacheTagsToInvalidate public function Returns the cache tags that should be used to invalidate caches. Overrides EntityInterface::getCacheTagsToInvalidate 2
EntityBase::getConfigDependencyKey public function Gets the key that is used to store configuration dependencies. Overrides EntityInterface::getConfigDependencyKey
EntityBase::getConfigDependencyName public function Gets the configuration dependency name. Overrides EntityInterface::getConfigDependencyName 1
EntityBase::getConfigTarget public function Gets the configuration target identifier for the entity. Overrides EntityInterface::getConfigTarget 1
EntityBase::getEntityType public function Gets the entity type definition. Overrides EntityInterface::getEntityType
EntityBase::getEntityTypeId public function Gets the ID of the type of the entity. Overrides EntityInterface::getEntityTypeId
EntityBase::getListCacheTagsToInvalidate protected function The list cache tags to invalidate for this entity.
EntityBase::getOriginalId public function Gets the original ID. Overrides EntityInterface::getOriginalId 1
EntityBase::getTypedData public function Gets a typed data object for this entity object. Overrides EntityInterface::getTypedData
EntityBase::hasLinkTemplate public function Indicates if a link template exists for a given key. Overrides EntityInterface::hasLinkTemplate
EntityBase::invalidateTagsOnDelete protected static function Invalidates an entity's cache tags upon delete. 1
EntityBase::invalidateTagsOnSave protected function Invalidates an entity's cache tags upon save. 1
EntityBase::isNew public function Determines whether the entity is new. Overrides EntityInterface::isNew 2
EntityBase::language public function Gets the language of the entity. Overrides EntityInterface::language 1
EntityBase::languageManager protected function Gets the language manager.
EntityBase::link public function Deprecated way of generating a link to the entity. See toLink(). Overrides EntityInterface::link 1
EntityBase::linkTemplates protected function Gets an array link templates. 1
EntityBase::load public static function Loads an entity. Overrides EntityInterface::load
EntityBase::loadMultiple public static function Loads one or more entities. Overrides EntityInterface::loadMultiple
EntityBase::postCreate public function Acts on a created entity before hooks are invoked. Overrides EntityInterface::postCreate 4
EntityBase::postLoad public static function Acts on loaded entities. Overrides EntityInterface::postLoad 2
EntityBase::postSave public function Acts on a saved entity before the insert or update hook is invoked. Overrides EntityInterface::postSave 14
EntityBase::preCreate public static function Changes the values of an entity before it is created. Overrides EntityInterface::preCreate 5
EntityBase::preDelete public static function Acts on entities before they are deleted and before hooks are invoked. Overrides EntityInterface::preDelete 4
EntityBase::preSave public function Acts on an entity before the presave hook is invoked. Overrides EntityInterface::preSave 2
EntityBase::referencedEntities public function Gets a list of entities referenced by this entity. Overrides EntityInterface::referencedEntities 1
EntityBase::save public function Saves an entity permanently. Overrides EntityInterface::save 3
EntityBase::setOriginalId public function Sets the original ID. Overrides EntityInterface::setOriginalId 1
EntityBase::toArray public function Gets an array of all property values. Overrides EntityInterface::toArray 2
EntityBase::toLink public function Generates the HTML for a link to this entity. Overrides EntityInterface::toLink
EntityBase::toUrl public function Gets the URL object for the entity. Overrides EntityInterface::toUrl 2
EntityBase::uriRelationships public function Gets a list of URI relationships supported by this entity. Overrides EntityInterface::uriRelationships
EntityBase::url public function Gets the public URL for this entity. Overrides EntityInterface::url 2
EntityBase::urlInfo public function Gets the URL object for the entity. Overrides EntityInterface::urlInfo 1
EntityBase::urlRouteParameters protected function Gets an array of placeholders for this entity. 2
EntityBase::uuidGenerator protected function Gets the UUID generator.
EntityBase::__sleep public function 2
RefinableCacheableDependencyTrait::addCacheableDependency public function 1
RefinableCacheableDependencyTrait::addCacheContexts public function
RefinableCacheableDependencyTrait::addCacheTags public function
RefinableCacheableDependencyTrait::mergeCacheMaxAge public function