diff --git a/lib/Alchemy/Phrasea/Controller/Api/InstanceIdAware.php b/lib/Alchemy/Phrasea/Controller/Api/InstanceIdAware.php new file mode 100644 index 0000000000..6d93a27921 --- /dev/null +++ b/lib/Alchemy/Phrasea/Controller/Api/InstanceIdAware.php @@ -0,0 +1,31 @@ +instanceId = $conf->get( + ['main', 'instance_id'], + md5($conf->get(['main', 'key'], '')) + ); + + return $this; + } + + public function getResourceIdResolver() + { + return function(\record_adapter $record): string { + return $this->instanceId . '_' . $record->getDataboxId() . '_' . $record->getRecordId(); + }; + } +} diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php index 4b2737e01d..728cb743a3 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php @@ -113,6 +113,7 @@ class V1Controller extends Controller use DispatcherAware; use FilesystemAware; use JsonBodyAware; + use InstanceIdAware; const OBJECT_TYPE_USER = 'http://api.phraseanet.com/api/objects/user'; const OBJECT_TYPE_STORY = 'http://api.phraseanet.com/api/objects/story'; @@ -1216,7 +1217,7 @@ public function searchAction(Request $request) { $subdefTransformer = new SubdefTransformer($this->app['acl'], $this->getAuthenticatedUser(), new PermalinkTransformer()); $technicalDataTransformer = new TechnicalDataTransformer(); - $recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer); + $recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer, $this->getResourceIdResolver()); $storyTransformer = new StoryTransformer($subdefTransformer, $recordTransformer); $compositeTransformer = new V1SearchCompositeResultTransformer($recordTransformer, $storyTransformer); $searchTransformer = new V1SearchResultTransformer($compositeTransformer); @@ -1275,7 +1276,7 @@ public function searchRecordsAction(Request $request) { $subdefTransformer = new SubdefTransformer($this->app['acl'], $this->getAuthenticatedUser(), new PermalinkTransformer()); $technicalDataTransformer = new TechnicalDataTransformer(); - $recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer); + $recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer, $this->getResourceIdResolver()); $searchTransformer = new V1SearchRecordsResultTransformer($recordTransformer); $transformerResolver = new SearchResultTransformerResolver([ @@ -1667,6 +1668,7 @@ private function listRecord(Request $request, record_adapter $record) $data = [ 'databox_id' => $record->getDataboxId(), 'record_id' => $record->getRecordId(), + 'resource_id' => ($this->getResourceIdResolver())($record), 'mime_type' => $record->getMimeType(), 'title' => $record->get_title(['encode'=> record_adapter::ENCODE_NONE]), 'original_name' => $record->get_original_name(), @@ -1721,17 +1723,18 @@ private function listStory(Request $request, record_adapter $story) }; return [ - '@entity@' => self::OBJECT_TYPE_STORY, - 'databox_id' => $story->getDataboxId(), - 'story_id' => $story->getRecordId(), + '@entity@' => self::OBJECT_TYPE_STORY, + 'databox_id' => $story->getDataboxId(), + 'story_id' => $story->getRecordId(), + 'resource_id' => ($this->getResourceIdResolver())($story), 'cover_record_id' => $story->getCoverRecordId(), - 'updated_on' => $story->getUpdated()->format(DATE_ATOM), - 'created_on' => $story->getCreated()->format(DATE_ATOM), - 'collection_id' => $story->getCollectionId(), - 'base_id' => $story->getBaseId(), - 'thumbnail' => $this->listEmbeddableMedia($request, $story, $story->get_thumbnail()), - 'uuid' => $story->getUuid(), - 'metadatas' => [ + 'updated_on' => $story->getUpdated()->format(DATE_ATOM), + 'created_on' => $story->getCreated()->format(DATE_ATOM), + 'collection_id' => $story->getCollectionId(), + 'base_id' => $story->getBaseId(), + 'thumbnail' => $this->listEmbeddableMedia($request, $story, $story->get_thumbnail()), + 'uuid' => $story->getUuid(), + 'metadatas' => [ '@entity@' => self::OBJECT_TYPE_STORY_METADATA_BAG, 'dc:contributor' => $format($caption, \databox_Field_DCESAbstract::Contributor), 'dc:coverage' => $format($caption, \databox_Field_DCESAbstract::Coverage), @@ -1749,7 +1752,7 @@ private function listStory(Request $request, record_adapter $story) 'dc:title' => $format($caption, \databox_Field_DCESAbstract::Title), 'dc:type' => $format($caption, \databox_Field_DCESAbstract::Type), ], - 'records' => $this->listRecords($request, array_values($story->getChildren()->get_elements())), + 'records' => $this->listRecords($request, array_values($story->getChildren()->get_elements())), ]; } diff --git a/lib/Alchemy/Phrasea/Controller/Api/V3/V3ResultHelpers.php b/lib/Alchemy/Phrasea/Controller/Api/V3/V3ResultHelpers.php index 1a4849fc22..f2cc28e482 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V3/V3ResultHelpers.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V3/V3ResultHelpers.php @@ -5,6 +5,7 @@ use ACL; use Alchemy\Phrasea\Authentication\Authenticator; +use Alchemy\Phrasea\Controller\Api\InstanceIdAware; use Alchemy\Phrasea\Core\Configuration\PropertyAccess; use Alchemy\Phrasea\Media\MediaSubDefinitionUrlGenerator; use databox_status; @@ -17,6 +18,8 @@ class V3ResultHelpers { + use InstanceIdAware; + /** @var PropertyAccess */ private $conf; @@ -151,6 +154,7 @@ public function listRecord(Request $request, record_adapter $record, ACL $aclfor $data = [ 'databox_id' => $record->getDataboxId(), 'record_id' => $record->getRecordId(), + 'resource_id' => ($this->getResourceIdResolver())($record), 'mime_type' => $record->getMimeType(), 'title' => $record->get_title(['encode'=> record_adapter::ENCODE_NONE]), 'original_name' => $record->get_original_name(), diff --git a/lib/Alchemy/Phrasea/Controller/Api/V3/V3SearchController.php b/lib/Alchemy/Phrasea/Controller/Api/V3/V3SearchController.php index c16b13fa82..6cfd6bd682 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V3/V3SearchController.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V3/V3SearchController.php @@ -5,6 +5,7 @@ use Alchemy\Phrasea\Application\Helper\DispatcherAware; use Alchemy\Phrasea\Application\Helper\JsonBodyAware; use Alchemy\Phrasea\Collection\Reference\CollectionReference; +use Alchemy\Phrasea\Controller\Api\InstanceIdAware; use Alchemy\Phrasea\Controller\Api\Result; use Alchemy\Phrasea\Controller\Controller; use Alchemy\Phrasea\Databox\DataboxGroupable; @@ -51,6 +52,7 @@ class V3SearchController extends Controller { use JsonBodyAware; use DispatcherAware; + use InstanceIdAware; /** * Search for results @@ -65,7 +67,7 @@ public function searchAction(Request $request) $subdefTransformer = new SubdefTransformer($this->app['acl'], $this->getAuthenticatedUser(), new PermalinkTransformer()); $technicalDataTransformer = new TechnicalDataTransformer(); - $recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer); + $recordTransformer = new RecordTransformer($subdefTransformer, $technicalDataTransformer, $this->getResourceIdResolver()); $storyTransformer = new V3StoryTransformer($recordTransformer); $compositeTransformer = new V3SearchCompositeResultTransformer($recordTransformer, $storyTransformer); $searchTransformer = new V3SearchResultTransformer($compositeTransformer); diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Api/V1.php b/lib/Alchemy/Phrasea/ControllerProvider/Api/V1.php index bdc7a8cd50..a7cc39aa8e 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Api/V1.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Api/V1.php @@ -38,7 +38,9 @@ public function register(Application $app) ->setDataboxLoggerLocator($app['phraseanet.logger']) ->setDispatcher($app['dispatcher']) ->setFileSystemLocator(new LazyLocator($app, 'filesystem')) - ->setJsonBodyHelper(new LazyLocator($app, 'json.body_helper')); + ->setJsonBodyHelper(new LazyLocator($app, 'json.body_helper')) + ->setInstanceId($app['conf']) + ; }); } @@ -186,6 +188,7 @@ public function connect(Application $app) ->assert('databox_id', '\d+') ->assert('record_id', '\d+'); + /** @uses \Alchemy\Phrasea\Controller\Api\V1Controller::getRecordAction */ $controllers->get('/records/{databox_id}/{record_id}/', 'controller.api.v1:getRecordAction') ->before('controller.api.v1:ensureCanAccessToRecord') ->assert('databox_id', '\d+') @@ -238,6 +241,7 @@ public function connect(Application $app) ->assert('record_id', '\d+'); $controllers->get('/stories/{any_id}/{anyother_id}/embed/', 'controller.api.v1:getBadRequestAction'); + /** @uses \Alchemy\Phrasea\Controller\Api\V1Controller::getStoryAction */ $controllers->get('/stories/{databox_id}/{record_id}/', 'controller.api.v1:getStoryAction') ->before('controller.api.v1:ensureCanAccessToRecord') ->assert('databox_id', '\d+') diff --git a/lib/Alchemy/Phrasea/ControllerProvider/Api/V3.php b/lib/Alchemy/Phrasea/ControllerProvider/Api/V3.php index e7797eaf92..dafff86a2f 100644 --- a/lib/Alchemy/Phrasea/ControllerProvider/Api/V3.php +++ b/lib/Alchemy/Phrasea/ControllerProvider/Api/V3.php @@ -30,8 +30,8 @@ public function register(Application $app) $app['conf'], $app['media_accessor.subdef_url_generator'], $app['authentication'], - $app['url_generator'] - )); + $app['url_generator'])) + ->setInstanceId($app['conf']); }); $app['controller.api.v3.subdefs_service'] = $app->share(function (PhraseaApplication $app) { return (new V3SubdefsServiceController($app)) @@ -46,7 +46,9 @@ public function register(Application $app) ; }); $app['controller.api.v3.search'] = $app->share(function (PhraseaApplication $app) { - return (new V3SearchController($app)); + return (new V3SearchController($app)) + ->setInstanceId($app['conf']) + ; }); $app['controller.api.v3.searchraw'] = $app->share(function (PhraseaApplication $app) { return (new V3SearchRawController($app)); diff --git a/lib/Alchemy/Phrasea/Search/RecordTransformer.php b/lib/Alchemy/Phrasea/Search/RecordTransformer.php index 7dd6cd5a5e..9f6a715e93 100644 --- a/lib/Alchemy/Phrasea/Search/RecordTransformer.php +++ b/lib/Alchemy/Phrasea/Search/RecordTransformer.php @@ -41,10 +41,16 @@ class RecordTransformer extends TransformerAbstract */ private $technicalDataTransformer; - public function __construct(SubdefTransformer $subdefTransformer, TechnicalDataTransformer $technicalDataTransformer) + /** + * @var callable + */ + private $resourceIdResolver; + + public function __construct(SubdefTransformer $subdefTransformer, TechnicalDataTransformer $technicalDataTransformer, callable $resourceIdResolver) { $this->subdefTransformer = $subdefTransformer; $this->technicalDataTransformer = $technicalDataTransformer; + $this->resourceIdResolver = $resourceIdResolver; } public function transform($recordView) @@ -55,6 +61,7 @@ public function transform($recordView) return [ 'databox_id' => $record->getDataboxId(), 'record_id' => $record->getRecordId(), + 'resource_id' => ($this->resourceIdResolver)($record), 'mime_type' => $record->getMimeType(), 'title' => $record->get_title(['encode'=> record_adapter::ENCODE_NONE]), 'original_name' => $record->get_original_name(), @@ -160,4 +167,12 @@ public function includeCaption(RecordView $recordView) ]; }); } + + /** + * @return callable + */ + public function getResourceIdResolver(): callable + { + return $this->resourceIdResolver; + } } diff --git a/lib/Alchemy/Phrasea/Search/StoryTransformer.php b/lib/Alchemy/Phrasea/Search/StoryTransformer.php index 17f67f0e64..4fb17274b6 100644 --- a/lib/Alchemy/Phrasea/Search/StoryTransformer.php +++ b/lib/Alchemy/Phrasea/Search/StoryTransformer.php @@ -53,6 +53,7 @@ public function transform(StoryView $storyView) '@entity@' => 'http://api.phraseanet.com/api/objects/story', 'databox_id' => $story->getDataboxId(), 'story_id' => $story->getRecordId(), + 'resource_id' => ($this->recordTransformer->getResourceIdResolver())($story), 'cover_record_id' => $story->getCoverRecordId(), 'updated_on' => NullableDateTime::format($story->getUpdated()), 'created_on' => NullableDateTime::format($story->getUpdated()),