January 25, 2022 - 3 min

Use Symfony Components to Build WordPress Plugin Maker for CLI - Part 1


				
				

Anka Bajurin Stiskalov

Senior Software developer

You can create your console command-line commands using the Symfony Console component. I needed one for my WordPress plugin skeleton. It is explained why here. In summary, I needed a WordPress plugin maker for my team.


Your task is to do the same. A new plugin needs to be created from the files of the WordPress plugin skeleton. Download files of the skeleton here. Let’s build a new console and have fun with finding and creating new files using CLI.


Create console with Symfony Console component


Symfony components have such great documentation. Check the one for the Console component here.


Now open your CLI and make a new folder for this project.


Go inside that folder and run:




$ composer require symfony/console



Create an app directory in the root of the project and edit composer.json file to add PSR-4 autoloading:




"autoload": {
    "psr-4": {
        "App\\": "app/"
    }
}



Create file named console inside app/bin folder and add this code inside:




#!/usr/bin/env php
<?php
// application.php
require __DIR__.'/../../vendor/autoload.php';

use Symfony\Component\Console\Application;

$application = new Application();
$application->run();



You have your console ready!


Find files with Symfony Finder component


Create logic for finding and creating new files with Finder and Filesystem Symfony components.


Your task is to copy files from wp-plugin-skeleton, Rename those files, class names and constants to make a new plugin that is ready to use inside the WordPress project without conflicts with other plugins that are built from the same skeleton.


Download files here and put the wp-plugin-skeleton folder in the root folder of your project.


Create a service class inside the app/Service folder named WPPluginMaker with namespace App\Service. This class will hold the logic for creating a new WordPress plugin from the skeleton files.


Briefly check Symfony documentation for Finder component here.




$ composer require symfony/finder



Now you can use Finder in your service. Add dependency to Symfony\Component\Finder\Finder in the constructor:




<?php

namespace App\Service;

use Symfony\Component\Finder\Finder;

class WPPluginMaker

{

    protected $finder;

    public function __construct()
    {
        $this->finder = new Finder();
    }



Create a public function createNewPluginFromWpPluginSkeleton(){} in which we are going to use Finder to find all wp-plugin-skeleton files that we need to copy and manipulate later.


We don’t wish to copy the vendor folder (if it is installed for some reason). To make sure you are not copying vendor folder add:




$this->finder->notPath('vendor');



Define location of the files you are searching:




$this->finder->files()->in(__DIR__.'/../../wp-plugin-skeleton');



Loop through the results. Use yield to return values so that we can iterate results later using command-line command:




if ($this->finder->hasResults()) {
    foreach ($this->finder as $file) {
        yield $file->getRelativePathname();
    }
}



Set the return type to Generator for createNewPluginFromWpPluginSkeleton method:




public function createNewPluginFromWpSkeletonPlugin(): \Generator
{
...



Create command-line command


To build a command, create a class that will extend Symfony\Component\Console\Command\Command. Create an app/Command folder and a class named WpPluginMakerCommand with namespace App\Command inside. You can learn more about creating commands here.




<?php

namespace App\Command;

use Symfony\Component\Console\Command\Command;

class WpPluginMakerCommand extends Command
{

}



Add defaultName parameter that will be passed to the console to call your command:




protected static $defaultName = 'app:make-wp-plugin';



Next, add dependency in the constructor to your service class because we will use this command only to execute logic from that service:




<?php

namespace App\Command;

use App\Service\WPPluginMaker;
use Symfony\Component\Console\Command\Command;

class WpPluginMakerCommand extends Command
{
    protected static $defaultName = 'app:make-wp-plugin';

    /**
     * @var WPPluginMaker
     */
    protected $wpPluginMaker;

    public function __construct()
    {
        $this->wpPluginMaker = new WPPluginMaker();
        parent::__construct();
    }

}



Output results


Let’s see if the Finder found the files correctly. Add the execute method to the command class. Execute method has access to the output stream to write messages to the console:




protected function execute(InputInterface $input, OutputInterface $output): int
{
}



Loop through the results of WPPluginMaker service and output file name for each file:




$fileNames = $this->wpPluginMaker->createNewPluginFromWpPluginSkeleton();
foreach ( $fileNames as  $val ){
        $output->writeln('Writing '.$val);
    }
return Command::SUCCESS;



Run command in CLI


To be able to run the command in CLI, you need to open your console file and add your Command with Application’s add method:




$application->add(new WpPluginMakerCommand());:



The final console file looks like this:




#!/usr/bin/env php
<?php
// application.php
require __DIR__.'/../../vendor/autoload.php';

use App\Command\WpPluginMakerCommand;
use Symfony\Component\Console\Application;

$application = new Application();
$application->add(new WpPluginMakerCommand());
$application->run();



Now you can run your command inside CLI.




$ php app/bin/console app:make-wp-plugin



Conclusion


If you see the list of the files, yeey, you have it working! You have built your console and custom command that can run inside CLI without using the framework or setting up any environment other than your local device with PHP and Composer installed.


In part 2 we will add the Symfony Filesystem component to copy and manipulate files to create brand new ready-to-use plugins.


Give Kudos by sharing the post!

Share:

ABOUT AUTHOR

Anka Bajurin Stiskalov

Senior Software developer

Senior Software developer at Q. I love to develop things thinking of other developers while doing it. Let's make each other's lives easier!