Open Data Catalog v2.0.0
ResourceMapper.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Drupal\metastore;
4 
8 use Drupal\common\EventDispatcherTrait;
11 
16  use EventDispatcherTrait;
17 
18  const EVENT_REGISTRATION = 'dkan_metastore_resource_mapper_registration';
19  const EVENT_RESOURCE_MAPPER_PRE_REMOVE_SOURCE = 'dkan_metastore_pre_remove_source';
20 
21  const DEREFERENCE_NO = 0;
22  const DEREFERENCE_YES = 1;
23 
29  private $store;
30 
36  private $eventDispatcher;
37 
41  public function __construct(DatabaseTableInterface $store) {
42  $this->store = $store;
43  }
44 
51  public static function newRevision() {
52  return drupal_static('metastore_resource_mapper_new_revision', 0);
53  }
54 
61  public function register(Resource $resource) : bool {
62  $this->filePathExists($resource->getFilePath());
63  $this->store->store(json_encode($resource));
64  $this->dispatchEvent(self::EVENT_REGISTRATION, $resource);
65 
66  return TRUE;
67  }
68 
75  public function registerNewPerspective(Resource $resource): void {
76  $identifier = $resource->getIdentifier();
77  $version = $resource->getVersion();
78  // Ensure a source perspective already exists for the resource.
79  if (!$this->exists($identifier, Resource::DEFAULT_SOURCE_PERSPECTIVE, $version)) {
80  throw new \Exception("A resource with identifier {$identifier} was not found.");
81  }
82 
83  $perspective = $resource->getPerspective();
84  // Ensure the current perspective does not already exist for the resource.
85  if ($this->exists($identifier, $perspective, $version)) {
86  throw new AlreadyRegistered("A resource with identifier {$identifier} and perspective {$perspective} already exists.");
87  }
88 
89  // If the given resource has a local file, generate a checksum for the
90  // file before storing the resource.
91  if ($perspective == ResourceLocalizer::LOCAL_FILE_PERSPECTIVE) {
92  $resource->generateChecksum();
93  }
94 
95  // Record resource in mapper table and dispatch an event for the
96  // resource's registration.
97  $this->store->store(json_encode($resource));
98  $this->dispatchEvent(self::EVENT_REGISTRATION, $resource);
99  }
100 
104  public function registerNewVersion(Resource $resource) {
105  $this->validateNewVersion($resource);
106  $this->getStore()->store(json_encode($resource));
107  $this->dispatchEvent(self::EVENT_REGISTRATION, $resource);
108  }
109 
113  protected function validateNewVersion(Resource $resource) {
115  throw new \Exception("Only versions of source resources are allowed.");
116  }
117 
118  $identifier = $resource->getIdentifier();
119  if (!$this->exists($identifier, Resource::DEFAULT_SOURCE_PERSPECTIVE)) {
120  throw new \Exception(
121  "A resource with identifier {$identifier} was not found.");
122  }
123 
124  $version = $resource->getVersion();
125  if ($this->exists($identifier, Resource::DEFAULT_SOURCE_PERSPECTIVE, $version)) {
126  throw new AlreadyRegistered(
127  "A resource with identifier {$identifier} and version {$version} already exists.");
128  }
129  }
130 
134  public function get(string $identifier, $perspective = Resource::DEFAULT_SOURCE_PERSPECTIVE, $version = NULL): ?Resource {
135  $data = $this->getFull($identifier, $perspective, $version);
136  return ($data != FALSE) ? Resource::hydrate(json_encode($data)) : NULL;
137  }
138 
142  private function getFull(string $identifier, $perspective, $version) {
143  if (!$version) {
144  $data = $this->getLatestRevision($identifier, $perspective);
145  }
146  else {
147  $data = $this->getRevision($identifier, $perspective, $version);
148  }
149  return $data;
150  }
151 
155  public function remove(Resource $resource) {
156  if ($this->exists($resource->getIdentifier(), $resource->getPerspective(), $resource->getVersion())) {
157  $object = $this->getRevision($resource->getIdentifier(), $resource->getPerspective(), $resource->getVersion());
158  if ($resource->getPerspective() == 'source') {
159  // Dispatch event to initiate removal of
160  // the the datastore and local file.
161  $this->dispatchEvent(self::EVENT_RESOURCE_MAPPER_PRE_REMOVE_SOURCE, $resource);
162  }
163  // Remove the resource mapper perspective.
164  $this->store->remove($object->id);
165  }
166  }
167 
174  private function getLatestRevision($identifier, $perspective) {
175  $query = $this->getCommonQuery($identifier, $perspective);
176  $query->sortByDescending('version');
177  $items = $this->store->query($query);
178  return reset($items);
179  }
180 
187  private function getRevision($identifier, $perspective, $version) {
188  $query = $this->getCommonQuery($identifier, $perspective);
189  $query->conditionByIsEqualTo('version', $version);
190  $items = $this->store->query($query);
191  return reset($items);
192  }
193 
197  private function getCommonQuery($identifier, $perspective) {
198  $query = new Query();
199  $query->properties = [
200  'identifier',
201  'version',
202  'perspective',
203  'filePath',
204  'mimeType',
205  'id',
206  ];
207  $query->conditionByIsEqualTo('identifier', $identifier);
208  $query->conditionByIsEqualTo('perspective', $perspective);
209  $query->limitTo(1);
210  return $query;
211  }
212 
228  public function filePathExists($filePath) {
229  $query = new Query();
230  $query->conditionByIsEqualTo('filePath', $filePath, TRUE);
231  $results = $this->getStore()->query($query);
232  if (!empty($results)) {
233  throw new AlreadyRegistered(json_encode($results));
234  }
235  return FALSE;
236  }
237 
241  private function exists($identifier, $perspective, $version = NULL) : bool {
242  $item = $this->get($identifier, $perspective, $version);
243  return isset($item);
244  }
245 
252  public function getStore() {
253  return $this->store;
254  }
255 
256 }
Drupal\metastore\Exception\AlreadyRegistered
Definition: AlreadyRegistered.php:10
Drupal\metastore\ResourceMapper\newRevision
static newRevision()
Definition: ResourceMapper.php:51
Drupal\metastore\ResourceMapper\validateNewVersion
validateNewVersion(Resource $resource)
Definition: ResourceMapper.php:113
Drupal\metastore
Drupal\common\Resource
Definition: Resource.php:29
Drupal\metastore\ResourceMapper\registerNewPerspective
registerNewPerspective(Resource $resource)
Definition: ResourceMapper.php:75
Drupal\metastore\ResourceMapper\filePathExists
filePathExists($filePath)
Definition: ResourceMapper.php:228
Drupal\datastore\Service\ResourceLocalizer
Definition: ResourceLocalizer.php:24
Drupal\metastore\ResourceMapper\getStore
getStore()
Definition: ResourceMapper.php:252
Drupal\common\Resource\DEFAULT_SOURCE_PERSPECTIVE
const DEFAULT_SOURCE_PERSPECTIVE
Definition: Resource.php:32
Drupal\metastore\ResourceMapper\DEREFERENCE_NO
const DEREFERENCE_NO
Definition: ResourceMapper.php:21
Drupal\common\Resource\getPerspective
getPerspective()
Definition: Resource.php:188
Drupal\common\Resource\getVersion
getVersion()
Definition: Resource.php:181
Drupal\common\Storage\DatabaseTableInterface
Definition: DatabaseTableInterface.php:13
Drupal\metastore\ResourceMapper\__construct
__construct(DatabaseTableInterface $store)
Definition: ResourceMapper.php:41
Drupal\metastore\ResourceMapper\EVENT_RESOURCE_MAPPER_PRE_REMOVE_SOURCE
const EVENT_RESOURCE_MAPPER_PRE_REMOVE_SOURCE
Definition: ResourceMapper.php:19
Drupal\common\Resource\generateChecksum
generateChecksum()
Definition: Resource.php:304
Drupal\datastore\Service\ResourceLocalizer\LOCAL_FILE_PERSPECTIVE
const LOCAL_FILE_PERSPECTIVE
Definition: ResourceLocalizer.php:28
Drupal\metastore\ResourceMapper
Definition: ResourceMapper.php:15
Drupal\common\Storage\Query
Definition: Query.php:13
Drupal\metastore\ResourceMapper\EVENT_REGISTRATION
const EVENT_REGISTRATION
Definition: ResourceMapper.php:18
Drupal\metastore\ResourceMapper\DEREFERENCE_YES
const DEREFERENCE_YES
Definition: ResourceMapper.php:22
Drupal\metastore\ResourceMapper\registerNewVersion
registerNewVersion(Resource $resource)
Definition: ResourceMapper.php:104
Drupal\common\Resource\getIdentifier
getIdentifier()
Definition: Resource.php:153