Source of file CQRSExtension.php
Size: 7,248 Bytes - Last Modified: 2021-12-23T10:01:46+00:00
/var/www/docs.ssmods.com/process/src/code/CQRSExtension.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | <?php /** * Class CQRSExtension * TODO: Better Buttons Actions return "1" on success * TODO: Reload logic when CQRS actions are applied to reflect new state immediately */ class CQRSExtension extends Extension { private static $better_buttons_actions = [ 'writeToPayloadStore' ]; private static $only_admin_can_update = false; /** * @var string Default config for payload store handler type */ private static $payload_store_handler_type = RedisPayloadStoreHandler::class; /** * @var string */ private $key; /** * @var PayloadManifestParser */ private $parser; /** * @var PayloadStoreHandler */ private $payloadStoreHandler; /** * CQRSExtension constructor. * * @param $key string * @param $config array optional config object for store handler etc. */ public function __construct($key, $config = []) { parent::__construct(); $payloadStoreHandlerType = array_key_exists('store', $config) ? $config['store'] : Config::inst()->get($this->class, 'payload_store_handler_type'); $this->key = $key; $this->parser = new PayloadManifestParser(); $this->payloadStoreHandler = new $payloadStoreHandlerType($config); } public function onAfterWrite() { if (Config::inst()->get($this->owner->class, 'auto_write_to_payload') === true) $this->writeToPayloadStore(); } public function onAfterDelete() { $this->removeFromPayloadStore(); } /** * @return PayloadStoreHandler */ public function getActiveHandler() { return $this->payloadStoreHandler; } /** * @return string */ private function getPayloadStoreKey() { return $this->owner->{$this->key} ?: $this->key; } /** * Obtains the commited payload * * @return array */ private function getCommitedPayload() { $payload = $this->getActiveHandler()->read($this->getPayloadStoreKey()); if (get_class($this->getActiveHandler()) === MongoPayloadStoreHandler::class && $payload && isset($payload['payload'])) { return $payload['payload']; } return $payload; } /** * Generates a MD5 hash of the given payload. * * @param $payload * * @return string */ private function getPayloadChecksum($payload) { return md5(Convert::array2json($payload, JSON_NUMERIC_CHECK, JSON_UNESCAPED_SLASHES)); } /** * Checks if the current data is equal to the commited payload. * * @return bool */ public function isInSync() { return $this->getPayloadChecksum($this->getCommitedPayload()) === $this->getPayloadChecksum($this->parser->commit($this->owner, false)); } public function updateCMSActions($actions) { if ($this->owner->canEdit()) { // Add "save" action $actions->push(FormAction::create('save', _t('CMSMain.SAVE')) ->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')); // Add action for writing data to payload store if (Config::inst()->get($this->owner->class, 'show_write_to_payload_action') !== false) { if (Permission::check('PUBLISH_' . mb_strtoupper($this->owner->class))) { $updateAction = FormAction::create( 'writeToPayloadStore', _t('CQRSExtension.WRITE', 'Lesedatenbank aktualisieren') )->setDisabled($this->isInSync()); if ($this->isInSync()) { $updateAction->setDescription(_t('CQRSExtension.UP_TO_DATE', 'Lesedatenbank ist aktuell')); } $actions->push($updateAction); } } } } /** * Writes the committed payload to the current payload store. * * @return bool successful or not * @throws Exception */ public function writeToPayloadStore() { if ($payload = $this->getWritePayload()) { // Check if record can be commited if ($this->owner->hasMethod('canWriteToPayloadStore') && $this->owner->canWriteToPayloadStore() === false) { return false; } $handler = $this->getActiveHandler(); $handler->write($this->getPayloadStoreKey(), $payload); return true; } return false; } /** * Get the committed payload which should be written to the current payload store. * * @return array|bool * @throws Exception */ public function getWritePayload() { $payload = $this->parser->commit($this->owner); if ($this->parser->canCommit()) { return $payload; } else { if (!Director::is_cli()) { Session::set( "FormInfo.Form_ItemEditForm.formError.message", $this->getErrorMessageForTemplate() ); Session::set("FormInfo.Form_ItemEditForm.formError.type", "bad"); } return false; } } /** * Removes the current record from the payload store */ public function removeFromPayloadStore() { $this->getActiveHandler()->delete($this->owner->{$this->key}); } /** * Provides BetterButtonsAction for Super-Admin View. * * TODO: Disabled state not working when in super admin view * * @param $actions */ public function updateBetterButtonsActions($actions) { $updateAction = BetterButtonCustomAction::create( 'writeToPayloadStore', _t('CQRSExtension.WRITE', 'Lesedatenbank aktualisieren') )->setDisabled($this->isInSync()); if ($this->isInSync()) { $updateAction->setDescription(_t('CQRSExtension.UP_TO_DATE', 'Lesedatenbank ist aktuell')); } $showAction = Config::inst()->get($this->owner->class, 'show_write_to_payload_action'); if ($this->canManipulatePayloadStore() && $showAction !== false) $actions->push($updateAction); } /** * @return bool Check if actions are admin-restricted */ public function canManipulatePayloadStore() { $onlyAdminCanUpdate = Config::inst()->get($this->owner->class, 'only_admin_can_update'); return !$onlyAdminCanUpdate || Permission::check('ADMIN'); } /** * Renders a list of validation errors. * * @return mixed */ public function getErrorMessageForTemplate() { return $this->owner->customise([ 'ValidationErrors' => ArrayList::create(array_map(function ($error) { return [ "value" => $error ]; }, $this->getValidationErrors())) ])->renderWith('CQRSErrorMessage'); } /** * Return the list of validation errors if exists. * * @return array */ public function getValidationErrors() { return $this->owner->cqrsValidationErrors; } } |