Example #1
0
 /**
  * Ingest from a URL.
  *
  * Accepts the following non-prefixed keys:
  *
  * + ingest_url: (required) The URL to ingest. The idea is that some URLs
  *   contain sensitive data that should not be saved to the database, such
  *   as private keys. To preserve the URL, remove sensitive data from the
  *   URL and set it to o:source.
  * + store_original: (optional, default true) Whether to store an original
  *   file. This is helpful when you want the media to have thumbnails but do
  *   not need the original file.
  *
  * {@inheritDoc}
  */
 public function ingest(Media $media, Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (!isset($data['ingest_url'])) {
         $errorStore->addError('error', 'No ingest URL specified');
         return;
     }
     $uri = new HttpUri($data['ingest_url']);
     if (!($uri->isValid() && $uri->isAbsolute())) {
         $errorStore->addError('ingest_url', 'Invalid ingest URL');
         return;
     }
     $file = $this->getServiceLocator()->get('Omeka\\File');
     $file->setSourceName($uri->getPath());
     $this->downloadFile($uri, $file->getTempPath());
     $fileManager = $this->getServiceLocator()->get('Omeka\\File\\Manager');
     $hasThumbnails = $fileManager->storeThumbnails($file);
     $media->setHasThumbnails($hasThumbnails);
     if (!isset($data['store_original']) || $data['store_original']) {
         $fileManager->storeOriginal($file);
         $media->setHasOriginal(true);
     }
     $media->setFilename($file->getStorageName());
     $media->setMediaType($file->getMediaType());
     if (!array_key_exists('o:source', $data)) {
         $media->setSource($uri);
     }
 }
Example #2
0
 public function testMergesErrors()
 {
     $this->response->addError('foo', 'foo_message_one');
     $errorStore = new ErrorStore();
     $errorStore->addError('foo', 'foo_message_two');
     $errorStore->addError('bar', 'bar_message');
     $this->response->mergeErrors($errorStore);
     $this->assertEquals(['foo' => ['foo_message_one', 'foo_message_two'], 'bar' => ['bar_message']], $this->response->getErrors());
 }
Example #3
0
 /**
  * {@inheritDoc}
  */
 public function validateRequest(Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (array_key_exists('o:item_set', $data) && !is_array($data['o:item_set'])) {
         $errorStore->addError('o:item_set', 'Item sets must be an array');
     }
     if (array_key_exists('o:media', $data) && !is_array($data['o:media'])) {
         $errorStore->addError('o:item_set', 'Media must be an array');
     }
 }
 /**
  * {@inheritDoc}
  */
 public function validateEntity(EntityInterface $entity, ErrorStore $errorStore)
 {
     $label = $entity->getLabel();
     if (false == trim($label)) {
         $errorStore->addError('o:label', 'The label cannot be empty.');
     }
     if (!$this->isUnique($entity, ['label' => $label])) {
         $errorStore->addError('o:label', 'The label is already taken.');
     }
 }
Example #5
0
 public function isValid(array $data, ErrorStore $errorStore)
 {
     if (!isset($data['label'])) {
         $errorStore->addError('o:navigation', 'Invalid navigation: URL link missing label');
         return false;
     }
     if (!isset($data['url'])) {
         $errorStore->addError('o:navigation', 'Invalid navigation: URL link missing URL');
         return false;
     }
     return true;
 }
Example #6
0
 /**
  * {@inheritDoc}
  */
 public function validateEntity(EntityInterface $entity, ErrorStore $errorStore)
 {
     if (false == $entity->getName()) {
         $errorStore->addError('o:name', 'The name cannot be empty.');
     }
     $email = $entity->getEmail();
     $validator = new EmailAddress();
     if (!$validator->isValid($email)) {
         $errorStore->addValidatorMessages('o:email', $validator->getMessages());
     }
     if (!$this->isUnique($entity, ['email' => $email])) {
         $errorStore->addError('o:email', sprintf('The email "%s" is already taken.', $email));
     }
     if (false == $entity->getRole()) {
         $errorStore->addError('o:role', 'Users must have a role.');
     }
 }
