mirror of
https://github.com/Karaka-Management/oms-Workflow.git
synced 2026-01-11 06:48:41 +00:00
prepare workflows
This commit is contained in:
parent
fe21c97c5f
commit
94f57e6121
|
|
@ -21,8 +21,9 @@
|
||||||
"en": "Check condition",
|
"en": "Check condition",
|
||||||
"de": "Überprüfe Bedingung"
|
"de": "Überprüfe Bedingung"
|
||||||
},
|
},
|
||||||
"function_type": "API",
|
"function_type": "Api",
|
||||||
"function": "apiValidateCondition",
|
"function": "apiValidateCondition",
|
||||||
|
"module": "Workflow",
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"field_name",
|
"field_name",
|
||||||
"field_value",
|
"field_value",
|
||||||
|
|
@ -181,8 +182,9 @@
|
||||||
"en": "Takes input data and forwards the data to another action. Check the outputs and inputs of the actions to create the correct mapping.",
|
"en": "Takes input data and forwards the data to another action. Check the outputs and inputs of the actions to create the correct mapping.",
|
||||||
"de": "Übernimmt Eingangsdaten und leitet diese an eine andere Aktion weiter. Überprüfe die Ausgaben und Eingaben der jeweiligen Aktionen um die korrekten Verknüpfungen zu erstellen."
|
"de": "Übernimmt Eingangsdaten und leitet diese an eine andere Aktion weiter. Überprüfe die Ausgaben und Eingaben der jeweiligen Aktionen um die korrekten Verknüpfungen zu erstellen."
|
||||||
},
|
},
|
||||||
"function_type": "API",
|
"function_type": "Api",
|
||||||
"function": "apiAdapter",
|
"function": "apiAdapter",
|
||||||
|
"module": "Workflow",
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"map",
|
"map",
|
||||||
"{*}"
|
"{*}"
|
||||||
|
|
@ -217,8 +219,9 @@
|
||||||
"en": "Listens to trigger",
|
"en": "Listens to trigger",
|
||||||
"de": "Wartet auf Trigger"
|
"de": "Wartet auf Trigger"
|
||||||
},
|
},
|
||||||
"function_type": "API",
|
"function_type": "Api",
|
||||||
"function": "apiListenToTrigger",
|
"function": "apiListenToTrigger",
|
||||||
|
"module": "Workflow",
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"type",
|
"type",
|
||||||
"trigger",
|
"trigger",
|
||||||
|
|
@ -328,8 +331,9 @@
|
||||||
"en": "Takes input data and forwards the data to another action. Check the outputs and inputs of the actions to create the correct mapping.",
|
"en": "Takes input data and forwards the data to another action. Check the outputs and inputs of the actions to create the correct mapping.",
|
||||||
"de": "Übernimmt Eingangsdaten und leitet diese an eine andere Aktion weiter. Überprüfe die Ausgaben und Eingaben der jeweiligen Aktionen um die korrekten Verknüpfungen zu erstellen."
|
"de": "Übernimmt Eingangsdaten und leitet diese an eine andere Aktion weiter. Überprüfe die Ausgaben und Eingaben der jeweiligen Aktionen um die korrekten Verknüpfungen zu erstellen."
|
||||||
},
|
},
|
||||||
"function_type": "API",
|
"function_type": "Api",
|
||||||
"function": "apiRun",
|
"function": "apiRun",
|
||||||
|
"module": "Workflow",
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"map",
|
"map",
|
||||||
"{*}"
|
"{*}"
|
||||||
|
|
@ -359,13 +363,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"1005500005": {
|
"1005500005": {
|
||||||
"name": "Timed Trigger",
|
"name": "Timed Trigger (Job/Task)",
|
||||||
"description": {
|
"description": {
|
||||||
"en": "Timed trigger",
|
"en": "Timed trigger (Job/Task)",
|
||||||
"de": "Wartet auf Trigger"
|
"de": "Zeitgesteuerter Trigger (Job/Task)"
|
||||||
},
|
},
|
||||||
"function_type": "API",
|
"function_type": "Api",
|
||||||
"function": "apiRun",
|
"function": "apiRun",
|
||||||
|
"module": "Workflow",
|
||||||
|
"function_install": {
|
||||||
|
"module": "Workflow",
|
||||||
|
"function": "installTimedTrigger"
|
||||||
|
},
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"interval",
|
"interval",
|
||||||
"{*}"
|
"{*}"
|
||||||
|
|
@ -398,8 +407,9 @@
|
||||||
"en": "Cli action",
|
"en": "Cli action",
|
||||||
"de": "Konsolenbefehl"
|
"de": "Konsolenbefehl"
|
||||||
},
|
},
|
||||||
"function_type": "API",
|
"function_type": "Api",
|
||||||
"function": "apiRun",
|
"function": "apiRun",
|
||||||
|
"module": "Workflow",
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"cmd",
|
"cmd",
|
||||||
"{*}"
|
"{*}"
|
||||||
|
|
@ -432,8 +442,9 @@
|
||||||
"en": "Workflow script",
|
"en": "Workflow script",
|
||||||
"de": "Workflow Script"
|
"de": "Workflow Script"
|
||||||
},
|
},
|
||||||
"function_type": "API",
|
"function_type": "Api",
|
||||||
"function": "apiRun",
|
"function": "apiRun",
|
||||||
|
"module": "Workflow",
|
||||||
"inputs": [
|
"inputs": [
|
||||||
"{*}"
|
"{*}"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,12 @@ use phpOMS\Message\NotificationLevel;
|
||||||
use phpOMS\Message\RequestAbstract;
|
use phpOMS\Message\RequestAbstract;
|
||||||
use phpOMS\Message\ResponseAbstract;
|
use phpOMS\Message\ResponseAbstract;
|
||||||
use phpOMS\Model\Message\FormValidation;
|
use phpOMS\Model\Message\FormValidation;
|
||||||
|
use phpOMS\System\File\FileUtils;
|
||||||
use phpOMS\System\MimeType;
|
use phpOMS\System\MimeType;
|
||||||
use phpOMS\Utils\Parser\Markdown\Markdown;
|
use phpOMS\Utils\Parser\Markdown\Markdown;
|
||||||
use phpOMS\Utils\StringUtils;
|
use phpOMS\Utils\StringUtils;
|
||||||
|
use phpOMS\Utils\TaskSchedule\SchedulerFactory;
|
||||||
|
use phpOMS\Utils\TaskSchedule\TaskFactory;
|
||||||
use phpOMS\Views\View;
|
use phpOMS\Views\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -495,9 +498,49 @@ final class ApiController extends Controller
|
||||||
$this->createDatabaseForTemplate($template);
|
$this->createDatabaseForTemplate($template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// perform other workflow installation actions
|
||||||
|
$actions = \json_decode(\file_get_contents(__DIR__ . '/../Definitions/actions.json'), true);
|
||||||
|
$this->installWorkflowModel($template, $actions);
|
||||||
|
|
||||||
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Template', 'Template successfully created', $template);
|
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Template', 'Template successfully created', $template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function installWorkflowModel(WorkflowTemplate $template, array $actions) : void
|
||||||
|
{
|
||||||
|
$schema = $template->schema;
|
||||||
|
foreach ($schema as $primary) {
|
||||||
|
$id = $primary['id'] ?? '';
|
||||||
|
|
||||||
|
if (!isset($actions[$id]['function_install'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->app->moduleManager->get($actions[$id]['function_install']['module'])->{$actions[$id]['function_install']['function_install_function']}($template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function installTimedTrigger(WorkflowTemplate $template) : void
|
||||||
|
{
|
||||||
|
$id = 'Workflow-' . $template->getId();
|
||||||
|
$scheduler = SchedulerFactory::create();
|
||||||
|
|
||||||
|
if (!empty($scheduler->getAllByName($id))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$job = TaskFactory::create($id);
|
||||||
|
|
||||||
|
$job->interval = $template->schema['settings']['interval'] ?? '';
|
||||||
|
$job->command = 'php '
|
||||||
|
. FileUtils::absolute(__DIR__ . '/../../../Cli/cli.php')
|
||||||
|
. ' /workflow/instance -id '
|
||||||
|
. $template->getId()
|
||||||
|
. ' -trigger 1005500005';
|
||||||
|
|
||||||
|
$scheduler->create($job);
|
||||||
|
$scheduler->reload();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse and replace placeholder elements
|
* Parse and replace placeholder elements
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Modules\Workflow\Controller;
|
namespace Modules\Workflow\Controller;
|
||||||
|
|
||||||
|
use Modules\Workflow\Models\WorkflowInstance;
|
||||||
use Modules\Workflow\Models\WorkflowInstanceAbstract;
|
use Modules\Workflow\Models\WorkflowInstanceAbstract;
|
||||||
|
use Modules\Workflow\Models\WorkflowInstanceAbstractMapper;
|
||||||
use Modules\Workflow\Models\WorkflowStatus;
|
use Modules\Workflow\Models\WorkflowStatus;
|
||||||
use Modules\Workflow\Models\WorkflowTemplate;
|
use Modules\Workflow\Models\WorkflowTemplate;
|
||||||
use Modules\Workflow\Models\WorkflowTemplateMapper;
|
use Modules\Workflow\Models\WorkflowTemplateMapper;
|
||||||
|
|
@ -122,6 +124,21 @@ final class CliController extends Controller
|
||||||
return $view;
|
return $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function runWorkflowElement(array $actions, WorkflowTemplate $template, WorkflowInstanceAbstract $instance, array $element) : void
|
||||||
|
{
|
||||||
|
if (isset($actions[$element['id']])) {
|
||||||
|
$result = $this->app->moduleManager
|
||||||
|
->get($actions[$element['id']]['modules'], $actions[$element['id']]['function_type'])
|
||||||
|
->{$actions[$element['id']]['function']}($template);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo: currently all children are executed one after another, maybe consider parallel execution
|
||||||
|
foreach ($element['children'] as $child) {
|
||||||
|
// @todo: pass previous results (probably needs a populator for input variables based on previous output variables)
|
||||||
|
$this->runWorkflowElement($actions, $template, $instance, $child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate template create request
|
* Validate template create request
|
||||||
*
|
*
|
||||||
|
|
@ -134,7 +151,7 @@ final class CliController extends Controller
|
||||||
private function validateInstanceCreate(RequestAbstract $request) : array
|
private function validateInstanceCreate(RequestAbstract $request) : array
|
||||||
{
|
{
|
||||||
$val = [];
|
$val = [];
|
||||||
if (($val['j'] = !$request->hasData('j'))) {
|
if (($val['id'] = !$request->hasData('id'))) {
|
||||||
return $val;
|
return $val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,6 +164,8 @@ final class CliController extends Controller
|
||||||
* @param RequestAbstract $request Request
|
* @param RequestAbstract $request Request
|
||||||
*
|
*
|
||||||
* @return WorkflowInstanceAbstract
|
* @return WorkflowInstanceAbstract
|
||||||
|
*
|
||||||
|
* @todo: How to handle workflow instances which are not saved in the database and are continued?
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
|
|
@ -154,28 +173,21 @@ final class CliController extends Controller
|
||||||
{
|
{
|
||||||
/** @var \Modules\Workflow\Models\WorkflowTemplate $template */
|
/** @var \Modules\Workflow\Models\WorkflowTemplate $template */
|
||||||
$template = WorkflowTemplateMapper::get()
|
$template = WorkflowTemplateMapper::get()
|
||||||
->where('id', (int) $request->getData('j'))
|
->where('id', (int) $request->getData('id'))
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$controller = null;
|
$instance = new WorkflowInstance();
|
||||||
|
|
||||||
$files = $template->source->getSources();
|
$actions = \json_decode(\file_get_contents(__DIR__ . '/../Definitions/actions.json'), true);
|
||||||
foreach ($files as $tMedia) {
|
|
||||||
$lowerPath = \strtolower($tMedia->getPath());
|
|
||||||
|
|
||||||
switch (true) {
|
foreach ($template->schema as $e) {
|
||||||
case StringUtils::endsWith($lowerPath, 'WorkflowController.php'):
|
if ($e['id'] === $request->getDataString('trigger')) {
|
||||||
require_once $lowerPath;
|
$this->runWorkflowElement($actions, $template, $instance, $e);
|
||||||
|
|
||||||
$controller = new WorkflowController($this->app, $template);
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var \Modules\Workflow\Models\WorkflowControllerInterface $controller */
|
|
||||||
$instance = $controller->createInstanceFromRequest($request, $template);
|
|
||||||
$controller->createInstanceDbModel($instance);
|
|
||||||
|
|
||||||
return $instance;
|
return $instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,13 @@ A `States.php` file contains all workflow states. This is especially important i
|
||||||
|
|
||||||
The `Workflow.php` file is the heart of every workflow. This file is responsible for executing state driven actions and it can also be seen as the API for a workflow. All workflow related actions will be forwarded to this file and can be handled inside including database queries.
|
The `Workflow.php` file is the heart of every workflow. This file is responsible for executing state driven actions and it can also be seen as the API for a workflow. All workflow related actions will be forwarded to this file and can be handled inside including database queries.
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
||||||
|
1. Workflow gets installed with a trigger (either hook or cron job)
|
||||||
|
2. Trigger is fired
|
||||||
|
3. Hook loads CliApplication::installWorkflowTemplate with template ID, action ID and Hook
|
||||||
|
4. Installer creates WorkflowInstance Model
|
||||||
|
5. Installer calls CliApplication::runWorkflow with template, action ID, Hook, instance, and element for every element on this level.
|
||||||
|
6. runWorkflow executes the element by calling the respective function
|
||||||
|
7. runWorkflow calls itself with all child elements
|
||||||
|
|
|
||||||
27
Models/WorkflowInstance.php
Normal file
27
Models/WorkflowInstance.php
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Karaka
|
||||||
|
*
|
||||||
|
* PHP Version 8.1
|
||||||
|
*
|
||||||
|
* @package Modules\Workflow\Models
|
||||||
|
* @copyright Dennis Eichhorn
|
||||||
|
* @license OMS License 2.0
|
||||||
|
* @version 1.0.0
|
||||||
|
* @link https://jingga.app
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Modules\Workflow\Models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workflow instance model
|
||||||
|
*
|
||||||
|
* @package Modules\Workflow\Models
|
||||||
|
* @license OMS License 2.0
|
||||||
|
* @link https://jingga.app
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
class WorkflowInstance extends WorkflowInstanceAbstract
|
||||||
|
{
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user