DEV Community

Cover image for Creating a simple app using Minicli
Simonarde Lima
Simonarde Lima

Posted on • Updated on

Creating a simple app using Minicli

Minicli is an experimental dependency-free toolkit for building CLI-only applications in PHP created by @erikaheidi.

In this example, we are going to build a simple app to show some info about a chosen Pokemon.

To get started, you'll need:

Creating a Simple App

First, we need to create a new project using Minicli template app, using your terminal of choice, enter the following command:

composer create-project --prefer-dist minicli/application pokemonApiConsumer

This will give us a starting point to build our app.

Creating a command

Minicli will register all commands inside the directory app/Command.
The name you give to a folder inside Command is the name of your Command Namespace, so, in this example, we will create a folder called Pokemon. Cd to our app root folder and type the following command:

cd pokemonApiConsumer
mkdir app/Command/Pokemon
Enter fullscreen mode Exit fullscreen mode

Now, we have to create our Controller file, this is the actual name of the command you want to execute, so, in this example, we will create a command called fetchinfo:

cd app/Command/Pokemon
touch FetchInfoController.php
Enter fullscreen mode Exit fullscreen mode

Put the following code inside FetchInfoController:

<?php
namespace App\Command\Pokemon;
use Minicli\Command\CommandController;
use Minicli\Output\Filter\ColorOutputFilter;
use Minicli\Output\Helper\TableHelper;
class FetchInfoController extends CommandController
{
    public $baseApi = 'https://pokeapi.co/api/v2';
    public function handle()
    {
        if( empty($this->hasParam('name')) ) {
            $this->getPrinter()->error("Please, inform the name of Pokemon you want to fetch info.");
            $this->getPrinter()->error("Usage: ./minicli pokemon fetchinfo name=\"bulbasaur\"");
            return;
        }
        $name = $this->getParam('name');
        $this->getPrinter()->display('Showing info about ' . $name);
        $this->fetchPokemonInfo($name);
    }
    public function fetchPokemonInfo($name)
    {
        // code
    }
    public function printPokemonTableInfo($info)
    {
        // code
    }
    public function get($url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
    }
}
Enter fullscreen mode Exit fullscreen mode

We will implement fetchPokemonInfo and printPokemonInfo in a minute, but, right now, you can call your command to see if works using:

./minicli pokemon fetchinfo name="bulbasaur"
Enter fullscreen mode Exit fullscreen mode

* remember, you have to execute this command from the root of your app.

You should see something like:

Showing info about bulbasaur

Implementing fetchPokemonInfo

In this example, we are using PokeAPI. To pull the info about our chosen pokemon, we are going to use the following endpoint https://pokeapi.co/api/v2/pokemon/<name>, and, if you see the code we have putted inside FetchInfoController.php, we have a method called get, which uses curl to make a request to a given url. Let's use it then, inside FetchInfoController.php:

public function fetchPokemonInfo($name)
{
    $pokemonInfo = $this->get($this->baseApi . '/pokemon/' . $name);
}
Enter fullscreen mode Exit fullscreen mode

If you run fetchinfo command again, you will not see any new output, that's because we are making the request to PokeAPI, but not showing anywhere. Let's fix this!

Implementing printPokemonTableInfo

Now we will display the info PokeAPI has returned in your last request. Open FetchInfoController.php and replace printPokemonTableInfo content with the following:

public function printPokemonTableInfo($info)
{
    $info = json_decode($info, true);
    $table = new TableHelper();
    $table->addHeader(['Name', 'Height', 'Weight']);
    $table->addRow([ucfirst($info['name']), $info['height'], $info['weight']]);
    $table->addHeader(['Type', '', '']);
    array_map(function($item) use ($table) {
        $table->addRow([$item['type']['name']]);
    }, $info['types']);
    $table->addHeader(['Moves', '', '']);
    array_map(function($item) use ($table) {
        $table->addRow([str_replace('-', ' ', $item['move']['name'])]);
    }, $info['moves']);
    $this->getPrinter()->rawOutput($table->getFormattedTable(new ColorOutputFilter()));
    $this->getPrinter()->newline();
}
Enter fullscreen mode Exit fullscreen mode

If you run fetchinfo command again, you will notice that the info will not be shown to us. That's because we have implemented the printPokemonTableInfo, but we are not calling it. Let's call it then:

public function fetchPokemonInfo($name)
{
    $pokemonInfo = $this->get($this->baseApi . '/pokemon/' . $name);
    $this->printPokemonTableInfo($pokemonInfo);
}
Enter fullscreen mode Exit fullscreen mode

Now, run fetchinfo again:

./minicli pokemon fetchinfo name="bulbasaur"
Enter fullscreen mode Exit fullscreen mode

You should see some info now! Have fun!

You can see the complete code here.

* disclaimer: this is a very basic piece of code, and it is, by no means, the best and the cleanest way to implement a command using Minicli.

Top comments (0)