Beispiel #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);
     }
 }
Beispiel #2
0
 public function update(Media $media, Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     $html = $data['o:media']['__index__']['html'];
     $serviceLocator = $this->getServiceLocator();
     $purifier = $serviceLocator->get('Omeka\\HtmlPurifier');
     $html = $purifier->purify($html);
     $media->setData(['html' => $html]);
 }
Beispiel #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');
     }
 }
Beispiel #4
0
 /**
  * {@inheritDoc}
  */
 public function validateRequest(Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (array_key_exists('o:class', $data) && !is_array($data['o:class'])) {
         $errorStore->addError('o:item_set', 'Classes must be an array');
     }
     if (array_key_exists('o:property', $data) && !is_array($data['o:property'])) {
         $errorStore->addError('o:item_set', 'Properties must be an array');
     }
 }
Beispiel #5
0
 public function ingest(Media $media, Request $request, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (!isset($data['o:source'])) {
         $errorStore->addError('o:source', 'No OEmbed URL specified');
         return;
     }
     $config = $this->getServiceLocator()->get('Config');
     $whitelist = $config['oembed']['whitelist'];
     $whitelisted = false;
     foreach ($whitelist as $regex) {
         if (preg_match($regex, $data['o:source']) === 1) {
             $whitelisted = true;
             break;
         }
     }
     if (!$whitelisted) {
         $errorStore->addError('o:source', 'Invalid OEmbed URL');
         return;
     }
     $source = $data['o:source'];
     $response = $this->makeRequest($source, 'OEmbed URL', $errorStore);
     if (!$response) {
         return;
     }
     $document = $response->getBody();
     $dom = new Query($document);
     $oEmbedLinks = $dom->queryXpath('//link[@rel="alternate" or @rel="alternative"][@type="application/json+oembed"]');
     if (!count($oEmbedLinks)) {
         $errorStore->addError('o:source', 'No OEmbed links were found at the given URI');
         return;
     }
     $oEmbedLink = $oEmbedLinks[0];
     $linkResponse = $this->makeRequest($oEmbedLink->getAttribute('href'), 'OEmbed link URL', $errorStore);
     if (!$linkResponse) {
         return;
     }
     $mediaData = json_decode($linkResponse->getBody(), true);
     if (!$mediaData) {
         $errorStore->addError('o:source', 'Error decoding OEmbed JSON');
         return;
     }
     if (isset($mediaData['thumbnail_url'])) {
         $fileManager = $this->getServiceLocator()->get('Omeka\\File\\Manager');
         $file = $this->getServiceLocator()->get('Omeka\\File');
         $this->downloadFile($mediaData['thumbnail_url'], $file->getTempPath());
         $hasThumbnails = $fileManager->storeThumbnails($file);
         if ($hasThumbnails) {
             $media->setFilename($file->getStorageName());
             $media->setHasThumbnails(true);
         }
     }
     $media->setData($mediaData);
     $media->setSource($source);
 }
Beispiel #6
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);
         }
     }
 }
Beispiel #7
0
 /**
  * {@inheritDoc}
  */
 public function hydrate(Request $request, EntityInterface $entity, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     $this->hydrateOwner($request, $entity);
     if ($this->shouldHydrate($request, 'o:local_name')) {
         $entity->setLocalName($request->getValue('o:local_name'));
     }
     if ($this->shouldHydrate($request, 'o:label')) {
         $entity->setLabel($request->getValue('o:label'));
     }
     if ($this->shouldHydrate($request, 'o:comment')) {
         $entity->setComment($request->getValue('o:comment'));
     }
 }
