diff --git a/.gitignore b/.gitignore index a399cc7..c8ac215 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ Thumbs.db # Composer /vendor/* composer.lock + +/tmp diff --git a/README.md b/README.md index 4ed9feb..adea9e6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CakePHP-LoadsysTheme +# Loadsys Bake Theme for CakePHP [![Latest Version](https://img.shields.io/github/release/loadsys/CakePHP-LoadsysTheme.svg?style=flat-square)](https://github.com/loadsys/CakePHP-LoadsysTheme/releases) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) @@ -9,7 +9,7 @@ [![Coverage Status](https://coveralls.io/repos/loadsys/CakePHP-LoadsysTheme/badge.svg)](https://coveralls.io/r/loadsys/CakePHP-LoadsysTheme) --> -CakePHP 3.x bake generation theme that matches Loadsys' code sniffer standards. +A CakePHP 3.x bake generation theme that matches Loadsys' code sniffer standards. It's designed to dovetail with our [CakePHP App Skeleton](https://github.com/loadsys/CakePHP-Skeleton). ## Requirements @@ -23,13 +23,15 @@ CakePHP 3.x bake generation theme that matches Loadsys' code sniffer standards. $ composer require loadsys/cakephp-loadsys-theme:~1.0 ```` +_This plugin includes Bake in its own composer dependencies, so when using this theme you do not need to include it separately in your projects._ + ## Usage * Add this plugin to your application by adding this line to your bootstrap.php ````php -CakePlugin::load('LoadsysTheme'); +CakePlugin::load('LoadsysTheme', ['bootstrap' => true, 'routes' => false]); ```` * To use when baking, use the CLI option `--theme LoadsysTheme` like so @@ -77,6 +79,11 @@ Please use [GitHub Isuses](https://github.com/loadsys/CakePHP-LoadsysTheme/issue When developing this plugin, please fork and issue a PR for any new development. +### Running Tests + +* `vendor/bin/phpunit --coverage-html=tmp/coverage/` +* `vendor/bin/phpcs` + ## License ## diff --git a/composer.json b/composer.json index cf08ffa..7d2bca8 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "require": { "php": ">=5.4.16", "cakephp/cakephp": "~3.0", + "cakephp/bake": "~1.1", "loadsys/loadsys_codesniffer": "~3.0" }, "require-dev": { diff --git a/config/bootstrap.php b/config/bootstrap.php new file mode 100644 index 0000000..8a391e4 --- /dev/null +++ b/config/bootstrap.php @@ -0,0 +1,26 @@ +on('Bake.initialize', function (Event $event) { + $view = $event->subject; + + // Use the LoadsysTheme if none was explicitly named. + if (empty($view->theme())) { + $view->theme('LoadsysTheme'); + } + + // Swap in our overridden BakeHelper class. + $view->helpers()->unload('Bake'); + $view->loadHelper('LoadsysTheme.Bake'); +}); diff --git a/config/routes.php b/config/routes.php index 798c4e4..0f866b0 100644 --- a/config/routes.php +++ b/config/routes.php @@ -1,6 +1,6 @@ fallbacks('InflectedRoute'); -}); +use Cake\Routing\Router; diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..384e956 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,17 @@ + + + Import rules from Loadsys standard. + + + + + + + + + + + ./config + ./src + ./tests + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e64c575..0e99764 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,7 +4,7 @@ processIsolation="false" stopOnFailure="false" syntaxCheck="false" - bootstrap="./tests/bootstrap.php" + bootstrap="tests/bootstrap.php" > @@ -18,15 +18,8 @@ - + - - - - - diff --git a/src/Controller/AppController.php b/src/Controller/AppController.php index d29017e..cc32378 100644 --- a/src/Controller/AppController.php +++ b/src/Controller/AppController.php @@ -4,7 +4,5 @@ use App\Controller\AppController as BaseController; -class AppController extends BaseController -{ - +class AppController extends BaseController { } diff --git a/src/Template/Bake/Controller/component.ctp b/src/Template/Bake/Controller/component.ctp index db0d469..73c7a2d 100644 --- a/src/Template/Bake/Controller/component.ctp +++ b/src/Template/Bake/Controller/component.ctp @@ -14,13 +14,16 @@ */ %> Component + */ namespace <%= $namespace %>\Controller\Component; use Cake\Controller\Component; use Cake\Controller\ComponentRegistry; /** - * <%= $name %> component + * \<%= $namespace %>\Controller\Component\<%= $name %> */ class <%= $name %>Component extends Component { diff --git a/src/Template/Bake/Controller/controller.ctp b/src/Template/Bake/Controller/controller.ctp index bacb11e..450d5bf 100644 --- a/src/Template/Bake/Controller/controller.ctp +++ b/src/Template/Bake/Controller/controller.ctp @@ -22,12 +22,15 @@ $defaultModel = $name; $ignoreAssociations = ['Creators', 'Modifiers']; %> Controller + */ namespace <%= $namespace %>\Controller<%= $prefix %>; use <%= $namespace %>\Controller\AppController; /** - * <%= $name %> Controller + * \<%= $namespace %>\Controller<%= $prefix %>\<%= $name %> * * @property \<%= $namespace %>\Model\Table\<%= $defaultModel %>Table $<%= $defaultModel %> <% diff --git a/src/Template/Bake/Element/Controller/delete.ctp b/src/Template/Bake/Element/Controller/delete.ctp index f4bb2fc..0537808 100644 --- a/src/Template/Bake/Element/Controller/delete.ctp +++ b/src/Template/Bake/Element/Controller/delete.ctp @@ -29,5 +29,6 @@ } else { $this->Flash->error(__('The <%= strtolower($singularHumanName) %> could not be deleted. Please, try again.')); } + return $this->redirect(['action' => 'index']); } diff --git a/src/Template/Bake/Element/Controller/edit.ctp b/src/Template/Bake/Element/Controller/edit.ctp index 35dbcd0..3326331 100644 --- a/src/Template/Bake/Element/Controller/edit.ctp +++ b/src/Template/Bake/Element/Controller/edit.ctp @@ -27,7 +27,7 @@ $compact = ["'" . $singularName . "'"]; */ public function edit($id = null) { $<%= $singularName %> = $this-><%= $currentModelName %>->get($id, [ - 'contain' => [<%= $this->Bake->stringifyList($belongsToMany, ['indent' => false]) %>] + 'contain' => [<%= $this->Bake->stringifyList($belongsToMany, ['indent' => false]) %>], ]); if ($this->request->is(['patch', 'post', 'put'])) { $<%= $singularName %> = $this-><%= $currentModelName %>->patchEntity($<%= $singularName %>, $this->request->data); diff --git a/src/Template/Bake/Element/Controller/index.ctp b/src/Template/Bake/Element/Controller/index.ctp index 49f818d..2cb02be 100644 --- a/src/Template/Bake/Element/Controller/index.ctp +++ b/src/Template/Bake/Element/Controller/index.ctp @@ -24,7 +24,7 @@ <% if ($belongsTo): $belongsTo = array_diff($belongsTo, $ignoreAssociations); %> $this->paginate = [ - 'contain' => [<%= $this->Bake->stringifyList($belongsTo, ['indent' => false]) %>] + 'contain' => [<%= $this->Bake->stringifyList($belongsTo, ['indent' => false]) %>], ]; <% endif; %> $this->set('<%= $pluralName %>', $this->paginate($this-><%= $currentModelName %>)); diff --git a/src/Template/Bake/Element/Controller/view.ctp b/src/Template/Bake/Element/Controller/view.ctp index e952c4b..16a1df7 100644 --- a/src/Template/Bake/Element/Controller/view.ctp +++ b/src/Template/Bake/Element/Controller/view.ctp @@ -30,7 +30,7 @@ $allAssociations = array_merge( */ public function view($id = null) { $<%= $singularName%> = $this-><%= $currentModelName %>->get($id, [ - 'contain' => [<%= $this->Bake->stringifyList($allAssociations, ['indent' => false]) %>] + 'contain' => [<%= $this->Bake->stringifyList($allAssociations, ['indent' => false]) %>], ]); $this->set('<%= $singularName %>', $<%= $singularName %>); $this->set('_serialize', ['<%= $singularName %>']); diff --git a/src/Template/Bake/Element/add-columns.ctp b/src/Template/Bake/Element/add-columns.ctp new file mode 100644 index 0000000..5a118da --- /dev/null +++ b/src/Template/Bake/Element/add-columns.ctp @@ -0,0 +1,12 @@ +<% foreach ($columns as $columnName => $columnAttributes): +$type = $columnAttributes['type']; +unset($columnAttributes['type']); + +$columnAttributes = $this->Migration->getColumnOption($columnAttributes); +$columnAttributes = $this->Migration->stringifyList($columnAttributes, ['indent' => 4]); +if (!empty($columnAttributes)): %> + ->addColumn('<%= $columnName %>', '<%= $type %>', [<%= $columnAttributes %>]) +<% else: %> + ->addColumn('<%= $columnName %>', '<%= $type %>') +<% endif; %> +<% endforeach; %> diff --git a/src/Template/Bake/Element/add-foreign-keys-from-create.ctp b/src/Template/Bake/Element/add-foreign-keys-from-create.ctp new file mode 100644 index 0000000..0ab3269 --- /dev/null +++ b/src/Template/Bake/Element/add-foreign-keys-from-create.ctp @@ -0,0 +1,3 @@ +<% foreach ($constraints as $table => $tableConstraints): + echo $this->element('LoadsysTheme.add-foreign-keys', ['constraints' => $tableConstraints, 'table' => $table]); +endforeach; %> diff --git a/src/Template/Bake/Element/add-foreign-keys.ctp b/src/Template/Bake/Element/add-foreign-keys.ctp new file mode 100644 index 0000000..096e986 --- /dev/null +++ b/src/Template/Bake/Element/add-foreign-keys.ctp @@ -0,0 +1,44 @@ +<% +$statement = $this->Migration->tableStatement($table, true); +$hasProcessedConstraint = false; +%> +<% foreach ($constraints as $constraint): + $constraintColumns = $constraint['columns']; + sort($constraintColumns); + if ($constraint['type'] !== 'unique'): + $hasProcessedConstraint = true; + $columnsList = '\'' . $constraint['columns'][0] . '\''; + if (count($constraint['columns']) > 1): + $columnsList = '[' . $this->Migration->stringifyList($constraint['columns'], ['indent' => 5]) . ']'; + endif; + $this->Migration->returnedData['dropForeignKeys'][$table][] = $columnsList; + + if (is_array($constraint['references'][1])): + $columnsReference = '[' . $this->Migration->stringifyList($constraint['references'][1], ['indent' => 5]) . ']'; + else: + $columnsReference = '\'' . $constraint['references'][1] . '\''; + endif; + + if (!isset($statement)): + $statement = $this->Migration->tableStatement($table); + endif; + + if (!empty($statement)): %> + + <%= $statement %> +<% unset($statement); + endif; %> + ->addForeignKey( + <%= $columnsList %>, + '<%= $constraint['references'][0] %>', + <%= $columnsReference %>, + [ + 'update' => '<%= strtoupper($constraint['update']) %>', + 'delete' => '<%= strtoupper($constraint['delete']) %>' + ] + ) +<% endif; %> +<% endforeach; %> +<% if (isset($this->Migration->tableStatements[$table]) && $hasProcessedConstraint): %> + ->update(); +<% endif; %> diff --git a/src/Template/Bake/Element/add-indexes.ctp b/src/Template/Bake/Element/add-indexes.ctp new file mode 100644 index 0000000..24657c4 --- /dev/null +++ b/src/Template/Bake/Element/add-indexes.ctp @@ -0,0 +1,9 @@ +<% foreach ($indexes as $indexName => $index): %> + ->addIndex([<% echo $this->Migration->stringifyList($index['columns'], ['indent' => false]); %>], [<% + $params = ['name' => $indexName]; + if ($index['type'] === 'unique'): + $params['unique'] = true; + endif; + echo $this->Migration->stringifyList($params, ['indent' => 4]); + %>]) +<% endforeach; %> diff --git a/src/Template/Bake/Element/breadcrumbs.ctp b/src/Template/Bake/Element/breadcrumbs.ctp index a5bd45b..7c49921 100644 --- a/src/Template/Bake/Element/breadcrumbs.ctp +++ b/src/Template/Bake/Element/breadcrumbs.ctp @@ -14,27 +14,27 @@ $display = "\$$singularVar->{$displayField}"; $keyedActions = ['view', 'edit']; switch ($action) { - case 'view': - $lastCrumb = "h({$display})"; - break; - default: - $humanAction = Inflector::humanize($action); - $lastCrumb = "__('{$humanAction} {$singularHumanName}')"; - break; + case 'view': + $lastCrumb = "h({$display})"; + break; + default: + $humanAction = Inflector::humanize($action); + $lastCrumb = "__('{$humanAction} {$singularHumanName}')"; + break; } %> set('breadcrumbs', [ - __('<%= $pluralHumanName %>') => [ - 'prefix' => $this->request->params['prefix'], - 'controller' => '<%= Inflector::camelize($pluralVar) %>', - 'action' => 'index', - ], + __('<%= $pluralHumanName %>') => [ + 'prefix' => $this->request->params['prefix'], + 'controller' => '<%= Inflector::camelize($pluralVar) %>', + 'action' => 'index', + ], <% if ($action != "index"): %> - <%= $lastCrumb %> => [ - 'prefix' => $this->request->params['prefix'], - 'controller' => '<%= Inflector::camelize($pluralVar) %>', - 'action' => '<%= $action %>', + <%= $lastCrumb %> => [ + 'prefix' => $this->request->params['prefix'], + 'controller' => '<%= Inflector::camelize($pluralVar) %>', + 'action' => '<%= $action %>', <%= (in_array($action, $keyedActions) ? "\t\t{$pk},\n" : '') %> ], <% endif; %> ]); diff --git a/src/Template/Bake/Element/create-tables.ctp b/src/Template/Bake/Element/create-tables.ctp new file mode 100644 index 0000000..acb7e1e --- /dev/null +++ b/src/Template/Bake/Element/create-tables.ctp @@ -0,0 +1,82 @@ +<% foreach ($tables as $table => $schema): + $tableArgForMethods = $useSchema === true ? $schema : $table; + $tableArgForArray = $useSchema === true ? $table : $schema; + +$foreignKeys = []; +$primaryKeysColumns = $this->Migration->primaryKeysColumnsList($tableArgForMethods); +$primaryKeys = $this->Migration->primaryKeys($tableArgForMethods); +$specialPk = (count($primaryKeys) > 1 || $primaryKeys[0]['name'] !== 'id' || $primaryKeys[0]['info']['columnType'] !== 'integer') && $autoId; +%> +<% if ($specialPk): %> + + $this->table('<%= $tableArgForArray %>', ['id' => false, 'primary_key' => ['<%= implode("', '", \Cake\Utility\Hash::extract($primaryKeys, '{n}.name')) %>'], ['comment' => '']]) +<% else: %> + + $this->table('<%= $tableArgForArray %>', ['comment' => '']) +<% endif; %> +<% if ($specialPk || !$autoId): + foreach ($primaryKeys as $primaryKey) : +%> + ->addColumn('<%= $primaryKey['name'] %>', '<%= $primaryKey['info']['columnType'] %>', [<% + $columnOptions = $this->Migration->getColumnOption($primaryKey['info']['options']); + echo $this->Migration->stringifyList($columnOptions, ['indent' => 4]); + %>]) +<% endforeach; %> +<% if (!$autoId): %> + ->addPrimaryKey(['<%= implode("', '", \Cake\Utility\Hash::extract($primaryKeys, '{n}.name')) %>']) +<% endif; %> +<% endif; +foreach ($this->Migration->columns($tableArgForMethods) as $column => $config): +%> + ->addColumn('<%= $column %>', '<%= $config['columnType'] %>', [<% + $columnOptions = $this->Migration->getColumnOption($config['options']); + $columnOptions['comment'] = ''; + //@TODO: init proper integrity checks matching MigrationsTest from skeleton. (Example: int id must be signed=false) + if ($config['columnType'] === 'boolean' && isset($columnOptions['default']) && $this->Migration->value($columnOptions['default']) !== 'null'): + $columnOptions['default'] = (bool)$columnOptions['default']; + endif; + echo $this->Migration->stringifyList($columnOptions, ['indent' => 4]); + %>]) +<% endforeach; +$tableConstraints = $this->Migration->constraints($tableArgForMethods); +if (!empty($tableConstraints)): + sort($tableConstraints); + $constraints[$tableArgForArray] = $tableConstraints; + + foreach ($constraints[$tableArgForArray] as $name => $constraint): + if ($constraint['type'] === 'foreign'): + $foreignKeys[] = $constraint['columns']; + endif; + if ($constraint['columns'] !== $primaryKeysColumns): %> + ->addIndex( + [<% echo $this->Migration->stringifyList($constraint['columns'], ['indent' => 5]); %>]<% echo ($constraint['type'] === 'unique') ? ',' : ''; %> + +<% if ($constraint['type'] === 'unique'): %> + ['unique' => true] +<% endif; %> + ) +<% endif; + endforeach; +endif; +foreach($this->Migration->indexes($tableArgForMethods) as $index): + sort($foreignKeys); + $indexColumns = $index['columns']; + sort($indexColumns); + if (!in_array($indexColumns, $foreignKeys)): + %> + ->addIndex( + [<% + echo $this->Migration->stringifyList($index['columns'], ['indent' => 5]); + %>]<% echo ($index['type'] === 'fulltext') ? ',' : ''; %> + + <%- if ($index['type'] === 'fulltext'): %> + ['type' => 'fulltext'] + <%- endif; %> + ) +<% endif; +endforeach; %> + ->create(); +<% endforeach; %> +<% if (!empty($constraints)): %> +<% echo $this->element('LoadsysTheme.add-foreign-keys-from-create', ['constraints' => $constraints]); %> +<% endif; %> diff --git a/src/Template/Bake/Form/form.ctp b/src/Template/Bake/Form/form.ctp index 4c4d61b..0374a8b 100644 --- a/src/Template/Bake/Form/form.ctp +++ b/src/Template/Bake/Form/form.ctp @@ -14,6 +14,9 @@ */ %> Form + */ namespace <%= $namespace %>\Form; use Cake\Form\Form; @@ -21,7 +24,7 @@ use Cake\Form\Schema; use Cake\Validation\Validator; /** - * <%= $name %> Form. + * \<%= $namespace %>\Form\<%= $name %> */ class <%= $name %>Form extends Form { /** diff --git a/src/Template/Bake/Model/behavior.ctp b/src/Template/Bake/Model/behavior.ctp index 543c38e..c6c7454 100644 --- a/src/Template/Bake/Model/behavior.ctp +++ b/src/Template/Bake/Model/behavior.ctp @@ -14,13 +14,16 @@ */ %> Behavior + */ namespace <%= $namespace %>\Model\Behavior; use Cake\ORM\Behavior; use Cake\ORM\Table; /** - * <%= $name %> behavior + * \<%= $namespace %>\Model\Behavior\<%= $name %> */ class <%= $name %>Behavior extends Behavior { diff --git a/src/Template/Bake/Model/entity.ctp b/src/Template/Bake/Model/entity.ctp index b3d8868..51d882b 100644 --- a/src/Template/Bake/Model/entity.ctp +++ b/src/Template/Bake/Model/entity.ctp @@ -14,12 +14,15 @@ */ %> Entity + */ namespace <%= $namespace %>\Model\Entity; use Cake\ORM\Entity; /** - * <%= $name %> Entity. + * \<%= $namespace %>\Model\Entity\<%= $name %> */ class <%= $name %> extends Entity { <% if (!empty($fields)): %> @@ -42,7 +45,7 @@ class <%= $name %> extends Entity { * * @var array */ - protected $_hidden = [<%= str_replace(' ', "\t", $this->Bake->stringifyList($hidden)) %>]; + protected $_hidden = [<%= $this->Bake->stringifyList($hidden) %>]; <% endif %> <% if (empty($fields) && empty($hidden)): %> diff --git a/src/Template/Bake/Model/table.ctp b/src/Template/Bake/Model/table.ctp index 1a3f165..a6cd9eb 100644 --- a/src/Template/Bake/Model/table.ctp +++ b/src/Template/Bake/Model/table.ctp @@ -36,6 +36,9 @@ $appTableValidations = [ ]; %> Model + */ namespace <%= $namespace %>\Model\Table; <% @@ -52,7 +55,7 @@ echo implode("\n", $uses); /** - * <%= $name %> Model + * \<%= $namespace %>\Model\Table\<%= $name %> <% if ($associations): %> * <% foreach ($associations as $type => $assocs): %> @@ -86,7 +89,6 @@ class <%= $name %>Table extends Table { $this->primaryKey('<%= current((array)$primaryKey) %>'); <% endif %> <% endif %> - <% foreach ($behaviors as $behavior => $behaviorData): if (in_array($behavior, $appTableBehaviors)) { continue; } %> $this->addBehavior('<%= $behavior %>'<%= $behaviorData ? ", [" . implode(', ', $behaviorData) . ']' : '' %>); @@ -97,7 +99,7 @@ class <%= $name %>Table extends Table { $alias = $assoc['alias']; unset($assoc['alias']); %> - $this-><%= $type %>('<%= $alias %>', [<%= str_replace(' ', "\t", $this->Bake->stringifyList($assoc, ['indent' => 3])) %>]); + $this-><%= $type %>('<%= $alias %>', [<%= $this->Bake->stringifyList($assoc, ['indent' => 3]) %>]); <% endforeach %> <% endforeach %> } diff --git a/src/Template/Bake/Plugin/config/routes.php.ctp b/src/Template/Bake/Plugin/config/routes.php.ctp index ac91d1f..09f48fb 100644 --- a/src/Template/Bake/Plugin/config/routes.php.ctp +++ b/src/Template/Bake/Plugin/config/routes.php.ctp @@ -17,5 +17,5 @@ use Cake\Routing\Router; Router::plugin('<%= $plugin %>', function ($routes) { - $routes->fallbacks('InflectedRoute'); + $routes->fallbacks('DashedRoute'); }); diff --git a/src/Template/Bake/Seed/seed.ctp b/src/Template/Bake/Seed/seed.ctp new file mode 100644 index 0000000..d851a5c --- /dev/null +++ b/src/Template/Bake/Seed/seed.ctp @@ -0,0 +1,46 @@ +<% +/** + * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt + * Redistributions of files must retain the above copyright notice. + * + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://cakephp.org CakePHP(tm) Project + * @since 0.1.0 + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ +%> + seed. + */ +use Phinx\Seed\AbstractSeed; + +/** + * \<%= $name %> + */ +class <%= $name %>Seed extends AbstractSeed { + /** + * Run Method. + * + * Write your database seeder using this method. + * + * More information on writing seeders is available here: + * http://docs.phinx.org/en/latest/seeding.html + * + * @return void + */ + public function run() { +<% if ($records): %> + $data = <%= $records %>; +<% else: %> + $data = []; +<% endif; %> + + $table = $this->table('<%= $table %>'); + $table->insert($data)->save(); + } +} diff --git a/src/Template/Bake/Shell/shell.ctp b/src/Template/Bake/Shell/shell.ctp index e607a05..1579614 100644 --- a/src/Template/Bake/Shell/shell.ctp +++ b/src/Template/Bake/Shell/shell.ctp @@ -14,12 +14,15 @@ */ %> Shell + */ namespace <%= $namespace %>\Shell; use Cake\Console\Shell; /** - * <%= $name %> shell command. + * \<%= $namespace %>\Shell\<%= $name %> */ class <%= $name %>Shell extends Shell { diff --git a/src/Template/Bake/View/cell.ctp b/src/Template/Bake/View/cell.ctp index 71c2271..7c479c6 100644 --- a/src/Template/Bake/View/cell.ctp +++ b/src/Template/Bake/View/cell.ctp @@ -14,12 +14,15 @@ */ %> Cell + */ namespace <%= $namespace %>\View\Cell; use Cake\View\Cell; /** - * <%= $name %> cell + * \<%= $namespace %>\View\Cell\<%= $name %> */ class <%= $name %>Cell extends Cell { diff --git a/src/Template/Bake/View/helper.ctp b/src/Template/Bake/View/helper.ctp index 54ff965..f8149cc 100644 --- a/src/Template/Bake/View/helper.ctp +++ b/src/Template/Bake/View/helper.ctp @@ -14,13 +14,16 @@ */ %> Helper + */ namespace <%= $namespace %>\View\Helper; use Cake\View\Helper; use Cake\View\View; /** - * <%= $name %> helper + * \<%= $namespace %>\View\Helper\<%= $name %> */ class <%= $name %>Helper extends Helper { diff --git a/src/Template/Bake/config/diff.ctp b/src/Template/Bake/config/diff.ctp new file mode 100644 index 0000000..3904b91 --- /dev/null +++ b/src/Template/Bake/config/diff.ctp @@ -0,0 +1,238 @@ +<% +/** +* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) +* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) +* +* Licensed under The MIT License +* For full copyright and license information, please see the LICENSE.txt +* Redistributions of files must retain the above copyright notice. +* +* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) +* @link http://cakephp.org CakePHP(tm) Project +* @since 3.0.0 +* @license http://www.opensource.org/licenses/mit-license.php MIT License +*/ + +$tables = $data['fullTables']; +unset($data['fullTables']); +$constraints = []; + +$hasUnsignedPk = $this->Migration->hasUnsignedPrimaryKey($tables['add']); + +$autoId = true; +if ($hasUnsignedPk) { + $autoId = false; +} +%> + Migration + */ +use Migrations\AbstractMigration; + +/** + * \<%= $name %> + */ +class <%= $name %> extends AbstractMigration { + <%- if (!$autoId): %> + + /** + * Auto ID. + * + * @var bool + */ + public $autoId = false; + <%- endif; %> + + /** + * Up Method. + * + * More information on this method is available here: + * http://docs.phinx.org/en/latest/migrations.html#the-up-method + * + * @return void + */ + public function up() { + <%- foreach ($data as $tableName => $tableDiff): + $hasRemoveFK = !empty($tableDiff['constraints']['remove']) || !empty($tableDiff['indexes']['remove']); + %> + <%- if ($hasRemoveFK): %> + $this->table('<%= $tableName %>') + <%- endif; %> + <%- if (!empty($tableDiff['constraints']['remove'])): %> + <%- foreach ($tableDiff['constraints']['remove'] as $constraintName => $constraintDefinition): %> + ->dropForeignKey([], '<%= $constraintName %>') + <%- endforeach; %> + <%- endif; %> + <%- if (!empty($tableDiff['indexes']['remove'])): %> + <%- foreach ($tableDiff['indexes']['remove'] as $indexName => $indexDefinition): %> + ->removeIndexByName('<%= $indexName %>') + <%- endforeach; %> + <%- endif; %> + <%- if ($hasRemoveFK): %> + ->update(); + + <%- endif; %> + <%- if (!empty($tableDiff['columns']['remove'])): + $statement = $this->Migration->tableStatement($tableName); + if (!empty($statement)): %> + <%= $statement %> + <%- endif; %> + <%- foreach ($tableDiff['columns']['remove'] as $columnName => $columnDefinition): %> + ->removeColumn('<%= $columnName %>') + <%- endforeach; %> + <%- endif; %> + <%- if (!empty($tableDiff['columns']['changed'])): + $statement = $this->Migration->tableStatement($tableName); + if (!empty($statement)): %> + <%= $statement %> + <%- endif; %> + <%- foreach ($tableDiff['columns']['changed'] as $columnName => $columnAttributes): + $type = $columnAttributes['type']; + unset($columnAttributes['type']); + $columnAttributes = $this->Migration->getColumnOption($columnAttributes); + $columnAttributes = $this->Migration->stringifyList($columnAttributes, ['indent' => 4]); + if (!empty($columnAttributes)): %> + ->changeColumn('<%= $columnName %>', '<%= $type %>', [<%= $columnAttributes %>]) + <%- else: %> + ->changeColumn('<%= $columnName %>', '<%= $type %>') + <%- endif; %> + <%- endforeach; + if (isset($this->Migration->tableStatements[$tableName])): %> + ->update(); + <%- endif; %> + <%- endif; %> + <%- endforeach; %> + <%- if (!empty($tables['add'])): %> + <%- echo $this->element('LoadsysTheme.create-tables', ['tables' => $tables['add'], 'autoId' => $autoId, 'useSchema' => true]) %> + <%- endif; %> + <%- foreach ($data as $tableName => $tableDiff): %> + <%- if (!empty($tableDiff['columns']['add'])): + $statement = $this->Migration->tableStatement($tableName, true); + if (!empty($statement)): %> + + <%= $statement %> + <%- endif; %> + <%- echo $this->element('LoadsysTheme.add-columns', ['columns' => $tableDiff['columns']['add']]) %> + <%- endif; %> + <%- if (!empty($tableDiff['indexes']['add'])): + $statement = $this->Migration->tableStatement($tableName); + if (!empty($statement)): %> + <%= $statement %> + <%- endif; %> + <%- echo $this->element('LoadsysTheme.add-indexes', ['indexes' => $tableDiff['indexes']['add']]) %> + <%- endif; + if (isset($this->Migration->tableStatements[$tableName])): %> + ->update(); + <%- endif; %> + <%- endforeach; %> + <%- foreach ($data as $tableName => $tableDiff): %> + <%- if (!empty($tableDiff['constraints']['add'])): %> + <%- echo $this->element( + 'Migrations.add-foreign-keys', + ['constraints' => $tableDiff['constraints']['add'], 'table' => $tableName] + ); %> + <%- endif; %> + <%- endforeach; %> + + <%- if (!empty($tables['remove'])): %> + <%- foreach ($tables['remove'] as $tableName => $table): %> + $this->dropTable('<%= $tableName %>'); + <%- endforeach; %> + <%- endif; %> + } + + /** + * Down Method. + * + * More information on this method is available here: + * http://docs.phinx.org/en/latest/migrations.html#the-down-method + * + * @return void + */ + public function down() { + <%- $constraints = []; + $emptyLine = false; + if (!empty($this->Migration->returnedData['dropForeignKeys'])): + foreach ($this->Migration->returnedData['dropForeignKeys'] as $table => $columnsList): + $maxKey = count($columnsList) - 1; + if ($emptyLine === true): %> + + <%- else: + $emptyLine = true; + endif; %> + $this->table('<%= $table %>') + <%- foreach ($columnsList as $key => $columns): %> + ->dropForeignKey( + <%= $columns %> + )<%= ($key === $maxKey) ? ';' : '' %> + <%- endforeach; %> + <%- endforeach; %> + <%- endif; %> + <%- if (!empty($tables['remove'])): %> + <%- echo $this->element('LoadsysTheme.create-tables', ['tables' => $tables['remove'], 'autoId' => $autoId, 'useSchema' => true]) %> + <%- endif; %> + <%- foreach ($data as $tableName => $tableDiff): %> + <%- if (!empty($tableDiff['indexes']['add'])): %> + + $this->table('<%= $tableName %>') + <%- foreach ($tableDiff['indexes']['add'] as $indexName => $index): %> + ->removeIndexByName('<%= $indexName %>') + <%- endforeach %> + ->update(); + <%- endif; %> + <%- if (!empty($tableDiff['columns']['remove']) || + !empty($tableDiff['columns']['changed']) || + !empty($tableDiff['columns']['add']) || + !empty($tableDiff['indexes']['remove']) + ): %> + + <%= $this->Migration->tableStatement($tableName, true) %> + <%- endif; %> + <%- if (!empty($tableDiff['columns']['remove'])): %> + <%- echo $this->element('LoadsysTheme.add-columns', ['columns' => $tableDiff['columns']['remove']]) %> + <%- endif; %> + <%- if (!empty($tableDiff['columns']['changed'])): + $oldTableDef = $dumpSchema[$tableName]; + foreach ($tableDiff['columns']['changed'] as $columnName => $columnAttributes): + $columnAttributes = $oldTableDef->column($columnName); + $type = $columnAttributes['type']; + unset($columnAttributes['type']); + $columnAttributes = $this->Migration->getColumnOption($columnAttributes); + $columnAttributes = $this->Migration->stringifyList($columnAttributes, ['indent' => 4]); + if (!empty($columnAttributes)): %> + ->changeColumn('<%= $columnName %>', '<%= $type %>', [<%= $columnAttributes %>]) + <%- else: %> + ->changeColumn('<%= $columnName %>', '<%= $type %>') + <%- endif; %> + <%- endforeach; %> + <%- endif; %> + <%- if (!empty($tableDiff['columns']['add'])): %> + <%- foreach ($tableDiff['columns']['add'] as $columnName => $columnAttributes): %> + ->removeColumn('<%= $columnName %>') + <%- endforeach; %> + <%- endif; %> + <%- if (!empty($tableDiff['indexes']['remove'])): %> + <%- echo $this->element('LoadsysTheme.add-indexes', ['indexes' => $tableDiff['indexes']['remove']]) %> + <%- endif; + if (isset($this->Migration->tableStatements[$tableName])): %> + ->update(); + <%- endif; %> + <%- endforeach; %> + <%- foreach ($data as $tableName => $tableDiff): %> + <%- if (!empty($tableDiff['constraints']['remove'])): %> + <%- echo $this->element( + 'Migrations.add-foreign-keys', + ['constraints' => $tableDiff['constraints']['remove'], 'table' => $tableName] + ); %> + <%- endif; %> + <%- endforeach; %> + <%- if (!empty($tables['add'])): %> + <%- foreach ($tables['add'] as $tableName => $table): %> + + $this->dropTable('<%= $tableName %>'); + <%- endforeach; %> + <%- endif; %> + } +} + diff --git a/src/Template/Bake/config/skeleton.ctp b/src/Template/Bake/config/skeleton.ctp new file mode 100644 index 0000000..fa0b72a --- /dev/null +++ b/src/Template/Bake/config/skeleton.ctp @@ -0,0 +1,85 @@ +<% +/** + * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt + * Redistributions of files must retain the above copyright notice. + * + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://cakephp.org CakePHP(tm) Project + * @since 3.0.0 + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +$wantedOptions = array_flip(['length', 'limit', 'default', 'unsigned', 'null', 'comment', 'autoIncrement']); +$tableMethod = $this->Migration->tableMethod($action); +$columnMethod = $this->Migration->columnMethod($action); +$indexMethod = $this->Migration->indexMethod($action); +%> + Migration + */ +use Migrations\AbstractMigration; + +/** + * \<%= $name %> + */ +class <%= $name %> extends AbstractMigration { + <%- if ($tableMethod === 'create' && !empty($columns['primaryKey'])): %> + + /** + * Auto ID. + * + * @var bool + */ + public $autoId = false; + + <%- endif; %> + /** + * Change Method. + * + * More information on this method is available here: + * http://docs.phinx.org/en/latest/migrations.html#the-change-method + * @return void + */ + public function change() { +<% foreach ($tables as $table): %> + $table = $this->table('<%= $table%>', ['comment' => '']); +<% if ($tableMethod !== 'drop') : %> +<% if ($columnMethod === 'removeColumn'): %> +<% foreach ($columns['fields'] as $column => $config): %> + <%= "\$table->$columnMethod('" . $column . "');"; %> +<% endforeach; %> +<% foreach ($columns['indexes'] as $column => $config): %> + <%= "\$table->$indexMethod([" . $this->Bake->stringifyList($config['columns']) . ");"; %> +<% endforeach; %> +<% else : %> +<% foreach ($columns['fields'] as $column => $config): %> + $table-><%= $columnMethod %>('<%= $column %>', '<%= $config['columnType'] %>', [<% + $columnOptions = $config['options']; + $columnOptions = array_intersect_key($columnOptions, $wantedOptions); + $columnOptions['comment'] = ''; + echo $this->Bake->stringifyList($columnOptions, ['indent' => 3]); + %>]); +<% endforeach; %> +<% foreach ($columns['indexes'] as $column => $config): %> + $table-><%= $indexMethod %>([<%= + $this->Bake->stringifyList($config['columns'], ['indent' => 3]) + %>], [<% + echo $this->Bake->stringifyList($config['options'], ['indent' => 3]); + %>]); +<% endforeach; %> +<% if ($tableMethod === 'create' && !empty($columns['primaryKey'])): %> + $table->addPrimaryKey([<%= + $this->Bake->stringifyList($columns['primaryKey'], ['indent' => 3]) + %>]); +<% endif; %> +<% endif; %> +<% endif; %> + $table-><%= $tableMethod %>(); +<% endforeach; %> + } +} diff --git a/src/Template/Bake/config/snapshot.ctp b/src/Template/Bake/config/snapshot.ctp new file mode 100644 index 0000000..9b1966c --- /dev/null +++ b/src/Template/Bake/config/snapshot.ctp @@ -0,0 +1,82 @@ +<% +/** + * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt + * Redistributions of files must retain the above copyright notice. + * + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://cakephp.org CakePHP(tm) Project + * @since 3.0.0 + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +use Cake\Database\Schema\Table; + +$constraints = $foreignKeys = $dropForeignKeys = []; +$hasUnsignedPk = $this->Migration->hasUnsignedPrimaryKey($tables); + +if ($autoId && $hasUnsignedPk) { + $autoId = false; +} +%> + Migration + */ + +use Migrations\AbstractMigration; + +/** + * \<%= $name %> + */ +class <%= $name %> extends AbstractMigration { + <%- if (!$autoId): %> + + /** + * Auto ID. + * + * @var bool + */ + public $autoId = false; + + <%- endif; %> + /** + * Up Method. + * + * More information on this method is available here: + * http://docs.phinx.org/en/latest/migrations.html#the-up-method + * + * @return void + */ + public function up() { + <%- echo $this->element('LoadsysTheme.create-tables', ['tables' => $tables, 'autoId' => $autoId, 'useSchema' => false]) %> + } + + /** + * Down Method. + * + * More information on this method is available here: + * http://docs.phinx.org/en/latest/migrations.html#the-down-method + * + * @return void + */ + public function down() { + <%- foreach ($this->Migration->returnedData['dropForeignKeys'] as $table => $columnsList): + $maxKey = count($columnsList) - 1; + %> + $this->table('<%= $table %>') + <%- foreach ($columnsList as $key => $columns): %> + ->dropForeignKey( + <%= $columns %> + )<%= ($key === $maxKey) ? ';' : '' %> + <%- endforeach; %> + + <%- endforeach; %> + <%- foreach ($tables as $table): %> + $this->dropTable('<%= $table%>'); + <%- endforeach; %> + } +} diff --git a/src/Template/Bake/tests/fixture.ctp b/src/Template/Bake/tests/fixture.ctp index 0cd0073..ed33a50 100644 --- a/src/Template/Bake/tests/fixture.ctp +++ b/src/Template/Bake/tests/fixture.ctp @@ -18,13 +18,15 @@ */ %> Fixture + */ namespace <%= $namespace %>\Test\Fixture; use Cake\TestSuite\Fixture\TestFixture; /** - * <%= $name %>Fixture - * + * \<%= $namespace %>\Test\Fixture\<%= $name %>Fixture */ class <%= $name %>Fixture extends TestFixture { <% if ($table): %> diff --git a/src/Template/Bake/tests/test_case.ctp b/src/Template/Bake/tests/test_case.ctp index c86b3f3..61323a6 100644 --- a/src/Template/Bake/tests/test_case.ctp +++ b/src/Template/Bake/tests/test_case.ctp @@ -26,6 +26,9 @@ if ($isController) { sort($uses); %> class. + */ namespace <%= $baseNamespace; %>\Test\TestCase\<%= $subNamespace %>; <% foreach ($uses as $dependency): %> @@ -33,7 +36,7 @@ use <%= $dependency; %>; <% endforeach; %> /** - * <%= $fullClassName %> Test Case + * <%= $baseNamespace; %>\Test\TestCase\<%= $subNamespace %>\<%= $className %> */ <% if ($isController): %> class <%= $className %>Test extends IntegrationTestCase { @@ -47,7 +50,7 @@ class <%= $className %>Test extends TestCase { * * @var array */ - public $fixtures = [<%= str_replace(' ', "\t", $this->Bake->stringifyList(array_values($fixtures))) %>]; + public $fixtures = [<%= $this->Bake->stringifyList(array_values($fixtures)) %>]; <% endif; %> <% if (!empty($construction)): %> diff --git a/src/View/Helper/BakeHelper.php b/src/View/Helper/BakeHelper.php new file mode 100644 index 0000000..d7cc74c --- /dev/null +++ b/src/View/Helper/BakeHelper.php @@ -0,0 +1,38 @@ + 2, + 'tab' => "\t", + ]; + + // MUST be layered in a second pass to pick up the layered [indent] + // value from the first pass! + $options += [ + 'trailingComma' => ($options['indent'] !== false), + ]; + + return parent::stringifyList($list, $options); + } +} diff --git a/tests/TestCase/View/Helper/BakeHelperTest.php b/tests/TestCase/View/Helper/BakeHelperTest.php new file mode 100644 index 0000000..779d2e5 --- /dev/null +++ b/tests/TestCase/View/Helper/BakeHelperTest.php @@ -0,0 +1,67 @@ +View = new BakeView($request, $response); + $this->BakeHelper = new BakeHelper($this->View); + } + + /** + * tearDown method + * + * @return void + */ + public function tearDown() { + unset($this->View); + unset($this->BakeHelper); + + parent::tearDown(); + } + + /** + * test stringifyList defaults + * + * @return void + */ + public function testStringifyListDefaults() { + $list = ['one' => 'foo', 'two' => 'bar', 'three']; + $result = $this->BakeHelper->stringifyList($list); + $spaces = "\t"; + $expected = "\n" . + $spaces . $spaces . "'one' => 'foo',\n" . + $spaces . $spaces . "'two' => 'bar',\n" . + $spaces . $spaces . "'three',\n" . + $spaces; + $this->assertSame($expected, $result); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..f2bd6b4 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,16 @@ + dirname(dirname(__FILE__)) . DS, +]);