cerebrate/libraries/default/OutboxProcessors/GenericOutboxProcessor.php

219 lines
7.6 KiB
PHP

<?php
use Cake\ORM\TableRegistry;
use Cake\Filesystem\File;
use Cake\Utility\Inflector;
use Cake\Validation\Validator;
use Cake\View\ViewBuilder;
use Cake\Routing\Router;
interface GenericProcessorActionI
{
public function create($requestData);
public function process($requestID, $serverRequest, $outboxRequest);
public function discard($requestID ,$requestData);
}
class GenericOutboxProcessor
{
protected $Outbox;
protected $registeredActions = [];
protected $validator;
protected $processingTemplate = '/genericTemplates/confirm';
protected $processingTemplatesDirectory = ROOT . '/libraries/default/OutboxProcessors/templates';
public function __construct($registerActions=false) {
$this->Outbox = TableRegistry::getTableLocator()->get('Outbox');
if ($registerActions) {
$this->registerActionInProcessor();
}
$this->assignProcessingTemplate();
}
private function assignProcessingTemplate()
{
$processingTemplatePath = $this->getProcessingTemplatePath();
$file = new File($this->processingTemplatesDirectory . DS . $processingTemplatePath);
if ($file->exists()) {
$this->processingTemplate = str_replace('.php', '', $processingTemplatePath);
}
$file->close();
}
protected function updateProcessingTemplate($request)
{
}
public function getRegisteredActions()
{
return $this->registeredActions;
}
public function getScope()
{
return $this->scope;
}
public function getDescription()
{
return $this->description ?? '';
}
protected function getProcessingTemplatePath()
{
return sprintf('%s/%s.php',
$this->scope,
$this->action
);
}
public function getProcessingTemplate()
{
return $this->processingTemplate;
}
public function render($request=[], Cake\Http\ServerRequest $serverRequest)
{
$viewVariables = $this->getViewVariables($request);
$this->updateProcessingTemplate($request);
$processingTemplate = $this->getProcessingTemplate();
$builder = new ViewBuilder();
$builder->disableAutoLayout()
->setClassName('Monad')
->setTemplate($processingTemplate);
$view = $builder->build($viewVariables);
$view->setRequest($serverRequest);
return $view->render();
}
protected function generateRequest($requestData)
{
$request = $this->Outbox->newEmptyEntity();
$request = $this->Outbox->patchEntity($request, $requestData);
if ($request->getErrors()) {
throw new Exception(__('Could not create request.{0}Reason: {1}', PHP_EOL, json_encode($request->getErrors())), 1);
}
return $request;
}
protected function validateRequestData($requestData)
{
$errors = [];
if (!isset($requestData['data'])) {
$errors[] = __('No request data provided');
}
$validator = new Validator();
if (method_exists($this, 'addValidatorRules')) {
$validator = $this->addValidatorRules($validator);
$errors = $validator->validate($requestData['data']);
}
if (!empty($errors)) {
throw new Exception('Error while validating request data. ' . json_encode($errors), 1);
}
}
protected function registerActionInProcessor()
{
foreach ($this->registeredActions as $i => $action) {
$className = "{$action}Processor";
$reflection = new ReflectionClass($className);
if ($reflection->isAbstract() || $reflection->isInterface()) {
throw new Exception(__('Cannot create instance of %s, as it is abstract or is an interface'));
}
$this->{$action} = $reflection->newInstance();
}
}
protected function getViewVariablesConfirmModal($id, $title='', $question='', $actionName='')
{
return [
'title' => !empty($title) ? $title : __('Process request {0}', $id),
'question' => !empty($question) ? $question : __('Confirm request {0}', $id),
'actionName' => !empty($actionName) ? $actionName : __('Confirm'),
'path' => ['controller' => 'outbox', 'action' => 'process', $id]
];
}
public function getViewVariables($request)
{
return $this->getViewVariablesConfirmModal($request->id, '', '', '');
}
protected function genActionResult($data, $success, $message, $errors=[])
{
return [
'data' => $data,
'success' => $success,
'message' => $message,
'errors' => $errors,
];
}
public function genHTTPReply($controller, $processResult, $redirect=null)
{
$scope = $this->scope;
$action = $this->action;
if ($processResult['success']) {
$message = !empty($processResult['message']) ? $processResult['message'] : __('Request {0} successfully processed.', $id);
if ($controller->ParamHandler->isRest()) {
$response = $controller->RestResponse->viewData($processResult, 'json');
} else if ($controller->ParamHandler->isAjax()) {
$response = $controller->RestResponse->ajaxSuccessResponse('OutboxProcessor', "{$scope}.{$action}", $processResult['data'], $message);
} else {
$controller->Flash->success($message);
if (!is_null($redirect)) {
$response = $controller->redirect($redirect);
} else {
$response = $controller->redirect(['action' => 'index']);
}
}
} else {
$message = !empty($processResult['message']) ? $processResult['message'] : __('Request {0} could not be processed.', $id);
if ($controller->ParamHandler->isRest()) {
$response = $controller->RestResponse->viewData($processResult, 'json');
} else if ($controller->ParamHandler->isAjax()) {
$response = $controller->RestResponse->ajaxFailResponse('OutboxProcessor', "{$scope}.{$action}", $processResult['data'], $message, $processResult['errors']);
} else {
$controller->Flash->error($message);
if (!is_null($redirect)) {
$response = $controller->redirect($redirect);
} else {
$response = $controller->redirect(['action' => 'index']);
}
}
}
return $response;
}
public function checkLoading()
{
return 'Assimilation successful!';
}
public function create($requestData)
{
$user_id = Router::getRequest()->getSession()->read('Auth.id');
$requestData['scope'] = $this->scope;
$requestData['action'] = $this->action;
$requestData['description'] = $this->description;
$requestData['user_id'] = $user_id;
$request = $this->generateRequest($requestData);
$savedRequest = $this->Outbox->createEntry($request);
return $this->genActionResult(
$savedRequest,
$savedRequest !== false,
__('{0} request for {1} created', $this->scope, $this->action),
$request->getErrors()
);
}
public function discard($id, $requestData)
{
$request = $this->Outbox->get($id);
$this->Outbox->delete($request);
return $this->genActionResult(
[],
true,
__('{0}.{1} request #{2} discarded', $this->scope, $this->action, $id)
);
}
}