abstract class AppQueryBase in Apigee Edge 8
Base entity query class for developer- and team apps.
Hierarchy
- class \Drupal\Core\Entity\Query\QueryBase implements QueryInterface
- class \Drupal\apigee_edge\Entity\Query\Query implements QueryInterface
- class \Drupal\apigee_edge\Entity\Query\AppQueryBase
- class \Drupal\apigee_edge\Entity\Query\Query implements QueryInterface
Expanded class hierarchy of AppQueryBase
1 file declares its use of AppQueryBase
- TeamAppQuery.php in modules/
apigee_edge_teams/ src/ Entity/ Query/ TeamAppQuery.php
File
- src/
Entity/ Query/ AppQueryBase.php, line 30
Namespace
Drupal\apigee_edge\Entity\QueryView source
abstract class AppQueryBase extends Query {
/**
* Returns field names(s) in a condition that contain an app owner criteria.
*
* @return array
* Array of field name(s) that contain an app owner criteria in a query.
*/
protected abstract function appOwnerConditionFields() : array;
/**
* Returns an app by owner controller.
*
* @param string $owner
* The owner an of an app.
*
* @return \Apigee\Edge\Api\Management\Controller\AppByOwnerControllerInterface
* The app by owner controller instance for the owner.
*/
protected abstract function appByOwnerController(string $owner) : AppByOwnerControllerInterface;
/**
* {@inheritdoc}
*/
protected function getFromStorage() : array {
/** @var \Drupal\apigee_edge\Entity\Storage\AppStorage $storage */
$storage = $this->entityTypeManager
->getStorage($this->entityTypeId);
$ids = NULL;
$app_owner_in_conditions = NULL;
$app_name = NULL;
$original_conditions =& $this->condition
->conditions();
$filtered_conditions = [];
foreach ($original_conditions as $key => $condition) {
$filtered_conditions[$key] = $condition;
if (in_array($condition['field'], $this
->appOwnerConditionFields()) && in_array($condition['operator'], [
NULL,
'=',
])) {
// Indicates whether we found a single app owner id in this condition
// or not.
$app_owner_id_found = FALSE;
if (!is_array($condition['value'])) {
$app_owner_in_conditions = $condition['value'];
$app_owner_id_found = TRUE;
}
elseif (is_array($condition['value']) && count($condition['value']) === 1) {
$app_owner_in_conditions = reset($condition['value']);
$app_owner_id_found = TRUE;
}
if ($app_owner_id_found) {
// Sanity- and security check. The developer who set an empty value
// (null, false, '', etc) as the value of an app owner id condition
// probably made an unintentional mistake. If we would still load all
// apps in this case that could lead to information
// disclosure or worse case a security leak.
if (empty($app_owner_in_conditions)) {
return [];
}
else {
// We have a valid app owner id that can be passed to Apigee Edge
// to return its apps.
unset($filtered_conditions[$key]);
}
}
}
elseif ($condition['field'] === 'name' && in_array($condition['operator'], [
NULL,
'=',
])) {
$app_name_found = FALSE;
if (!is_array($condition['value'])) {
$app_name = $condition['value'];
$app_name_found = TRUE;
}
elseif (is_array($condition['value']) && count($condition['value']) === 1) {
$app_name = reset($condition['value']);
$app_name_found = TRUE;
}
if ($app_name_found) {
// The same as above, the provided condition can not be evaluated
// on Apigee Edge so let's return immediately.
if (empty($app_name)) {
return [];
}
else {
// We have a valid app name that can be passed to Apigee Edge
// to return its apps.
unset($filtered_conditions[$key]);
}
}
}
}
// Remove conditions that is going to be applied on Apigee Edge
// (by calling the proper API with the proper parameters).
// We do not want to apply the same filters on the result in execute()
// again.
$original_conditions = $filtered_conditions;
// Load only one app owner's apps instead of all apps.
if ($app_owner_in_conditions !== NULL) {
// Load only one app instead of all apps of an app owner.
if ($app_name !== NULL) {
// Try to retrieve the appId from the cache, because if we load the
// app with that then we can leverage the our entity cache.
$app_id = $storage
->getCachedAppId($app_owner_in_conditions, $app_name);
if ($app_id) {
try {
$entity = $storage
->load($app_id);
// If the app found in the cache then return it, if not then it can
// mean that the cached app id is outdated (ex.: app had been
// deleted from Apigee Edge in somewhere else than the Developer
// Portal). In that case try to load the app by name directly from
// Apigee Edge.
if ($entity) {
return [
$entity,
];
}
} catch (EntityStorageException $e) {
// Just catch it and try to load the app by name.
}
}
try {
/** @var \Apigee\Edge\Api\Management\Entity\AppInterface $entity */
$entity = $this
->appByOwnerController($app_owner_in_conditions)
->load($app_name);
// We have to use the storage because it ensures that next time the
// app can be found in the cache (and various other things as well).
return [
$storage
->load($entity
->getAppId()),
];
} catch (ApiException $e) {
// App does not exists with name.
}
return [];
}
else {
// Get the name of apps that the app owner owns. Apigee Edge only
// returns the name of the apps therefore the response body should
// be a lot smaller compared with retrieving all app entity data - maybe
// unnecessarily if we already have them in cache - and it should be
// produced and retrieved more quickly.
$app_names = $this
->appByOwnerController($app_owner_in_conditions)
->getEntityIds();
$cached_app_ids = array_map(function ($app_name) use ($storage, $app_owner_in_conditions) {
return $storage
->getCachedAppId($app_owner_in_conditions, $app_name);
}, $app_names);
// Remove those null values that indicates an app name could not be
// found in cache.
$cached_app_ids = array_filter($cached_app_ids);
// It seems that we might have all apps in cache that this app owner
// owns at this moment.
if (count($app_names) === count($cached_app_ids)) {
return $storage
->loadMultiple($cached_app_ids);
}
// It seems we do not have cached app ids for all apps that this
// app owner owns.
// We need app ids (UUIDs) first that are only available on app
// entities therefore we have to load them by using the controller.
// After we have the app ids we have to let the storage to load
// entities again, because that ensures that new entities being cached
// and all hooks and events are being called and trigger (besides
// other various tasks).
// (Add static cache to the controller if this still not performs as
// good as expected.)
$ids = array_map(function ($entity) {
/** @var \Drupal\apigee_edge\Entity\AppInterface $entity */
return $entity
->getAppId();
}, $this
->appByOwnerController($app_owner_in_conditions)
->getEntities());
if ($ids) {
return $storage
->loadMultiple($ids);
}
}
// The app owner has no apps, do not call Apigee Edge unnecessarily.
return [];
}
return parent::getFromStorage();
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AppQueryBase:: |
abstract protected | function | Returns an app by owner controller. | 2 |
AppQueryBase:: |
abstract protected | function | Returns field names(s) in a condition that contain an app owner criteria. | 2 |
AppQueryBase:: |
protected | function |
Loads entities from the entity storage for querying. Overrides Query:: |
|
Query:: |
protected | property | The entity type manager. | |
Query:: |
public | function |
Execute the query. Overrides QueryInterface:: |
|
Query:: |
protected | function | Returns an array of properties that should be considered as entity ids. | |
Query:: |
public | function |
Constructs a Query object. Overrides QueryBase:: |
|
QueryBase:: |
protected | property | Whether access check is requested or not. Defaults to TRUE. | |
QueryBase:: |
protected | property | The list of aggregate expressions. | |
QueryBase:: |
protected | property | Flag indicating whether to query the current revision or all revisions. | |
QueryBase:: |
protected | property | The query metadata for alter purposes. | |
QueryBase:: |
protected | property | The query tags. | |
QueryBase:: |
protected | property | Conditions. | 1 |
QueryBase:: |
protected | property | Aggregate Conditions | |
QueryBase:: |
protected | property | TRUE if this is a count query, FALSE if it isn't. | |
QueryBase:: |
protected | property | Information about the entity type. | 1 |
QueryBase:: |
protected | property | The entity type this query runs against. | |
QueryBase:: |
protected | property | The list of columns to group on. | |
QueryBase:: |
protected | property | Flag indicating whether to query the latest revision. | |
QueryBase:: |
protected | property | List of potential namespaces of the classes belonging to this query. | |
QueryBase:: |
protected | property | The query pager data. | |
QueryBase:: |
protected | property | The query range. | |
QueryBase:: |
protected | property | The list of sorts. | |
QueryBase:: |
protected | property | The list of sorts over the aggregate results. | |
QueryBase:: |
public | function |
Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Adds additional metadata to the query. Overrides AlterableInterface:: |
|
QueryBase:: |
public | function |
Adds a tag to a query. Overrides AlterableInterface:: |
|
QueryBase:: |
public | function | ||
QueryBase:: |
public | function |
Queries all the revisions. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Creates a new group of conditions ANDed together. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Add a condition to the query or a condition group. Overrides QueryInterface:: |
1 |
QueryBase:: |
public | function | ||
QueryBase:: |
protected | function | Creates an object holding a group of conditions. | |
QueryBase:: |
public | function |
Makes this a count query. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Queries the current revision. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Queries for a non-empty value on a field. Overrides QueryInterface:: |
|
QueryBase:: |
protected | function | Generates an alias for a field and its aggregated function. | |
QueryBase:: |
public static | function | Finds a class in a list of namespaces. | |
QueryBase:: |
public | function |
Gets the ID of the entity type for this query. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Retrieves a given piece of metadata. Overrides AlterableInterface:: |
|
QueryBase:: |
public static | function | Gets a list of namespaces of the ancestors of a class. | |
QueryBase:: |
public | function | ||
QueryBase:: |
public | function |
Determines if a given query has all specified tags. Overrides AlterableInterface:: |
|
QueryBase:: |
public | function |
Determines if a given query has any specified tag. Overrides AlterableInterface:: |
|
QueryBase:: |
public | function |
Determines if a given query has a given tag. Overrides AlterableInterface:: |
|
QueryBase:: |
protected | function | Gets the total number of results and initialize a pager for the query. | |
QueryBase:: |
public | function |
Queries the latest revision. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Queries for an empty field. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Creates a new group of conditions ORed together. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Enables a pager for the query. Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Overrides QueryInterface:: |
|
QueryBase:: |
public | function |
Overrides QueryInterface:: |
|
QueryBase:: |
public | function | ||
QueryBase:: |
public | function |
Enables sortable tables for this query. Overrides QueryInterface:: |
|
QueryBase:: |
public | function | Makes sure that the Condition object is cloned as well. | 1 |