├── plugins
└── empty
├── webroot
├── js
│ └── empty
├── favicon.ico
├── img
│ ├── cake.icon.png
│ └── cake.power.gif
├── .htaccess
├── index.php
└── css
│ └── cake.css
├── src
├── View
│ ├── Helper
│ │ └── empty
│ ├── AppView.php
│ └── AjaxView.php
├── Model
│ ├── Behavior
│ │ └── empty
│ ├── Entity
│ │ ├── Post.php
│ │ ├── Widget.php
│ │ ├── Group.php
│ │ └── User.php
│ └── Table
│ │ ├── WidgetsTable.php
│ │ ├── GroupsTable.php
│ │ ├── PostsTable.php
│ │ └── UsersTable.php
├── Controller
│ ├── Component
│ │ └── empty
│ ├── PagesController.php
│ ├── AppController.php
│ ├── WidgetsController.php
│ ├── GroupsController.php
│ ├── PostsController.php
│ └── UsersController.php
├── Template
│ ├── Element
│ │ └── Flash
│ │ │ ├── error.ctp
│ │ │ ├── success.ctp
│ │ │ └── default.ctp
│ ├── Users
│ │ ├── login.ctp
│ │ ├── add.ctp
│ │ ├── edit.ctp
│ │ ├── index.ctp
│ │ └── view.ctp
│ ├── Layout
│ │ ├── rss
│ │ │ └── default.ctp
│ │ ├── ajax.ctp
│ │ ├── Email
│ │ │ ├── text
│ │ │ │ └── default.ctp
│ │ │ └── html
│ │ │ │ └── default.ctp
│ │ ├── error.ctp
│ │ └── default.ctp
│ ├── Email
│ │ ├── text
│ │ │ └── default.ctp
│ │ └── html
│ │ │ └── default.ctp
│ ├── Widgets
│ │ ├── add.ctp
│ │ ├── edit.ctp
│ │ ├── view.ctp
│ │ └── index.ctp
│ ├── Groups
│ │ ├── add.ctp
│ │ ├── edit.ctp
│ │ ├── index.ctp
│ │ └── view.ctp
│ ├── Posts
│ │ ├── add.ctp
│ │ ├── edit.ctp
│ │ ├── view.ctp
│ │ └── index.ctp
│ ├── Error
│ │ ├── error500.ctp
│ │ └── error400.ctp
│ └── Pages
│ │ └── home.ctp
├── Shell
│ └── ConsoleShell.php
└── Console
│ └── Installer.php
├── tests
├── TestCase
│ ├── View
│ │ └── Helper
│ │ │ └── empty
│ ├── Model
│ │ ├── Behavior
│ │ │ └── empty
│ │ └── Table
│ │ │ ├── WidgetsTableTest.php
│ │ │ ├── GroupsTableTest.php
│ │ │ ├── PostsTableTest.php
│ │ │ └── UsersTableTest.php
│ └── Controller
│ │ ├── Component
│ │ └── empty
│ │ ├── WidgetsControllerTest.php
│ │ ├── GroupsControllerTest.php
│ │ ├── PostsControllerTest.php
│ │ └── UsersControllerTest.php
├── bootstrap.php
└── Fixture
│ ├── GroupsFixture.php
│ ├── WidgetsFixture.php
│ ├── UsersFixture.php
│ └── PostsFixture.php
├── .gitignore
├── .htaccess
├── .travis.yml
├── .editorconfig
├── config
├── schema
│ ├── sessions.sql
│ └── i18n.sql
├── bootstrap_cli.php
├── paths.php
├── routes.php
├── bootstrap.php
└── app.default.php
├── index.php
├── .gitattributes
├── phpunit.xml.dist
├── bin
├── cake.bat
├── cake.php
└── cake
├── composer.json
├── README.md
└── composer.lock
/plugins/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/webroot/js/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/View/Helper/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Model/Behavior/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Controller/Component/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/TestCase/View/Helper/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/TestCase/Model/Behavior/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/TestCase/Controller/Component/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/*
2 | /config/app.php
3 | /tmp/*
4 | /logs/*
5 |
--------------------------------------------------------------------------------
/src/Template/Element/Flash/error.ctp:
--------------------------------------------------------------------------------
1 |
= h($message) ?>
2 |
--------------------------------------------------------------------------------
/src/Template/Element/Flash/success.ctp:
--------------------------------------------------------------------------------
1 | = h($message) ?>
2 |
--------------------------------------------------------------------------------
/webroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattmemmesheimer/cakephp-3-acl-example/HEAD/webroot/favicon.ico
--------------------------------------------------------------------------------
/webroot/img/cake.icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattmemmesheimer/cakephp-3-acl-example/HEAD/webroot/img/cake.icon.png
--------------------------------------------------------------------------------
/webroot/img/cake.power.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mattmemmesheimer/cakephp-3-acl-example/HEAD/webroot/img/cake.power.gif
--------------------------------------------------------------------------------
/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | RewriteEngine on
3 | RewriteRule ^$ webroot/ [L]
4 | RewriteRule (.*) webroot/$1 [L]
5 |
--------------------------------------------------------------------------------
/webroot/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | RewriteEngine On
3 | RewriteCond %{REQUEST_FILENAME} !-f
4 | RewriteRule ^ index.php [L]
5 |
6 |
--------------------------------------------------------------------------------
/src/Template/Element/Flash/default.ctp:
--------------------------------------------------------------------------------
1 |
7 | = h($message) ?>
8 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | Form->create() ?>
2 |
3 | = __('Login') ?>
4 | = $this->Form->input('username') ?>
5 | = $this->Form->input('password') ?>
6 | = $this->Form->submit(__('Login')) ?>
7 |
8 | = $this->Form->end() ?>
--------------------------------------------------------------------------------
/src/Template/Layout/rss/default.ctp:
--------------------------------------------------------------------------------
1 | fetch('title');
7 | endif;
8 |
9 | echo $this->Rss->document(
10 | $this->Rss->channel(
11 | array(), $channel, $this->fetch('content')
12 | )
13 | );
14 | ?>
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | sudo: false
4 |
5 | php:
6 | - 7.0
7 |
8 | before_script:
9 | - sh -c "composer require 'cakephp/cakephp-codesniffer:dev-master'"
10 | - phpenv rehash
11 |
12 | script:
13 | - sh -c "vendor/bin/phpcs -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests ./config ./webroot"
14 |
15 | notifications:
16 | email: false
17 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This file is for unifying the coding style for different editors and IDEs.
2 | ; More information at http://editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 4
9 | end_of_line = lf
10 | insert_final_newline = true
11 | trim_trailing_whitespace = true
12 |
13 | [*.bat]
14 | end_of_line = crlf
15 |
16 | [*.yml]
17 | indent_style = space
18 | indent_size = 2
19 |
--------------------------------------------------------------------------------
/src/Model/Entity/Post.php:
--------------------------------------------------------------------------------
1 | true,
19 | 'id' => false,
20 | ];
21 | }
22 |
--------------------------------------------------------------------------------
/src/Model/Entity/Widget.php:
--------------------------------------------------------------------------------
1 | true,
19 | 'id' => false,
20 | ];
21 | }
22 |
--------------------------------------------------------------------------------
/src/Model/Entity/Group.php:
--------------------------------------------------------------------------------
1 | true,
19 | 'id' => false,
20 | ];
21 |
22 | public function parentNode()
23 | {
24 | return null;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/config/schema/sessions.sql:
--------------------------------------------------------------------------------
1 | # $Id$
2 | #
3 | # Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
4 | # 1785 E. Sahara Avenue, Suite 490-204
5 | # Las Vegas, Nevada 89104
6 | #
7 | # Licensed under The MIT License
8 | # For full copyright and license information, please see the LICENSE.txt
9 | # Redistributions of files must retain the above copyright notice.
10 | # MIT License (http://www.opensource.org/licenses/mit-license.php)
11 |
12 | CREATE TABLE sessions (
13 | id varchar(40) NOT NULL default '',
14 | data text,
15 | expires INT(11) NOT NULL,
16 | PRIMARY KEY (id)
17 | );
18 |
--------------------------------------------------------------------------------
/src/Template/Email/text/default.ctp:
--------------------------------------------------------------------------------
1 |
16 | = $content ?>
17 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 |
16 | = $this->fetch('content') ?>
17 |
--------------------------------------------------------------------------------
/src/Template/Layout/Email/text/default.ctp:
--------------------------------------------------------------------------------
1 |
16 | = $this->fetch('content') ?>
17 |
--------------------------------------------------------------------------------
/src/Template/Widgets/add.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('List Widgets'), ['action' => 'index']) ?>
5 |
6 |
7 |
8 | = $this->Form->create($widget) ?>
9 |
10 | = __('Add Widget') ?>
11 | Form->input('name');
13 | echo $this->Form->input('part_no');
14 | echo $this->Form->input('quantity');
15 | ?>
16 |
17 | = $this->Form->button(__('Submit')) ?>
18 | = $this->Form->end() ?>
19 |
20 |
--------------------------------------------------------------------------------
/src/Template/Email/html/default.ctp:
--------------------------------------------------------------------------------
1 |
16 | ' . $line . "\n";
21 | endforeach;
22 | ?>
23 |
--------------------------------------------------------------------------------
/src/Template/Groups/add.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('List Groups'), ['action' => 'index']) ?>
5 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
6 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
7 |
8 |
9 |
10 | = $this->Form->create($group) ?>
11 |
12 | = __('Add Group') ?>
13 | Form->input('name');
15 | ?>
16 |
17 | = $this->Form->button(__('Submit')) ?>
18 | = $this->Form->end() ?>
19 |
20 |
--------------------------------------------------------------------------------
/src/Template/Layout/Email/html/default.ctp:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 | = $this->fetch('title') ?>
20 |
21 |
22 | = $this->fetch('content') ?>
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/Model/Entity/User.php:
--------------------------------------------------------------------------------
1 | true,
19 | 'id' => false,
20 | ];
21 |
22 | public function parentNode()
23 | {
24 | if (!$this->id) {
25 | return null;
26 | }
27 | if (isset($this->group_id)) {
28 | $groupId = $this->group_id;
29 | } else {
30 | $Users = TableRegistry::get('Users');
31 | $user = $Users->find('all', ['fields' => ['group_id']])->where(['id' => $this->id])->first();
32 | $groupId = $user->group_id;
33 | }
34 | if (!$groupId) {
35 | return null;
36 | }
37 | return ['Groups' => ['id' => $groupId]];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Define the line ending behavior of the different file extensions
2 | # Set default behaviour, in case users don't have core.autocrlf set.
3 | * text=auto
4 | * text eol=lf
5 |
6 | # Explicitly declare text files we want to always be normalized and converted
7 | # to native line endings on checkout.
8 | *.php text
9 | *.default text
10 | *.ctp text
11 | *.sql text
12 | *.md text
13 | *.po text
14 | *.js text
15 | *.css text
16 | *.ini text
17 | *.properties text
18 | *.txt text
19 | *.xml text
20 | *.yml text
21 | .htaccess text
22 |
23 | # Declare files that will always have CRLF line endings on checkout.
24 | *.bat eol=crlf
25 |
26 | # Declare files that will always have LF line endings on checkout.
27 | *.pem eol=lf
28 |
29 | # Denote all files that are truly binary and should not be modified.
30 | *.png binary
31 | *.jpg binary
32 | *.gif binary
33 | *.ico binary
34 | *.mo binary
35 | *.pdf binary
36 | *.phar binary
37 |
--------------------------------------------------------------------------------
/src/Template/Posts/add.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('List Posts'), ['action' => 'index']) ?>
5 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
6 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
7 |
8 |
9 |
10 | = $this->Form->create($post) ?>
11 |
12 | = __('Add Post') ?>
13 | Form->input('user_id', ['options' => $users]);
15 | echo $this->Form->input('title');
16 | echo $this->Form->input('body');
17 | ?>
18 |
19 | = $this->Form->button(__('Submit')) ?>
20 | = $this->Form->end() ?>
21 |
22 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ./tests/TestCase
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/Template/Widgets/edit.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Form->postLink(
5 | __('Delete'),
6 | ['action' => 'delete', $widget->id],
7 | ['confirm' => __('Are you sure you want to delete # {0}?', $widget->id)]
8 | )
9 | ?>
10 | = $this->Html->link(__('List Widgets'), ['action' => 'index']) ?>
11 |
12 |
13 |
14 | = $this->Form->create($widget) ?>
15 |
16 | = __('Edit Widget') ?>
17 | Form->input('name');
19 | echo $this->Form->input('part_no');
20 | echo $this->Form->input('quantity');
21 | ?>
22 |
23 | = $this->Form->button(__('Submit')) ?>
24 | = $this->Form->end() ?>
25 |
26 |
--------------------------------------------------------------------------------
/src/View/AppView.php:
--------------------------------------------------------------------------------
1 | loadHelper('Html');`
29 | *
30 | * @return void
31 | */
32 | public function initialize()
33 | {
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/config/schema/i18n.sql:
--------------------------------------------------------------------------------
1 | # $Id$
2 | #
3 | # Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
4 | #
5 | # Licensed under The MIT License
6 | # For full copyright and license information, please see the LICENSE.txt
7 | # Redistributions of files must retain the above copyright notice.
8 | # MIT License (http://www.opensource.org/licenses/mit-license.php)
9 |
10 | CREATE TABLE i18n (
11 | id int(10) NOT NULL auto_increment,
12 | locale varchar(6) NOT NULL,
13 | model varchar(255) NOT NULL,
14 | foreign_key int(10) NOT NULL,
15 | field varchar(255) NOT NULL,
16 | content mediumtext,
17 | PRIMARY KEY (id),
18 | # UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
19 | # INDEX I18N_LOCALE_ROW(locale, model, foreign_key),
20 | # INDEX I18N_LOCALE_MODEL(locale, model),
21 | # INDEX I18N_FIELD(model, foreign_key, field),
22 | # INDEX I18N_ROW(model, foreign_key),
23 | INDEX locale (locale),
24 | INDEX model (model),
25 | INDEX row_id (foreign_key),
26 | INDEX field (field)
27 | );
--------------------------------------------------------------------------------
/src/Template/Error/error500.ctp:
--------------------------------------------------------------------------------
1 | layout = 'dev_error';
7 |
8 | $this->assign('title', $message);
9 | $this->assign('templateName', 'error500.ctp');
10 |
11 | $this->start('file');
12 | ?>
13 | queryString)) : ?>
14 |
15 | SQL Query:
16 | = h($error->queryString) ?>
17 |
18 |
19 | params)) : ?>
20 | SQL Query Params:
21 | = Debugger::dump($error->params) ?>
22 |
23 | element('auto_table_warning');
25 |
26 | if (extension_loaded('xdebug')):
27 | xdebug_print_function_stack();
28 | endif;
29 |
30 | $this->end();
31 | endif;
32 | ?>
33 | = __d('cake', 'An Internal Error Has Occurred') ?>
34 |
35 | = __d('cake', 'Error') ?>:
36 | = h($message) ?>
37 |
38 |
--------------------------------------------------------------------------------
/bin/cake.bat:
--------------------------------------------------------------------------------
1 | ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2 | ::
3 | :: Cake is a Windows batch script for invoking CakePHP shell commands
4 | ::
5 | :: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6 | :: Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7 | ::
8 | :: Licensed under The MIT License
9 | :: Redistributions of files must retain the above copyright notice.
10 | ::
11 | :: @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
12 | :: @link http://cakephp.org CakePHP(tm) Project
13 | :: @since 2.0.0
14 | :: @license http://www.opensource.org/licenses/mit-license.php MIT License
15 | ::
16 | ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
17 |
18 | :: In order for this script to work as intended, the cake\console\ folder must be in your PATH
19 |
20 | @echo.
21 | @echo off
22 |
23 | SET app=%0
24 | SET lib=%~dp0
25 |
26 | php "%lib%cake.php" %*
27 |
28 | echo.
29 |
30 | exit /B %ERRORLEVEL%
31 |
--------------------------------------------------------------------------------
/src/Template/Groups/edit.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Form->postLink(
5 | __('Delete'),
6 | ['action' => 'delete', $group->id],
7 | ['confirm' => __('Are you sure you want to delete # {0}?', $group->id)]
8 | )
9 | ?>
10 | = $this->Html->link(__('List Groups'), ['action' => 'index']) ?>
11 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
12 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
13 |
14 |
15 |
16 | = $this->Form->create($group) ?>
17 |
18 | = __('Edit Group') ?>
19 | Form->input('name');
21 | ?>
22 |
23 | = $this->Form->button(__('Submit')) ?>
24 | = $this->Form->end() ?>
25 |
26 |
--------------------------------------------------------------------------------
/src/Template/Error/error400.ctp:
--------------------------------------------------------------------------------
1 | layout = 'dev_error';
6 |
7 | $this->assign('title', $message);
8 | $this->assign('templateName', 'error400.ctp');
9 |
10 | $this->start('file');
11 | ?>
12 | queryString)) : ?>
13 |
14 | SQL Query:
15 | = h($error->queryString) ?>
16 |
17 |
18 | params)) : ?>
19 | SQL Query Params:
20 | = Debugger::dump($error->params) ?>
21 |
22 | = $this->element('auto_table_warning') ?>
23 | end();
29 | endif;
30 | ?>
31 | = h($message) ?>
32 |
33 | = __d('cake', 'Error') ?>:
34 | = sprintf(
35 | __d('cake', 'The requested address %s was not found on this server.'),
36 | "'{$url}' "
37 | ) ?>
38 |
39 |
--------------------------------------------------------------------------------
/src/Template/Users/add.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('List Users'), ['action' => 'index']) ?>
5 | = $this->Html->link(__('List Groups'), ['controller' => 'Groups', 'action' => 'index']) ?>
6 | = $this->Html->link(__('New Group'), ['controller' => 'Groups', 'action' => 'add']) ?>
7 | = $this->Html->link(__('List Posts'), ['controller' => 'Posts', 'action' => 'index']) ?>
8 | = $this->Html->link(__('New Post'), ['controller' => 'Posts', 'action' => 'add']) ?>
9 |
10 |
11 |
12 | = $this->Form->create($user) ?>
13 |
14 | = __('Add User') ?>
15 | Form->input('username');
17 | echo $this->Form->input('password');
18 | echo $this->Form->input('group_id', ['options' => $groups]);
19 | ?>
20 |
21 | = $this->Form->button(__('Submit')) ?>
22 | = $this->Form->end() ?>
23 |
24 |
--------------------------------------------------------------------------------
/config/bootstrap_cli.php:
--------------------------------------------------------------------------------
1 |
2 | = __('Actions') ?>
3 |
4 | = $this->Form->postLink(
5 | __('Delete'),
6 | ['action' => 'delete', $post->id],
7 | ['confirm' => __('Are you sure you want to delete # {0}?', $post->id)]
8 | )
9 | ?>
10 | = $this->Html->link(__('List Posts'), ['action' => 'index']) ?>
11 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
12 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
13 |
14 |
15 |
16 | = $this->Form->create($post) ?>
17 |
18 | = __('Edit Post') ?>
19 | Form->input('user_id', ['options' => $users]);
21 | echo $this->Form->input('title');
22 | echo $this->Form->input('body');
23 | ?>
24 |
25 | = $this->Form->button(__('Submit')) ?>
26 | = $this->Form->end() ?>
27 |
28 |
--------------------------------------------------------------------------------
/bin/cake.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/php -q
2 | require->php)) {
23 | $minVersion = preg_replace('/([^0-9\.])/', '', $composer->require->php);
24 | }
25 | }
26 | if (version_compare(phpversion(), $minVersion, '<')) {
27 | fwrite(STDERR, sprintf("Minimum PHP version: %s. You are using: %s.\n", $minVersion, phpversion()));
28 | exit(-1);
29 | }
30 |
31 | include dirname(__DIR__) . '/config/bootstrap.php';
32 |
33 | exit(Cake\Console\ShellDispatcher::run($argv));
34 |
--------------------------------------------------------------------------------
/src/Template/Users/edit.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Form->postLink(
5 | __('Delete'),
6 | ['action' => 'delete', $user->id],
7 | ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]
8 | )
9 | ?>
10 | = $this->Html->link(__('List Users'), ['action' => 'index']) ?>
11 | = $this->Html->link(__('List Groups'), ['controller' => 'Groups', 'action' => 'index']) ?>
12 | = $this->Html->link(__('New Group'), ['controller' => 'Groups', 'action' => 'add']) ?>
13 | = $this->Html->link(__('List Posts'), ['controller' => 'Posts', 'action' => 'index']) ?>
14 | = $this->Html->link(__('New Post'), ['controller' => 'Posts', 'action' => 'add']) ?>
15 |
16 |
17 |
18 | = $this->Form->create($user) ?>
19 |
20 | = __('Edit User') ?>
21 | Form->input('username');
23 | echo $this->Form->input('group_id', ['options' => $groups]);
24 | ?>
25 |
26 | = $this->Form->button(__('Submit')) ?>
27 | = $this->Form->end() ?>
28 |
29 |
--------------------------------------------------------------------------------
/src/Template/Widgets/view.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('Edit Widget'), ['action' => 'edit', $widget->id]) ?>
5 | = $this->Form->postLink(__('Delete Widget'), ['action' => 'delete', $widget->id], ['confirm' => __('Are you sure you want to delete # {0}?', $widget->id)]) ?>
6 | = $this->Html->link(__('List Widgets'), ['action' => 'index']) ?>
7 | = $this->Html->link(__('New Widget'), ['action' => 'add']) ?>
8 |
9 |
10 |
27 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cakephp/app",
3 | "description": "CakePHP skeleton app",
4 | "homepage": "http://cakephp.org",
5 | "type": "project",
6 | "license": "MIT",
7 | "require": {
8 | "php": ">=5.4.16",
9 | "cakephp/cakephp": "~3.0",
10 | "cakephp/acl": "dev-master",
11 | "mobiledetect/mobiledetectlib": "2.*",
12 | "cakephp/migrations": "~1.0",
13 | "cakephp/plugin-installer": "*"
14 | },
15 | "require-dev": {
16 | "psy/psysh": "@stable",
17 | "cakephp/debug_kit": "~3.0",
18 | "cakephp/bake": "~1.0"
19 | },
20 | "suggest": {
21 | "phpunit/phpunit": "Allows automated tests to be run without system-wide install.",
22 | "cakephp/cakephp-codesniffer": "Allows to check the code against the coding standards used in CakePHP."
23 | },
24 | "autoload": {
25 | "psr-4": {
26 | "App\\": "src"
27 | }
28 | },
29 | "autoload-dev": {
30 | "psr-4": {
31 | "App\\Test\\": "tests",
32 | "Cake\\Test\\": "./vendor/cakephp/cakephp/tests"
33 | }
34 | },
35 | "scripts": {
36 | "post-install-cmd": "App\\Console\\Installer::postInstall",
37 | "post-autoload-dump": "Cake\\Composer\\Installer\\PluginInstaller::postAutoloadDump"
38 | },
39 | "minimum-stability": "dev",
40 | "prefer-stable": true
41 | }
42 |
--------------------------------------------------------------------------------
/webroot/index.php:
--------------------------------------------------------------------------------
1 | dispatch(
35 | Request::createFromGlobals(),
36 | new Response()
37 | );
38 |
--------------------------------------------------------------------------------
/src/Model/Table/WidgetsTable.php:
--------------------------------------------------------------------------------
1 | table('widgets');
28 | $this->displayField('name');
29 | $this->primaryKey('id');
30 | }
31 |
32 | /**
33 | * Default validation rules.
34 | *
35 | * @param \Cake\Validation\Validator $validator Validator instance.
36 | * @return \Cake\Validation\Validator
37 | */
38 | public function validationDefault(Validator $validator)
39 | {
40 | $validator
41 | ->add('id', 'valid', ['rule' => 'numeric'])
42 | ->allowEmpty('id', 'create');
43 |
44 | $validator
45 | ->requirePresence('name', 'create')
46 | ->notEmpty('name');
47 |
48 | $validator
49 | ->allowEmpty('part_no');
50 |
51 | $validator
52 | ->add('quantity', 'valid', ['rule' => 'numeric'])
53 | ->allowEmpty('quantity');
54 |
55 | return $validator;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/bin/cake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | ################################################################################
3 | #
4 | # Cake is a shell script for invoking CakePHP shell commands
5 | #
6 | # CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
7 | # Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
8 | #
9 | # Licensed under The MIT License
10 | # For full copyright and license information, please see the LICENSE.txt
11 | # Redistributions of files must retain the above copyright notice.
12 | #
13 | # @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14 | # @link http://cakephp.org CakePHP(tm) Project
15 | # @since 1.2.0
16 | # @license http://www.opensource.org/licenses/mit-license.php MIT License
17 | #
18 | ################################################################################
19 |
20 | # Canonicalize by following every symlink of the given name recursively
21 | canonicalize() {
22 | NAME="$1"
23 | if [ -f "$NAME" ]
24 | then
25 | DIR=$(dirname -- "$NAME")
26 | NAME=$(cd -P "$DIR" > /dev/null && pwd -P)/$(basename -- "$NAME")
27 | fi
28 | while [ -h "$NAME" ]; do
29 | DIR=$(dirname -- "$NAME")
30 | SYM=$(readlink "$NAME")
31 | NAME=$(cd "$DIR" > /dev/null && cd $(dirname -- "$SYM") > /dev/null && pwd)/$(basename -- "$SYM")
32 | done
33 | echo "$NAME"
34 | }
35 |
36 | CONSOLE=$(dirname -- "$(canonicalize "$0")")
37 | APP=$(dirname "$CONSOLE")
38 |
39 | exec php "$CONSOLE"/cake.php "$@"
40 | exit
41 |
--------------------------------------------------------------------------------
/tests/TestCase/Model/Table/WidgetsTableTest.php:
--------------------------------------------------------------------------------
1 | 'App\Model\Table\WidgetsTable'];
32 | $this->Widgets = TableRegistry::get('Widgets', $config);
33 | }
34 |
35 | /**
36 | * tearDown method
37 | *
38 | * @return void
39 | */
40 | public function tearDown()
41 | {
42 | unset($this->Widgets);
43 |
44 | parent::tearDown();
45 | }
46 |
47 | /**
48 | * Test initialize method
49 | *
50 | * @return void
51 | */
52 | public function testInitialize()
53 | {
54 | $this->markTestIncomplete('Not implemented yet.');
55 | }
56 |
57 | /**
58 | * Test validationDefault method
59 | *
60 | * @return void
61 | */
62 | public function testValidationDefault()
63 | {
64 | $this->markTestIncomplete('Not implemented yet.');
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Model/Table/GroupsTable.php:
--------------------------------------------------------------------------------
1 | table('groups');
29 | $this->displayField('name');
30 | $this->primaryKey('id');
31 | $this->addBehavior('Timestamp');
32 | $this->addBehavior('Acl.Acl', ['type' => 'requester']);
33 | $this->hasMany('Users', [
34 | 'foreignKey' => 'group_id'
35 | ]);
36 | }
37 |
38 | /**
39 | * Default validation rules.
40 | *
41 | * @param \Cake\Validation\Validator $validator Validator instance.
42 | * @return \Cake\Validation\Validator
43 | */
44 | public function validationDefault(Validator $validator)
45 | {
46 | $validator
47 | ->add('id', 'valid', ['rule' => 'numeric'])
48 | ->allowEmpty('id', 'create');
49 |
50 | $validator
51 | ->requirePresence('name', 'create')
52 | ->notEmpty('name');
53 |
54 | return $validator;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/TestCase/Model/Table/GroupsTableTest.php:
--------------------------------------------------------------------------------
1 | 'App\Model\Table\GroupsTable'];
33 | $this->Groups = TableRegistry::get('Groups', $config);
34 | }
35 |
36 | /**
37 | * tearDown method
38 | *
39 | * @return void
40 | */
41 | public function tearDown()
42 | {
43 | unset($this->Groups);
44 |
45 | parent::tearDown();
46 | }
47 |
48 | /**
49 | * Test initialize method
50 | *
51 | * @return void
52 | */
53 | public function testInitialize()
54 | {
55 | $this->markTestIncomplete('Not implemented yet.');
56 | }
57 |
58 | /**
59 | * Test validationDefault method
60 | *
61 | * @return void
62 | */
63 | public function testValidationDefault()
64 | {
65 | $this->markTestIncomplete('Not implemented yet.');
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/TestCase/Controller/WidgetsControllerTest.php:
--------------------------------------------------------------------------------
1 | markTestIncomplete('Not implemented yet.');
30 | }
31 |
32 | /**
33 | * Test view method
34 | *
35 | * @return void
36 | */
37 | public function testView()
38 | {
39 | $this->markTestIncomplete('Not implemented yet.');
40 | }
41 |
42 | /**
43 | * Test add method
44 | *
45 | * @return void
46 | */
47 | public function testAdd()
48 | {
49 | $this->markTestIncomplete('Not implemented yet.');
50 | }
51 |
52 | /**
53 | * Test edit method
54 | *
55 | * @return void
56 | */
57 | public function testEdit()
58 | {
59 | $this->markTestIncomplete('Not implemented yet.');
60 | }
61 |
62 | /**
63 | * Test delete method
64 | *
65 | * @return void
66 | */
67 | public function testDelete()
68 | {
69 | $this->markTestIncomplete('Not implemented yet.');
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/View/AjaxView.php:
--------------------------------------------------------------------------------
1 | response->type('ajax');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/TestCase/Controller/GroupsControllerTest.php:
--------------------------------------------------------------------------------
1 | markTestIncomplete('Not implemented yet.');
31 | }
32 |
33 | /**
34 | * Test view method
35 | *
36 | * @return void
37 | */
38 | public function testView()
39 | {
40 | $this->markTestIncomplete('Not implemented yet.');
41 | }
42 |
43 | /**
44 | * Test add method
45 | *
46 | * @return void
47 | */
48 | public function testAdd()
49 | {
50 | $this->markTestIncomplete('Not implemented yet.');
51 | }
52 |
53 | /**
54 | * Test edit method
55 | *
56 | * @return void
57 | */
58 | public function testEdit()
59 | {
60 | $this->markTestIncomplete('Not implemented yet.');
61 | }
62 |
63 | /**
64 | * Test delete method
65 | *
66 | * @return void
67 | */
68 | public function testDelete()
69 | {
70 | $this->markTestIncomplete('Not implemented yet.');
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/tests/TestCase/Controller/PostsControllerTest.php:
--------------------------------------------------------------------------------
1 | markTestIncomplete('Not implemented yet.');
32 | }
33 |
34 | /**
35 | * Test view method
36 | *
37 | * @return void
38 | */
39 | public function testView()
40 | {
41 | $this->markTestIncomplete('Not implemented yet.');
42 | }
43 |
44 | /**
45 | * Test add method
46 | *
47 | * @return void
48 | */
49 | public function testAdd()
50 | {
51 | $this->markTestIncomplete('Not implemented yet.');
52 | }
53 |
54 | /**
55 | * Test edit method
56 | *
57 | * @return void
58 | */
59 | public function testEdit()
60 | {
61 | $this->markTestIncomplete('Not implemented yet.');
62 | }
63 |
64 | /**
65 | * Test delete method
66 | *
67 | * @return void
68 | */
69 | public function testDelete()
70 | {
71 | $this->markTestIncomplete('Not implemented yet.');
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/TestCase/Controller/UsersControllerTest.php:
--------------------------------------------------------------------------------
1 | markTestIncomplete('Not implemented yet.');
32 | }
33 |
34 | /**
35 | * Test view method
36 | *
37 | * @return void
38 | */
39 | public function testView()
40 | {
41 | $this->markTestIncomplete('Not implemented yet.');
42 | }
43 |
44 | /**
45 | * Test add method
46 | *
47 | * @return void
48 | */
49 | public function testAdd()
50 | {
51 | $this->markTestIncomplete('Not implemented yet.');
52 | }
53 |
54 | /**
55 | * Test edit method
56 | *
57 | * @return void
58 | */
59 | public function testEdit()
60 | {
61 | $this->markTestIncomplete('Not implemented yet.');
62 | }
63 |
64 | /**
65 | * Test delete method
66 | *
67 | * @return void
68 | */
69 | public function testDelete()
70 | {
71 | $this->markTestIncomplete('Not implemented yet.');
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/Fixture/GroupsFixture.php:
--------------------------------------------------------------------------------
1 | ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
21 | 'name' => ['type' => 'string', 'length' => 100, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
22 | 'created' => ['type' => 'datetime', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
23 | 'modified' => ['type' => 'datetime', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
24 | '_constraints' => [
25 | 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
26 | ],
27 | '_options' => [
28 | 'engine' => 'InnoDB',
29 | 'collation' => 'latin1_swedish_ci'
30 | ],
31 | ];
32 | // @codingStandardsIgnoreEnd
33 |
34 | /**
35 | * Records
36 | *
37 | * @var array
38 | */
39 | public $records = [
40 | [
41 | 'id' => 1,
42 | 'name' => 'Lorem ipsum dolor sit amet',
43 | 'created' => '2015-08-14 23:27:38',
44 | 'modified' => '2015-08-14 23:27:38'
45 | ],
46 | ];
47 | }
48 |
--------------------------------------------------------------------------------
/tests/Fixture/WidgetsFixture.php:
--------------------------------------------------------------------------------
1 | ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
21 | 'name' => ['type' => 'string', 'length' => 100, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
22 | 'part_no' => ['type' => 'string', 'length' => 12, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
23 | 'quantity' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
24 | '_constraints' => [
25 | 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
26 | ],
27 | '_options' => [
28 | 'engine' => 'InnoDB',
29 | 'collation' => 'latin1_swedish_ci'
30 | ],
31 | ];
32 | // @codingStandardsIgnoreEnd
33 |
34 | /**
35 | * Records
36 | *
37 | * @var array
38 | */
39 | public $records = [
40 | [
41 | 'id' => 1,
42 | 'name' => 'Lorem ipsum dolor sit amet',
43 | 'part_no' => 'Lorem ipsu',
44 | 'quantity' => 1
45 | ],
46 | ];
47 | }
48 |
--------------------------------------------------------------------------------
/tests/TestCase/Model/Table/PostsTableTest.php:
--------------------------------------------------------------------------------
1 | 'App\Model\Table\PostsTable'];
34 | $this->Posts = TableRegistry::get('Posts', $config);
35 | }
36 |
37 | /**
38 | * tearDown method
39 | *
40 | * @return void
41 | */
42 | public function tearDown()
43 | {
44 | unset($this->Posts);
45 |
46 | parent::tearDown();
47 | }
48 |
49 | /**
50 | * Test initialize method
51 | *
52 | * @return void
53 | */
54 | public function testInitialize()
55 | {
56 | $this->markTestIncomplete('Not implemented yet.');
57 | }
58 |
59 | /**
60 | * Test validationDefault method
61 | *
62 | * @return void
63 | */
64 | public function testValidationDefault()
65 | {
66 | $this->markTestIncomplete('Not implemented yet.');
67 | }
68 |
69 | /**
70 | * Test buildRules method
71 | *
72 | * @return void
73 | */
74 | public function testBuildRules()
75 | {
76 | $this->markTestIncomplete('Not implemented yet.');
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tests/TestCase/Model/Table/UsersTableTest.php:
--------------------------------------------------------------------------------
1 | 'App\Model\Table\UsersTable'];
34 | $this->Users = TableRegistry::get('Users', $config);
35 | }
36 |
37 | /**
38 | * tearDown method
39 | *
40 | * @return void
41 | */
42 | public function tearDown()
43 | {
44 | unset($this->Users);
45 |
46 | parent::tearDown();
47 | }
48 |
49 | /**
50 | * Test initialize method
51 | *
52 | * @return void
53 | */
54 | public function testInitialize()
55 | {
56 | $this->markTestIncomplete('Not implemented yet.');
57 | }
58 |
59 | /**
60 | * Test validationDefault method
61 | *
62 | * @return void
63 | */
64 | public function testValidationDefault()
65 | {
66 | $this->markTestIncomplete('Not implemented yet.');
67 | }
68 |
69 | /**
70 | * Test buildRules method
71 | *
72 | * @return void
73 | */
74 | public function testBuildRules()
75 | {
76 | $this->markTestIncomplete('Not implemented yet.');
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/Template/Widgets/index.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('New Widget'), ['action' => 'add']) ?>
5 |
6 |
7 |
44 |
--------------------------------------------------------------------------------
/src/Template/Layout/error.ctp:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 | = $this->Html->charset() ?>
22 |
23 | = $cakeDescription ?>:
24 | = $this->fetch('title') ?>
25 |
26 | = $this->Html->meta('icon') ?>
27 |
28 | = $this->Html->css('base.css') ?>
29 | = $this->Html->css('cake.css') ?>
30 |
31 | = $this->fetch('meta') ?>
32 | = $this->fetch('css') ?>
33 | = $this->fetch('script') ?>
34 |
35 |
36 |
37 |
40 |
41 | = $this->Flash->render() ?>
42 |
43 | = $this->fetch('content') ?>
44 |
45 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/Model/Table/PostsTable.php:
--------------------------------------------------------------------------------
1 | table('posts');
29 | $this->displayField('title');
30 | $this->primaryKey('id');
31 | $this->addBehavior('Timestamp');
32 | $this->belongsTo('Users', [
33 | 'foreignKey' => 'user_id',
34 | 'joinType' => 'INNER'
35 | ]);
36 | }
37 |
38 | /**
39 | * Default validation rules.
40 | *
41 | * @param \Cake\Validation\Validator $validator Validator instance.
42 | * @return \Cake\Validation\Validator
43 | */
44 | public function validationDefault(Validator $validator)
45 | {
46 | $validator
47 | ->add('id', 'valid', ['rule' => 'numeric'])
48 | ->allowEmpty('id', 'create');
49 |
50 | $validator
51 | ->requirePresence('title', 'create')
52 | ->notEmpty('title');
53 |
54 | $validator
55 | ->allowEmpty('body');
56 |
57 | return $validator;
58 | }
59 |
60 | /**
61 | * Returns a rules checker object that will be used for validating
62 | * application integrity.
63 | *
64 | * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
65 | * @return \Cake\ORM\RulesChecker
66 | */
67 | public function buildRules(RulesChecker $rules)
68 | {
69 | $rules->add($rules->existsIn(['user_id'], 'Users'));
70 | return $rules;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Template/Layout/default.ctp:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 | = $this->Html->charset() ?>
22 |
23 |
24 | = $cakeDescription ?>:
25 | = $this->fetch('title') ?>
26 |
27 | = $this->Html->meta('icon') ?>
28 |
29 | = $this->Html->css('base.css') ?>
30 | = $this->Html->css('cake.css') ?>
31 |
32 | = $this->fetch('meta') ?>
33 | = $this->fetch('css') ?>
34 | = $this->fetch('script') ?>
35 |
36 |
37 |
46 |
47 |
48 |
49 | = $this->Flash->render() ?>
50 |
51 |
52 | = $this->fetch('content') ?>
53 |
54 |
55 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/src/Template/Posts/view.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('Edit Post'), ['action' => 'edit', $post->id]) ?>
5 | = $this->Form->postLink(__('Delete Post'), ['action' => 'delete', $post->id], ['confirm' => __('Are you sure you want to delete # {0}?', $post->id)]) ?>
6 | = $this->Html->link(__('List Posts'), ['action' => 'index']) ?>
7 | = $this->Html->link(__('New Post'), ['action' => 'add']) ?>
8 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
9 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
10 |
11 |
12 |
13 |
= h($post->title) ?>
14 |
15 |
16 |
17 |
= $post->has('user') ? $this->Html->link($post->user->id, ['controller' => 'Users', 'action' => 'view', $post->user->id]) : '' ?>
18 |
19 |
= h($post->title) ?>
20 |
21 |
22 |
23 |
= $this->Number->format($post->id) ?>
24 |
25 |
26 |
27 |
= h($post->created) ?>
28 |
29 |
= h($post->modified) ?>
30 |
31 |
32 |
33 |
34 |
35 | = $this->Text->autoParagraph(h($post->body)) ?>
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/Template/Groups/index.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('New Group'), ['action' => 'add']) ?>
5 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
6 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
7 |
8 |
9 |
10 |
11 |
12 |
13 | = $this->Paginator->sort('id') ?>
14 | = $this->Paginator->sort('name') ?>
15 | = $this->Paginator->sort('created') ?>
16 | = $this->Paginator->sort('modified') ?>
17 | = __('Actions') ?>
18 |
19 |
20 |
21 |
22 |
23 | = $this->Number->format($group->id) ?>
24 | = h($group->name) ?>
25 | = h($group->created) ?>
26 | = h($group->modified) ?>
27 |
28 | = $this->Html->link(__('View'), ['action' => 'view', $group->id]) ?>
29 | = $this->Html->link(__('Edit'), ['action' => 'edit', $group->id]) ?>
30 | = $this->Form->postLink(__('Delete'), ['action' => 'delete', $group->id], ['confirm' => __('Are you sure you want to delete # {0}?', $group->id)]) ?>
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
= $this->Paginator->counter() ?>
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/Controller/PagesController.php:
--------------------------------------------------------------------------------
1 | redirect('/');
45 | }
46 | $page = $subpage = null;
47 |
48 | if (!empty($path[0])) {
49 | $page = $path[0];
50 | }
51 | if (!empty($path[1])) {
52 | $subpage = $path[1];
53 | }
54 | $this->set(compact('page', 'subpage'));
55 |
56 | try {
57 | $this->render(implode('/', $path));
58 | } catch (MissingTemplateException $e) {
59 | if (Configure::read('debug')) {
60 | throw $e;
61 | }
62 | throw new NotFoundException();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/Fixture/UsersFixture.php:
--------------------------------------------------------------------------------
1 | ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
21 | 'username' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
22 | 'password' => ['type' => 'string', 'fixed' => true, 'length' => 60, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null],
23 | 'group_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
24 | 'created' => ['type' => 'datetime', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
25 | 'modified' => ['type' => 'datetime', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
26 | '_constraints' => [
27 | 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
28 | 'username' => ['type' => 'unique', 'columns' => ['username'], 'length' => []],
29 | ],
30 | '_options' => [
31 | 'engine' => 'InnoDB',
32 | 'collation' => 'latin1_swedish_ci'
33 | ],
34 | ];
35 | // @codingStandardsIgnoreEnd
36 |
37 | /**
38 | * Records
39 | *
40 | * @var array
41 | */
42 | public $records = [
43 | [
44 | 'id' => 1,
45 | 'username' => 'Lorem ipsum dolor sit amet',
46 | 'password' => 'Lorem ipsum dolor sit amet',
47 | 'group_id' => 1,
48 | 'created' => '2015-08-14 23:27:44',
49 | 'modified' => '2015-08-14 23:27:44'
50 | ],
51 | ];
52 | }
53 |
--------------------------------------------------------------------------------
/src/Controller/AppController.php:
--------------------------------------------------------------------------------
1 | [
31 | 'className' => 'Acl.Acl'
32 | ]
33 | ];
34 |
35 | /**
36 | * Initialization hook method.
37 | *
38 | * Use this method to add common initialization code like loading components.
39 | *
40 | * @return void
41 | */
42 | public function initialize()
43 | {
44 | parent::initialize();
45 | $this->loadComponent('Flash');
46 | $this->loadComponent('Auth', [
47 | 'authorize' => [
48 | 'Acl.Actions' => ['actionPath' => 'controllers/']
49 | ],
50 | 'loginAction' => [
51 | 'plugin' => false,
52 | 'controller' => 'Users',
53 | 'action' => 'login'
54 | ],
55 | 'loginRedirect' => [
56 | 'plugin' => false,
57 | 'controller' => 'Posts',
58 | 'action' => 'index'
59 | ],
60 | 'logoutRedirect' => [
61 | 'plugin' => false,
62 | 'controller' => 'Users',
63 | 'action' => 'login'
64 | ],
65 | 'unauthorizedRedirect' => [
66 | 'controller' => 'Users',
67 | 'action' => 'login',
68 | 'prefix' => false
69 | ],
70 | 'authError' => 'You are not authorized to access that location.',
71 | 'flash' => [
72 | 'element' => 'error'
73 | ]
74 | ]);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Template/Posts/index.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('New Post'), ['action' => 'add']) ?>
5 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
6 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
7 |
8 |
9 |
10 |
11 |
12 |
13 | = $this->Paginator->sort('id') ?>
14 | = $this->Paginator->sort('user_id') ?>
15 | = $this->Paginator->sort('title') ?>
16 | = $this->Paginator->sort('created') ?>
17 | = $this->Paginator->sort('modified') ?>
18 | = __('Actions') ?>
19 |
20 |
21 |
22 |
23 |
24 | = $this->Number->format($post->id) ?>
25 |
26 | = $post->has('user') ? $this->Html->link($post->user->id, ['controller' => 'Users', 'action' => 'view', $post->user->id]) : '' ?>
27 |
28 | = h($post->title) ?>
29 | = h($post->created) ?>
30 | = h($post->modified) ?>
31 |
32 | = $this->Html->link(__('View'), ['action' => 'view', $post->id]) ?>
33 | = $this->Html->link(__('Edit'), ['action' => 'edit', $post->id]) ?>
34 | = $this->Form->postLink(__('Delete'), ['action' => 'delete', $post->id], ['confirm' => __('Are you sure you want to delete # {0}?', $post->id)]) ?>
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
47 |
= $this->Paginator->counter() ?>
48 |
49 |
50 |
--------------------------------------------------------------------------------
/tests/Fixture/PostsFixture.php:
--------------------------------------------------------------------------------
1 | ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'autoIncrement' => true, 'precision' => null],
21 | 'user_id' => ['type' => 'integer', 'length' => 11, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],
22 | 'title' => ['type' => 'string', 'length' => 255, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'fixed' => null],
23 | 'body' => ['type' => 'text', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
24 | 'created' => ['type' => 'datetime', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
25 | 'modified' => ['type' => 'datetime', 'length' => null, 'null' => true, 'default' => null, 'comment' => '', 'precision' => null],
26 | '_constraints' => [
27 | 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
28 | ],
29 | '_options' => [
30 | 'engine' => 'InnoDB',
31 | 'collation' => 'latin1_swedish_ci'
32 | ],
33 | ];
34 | // @codingStandardsIgnoreEnd
35 |
36 | /**
37 | * Records
38 | *
39 | * @var array
40 | */
41 | public $records = [
42 | [
43 | 'id' => 1,
44 | 'user_id' => 1,
45 | 'title' => 'Lorem ipsum dolor sit amet',
46 | 'body' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
47 | 'created' => '2015-08-14 23:27:50',
48 | 'modified' => '2015-08-14 23:27:50'
49 | ],
50 | ];
51 | }
52 |
--------------------------------------------------------------------------------
/config/paths.php:
--------------------------------------------------------------------------------
1 |
2 | = __('Actions') ?>
3 |
4 | = $this->Html->link(__('New User'), ['action' => 'add']) ?>
5 | = $this->Html->link(__('List Groups'), ['controller' => 'Groups', 'action' => 'index']) ?>
6 | = $this->Html->link(__('New Group'), ['controller' => 'Groups', 'action' => 'add']) ?>
7 | = $this->Html->link(__('List Posts'), ['controller' => 'Posts', 'action' => 'index']) ?>
8 | = $this->Html->link(__('New Post'), ['controller' => 'Posts', 'action' => 'add']) ?>
9 |
10 |
11 |
12 |
13 |
14 |
15 | = $this->Paginator->sort('id') ?>
16 | = $this->Paginator->sort('username') ?>
17 | = $this->Paginator->sort('group_id') ?>
18 | = $this->Paginator->sort('created') ?>
19 | = $this->Paginator->sort('modified') ?>
20 | = __('Actions') ?>
21 |
22 |
23 |
24 |
25 |
26 | = $this->Number->format($user->id) ?>
27 | = h($user->username) ?>
28 |
29 | = $user->has('group') ? $this->Html->link($user->group->name, ['controller' => 'Groups', 'action' => 'view', $user->group->id]) : '' ?>
30 |
31 | = h($user->created) ?>
32 | = h($user->modified) ?>
33 |
34 | = $this->Html->link(__('View'), ['action' => 'view', $user->id]) ?>
35 | = $this->Html->link(__('Edit'), ['action' => 'edit', $user->id]) ?>
36 | = $this->Form->postLink(__('Delete'), ['action' => 'delete', $user->id], ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]) ?>
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
49 |
= $this->Paginator->counter() ?>
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/Model/Table/UsersTable.php:
--------------------------------------------------------------------------------
1 | table('users');
31 | $this->displayField('id');
32 | $this->primaryKey('id');
33 | $this->addBehavior('Timestamp');
34 | $this->addBehavior('Acl.Acl', ['type' => 'requester']);
35 | $this->belongsTo('Groups', [
36 | 'foreignKey' => 'group_id',
37 | 'joinType' => 'INNER'
38 | ]);
39 | $this->hasMany('Posts', [
40 | 'foreignKey' => 'user_id'
41 | ]);
42 | }
43 |
44 | /**
45 | * Default validation rules.
46 | *
47 | * @param \Cake\Validation\Validator $validator Validator instance.
48 | * @return \Cake\Validation\Validator
49 | */
50 | public function validationDefault(Validator $validator)
51 | {
52 | $validator
53 | ->add('id', 'valid', ['rule' => 'numeric'])
54 | ->allowEmpty('id', 'create');
55 |
56 | $validator
57 | ->requirePresence('username', 'create')
58 | ->notEmpty('username')
59 | ->add('username', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
60 |
61 | $validator
62 | ->requirePresence('password', 'create')
63 | ->notEmpty('password');
64 |
65 | return $validator;
66 | }
67 |
68 | /**
69 | * Returns a rules checker object that will be used for validating
70 | * application integrity.
71 | *
72 | * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
73 | * @return \Cake\ORM\RulesChecker
74 | */
75 | public function buildRules(RulesChecker $rules)
76 | {
77 | $rules->add($rules->isUnique(['username']));
78 | $rules->add($rules->existsIn(['group_id'], 'Groups'));
79 | return $rules;
80 | }
81 |
82 | public function beforeSave(\Cake\Event\Event $event, \Cake\ORM\Entity $entity,
83 | \ArrayObject $options)
84 | {
85 | $hasher = new DefaultPasswordHasher;
86 | $entity->password = $hasher->hash($entity->password);
87 | return true;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Shell/ConsoleShell.php:
--------------------------------------------------------------------------------
1 | err('Unable to load Psy\Shell. ');
37 | $this->err('');
38 | $this->err('Make sure you have installed psysh as a dependency,');
39 | $this->err('and that Psy\Shell is registered in your autoloader.');
40 | $this->err('');
41 | $this->err('If you are using composer run');
42 | $this->err('');
43 | $this->err('$ php composer.phar require --dev psy/psysh ');
44 | $this->err('');
45 | return 1;
46 | }
47 |
48 | $this->out("You can exit with `CTRL-C` or `exit` ");
49 | $this->out('');
50 |
51 | Log::drop('debug');
52 | Log::drop('error');
53 | $this->_io->setLoggers(false);
54 | restore_error_handler();
55 | restore_exception_handler();
56 |
57 | $psy = new PsyShell();
58 | $psy->run();
59 | }
60 |
61 | /**
62 | * Display help for this console.
63 | *
64 | * @return ConsoleOptionParser
65 | */
66 | public function getOptionParser()
67 | {
68 | $parser = new ConsoleOptionParser('console');
69 | $parser->description(
70 | 'This shell provides a REPL that you can use to interact ' .
71 | 'with your application in an interactive fashion. You can use ' .
72 | 'it to run adhoc queries with your models, or experiment ' .
73 | 'and explore the features of CakePHP and your application.' .
74 | "\n\n" .
75 | 'You will need to have psysh installed for this Shell to work.'
76 | );
77 | return $parser;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/config/routes.php:
--------------------------------------------------------------------------------
1 | connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
51 |
52 | /**
53 | * ...and connect the rest of 'Pages' controller's URLs.
54 | */
55 | $routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
56 |
57 | /**
58 | * Connect catchall routes for all controllers.
59 | *
60 | * Using the argument `InflectedRoute`, the `fallbacks` method is a shortcut for
61 | * `$routes->connect('/:controller', ['action' => 'index'], ['routeClass' => 'InflectedRoute']);`
62 | * `$routes->connect('/:controller/:action/*', [], ['routeClass' => 'InflectedRoute']);`
63 | *
64 | * Any route class can be used with this method, such as:
65 | * - DashedRoute
66 | * - InflectedRoute
67 | * - Route
68 | * - Or your own route class
69 | *
70 | * You can remove these routes once you've connected the
71 | * routes you want in your application.
72 | */
73 | $routes->fallbacks('InflectedRoute');
74 | });
75 |
76 | /**
77 | * Load all plugin routes. See the Plugin documentation on
78 | * how to customize the loading of plugin routes.
79 | */
80 | Plugin::routes();
81 |
--------------------------------------------------------------------------------
/src/Template/Groups/view.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('Edit Group'), ['action' => 'edit', $group->id]) ?>
5 | = $this->Form->postLink(__('Delete Group'), ['action' => 'delete', $group->id], ['confirm' => __('Are you sure you want to delete # {0}?', $group->id)]) ?>
6 | = $this->Html->link(__('List Groups'), ['action' => 'index']) ?>
7 | = $this->Html->link(__('New Group'), ['action' => 'add']) ?>
8 | = $this->Html->link(__('List Users'), ['controller' => 'Users', 'action' => 'index']) ?>
9 | = $this->Html->link(__('New User'), ['controller' => 'Users', 'action' => 'add']) ?>
10 |
11 |
12 |
13 |
= h($group->name) ?>
14 |
15 |
16 |
17 |
= h($group->name) ?>
18 |
19 |
20 |
21 |
= $this->Number->format($group->id) ?>
22 |
23 |
24 |
25 |
= h($group->created) ?>
26 |
27 |
= h($group->modified) ?>
28 |
29 |
30 |
31 |
69 |
--------------------------------------------------------------------------------
/src/Template/Users/view.ctp:
--------------------------------------------------------------------------------
1 |
2 |
= __('Actions') ?>
3 |
4 | = $this->Html->link(__('Edit User'), ['action' => 'edit', $user->id]) ?>
5 | = $this->Form->postLink(__('Delete User'), ['action' => 'delete', $user->id], ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]) ?>
6 | = $this->Html->link(__('List Users'), ['action' => 'index']) ?>
7 | = $this->Html->link(__('New User'), ['action' => 'add']) ?>
8 | = $this->Html->link(__('List Groups'), ['controller' => 'Groups', 'action' => 'index']) ?>
9 | = $this->Html->link(__('New Group'), ['controller' => 'Groups', 'action' => 'add']) ?>
10 | = $this->Html->link(__('List Posts'), ['controller' => 'Posts', 'action' => 'index']) ?>
11 | = $this->Html->link(__('New Post'), ['controller' => 'Posts', 'action' => 'add']) ?>
12 |
13 |
14 |
15 |
= h($user->id) ?>
16 |
17 |
18 |
19 |
= h($user->username) ?>
20 |
21 |
= $user->has('group') ? $this->Html->link($user->group->name, ['controller' => 'Groups', 'action' => 'view', $user->group->id]) : '' ?>
22 |
23 |
24 |
25 |
= $this->Number->format($user->id) ?>
26 |
27 |
28 |
29 |
= h($user->created) ?>
30 |
31 |
= h($user->modified) ?>
32 |
33 |
34 |
35 |
73 |
--------------------------------------------------------------------------------
/src/Controller/WidgetsController.php:
--------------------------------------------------------------------------------
1 | set('widgets', $this->paginate($this->Widgets));
22 | $this->set('_serialize', ['widgets']);
23 | }
24 |
25 | /**
26 | * View method
27 | *
28 | * @param string|null $id Widget id.
29 | * @return void
30 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
31 | */
32 | public function view($id = null)
33 | {
34 | $widget = $this->Widgets->get($id, [
35 | 'contain' => []
36 | ]);
37 | $this->set('widget', $widget);
38 | $this->set('_serialize', ['widget']);
39 | }
40 |
41 | /**
42 | * Add method
43 | *
44 | * @return void Redirects on successful add, renders view otherwise.
45 | */
46 | public function add()
47 | {
48 | $widget = $this->Widgets->newEntity();
49 | if ($this->request->is('post')) {
50 | $widget = $this->Widgets->patchEntity($widget, $this->request->data);
51 | if ($this->Widgets->save($widget)) {
52 | $this->Flash->success(__('The widget has been saved.'));
53 | return $this->redirect(['action' => 'index']);
54 | } else {
55 | $this->Flash->error(__('The widget could not be saved. Please, try again.'));
56 | }
57 | }
58 | $this->set(compact('widget'));
59 | $this->set('_serialize', ['widget']);
60 | }
61 |
62 | /**
63 | * Edit method
64 | *
65 | * @param string|null $id Widget id.
66 | * @return void Redirects on successful edit, renders view otherwise.
67 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
68 | */
69 | public function edit($id = null)
70 | {
71 | $widget = $this->Widgets->get($id, [
72 | 'contain' => []
73 | ]);
74 | if ($this->request->is(['patch', 'post', 'put'])) {
75 | $widget = $this->Widgets->patchEntity($widget, $this->request->data);
76 | if ($this->Widgets->save($widget)) {
77 | $this->Flash->success(__('The widget has been saved.'));
78 | return $this->redirect(['action' => 'index']);
79 | } else {
80 | $this->Flash->error(__('The widget could not be saved. Please, try again.'));
81 | }
82 | }
83 | $this->set(compact('widget'));
84 | $this->set('_serialize', ['widget']);
85 | }
86 |
87 | /**
88 | * Delete method
89 | *
90 | * @param string|null $id Widget id.
91 | * @return void Redirects to index.
92 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
93 | */
94 | public function delete($id = null)
95 | {
96 | $this->request->allowMethod(['post', 'delete']);
97 | $widget = $this->Widgets->get($id);
98 | if ($this->Widgets->delete($widget)) {
99 | $this->Flash->success(__('The widget has been deleted.'));
100 | } else {
101 | $this->Flash->error(__('The widget could not be deleted. Please, try again.'));
102 | }
103 | return $this->redirect(['action' => 'index']);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/Controller/GroupsController.php:
--------------------------------------------------------------------------------
1 | Auth->allow();
19 | }
20 |
21 | /**
22 | * Index method
23 | *
24 | * @return void
25 | */
26 | public function index()
27 | {
28 | $this->set('groups', $this->paginate($this->Groups));
29 | $this->set('_serialize', ['groups']);
30 | }
31 |
32 | /**
33 | * View method
34 | *
35 | * @param string|null $id Group id.
36 | * @return void
37 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
38 | */
39 | public function view($id = null)
40 | {
41 | $group = $this->Groups->get($id, [
42 | 'contain' => ['Users']
43 | ]);
44 | $this->set('group', $group);
45 | $this->set('_serialize', ['group']);
46 | }
47 |
48 | /**
49 | * Add method
50 | *
51 | * @return void Redirects on successful add, renders view otherwise.
52 | */
53 | public function add()
54 | {
55 | $group = $this->Groups->newEntity();
56 | if ($this->request->is('post')) {
57 | $group = $this->Groups->patchEntity($group, $this->request->data);
58 | if ($this->Groups->save($group)) {
59 | $this->Flash->success(__('The group has been saved.'));
60 | return $this->redirect(['action' => 'index']);
61 | } else {
62 | $this->Flash->error(__('The group could not be saved. Please, try again.'));
63 | }
64 | }
65 | $this->set(compact('group'));
66 | $this->set('_serialize', ['group']);
67 | }
68 |
69 | /**
70 | * Edit method
71 | *
72 | * @param string|null $id Group id.
73 | * @return void Redirects on successful edit, renders view otherwise.
74 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
75 | */
76 | public function edit($id = null)
77 | {
78 | $group = $this->Groups->get($id, [
79 | 'contain' => []
80 | ]);
81 | if ($this->request->is(['patch', 'post', 'put'])) {
82 | $group = $this->Groups->patchEntity($group, $this->request->data);
83 | if ($this->Groups->save($group)) {
84 | $this->Flash->success(__('The group has been saved.'));
85 | return $this->redirect(['action' => 'index']);
86 | } else {
87 | $this->Flash->error(__('The group could not be saved. Please, try again.'));
88 | }
89 | }
90 | $this->set(compact('group'));
91 | $this->set('_serialize', ['group']);
92 | }
93 |
94 | /**
95 | * Delete method
96 | *
97 | * @param string|null $id Group id.
98 | * @return void Redirects to index.
99 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
100 | */
101 | public function delete($id = null)
102 | {
103 | $this->request->allowMethod(['post', 'delete']);
104 | $group = $this->Groups->get($id);
105 | if ($this->Groups->delete($group)) {
106 | $this->Flash->success(__('The group has been deleted.'));
107 | } else {
108 | $this->Flash->error(__('The group could not be deleted. Please, try again.'));
109 | }
110 | return $this->redirect(['action' => 'index']);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/Controller/PostsController.php:
--------------------------------------------------------------------------------
1 | paginate = [
22 | 'contain' => ['Users']
23 | ];
24 | $this->set('posts', $this->paginate($this->Posts));
25 | $this->set('_serialize', ['posts']);
26 | }
27 |
28 | /**
29 | * View method
30 | *
31 | * @param string|null $id Post id.
32 | * @return void
33 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
34 | */
35 | public function view($id = null)
36 | {
37 | $post = $this->Posts->get($id, [
38 | 'contain' => ['Users']
39 | ]);
40 | $this->set('post', $post);
41 | $this->set('_serialize', ['post']);
42 | }
43 |
44 | /**
45 | * Add method
46 | *
47 | * @return void Redirects on successful add, renders view otherwise.
48 | */
49 | public function add()
50 | {
51 | $post = $this->Posts->newEntity();
52 | if ($this->request->is('post')) {
53 | $post = $this->Posts->patchEntity($post, $this->request->data);
54 | if ($this->Posts->save($post)) {
55 | $this->Flash->success(__('The post has been saved.'));
56 | return $this->redirect(['action' => 'index']);
57 | } else {
58 | $this->Flash->error(__('The post could not be saved. Please, try again.'));
59 | }
60 | }
61 | $users = $this->Posts->Users->find('list', ['limit' => 200]);
62 | $this->set(compact('post', 'users'));
63 | $this->set('_serialize', ['post']);
64 | }
65 |
66 | /**
67 | * Edit method
68 | *
69 | * @param string|null $id Post id.
70 | * @return void Redirects on successful edit, renders view otherwise.
71 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
72 | */
73 | public function edit($id = null)
74 | {
75 | $post = $this->Posts->get($id, [
76 | 'contain' => []
77 | ]);
78 | if ($this->request->is(['patch', 'post', 'put'])) {
79 | $post = $this->Posts->patchEntity($post, $this->request->data);
80 | if ($this->Posts->save($post)) {
81 | $this->Flash->success(__('The post has been saved.'));
82 | return $this->redirect(['action' => 'index']);
83 | } else {
84 | $this->Flash->error(__('The post could not be saved. Please, try again.'));
85 | }
86 | }
87 | $users = $this->Posts->Users->find('list', ['limit' => 200]);
88 | $this->set(compact('post', 'users'));
89 | $this->set('_serialize', ['post']);
90 | }
91 |
92 | /**
93 | * Delete method
94 | *
95 | * @param string|null $id Post id.
96 | * @return void Redirects to index.
97 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
98 | */
99 | public function delete($id = null)
100 | {
101 | $this->request->allowMethod(['post', 'delete']);
102 | $post = $this->Posts->get($id);
103 | if ($this->Posts->delete($post)) {
104 | $this->Flash->success(__('The post has been deleted.'));
105 | } else {
106 | $this->Flash->error(__('The post could not be deleted. Please, try again.'));
107 | }
108 | return $this->redirect(['action' => 'index']);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/Controller/UsersController.php:
--------------------------------------------------------------------------------
1 | Auth->allow();
19 | }
20 |
21 | /**
22 | * Index method
23 | *
24 | * @return void
25 | */
26 | public function index()
27 | {
28 | $this->paginate = [
29 | 'contain' => ['Groups']
30 | ];
31 | $this->set('users', $this->paginate($this->Users));
32 | $this->set('_serialize', ['users']);
33 | }
34 |
35 | /**
36 | * View method
37 | *
38 | * @param string|null $id User id.
39 | * @return void
40 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
41 | */
42 | public function view($id = null)
43 | {
44 | $user = $this->Users->get($id, [
45 | 'contain' => ['Groups', 'Posts']
46 | ]);
47 | $this->set('user', $user);
48 | $this->set('_serialize', ['user']);
49 | }
50 |
51 | /**
52 | * Add method
53 | *
54 | * @return void Redirects on successful add, renders view otherwise.
55 | */
56 | public function add()
57 | {
58 | $user = $this->Users->newEntity();
59 | if ($this->request->is('post')) {
60 | $user = $this->Users->patchEntity($user, $this->request->data);
61 | if ($this->Users->save($user)) {
62 | $this->Flash->success(__('The user has been saved.'));
63 | return $this->redirect(['action' => 'index']);
64 | } else {
65 | $this->Flash->error(__('The user could not be saved. Please, try again.'));
66 | }
67 | }
68 | $groups = $this->Users->Groups->find('list', ['limit' => 200]);
69 | $this->set(compact('user', 'groups'));
70 | $this->set('_serialize', ['user']);
71 | }
72 |
73 | /**
74 | * Edit method
75 | *
76 | * @param string|null $id User id.
77 | * @return void Redirects on successful edit, renders view otherwise.
78 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
79 | */
80 | public function edit($id = null)
81 | {
82 | $user = $this->Users->get($id, [
83 | 'contain' => []
84 | ]);
85 | if ($this->request->is(['patch', 'post', 'put'])) {
86 | $user = $this->Users->patchEntity($user, $this->request->data);
87 | if ($this->Users->save($user)) {
88 | $this->Flash->success(__('The user has been saved.'));
89 | return $this->redirect(['action' => 'index']);
90 | } else {
91 | $this->Flash->error(__('The user could not be saved. Please, try again.'));
92 | }
93 | }
94 | $groups = $this->Users->Groups->find('list', ['limit' => 200]);
95 | $this->set(compact('user', 'groups'));
96 | $this->set('_serialize', ['user']);
97 | }
98 |
99 | /**
100 | * Delete method
101 | *
102 | * @param string|null $id User id.
103 | * @return void Redirects to index.
104 | * @throws \Cake\Network\Exception\NotFoundException When record not found.
105 | */
106 | public function delete($id = null)
107 | {
108 | $this->request->allowMethod(['post', 'delete']);
109 | $user = $this->Users->get($id);
110 | if ($this->Users->delete($user)) {
111 | $this->Flash->success(__('The user has been deleted.'));
112 | } else {
113 | $this->Flash->error(__('The user could not be deleted. Please, try again.'));
114 | }
115 | return $this->redirect(['action' => 'index']);
116 | }
117 |
118 | /**
119 | * Login method
120 | *
121 | * @return void Redirects on successful login, renders view otherwise.
122 | */
123 | public function login() {
124 | if ($this->request->is('post')) {
125 | $user = $this->Auth->identify();
126 | if ($user) {
127 | $this->Auth->setUser($user);
128 | return $this->redirect($this->Auth->redirectUrl());
129 | }
130 | $this->Flash->error(__('Your username or password was incorrect.'));
131 | }
132 | }
133 |
134 | /**
135 | * Logout method
136 | *
137 | * @return void Redirects to the logout redirect location defined in the AuthComponent
138 | */
139 | public function logout() {
140 | $this->Flash->success(__('Good-Bye'));
141 | $this->redirect($this->Auth->logout());
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/Console/Installer.php:
--------------------------------------------------------------------------------
1 | getIO();
37 |
38 | $rootDir = dirname(dirname(__DIR__));
39 |
40 | static::createAppConfig($rootDir, $io);
41 | static::createWritableDirectories($rootDir, $io);
42 |
43 | // ask if the permissions should be changed
44 | if ($io->isInteractive()) {
45 | $validator = function ($arg) {
46 | if (in_array($arg, ['Y', 'y', 'N', 'n'])) {
47 | return $arg;
48 | }
49 | throw new Exception('This is not a valid answer. Please choose Y or n.');
50 | };
51 | $setFolderPermissions = $io->askAndValidate(
52 | 'Set Folder Permissions ? (Default to Y) [Y,n ]? ',
53 | $validator,
54 | 10,
55 | 'Y'
56 | );
57 |
58 | if (in_array($setFolderPermissions, ['Y', 'y'])) {
59 | static::setFolderPermissions($rootDir, $io);
60 | }
61 | } else {
62 | static::setFolderPermissions($rootDir, $io);
63 | }
64 |
65 | static::setSecuritySalt($rootDir, $io);
66 |
67 | if (class_exists('\Cake\Codeception\Console\Installer')) {
68 | \Cake\Codeception\Console\Installer::customizeCodeceptionBinary($event);
69 | }
70 | }
71 |
72 | /**
73 | * Create the config/app.php file if it does not exist.
74 | *
75 | * @param string $dir The application's root directory.
76 | * @param \Composer\IO\IOInterface $io IO interface to write to console.
77 | * @return void
78 | */
79 | public static function createAppConfig($dir, $io)
80 | {
81 | $appConfig = $dir . '/config/app.php';
82 | $defaultConfig = $dir . '/config/app.default.php';
83 | if (!file_exists($appConfig)) {
84 | copy($defaultConfig, $appConfig);
85 | $io->write('Created `config/app.php` file');
86 | }
87 | }
88 |
89 | /**
90 | * Create the `logs` and `tmp` directories.
91 | *
92 | * @param string $dir The application's root directory.
93 | * @param \Composer\IO\IOInterface $io IO interface to write to console.
94 | * @return void
95 | */
96 | public static function createWritableDirectories($dir, $io)
97 | {
98 | $paths = [
99 | 'logs',
100 | 'tmp',
101 | 'tmp/cache',
102 | 'tmp/cache/models',
103 | 'tmp/cache/persistent',
104 | 'tmp/cache/views',
105 | 'tmp/sessions',
106 | 'tmp/tests'
107 | ];
108 |
109 | foreach ($paths as $path) {
110 | $path = $dir . '/' . $path;
111 | if (!file_exists($path)) {
112 | mkdir($path);
113 | $io->write('Created `' . $path . '` directory');
114 | }
115 | }
116 | }
117 |
118 | /**
119 | * Set globally writable permissions on the "tmp" and "logs" directory.
120 | *
121 | * This is not the most secure default, but it gets people up and running quickly.
122 | *
123 | * @param string $dir The application's root directory.
124 | * @param \Composer\IO\IOInterface $io IO interface to write to console.
125 | * @return void
126 | */
127 | public static function setFolderPermissions($dir, $io)
128 | {
129 | // Change the permissions on a path and output the results.
130 | $changePerms = function ($path, $perms, $io) {
131 | // Get current permissions in decimal format so we can bitmask it.
132 | $currentPerms = octdec(substr(sprintf('%o', fileperms($path)), -4));
133 | if (($currentPerms & $perms) == $perms) {
134 | return;
135 | }
136 |
137 | $res = chmod($path, $currentPerms | $perms);
138 | if ($res) {
139 | $io->write('Permissions set on ' . $path);
140 | } else {
141 | $io->write('Failed to set permissions on ' . $path);
142 | }
143 | };
144 |
145 | $walker = function ($dir, $perms, $io) use (&$walker, $changePerms) {
146 | $files = array_diff(scandir($dir), ['.', '..']);
147 | foreach ($files as $file) {
148 | $path = $dir . '/' . $file;
149 |
150 | if (!is_dir($path)) {
151 | continue;
152 | }
153 |
154 | $changePerms($path, $perms, $io);
155 | $walker($path, $perms, $io);
156 | }
157 | };
158 |
159 | $worldWritable = bindec('0000000111');
160 | $walker($dir . '/tmp', $worldWritable, $io);
161 | $changePerms($dir . '/tmp', $worldWritable, $io);
162 | $changePerms($dir . '/logs', $worldWritable, $io);
163 | }
164 |
165 | /**
166 | * Set the security.salt value in the application's config file.
167 | *
168 | * @param string $dir The application's root directory.
169 | * @param \Composer\IO\IOInterface $io IO interface to write to console.
170 | * @return void
171 | */
172 | public static function setSecuritySalt($dir, $io)
173 | {
174 | $config = $dir . '/config/app.php';
175 | $content = file_get_contents($config);
176 |
177 | $newKey = hash('sha256', $dir . php_uname() . microtime(true));
178 | $content = str_replace('__SALT__', $newKey, $content, $count);
179 |
180 | if ($count == 0) {
181 | $io->write('No Security.salt placeholder to replace.');
182 | return;
183 | }
184 |
185 | $result = file_put_contents($config, $content);
186 | if ($result) {
187 | $io->write('Updated Security.salt value in config/app.php');
188 | return;
189 | }
190 | $io->write('Unable to update Security.salt value.');
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | getMessage() . "\n");
70 | }
71 |
72 | // Load an environment local configuration file.
73 | // You can use a file like app_local.php to provide local overrides to your
74 | // shared configuration.
75 | //Configure::load('app_local', 'default');
76 |
77 | // When debug = false the metadata cache should last
78 | // for a very very long time, as we don't want
79 | // to refresh the cache while users are doing requests.
80 | if (!Configure::read('debug')) {
81 | Configure::write('Cache._cake_model_.duration', '+1 years');
82 | Configure::write('Cache._cake_core_.duration', '+1 years');
83 | }
84 |
85 | /**
86 | * Set server timezone to UTC. You can change it to another timezone of your
87 | * choice but using UTC makes time calculations / conversions easier.
88 | */
89 | date_default_timezone_set('UTC');
90 |
91 | /**
92 | * Configure the mbstring extension to use the correct encoding.
93 | */
94 | mb_internal_encoding(Configure::read('App.encoding'));
95 |
96 | /**
97 | * Set the default locale. This controls how dates, number and currency is
98 | * formatted and sets the default language to use for translations.
99 | */
100 | ini_set('intl.default_locale', 'en_US');
101 |
102 | /**
103 | * Register application error and exception handlers.
104 | */
105 | $isCli = php_sapi_name() === 'cli';
106 | if ($isCli) {
107 | (new ConsoleErrorHandler(Configure::read('Error')))->register();
108 | } else {
109 | (new ErrorHandler(Configure::read('Error')))->register();
110 | }
111 |
112 | // Include the CLI bootstrap overrides.
113 | if ($isCli) {
114 | require __DIR__ . '/bootstrap_cli.php';
115 | }
116 |
117 | /**
118 | * Set the full base URL.
119 | * This URL is used as the base of all absolute links.
120 | *
121 | * If you define fullBaseUrl in your config file you can remove this.
122 | */
123 | if (!Configure::read('App.fullBaseUrl')) {
124 | $s = null;
125 | if (env('HTTPS')) {
126 | $s = 's';
127 | }
128 |
129 | $httpHost = env('HTTP_HOST');
130 | if (isset($httpHost)) {
131 | Configure::write('App.fullBaseUrl', 'http' . $s . '://' . $httpHost);
132 | }
133 | unset($httpHost, $s);
134 | }
135 |
136 | Cache::config(Configure::consume('Cache'));
137 | ConnectionManager::config(Configure::consume('Datasources'));
138 | Email::configTransport(Configure::consume('EmailTransport'));
139 | Email::config(Configure::consume('Email'));
140 | Log::config(Configure::consume('Log'));
141 | Security::salt(Configure::consume('Security.salt'));
142 |
143 | /**
144 | * The default crypto extension in 3.0 is OpenSSL.
145 | * If you are migrating from 2.x uncomment this code to
146 | * use a more compatible Mcrypt based implementation
147 | */
148 | // Security::engine(new \Cake\Utility\Crypto\Mcrypt());
149 |
150 | /**
151 | * Setup detectors for mobile and tablet.
152 | */
153 | Request::addDetector('mobile', function ($request) {
154 | $detector = new \Detection\MobileDetect();
155 | return $detector->isMobile();
156 | });
157 | Request::addDetector('tablet', function ($request) {
158 | $detector = new \Detection\MobileDetect();
159 | return $detector->isTablet();
160 | });
161 |
162 | /**
163 | * Custom Inflector rules, can be set to correctly pluralize or singularize
164 | * table, model, controller names or whatever other string is passed to the
165 | * inflection functions.
166 | *
167 | * Inflector::rules('plural', ['/^(inflect)or$/i' => '\1ables']);
168 | * Inflector::rules('irregular', ['red' => 'redlings']);
169 | * Inflector::rules('uninflected', ['dontinflectme']);
170 | * Inflector::rules('transliteration', ['/å/' => 'aa']);
171 | */
172 |
173 | /**
174 | * Plugins need to be loaded manually, you can either load them one by one or all of them in a single call
175 | * Uncomment one of the lines below, as you need. make sure you read the documentation on Plugin to use more
176 | * advanced ways of loading plugins
177 | *
178 | * Plugin::loadAll(); // Loads all plugins at once
179 | * Plugin::load('Migrations'); //Loads a single plugin named Migrations
180 | *
181 | */
182 |
183 | Plugin::load('Migrations');
184 | Plugin::load('Acl', ['bootstrap' => true]);
185 |
186 | // Only try to load DebugKit in development mode
187 | // Debug Kit should not be installed on a production system
188 | if (Configure::read('debug')) {
189 | Plugin::load('DebugKit', ['bootstrap' => true]);
190 | }
191 |
192 | /**
193 | * Connect middleware/dispatcher filters.
194 | */
195 | DispatcherFactory::add('Asset');
196 | DispatcherFactory::add('Routing');
197 | DispatcherFactory::add('ControllerFactory');
198 |
199 | /**
200 | * Enable default locale format parsing.
201 | * This is needed for matching the auto-localized string output of Time() class when parsing dates.
202 | */
203 | Type::build('datetime')->useLocaleParser();
204 |
--------------------------------------------------------------------------------
/webroot/css/cake.css:
--------------------------------------------------------------------------------
1 | a.disabled {
2 | pointer-events: none;
3 | }
4 |
5 | a:hover {
6 | color: #15848F;
7 | }
8 |
9 | a {
10 | color: #1798A5;
11 | }
12 |
13 | .side-nav li a:not(.button) {
14 | color: #15848F;
15 | }
16 |
17 | .side-nav li a:not(.button):hover {
18 | color: #15848F;
19 | }
20 |
21 | header {
22 | background-color: #15848F;
23 | color: #ffffff;
24 | font-size: 30px;
25 | height: 84px;
26 | line-height: 64px;
27 | padding: 16px 0px;
28 | box-shadow: 0px 1px rgba(0, 0, 0, 0.24);
29 | }
30 |
31 | header .header-title {
32 | padding-left:80px
33 | }
34 |
35 |
36 | legend {
37 | color:#15848F;
38 | }
39 |
40 | .row {
41 | max-width: 80rem;
42 | }
43 |
44 | .actions.columns {
45 | margin-top:1rem;
46 | border-left: 5px solid #15848F;
47 | padding-left: 15px;
48 | padding: 32px 20px;
49 | }
50 |
51 | .actions.columns h3 {
52 | color:#15848F;
53 | }
54 |
55 | .index table {
56 | margin-top: 2rem;
57 | border: 0;
58 | }
59 |
60 | .index table thead {
61 | height: 3.5rem;
62 | }
63 |
64 | .header-help {
65 | float: right;
66 | margin-right:2rem;
67 | margin-top: -80px;
68 | font-size:16px;
69 | }
70 |
71 | .header-help span {
72 | font-weight: normal;
73 | text-align: center;
74 | text-decoration: none;
75 | line-height: 1;
76 | white-space: nowrap;
77 | display: inline-block;
78 | padding: 0.25rem 0.5rem 0.375rem;
79 | font-size: 0.8rem;
80 | background-color: #0097a7;
81 | color: #FFF;
82 | border-radius: 1000px;
83 | }
84 |
85 | .header-help a {
86 | color: #fff;
87 | }
88 |
89 | ul.pagination li a {
90 | color: rgba(0, 0 ,0 , 0.54);
91 | }
92 |
93 | ul.pagination li.active a {
94 | background: none repeat scroll 0% 0% #DCE47E;
95 | color: #FFF;
96 | font-weight: bold;
97 | cursor: default;
98 | }
99 |
100 | .paginator {
101 | text-align: center;
102 | }
103 |
104 | .paginator ul.pagination li {
105 | float: none;
106 | display: inline-block;
107 | }
108 |
109 | .paginator p {
110 | text-align: right;
111 | color: rgba(0, 0 ,0 , 0.54);
112 | }
113 |
114 | button {
115 | background: #8D6E65;
116 | }
117 |
118 | .form button:hover, .form button:focus {
119 | background: #7A6058;
120 | box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.26) !important;
121 | }
122 |
123 | .form button[type="submit"] {
124 | float: right;
125 | text-transform: uppercase;
126 | box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.26);
127 | }
128 |
129 | .form .error-message {
130 | display: block;
131 | padding: 0.375rem 0.5625rem 0.5625rem;
132 | margin-top: -1px;
133 | margin-bottom: 1rem;
134 | font-size: 0.75rem;
135 | font-weight: normal;
136 | font-style: italic;
137 | color: rgba(0, 0, 0, 0.54);
138 | }
139 |
140 | .required > label {
141 | font-weight: bold;
142 | }
143 | .required > label:after {
144 | content: ' *';
145 | color: #C3232D;
146 | }
147 |
148 | select[multiple] {
149 | min-height:150px;
150 | background: none;
151 | }
152 | input[type=checkbox],
153 | input[type=radio] {
154 | margin-right: 0.5em;
155 | }
156 |
157 | .date select,
158 | .time select,
159 | .datetime select {
160 | display: inline;
161 | width: auto;
162 | margin-right: 10px;
163 | }
164 |
165 | .error label,
166 | .error label.error {
167 | color: #C3232D;
168 | }
169 |
170 | div.message {
171 | border-style: solid;
172 | border-width: 1px;
173 | display: block;
174 | font-weight: normal;
175 | position: relative;
176 | padding: 0.875rem 1.5rem 0.875rem 20%;
177 | transition: opacity 300ms ease-out 0s;
178 | background-color: #DCE47E;
179 | border-color: #DCE47E;
180 | color: #626262;
181 | }
182 |
183 | div.message.error {
184 | background-color: #C3232D;
185 | border-color: #C3232D;
186 | color: #FFF;
187 | }
188 |
189 | div.message:before {
190 | line-height: 0px;
191 | font-size: 20px;
192 | height: 12px;
193 | width: 12px;
194 | border-radius: 15px;
195 | text-align: center;
196 | vertical-align: middle;
197 | display: inline-block;
198 | position: relative;
199 | left: -11px;
200 | background-color: #FFF;
201 | padding: 12px 14px 12px 10px;
202 | content: "i";
203 | color: #DCE47E;
204 | }
205 |
206 | div.message.error:before {
207 | padding: 11px 16px 14px 7px;
208 | color: #C3232D;
209 | content: "x";
210 | }
211 |
212 | .view h2 {
213 | color: #6F6F6F;
214 | }
215 |
216 | .view .columns.strings {
217 | border-radius: 3px;
218 | box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24);
219 | margin-right:0.7rem;
220 | }
221 |
222 | .view .numbers {
223 | background-color: #B7E3EC;
224 | color: #FFF;
225 | border-radius: 3px;
226 | box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24);
227 | margin-right: 0.7rem;
228 | }
229 |
230 | .view .columns.dates {
231 | border-radius: 3px;
232 | box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24);
233 | margin-right:0.7rem;
234 | background-color:#DCE47E;
235 | color: #fff;
236 | }
237 |
238 | .view .columns.booleans {
239 | border-radius: 3px;
240 | box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24);
241 | margin-right:0.7rem;
242 | background-color: #8D6E65;
243 | color: #fff;
244 | }
245 |
246 | .view .strings p {
247 | border-bottom: 1px solid #eee;
248 | }
249 | .view .numbers .subheader, .view .dates .subheader {
250 | color:#747474;
251 | }
252 | .view .booleans .subheader {
253 | color: #E9E9E9
254 | }
255 |
256 | .view .texts .columns {
257 | margin-top:1.2rem;
258 | border-bottom: 1px solid #eee;
259 | }
260 |
261 |
262 | /** Notices and Errors **/
263 | .cake-error,
264 | .cake-debug,
265 | .notice,
266 | p.error,
267 | p.notice {
268 | display: block;
269 | clear: both;
270 | background-repeat: repeat-x;
271 | margin-bottom: 18px;
272 | padding: 7px 14px;
273 | border-radius: 3px;
274 | box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24);
275 | }
276 |
277 | .cake-debug,
278 | .notice,
279 | p.notice {
280 | color: #000000;
281 | background: #ffcc00;
282 | }
283 |
284 | .cake-error,
285 | p.error {
286 | color: #fff;
287 | background: #C3232D;
288 | }
289 |
290 | pre {
291 | background: none repeat scroll 0% 0% #FFF;
292 | box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24);
293 | margin: 15px 0px;
294 | color: rgba(0, 0 ,0 , 0.74);
295 | padding:5px;
296 | }
297 |
298 | .cake-error .cake-stack-trace {
299 | margin-top:10px;
300 | }
301 |
302 | .cake-stack-trace code {
303 | background: inherit;
304 | border:0;
305 | }
306 |
307 | .cake-code-dump .code-highlight {
308 | display: block;
309 | background-color: #FFC600;
310 | }
311 |
312 | .cake-error a,
313 | .cake-error a:hover {
314 | color:#fff;
315 | text-decoration: underline;
316 | }
317 |
318 | .home header {
319 | width: 100%;
320 | height: 85%;
321 | position: relative;
322 | display: table;
323 | }
324 |
325 | .home h1 {
326 | font-family: "Gill Sans MT", Calibri, sans-serif;
327 | }
328 |
329 | .home header .header-image {
330 | display: table-cell;
331 | vertical-align: middle;
332 | text-align: center;
333 | }
334 |
335 | .home header h1 {
336 | color: #fff;
337 | }
338 |
339 | .home .checks {
340 | padding:30px;
341 | color: #626262;
342 | border-radius: 3px;
343 | box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.24);
344 | margin-top:50px;
345 | }
346 |
347 | .checks.platform {
348 | background-color: #B7E3EC;
349 | }
350 |
351 | .checks.filesystem {
352 | background: #DCE47E;
353 | }
354 |
355 | .checks.database {
356 | background-color: #DFF0D8;
357 | padding-bottom: 10px;
358 | margin-bottom: 30px;
359 | }
360 |
361 | .home .checks .success:before, .home .checks .problem:before {
362 | line-height: 0px;
363 | font-size: 28px;
364 | height: 12px;
365 | width: 12px;
366 | border-radius: 15px;
367 | text-align: center;
368 | vertical-align: middle;
369 | display: inline-block;
370 | position: relative;
371 | left: -11px;
372 | }
373 |
374 | .home .checks .success:before {
375 | content: "✓";
376 | color: green;
377 | margin-right: 9px;
378 | }
379 |
380 | .home .checks .problem:before {
381 | content: "✘";
382 | color: red;
383 | margin-right: 9px;
384 | }
385 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cakephp-3-acl-example
2 | A very simple CakePHP 3 ACL plugin usage example. This example is based on [Simple Acl controlled Application](http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html) for CakePHP 2. The differences are described in this document. The files in this repository contain the changes and implementations of functions discuessed below.
3 |
4 | ### Getting started
5 | - Assuming you are using [composer](https://getcomposer.org/), get a copy of the latest cakephp release by running `composer create-project --prefer-dist cakephp/app acl-example`. This will create an empty CakePHP project in the `acl-example` directory. Answer YES when asked if folder permissions should be set.
6 | - Navigate to the CakePHP project directory (`acl-example` in this case) `cd acl-example`
7 | - Install the [CakePHP ACL plugin](https://github.com/cakephp/acl) by running `composer require cakephp/acl`
8 | - Include the ACL plugin in `app/config/bootstrap.php`
9 |
10 | ```php
11 | Plugin::load('Acl', ['bootstrap' => true]);
12 | ```
13 |
14 | ###Example schema
15 | An example schema taken from the CakePHP 2 ACL tutorial:
16 | ```sql
17 | CREATE TABLE users (
18 | id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
19 | username VARCHAR(255) NOT NULL UNIQUE,
20 | password CHAR(60) NOT NULL,
21 | group_id INT(11) NOT NULL,
22 | created DATETIME,
23 | modified DATETIME
24 | );
25 |
26 | CREATE TABLE groups (
27 | id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
28 | name VARCHAR(100) NOT NULL,
29 | created DATETIME,
30 | modified DATETIME
31 | );
32 |
33 | CREATE TABLE posts (
34 | id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
35 | user_id INT(11) NOT NULL,
36 | title VARCHAR(255) NOT NULL,
37 | body TEXT,
38 | created DATETIME,
39 | modified DATETIME
40 | );
41 |
42 | CREATE TABLE widgets (
43 | id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
44 | name VARCHAR(100) NOT NULL,
45 | part_no VARCHAR(12),
46 | quantity INT(11)
47 | );
48 | ```
49 | After the schema is created, proceed to "bake" the application.
50 |
51 | ```bash
52 | bin/cake bake all groups
53 | bin/cake bake all users
54 | bin/cake bake all posts
55 | bin/cake bake all widgets
56 | ```
57 |
58 | ### Preparing to Add Auth
59 | Add `UsersController::login` function
60 | ```php
61 | public function login() {
62 | if ($this->request->is('post')) {
63 | $user = $this->Auth->identify();
64 | if ($user) {
65 | $this->Auth->setUser($user);
66 | return $this->redirect($this->Auth->redirectUrl());
67 | }
68 | $this->Flash->error(__('Your username or password was incorrect.'));
69 | }
70 | }
71 | ```
72 | Add `UsersController::logout` function
73 | ```php
74 | public function logout() {
75 | $this->Flash->success(__('Good-Bye'));
76 | $this->redirect($this->Auth->logout());
77 | }
78 | ```
79 | Add `src/Templates/Users/login.ctp`
80 | ```php
81 | = $this->Form->create() ?>
82 |
83 | = __('Login') ?>
84 | = $this->Form->input('username') ?>
85 | = $this->Form->input('password') ?>
86 | = $this->Form->submit(__('Login')) ?>
87 |
88 | = $this->Form->end() ?>
89 | ```
90 | Modify `UsersTable::beforeSave` to hash the password before saving
91 | ```php
92 | use Cake\Auth\DefaultPasswordHasher;
93 | ...
94 | public function beforeSave(\Cake\Event\Event $event, \Cake\ORM\Entity $entity,
95 | \ArrayObject $options)
96 | {
97 | $hasher = new DefaultPasswordHasher;
98 | $entity->password = $hasher->hash($entity->password);
99 | return true;
100 | }
101 | ```
102 | Include and configure the `AuthComponent` and the `AclComponent` in the `AppController`
103 | ```php
104 | public $components = [
105 | 'Acl' => [
106 | 'className' => 'Acl.Acl'
107 | ]
108 | ];
109 | ...
110 | $this->loadComponent('Auth', [
111 | 'authorize' => [
112 | 'Acl.Actions' => ['actionPath' => 'controllers/']
113 | ],
114 | 'loginAction' => [
115 | 'plugin' => false,
116 | 'controller' => 'Users',
117 | 'action' => 'login'
118 | ],
119 | 'loginRedirect' => [
120 | 'plugin' => false,
121 | 'controller' => 'Posts',
122 | 'action' => 'index'
123 | ],
124 | 'logoutRedirect' => [
125 | 'plugin' => false,
126 | 'controller' => 'Users',
127 | 'action' => 'login'
128 | ],
129 | 'unauthorizedRedirect' => [
130 | 'controller' => 'Users',
131 | 'action' => 'login',
132 | 'prefix' => false
133 | ],
134 | 'authError' => 'You are not authorized to access that location.',
135 | 'flash' => [
136 | 'element' => 'error'
137 | ]
138 | ]);
139 | ```
140 |
141 | ### Add Temporary Auth Overrides
142 | Temporarily allow access to `UsersController` and `GroupsController` so groups and users can be added. Add the following implementation of `beforeFilter` to `src/Controllers/UsersController.php` and `src/Controllers/GroupsController.php`:
143 | ```php
144 | public function initialize()
145 | {
146 | parent::initialize();
147 |
148 | $this->Auth->allow();
149 | }
150 | ```
151 |
152 | ### Initialize the Db Acl tables
153 | - Create the ACL related tables by running `bin/cake Migrations.migrations migrate -p Acl`
154 |
155 | ### Model Setup
156 | #### Acting as a requester
157 | - Add the requester behavior to `GroupsTable` and `UsersTable`
158 | - Add `$this->addBehavior('Acl.Acl', ['type' => 'requester']);` to the `initialize` function in the files `src/Model/Table/UsersTable.php` and `src/Model/Table/GroupsTable.php`
159 |
160 |
161 | #### Implement `parentNode` function in `Group` entity
162 | Add the following implementation of `parentNode` to the file `src/Model/Entity/Group.php`:
163 | ```php
164 | public function parentNode()
165 | {
166 | return null;
167 | }
168 | ```
169 |
170 | #### Implement `parentNode` function in `User` entity
171 | Add the following implementation of `parentNode` to the file `src/Model/Entity/User.php`:
172 | ```php
173 | public function parentNode()
174 | {
175 | if (!$this->id) {
176 | return null;
177 | }
178 | if (isset($this->group_id)) {
179 | $groupId = $this->group_id;
180 | } else {
181 | $Users = TableRegistry::get('Users');
182 | $user = $Users->find('all', ['fields' => ['group_id']])->where(['id' => $this->id])->first();
183 | $groupId = $user->group_id;
184 | }
185 | if (!$groupId) {
186 | return null;
187 | }
188 | return ['Groups' => ['id' => $groupId]];
189 | }
190 | ```
191 |
192 | ### Creating ACOs
193 | The [ACL Extras](https://github.com/markstory/acl_extras/) plugin referred to in the CakePHP 2 ACL tutorial is now integrated into the [CakePHP ACL plugin](https://github.com/cakephp/acl) for CakePHP 3.
194 | - Run `bin/cake acl_extras aco_sync` to automatically create ACOs.
195 | - ACOs and AROs can be managed manually using the ACL shell. Run `bin/cake acl` for more information.
196 |
197 | ### Creating Users and Groups
198 | #### Create Groups
199 | - Navigate to `/groups/add` and add the groups
200 | - For this example, we will create `Administrator`, `Manager`, and `User`
201 |
202 | #### Create Users
203 | - Navigate to `/users/add` and add the users
204 | - For this example, we will create one user in each group
205 | - `test-administrator` is an `Administrator`
206 | - `test-manager` is a `Manager`
207 | - `test-user` is a `User`
208 |
209 | ### Remove Temporary Auth Overrides
210 | Remove the temporary auth overrides by removing the `beforeFilter` function or the call to `$this->Auth->allow();` in `src/Controllers/UsersController.php` and `src/Controllers/GroupsController.php`.
211 |
212 | ### Configuring Permissions
213 | #### Configuring permissions using the ACL shell
214 | First, find the IDs of each group you want to grant permissions on. There are several ways of doing this. Since we will be at the console anyway, the quickest way is probably to run `bin/cake acl view aro` to view the ARO tree. In this example, we will assume the `Administrator`, `Manager`, and `User` groups have IDs 1, 2, and 3 respectively.
215 | - Grant members of the `Administrator` group permission to everything
216 | - Run `bin/cake acl grant Groups.1 controllers`
217 | - Grant members of the `Manager` group permission to all actions in `Posts` and `Widgets`
218 | - Run `bin/cake acl deny Groups.2 controllers`
219 | - Run `bin/cake acl grant Groups.2 controllers/Posts`
220 | - Run `bin/cake acl grant Groups.2 controllers/Widgets`
221 | - Grant members of the `User` group permission to view `Posts` and `Widgets`
222 | - Run `bin/cake acl deny Groups.3 controllers`
223 | - Run `bin/cake acl grant Groups.3 controllers/Posts/index`
224 | - Run `bin/cake acl grant Groups.3 controllers/Posts/view`
225 | - Run `bin/cake acl grant Groups.3 controllers/Widgets/index`
226 | - Run `bin/cake acl grant Groups.3 controllers/Widgets/view`
227 | - Allow all groups to logout
228 | - Run `bin/cake acl grant Groups.2 controllers/Users/logout`
229 | - Run `bin/cake acl grant Groups.3 controllers/Users/logout`
230 |
--------------------------------------------------------------------------------
/src/Template/Pages/home.ctp:
--------------------------------------------------------------------------------
1 | layout = false;
22 |
23 | if (!Configure::read('debug')):
24 | throw new NotFoundException();
25 | endif;
26 |
27 | $cakeDescription = 'CakePHP: the rapid development php framework';
28 | ?>
29 |
30 |
31 |
32 | = $this->Html->charset() ?>
33 |
34 |
35 | = $cakeDescription ?>
36 |
37 | = $this->Html->meta('icon') ?>
38 | = $this->Html->css('base.css') ?>
39 | = $this->Html->css('cake.css') ?>
40 |
41 |
42 |
48 |
49 |
50 |
51 | URL rewriting is not properly configured on your server.
52 | 1) Help me configure it
53 | 2) I don't / can't use URL rewriting
54 |
55 |
56 |
57 |
84 |
85 |
86 |
Your tmp directory is writable.
87 |
88 |
Your tmp directory is NOT writable.
89 |
90 |
91 |
92 |
Your logs directory is writable.
93 |
94 |
Your logs directory is NOT writable.
95 |
96 |
97 |
98 |
99 |
The = $settings['className'] ?>Engine is being used for core caching. To change the config edit config/app.php
100 |
101 |
Your cache is NOT working. Please check the settings in config/app.php
102 |
103 |
104 |
105 |
106 |
107 | connect();
111 | } catch (Exception $connectionError) {
112 | $connected = false;
113 | $errorMsg = $connectionError->getMessage();
114 | if (method_exists($connectionError, 'getAttributes')):
115 | $attributes = $connectionError->getAttributes();
116 | if (isset($errorMsg['message'])):
117 | $errorMsg .= '
' . $attributes['message'];
118 | endif;
119 | endif;
120 | }
121 | ?>
122 |
123 |
CakePHP is able to connect to the database.
124 |
125 |
CakePHP is NOT able to connect to the database. = $errorMsg ?>
126 |
127 |
128 |
129 |
130 |
131 |
Editing this Page
132 |
133 | To change the content of this page, edit: src/Template/Pages/home.ctp.
134 | You can also add some CSS styles for your pages at: webroot/css/.
135 |
136 |
137 |
138 |
Getting Started
139 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
More about Cake
152 |
153 | CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Front Controller and MVC.
154 |
155 |
156 | Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.
157 |
158 |
159 |
181 |
182 |
183 |
184 |
186 |
187 |
188 |
--------------------------------------------------------------------------------
/config/app.default.php:
--------------------------------------------------------------------------------
1 | true,
13 |
14 | /**
15 | * Configure basic information about the application.
16 | *
17 | * - namespace - The namespace to find app classes under.
18 | * - encoding - The encoding used for HTML + database connections.
19 | * - base - The base directory the app resides in. If false this
20 | * will be auto detected.
21 | * - dir - Name of app directory.
22 | * - webroot - The webroot directory.
23 | * - wwwRoot - The file path to webroot.
24 | * - baseUrl - To configure CakePHP to *not* use mod_rewrite and to
25 | * use CakePHP pretty URLs, remove these .htaccess
26 | * files:
27 | * /.htaccess
28 | * /webroot/.htaccess
29 | * And uncomment the baseUrl key below.
30 | * - fullBaseUrl - A base URL to use for absolute links.
31 | * - imageBaseUrl - Web path to the public images directory under webroot.
32 | * - cssBaseUrl - Web path to the public css directory under webroot.
33 | * - jsBaseUrl - Web path to the public js directory under webroot.
34 | * - paths - Configure paths for non class based resources. Supports the
35 | * `plugins`, `templates`, `locales` subkeys, which allow the definition of
36 | * paths for plugins, view templates and locale files respectively.
37 | */
38 | 'App' => [
39 | 'namespace' => 'App',
40 | 'encoding' => 'UTF-8',
41 | 'base' => false,
42 | 'dir' => 'src',
43 | 'webroot' => 'webroot',
44 | 'wwwRoot' => WWW_ROOT,
45 | // 'baseUrl' => env('SCRIPT_NAME'),
46 | 'fullBaseUrl' => false,
47 | 'imageBaseUrl' => 'img/',
48 | 'cssBaseUrl' => 'css/',
49 | 'jsBaseUrl' => 'js/',
50 | 'paths' => [
51 | 'plugins' => [ROOT . DS . 'plugins' . DS],
52 | 'templates' => [APP . 'Template' . DS],
53 | 'locales' => [APP . 'Locale' . DS],
54 | ],
55 | ],
56 |
57 | /**
58 | * Security and encryption configuration
59 | *
60 | * - salt - A random string used in security hashing methods.
61 | * The salt value is also used as the encryption key.
62 | * You should treat it as extremely sensitive data.
63 | */
64 | 'Security' => [
65 | 'salt' => '__SALT__',
66 | ],
67 |
68 | /**
69 | * Apply timestamps with the last modified time to static assets (js, css, images).
70 | * Will append a querystring parameter containing the time the file was modified.
71 | * This is useful for busting browser caches.
72 | *
73 | * Set to true to apply timestamps when debug is true. Set to 'force' to always
74 | * enable timestamping regardless of debug value.
75 | */
76 | 'Asset' => [
77 | // 'timestamp' => true,
78 | ],
79 |
80 | /**
81 | * Configure the cache adapters.
82 | */
83 | 'Cache' => [
84 | 'default' => [
85 | 'className' => 'File',
86 | 'path' => CACHE,
87 | ],
88 |
89 | /**
90 | * Configure the cache used for general framework caching. Path information,
91 | * object listings, and translation cache files are stored with this
92 | * configuration.
93 | */
94 | '_cake_core_' => [
95 | 'className' => 'File',
96 | 'prefix' => 'myapp_cake_core_',
97 | 'path' => CACHE . 'persistent/',
98 | 'serialize' => true,
99 | 'duration' => '+2 minutes',
100 | ],
101 |
102 | /**
103 | * Configure the cache for model and datasource caches. This cache
104 | * configuration is used to store schema descriptions, and table listings
105 | * in connections.
106 | */
107 | '_cake_model_' => [
108 | 'className' => 'File',
109 | 'prefix' => 'myapp_cake_model_',
110 | 'path' => CACHE . 'models/',
111 | 'serialize' => true,
112 | 'duration' => '+2 minutes',
113 | ],
114 | ],
115 |
116 | /**
117 | * Configure the Error and Exception handlers used by your application.
118 | *
119 | * By default errors are displayed using Debugger, when debug is true and logged
120 | * by Cake\Log\Log when debug is false.
121 | *
122 | * In CLI environments exceptions will be printed to stderr with a backtrace.
123 | * In web environments an HTML page will be displayed for the exception.
124 | * With debug true, framework errors like Missing Controller will be displayed.
125 | * When debug is false, framework errors will be coerced into generic HTTP errors.
126 | *
127 | * Options:
128 | *
129 | * - `errorLevel` - int - The level of errors you are interested in capturing.
130 | * - `trace` - boolean - Whether or not backtraces should be included in
131 | * logged errors/exceptions.
132 | * - `log` - boolean - Whether or not you want exceptions logged.
133 | * - `exceptionRenderer` - string - The class responsible for rendering
134 | * uncaught exceptions. If you choose a custom class you should place
135 | * the file for that class in src/Error. This class needs to implement a
136 | * render method.
137 | * - `skipLog` - array - List of exceptions to skip for logging. Exceptions that
138 | * extend one of the listed exceptions will also be skipped for logging.
139 | * E.g.:
140 | * `'skipLog' => ['Cake\Network\Exception\NotFoundException', 'Cake\Network\Exception\UnauthorizedException']`
141 | */
142 | 'Error' => [
143 | 'errorLevel' => E_ALL & ~E_DEPRECATED,
144 | 'exceptionRenderer' => 'Cake\Error\ExceptionRenderer',
145 | 'skipLog' => [],
146 | 'log' => true,
147 | 'trace' => true,
148 | ],
149 |
150 | /**
151 | * Email configuration.
152 | *
153 | * By defining transports separately from delivery profiles you can easily
154 | * re-use transport configuration across multiple profiles.
155 | *
156 | * You can specify multiple configurations for production, development and
157 | * testing.
158 | *
159 | * Each transport needs a `className`. Valid options are as follows:
160 | *
161 | * Mail - Send using PHP mail function
162 | * Smtp - Send using SMTP
163 | * Debug - Do not send the email, just return the result
164 | *
165 | * You can add custom transports (or override existing transports) by adding the
166 | * appropriate file to src/Network/Email. Transports should be named
167 | * 'YourTransport.php', where 'Your' is the name of the transport.
168 | */
169 | 'EmailTransport' => [
170 | 'default' => [
171 | 'className' => 'Mail',
172 | // The following keys are used in SMTP transports
173 | 'host' => 'localhost',
174 | 'port' => 25,
175 | 'timeout' => 30,
176 | 'username' => 'user',
177 | 'password' => 'secret',
178 | 'client' => null,
179 | 'tls' => null,
180 | ],
181 | ],
182 |
183 | /**
184 | * Email delivery profiles
185 | *
186 | * Delivery profiles allow you to predefine various properties about email
187 | * messages from your application and give the settings a name. This saves
188 | * duplication across your application and makes maintenance and development
189 | * easier. Each profile accepts a number of keys. See `Cake\Network\Email\Email`
190 | * for more information.
191 | */
192 | 'Email' => [
193 | 'default' => [
194 | 'transport' => 'default',
195 | 'from' => 'you@localhost',
196 | //'charset' => 'utf-8',
197 | //'headerCharset' => 'utf-8',
198 | ],
199 | ],
200 |
201 | /**
202 | * Connection information used by the ORM to connect
203 | * to your application's datastores.
204 | * Drivers include Mysql Postgres Sqlite Sqlserver
205 | * See vendor\cakephp\cakephp\src\Database\Driver for complete list
206 | */
207 | 'Datasources' => [
208 | 'default' => [
209 | 'className' => 'Cake\Database\Connection',
210 | 'driver' => 'Cake\Database\Driver\Mysql',
211 | 'persistent' => false,
212 | 'host' => 'localhost',
213 | /**
214 | * CakePHP will use the default DB port based on the driver selected
215 | * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
216 | * the following line and set the port accordingly
217 | */
218 | //'port' => 'nonstandard_port_number',
219 | 'username' => 'my_app',
220 | 'password' => 'secret',
221 | 'database' => 'my_app',
222 | 'encoding' => 'utf8',
223 | 'timezone' => 'UTC',
224 | 'cacheMetadata' => true,
225 |
226 | /**
227 | * Set identifier quoting to true if you are using reserved words or
228 | * special characters in your table or column names. Enabling this
229 | * setting will result in queries built using the Query Builder having
230 | * identifiers quoted when creating SQL. It should be noted that this
231 | * decreases performance because each query needs to be traversed and
232 | * manipulated before being executed.
233 | */
234 | 'quoteIdentifiers' => false,
235 |
236 | /**
237 | * During development, if using MySQL < 5.6, uncommenting the
238 | * following line could boost the speed at which schema metadata is
239 | * fetched from the database. It can also be set directly with the
240 | * mysql configuration directive 'innodb_stats_on_metadata = 0'
241 | * which is the recommended value in production environments
242 | */
243 | //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
244 | ],
245 |
246 | /**
247 | * The test connection is used during the test suite.
248 | */
249 | 'test' => [
250 | 'className' => 'Cake\Database\Connection',
251 | 'driver' => 'Cake\Database\Driver\Mysql',
252 | 'persistent' => false,
253 | 'host' => 'localhost',
254 | //'port' => 'nonstandard_port_number',
255 | 'username' => 'my_app',
256 | 'password' => 'secret',
257 | 'database' => 'test_myapp',
258 | 'encoding' => 'utf8',
259 | 'timezone' => 'UTC',
260 | 'cacheMetadata' => true,
261 | 'quoteIdentifiers' => false,
262 | //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
263 | ],
264 | ],
265 |
266 | /**
267 | * Configures logging options
268 | */
269 | 'Log' => [
270 | 'debug' => [
271 | 'className' => 'Cake\Log\Engine\FileLog',
272 | 'path' => LOGS,
273 | 'file' => 'debug',
274 | 'levels' => ['notice', 'info', 'debug'],
275 | ],
276 | 'error' => [
277 | 'className' => 'Cake\Log\Engine\FileLog',
278 | 'path' => LOGS,
279 | 'file' => 'error',
280 | 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
281 | ],
282 | ],
283 |
284 | /**
285 | * Session configuration.
286 | *
287 | * Contains an array of settings to use for session configuration. The
288 | * `defaults` key is used to define a default preset to use for sessions, any
289 | * settings declared here will override the settings of the default config.
290 | *
291 | * ## Options
292 | *
293 | * - `cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'.
294 | * - `cookiePath` - The url path for which session cookie is set. Maps to the
295 | * `session.cookie_path` php.ini config. Defaults to base path of app.
296 | * - `timeout` - The time in minutes the session should be valid for.
297 | * Pass 0 to disable checking timeout.
298 | * Please note that php.ini's session.gc_maxlifetime must be equal to or greater
299 | * than the largest Session['timeout'] in all served websites for it to have the
300 | * desired effect.
301 | * - `defaults` - The default configuration set to use as a basis for your session.
302 | * There are four built-in options: php, cake, cache, database.
303 | * - `handler` - Can be used to enable a custom session handler. Expects an
304 | * array with at least the `engine` key, being the name of the Session engine
305 | * class to use for managing the session. CakePHP bundles the `CacheSession`
306 | * and `DatabaseSession` engines.
307 | * - `ini` - An associative array of additional ini values to set.
308 | *
309 | * The built-in `defaults` options are:
310 | *
311 | * - 'php' - Uses settings defined in your php.ini.
312 | * - 'cake' - Saves session files in CakePHP's /tmp directory.
313 | * - 'database' - Uses CakePHP's database sessions.
314 | * - 'cache' - Use the Cache class to save sessions.
315 | *
316 | * To define a custom session handler, save it at src/Network/Session/.php.
317 | * Make sure the class implements PHP's `SessionHandlerInterface` and set
318 | * Session.handler to
319 | *
320 | * To use database sessions, load the SQL file located at config/Schema/sessions.sql
321 | */
322 | 'Session' => [
323 | 'defaults' => 'php',
324 | ],
325 | ];
326 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "f3f3edc148d3456315dc6ef7b5ab3a76",
8 | "content-hash": "57453b94b1978121b769f119a370b9d3",
9 | "packages": [
10 | {
11 | "name": "aura/installer-default",
12 | "version": "1.0.0",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/auraphp/installer-default.git",
16 | "reference": "52f8de3670cc1ef45a916f40f732937436d028c8"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/auraphp/installer-default/zipball/52f8de3670cc1ef45a916f40f732937436d028c8",
21 | "reference": "52f8de3670cc1ef45a916f40f732937436d028c8",
22 | "shasum": ""
23 | },
24 | "type": "composer-installer",
25 | "extra": {
26 | "class": "Aura\\Composer\\DefaultInstaller"
27 | },
28 | "autoload": {
29 | "psr-0": {
30 | "Aura\\Composer\\": "src/"
31 | }
32 | },
33 | "notification-url": "https://packagist.org/downloads/",
34 | "license": [
35 | "BSD-2-Clause"
36 | ],
37 | "authors": [
38 | {
39 | "name": "Paul M. Jones",
40 | "email": "pmjones88@gmail.com",
41 | "homepage": "http://paul-m-jones.com"
42 | }
43 | ],
44 | "description": "Installs Aura packages using the Composer defaults.",
45 | "keywords": [
46 | "aura",
47 | "installer"
48 | ],
49 | "time": "2012-11-26 21:35:57"
50 | },
51 | {
52 | "name": "aura/intl",
53 | "version": "1.1.1",
54 | "source": {
55 | "type": "git",
56 | "url": "https://github.com/auraphp/Aura.Intl.git",
57 | "reference": "c5fe620167550ad6fa77dd3570fba2efc77a2a21"
58 | },
59 | "dist": {
60 | "type": "zip",
61 | "url": "https://api.github.com/repos/auraphp/Aura.Intl/zipball/c5fe620167550ad6fa77dd3570fba2efc77a2a21",
62 | "reference": "c5fe620167550ad6fa77dd3570fba2efc77a2a21",
63 | "shasum": ""
64 | },
65 | "require": {
66 | "aura/installer-default": "1.0.*",
67 | "php": ">=5.4.0"
68 | },
69 | "type": "aura-package",
70 | "extra": {
71 | "aura": {
72 | "type": "library",
73 | "config": {
74 | "common": "Aura\\Intl\\_Config\\Common"
75 | }
76 | },
77 | "branch-alias": {
78 | "dev-develop": "1.1.x-dev"
79 | }
80 | },
81 | "autoload": {
82 | "psr-0": {
83 | "Aura\\Intl": "src/"
84 | },
85 | "psr-4": {
86 | "Aura\\Intl\\_Config\\": "config/"
87 | }
88 | },
89 | "notification-url": "https://packagist.org/downloads/",
90 | "license": [
91 | "BSD-2-Clause"
92 | ],
93 | "authors": [
94 | {
95 | "name": "Paul M. Jones",
96 | "email": "pmjones88@gmail.com",
97 | "homepage": "http://paul-m-jones.com"
98 | },
99 | {
100 | "name": "Aura.Intl Contributors",
101 | "homepage": "https://github.com/auraphp/Aura.Intl/contributors"
102 | },
103 | {
104 | "name": "Pascal Borreli",
105 | "email": "pascal@borreli.com"
106 | },
107 | {
108 | "name": "Mapthegod",
109 | "email": "mapthegod@gmail.com"
110 | },
111 | {
112 | "name": "Jose Lorenzo Rodriguez",
113 | "email": "jose.zap@gmail.com"
114 | }
115 | ],
116 | "description": "The Aura.Intl package provides internationalization (I18N) tools, specifically\npackage-oriented per-locale message translation.",
117 | "homepage": "http://auraphp.com/Aura.Intl",
118 | "keywords": [
119 | "g11n",
120 | "globalization",
121 | "i18n",
122 | "internationalization",
123 | "intl",
124 | "l10n",
125 | "localization"
126 | ],
127 | "time": "2014-08-24 00:00:00"
128 | },
129 | {
130 | "name": "cakephp/acl",
131 | "version": "dev-master",
132 | "source": {
133 | "type": "git",
134 | "url": "https://github.com/cakephp/acl.git",
135 | "reference": "9b9808e14cb07ac45b40cf957c7eec177813c567"
136 | },
137 | "dist": {
138 | "type": "zip",
139 | "url": "https://api.github.com/repos/cakephp/acl/zipball/9b9808e14cb07ac45b40cf957c7eec177813c567",
140 | "reference": "9b9808e14cb07ac45b40cf957c7eec177813c567",
141 | "shasum": ""
142 | },
143 | "require": {
144 | "cakephp/cakephp": "^3.1.0"
145 | },
146 | "require-dev": {
147 | "cakephp/cakephp-codesniffer": "^2.0",
148 | "phpunit/phpunit": ">= 4.2"
149 | },
150 | "type": "cakephp-plugin",
151 | "autoload": {
152 | "psr-4": {
153 | "Acl\\": "src"
154 | }
155 | },
156 | "notification-url": "https://packagist.org/downloads/",
157 | "license": [
158 | "MIT"
159 | ],
160 | "authors": [
161 | {
162 | "name": "CakePHP Community",
163 | "homepage": "https://github.com/cakephp/acl/graphs/contributors"
164 | }
165 | ],
166 | "description": "Acl Plugin for CakePHP 3.x framework",
167 | "homepage": "http://cakephp.org",
168 | "keywords": [
169 | "acl",
170 | "cakephp"
171 | ],
172 | "time": "2016-05-24 00:02:18"
173 | },
174 | {
175 | "name": "cakephp/cakephp",
176 | "version": "3.2.11",
177 | "source": {
178 | "type": "git",
179 | "url": "https://github.com/cakephp/cakephp.git",
180 | "reference": "2c1463f4f80ec138f65a87a9c7d95d466a051e6f"
181 | },
182 | "dist": {
183 | "type": "zip",
184 | "url": "https://api.github.com/repos/cakephp/cakephp/zipball/2c1463f4f80ec138f65a87a9c7d95d466a051e6f",
185 | "reference": "2c1463f4f80ec138f65a87a9c7d95d466a051e6f",
186 | "shasum": ""
187 | },
188 | "require": {
189 | "aura/intl": "1.1.*",
190 | "cakephp/chronos": "*",
191 | "ext-intl": "*",
192 | "ext-mbstring": "*",
193 | "php": ">=5.5.9",
194 | "psr/log": "1.0"
195 | },
196 | "replace": {
197 | "cakephp/cache": "self.version",
198 | "cakephp/collection": "self.version",
199 | "cakephp/core": "self.version",
200 | "cakephp/database": "self.version",
201 | "cakephp/datasource": "self.version",
202 | "cakephp/event": "self.version",
203 | "cakephp/filesystem": "self.version",
204 | "cakephp/i18n": "self.version",
205 | "cakephp/log": "self.version",
206 | "cakephp/orm": "self.version",
207 | "cakephp/utility": "self.version",
208 | "cakephp/validation": "self.version"
209 | },
210 | "require-dev": {
211 | "cakephp/cakephp-codesniffer": "dev-master",
212 | "phpunit/phpunit": "*"
213 | },
214 | "suggest": {
215 | "ext-openssl": "To use Security::encrypt() or have secure CSRF token generation."
216 | },
217 | "type": "library",
218 | "autoload": {
219 | "psr-4": {
220 | "Cake\\": "src"
221 | },
222 | "files": [
223 | "src/Core/functions.php",
224 | "src/Collection/functions.php",
225 | "src/I18n/functions.php",
226 | "src/Utility/bootstrap.php"
227 | ]
228 | },
229 | "notification-url": "https://packagist.org/downloads/",
230 | "license": [
231 | "MIT"
232 | ],
233 | "authors": [
234 | {
235 | "name": "CakePHP Community",
236 | "homepage": "https://github.com/cakephp/cakephp/graphs/contributors"
237 | }
238 | ],
239 | "description": "The CakePHP framework",
240 | "homepage": "http://cakephp.org",
241 | "keywords": [
242 | "framework"
243 | ],
244 | "time": "2016-06-21 03:01:37"
245 | },
246 | {
247 | "name": "cakephp/chronos",
248 | "version": "0.4.11",
249 | "source": {
250 | "type": "git",
251 | "url": "https://github.com/cakephp/chronos.git",
252 | "reference": "39db65d38488d6edd88bab5f33e19b1205ceeeda"
253 | },
254 | "dist": {
255 | "type": "zip",
256 | "url": "https://api.github.com/repos/cakephp/chronos/zipball/39db65d38488d6edd88bab5f33e19b1205ceeeda",
257 | "reference": "39db65d38488d6edd88bab5f33e19b1205ceeeda",
258 | "shasum": ""
259 | },
260 | "require": {
261 | "php": ">=5.5.9"
262 | },
263 | "require-dev": {
264 | "athletic/athletic": "~0.1",
265 | "cakephp/cakephp-codesniffer": "dev-master",
266 | "phpunit/phpunit": "*"
267 | },
268 | "type": "library",
269 | "autoload": {
270 | "psr-4": {
271 | "Cake\\Chronos\\": "src"
272 | },
273 | "files": [
274 | "src/carbon_compat.php"
275 | ]
276 | },
277 | "notification-url": "https://packagist.org/downloads/",
278 | "license": [
279 | "MIT"
280 | ],
281 | "authors": [
282 | {
283 | "name": "Brian Nesbitt",
284 | "email": "brian@nesbot.com",
285 | "homepage": "http://nesbot.com"
286 | },
287 | {
288 | "name": "The CakePHP Team",
289 | "homepage": "http://cakephp.org"
290 | }
291 | ],
292 | "description": "A simple API extension for DateTime.",
293 | "homepage": "http://cakephp.org",
294 | "keywords": [
295 | "date",
296 | "datetime",
297 | "time"
298 | ],
299 | "time": "2016-06-15 06:26:37"
300 | },
301 | {
302 | "name": "cakephp/migrations",
303 | "version": "1.6.3",
304 | "source": {
305 | "type": "git",
306 | "url": "https://github.com/cakephp/migrations.git",
307 | "reference": "b683daebb6d0f0ea41546b14f8a9ea591cebedfd"
308 | },
309 | "dist": {
310 | "type": "zip",
311 | "url": "https://api.github.com/repos/cakephp/migrations/zipball/b683daebb6d0f0ea41546b14f8a9ea591cebedfd",
312 | "reference": "b683daebb6d0f0ea41546b14f8a9ea591cebedfd",
313 | "shasum": ""
314 | },
315 | "require": {
316 | "cakephp/cakephp": "~3.1",
317 | "php": ">=5.4",
318 | "robmorgan/phinx": "0.5.3"
319 | },
320 | "require-dev": {
321 | "cakephp/bake": "@stable",
322 | "phpunit/phpunit": "*"
323 | },
324 | "suggest": {
325 | "cakephp/bake": "Required if you want to generate migrations."
326 | },
327 | "type": "cakephp-plugin",
328 | "autoload": {
329 | "psr-4": {
330 | "Migrations\\": "src"
331 | }
332 | },
333 | "notification-url": "https://packagist.org/downloads/",
334 | "license": [
335 | "MIT"
336 | ],
337 | "authors": [
338 | {
339 | "name": "CakePHP Community",
340 | "homepage": "https://github.com/cakephp/migrations/graphs/contributors"
341 | }
342 | ],
343 | "description": "Database Migration plugin for CakePHP 3.0 based on Phinx",
344 | "homepage": "https://github.com/cakephp/migrations",
345 | "keywords": [
346 | "cakephp",
347 | "migrations"
348 | ],
349 | "time": "2016-06-23 17:18:29"
350 | },
351 | {
352 | "name": "cakephp/plugin-installer",
353 | "version": "0.0.15",
354 | "source": {
355 | "type": "git",
356 | "url": "https://github.com/cakephp/plugin-installer.git",
357 | "reference": "8e84898b44df50e88b5109bb7d4d28de845e9bf8"
358 | },
359 | "dist": {
360 | "type": "zip",
361 | "url": "https://api.github.com/repos/cakephp/plugin-installer/zipball/8e84898b44df50e88b5109bb7d4d28de845e9bf8",
362 | "reference": "8e84898b44df50e88b5109bb7d4d28de845e9bf8",
363 | "shasum": ""
364 | },
365 | "require-dev": {
366 | "cakephp/cakephp-codesniffer": "dev-master",
367 | "composer/composer": "1.0.*@dev"
368 | },
369 | "type": "composer-installer",
370 | "extra": {
371 | "class": "Cake\\Composer\\Installer\\PluginInstaller"
372 | },
373 | "autoload": {
374 | "psr-4": {
375 | "Cake\\Composer\\": "src"
376 | }
377 | },
378 | "notification-url": "https://packagist.org/downloads/",
379 | "license": [
380 | "MIT"
381 | ],
382 | "authors": [
383 | {
384 | "name": "CakePHP Community",
385 | "homepage": "http://cakephp.org"
386 | }
387 | ],
388 | "description": "A composer installer for CakePHP 3.0+ plugins.",
389 | "time": "2016-04-28 03:01:34"
390 | },
391 | {
392 | "name": "mobiledetect/mobiledetectlib",
393 | "version": "2.8.22",
394 | "source": {
395 | "type": "git",
396 | "url": "https://github.com/serbanghita/Mobile-Detect.git",
397 | "reference": "53cddae0c272a478b24a4b5fb60d0f838caf70b6"
398 | },
399 | "dist": {
400 | "type": "zip",
401 | "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/53cddae0c272a478b24a4b5fb60d0f838caf70b6",
402 | "reference": "53cddae0c272a478b24a4b5fb60d0f838caf70b6",
403 | "shasum": ""
404 | },
405 | "require": {
406 | "php": ">=5.0.0"
407 | },
408 | "require-dev": {
409 | "codeclimate/php-test-reporter": "dev-master",
410 | "johnkary/phpunit-speedtrap": "~1.0@dev",
411 | "phpunit/phpunit": "*"
412 | },
413 | "type": "library",
414 | "autoload": {
415 | "classmap": [
416 | "Mobile_Detect.php"
417 | ],
418 | "psr-0": {
419 | "Detection": "namespaced/"
420 | }
421 | },
422 | "notification-url": "https://packagist.org/downloads/",
423 | "license": [
424 | "MIT"
425 | ],
426 | "authors": [
427 | {
428 | "name": "Serban Ghita",
429 | "email": "serbanghita@gmail.com",
430 | "homepage": "http://mobiledetect.net",
431 | "role": "Developer"
432 | }
433 | ],
434 | "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.",
435 | "homepage": "https://github.com/serbanghita/Mobile-Detect",
436 | "keywords": [
437 | "detect mobile devices",
438 | "mobile",
439 | "mobile detect",
440 | "mobile detector",
441 | "php mobile detect"
442 | ],
443 | "time": "2016-04-24 09:47:16"
444 | },
445 | {
446 | "name": "psr/log",
447 | "version": "1.0.0",
448 | "source": {
449 | "type": "git",
450 | "url": "https://github.com/php-fig/log.git",
451 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
452 | },
453 | "dist": {
454 | "type": "zip",
455 | "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
456 | "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
457 | "shasum": ""
458 | },
459 | "type": "library",
460 | "autoload": {
461 | "psr-0": {
462 | "Psr\\Log\\": ""
463 | }
464 | },
465 | "notification-url": "https://packagist.org/downloads/",
466 | "license": [
467 | "MIT"
468 | ],
469 | "authors": [
470 | {
471 | "name": "PHP-FIG",
472 | "homepage": "http://www.php-fig.org/"
473 | }
474 | ],
475 | "description": "Common interface for logging libraries",
476 | "keywords": [
477 | "log",
478 | "psr",
479 | "psr-3"
480 | ],
481 | "time": "2012-12-21 11:40:51"
482 | },
483 | {
484 | "name": "robmorgan/phinx",
485 | "version": "v0.5.3",
486 | "source": {
487 | "type": "git",
488 | "url": "https://github.com/robmorgan/phinx.git",
489 | "reference": "4e7fee7792f4bf3dbf55ee29001850ba26c86a88"
490 | },
491 | "dist": {
492 | "type": "zip",
493 | "url": "https://api.github.com/repos/robmorgan/phinx/zipball/4e7fee7792f4bf3dbf55ee29001850ba26c86a88",
494 | "reference": "4e7fee7792f4bf3dbf55ee29001850ba26c86a88",
495 | "shasum": ""
496 | },
497 | "require": {
498 | "php": ">=5.4",
499 | "symfony/config": "~2.8|~3.0",
500 | "symfony/console": "~2.8|~3.0",
501 | "symfony/yaml": "~2.8|~3.0"
502 | },
503 | "require-dev": {
504 | "phpunit/phpunit": "^3.7|^4.0|^5.0"
505 | },
506 | "bin": [
507 | "bin/phinx"
508 | ],
509 | "type": "library",
510 | "autoload": {
511 | "psr-4": {
512 | "Phinx\\": "src/Phinx"
513 | }
514 | },
515 | "notification-url": "https://packagist.org/downloads/",
516 | "license": [
517 | "MIT"
518 | ],
519 | "authors": [
520 | {
521 | "name": "Rob Morgan",
522 | "email": "robbym@gmail.com",
523 | "homepage": "http://robmorgan.id.au",
524 | "role": "Lead Developer"
525 | },
526 | {
527 | "name": "Woody Gilk",
528 | "email": "woody.gilk@gmail.com",
529 | "homepage": "http://shadowhand.me",
530 | "role": "Developer"
531 | }
532 | ],
533 | "description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.",
534 | "homepage": "https://phinx.org",
535 | "keywords": [
536 | "database",
537 | "database migrations",
538 | "db",
539 | "migrations",
540 | "phinx"
541 | ],
542 | "time": "2016-03-07 14:09:22"
543 | },
544 | {
545 | "name": "symfony/config",
546 | "version": "v3.1.2",
547 | "source": {
548 | "type": "git",
549 | "url": "https://github.com/symfony/config.git",
550 | "reference": "bcf5aebabc95b56e370e13d78565f74c7d8726dc"
551 | },
552 | "dist": {
553 | "type": "zip",
554 | "url": "https://api.github.com/repos/symfony/config/zipball/bcf5aebabc95b56e370e13d78565f74c7d8726dc",
555 | "reference": "bcf5aebabc95b56e370e13d78565f74c7d8726dc",
556 | "shasum": ""
557 | },
558 | "require": {
559 | "php": ">=5.5.9",
560 | "symfony/filesystem": "~2.8|~3.0"
561 | },
562 | "suggest": {
563 | "symfony/yaml": "To use the yaml reference dumper"
564 | },
565 | "type": "library",
566 | "extra": {
567 | "branch-alias": {
568 | "dev-master": "3.1-dev"
569 | }
570 | },
571 | "autoload": {
572 | "psr-4": {
573 | "Symfony\\Component\\Config\\": ""
574 | },
575 | "exclude-from-classmap": [
576 | "/Tests/"
577 | ]
578 | },
579 | "notification-url": "https://packagist.org/downloads/",
580 | "license": [
581 | "MIT"
582 | ],
583 | "authors": [
584 | {
585 | "name": "Fabien Potencier",
586 | "email": "fabien@symfony.com"
587 | },
588 | {
589 | "name": "Symfony Community",
590 | "homepage": "https://symfony.com/contributors"
591 | }
592 | ],
593 | "description": "Symfony Config Component",
594 | "homepage": "https://symfony.com",
595 | "time": "2016-06-29 05:41:56"
596 | },
597 | {
598 | "name": "symfony/console",
599 | "version": "v3.1.2",
600 | "source": {
601 | "type": "git",
602 | "url": "https://github.com/symfony/console.git",
603 | "reference": "747154aa69b0f83cd02fc9aa554836dee417631a"
604 | },
605 | "dist": {
606 | "type": "zip",
607 | "url": "https://api.github.com/repos/symfony/console/zipball/747154aa69b0f83cd02fc9aa554836dee417631a",
608 | "reference": "747154aa69b0f83cd02fc9aa554836dee417631a",
609 | "shasum": ""
610 | },
611 | "require": {
612 | "php": ">=5.5.9",
613 | "symfony/polyfill-mbstring": "~1.0"
614 | },
615 | "require-dev": {
616 | "psr/log": "~1.0",
617 | "symfony/event-dispatcher": "~2.8|~3.0",
618 | "symfony/process": "~2.8|~3.0"
619 | },
620 | "suggest": {
621 | "psr/log": "For using the console logger",
622 | "symfony/event-dispatcher": "",
623 | "symfony/process": ""
624 | },
625 | "type": "library",
626 | "extra": {
627 | "branch-alias": {
628 | "dev-master": "3.1-dev"
629 | }
630 | },
631 | "autoload": {
632 | "psr-4": {
633 | "Symfony\\Component\\Console\\": ""
634 | },
635 | "exclude-from-classmap": [
636 | "/Tests/"
637 | ]
638 | },
639 | "notification-url": "https://packagist.org/downloads/",
640 | "license": [
641 | "MIT"
642 | ],
643 | "authors": [
644 | {
645 | "name": "Fabien Potencier",
646 | "email": "fabien@symfony.com"
647 | },
648 | {
649 | "name": "Symfony Community",
650 | "homepage": "https://symfony.com/contributors"
651 | }
652 | ],
653 | "description": "Symfony Console Component",
654 | "homepage": "https://symfony.com",
655 | "time": "2016-06-29 07:02:31"
656 | },
657 | {
658 | "name": "symfony/filesystem",
659 | "version": "v3.1.2",
660 | "source": {
661 | "type": "git",
662 | "url": "https://github.com/symfony/filesystem.git",
663 | "reference": "322da5f0910d8aa0b25fa65ffccaba68dbddb890"
664 | },
665 | "dist": {
666 | "type": "zip",
667 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/322da5f0910d8aa0b25fa65ffccaba68dbddb890",
668 | "reference": "322da5f0910d8aa0b25fa65ffccaba68dbddb890",
669 | "shasum": ""
670 | },
671 | "require": {
672 | "php": ">=5.5.9"
673 | },
674 | "type": "library",
675 | "extra": {
676 | "branch-alias": {
677 | "dev-master": "3.1-dev"
678 | }
679 | },
680 | "autoload": {
681 | "psr-4": {
682 | "Symfony\\Component\\Filesystem\\": ""
683 | },
684 | "exclude-from-classmap": [
685 | "/Tests/"
686 | ]
687 | },
688 | "notification-url": "https://packagist.org/downloads/",
689 | "license": [
690 | "MIT"
691 | ],
692 | "authors": [
693 | {
694 | "name": "Fabien Potencier",
695 | "email": "fabien@symfony.com"
696 | },
697 | {
698 | "name": "Symfony Community",
699 | "homepage": "https://symfony.com/contributors"
700 | }
701 | ],
702 | "description": "Symfony Filesystem Component",
703 | "homepage": "https://symfony.com",
704 | "time": "2016-06-29 05:41:56"
705 | },
706 | {
707 | "name": "symfony/polyfill-mbstring",
708 | "version": "v1.2.0",
709 | "source": {
710 | "type": "git",
711 | "url": "https://github.com/symfony/polyfill-mbstring.git",
712 | "reference": "dff51f72b0706335131b00a7f49606168c582594"
713 | },
714 | "dist": {
715 | "type": "zip",
716 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
717 | "reference": "dff51f72b0706335131b00a7f49606168c582594",
718 | "shasum": ""
719 | },
720 | "require": {
721 | "php": ">=5.3.3"
722 | },
723 | "suggest": {
724 | "ext-mbstring": "For best performance"
725 | },
726 | "type": "library",
727 | "extra": {
728 | "branch-alias": {
729 | "dev-master": "1.2-dev"
730 | }
731 | },
732 | "autoload": {
733 | "psr-4": {
734 | "Symfony\\Polyfill\\Mbstring\\": ""
735 | },
736 | "files": [
737 | "bootstrap.php"
738 | ]
739 | },
740 | "notification-url": "https://packagist.org/downloads/",
741 | "license": [
742 | "MIT"
743 | ],
744 | "authors": [
745 | {
746 | "name": "Nicolas Grekas",
747 | "email": "p@tchwork.com"
748 | },
749 | {
750 | "name": "Symfony Community",
751 | "homepage": "https://symfony.com/contributors"
752 | }
753 | ],
754 | "description": "Symfony polyfill for the Mbstring extension",
755 | "homepage": "https://symfony.com",
756 | "keywords": [
757 | "compatibility",
758 | "mbstring",
759 | "polyfill",
760 | "portable",
761 | "shim"
762 | ],
763 | "time": "2016-05-18 14:26:46"
764 | },
765 | {
766 | "name": "symfony/yaml",
767 | "version": "v3.1.2",
768 | "source": {
769 | "type": "git",
770 | "url": "https://github.com/symfony/yaml.git",
771 | "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de"
772 | },
773 | "dist": {
774 | "type": "zip",
775 | "url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de",
776 | "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de",
777 | "shasum": ""
778 | },
779 | "require": {
780 | "php": ">=5.5.9"
781 | },
782 | "type": "library",
783 | "extra": {
784 | "branch-alias": {
785 | "dev-master": "3.1-dev"
786 | }
787 | },
788 | "autoload": {
789 | "psr-4": {
790 | "Symfony\\Component\\Yaml\\": ""
791 | },
792 | "exclude-from-classmap": [
793 | "/Tests/"
794 | ]
795 | },
796 | "notification-url": "https://packagist.org/downloads/",
797 | "license": [
798 | "MIT"
799 | ],
800 | "authors": [
801 | {
802 | "name": "Fabien Potencier",
803 | "email": "fabien@symfony.com"
804 | },
805 | {
806 | "name": "Symfony Community",
807 | "homepage": "https://symfony.com/contributors"
808 | }
809 | ],
810 | "description": "Symfony Yaml Component",
811 | "homepage": "https://symfony.com",
812 | "time": "2016-06-29 05:41:56"
813 | }
814 | ],
815 | "packages-dev": [
816 | {
817 | "name": "cakephp/bake",
818 | "version": "1.2.5",
819 | "source": {
820 | "type": "git",
821 | "url": "https://github.com/cakephp/bake.git",
822 | "reference": "876e074d2a936b0a2c825db06d81f3ea1d4b2af3"
823 | },
824 | "dist": {
825 | "type": "zip",
826 | "url": "https://api.github.com/repos/cakephp/bake/zipball/876e074d2a936b0a2c825db06d81f3ea1d4b2af3",
827 | "reference": "876e074d2a936b0a2c825db06d81f3ea1d4b2af3",
828 | "shasum": ""
829 | },
830 | "require": {
831 | "cakephp/cakephp": ">=3.2.0",
832 | "php": ">=5.5.9"
833 | },
834 | "require-dev": {
835 | "cakephp/cakephp-codesniffer": "dev-master",
836 | "phpunit/phpunit": "*"
837 | },
838 | "type": "cakephp-plugin",
839 | "autoload": {
840 | "psr-4": {
841 | "Bake\\": "src"
842 | }
843 | },
844 | "notification-url": "https://packagist.org/downloads/",
845 | "license": [
846 | "MIT"
847 | ],
848 | "authors": [
849 | {
850 | "name": "CakePHP Community",
851 | "homepage": "https://github.com/cakephp/bake/graphs/contributors"
852 | }
853 | ],
854 | "description": "Bake plugin for CakePHP 3.0",
855 | "homepage": "https://github.com/cakephp/bake",
856 | "keywords": [
857 | "bake",
858 | "cakephp"
859 | ],
860 | "time": "2016-06-28 01:58:30"
861 | },
862 | {
863 | "name": "cakephp/debug_kit",
864 | "version": "3.2.9",
865 | "source": {
866 | "type": "git",
867 | "url": "https://github.com/cakephp/debug_kit.git",
868 | "reference": "5c351136576b05a386eb2bbb02267529123edf7b"
869 | },
870 | "dist": {
871 | "type": "zip",
872 | "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/5c351136576b05a386eb2bbb02267529123edf7b",
873 | "reference": "5c351136576b05a386eb2bbb02267529123edf7b",
874 | "shasum": ""
875 | },
876 | "require": {
877 | "cakephp/cakephp": ">=3.1.0 <4.0",
878 | "jdorn/sql-formatter": "~1.2"
879 | },
880 | "require-dev": {
881 | "cakephp/cakephp-codesniffer": "dev-master",
882 | "phpunit/phpunit": "4.1.*"
883 | },
884 | "suggest": {
885 | "ext-sqlite": "DebugKit needs to store panel data in a database. SQLite is simple and easy to use."
886 | },
887 | "type": "cakephp-plugin",
888 | "autoload": {
889 | "psr-4": {
890 | "DebugKit\\": "src",
891 | "DebugKit\\Test\\Fixture\\": "tests\\Fixture"
892 | }
893 | },
894 | "notification-url": "https://packagist.org/downloads/",
895 | "license": [
896 | "MIT"
897 | ],
898 | "authors": [
899 | {
900 | "name": "Mark Story",
901 | "homepage": "http://mark-story.com",
902 | "role": "Author"
903 | },
904 | {
905 | "name": "CakePHP Community",
906 | "homepage": "https://github.com/cakephp/debug_kit/graphs/contributors"
907 | }
908 | ],
909 | "description": "CakePHP Debug Kit",
910 | "homepage": "https://github.com/cakephp/debug_kit",
911 | "keywords": [
912 | "cakephp",
913 | "debug",
914 | "kit"
915 | ],
916 | "time": "2016-05-28 15:47:46"
917 | },
918 | {
919 | "name": "dnoegel/php-xdg-base-dir",
920 | "version": "0.1",
921 | "source": {
922 | "type": "git",
923 | "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
924 | "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a"
925 | },
926 | "dist": {
927 | "type": "zip",
928 | "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a",
929 | "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a",
930 | "shasum": ""
931 | },
932 | "require": {
933 | "php": ">=5.3.2"
934 | },
935 | "require-dev": {
936 | "phpunit/phpunit": "@stable"
937 | },
938 | "type": "project",
939 | "autoload": {
940 | "psr-4": {
941 | "XdgBaseDir\\": "src/"
942 | }
943 | },
944 | "notification-url": "https://packagist.org/downloads/",
945 | "license": [
946 | "MIT"
947 | ],
948 | "description": "implementation of xdg base directory specification for php",
949 | "time": "2014-10-24 07:27:01"
950 | },
951 | {
952 | "name": "jakub-onderka/php-console-color",
953 | "version": "0.1",
954 | "source": {
955 | "type": "git",
956 | "url": "https://github.com/JakubOnderka/PHP-Console-Color.git",
957 | "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1"
958 | },
959 | "dist": {
960 | "type": "zip",
961 | "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1",
962 | "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1",
963 | "shasum": ""
964 | },
965 | "require": {
966 | "php": ">=5.3.2"
967 | },
968 | "require-dev": {
969 | "jakub-onderka/php-code-style": "1.0",
970 | "jakub-onderka/php-parallel-lint": "0.*",
971 | "jakub-onderka/php-var-dump-check": "0.*",
972 | "phpunit/phpunit": "3.7.*",
973 | "squizlabs/php_codesniffer": "1.*"
974 | },
975 | "type": "library",
976 | "autoload": {
977 | "psr-0": {
978 | "JakubOnderka\\PhpConsoleColor": "src/"
979 | }
980 | },
981 | "notification-url": "https://packagist.org/downloads/",
982 | "license": [
983 | "BSD-2-Clause"
984 | ],
985 | "authors": [
986 | {
987 | "name": "Jakub Onderka",
988 | "email": "jakub.onderka@gmail.com",
989 | "homepage": "http://www.acci.cz"
990 | }
991 | ],
992 | "time": "2014-04-08 15:00:19"
993 | },
994 | {
995 | "name": "jakub-onderka/php-console-highlighter",
996 | "version": "v0.3.2",
997 | "source": {
998 | "type": "git",
999 | "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git",
1000 | "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5"
1001 | },
1002 | "dist": {
1003 | "type": "zip",
1004 | "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5",
1005 | "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5",
1006 | "shasum": ""
1007 | },
1008 | "require": {
1009 | "jakub-onderka/php-console-color": "~0.1",
1010 | "php": ">=5.3.0"
1011 | },
1012 | "require-dev": {
1013 | "jakub-onderka/php-code-style": "~1.0",
1014 | "jakub-onderka/php-parallel-lint": "~0.5",
1015 | "jakub-onderka/php-var-dump-check": "~0.1",
1016 | "phpunit/phpunit": "~4.0",
1017 | "squizlabs/php_codesniffer": "~1.5"
1018 | },
1019 | "type": "library",
1020 | "autoload": {
1021 | "psr-0": {
1022 | "JakubOnderka\\PhpConsoleHighlighter": "src/"
1023 | }
1024 | },
1025 | "notification-url": "https://packagist.org/downloads/",
1026 | "license": [
1027 | "MIT"
1028 | ],
1029 | "authors": [
1030 | {
1031 | "name": "Jakub Onderka",
1032 | "email": "acci@acci.cz",
1033 | "homepage": "http://www.acci.cz/"
1034 | }
1035 | ],
1036 | "time": "2015-04-20 18:58:01"
1037 | },
1038 | {
1039 | "name": "jdorn/sql-formatter",
1040 | "version": "v1.2.17",
1041 | "source": {
1042 | "type": "git",
1043 | "url": "https://github.com/jdorn/sql-formatter.git",
1044 | "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc"
1045 | },
1046 | "dist": {
1047 | "type": "zip",
1048 | "url": "https://api.github.com/repos/jdorn/sql-formatter/zipball/64990d96e0959dff8e059dfcdc1af130728d92bc",
1049 | "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc",
1050 | "shasum": ""
1051 | },
1052 | "require": {
1053 | "php": ">=5.2.4"
1054 | },
1055 | "require-dev": {
1056 | "phpunit/phpunit": "3.7.*"
1057 | },
1058 | "type": "library",
1059 | "extra": {
1060 | "branch-alias": {
1061 | "dev-master": "1.3.x-dev"
1062 | }
1063 | },
1064 | "autoload": {
1065 | "classmap": [
1066 | "lib"
1067 | ]
1068 | },
1069 | "notification-url": "https://packagist.org/downloads/",
1070 | "license": [
1071 | "MIT"
1072 | ],
1073 | "authors": [
1074 | {
1075 | "name": "Jeremy Dorn",
1076 | "email": "jeremy@jeremydorn.com",
1077 | "homepage": "http://jeremydorn.com/"
1078 | }
1079 | ],
1080 | "description": "a PHP SQL highlighting library",
1081 | "homepage": "https://github.com/jdorn/sql-formatter/",
1082 | "keywords": [
1083 | "highlight",
1084 | "sql"
1085 | ],
1086 | "time": "2014-01-12 16:20:24"
1087 | },
1088 | {
1089 | "name": "nikic/php-parser",
1090 | "version": "v2.1.0",
1091 | "source": {
1092 | "type": "git",
1093 | "url": "https://github.com/nikic/PHP-Parser.git",
1094 | "reference": "47b254ea51f1d6d5dc04b9b299e88346bf2369e3"
1095 | },
1096 | "dist": {
1097 | "type": "zip",
1098 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/47b254ea51f1d6d5dc04b9b299e88346bf2369e3",
1099 | "reference": "47b254ea51f1d6d5dc04b9b299e88346bf2369e3",
1100 | "shasum": ""
1101 | },
1102 | "require": {
1103 | "ext-tokenizer": "*",
1104 | "php": ">=5.4"
1105 | },
1106 | "require-dev": {
1107 | "phpunit/phpunit": "~4.0"
1108 | },
1109 | "bin": [
1110 | "bin/php-parse"
1111 | ],
1112 | "type": "library",
1113 | "extra": {
1114 | "branch-alias": {
1115 | "dev-master": "2.1-dev"
1116 | }
1117 | },
1118 | "autoload": {
1119 | "psr-4": {
1120 | "PhpParser\\": "lib/PhpParser"
1121 | }
1122 | },
1123 | "notification-url": "https://packagist.org/downloads/",
1124 | "license": [
1125 | "BSD-3-Clause"
1126 | ],
1127 | "authors": [
1128 | {
1129 | "name": "Nikita Popov"
1130 | }
1131 | ],
1132 | "description": "A PHP parser written in PHP",
1133 | "keywords": [
1134 | "parser",
1135 | "php"
1136 | ],
1137 | "time": "2016-04-19 13:41:41"
1138 | },
1139 | {
1140 | "name": "psy/psysh",
1141 | "version": "v0.7.2",
1142 | "source": {
1143 | "type": "git",
1144 | "url": "https://github.com/bobthecow/psysh.git",
1145 | "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280"
1146 | },
1147 | "dist": {
1148 | "type": "zip",
1149 | "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e64e10b20f8d229cac76399e1f3edddb57a0f280",
1150 | "reference": "e64e10b20f8d229cac76399e1f3edddb57a0f280",
1151 | "shasum": ""
1152 | },
1153 | "require": {
1154 | "dnoegel/php-xdg-base-dir": "0.1",
1155 | "jakub-onderka/php-console-highlighter": "0.3.*",
1156 | "nikic/php-parser": "^1.2.1|~2.0",
1157 | "php": ">=5.3.9",
1158 | "symfony/console": "~2.3.10|^2.4.2|~3.0",
1159 | "symfony/var-dumper": "~2.7|~3.0"
1160 | },
1161 | "require-dev": {
1162 | "fabpot/php-cs-fixer": "~1.5",
1163 | "phpunit/phpunit": "~3.7|~4.0|~5.0",
1164 | "squizlabs/php_codesniffer": "~2.0",
1165 | "symfony/finder": "~2.1|~3.0"
1166 | },
1167 | "suggest": {
1168 | "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
1169 | "ext-pdo-sqlite": "The doc command requires SQLite to work.",
1170 | "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
1171 | "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history."
1172 | },
1173 | "bin": [
1174 | "bin/psysh"
1175 | ],
1176 | "type": "library",
1177 | "extra": {
1178 | "branch-alias": {
1179 | "dev-develop": "0.8.x-dev"
1180 | }
1181 | },
1182 | "autoload": {
1183 | "files": [
1184 | "src/Psy/functions.php"
1185 | ],
1186 | "psr-4": {
1187 | "Psy\\": "src/Psy/"
1188 | }
1189 | },
1190 | "notification-url": "https://packagist.org/downloads/",
1191 | "license": [
1192 | "MIT"
1193 | ],
1194 | "authors": [
1195 | {
1196 | "name": "Justin Hileman",
1197 | "email": "justin@justinhileman.info",
1198 | "homepage": "http://justinhileman.com"
1199 | }
1200 | ],
1201 | "description": "An interactive shell for modern PHP.",
1202 | "homepage": "http://psysh.org",
1203 | "keywords": [
1204 | "REPL",
1205 | "console",
1206 | "interactive",
1207 | "shell"
1208 | ],
1209 | "time": "2016-03-09 05:03:14"
1210 | },
1211 | {
1212 | "name": "symfony/var-dumper",
1213 | "version": "v3.1.2",
1214 | "source": {
1215 | "type": "git",
1216 | "url": "https://github.com/symfony/var-dumper.git",
1217 | "reference": "39492b8b8fe514163e677bf154fd80f6cc995759"
1218 | },
1219 | "dist": {
1220 | "type": "zip",
1221 | "url": "https://api.github.com/repos/symfony/var-dumper/zipball/39492b8b8fe514163e677bf154fd80f6cc995759",
1222 | "reference": "39492b8b8fe514163e677bf154fd80f6cc995759",
1223 | "shasum": ""
1224 | },
1225 | "require": {
1226 | "php": ">=5.5.9",
1227 | "symfony/polyfill-mbstring": "~1.0"
1228 | },
1229 | "require-dev": {
1230 | "twig/twig": "~1.20|~2.0"
1231 | },
1232 | "suggest": {
1233 | "ext-symfony_debug": ""
1234 | },
1235 | "type": "library",
1236 | "extra": {
1237 | "branch-alias": {
1238 | "dev-master": "3.1-dev"
1239 | }
1240 | },
1241 | "autoload": {
1242 | "files": [
1243 | "Resources/functions/dump.php"
1244 | ],
1245 | "psr-4": {
1246 | "Symfony\\Component\\VarDumper\\": ""
1247 | },
1248 | "exclude-from-classmap": [
1249 | "/Tests/"
1250 | ]
1251 | },
1252 | "notification-url": "https://packagist.org/downloads/",
1253 | "license": [
1254 | "MIT"
1255 | ],
1256 | "authors": [
1257 | {
1258 | "name": "Nicolas Grekas",
1259 | "email": "p@tchwork.com"
1260 | },
1261 | {
1262 | "name": "Symfony Community",
1263 | "homepage": "https://symfony.com/contributors"
1264 | }
1265 | ],
1266 | "description": "Symfony mechanism for exploring and dumping PHP variables",
1267 | "homepage": "https://symfony.com",
1268 | "keywords": [
1269 | "debug",
1270 | "dump"
1271 | ],
1272 | "time": "2016-06-29 05:41:56"
1273 | }
1274 | ],
1275 | "aliases": [],
1276 | "minimum-stability": "dev",
1277 | "stability-flags": {
1278 | "cakephp/acl": 20,
1279 | "psy/psysh": 0
1280 | },
1281 | "prefer-stable": true,
1282 | "prefer-lowest": false,
1283 | "platform": {
1284 | "php": ">=5.4.16"
1285 | },
1286 | "platform-dev": []
1287 | }
1288 |
--------------------------------------------------------------------------------