Example #7
0
 /**
  * {@inheritDoc}
  */
 public function ingest(Media $media, Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     $fileData = $request->getFileData();
     if (!isset($fileData['file'])) {
         $errorStore->addError('error', 'No files were uploaded');
         return;
     }
     if (!isset($data['file_index'])) {
         $errorStore->addError('error', 'No file index was specified');
         return;
     }
     $index = $data['file_index'];
     if (!isset($fileData['file'][$index])) {
         $errorStore->addError('error', 'No file uploaded for the specified index');
         return;
     }
     $fileManager = $this->getServiceLocator()->get('Omeka\\File\\Manager');
     $file = $this->getServiceLocator()->get('Omeka\\File');
     $fileInput = new FileInput('file');
     $fileInput->getFilterChain()->attach(new RenameUpload(['target' => $file->getTempPath(), 'overwrite' => true]));
     $fileData = $fileData['file'][$index];
     $fileInput->setValue($fileData);
     if (!$fileInput->isValid()) {
         foreach ($fileInput->getMessages() as $message) {
             $errorStore->addError('upload', $message);
         }
         return;
     }
     // Actually process and move the upload
     $fileInput->getValue();
     $file->setSourceName($fileData['name']);
     $hasThumbnails = $fileManager->storeThumbnails($file);
     $fileManager->storeOriginal($file);
     $media->setFilename($file->getStorageName());
     $media->setMediaType($file->getMediaType());
     $media->setHasThumbnails($hasThumbnails);
     $media->setHasOriginal(true);
     if (!array_key_exists('o:source', $data)) {
         $media->setSource($fileData['name']);
     }
 }
Example #8
0
 public function isValid(array $data, ErrorStore $errorStore)
 {
     if (!isset($data['label'])) {
         $errorStore->addError('o:navigation', 'Invalid navigation: page link missing label');
         return false;
     }
     if (!isset($data['id'])) {
         $errorStore->addError('o:navigation', 'Invalid navigation: page link missing page ID');
         return false;
     }
     if (!isset($data['pageSlug'])) {
         $errorStore->addError('o:navigation', 'Invalid navigation: page link missing page slug');
         return false;
     }
     if (!isset($data['pageTitle'])) {
         $errorStore->addError('o:navigation', 'Invalid navigation: page link missing page title');
         return false;
     }
     return true;
 }
Example #9
0
 public function ingest(Media $media, Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (!isset($data['o:source'])) {
         $errorStore->addError('o:source', 'No IIIF Image URL specified');
         return;
     }
     $source = $data['o:source'];
     //Make a request and handle any errors that might occur.
     $uri = new HttpUri($source);
     if (!($uri->isValid() && $uri->isAbsolute())) {
         $errorStore->addError('o:source', "Invalid url specified");
         return false;
     }
     $client = $this->getServiceLocator()->get('Omeka\\HttpClient');
     $client->setUri($uri);
     $response = $client->send();
     if (!$response->isOk()) {
         $errorStore->addError('o:source', sprintf("Error reading %s: %s (%s)", $type, $response->getReasonPhrase(), $response->getStatusCode()));
         return false;
     }
     $IIIFData = json_decode($response->getBody(), true);
     if (!$IIIFData) {
         $errorStore->addError('o:source', 'Error decoding IIIF JSON');
         return;
     }
     //Check if valid IIIF data
     if ($this->validate($IIIFData)) {
         $media->setData($IIIFData);
         // Not IIIF
     } else {
         $errorStore->addError('o:source', 'URL does not link to IIIF JSON');
         return;
     }
     //Check API version and generate a thumbnail
     //Version 2.0
     if (isset($IIIFData['@context']) && $IIIFData['@context'] == 'http://iiif.io/api/image/2/context.json') {
         $URLString = '/full/full/0/default.jpg';
         // Earlier versions
     } else {
         $URLString = '/full/full/0/native.jpg';
     }
     if (isset($IIIFData['@id'])) {
         $fileManager = $this->getServiceLocator()->get('Omeka\\File\\Manager');
         $file = $this->getServiceLocator()->get('Omeka\\File');
         $this->downloadFile($IIIFData['@id'] . $URLString, $file->getTempPath());
         $hasThumbnails = $fileManager->storeThumbnails($file);
         if ($hasThumbnails) {
             $media->setFilename($file->getStorageName());
             $media->setHasThumbnails(true);
         }
     }
 }
Example #10
0
 public function ingest(Media $media, Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (!isset($data['o:source'])) {
         $errorStore->addError('o:source', 'No YouTube URL specified');
         return;
     }
     $uri = new HttpUri($data['o:source']);
     if (!($uri->isValid() && $uri->isAbsolute())) {
         $errorStore->addError('o:source', 'Invalid YouTube URL specified');
         return;
     }
     switch ($uri->getHost()) {
         case 'www.youtube.com':
             if ('/watch' !== $uri->getPath()) {
                 $errorStore->addError('o:source', 'Invalid YouTube URL specified, missing "/watch" path');
                 return;
             }
             $query = $uri->getQueryAsArray();
             if (!isset($query['v'])) {
                 $errorStore->addError('o:source', 'Invalid YouTube URL specified, missing "v" parameter');
                 return;
             }
             $youtubeId = $query['v'];
             break;
         case 'youtu.be':
             $youtubeId = substr($uri->getPath(), 1);
             break;
         default:
             $errorStore->addError('o:source', 'Invalid YouTube URL specified, not a YouTube URL');
             return;
     }
     $fileManager = $this->getServiceLocator()->get('Omeka\\File\\Manager');
     $file = $this->getServiceLocator()->get('Omeka\\File');
     $url = sprintf('http://img.youtube.com/vi/%s/0.jpg', $youtubeId);
     $this->downloadFile($url, $file->getTempPath());
     $hasThumbnails = $fileManager->storeThumbnails($file);
     $media->setData(['id' => $youtubeId, 'start' => $request->getValue('start'), 'end' => $request->getValue('end')]);
     if ($hasThumbnails) {
         $media->setFilename($file->getStorageName());
         $media->setHasThumbnails(true);
     }
 }