Beispiel #8
0
 /**
  * {@inheritDoc}
  */
 public function hydrate(Request $request, EntityInterface $entity, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (Request::CREATE === $request->getOperation() && isset($data['o:site']['o:id'])) {
         $site = $this->getAdapter('sites')->findEntity($data['o:site']['o:id']);
         $this->authorize($site, 'add-page');
         $entity->setSite($site);
     }
     if ($this->shouldHydrate($request, 'o:slug')) {
         $entity->setSlug($request->getValue('o:slug'));
     }
     if ($this->shouldHydrate($request, 'o:title')) {
         $entity->setTitle($request->getValue('o:title'));
     }
     $appendBlocks = $request->getOperation() === Request::UPDATE && $request->isPartial();
     $this->hydrateBlocks($request->getValue('o:block', []), $entity, $errorStore, $appendBlocks);
 }
 /**
  * {@inheritDoc}
  */
 public function hydrate(Request $request, EntityInterface $entity, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if ($this->shouldHydrate($request, 'o:is_public')) {
         $entity->setIsPublic($request->getValue('o:is_public', true));
     }
     // Hydrate this resource's values.
     $append = $request->getOperation() === Request::UPDATE && $request->isPartial();
     $valueHydrator = new ValueHydrator($this);
     $valueHydrator->hydrate($data, $entity, $append);
     // o:owner
     $this->hydrateOwner($request, $entity);
     // o:resource_class
     $this->hydrateResourceClass($request, $entity);
     // o:resource_template
     $this->hydrateResourceTemplate($request, $entity);
 }
Beispiel #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);
     }
 }
Beispiel #11
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']);
     }
 }
Beispiel #12
0
 /**
  * {@inheritDoc}
  */
 public function hydrate(Request $request, EntityInterface $entity, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     if (Request::CREATE === $request->getOperation()) {
         // Accept the passed ingester only on CREATE to prevent overwriting
         // on subsequent UPDATE requests.
         $ingesterName = $request->getValue('o:ingester');
     } else {
         $ingesterName = $entity->getIngester();
     }
     $ingester = $this->getServiceLocator()->get('Omeka\\MediaIngesterManager')->get($ingesterName);
     if (Request::CREATE === $request->getOperation()) {
         if ($ingester instanceof Fallback) {
             $errorStore->addError('o:ingester', 'Media must set a valid ingester.');
             return;
         }
         $entity->setIngester($ingesterName);
         $entity->setRenderer($ingester->getRenderer());
         if (isset($data['o:item']['o:id'])) {
             $item = $this->getAdapter('items')->findEntity($data['o:item']['o:id']);
             $entity->setItem($item);
         }
         if (isset($data['data'])) {
             $entity->setData($data['data']);
         }
         if (isset($data['o:source'])) {
             $entity->setSource($data['o:source']);
         }
     }
     parent::hydrate($request, $entity, $errorStore);
     if ($this->shouldHydrate($request, 'o:lang')) {
         $entity->setLang($request->getValue('o:lang', null));
     }
     if (Request::CREATE === $request->getOperation()) {
         $ingester->ingest($entity, $request, $errorStore);
     } elseif ($ingester instanceof MutableIngesterInterface) {
         $ingester->update($entity, $request, $errorStore);
     }
 }
