From cb206c79bf392e5ca9c4b1e63edf3875b7ec5b47 Mon Sep 17 00:00:00 2001 From: aynsix Date: Tue, 7 Dec 2021 15:24:58 +0300 Subject: [PATCH] PHRAS-3555 add description in record.edit webhook --- .../Phrasea/Controller/Api/V1Controller.php | 6 ++-- .../Controller/Api/V3/V3RecordController.php | 3 +- .../Controller/Prod/StoryController.php | 6 ++-- lib/Alchemy/Phrasea/Core/Event/RecordEdit.php | 14 ++++++++ .../WebhookRecordEventSubscriber.php | 28 +++++++++++++-- .../Worker/CreateRecordWorker.php | 3 +- .../WorkerManager/Worker/EditRecordWorker.php | 3 +- lib/classes/record/adapter.php | 34 ++++++++++++++++++- 8 files changed, 87 insertions(+), 10 deletions(-) diff --git a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php index 7afcfc3ca5..a68e0344c9 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V1Controller.php @@ -2013,6 +2013,7 @@ class V1Controller extends Controller { $databox = $this->findDataboxById($databox_id); $record = $databox->get_record($record_id); + $previousDescription = $record->getRecordDescriptionAsArray(); $statusStructure = $databox->getStatusStructure(); $status = $request->get('status'); @@ -2039,7 +2040,7 @@ class V1Controller extends Controller $record->setStatus(strrev($datas)); // @todo Move event dispatch inside record_adapter class (keeps things encapsulated) - $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record)); + $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record, $previousDescription)); $ret = ["status" => $this->listRecordStatus($record)]; @@ -2624,11 +2625,12 @@ class V1Controller extends Controller { $data = $this->decodeJsonBody($request, 'story_records.json'); $story = new \record_adapter($this->app, $databox_id, $story_id); + $previousDescriptions = $story->getRecordDescriptionAsArray(); $records = $this->addOrDelStoryRecordsFromData($story, $data->story_records, $action); $result = Result::create($request, array('records' => $records)); - $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story)); + $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story, $previousDescriptions)); return $result->createResponse(); } diff --git a/lib/Alchemy/Phrasea/Controller/Api/V3/V3RecordController.php b/lib/Alchemy/Phrasea/Controller/Api/V3/V3RecordController.php index d4d39a2cd1..ffa22a36f5 100644 --- a/lib/Alchemy/Phrasea/Controller/Api/V3/V3RecordController.php +++ b/lib/Alchemy/Phrasea/Controller/Api/V3/V3RecordController.php @@ -249,6 +249,7 @@ class V3RecordController extends Controller public function indexAction_PATCH(Request $request, $databox_id, $record_id) { $record = $this->findDataboxById($databox_id)->get_record($record_id); + $previousDescription = $record->getRecordDescriptionAsArray(); try { $body = $this->decodeJsonBody($request); @@ -265,7 +266,7 @@ class V3RecordController extends Controller } // @todo Move event dispatch inside record_adapter class (keeps things encapsulated) - $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record)); + $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record, $previousDescription)); $ret = $this->getResultHelpers()->listRecord($request, $record, $this->getAclForUser()); diff --git a/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php b/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php index 0f3cefa849..e0848d114e 100644 --- a/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php +++ b/lib/Alchemy/Phrasea/Controller/Prod/StoryController.php @@ -112,6 +112,7 @@ class StoryController extends Controller public function addElementsAction(Request $request, $sbas_id, $record_id) { $Story = new \record_adapter($this->app, $sbas_id, $record_id); + $previousDescription = $Story->getRecordDescriptionAsArray(); if (!$this->getAclForUser()->has_right_on_base($Story->getBaseId(), \ACL::CANMODIFRECORD)) { throw new AccessDeniedHttpException('You can not add document to this Story'); @@ -130,7 +131,7 @@ class StoryController extends Controller $n++; } - $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($Story)); + $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($Story, $previousDescription)); $data = [ 'success' => true, @@ -187,6 +188,7 @@ class StoryController extends Controller { try { $story = new \record_adapter($this->app, $sbas_id, $record_id); + $previousDescription = $story->getRecordDescriptionAsArray(); if (!$story->isStory()) { throw new \Exception('This is not a story'); @@ -210,7 +212,7 @@ class StoryController extends Controller $stmt->closeCursor(); - $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story)); + $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story, $previousDescription)); $ret = ['success' => true, 'message' => $this->app->trans('Story updated')]; } catch (ControllerException $e) { $ret = ['success' => false, 'message' => $e->getMessage()]; diff --git a/lib/Alchemy/Phrasea/Core/Event/RecordEdit.php b/lib/Alchemy/Phrasea/Core/Event/RecordEdit.php index 8f0a7cf258..1c2d50824d 100644 --- a/lib/Alchemy/Phrasea/Core/Event/RecordEdit.php +++ b/lib/Alchemy/Phrasea/Core/Event/RecordEdit.php @@ -15,4 +15,18 @@ use Alchemy\Phrasea\Core\Event\Record\RecordEvent; class RecordEdit extends RecordEvent { + /** @var array */ + private $previousDescription; + + public function __construct(\record_adapter $record, array $previousDescription = []) + { + parent::__construct($record); + + $this->previousDescription = $previousDescription; + } + + public function getPrevousDescription() + { + return $this->previousDescription; + } } diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/WebhookRecordEventSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/WebhookRecordEventSubscriber.php index f873b42ecc..e2a695e0ab 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/WebhookRecordEventSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/WebhookRecordEventSubscriber.php @@ -7,6 +7,7 @@ use Alchemy\Phrasea\Core\Event\Record\CollectionChangedEvent; use Alchemy\Phrasea\Core\Event\Record\RecordEvent; use Alchemy\Phrasea\Core\Event\Record\RecordEvents; use Alchemy\Phrasea\Core\Event\Record\StatusChangedEvent; +use Alchemy\Phrasea\Core\Event\RecordEdit; use Alchemy\Phrasea\Core\LazyLocator; use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Model\Entities\WebhookEvent; @@ -40,9 +41,32 @@ class WebhookRecordEventSubscriber implements EventSubscriberInterface $this->createWebhookEvent($event, WebhookEvent::RECORD_CREATED); } - public function onRecordEdit(RecordEvent $event) + public function onRecordEdit(RecordEdit $event) { - $this->createWebhookEvent($event, WebhookEvent::RECORD_EDITED); + $record = $this->convertToRecordAdapter($event->getRecord()); + + if ($record !== null) { + $eventData = [ + 'databox_id' => $event->getRecord()->getDataboxId(), + 'record_id' => $event->getRecord()->getRecordId(), + 'collection_name' => $record->getCollection()->get_name(), + 'base_id' => $record->getBaseId(), + 'record_type' => $event->getRecord()->isStory() ? "story" : "record", + 'description' => [ + 'before' => $event->getPrevousDescription(), + 'after' => $record->getRecordDescriptionAsArray() + ] + ]; + + $this->app['manipulator.webhook-event']->create( + WebhookEvent::RECORD_EDITED, + WebhookEvent::RECORD_TYPE, + $eventData, + [$event->getRecord()->getBaseId()] + ); + } else { + $this->app['logger']->error("Record not found when wanting to create webhook data!"); + } } public function onRecordDeleted(RecordEvent $event) diff --git a/lib/Alchemy/Phrasea/WorkerManager/Worker/CreateRecordWorker.php b/lib/Alchemy/Phrasea/WorkerManager/Worker/CreateRecordWorker.php index 42a68a515e..2d7a7f0152 100644 --- a/lib/Alchemy/Phrasea/WorkerManager/Worker/CreateRecordWorker.php +++ b/lib/Alchemy/Phrasea/WorkerManager/Worker/CreateRecordWorker.php @@ -286,6 +286,7 @@ class CreateRecordWorker implements WorkerInterface private function addRecordInStory($user, $elementCreated, $sbasId, $storyId, $formData) { $story = new \record_adapter($this->app, $sbasId, $storyId); + $previousDescription = $story->getRecordDescriptionAsArray(); if (!$this->getAclForUser($user)->has_right_on_base($story->getBaseId(), \ACL::CANMODIFRECORD)) { $this->messagePublisher->pushLog(sprintf("The user %s can not add document to the story story_id = %d", $user->getLogin(), $story->getRecordId())); @@ -321,7 +322,7 @@ class CreateRecordWorker implements WorkerInterface } $this->messagePublisher->pushLog(sprintf('The record record_id= %d was successfully added in the story record_id= %d', $elementCreated->getRecordId(), $story->getRecordId())); - $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story)); + $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story, $previousDescription)); } } diff --git a/lib/Alchemy/Phrasea/WorkerManager/Worker/EditRecordWorker.php b/lib/Alchemy/Phrasea/WorkerManager/Worker/EditRecordWorker.php index 98d8dafbe4..652f4fdb64 100644 --- a/lib/Alchemy/Phrasea/WorkerManager/Worker/EditRecordWorker.php +++ b/lib/Alchemy/Phrasea/WorkerManager/Worker/EditRecordWorker.php @@ -97,6 +97,7 @@ class EditRecordWorker implements WorkerInterface /** @var \record_adapter $record */ $record = $databox->get_record($payload['record_id']); + $previousDescription = $record->getRecordDescriptionAsArray(); $statbits = $payload['status']; $editDirty = $payload['edit']; @@ -109,7 +110,7 @@ class EditRecordWorker implements WorkerInterface if (isset($payload['metadatas']) && is_array($payload['metadatas'])) { $record->set_metadatas($payload['metadatas']); - $this->dispatcher->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record)); + $this->dispatcher->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($record, $previousDescription)); } if (isset($payload['technicalsdatas']) && is_array($payload['technicalsdatas'])) { diff --git a/lib/classes/record/adapter.php b/lib/classes/record/adapter.php index 85d84eadc8..8c94ea83ef 100644 --- a/lib/classes/record/adapter.php +++ b/lib/classes/record/adapter.php @@ -37,6 +37,7 @@ use Alchemy\Phrasea\Model\Entities\User; use Alchemy\Phrasea\Model\RecordInterface; use Alchemy\Phrasea\Model\Serializer\CaptionSerializer; use Alchemy\Phrasea\Record\RecordReference; +use Alchemy\Phrasea\Twig\PhraseanetExtension; use Alchemy\Phrasea\WorkerManager\Event\RecordsWriteMetaEvent; use Alchemy\Phrasea\WorkerManager\Event\WorkerEvents; use Doctrine\DBAL\Connection; @@ -842,6 +843,35 @@ class record_adapter implements RecordInterface, cache_cacheableInterface return $this->getCaptionFieldsMap($this->get_caption()->get_fields($fields, true)); } + /** + * @return array + */ + public function getRecordDescriptionAsArray() + { + $helpers = new PhraseanetExtension($this->app); + $description = []; + + foreach ($this->getDatabox()->get_meta_structure()->get_elements() as $data_field) { + $fieldName = $data_field->get_name(); + + if ($this->get_caption()->has_field($fieldName)) { + try { + $captionField = $this->get_caption()->get_field($fieldName); + } catch (\Exception $e) { + continue; + } + + $fieldValues = $captionField->get_values(); + + $fieldLabel = $helpers->getCaptionFieldLabel($this, $fieldName); + + $description[$fieldLabel] = $helpers->getCaptionField($this, $fieldName, $fieldValues); + } + } + + return $description; + } + /** * @param caption_field[] $fields * @return array @@ -1704,6 +1734,8 @@ class record_adapter implements RecordInterface, cache_cacheableInterface if(!$this->isStory) { throw new \Exception(sprintf('Record is not a story')); } + + $previousDescription = $this->getRecordDescriptionAsArray(); $coverSources = array_merge(['thumbnail_cover_source' => 'thumbnail', 'preview_cover_source' => 'preview'], $coverSources); $fromChildRecord = new self($this->app, $this->getDataboxId(), $fromChildRecordId); @@ -1750,7 +1782,7 @@ class record_adapter implements RecordInterface, cache_cacheableInterface $this->delete_data_from_cache(); $this->dispatch(RecordEvents::STORY_COVER_CHANGED, new StoryCoverChangedEvent($this, $fromChildRecord)); - $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($this)); + $this->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($this, $previousDescription)); return $fromChildRecord->getId(); }