Example #11
0
 /**
  * Hydrate block data for the page.
  *
  * @param array $blockData
  * @param SitePage $page
  * @param bool $append
  */
 private function hydrateBlocks(array $blockData, SitePage $page, ErrorStore $errorStore, $append = false)
 {
     $blocks = $page->getBlocks();
     $existingBlocks = $blocks->toArray();
     $newBlocks = [];
     $position = 1;
     $fallbackBlock = ['o:layout' => null, 'o:data' => []];
     foreach ($blockData as $inputBlock) {
         if (!is_array($inputBlock)) {
             continue;
         }
         $inputBlock = array_merge($fallbackBlock, $inputBlock);
         $block = current($existingBlocks);
         if ($block === false || $append) {
             $block = new SitePageBlock();
             $block->setPage($page);
             $newBlocks[] = $block;
         } else {
             // Null out values as we re-use them
             $existingBlocks[key($existingBlocks)] = null;
             next($existingBlocks);
         }
         if (!is_string($inputBlock['o:layout']) || $inputBlock['o:layout'] === '') {
             $errorStore->addError('o:block', 'All blocks must have a layout.');
             return;
         }
         if (!is_array($inputBlock['o:data'])) {
             $errorStore->addError('o:block', 'Block data must not be a scalar value.');
             return;
         }
         $block->setLayout($inputBlock['o:layout']);
         $block->setData($inputBlock['o:data']);
         // (Re-)order blocks by their order in the input
         $block->setPosition($position++);
         $attachmentData = isset($inputBlock['o:attachment']) ? $inputBlock['o:attachment'] : [];
         // Hydrate attachments, and abort block hydration if there's an error
         if (!$this->hydrateAttachments($attachmentData, $block, $errorStore)) {
             return;
         }
         $handler = $this->getServiceLocator()->get('Omeka\\BlockLayoutManager')->get($inputBlock['o:layout'])->onHydrate($block, $errorStore);
     }
     // Remove any blocks that weren't reused
     if (!$append) {
         foreach ($existingBlocks as $key => $existingBlock) {
             if ($existingBlock !== null) {
                 $blocks->remove($key);
             }
         }
     }
     // Add any new blocks that had to be created
     foreach ($newBlocks as $newBlock) {
         $blocks->add($newBlock);
     }
 }
Example #12
0
 /**
  * Add errors derived from an ErrorStore.
  *
  * @param ErrorStore $errorStore
  */
 public function addErrorStore(ErrorStore $errorStore)
 {
     foreach ($errorStore->getErrors() as $error) {
         foreach ($error as $message) {
             $this->addError($message);
         }
     }
 }
Example #13
0
 /**
  * {@inheritDoc}
  */
 public function validateEntity(EntityInterface $entity, ErrorStore $errorStore)
 {
     // Validate local name
     if (false == $entity->getLocalName()) {
         $errorStore->addError('o:local_name', 'The local name cannot be empty.');
     }
     // Validate label
     if (false == $entity->getLabel()) {
         $errorStore->addError('o:label', 'The label cannot be empty.');
     }
     // Validate vocabulary
     if ($entity->getVocabulary() instanceof Vocabulary) {
         if ($entity->getVocabulary()->getId()) {
             // Vocabulary is persistent. Check for unique local name.
             $criteria = ['vocabulary' => $entity->getVocabulary(), 'localName' => $entity->getLocalName()];
             if (!$this->isUnique($entity, $criteria)) {
                 $errorStore->addError('o:local_name', sprintf('The local name "%s" is already taken.', $entity->getLocalName()));
             }
         }
     } else {
         $errorStore->addError('o:vocabulary', 'A vocabulary must be set.');
     }
 }
