edde-framework/edde-framework

View on GitHub
src/Edde/Ext/Rest/ProtocolService.php

Summary

Maintainability
A
35 mins
Test Coverage
<?php
    declare(strict_types=1);

    namespace Edde\Ext\Rest;

    use Edde\Api\Protocol\IElement;
    use Edde\Api\Protocol\LazyElementStoreTrait;
    use Edde\Api\Protocol\LazyProtocolManagerTrait;
    use Edde\Api\Store\LazyStoreManagerTrait;
    use Edde\Api\Thread\LazyThreadManagerTrait;
    use Edde\Api\Url\IUrl;
    use Edde\Common\Protocol\Error;
    use Edde\Common\Rest\AbstractService;
    use Edde\Common\Store\FileStore;
    use Edde\Ext\Protocol\ElementContent;
    use Edde\Ext\Session\SessionStore;

    class ProtocolService extends AbstractService {
        use LazyProtocolManagerTrait;
        use LazyElementStoreTrait;
        use LazyStoreManagerTrait;
        use LazyThreadManagerTrait;

        /**
         * @inheritdoc
         */
        public function match(IUrl $url): bool {
            return $url->match('~^/api/protocol$~') !== null;
        }

        /**
         * @inheritdoc
         */
        public function link($generate, array $parameterList = []) {
            return parent::link('/api/protocol', $parameterList);
        }

        /**
         * simple request to get current packet
         *
         * @param IElement $element
         */
        public function actionGet(IElement $element) {
            $this->element($element);
            try {
                $this->response(new ElementContent($packet = $this->protocolManager->createPacket()));
                if (($elementId = $element->getMeta('element'))) {
                    $reference = new Error(-101, sprintf('Requested element [%s] was not found.', $elementId));
                    if ($this->elementStore->has($elementId)) {
                        $reference = $this->elementStore->load($elementId);
                    }
                    $packet->reference($reference);
                } else if (($referenceId = $element->getMeta('reference'))) {
                    $packet->references(iterator_to_array($this->elementStore->getReferenceListBy($referenceId)));
                }
                $this->elementStore->save($packet);
            } finally {
                $this->storeManager->restore();
            }
        }

        /**
         * post packet which will be executed
         *
         * @param IElement $element
         */
        public function actionPost(IElement $element) {
            /**
             * same stuff for other supported methods
             */
            $this->element($element);
            try {
                /**
                 * execute incoming packet and return result content
                 */
                $this->response(new ElementContent($element = $this->protocolManager->execute($this->getContent($element, IElement::class))));
                /**
                 * execute thread if it is needed (are there some jobs?)
                 */
                $this->threadManager->execute(['store' => $this->storeManager->getCurrentName()]);
            } finally {
                /**
                 * this is necessary to do to be safe and do not change global context
                 */
                $this->storeManager->restore();
            }
        }

        protected function element(IElement $element) {
            /**
             * select proper store (session/broadcast)
             */
            $this->storeManager->select(SessionStore::class);
            if ($element->getMeta('broadcast', false)) {
                $this->storeManager->select(FileStore::class);
            }
        }
    }