@@ -42,151 +42,151 @@ |
||
| 42 | 42 | use OCP\WorkflowEngine\ISpecificOperation; |
| 43 | 43 | |
| 44 | 44 | abstract class ASettings implements ISettings { |
| 45 | - /** @var IL10N */ |
|
| 46 | - private $l10n; |
|
| 47 | - |
|
| 48 | - /** @var string */ |
|
| 49 | - private $appName; |
|
| 50 | - |
|
| 51 | - /** @var IEventDispatcher */ |
|
| 52 | - private $eventDispatcher; |
|
| 53 | - |
|
| 54 | - /** @var Manager */ |
|
| 55 | - protected $manager; |
|
| 56 | - |
|
| 57 | - /** @var IInitialStateService */ |
|
| 58 | - private $initialStateService; |
|
| 59 | - |
|
| 60 | - /** @var IConfig */ |
|
| 61 | - private $config; |
|
| 62 | - |
|
| 63 | - public function __construct( |
|
| 64 | - string $appName, |
|
| 65 | - IL10N $l, |
|
| 66 | - IEventDispatcher $eventDispatcher, |
|
| 67 | - Manager $manager, |
|
| 68 | - IInitialStateService $initialStateService, |
|
| 69 | - IConfig $config |
|
| 70 | - ) { |
|
| 71 | - $this->appName = $appName; |
|
| 72 | - $this->l10n = $l; |
|
| 73 | - $this->eventDispatcher = $eventDispatcher; |
|
| 74 | - $this->manager = $manager; |
|
| 75 | - $this->initialStateService = $initialStateService; |
|
| 76 | - $this->config = $config; |
|
| 77 | - } |
|
| 78 | - |
|
| 79 | - abstract public function getScope(): int; |
|
| 80 | - |
|
| 81 | - /** |
|
| 82 | - * @return TemplateResponse |
|
| 83 | - */ |
|
| 84 | - public function getForm() { |
|
| 85 | - $this->eventDispatcher->dispatch( |
|
| 86 | - 'OCP\WorkflowEngine::loadAdditionalSettingScripts', |
|
| 87 | - new LoadSettingsScriptsEvent() |
|
| 88 | - ); |
|
| 89 | - |
|
| 90 | - $entities = $this->manager->getEntitiesList(); |
|
| 91 | - $this->initialStateService->provideInitialState( |
|
| 92 | - Application::APP_ID, |
|
| 93 | - 'entities', |
|
| 94 | - $this->entitiesToArray($entities) |
|
| 95 | - ); |
|
| 96 | - |
|
| 97 | - $operators = $this->manager->getOperatorList(); |
|
| 98 | - $this->initialStateService->provideInitialState( |
|
| 99 | - Application::APP_ID, |
|
| 100 | - 'operators', |
|
| 101 | - $this->operatorsToArray($operators) |
|
| 102 | - ); |
|
| 103 | - |
|
| 104 | - $checks = $this->manager->getCheckList(); |
|
| 105 | - $this->initialStateService->provideInitialState( |
|
| 106 | - Application::APP_ID, |
|
| 107 | - 'checks', |
|
| 108 | - $this->checksToArray($checks) |
|
| 109 | - ); |
|
| 110 | - |
|
| 111 | - $this->initialStateService->provideInitialState( |
|
| 112 | - Application::APP_ID, |
|
| 113 | - 'scope', |
|
| 114 | - $this->getScope() |
|
| 115 | - ); |
|
| 116 | - |
|
| 117 | - $this->initialStateService->provideInitialState( |
|
| 118 | - Application::APP_ID, |
|
| 119 | - 'appstoreenabled', |
|
| 120 | - $this->config->getSystemValueBool('appstoreenabled', true) |
|
| 121 | - ); |
|
| 122 | - |
|
| 123 | - return new TemplateResponse(Application::APP_ID, 'settings', [], 'blank'); |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - /** |
|
| 127 | - * @return string the section ID, e.g. 'sharing' |
|
| 128 | - */ |
|
| 129 | - public function getSection() { |
|
| 130 | - return 'workflow'; |
|
| 131 | - } |
|
| 132 | - |
|
| 133 | - /** |
|
| 134 | - * @return int whether the form should be rather on the top or bottom of |
|
| 135 | - * the admin section. The forms are arranged in ascending order of the |
|
| 136 | - * priority values. It is required to return a value between 0 and 100. |
|
| 137 | - * |
|
| 138 | - * E.g.: 70 |
|
| 139 | - */ |
|
| 140 | - public function getPriority() { |
|
| 141 | - return 0; |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - private function entitiesToArray(array $entities) { |
|
| 145 | - return array_map(function (IEntity $entity) { |
|
| 146 | - $events = array_map(function (IEntityEvent $entityEvent) { |
|
| 147 | - return [ |
|
| 148 | - 'eventName' => $entityEvent->getEventName(), |
|
| 149 | - 'displayName' => $entityEvent->getDisplayName() |
|
| 150 | - ]; |
|
| 151 | - }, $entity->getEvents()); |
|
| 152 | - |
|
| 153 | - return [ |
|
| 154 | - 'id' => get_class($entity), |
|
| 155 | - 'icon' => $entity->getIcon(), |
|
| 156 | - 'name' => $entity->getName(), |
|
| 157 | - 'events' => $events, |
|
| 158 | - ]; |
|
| 159 | - }, $entities); |
|
| 160 | - } |
|
| 161 | - |
|
| 162 | - private function operatorsToArray(array $operators) { |
|
| 163 | - $operators = array_filter($operators, function (IOperation $operator) { |
|
| 164 | - return $operator->isAvailableForScope($this->getScope()); |
|
| 165 | - }); |
|
| 166 | - |
|
| 167 | - return array_map(function (IOperation $operator) { |
|
| 168 | - return [ |
|
| 169 | - 'id' => get_class($operator), |
|
| 170 | - 'icon' => $operator->getIcon(), |
|
| 171 | - 'name' => $operator->getDisplayName(), |
|
| 172 | - 'description' => $operator->getDescription(), |
|
| 173 | - 'fixedEntity' => $operator instanceof ISpecificOperation ? $operator->getEntityId() : '', |
|
| 174 | - 'isComplex' => $operator instanceof IComplexOperation, |
|
| 175 | - 'triggerHint' => $operator instanceof IComplexOperation ? $operator->getTriggerHint() : '', |
|
| 176 | - ]; |
|
| 177 | - }, $operators); |
|
| 178 | - } |
|
| 179 | - |
|
| 180 | - private function checksToArray(array $checks) { |
|
| 181 | - $checks = array_filter($checks, function (ICheck $check) { |
|
| 182 | - return $check->isAvailableForScope($this->getScope()); |
|
| 183 | - }); |
|
| 184 | - |
|
| 185 | - return array_map(function (ICheck $check) { |
|
| 186 | - return [ |
|
| 187 | - 'id' => get_class($check), |
|
| 188 | - 'supportedEntities' => $check->supportedEntities(), |
|
| 189 | - ]; |
|
| 190 | - }, $checks); |
|
| 191 | - } |
|
| 45 | + /** @var IL10N */ |
|
| 46 | + private $l10n; |
|
| 47 | + |
|
| 48 | + /** @var string */ |
|
| 49 | + private $appName; |
|
| 50 | + |
|
| 51 | + /** @var IEventDispatcher */ |
|
| 52 | + private $eventDispatcher; |
|
| 53 | + |
|
| 54 | + /** @var Manager */ |
|
| 55 | + protected $manager; |
|
| 56 | + |
|
| 57 | + /** @var IInitialStateService */ |
|
| 58 | + private $initialStateService; |
|
| 59 | + |
|
| 60 | + /** @var IConfig */ |
|
| 61 | + private $config; |
|
| 62 | + |
|
| 63 | + public function __construct( |
|
| 64 | + string $appName, |
|
| 65 | + IL10N $l, |
|
| 66 | + IEventDispatcher $eventDispatcher, |
|
| 67 | + Manager $manager, |
|
| 68 | + IInitialStateService $initialStateService, |
|
| 69 | + IConfig $config |
|
| 70 | + ) { |
|
| 71 | + $this->appName = $appName; |
|
| 72 | + $this->l10n = $l; |
|
| 73 | + $this->eventDispatcher = $eventDispatcher; |
|
| 74 | + $this->manager = $manager; |
|
| 75 | + $this->initialStateService = $initialStateService; |
|
| 76 | + $this->config = $config; |
|
| 77 | + } |
|
| 78 | + |
|
| 79 | + abstract public function getScope(): int; |
|
| 80 | + |
|
| 81 | + /** |
|
| 82 | + * @return TemplateResponse |
|
| 83 | + */ |
|
| 84 | + public function getForm() { |
|
| 85 | + $this->eventDispatcher->dispatch( |
|
| 86 | + 'OCP\WorkflowEngine::loadAdditionalSettingScripts', |
|
| 87 | + new LoadSettingsScriptsEvent() |
|
| 88 | + ); |
|
| 89 | + |
|
| 90 | + $entities = $this->manager->getEntitiesList(); |
|
| 91 | + $this->initialStateService->provideInitialState( |
|
| 92 | + Application::APP_ID, |
|
| 93 | + 'entities', |
|
| 94 | + $this->entitiesToArray($entities) |
|
| 95 | + ); |
|
| 96 | + |
|
| 97 | + $operators = $this->manager->getOperatorList(); |
|
| 98 | + $this->initialStateService->provideInitialState( |
|
| 99 | + Application::APP_ID, |
|
| 100 | + 'operators', |
|
| 101 | + $this->operatorsToArray($operators) |
|
| 102 | + ); |
|
| 103 | + |
|
| 104 | + $checks = $this->manager->getCheckList(); |
|
| 105 | + $this->initialStateService->provideInitialState( |
|
| 106 | + Application::APP_ID, |
|
| 107 | + 'checks', |
|
| 108 | + $this->checksToArray($checks) |
|
| 109 | + ); |
|
| 110 | + |
|
| 111 | + $this->initialStateService->provideInitialState( |
|
| 112 | + Application::APP_ID, |
|
| 113 | + 'scope', |
|
| 114 | + $this->getScope() |
|
| 115 | + ); |
|
| 116 | + |
|
| 117 | + $this->initialStateService->provideInitialState( |
|
| 118 | + Application::APP_ID, |
|
| 119 | + 'appstoreenabled', |
|
| 120 | + $this->config->getSystemValueBool('appstoreenabled', true) |
|
| 121 | + ); |
|
| 122 | + |
|
| 123 | + return new TemplateResponse(Application::APP_ID, 'settings', [], 'blank'); |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + /** |
|
| 127 | + * @return string the section ID, e.g. 'sharing' |
|
| 128 | + */ |
|
| 129 | + public function getSection() { |
|
| 130 | + return 'workflow'; |
|
| 131 | + } |
|
| 132 | + |
|
| 133 | + /** |
|
| 134 | + * @return int whether the form should be rather on the top or bottom of |
|
| 135 | + * the admin section. The forms are arranged in ascending order of the |
|
| 136 | + * priority values. It is required to return a value between 0 and 100. |
|
| 137 | + * |
|
| 138 | + * E.g.: 70 |
|
| 139 | + */ |
|
| 140 | + public function getPriority() { |
|
| 141 | + return 0; |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + private function entitiesToArray(array $entities) { |
|
| 145 | + return array_map(function (IEntity $entity) { |
|
| 146 | + $events = array_map(function (IEntityEvent $entityEvent) { |
|
| 147 | + return [ |
|
| 148 | + 'eventName' => $entityEvent->getEventName(), |
|
| 149 | + 'displayName' => $entityEvent->getDisplayName() |
|
| 150 | + ]; |
|
| 151 | + }, $entity->getEvents()); |
|
| 152 | + |
|
| 153 | + return [ |
|
| 154 | + 'id' => get_class($entity), |
|
| 155 | + 'icon' => $entity->getIcon(), |
|
| 156 | + 'name' => $entity->getName(), |
|
| 157 | + 'events' => $events, |
|
| 158 | + ]; |
|
| 159 | + }, $entities); |
|
| 160 | + } |
|
| 161 | + |
|
| 162 | + private function operatorsToArray(array $operators) { |
|
| 163 | + $operators = array_filter($operators, function (IOperation $operator) { |
|
| 164 | + return $operator->isAvailableForScope($this->getScope()); |
|
| 165 | + }); |
|
| 166 | + |
|
| 167 | + return array_map(function (IOperation $operator) { |
|
| 168 | + return [ |
|
| 169 | + 'id' => get_class($operator), |
|
| 170 | + 'icon' => $operator->getIcon(), |
|
| 171 | + 'name' => $operator->getDisplayName(), |
|
| 172 | + 'description' => $operator->getDescription(), |
|
| 173 | + 'fixedEntity' => $operator instanceof ISpecificOperation ? $operator->getEntityId() : '', |
|
| 174 | + 'isComplex' => $operator instanceof IComplexOperation, |
|
| 175 | + 'triggerHint' => $operator instanceof IComplexOperation ? $operator->getTriggerHint() : '', |
|
| 176 | + ]; |
|
| 177 | + }, $operators); |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + private function checksToArray(array $checks) { |
|
| 181 | + $checks = array_filter($checks, function (ICheck $check) { |
|
| 182 | + return $check->isAvailableForScope($this->getScope()); |
|
| 183 | + }); |
|
| 184 | + |
|
| 185 | + return array_map(function (ICheck $check) { |
|
| 186 | + return [ |
|
| 187 | + 'id' => get_class($check), |
|
| 188 | + 'supportedEntities' => $check->supportedEntities(), |
|
| 189 | + ]; |
|
| 190 | + }, $checks); |
|
| 191 | + } |
|
| 192 | 192 | } |
@@ -36,105 +36,105 @@ |
||
| 36 | 36 | use OCP\WorkflowEngine\IOperationCompat; |
| 37 | 37 | |
| 38 | 38 | class Application extends App { |
| 39 | - public const APP_ID = 'workflowengine'; |
|
| 40 | - |
|
| 41 | - /** @var IEventDispatcher */ |
|
| 42 | - protected $dispatcher; |
|
| 43 | - /** @var Manager */ |
|
| 44 | - protected $manager; |
|
| 45 | - |
|
| 46 | - public function __construct() { |
|
| 47 | - parent::__construct(self::APP_ID); |
|
| 48 | - |
|
| 49 | - $this->getContainer()->registerAlias('RequestTimeController', RequestTime::class); |
|
| 50 | - |
|
| 51 | - $this->dispatcher = $this->getContainer()->getServer()->query(IEventDispatcher::class); |
|
| 52 | - $this->manager = $this->getContainer()->query(Manager::class); |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - /** |
|
| 56 | - * Register all hooks and listeners |
|
| 57 | - */ |
|
| 58 | - public function registerHooksAndListeners() { |
|
| 59 | - $this->dispatcher->addListener( |
|
| 60 | - 'OCP\WorkflowEngine::loadAdditionalSettingScripts', |
|
| 61 | - function () { |
|
| 62 | - if (!function_exists('style')) { |
|
| 63 | - // This is hacky, but we need to load the template class |
|
| 64 | - class_exists(Template::class, true); |
|
| 65 | - } |
|
| 66 | - |
|
| 67 | - script('core', [ |
|
| 68 | - 'files/fileinfo', |
|
| 69 | - 'files/client', |
|
| 70 | - 'dist/systemtags', |
|
| 71 | - ]); |
|
| 72 | - |
|
| 73 | - script(self::APP_ID, [ |
|
| 74 | - 'workflowengine', |
|
| 75 | - ]); |
|
| 76 | - }, |
|
| 77 | - -100 |
|
| 78 | - ); |
|
| 79 | - } |
|
| 80 | - |
|
| 81 | - public function registerRuleListeners() { |
|
| 82 | - $configuredEvents = $this->manager->getAllConfiguredEvents(); |
|
| 83 | - |
|
| 84 | - foreach ($configuredEvents as $operationClass => $events) { |
|
| 85 | - foreach ($events as $entityClass => $eventNames) { |
|
| 86 | - array_map(function (string $eventName) use ($operationClass, $entityClass) { |
|
| 87 | - $this->dispatcher->addListener( |
|
| 88 | - $eventName, |
|
| 89 | - function ($event) use ($eventName, $operationClass, $entityClass) { |
|
| 90 | - $ruleMatcher = $this->manager->getRuleMatcher(); |
|
| 91 | - try { |
|
| 92 | - /** @var IEntity $entity */ |
|
| 93 | - $entity = $this->getContainer()->query($entityClass); |
|
| 94 | - /** @var IOperation $operation */ |
|
| 95 | - $operation = $this->getContainer()->query($operationClass); |
|
| 96 | - |
|
| 97 | - $ruleMatcher->setEntity($entity); |
|
| 98 | - $ruleMatcher->setOperation($operation); |
|
| 99 | - |
|
| 100 | - $ctx = new LogContext(); |
|
| 101 | - $ctx |
|
| 102 | - ->setOperation($operation) |
|
| 103 | - ->setEntity($entity) |
|
| 104 | - ->setEventName($eventName); |
|
| 105 | - |
|
| 106 | - /** @var Logger $flowLogger */ |
|
| 107 | - $flowLogger = $this->getContainer()->query(Logger::class); |
|
| 108 | - $flowLogger->logEventInit($ctx); |
|
| 109 | - |
|
| 110 | - if ($event instanceof Event) { |
|
| 111 | - $entity->prepareRuleMatcher($ruleMatcher, $eventName, $event); |
|
| 112 | - $operation->onEvent($eventName, $event, $ruleMatcher); |
|
| 113 | - } elseif ($entity instanceof IEntityCompat && $operation instanceof IOperationCompat) { |
|
| 114 | - // TODO: Remove this block (and the compat classes) in the first major release in 2023 |
|
| 115 | - $entity->prepareRuleMatcherCompat($ruleMatcher, $eventName, $event); |
|
| 116 | - $operation->onEventCompat($eventName, $event, $ruleMatcher); |
|
| 117 | - } else { |
|
| 118 | - $logger = $this->getContainer()->getServer()->getLogger(); |
|
| 119 | - $logger->debug( |
|
| 120 | - 'Cannot handle event {name} of {event} against entity {entity} and operation {operation}', |
|
| 121 | - [ |
|
| 122 | - 'app' => self::APP_ID, |
|
| 123 | - 'name' => $eventName, |
|
| 124 | - 'event' => get_class($event), |
|
| 125 | - 'entity' => $entityClass, |
|
| 126 | - 'operation' => $operationClass, |
|
| 127 | - ] |
|
| 128 | - ); |
|
| 129 | - } |
|
| 130 | - $flowLogger->logEventDone($ctx); |
|
| 131 | - } catch (QueryException $e) { |
|
| 132 | - // Ignore query exceptions since they might occur when an entity/operation were setup before by an app that is disabled now |
|
| 133 | - } |
|
| 134 | - } |
|
| 135 | - ); |
|
| 136 | - }, $eventNames ?? []); |
|
| 137 | - } |
|
| 138 | - } |
|
| 139 | - } |
|
| 39 | + public const APP_ID = 'workflowengine'; |
|
| 40 | + |
|
| 41 | + /** @var IEventDispatcher */ |
|
| 42 | + protected $dispatcher; |
|
| 43 | + /** @var Manager */ |
|
| 44 | + protected $manager; |
|
| 45 | + |
|
| 46 | + public function __construct() { |
|
| 47 | + parent::__construct(self::APP_ID); |
|
| 48 | + |
|
| 49 | + $this->getContainer()->registerAlias('RequestTimeController', RequestTime::class); |
|
| 50 | + |
|
| 51 | + $this->dispatcher = $this->getContainer()->getServer()->query(IEventDispatcher::class); |
|
| 52 | + $this->manager = $this->getContainer()->query(Manager::class); |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + /** |
|
| 56 | + * Register all hooks and listeners |
|
| 57 | + */ |
|
| 58 | + public function registerHooksAndListeners() { |
|
| 59 | + $this->dispatcher->addListener( |
|
| 60 | + 'OCP\WorkflowEngine::loadAdditionalSettingScripts', |
|
| 61 | + function () { |
|
| 62 | + if (!function_exists('style')) { |
|
| 63 | + // This is hacky, but we need to load the template class |
|
| 64 | + class_exists(Template::class, true); |
|
| 65 | + } |
|
| 66 | + |
|
| 67 | + script('core', [ |
|
| 68 | + 'files/fileinfo', |
|
| 69 | + 'files/client', |
|
| 70 | + 'dist/systemtags', |
|
| 71 | + ]); |
|
| 72 | + |
|
| 73 | + script(self::APP_ID, [ |
|
| 74 | + 'workflowengine', |
|
| 75 | + ]); |
|
| 76 | + }, |
|
| 77 | + -100 |
|
| 78 | + ); |
|
| 79 | + } |
|
| 80 | + |
|
| 81 | + public function registerRuleListeners() { |
|
| 82 | + $configuredEvents = $this->manager->getAllConfiguredEvents(); |
|
| 83 | + |
|
| 84 | + foreach ($configuredEvents as $operationClass => $events) { |
|
| 85 | + foreach ($events as $entityClass => $eventNames) { |
|
| 86 | + array_map(function (string $eventName) use ($operationClass, $entityClass) { |
|
| 87 | + $this->dispatcher->addListener( |
|
| 88 | + $eventName, |
|
| 89 | + function ($event) use ($eventName, $operationClass, $entityClass) { |
|
| 90 | + $ruleMatcher = $this->manager->getRuleMatcher(); |
|
| 91 | + try { |
|
| 92 | + /** @var IEntity $entity */ |
|
| 93 | + $entity = $this->getContainer()->query($entityClass); |
|
| 94 | + /** @var IOperation $operation */ |
|
| 95 | + $operation = $this->getContainer()->query($operationClass); |
|
| 96 | + |
|
| 97 | + $ruleMatcher->setEntity($entity); |
|
| 98 | + $ruleMatcher->setOperation($operation); |
|
| 99 | + |
|
| 100 | + $ctx = new LogContext(); |
|
| 101 | + $ctx |
|
| 102 | + ->setOperation($operation) |
|
| 103 | + ->setEntity($entity) |
|
| 104 | + ->setEventName($eventName); |
|
| 105 | + |
|
| 106 | + /** @var Logger $flowLogger */ |
|
| 107 | + $flowLogger = $this->getContainer()->query(Logger::class); |
|
| 108 | + $flowLogger->logEventInit($ctx); |
|
| 109 | + |
|
| 110 | + if ($event instanceof Event) { |
|
| 111 | + $entity->prepareRuleMatcher($ruleMatcher, $eventName, $event); |
|
| 112 | + $operation->onEvent($eventName, $event, $ruleMatcher); |
|
| 113 | + } elseif ($entity instanceof IEntityCompat && $operation instanceof IOperationCompat) { |
|
| 114 | + // TODO: Remove this block (and the compat classes) in the first major release in 2023 |
|
| 115 | + $entity->prepareRuleMatcherCompat($ruleMatcher, $eventName, $event); |
|
| 116 | + $operation->onEventCompat($eventName, $event, $ruleMatcher); |
|
| 117 | + } else { |
|
| 118 | + $logger = $this->getContainer()->getServer()->getLogger(); |
|
| 119 | + $logger->debug( |
|
| 120 | + 'Cannot handle event {name} of {event} against entity {entity} and operation {operation}', |
|
| 121 | + [ |
|
| 122 | + 'app' => self::APP_ID, |
|
| 123 | + 'name' => $eventName, |
|
| 124 | + 'event' => get_class($event), |
|
| 125 | + 'entity' => $entityClass, |
|
| 126 | + 'operation' => $operationClass, |
|
| 127 | + ] |
|
| 128 | + ); |
|
| 129 | + } |
|
| 130 | + $flowLogger->logEventDone($ctx); |
|
| 131 | + } catch (QueryException $e) { |
|
| 132 | + // Ignore query exceptions since they might occur when an entity/operation were setup before by an app that is disabled now |
|
| 133 | + } |
|
| 134 | + } |
|
| 135 | + ); |
|
| 136 | + }, $eventNames ?? []); |
|
| 137 | + } |
|
| 138 | + } |
|
| 139 | + } |
|
| 140 | 140 | } |