2020-10-20 01:53:00 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class CRUDComponent extends Component
|
|
|
|
{
|
2020-12-22 17:10:28 +01:00
|
|
|
/** @var AppController */
|
2020-10-20 01:53:00 +02:00
|
|
|
public $Controller = null;
|
|
|
|
|
|
|
|
public function initialize(Controller $controller, $settings=array()) {
|
|
|
|
$this->Controller = $controller;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function prepareResponse()
|
|
|
|
{
|
|
|
|
if ($this->Controller->request->is('ajax')) {
|
|
|
|
$this->Controller->set('ajax', true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-07 12:24:10 +01:00
|
|
|
public function index(array $options)
|
2020-10-20 01:53:00 +02:00
|
|
|
{
|
|
|
|
$this->prepareResponse();
|
|
|
|
if (!empty($options['quickFilters'])) {
|
|
|
|
if (empty($options['filters'])) {
|
|
|
|
$options['filters'] = [];
|
|
|
|
}
|
|
|
|
$options['filters'][] = 'quickFilter';
|
|
|
|
}
|
|
|
|
$params = $this->Controller->IndexFilter->harvestParameters(empty($options['filters']) ? [] : $options['filters']);
|
|
|
|
$query = [];
|
|
|
|
$query = $this->setFilters($params, $query);
|
|
|
|
$query = $this->setQuickFilters($params, $query, empty($options['quickFilters']) ? [] : $options['quickFilters']);
|
|
|
|
if (!empty($options['contain'])) {
|
|
|
|
$query['contain'] = $options['contain'];
|
|
|
|
}
|
|
|
|
if (!empty($options['conditions'])) {
|
|
|
|
$query['conditions']['AND'][] = $options['conditions'];
|
|
|
|
}
|
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
2020-11-11 10:45:39 +01:00
|
|
|
if (!empty($this->Controller->paginate['fields'])) {
|
|
|
|
$query['fields'] = $this->Controller->paginate['fields'];
|
|
|
|
}
|
2020-10-20 01:53:00 +02:00
|
|
|
$data = $this->Controller->{$this->Controller->defaultModel}->find('all', $query);
|
2020-11-11 10:45:39 +01:00
|
|
|
if (isset($options['afterFind'])) {
|
2020-11-30 23:35:02 +01:00
|
|
|
if (is_callable($options['afterFind'])) {
|
|
|
|
$data = $options['afterFind']($data);
|
|
|
|
} else {
|
|
|
|
$data = $this->Controller->{$this->Controller->defaultModel}->{$options['afterFind']}($data);
|
|
|
|
}
|
2020-11-11 10:45:39 +01:00
|
|
|
}
|
2020-10-20 01:53:00 +02:00
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->viewData($data, 'json');
|
|
|
|
} else {
|
|
|
|
$this->Controller->paginate = $query;
|
|
|
|
$data = $this->Controller->paginate();
|
2020-11-11 10:45:39 +01:00
|
|
|
if (isset($options['afterFind'])) {
|
2020-11-30 23:35:02 +01:00
|
|
|
if (is_callable($options['afterFind'])) {
|
|
|
|
$data = $options['afterFind']($data);
|
|
|
|
} else {
|
|
|
|
$data = $this->Controller->{$this->Controller->defaultModel}->{$options['afterFind']}($data);
|
|
|
|
}
|
2020-11-11 10:45:39 +01:00
|
|
|
}
|
2020-10-20 01:53:00 +02:00
|
|
|
$this->Controller->set('data', $data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function add(array $params = [])
|
|
|
|
{
|
|
|
|
$modelName = $this->Controller->defaultModel;
|
|
|
|
$data = [];
|
|
|
|
if ($this->Controller->request->is('post')) {
|
|
|
|
$input = $this->Controller->request->data;
|
|
|
|
if (empty($input[$modelName])) {
|
|
|
|
$input = [$modelName => $input];
|
|
|
|
}
|
|
|
|
if (!empty($params['override'])) {
|
|
|
|
foreach ($params['override'] as $field => $value) {
|
|
|
|
$input[$modelName][$field] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unset($input[$modelName]['id']);
|
|
|
|
if (!empty($params['fields'])) {
|
|
|
|
$data = [];
|
|
|
|
foreach ($params['fields'] as $field) {
|
|
|
|
$data[$field] = $input[$modelName][$field];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$data = $input;
|
|
|
|
}
|
2020-12-03 14:26:03 +01:00
|
|
|
/** @var Model $model */
|
|
|
|
$model = $this->Controller->{$modelName};
|
|
|
|
if ($model->save($data)) {
|
|
|
|
$data = $model->find('first', [
|
2020-10-20 01:53:00 +02:00
|
|
|
'recursive' => -1,
|
|
|
|
'conditions' => [
|
2020-12-03 14:26:03 +01:00
|
|
|
'id' => $model->id
|
2020-10-20 01:53:00 +02:00
|
|
|
]
|
|
|
|
]);
|
|
|
|
if (!empty($params['saveModelVariable'])) {
|
|
|
|
foreach ($params['saveModelVariable'] as $var) {
|
2020-12-03 14:26:03 +01:00
|
|
|
if (isset($model->$var)) {
|
|
|
|
$data[$modelName][$var] = $model->$var;
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-12-04 15:59:26 +01:00
|
|
|
if (isset($params['afterFind'])) {
|
|
|
|
$data = $params['afterFind']($data);
|
|
|
|
}
|
2020-10-20 01:53:00 +02:00
|
|
|
$message = __('%s added.', $modelName);
|
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->viewData($data, 'json');
|
|
|
|
} else {
|
|
|
|
$this->Controller->Flash->success($message);
|
|
|
|
if (!empty($params['displayOnSuccess'])) {
|
|
|
|
$this->Controller->set('entity', $data);
|
|
|
|
$this->Controller->set('referer', $this->Controller->referer());
|
|
|
|
$this->Controller->render($params['displayOnSuccess']);
|
|
|
|
return;
|
|
|
|
}
|
2020-12-22 17:42:29 +01:00
|
|
|
|
|
|
|
$redirect = isset($params['redirect']) ? $params['redirect'] : ['action' => 'index'];
|
|
|
|
// For AJAX requests doesn't make sense to redirect, redirect must be done on javascript side in `submitGenericFormInPlace`
|
|
|
|
if ($this->Controller->request->is('ajax')) {
|
|
|
|
$redirect = Router::url($redirect);
|
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->viewData(['redirect' => $redirect], 'json');
|
|
|
|
} else {
|
|
|
|
$this->Controller->redirect($redirect);
|
|
|
|
}
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$message = __('%s could not be added.', $modelName);
|
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
2020-12-03 14:26:03 +01:00
|
|
|
$controllerName = $this->Controller->params['controller'];
|
|
|
|
$actionName = $this->Controller->params['action'];
|
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->saveFailResponse($controllerName, $actionName, false, $model->validationErrors, 'json');
|
2020-10-20 01:53:00 +02:00
|
|
|
} else {
|
|
|
|
$this->Controller->Flash->error($message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$this->Controller->set('entity', $data);
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:48:38 +01:00
|
|
|
public function edit(int $id, array $params = [])
|
2020-10-20 01:53:00 +02:00
|
|
|
{
|
|
|
|
$modelName = $this->Controller->defaultModel;
|
|
|
|
if (empty($id)) {
|
2020-11-15 14:51:41 +01:00
|
|
|
throw new NotFoundException(__('Invalid %s.', $modelName));
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
$data = $this->Controller->{$modelName}->find('first',
|
|
|
|
isset($params['get']) ? $params['get'] : [
|
|
|
|
'recursive' => -1,
|
|
|
|
'conditions' => [
|
|
|
|
'id' => $id
|
|
|
|
]
|
|
|
|
]);
|
|
|
|
if ($this->Controller->request->is('post') || $this->Controller->request->is('put')) {
|
|
|
|
$input = $this->Controller->request->data;
|
|
|
|
if (empty($input[$modelName])) {
|
|
|
|
$input = [$modelName => $input];
|
|
|
|
}
|
|
|
|
if (!empty($params['override'])) {
|
|
|
|
foreach ($params['override'] as $field => $value) {
|
|
|
|
$input[$field] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!empty($params['fields'])) {
|
|
|
|
foreach ($params['fields'] as $field) {
|
2020-11-30 23:35:02 +01:00
|
|
|
$data[$modelName][$field] = $input[$modelName][$field];
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-11-30 23:35:02 +01:00
|
|
|
foreach ($input[$modelName] as $field => $fieldData) {
|
|
|
|
$data[$modelName][$field] = $fieldData;
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($this->Controller->{$modelName}->save($data)) {
|
|
|
|
$message = __('%s updated.', $modelName);
|
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->viewData($data, 'json');
|
2020-12-22 14:38:28 +01:00
|
|
|
return;
|
2020-10-20 01:53:00 +02:00
|
|
|
} else {
|
|
|
|
$this->Controller->Flash->success($message);
|
2020-12-22 14:38:28 +01:00
|
|
|
$this->Controller->redirect(isset($params['redirect']) ? $params['redirect'] : ['action' => 'index']);
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2020-11-30 23:35:02 +01:00
|
|
|
} else {
|
|
|
|
$this->Controller->request->data = $data;
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
$this->Controller->set('entity', $data);
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:48:38 +01:00
|
|
|
public function view(int $id, array $params = [])
|
2020-10-20 01:53:00 +02:00
|
|
|
{
|
2020-11-15 14:51:41 +01:00
|
|
|
$modelName = $this->Controller->defaultModel;
|
2020-10-20 01:53:00 +02:00
|
|
|
if (empty($id)) {
|
2020-11-15 14:51:41 +01:00
|
|
|
throw new NotFoundException(__('Invalid %s.', $modelName));
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
2020-11-15 14:51:41 +01:00
|
|
|
$query = [
|
2020-10-20 01:53:00 +02:00
|
|
|
'recursive' => -1,
|
2020-11-15 14:51:41 +01:00
|
|
|
'conditions' => [$modelName . '.id' => $id],
|
2020-10-20 01:53:00 +02:00
|
|
|
'contain' => empty($params['contain']) ? [] : $params['contain']
|
2020-11-15 14:51:41 +01:00
|
|
|
];
|
|
|
|
if (!empty($params['conditions'])) {
|
|
|
|
$query['conditions']['AND'][] = $params['conditions'];
|
|
|
|
}
|
|
|
|
$data = $this->Controller->{$modelName}->find('first', $query);
|
|
|
|
if (empty($data)) {
|
|
|
|
throw new NotFoundException(__('Invalid %s.', $modelName));
|
|
|
|
}
|
2020-11-29 20:13:41 +01:00
|
|
|
if (isset($params['afterFind'])) {
|
|
|
|
$data = $params['afterFind']($data);
|
|
|
|
}
|
2020-10-20 01:53:00 +02:00
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->viewData($data, 'json');
|
|
|
|
} else {
|
|
|
|
$this->Controller->set('data', $data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:48:38 +01:00
|
|
|
public function delete(int $id, array $params = [])
|
2020-10-20 01:53:00 +02:00
|
|
|
{
|
|
|
|
$this->prepareResponse();
|
|
|
|
$modelName = $this->Controller->defaultModel;
|
|
|
|
if (empty($id)) {
|
2020-11-15 14:51:41 +01:00
|
|
|
throw new NotFoundException(__('Invalid %s.', $modelName));
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
$conditions = [];
|
2020-11-15 14:51:41 +01:00
|
|
|
$conditions['AND'][] = [$modelName . '.id' => $id];
|
2020-10-20 01:53:00 +02:00
|
|
|
if (!empty($params['conditions'])) {
|
|
|
|
$conditions['AND'][] = $params['conditions'];
|
|
|
|
}
|
|
|
|
$data = $this->Controller->{$modelName}->find('first', [
|
|
|
|
'recursive' => -1,
|
2020-11-15 14:51:41 +01:00
|
|
|
'conditions' => $conditions,
|
|
|
|
'contain' => empty($params['contain']) ? [] : $params['contain'],
|
2020-10-20 01:53:00 +02:00
|
|
|
]);
|
|
|
|
if (empty($data)) {
|
2020-11-15 14:51:41 +01:00
|
|
|
throw new NotFoundException(__('Invalid %s.', $modelName));
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
2020-12-22 17:10:28 +01:00
|
|
|
$validationError = null;
|
|
|
|
if (isset($params['validate'])) {
|
|
|
|
try {
|
|
|
|
$params['validate']($data);
|
|
|
|
} catch (Exception $e) {
|
|
|
|
$validationError = $e->getMessage();
|
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->saveFailResponse($modelName, 'delete', $id, $validationError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($validationError === null && $this->Controller->request->is('post') || $this->Controller->request->is('delete')) {
|
2020-11-11 10:45:39 +01:00
|
|
|
if (!empty($params['modelFunction'])) {
|
|
|
|
$result = $this->Controller->$modelName->{$params['modelFunction']}($id);
|
|
|
|
} else {
|
|
|
|
$result = $this->Controller->{$modelName}->delete($id);
|
|
|
|
}
|
|
|
|
if ($result) {
|
2020-10-20 01:53:00 +02:00
|
|
|
$message = __('%s deleted.', $modelName);
|
|
|
|
if ($this->Controller->IndexFilter->isRest()) {
|
2020-11-15 14:51:41 +01:00
|
|
|
$this->Controller->restResponsePayload = $this->Controller->RestResponse->saveSuccessResponse($modelName, 'delete', $id, 'json', $message);
|
2020-12-22 17:10:28 +01:00
|
|
|
return;
|
2020-10-20 01:53:00 +02:00
|
|
|
} else {
|
|
|
|
$this->Controller->Flash->success($message);
|
|
|
|
$this->Controller->redirect($this->Controller->referer());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-12-22 17:10:28 +01:00
|
|
|
$this->Controller->set('validationError', $validationError);
|
2020-10-20 01:53:00 +02:00
|
|
|
$this->Controller->set('id', $data[$modelName]['id']);
|
|
|
|
$this->Controller->set('data', $data);
|
|
|
|
$this->Controller->layout = 'ajax';
|
|
|
|
$this->Controller->render('/genericTemplates/delete');
|
|
|
|
}
|
|
|
|
|
2020-12-07 12:24:10 +01:00
|
|
|
protected function setQuickFilters($params, array $query, $quickFilterFields)
|
2020-10-20 01:53:00 +02:00
|
|
|
{
|
|
|
|
if (!empty($params['quickFilter']) && !empty($quickFilterFields)) {
|
2020-12-07 12:24:10 +01:00
|
|
|
$queryConditions = [];
|
|
|
|
$filter = '%' . strtolower($params['quickFilter']) . '%';
|
2020-10-20 01:53:00 +02:00
|
|
|
foreach ($quickFilterFields as $filterField) {
|
2020-12-07 12:24:10 +01:00
|
|
|
$queryConditions["LOWER($filterField) LIKE"] = $filter;
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
2020-12-07 12:24:10 +01:00
|
|
|
$query['conditions']['OR'] = $queryConditions;
|
2020-10-20 01:53:00 +02:00
|
|
|
}
|
|
|
|
return $query;
|
|
|
|
}
|
|
|
|
|
2020-12-07 12:24:10 +01:00
|
|
|
protected function setFilters(array $params, array $query)
|
2020-10-20 01:53:00 +02:00
|
|
|
{
|
2020-12-07 12:24:10 +01:00
|
|
|
// For CakePHP 2, we don't need to distinguish between simpleFilters and relatedFilters
|
|
|
|
//$params = $this->massageFilters($params);
|
|
|
|
if (!empty($params)) {
|
|
|
|
foreach ($params as $filter => $filterValue) {
|
2020-10-20 01:53:00 +02:00
|
|
|
if ($filter === 'quickFilter') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (strlen(trim($filterValue, '%')) === strlen($filterValue)) {
|
|
|
|
$query['conditions']['AND'][] = [$filter => $filterValue];
|
|
|
|
} else {
|
|
|
|
$query['conditions']['AND'][] = [$filter . ' LIKE' => $filterValue];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Currently not implemented
|
|
|
|
if (!empty($params['relatedFilters'])) {
|
|
|
|
foreach ($params['relatedFilters'] as $filter => $filterValue) {
|
|
|
|
$filterParts = explode('.', $filter);
|
|
|
|
$query->matching($filterParts[0], function(\Cake\ORM\Query $q) use ($filterValue, $filter) {
|
|
|
|
if (strlen(trim($filterValue, '%')) === strlen($filterValue)) {
|
|
|
|
return $q->where([$filter => $filterValue]);
|
|
|
|
} else {
|
|
|
|
return $q->like([$filter => $filterValue]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
return $query;
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:48:38 +01:00
|
|
|
protected function massageFilters(array $params)
|
2020-10-20 01:53:00 +02:00
|
|
|
{
|
|
|
|
$massagedFilters = [
|
|
|
|
'simpleFilters' => [],
|
|
|
|
'relatedFilters' => []
|
|
|
|
];
|
|
|
|
if (!empty($params)) {
|
|
|
|
foreach ($params as $param => $paramValue) {
|
|
|
|
if (strpos($param, '.') !== false) {
|
|
|
|
$param = explode('.', $param);
|
|
|
|
if ($param[0] === $this->Controller->{$this->Controller->defaultModel}) {
|
|
|
|
$massagedFilters['simpleFilters'][implode('.', $param)] = $paramValue;
|
|
|
|
} else {
|
|
|
|
$massagedFilters['relatedFilters'][implode('.', $param)] = $paramValue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$massagedFilters['simpleFilters'][$param] = $paramValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $massagedFilters;
|
|
|
|
}
|
|
|
|
}
|