Custom file extensions (e.g. .env): routing and rendering serialized responses

It is fairly common to add json handler to a CakePHP route and have it automatically respond with formatted JSON. Consider this example. In your route: $routes->prefix(‘Api’, function (RouteBuilder $routes) { $routes->setExtensions([‘json’]); $routes->fallbacks(DashedRoute::class); }); In your controller: public function initialize(): void { parent::initialize(); $this->addViewClasses([\Cake\View\JsonView::class]); $this->viewBuilder()->setOption(‘serialize’, true); } So now when you request actions in that… Continue reading Custom file extensions (e.g. .env): routing and rendering serialized responses

Deploying a simple CakePHP app to Render.com using Docker

Render doesn’t have a ā€œnative PHP runtimeā€ like it does for Node/Python, but it does have Docker. So we can use a Docker image that will set up the PHP runtime for us. To make it happen, we will have to add these two files to our application: Dockerfile that imports and uses a prebuilt… Continue reading Deploying a simple CakePHP app to Render.com using Docker

Connection to Sqlite not established, unable to open database file

The problem You created a new CakePHP application and you try to visit its homepage. You get a database error. Missing Database Connection Cake\Database\Exception\MissingConnectionException Connection to Sqlite could not be established: SQLSTATE[HY000] [14] unable to open database file The (potential) reason Check your composer.json and see if your application uses cakephp/debug_kit: “require-dev”: { … “cakephp/debug_kit”:… Continue reading Connection to Sqlite not established, unable to open database file

Containing associated tables automatically

Say you have OrdersTable associated to CustomersTable, and you want every order you select to automatically contain the corresponding customer information. (So that you don’t have to do ->contain('Customers') on each find() call.) There are two ways to accomplish this. In your OrdersTable: public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) { $query->contain(‘Customers’); return… Continue reading Containing associated tables automatically

Structuring CakePHP models in subfolders

Say you want to organise your CakePHP models (tables) into subfolders. If you simply move the class into a subfolder, it won’t be picked up automatically. For example, here’s how you can tell the TableLocator to look for OrderStatuses in a specific subfolder Orders under Model/Table. In your controller: First, prepare the shorthand variables. $tableRegistry… Continue reading Structuring CakePHP models in subfolders

Setting up CakePHP CRUD plugin to use tables from another plugin

In the controller where you initialise Crud: $this->loadComponent(‘Crud.Crud’, [ // … ]); $this->Crud->useModel(sprintf( ‘%s.%s’, ‘MyPlugin’, $this->Crud->getController()->defaultTable )); Prevent linking to the plugin where your tables are: /** * Before render callback. * * @param \Cake\Event\Event $event The beforeRender event. * @return void */ public function beforeRender(\Cake\Event\EventInterface $event) { // prevent linking to the table plugin:… Continue reading Setting up CakePHP CRUD plugin to use tables from another plugin

Where to put an event listener in a plugin?

You’re creating an event listener that inserts a database record every time the matching event fires. And you need the listener to be in a plugin. Which folder do you put it in? Here it says: A good place for this might be Plugin/src/Controller/Event And @admad on CakeSF Slack says it can also be Plugin/src/Event/.… Continue reading Where to put an event listener in a plugin?

Undefined index: verifyTokenSource, samesite

Undefined index: verifyTokenSource Undefined index: samesite I started getting this error in src/Http/Middleware/CsrfProtectionMiddleware.php after running composer update. To fix, run bin/cake cache clear_all

Get the current plugin name in CakePHP

If you need the current plugin name in e.g. config/routes.php or config/bootstrap.php, and don’t want to hardcode it by hand, you can use $this->getName() instead. Example: Router::plugin($this->getName(), function (RouteBuilder $routes) { $routes->fallbacks(DashedRoute::class); }); The above is effectively the same as: Router::plugin('MyPlugin', function (RouteBuilder $routes) { $routes->fallbacks(DashedRoute::class); });