Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: CI
on:
push:
branches:
- '5.x'
- '5.next'
- '6.x'
pull_request:
branches:
Expand All @@ -21,9 +19,9 @@ jobs:
fail-fast: false
matrix:
include:
- php-version: '8.2'
- php-version: '8.4'
dependencies: 'lowest'
- php-version: '8.5'
- php-version: '8.4'
dependencies: 'highest'
- php-version: '8.5'
dependencies: 'highest'
Expand Down Expand Up @@ -63,7 +61,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.4'
extensions: mbstring, intl
coverage: none
tools: cs2pr, phpstan:2.3
Expand Down
4 changes: 2 additions & 2 deletions .htaccess
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(\.well-known/.*)$ $1 [L]
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
RewriteRule ^$ public/ [L]
RewriteRule (.*) public/$1 [L]
</IfModule>
42 changes: 34 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
# CakePHP Application Skeleton

![Build Status](https://github.com/cakephp/app/actions/workflows/ci.yml/badge.svg?branch=5.x)
![Build Status](https://github.com/cakephp/app/actions/workflows/ci.yml/badge.svg?branch=6.x)
[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/app.svg?style=flat-square)](https://packagist.org/packages/cakephp/app)
[![PHPStan](https://img.shields.io/badge/PHPStan-level%208-brightgreen.svg?style=flat-square)](https://github.com/phpstan/phpstan)

A skeleton for creating applications with [CakePHP](https://cakephp.org) 5.x.
A skeleton for creating applications with [CakePHP](https://cakephp.org) 6.x, requiring PHP 8.4 or higher.

This branch tracks CakePHP 6 development and allows development dependencies while preferring stable packages.
Migrations is tracked on `6.x-dev`. Installation and attribute routing currently depend on
[Migrations 6 compatibility](https://github.com/cakephp/migrations/pull/1121) and the
[repeated route attribute fix](https://github.com/cakephp/cakephp/pull/19663).

The framework source code can be found here: [cakephp/cakephp](https://github.com/cakephp/cakephp).

## Installation

1. Download [Composer](https://getcomposer.org/doc/00-intro.md) or update `composer self-update`.
2. Run `php composer.phar create-project --prefer-dist cakephp/app [app_name]`.
2. Run `php composer.phar create-project --prefer-dist cakephp/app myapp "6.x-dev"`.

If Composer is installed globally, run

```bash
composer create-project --prefer-dist cakephp/app
composer create-project --prefer-dist cakephp/app myapp "6.x-dev"
```

In case you want to use a custom app dir name (e.g. `/myapp/`):

```bash
composer create-project --prefer-dist cakephp/app myapp
composer create-project --prefer-dist cakephp/app /myapp "6.x-dev"
```

You can now either use your machine's webserver to view the default home page, or start
up the built-in webserver with:
Configure your webserver's document root to the application's `public/` directory,
which contains the front controller and static assets. You can also start the built-in webserver with:

```bash
bin/cake server -p 8765
Expand All @@ -36,7 +41,7 @@ Then visit `http://localhost:8765` to see the welcome page.

## Demo app

Check out the [5.x-demo branch](https://github.com/cakephp/app/tree/5.x-demo), which contains demo migrations and a seeder.
The [5.x-demo branch](https://github.com/cakephp/app/tree/5.x-demo) is a CakePHP 5 example containing demo migrations and a seeder.
See the [README](https://github.com/cakephp/app/blob/5.x-demo/README.md) on how to get it running.

## Update
Expand All @@ -51,6 +56,27 @@ Read and edit the environment specific `config/app_local.php` and set up the
`'Datasources'` and any other configuration relevant for your application.
Other environment agnostic settings can be changed in `config/app.php`.

The test suite uses PHPUnit 13, which requires PHP 8.4.1 or higher.

## Routing

Routes are declared explicitly using [PHP attributes](https://book.cakephp.org/6.x/development/attribute-routing.html)
on controller actions. The home page and `/pages/*` use `#[Get]` attributes on `PagesController::display()`.
Catchall routes are not enabled: add attributes to new controllers, including controllers generated by Bake,
or connect explicit routes in `config/routes.php` or `Application::routes()`.
Attribute routes are bootstrapped in `Application::routes()`. The included `config/routes.php`
contains a commented example of conventional routing and is loaded before the attribute routes.
You can delete this file if you only use attribute routing.
Controllers inherit `DashedRoute` from the `#[RouteClass]` attribute on `AppController`.

The attribute resolver scans application controllers, including nested controller directories.
Attribute metadata uses the `_cake_attributes_` PHP cache in production and is not persistently cached in debug mode.
Clear the metadata cache after deploying controller or route changes:

```bash
bin/cake cache clear _cake_attributes_
```

## Layout

The app skeleton uses [Milligram](https://milligram.io/) (v1.3) minimalist CSS
Expand Down
18 changes: 10 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
"type": "project",
"homepage": "https://cakephp.org",
"require": {
"php": ">=8.2",
"cakephp/cakephp": "5.4.*",
"cakephp/migrations": "^5.0",
"php": ">=8.4",
"cakephp/cakephp": "^6.0",
"cakephp/migrations": "6.x-dev",
"cakephp/plugin-installer": "^2.0",
"mobiledetect/mobiledetectlib": "^4.8.03"
},
"require-dev": {
"cakephp/bake": "^3.6",
"cakephp/cakephp-codesniffer": "^5.3",
"cakephp/debug_kit": "^5.2",
"cakephp/bake": "^4.0",
"cakephp/cakephp-codesniffer": "^6.0",
"cakephp/debug_kit": "^6.0",
"josegonzalez/dotenv": "^4.0",
"phpunit/phpunit": "^11.5.3 || ^12.1.3 || ^13.0"
"phpunit/phpunit": "^13.0"
},
"suggest": {
"cakephp/repl": "Console tools for a REPL interface for CakePHP applications.",
Expand Down Expand Up @@ -53,5 +53,7 @@
"cs-check": "phpcs --colors -p",
"cs-fix": "phpcbf --colors -p",
"test": "phpunit --colors=always"
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
31 changes: 24 additions & 7 deletions config/app.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Cake\Cache\Engine\FileEngine;
use Cake\Cache\Engine\PhpEngine;
use Cake\Database\Connection;
use Cake\Database\Driver\Mysql;
use Cake\Log\Engine\FileLog;
Expand Down Expand Up @@ -28,23 +29,23 @@
* - base - The base directory the app resides in. If false this
* will be auto-detected.
* - dir - Name of app directory.
* - webroot - The webroot directory.
* - wwwRoot - The file path to webroot.
* - webroot - The public directory name.
* - wwwRoot - The file path to the public directory.
* - baseUrl - To configure CakePHP to *not* use mod_rewrite and to
* use CakePHP pretty URLs, remove these .htaccess
* files:
* /.htaccess
* /webroot/.htaccess
* /public/.htaccess
* And uncomment the baseUrl key below.
* - fullBaseUrl - SECURITY: A base URL to use for absolute links.
* IMPORTANT: This MUST be set in production to prevent Host Header Injection attacks
* that can compromise password reset and other security-critical features.
* Set this via APP_FULL_BASE_URL environment variable or directly in config.
* Example: 'https://example.com'
* When not set, the application will throw an exception in production mode.
* - imageBaseUrl - Web path to the public images/ directory under webroot.
* - cssBaseUrl - Web path to the public css/ directory under webroot.
* - jsBaseUrl - Web path to the public js/ directory under webroot.
* - imageBaseUrl - Web path to the images/ directory under public/.
* - cssBaseUrl - Web path to the css/ directory under public/.
* - jsBaseUrl - Web path to the js/ directory under public/.
* - paths - Configure paths for non class-based resources. Supports the
* `plugins`, `templates`, `locales` subkeys, which allow the definition of
* paths for plugins, view templates and locale files respectively.
Expand All @@ -56,7 +57,7 @@
'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'),
'base' => false,
'dir' => 'src',
'webroot' => 'webroot',
'webroot' => 'public',
'wwwRoot' => WWW_ROOT,
//'baseUrl' => env('SCRIPT_NAME'),
'fullBaseUrl' => env('APP_FULL_BASE_URL', false),
Expand Down Expand Up @@ -133,6 +134,22 @@
'duration' => '+1 years',
'url' => env('CACHE_CAKEMODEL_URL', null),
],

// Attribute metadata is cached indefinitely in production. Clear at deploy time.
'_cake_attributes_' => [
'className' => PhpEngine::class,
'prefix' => 'myapp_attributes_',
'path' => CACHE . 'attributes' . DS,
'duration' => 0,
],
],

'AttributeResolver' => [
'default' => [
'paths' => ['Controller/*Controller.php', 'Controller/**/*Controller.php'],
'basePath' => APP,
'cache' => '_cake_attributes_',
],
],

/*
Expand Down
7 changes: 5 additions & 2 deletions config/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/
require CORE_PATH . 'config' . DS . 'bootstrap.php';

use Cake\AttributeResolver\AttributeResolver;
use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\Core\Configure\Engine\PhpConfig;
Expand Down Expand Up @@ -102,6 +103,7 @@
if (Configure::read('debug')) {
Configure::write('Cache._cake_model_.duration', '+1 minute');
Configure::write('Cache._cake_translations_.duration', '+1 minute');
Configure::write('AttributeResolver.default.cache', false);
}

/*
Expand Down Expand Up @@ -184,6 +186,7 @@
* This will also remove the loaded config data from memory.
*/
Cache::setConfig(Configure::consume('Cache'));
AttributeResolver::setConfig(Configure::consume('AttributeResolver'));
ConnectionManager::setConfig(Configure::consume('Datasources'));
TransportFactory::setConfig(Configure::consume('EmailTransport'));
Mailer::setConfig(Configure::consume('Email'));
Expand All @@ -210,7 +213,7 @@
* You can enable default locale format parsing by adding calls
* to `useLocaleParser()`. This enables the automatic conversion of
* locale specific date formats when processing request data. For details see
* @link https://book.cakephp.org/5/en/core-libraries/internationalization-and-localization.html#parsing-localized-datetime-data
* @link https://book.cakephp.org/6.x/core-libraries/internationalization-and-localization.html#parsing-localized-datetime-data
*/
// \Cake\Database\TypeFactory::build('time')->useLocaleParser();
// \Cake\Database\TypeFactory::build('date')->useLocaleParser();
Expand All @@ -231,7 +234,7 @@
// \Cake\Utility\Inflector::rules('uninflected', ['dontinflectme']);

// set a custom date and time format
// see https://book.cakephp.org/5/en/core-libraries/time.html#setting-the-default-locale-and-format-string
// see https://book.cakephp.org/6.x/core-libraries/time.html#setting-the-default-locale-and-format-string
// and https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
// \Cake\I18n\Date::setToStringFormat('dd.MM.yyyy');
// \Cake\I18n\Time::setToStringFormat('dd.MM.yyyy HH:mm');
6 changes: 3 additions & 3 deletions config/paths.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@
define('CONFIG', ROOT . DS . 'config' . DS);

/*
* File path to the webroot directory.
* File path to the public directory.
*
* To derive your webroot from your webserver change this to:
* To derive this path from your webserver change this to:
*
* `define('WWW_ROOT', rtrim($_SERVER['DOCUMENT_ROOT'], DS) . DS);`
*/
define('WWW_ROOT', ROOT . DS . 'webroot' . DS);
define('WWW_ROOT', ROOT . DS . 'public' . DS);

/*
* Path to the tests directory.
Expand Down
2 changes: 1 addition & 1 deletion config/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* In this file, you configure which plugins are loaded in the different states your app can be.
* It's loaded via the `parent::bootstrap();` call inside your `Application::bootstrap()` method.
* For more information see https://book.cakephp.org/5/en/plugins.html#loading-plugins-via-configuration-array
* For more information see https://book.cakephp.org/6.x/plugins.html#loading-plugins-via-configuration-array
*
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
Expand Down
81 changes: 4 additions & 77 deletions config/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@
/**
Comment thread
josbeir marked this conversation as resolved.
* Routes configuration.
*
* In this file, you set up routes to your controllers and their actions.
* Routes are very important mechanism that allows you to freely connect
* different URLs to chosen controllers and their actions (functions).
*
* It's loaded within the context of `Application::routes()` method which
* receives a `RouteBuilder` instance `$routes` as method argument.
*
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
Expand All @@ -21,76 +14,10 @@
* @license https://opensource.org/licenses/mit-license.php MIT License
*/

use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;

/*
* This file is loaded in the context of the `Application` class.
* So you can use `$this` to reference the application class instance
* if required.
*/
return function (RouteBuilder $routes): void {
/*
* The default class to use for all routes
*
* The following route classes are supplied with CakePHP and are appropriate
* to set as the default:
*
* - Route
* - InflectedRoute
* - DashedRoute
*
* If no call is made to `Router::defaultRouteClass()`, the class used is
* `Route` (`Cake\Routing\Route\Route`)
*
* Note that `Route` does not do any inflections on URLs which will result in
* inconsistently cased URLs when used with `{plugin}`, `{controller}` and
* `{action}` markers.
*/
$routes->setRouteClass(DashedRoute::class);

$routes->scope('/', function (RouteBuilder $builder): void {
/*
* Here, we are connecting '/' (base path) to a controller called 'Pages',
* its action called 'display', and we pass a param to select the view file
* to use (in this case, templates/Pages/home.php)...
*/
$builder->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);

/*
* ...and connect the rest of 'Pages' controller's URLs.
*/
$builder->connect('/pages/*', 'Pages::display');

/*
* Connect catchall routes for all controllers.
*
* The `fallbacks` method is a shortcut for
*
* ```
* $builder->connect('/{controller}', ['action' => 'index']);
* $builder->connect('/{controller}/{action}/*', []);
* ```
*
* It is NOT recommended to use fallback routes after your initial prototyping phase!
* See https://book.cakephp.org/5/en/development/routing.html#fallbacks-method for more information
*/
$builder->fallbacks();
});

/*
* If you need a different set of middleware or none at all,
* open new scope and define routes there.
*
* ```
* $routes->scope('/api', function (RouteBuilder $builder): void {
* // No $builder->applyMiddleware() here.
*
* // Parse specified extensions from URLs
* // $builder->setExtensions(['json', 'xml']);
*
* // Connect API actions here.
* });
* ```
*/
return static function (RouteBuilder $routes): void {
// Attribute routes are connected in Application::routes().
// You can also connect explicit routes here, for example:
// $routes->get('/contact', ['controller' => 'Pages', 'action' => 'display', 'contact'], 'contact');
};
2 changes: 1 addition & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
* @license https://opensource.org/licenses/mit-license.php MIT License
*/

require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
require 'public' . DIRECTORY_SEPARATOR . 'index.php';
Loading
Loading