Beispiel #13
0
 /**
  * Execute a batch create operation.
  *
  * @param Request $request
  * @param null|AdapterInterface $adapter Custom adapter
  * @return Response
  */
 protected function executeBatchCreate(Request $request, AdapterInterface $adapter)
 {
     $t = $this->getTranslator();
     if (!is_array($request->getContent())) {
         throw new Exception\BadRequestException($t->translate('Invalid batch operation request data.'));
     }
     // Create a simulated request for individual create events.
     $createRequest = new Request(Request::CREATE, $request->getResource());
     // Trigger the create.pre event for every resource.
     foreach ($request->getContent() as $content) {
         $createRequest->setContent($content);
         $createEvent = new Event(Event::API_CREATE_PRE, $adapter, ['request' => $createRequest]);
         $adapter->getEventManager()->trigger($createEvent);
     }
     $response = $adapter->batchCreate($request);
     // Do not trigger create.post events if an error has occured or if the
     // response does not return valid content.
     if ($response->isError() || !is_array($response->getContent())) {
         return $response;
     }
     // Trigger the create.post event for every created resource.
     foreach ($response->getContent() as $resource) {
         $createRequest->setContent($resource);
         $createEvent = new Event(Event::API_CREATE_POST, $adapter, ['request' => $createRequest, 'response' => new Response($resource)]);
         $adapter->getEventManager()->trigger($createEvent);
     }
     return $response;
 }
 /**
  * {@inheritDoc}
  */
 public function hydrate(Request $request, EntityInterface $entity, ErrorStore $errorStore)
 {
     $data = $request->getContent();
     $this->hydrateOwner($request, $entity);
     $this->hydrateResourceClass($request, $entity);
     if ($this->shouldHydrate($request, 'o:label')) {
         $entity->setLabel($request->getValue('o:label'));
     }
     if ($this->shouldHydrate($request, 'o:resource_template_property') && isset($data['o:resource_template_property']) && is_array($data['o:resource_template_property'])) {
         // Get a resource template property by property ID.
         $getResTemProp = function ($propertyId, $resTemProps) {
             foreach ($resTemProps as $resTemProp) {
                 if ($propertyId == $resTemProp->getProperty()->getId()) {
                     return $resTemProp;
                 }
             }
             return null;
         };
         $propertyAdapter = $this->getAdapter('properties');
         $resTemProps = $entity->getResourceTemplateProperties();
         $resTemPropsToRetain = [];
         $position = 1;
         foreach ($data['o:resource_template_property'] as $resTemPropData) {
             if (!isset($resTemPropData['o:property']['o:id'])) {
                 continue;
                 // skip when no property ID
             }
             $propertyId = $resTemPropData['o:property']['o:id'];
             $altLabel = null;
             if (isset($resTemPropData['o:alternate_label']) && '' !== trim($resTemPropData['o:alternate_label'])) {
                 $altLabel = $resTemPropData['o:alternate_label'];
             }
             $altComment = null;
             if (isset($resTemPropData['o:alternate_comment']) && '' !== trim($resTemPropData['o:alternate_comment'])) {
                 $altComment = $resTemPropData['o:alternate_comment'];
             }
             // Check whether a passed property is already assigned to this
             // resource template.
             $resTemProp = $getResTemProp($propertyId, $resTemProps);
             if ($resTemProp) {
                 // It is already assigned. Modify the existing entity.
                 $resTemProp->setAlternateLabel($altLabel);
                 $resTemProp->setAlternateComment($altComment);
             } else {
                 // It is not assigned. Add a new resource template property.
                 // No need to explicitly add it to the collection since it
                 // is added implicitly when setting the resource template.
                 $property = $propertyAdapter->findEntity($propertyId);
                 $resTemProp = new ResourceTemplateProperty();
                 $resTemProp->setResourceTemplate($entity);
                 $resTemProp->setProperty($property);
                 $resTemProp->setAlternateLabel($altLabel);
                 $resTemProp->setAlternateComment($altComment);
                 $entity->getResourceTemplateProperties()->add($resTemProp);
             }
             // Set the position of the property to its intrinsic order
             // within the passed array.
             $resTemProp->setPosition($position++);
             $resTemPropsToRetain[] = $resTemProp;
         }
         // Remove resource template properties that were not included in the
         // passed data.
         foreach ($resTemProps as $resTemPropId => $resTemProp) {
             if (!in_array($resTemProp, $resTemPropsToRetain)) {
                 $resTemProps->remove($resTemPropId);
             }
         }
     }
 }
 /**
  * Hydrate the entity's resource template.
  *
  * Assumes the resource template can be set to NULL.
  *
  * @param Request $request
  * @param EntityInterface $entity
  */
 public function hydrateResourceTemplate(Request $request, EntityInterface $entity)
 {
     $data = $request->getContent();
     $resourceTemplate = $entity->getResourceTemplate();
     if ($this->shouldHydrate($request, 'o:resource_template')) {
         if (isset($data['o:resource_template']['o:id']) && is_numeric($data['o:resource_template']['o:id'])) {
             $resourceTemplate = $this->getAdapter('resource_templates')->findEntity($data['o:resource_template']['o:id']);
         } else {
             $resourceTemplate = null;
         }
     }
     $entity->setResourceTemplate($resourceTemplate);
 }