-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from fr3nch13/dev
Adding controller traits and tests for them.
- Loading branch information
Showing
22 changed files
with
1,059 additions
and
15 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
/** | ||
* AppController | ||
*/ | ||
|
||
namespace Fr3nch13\Utilities\Controller; | ||
|
||
use Cake\View\JsonView; | ||
|
||
/** | ||
* App Controller | ||
* | ||
* @property \Cake\Controller\Component\RequestHandlerComponent $RequestHandler | ||
* @property \Cake\Controller\Component\FlashComponent $Flash | ||
*/ | ||
|
||
class AppController extends \Cake\Controller\Controller | ||
{ | ||
/** | ||
* Sets what classes this controller uses. | ||
* | ||
* @return array<string> | ||
*/ | ||
public function viewClasses(): array | ||
{ | ||
return [JsonView::class]; | ||
} | ||
|
||
/** | ||
* Figures out the referer with a given default. | ||
* | ||
* @param mixed|null $referer the default referer. | ||
* @return mixed The determined referer to use. | ||
*/ | ||
public function getReferer($referer = null) | ||
{ | ||
if (!$referer) { | ||
$referer = $this->getRequest()->referer(); | ||
} | ||
|
||
if ($this->getRequest()->getQuery('referer')) { | ||
$referer = $this->getRequest()->getQuery('referer'); | ||
if (is_string($referer) && strpos($referer, '%') !== false) { | ||
$referer = urldecode($referer); | ||
} | ||
} | ||
|
||
return $referer; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
/** | ||
* CoursesController | ||
*/ | ||
|
||
namespace Fr3nch13\Utilities\Controller; | ||
|
||
use Cake\Core\Configure; | ||
|
||
/** | ||
* Courses Controller | ||
* | ||
* Used to test the Controller Toggle Trait. | ||
* | ||
* @property \Cake\Controller\Component\RequestHandlerComponent $RequestHandler | ||
* @property \Fr3nch13\Utilities\Model\Table\CoursesTable $Courses | ||
*/ | ||
class CoursesController extends AppController | ||
{ | ||
use MergeDeleteTrait; | ||
use ToggleTrait; | ||
|
||
/** | ||
* Setup stuff for the actions to use | ||
* | ||
* @return void | ||
*/ | ||
public function initialize(): void | ||
{ | ||
parent::initialize(); | ||
if (Configure::check('LoadFlash') && Configure::read('LoadFlash')) { | ||
$this->loadComponent('Flash'); | ||
} | ||
} | ||
|
||
/** | ||
* Index method | ||
* | ||
* @return void | ||
*/ | ||
public function index(): void | ||
{ | ||
$courses = $this->Courses->find('all')->all(); | ||
$this->set(compact('courses')); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
/** | ||
* FuModelFindTrait | ||
*/ | ||
|
||
namespace Fr3nch13\Utilities\Controller; | ||
|
||
use Cake\Core\Configure; | ||
use Cake\Http\Exception\NotFoundException; | ||
|
||
trait FuModelFindTrait | ||
{ | ||
/** | ||
* The name of the model we're using, if it's not set, | ||
* then it'll use the name of the controller, to try to figure it out. | ||
* | ||
* @var null|string The name of the model. | ||
*/ | ||
public $fuModel = null; | ||
|
||
/** | ||
* @var null|string The model alias to use. | ||
*/ | ||
public $fuModelAlias = null; | ||
|
||
/** | ||
* Used to find the model for the other taits here. | ||
* @return void | ||
*/ | ||
public function traitModelFind(): void | ||
{ | ||
// try to figure out what model to use from the controller name. | ||
if (!$this->fuModel) { | ||
$this->fuModel = $this->defaultTable; | ||
// used for testing but should be set in the controller, not through Configure. | ||
if (Configure::check('fuModel')) { | ||
$this->fuModel = Configure::read('fuModel'); | ||
} | ||
} | ||
|
||
// If we're in a plugin, see if we can load the overloaded model from the app, if it exists. | ||
// This is incase there are other relationships we need to account for. | ||
$this->fuModelAlias = $this->fuModel; | ||
if (strpos($this->fuModel, '.') !== false) { | ||
$parts = explode('.', $this->fuModel); | ||
$this->fuModelAlias = array_pop($parts); | ||
// thows an exception if TableLocator::allowFallbackClass(false) | ||
try { | ||
$table = $this->fetchTable($this->fuModelAlias); | ||
if (get_class($table) != 'Cake\ORM\Table') { | ||
$this->{$this->fuModelAlias} = $table; | ||
} | ||
} catch (\Exception $e) { | ||
// pass | ||
} | ||
} | ||
|
||
// if it wasn't found as a model in app (aka, not overloaded), then use the plugin model. | ||
if (!isset($this->{$this->fuModelAlias})) { | ||
try { | ||
$this->{$this->fuModelAlias} = $this->fetchTable($this->fuModel); | ||
} catch (\Exception $e) { | ||
// pass | ||
} | ||
} | ||
|
||
// if we can't figure it out, throw an error to the user. | ||
// This looks for CahePHP's autoloading of tables. | ||
if (!isset($this->{$this->fuModelAlias}) || get_class($this->{$this->fuModelAlias}) == 'Cake\ORM\Table') { | ||
throw new NotFoundException(__('Unable to find the model `{0}` (alias:{1}) to use to toggle.', [ | ||
$this->fuModel, | ||
$this->fuModelAlias, | ||
])); | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
/** | ||
* MergeDeleteTrait | ||
*/ | ||
|
||
namespace Fr3nch13\Utilities\Controller; | ||
|
||
use Cake\Core\Configure; | ||
use Cake\Http\Exception\NotFoundException; | ||
|
||
/** | ||
* Merge/Delete Trait | ||
* | ||
* Common methods merging one record into another, then deleting the first record. | ||
*/ | ||
trait MergeDeleteTrait | ||
{ | ||
use FuModelFindTrait; | ||
|
||
/** | ||
* The merge-delete display field of the model. | ||
* Can be either real, or virtual. | ||
* | ||
* @var null|string | ||
*/ | ||
public $mdDisplayField = null; | ||
|
||
/** | ||
* Allows to merge associated records from one attribute to another, then delete the old record. | ||
* | ||
* @param int $sourceId The record id to delete. | ||
* @return \Cake\Http\Response|null | ||
* @throws \Cake\Http\Exception\NotFoundException When record not found. | ||
*/ | ||
public function mergeDelete($sourceId): ?\Cake\Http\Response | ||
{ | ||
$this->traitModelFind(); | ||
|
||
try { | ||
$sourceRecord = $this->{$this->fuModelAlias}->get($sourceId); | ||
} catch (\Exception $e) { | ||
throw new NotFoundException(__('Unable to find the old record to merge/delete.')); | ||
} | ||
|
||
if ($this->getRequest()->is(['patch', 'post', 'put'])) { | ||
$data = $this->getRequest()->getData(); | ||
|
||
if (!isset($data['id']) || !$data['id']) { | ||
throw new NotFoundException(__('No new record was selected.')); | ||
} | ||
if (is_string($data['id'])) { | ||
$data['id'] = intval($data['id']); | ||
} | ||
|
||
try { | ||
$result = $this->{$this->fuModelAlias}->mergeDelete($sourceRecord->get('id'), $data['id']); | ||
if ($result) { | ||
$this->Flash->success(__('The Old record has been merged into the new record, and deleted.')); | ||
$redirect = ['action' => 'index']; | ||
if (isset($data['referer'])) { | ||
$redirect = $data['referer']; | ||
} | ||
|
||
return $this->redirect($redirect); | ||
} | ||
} catch (\Exception $e) { | ||
throw new NotFoundException(__('Unable to merge the old record into ' . | ||
'the new record. Ensure both records exist.')); | ||
} | ||
} | ||
|
||
$displayField = $this->{$this->fuModelAlias}->getDisplayField(); | ||
// used for testing but should be set in the controller, not through Configure. | ||
if (Configure::check('mdDisplayField')) { | ||
$this->mdDisplayField = Configure::read('mdDisplayField'); | ||
} | ||
|
||
if ($this->mdDisplayField) { | ||
$displayField = $this->mdDisplayField; | ||
} | ||
|
||
$records = $this->{$this->fuModelAlias}->find('mergeRecords', [ | ||
'sourceId' => $sourceRecord->get('id'), | ||
'displayField' => $displayField, | ||
]); | ||
$stats = $this->{$this->fuModelAlias}->getMergeStats($sourceRecord->get('id')); | ||
|
||
$this->set([ | ||
'sourceRecord' => $sourceRecord, | ||
'displayField' => $displayField, | ||
'records' => $records, | ||
'stats' => $stats, | ||
]); | ||
|
||
return null; | ||
} | ||
} |
Oops, something went wrong.