Example #14
0
 /**
  * Make a request and handle any errors that might occur.
  *
  * @param string $url URL to request
  * @param string $type Type of URL (used to compose error messages)
  * @param ErrorStore $errorStore
  */
 protected function makeRequest($url, $type, ErrorStore $errorStore)
 {
     $uri = new HttpUri($url);
     if (!($uri->isValid() && $uri->isAbsolute())) {
         $errorStore->addError('o:source', "Invalid {$type} specified");
         return false;
     }
     $client = $this->getServiceLocator()->get('Omeka\\HttpClient');
     $client->setUri($uri);
     $response = $client->send();
     if (!$response->isOk()) {
         $errorStore->addError('o:source', sprintf("Error reading %s: %s (%s)", $type, $response->getReasonPhrase(), $response->getStatusCode()));
         return false;
     }
     return $response;
 }
Example #15
0
 /**
  * {@inheritDoc}
  */
 public function validateEntity(EntityInterface $entity, ErrorStore $errorStore)
 {
     if (!$entity->getItem() instanceof Item) {
         $errorStore->addError('o:item', 'Media must belong to an item.');
     }
 }
Example #16
0
 /**
  * Validate navigation.
  *
  * Prevent corrupt navigation data by validating prior to saving.
  *
  * @param EntityInterface $entity
  * @param ErrorStore $errorStore
  */
 protected function validateNavigation(EntityInterface $entity, ErrorStore $errorStore)
 {
     $navigation = $entity->getNavigation();
     if (!is_array($navigation)) {
         $errorStore->addError('o:navigation', 'Invalid navigation: navigation must be an array');
         return;
     }
     $pagesInNavigation = [];
     $manager = $this->getServiceLocator()->get('Omeka\\Site\\NavigationLinkManager');
     $validateLinks = function ($linksIn) use(&$validateLinks, $manager, $errorStore, $pagesInNavigation) {
         foreach ($linksIn as $key => $data) {
             if (!isset($data['type'])) {
                 $errorStore->addError('o:navigation', 'Invalid navigation: link missing type');
                 return;
             }
             if (!isset($data['data'])) {
                 $errorStore->addError('o:navigation', 'Invalid navigation: link missing data');
                 return;
             }
             if (!$manager->get($data['type'])->isValid($data['data'], $errorStore)) {
                 $errorStore->addError('o:navigation', 'Invalid navigation: invalid link data');
                 return;
             }
             if ('page' === $data['type']) {
                 if (in_array($data['data']['id'], $pagesInNavigation)) {
                     $errorStore->addError('o:navigation', 'Invalid navigation: page links must be unique');
                     return;
                 }
                 $pagesInNavigation[] = $data['data']['id'];
             }
             if (isset($data['links'])) {
                 if (!is_array($data['links'])) {
                     $errorStore->addError('o:navigation', 'Invalid navigation: links must be an array');
                     return;
                 }
                 $validateLinks($data['links']);
             }
         }
     };
     $validateLinks($navigation);
 }
Example #17
0
 /**
  * {@inheritDoc}
  */
 public function validateEntity(EntityInterface $entity, ErrorStore $errorStore)
 {
     // Validate namespace URI
     $namespaceUri = $entity->getNamespaceUri();
     if (false == $entity->getNamespaceUri()) {
         $errorStore->addError('o:namespace_uri', 'The namespace URI cannot be empty.');
     }
     if (!$this->isUnique($entity, ['namespaceUri' => $namespaceUri])) {
         $errorStore->addError('o:namespace_uri', sprintf('The namespace URI "%s" is already taken.', $namespaceUri));
     }
     // Validate prefix
     $prefix = $entity->getPrefix();
     if (false == $entity->getPrefix()) {
         $errorStore->addError('o:prefix', 'The prefix cannot be empty.');
     }
     if (!$this->isUnique($entity, ['prefix' => $prefix])) {
         $errorStore->addError('o:prefix', sprintf('The prefix "%s" is already taken.', $prefix));
     }
     // Validate label
     if (false == $entity->getLabel()) {
         $errorStore->addError('o:label', 'The label cannot be empty.');
     }
     // Check for uniqueness of resource class local names.
     $uniqueLocalNames = [];
     foreach ($entity->getResourceClasses() as $resourceClass) {
         if (in_array($resourceClass->getLocalName(), $uniqueLocalNames)) {
             $errorStore->addError('o:resource_class', sprintf('The local name "%s" is already taken.', $resourceClass->getLocalName()));
         } else {
             $uniqueLocalNames[] = $resourceClass->getLocalName();
         }
     }
     // Check for uniqueness of property local names.
     $uniqueLocalNames = [];
     foreach ($entity->getProperties() as $property) {
         if (in_array($property->getLocalName(), $uniqueLocalNames)) {
             $errorStore->addError('o:resource_class', sprintf('The local name "%s" is already taken.', $property->getLocalName()));
         } else {
             $uniqueLocalNames[] = $property->getLocalName();
         }
     }
 }