Search code examples
phpcakephpcakephp-3.0cakephp-bake

Overriding ControllerTask using plugin


I would like to produce an extra view file, inside the model's template folder when I bake a controller. I've copied (unchanged yet) ControllerTask.php into plugins/WetKit/src/Shell/Task in my plugin.

For instance, for the model Entries, I would like a new file to appear during baking: src/Templates/Entries/my_custom_file.ctp.

However, when I run cake bake controller entries -t WetKit, I get:

$ bin/cake bake controller entries -t WetKit
PHP Fatal error:  Cannot declare class Bake\Shell\Task\ControllerTask, because the name is already in use in C:\Users\me\Downloads\xampp3\xampp\htdocs\twofk\plugins\WetKit\src\Shell\Task\ControllerTask.php on line 28

What is the best way to accomplish this?

Edit 1: Would this be a namespace issue?

Edit 2:

Edits made to the WetKitControllerTask.php, kept as-is, but added "Yo!" in the output of the sprintf function:

namespace Wetkit\Bake\Shell\Task;

use Cake\Console\Shell;
use Cake\Core\Configure;
use Cake\ORM\TableRegistry;

use Bake\Shell\Task\ControllerTask;

/**
 * Task class for creating and updating controller files.
 *
 * @property \Bake\Shell\Task\ModelTask $Model
 * @property \Bake\Shell\Task\BakeTemplateTask $BakeTemplate
 * @property \Bake\Shell\Task\TestTask $Test
 */
class WetKitControllerTask extends ControllerTask
...
    public function bake($controllerName)
    {
        $this->out("\n" . sprintf('Yo! Baking controller class for %s...', $controllerName), 1, Shell::QUIET);
    

When I run the bake command, I don't seem to be getting "Yo!" to appear:

$ bin/cake bake controller entries -t WetKit

Baking controller class for Entries...

Edit 3

I get an error:

  • file: plugins/WetKit/src/Shell/Task/WetKitControllerTask.php
  • class name: ControllerTask
  • result: Cannot declare class Wetkit\Bake\Shell\Task\ControllerTask because the name is already in use

I get an error:

  • file: plugins/WetKit/src/Shell/Task/ControllerTask.php
  • class name: ControllerTask
  • result: Cannot declare class Wetkit\Bake\Shell\Task\ControllerTask because the name is already in use

No error, but doesn't output desired line:

  • file: plugins/WetKit/src/Shell/Task/ControllerTask.php
  • class name: WetKitControllerTask
  • result: no issues, but also not displaying added output command

Command

public function bake($controllerName)
    {
        $this->out("\n" . 'Override damn you!');
    

Under the Include tab in DebugKit, I see that my WetKit plugin is loaded.

To confirm, the override should happen in plugins/WetKit/src/Shell/Task/ of the plugin?

Edit 4

The namespace issue was my fault. I introduced this while trying to override the task.

In terms of autoloader, in composer.json:

"autoload": {
    "psr-4": {
        "WetKit\\": "src/"
    }
},

With:

  • Namespace: WetKit\Shell\Task
  • Filename: ControllerTask.php
  • Class name: WetKitControllerTask

I decided to refresh the autoload files:

$ composer dump-autoload -o
Generating optimized autoload files
Class WetKit\Shell\Task\WetKitControllerTask located in C:/Users/me/Downloads/xampp3/xampp/htdocs/twofk/plugins/WetKit/src\Shell\Task\ControllerTask.php does not comply with psr-4 autoloading standard. Skipping.
Generated optimized autoload files containing 3261 classes

If I change the filename to match the classname, composer will load the class and not output the PSR-4 issue. The baking still doesn't work, I don't see the class changes.

I tried to bake with the filename being ControllerTask.php and class name WetKitControllerTask. Composer would have skipped the file, but baking still doesn't show my class modifications. Strange.

Edit 5

Noting a change to targeting TemplateTask.php instead of ControllerTask.php. What I need to do fits better in TemplateTask.php.

With the class and filename matching, I cannot bake as I get the error shown below (which also happened with ControllerTask.php):

enter image description here

Edit 6

Solution:

...
use Bake\Shell\Task\TemplateTask as WetKitTemplateTask;
...
class TemplateTask extends WetKitTemplateTask

Solution

  • I just had to change the namespace and class definition as such and place the file under plugin/WetKit/src/Shell/Task.

    ...
    use Bake\Shell\Task\TemplateTask as WetKitTemplateTask;
    ...
    class TemplateTask extends WetKitTemplateTask