annotate core/modules/jsonapi/src/JsonApiResource/Data.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@18 1 <?php
Chris@18 2
Chris@18 3 namespace Drupal\jsonapi\JsonApiResource;
Chris@18 4
Chris@18 5 use Drupal\Component\Assertion\Inspector;
Chris@18 6 use Drupal\jsonapi\Exception\EntityAccessDeniedHttpException;
Chris@18 7
Chris@18 8 /**
Chris@18 9 * Represents the `data` and `included` objects of a top-level object.
Chris@18 10 *
Chris@18 11 * @internal JSON:API maintains no PHP API. The API is the HTTP API. This class
Chris@18 12 * may change at any time and could break any dependencies on it.
Chris@18 13 *
Chris@18 14 * @see https://www.drupal.org/project/jsonapi/issues/3032787
Chris@18 15 * @see jsonapi.api.php
Chris@18 16 */
Chris@18 17 abstract class Data implements \IteratorAggregate, \Countable {
Chris@18 18
Chris@18 19 /**
Chris@18 20 * Various representations of JSON:API objects.
Chris@18 21 *
Chris@18 22 * @var \Drupal\jsonapi\JsonApiResource\ResourceIdentifierInterface[]
Chris@18 23 */
Chris@18 24 protected $data;
Chris@18 25
Chris@18 26 /**
Chris@18 27 * The number of resources permitted in this collection.
Chris@18 28 *
Chris@18 29 * @var int
Chris@18 30 */
Chris@18 31 protected $cardinality;
Chris@18 32
Chris@18 33 /**
Chris@18 34 * Holds a boolean indicating if there is a next page.
Chris@18 35 *
Chris@18 36 * @var bool
Chris@18 37 */
Chris@18 38 protected $hasNextPage;
Chris@18 39
Chris@18 40 /**
Chris@18 41 * Holds the total count of entities.
Chris@18 42 *
Chris@18 43 * @var int
Chris@18 44 */
Chris@18 45 protected $count;
Chris@18 46
Chris@18 47 /**
Chris@18 48 * Instantiates a Data object.
Chris@18 49 *
Chris@18 50 * @param \Drupal\jsonapi\JsonApiResource\ResourceIdentifierInterface[] $data
Chris@18 51 * The resources or resource identifiers for the collection.
Chris@18 52 * @param int $cardinality
Chris@18 53 * The number of resources that this collection may contain. Related
Chris@18 54 * resource collections may handle both to-one or to-many relationships. A
Chris@18 55 * to-one relationship should have a cardinality of 1. Use -1 for unlimited
Chris@18 56 * cardinality.
Chris@18 57 */
Chris@18 58 public function __construct(array $data, $cardinality = -1) {
Chris@18 59 assert(Inspector::assertAllObjects($data, ResourceIdentifierInterface::class));
Chris@18 60 assert($cardinality >= -1 && $cardinality !== 0, 'Cardinality must be -1 for unlimited cardinality or a positive integer.');
Chris@18 61 assert($cardinality === -1 || count($data) <= $cardinality, 'If cardinality is not unlimited, the number of given resources must not exceed the cardinality of the collection.');
Chris@18 62 $this->data = array_values($data);
Chris@18 63 $this->cardinality = $cardinality;
Chris@18 64 }
Chris@18 65
Chris@18 66 /**
Chris@18 67 * Returns an iterator for entities.
Chris@18 68 *
Chris@18 69 * @return \ArrayIterator
Chris@18 70 * An \ArrayIterator instance
Chris@18 71 */
Chris@18 72 public function getIterator() {
Chris@18 73 return new \ArrayIterator($this->data);
Chris@18 74 }
Chris@18 75
Chris@18 76 /**
Chris@18 77 * Returns the number of entities.
Chris@18 78 *
Chris@18 79 * @return int
Chris@18 80 * The number of parameters
Chris@18 81 */
Chris@18 82 public function count() {
Chris@18 83 return count($this->data);
Chris@18 84 }
Chris@18 85
Chris@18 86 /**
Chris@18 87 * {@inheritdoc}
Chris@18 88 */
Chris@18 89 public function getTotalCount() {
Chris@18 90 return $this->count;
Chris@18 91 }
Chris@18 92
Chris@18 93 /**
Chris@18 94 * {@inheritdoc}
Chris@18 95 */
Chris@18 96 public function setTotalCount($count) {
Chris@18 97 $this->count = $count;
Chris@18 98 }
Chris@18 99
Chris@18 100 /**
Chris@18 101 * Returns the collection as an array.
Chris@18 102 *
Chris@18 103 * @return \Drupal\Core\Entity\EntityInterface[]
Chris@18 104 * The array of entities.
Chris@18 105 */
Chris@18 106 public function toArray() {
Chris@18 107 return $this->data;
Chris@18 108 }
Chris@18 109
Chris@18 110 /**
Chris@18 111 * Checks if there is a next page in the collection.
Chris@18 112 *
Chris@18 113 * @return bool
Chris@18 114 * TRUE if the collection has a next page.
Chris@18 115 */
Chris@18 116 public function hasNextPage() {
Chris@18 117 return (bool) $this->hasNextPage;
Chris@18 118 }
Chris@18 119
Chris@18 120 /**
Chris@18 121 * Sets the has next page flag.
Chris@18 122 *
Chris@18 123 * Once the collection query has been executed and we build the entity
Chris@18 124 * collection, we now if there will be a next page with extra entities.
Chris@18 125 *
Chris@18 126 * @param bool $has_next_page
Chris@18 127 * TRUE if the collection has a next page.
Chris@18 128 */
Chris@18 129 public function setHasNextPage($has_next_page) {
Chris@18 130 $this->hasNextPage = (bool) $has_next_page;
Chris@18 131 }
Chris@18 132
Chris@18 133 /**
Chris@18 134 * Gets the cardinality of this collection.
Chris@18 135 *
Chris@18 136 * @return int
Chris@18 137 * The cardinality of the resource collection. -1 for unlimited cardinality.
Chris@18 138 */
Chris@18 139 public function getCardinality() {
Chris@18 140 return $this->cardinality;
Chris@18 141 }
Chris@18 142
Chris@18 143 /**
Chris@18 144 * Returns a new Data object containing the entities of $this and $other.
Chris@18 145 *
Chris@18 146 * @param \Drupal\jsonapi\JsonApiResource\Data $a
Chris@18 147 * A Data object object to be merged.
Chris@18 148 * @param \Drupal\jsonapi\JsonApiResource\Data $b
Chris@18 149 * A Data object to be merged.
Chris@18 150 *
Chris@18 151 * @return \Drupal\jsonapi\JsonApiResource\Data
Chris@18 152 * A new merged Data object.
Chris@18 153 */
Chris@18 154 public static function merge(Data $a, Data $b) {
Chris@18 155 return new static(array_merge($a->toArray(), $b->toArray()));
Chris@18 156 }
Chris@18 157
Chris@18 158 /**
Chris@18 159 * Returns a new, deduplicated Data object.
Chris@18 160 *
Chris@18 161 * @param \Drupal\jsonapi\JsonApiResource\Data $collection
Chris@18 162 * The Data object to deduplicate.
Chris@18 163 *
Chris@18 164 * @return static
Chris@18 165 * A new merged Data object.
Chris@18 166 */
Chris@18 167 public static function deduplicate(Data $collection) {
Chris@18 168 $deduplicated = [];
Chris@18 169 foreach ($collection as $resource) {
Chris@18 170 $dedupe_key = $resource->getTypeName() . ':' . $resource->getId();
Chris@18 171 if ($resource instanceof EntityAccessDeniedHttpException && ($error = $resource->getError()) && !is_null($error['relationship_field'])) {
Chris@18 172 $dedupe_key .= ':' . $error['relationship_field'];
Chris@18 173 }
Chris@18 174 $deduplicated[$dedupe_key] = $resource;
Chris@18 175 }
Chris@18 176 return new static(array_values($deduplicated));
Chris@18 177 }
Chris@18 178
Chris@18 179 }