Created
August 3, 2020 09:11
-
-
Save geoidesic/de5c046448e146426bdb34090aa80c2d to your computer and use it in GitHub Desktop.
Refactor attempt of the CrudJsonApiControllerTrait as a CRUD Action class extension (note the `print_r` which mysteriously doesn't yield the request body)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Crud\Action; | |
use Cake\Http\Response; | |
use Crud\Error\Exception\ValidationException; | |
use Crud\Event\Subject; | |
use Crud\Traits\FindMethodTrait; | |
use Crud\Traits\RedirectTrait; | |
use Crud\Traits\SaveMethodTrait; | |
use Crud\Traits\SerializeTrait; | |
use Crud\Traits\ViewTrait; | |
use Crud\Traits\ViewVarTrait; | |
use Crud\Action\BaseAction; | |
/** | |
* Handles 'Edit' Crud actions | |
* | |
* Licensed under The MIT License | |
* For full copyright and license information, please see the LICENSE.txt | |
*/ | |
class RelationshipsAction extends BaseAction | |
{ | |
use FindMethodTrait; | |
use RedirectTrait; | |
use SaveMethodTrait; | |
use SerializeTrait; | |
use ViewTrait; | |
use ViewVarTrait; | |
/** | |
* Default settings for 'edit' actions | |
* | |
* `enabled` Is this crud action enabled or disabled | |
* | |
* `findMethod` The default `Model::find()` method for reading data | |
* | |
* `view` A map of the controller action and the view to render | |
* If `NULL` (the default) the controller action name will be used | |
* | |
* `relatedModels` is a map of the controller action and the whether it should fetch associations lists | |
* to be used in select boxes. An array as value means it is enabled and represent the list | |
* of model associations to be fetched | |
* | |
* `saveOptions` Options array used for $options argument of patchEntity() and save method. | |
* If you configure a key with your action name, it will override the default settings. | |
* | |
* @var array | |
*/ | |
protected $_defaultConfig = [ | |
'enabled' => true, | |
'scope' => 'entity', | |
'findMethod' => 'all', | |
'saveMethod' => 'save', | |
'view' => null, | |
'relatedModels' => true, | |
'saveOptions' => [], | |
'messages' => [ | |
'success' => [ | |
'text' => 'Successfully updated {name}', | |
], | |
'error' => [ | |
'text' => 'Could not update {name}', | |
], | |
], | |
'redirect' => [ | |
'post_add' => [ | |
'reader' => 'request.data', | |
'key' => '_add', | |
'url' => ['action' => 'add'], | |
], | |
'post_edit' => [ | |
'reader' => 'request.data', | |
'key' => '_edit', | |
'url' => ['action' => 'edit', ['subject.key', 'id']], | |
], | |
], | |
'api' => [ | |
'methods' => ['put', 'post', 'patch'], | |
'success' => [ | |
'code' => 200, | |
], | |
'error' => [ | |
'exception' => [ | |
'type' => 'validate', | |
'class' => ValidationException::class, | |
], | |
], | |
], | |
'serialize' => [], | |
]; | |
/** | |
* HTTP GET handler | |
* | |
* @param string|null $id Record id | |
* @return void | |
* @throws \Cake\Http\Exception\NotFoundException If record not found | |
*/ | |
protected function _get(?string $id = null): void | |
{ | |
$subject = $this->_subject(); | |
$subject->set(['id' => $id]); | |
$subject->set(['entity' => $this->_findRecord($id, $subject)]); | |
$this->_trigger('beforeRender', $subject); | |
} | |
/** | |
* HTTP PUT handler | |
* | |
* @param string|null $id Record id | |
* @return \Cake\Http\Response|null | |
*/ | |
protected function _put(?string $id = null) | |
{ | |
$subject = $this->_subject(); | |
$subject->set(['id' => $id]); | |
$entity = $this->_table()->patchEntity( | |
$this->_findRecord($id, $subject), | |
$this->_request()->getData(), | |
$this->saveOptions() | |
); | |
$this->_trigger('beforeSave', $subject); | |
if (call_user_func([$this->_table(), $this->saveMethod()], $entity, $this->saveOptions())) { | |
return $this->_success($subject); | |
} | |
$this->_error($subject); | |
} | |
/** | |
* HTTP POST handler | |
* | |
* Thin proxy for _put | |
* | |
* @param string|null $id Record id | |
* @return \Cake\Http\Response|null | |
*/ | |
protected function _post(?string $id = null) | |
{ | |
return $this->_put($id); | |
} | |
/** | |
* HTTP PATCH handler | |
* | |
* @param string|null $id Record id | |
* @return \Cake\Http\Response|null | |
*/ | |
protected function _patch() | |
{ | |
$subject = $this->_subject(); | |
$request = $this->_request(); | |
$id = $request->getParam('id'); | |
$foreignTableName = $request->getParam('foreignTableName'); | |
print_r($data); | |
$subject->set(['id' => $id]); | |
$entity = $this->_table()->patchEntity( | |
$this->_findRecord($id, $subject), | |
$this->_request()->getData(), | |
$this->saveOptions() | |
); | |
if (empty((array)$data['data'])) { | |
$entity->$foreignTableName = []; | |
} else { | |
$entity->$foreignTableName = []; | |
foreach ($data['data'] as $key => $recordAttributes) { | |
// get the related record | |
$foreignTable = $this->getTableLocator()->get(Inflector::camelize($foreignTableName)); | |
$foreignKey = $foreignTableName . '.id'; | |
$query = $foreignTable->findAllById($recordAttributes['id']); | |
$foreignRecord = $query->first(); | |
// push it onto the relationsships array if it exists | |
if (!empty($foreignRecord)) { | |
array_push($entity->$foreignTableName, $foreignRecord); | |
} | |
} | |
} | |
$this->_trigger('beforeSave', $subject); | |
if (call_user_func([$this->_table(), $this->saveMethod()], $entity, $this->saveOptions())) { | |
return $this->_success($subject); | |
} | |
$this->_error($subject); | |
} | |
/** | |
* Success callback | |
* | |
* @param \Crud\Event\Subject $subject Event subject | |
* @return \Cake\Http\Response|null | |
*/ | |
protected function _success(Subject $subject): ?Response | |
{ | |
$subject->set(['success' => true, 'created' => false]); | |
// $this->_trigger('afterSave', $subject); | |
$this->setFlash('success', $subject); | |
return $this->_redirect($subject, ['action' => 'index']); | |
} | |
/** | |
* Error callback | |
* | |
* @param \Crud\Event\Subject $subject Event subject | |
* @return void | |
*/ | |
protected function _error(Subject $subject): void | |
{ | |
$subject->set(['success' => false, 'created' => false]); | |
$this->_trigger('afterSave', $subject); | |
$this->setFlash('error', $subject); | |
$this->_trigger('beforeRender', $subject); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment