PHP Classes

CYMAPGT Console: Manage services to handle console commands

Recommend this page to a friend!
  Info   View files Example   Videos Videos   View files View files (21)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog    
Ratings Unique User Downloads Download Rankings
Not enough user ratingsTotal: 97 This week: 1All time: 9,825 This week: 560Up
Version License PHP version Categories
cymapgt-console 1.0.4BSD License5.4PHP 5, Console
Description 

Author

This package can manage services to handle console commands.

It can add, remove, replace and route to service classes that will handle commands entered in a console by the user.

The package can also display help text that will tell the user how each of the commands should be entered to pass options of those commands.

Innovation Award
PHP Programming Innovation award nominee
July 2017
Number 6
One way to structure better the components of an application is to build service components that can be called to provide separate services.

This package provides a means to use service components to implement different functionality for a console application.

Different components can be called based on the options that the user passed in the command line.

Manuel Lemos
Picture of Cyril Ogana
  Performance   Level  
Name: Cyril Ogana is available for providing paid consulting. Contact Cyril Ogana .
Classes: 4 packages by
Country: Kenya Kenya
Age: ???
All time rank: 14893 in Kenya Kenya
Week rank: 416 Up2 in Kenya Kenya Up
Innovation award
Innovation award
Nominee: 2x

Example

<?php
require('../vendor/autoload.php');

use
cymapgt\Exception\NetConsoleException;
use
cymapgt\core\utility\console\ConsoleManager;
use
cymapgt\core\utility\console\helper\ConsoleCredentials;
use
Hoa\Console\Readline\Readline;
use
Hoa\Console\Readline\Password;
use
Hoa\Console\Cursor;
use
Hoa\Console\Parser;

//instantiate the readline items
$readLine = new Readline();
$readPass = new Password();

//default level is in loginuserprompt (to load the userprompt screen)
$level = 'loginuserprompt';

//the main activity listening loop (implementing services may implement 1 of theirs in the execute function
do {
    if (
$level == 'loginpassprompt') {
       
$line = $readPass->readLine('');
    } elseif (
$level == 'loginuserprompt') {
       
Cursor::colorize('bold');
        echo
"[cymapgt-netconsole] \n";
       
Cursor::colorize('!bold');
       
$line = null;
    } else {
       
$line = $readLine->readLine('');
    }
   
   
//If user is logged in, display netconsole> prompt
   
if (ConsoleCredentials::$isLoggedIn) {
        echo
'netconsole> ';
    } else {
        echo
'> ';
    }
   
   
//update level for the next listening loop
   
$level = processCommand($line, $level);
} while (
false !== $line && 'quit' !== $line);

/**
 * Basic routing of the appropriate command input by user
 *
 * @param string $line
 * @param string $level
 */
function processCommand($line, $level) {
    switch (
$level) {
        case
'loginuserprompt':
            echo
netecho("\tUsername: ");
            return
'loginuserprocess';
        case
'loginuserprocess':
           
loginuserprocess($line);
            echo
netecho("\tPassword: ");
            return
'loginpassprompt';
        case
'loginpassprompt':
           
loginpassprompt($line);
            return
'commandprompt';
        case
'commandprompt':
           
commandprompt($line);
            return
'commandprompt';
    }
}

/**
 * Process the username validation
 *
 * @param string $line
 */
function loginuserprocess($line) {
    if (!(
preg_match('/^[a-zA-Z0-9]*$/', $line))) {
        echo
"\tUsername must be an alphanumeric entity\n";
        exit;
    }
   
   
ConsoleCredentials::$username = $line;
}

/**
 * Process the user credentials validation
 *
 * @param string $line
 *
 */
function loginpassprompt($line) {
   
ConsoleCredentials::$password = $line;
   
    try {
       
$loginResult = ConsoleCredentials::authenticate();
    } catch (
NetConsoleException $ncException) {
        echo
"\tWrong username / password combination or user not set in db\n";
        exit;
    }

   
//handle wrong credentials
   
if ($loginResult !== true) {
        echo
"\tWrong username / password combination\n";
        exit;
    } else {
       
ConsoleCredentials::$isLoggedIn = true;
       
Cursor::colorize('bold');
        echo
"Welcome to the CymapGT NetConsole.\n\n";
        echo
"Copyright (c) 2017, CYMAP Business Solutions, Gomersol Technologies.\n\n";
        echo
"Input a registered api name to access CGT package console functionality.\n";
        echo
"Use the 'add' command to enroll a new package namespace to the console environment\n";
        echo
"Use 'replace' command to update an existing packages details\n";
        echo
"Similarly, the 'remove' command deregisters a namespace from the environment\n";
        echo
"or the 'quit' command to exit.\n";
       
Cursor::colorize('!bold');
        echo
neteol();
        return
true;
    }
}

/**
 * Handle processing of console commands as well as routing / dispatching
 *
 * @param string $line
 */
function commandprompt($line) {
   
$commandParser = new Parser();
   
$commandParser->parse($line);
   
$commandSwitches = $commandParser->getSwitches();
   
$commandInputs = $commandParser->getInputs();
   
    if (!
count($commandInputs)) {
        echo
"Oops! You have not input any command into the console" . neteol();
        return;
    }
   
   
$apiName = $commandInputs[0];

   
$serviceName = 'console';
   
$serviceNamespace = '\cymapgt\core\utility\console\ConsoleManager';
           
    switch (
$apiName) {
        case
'add':
            if (!
count($commandSwitches) == 0) {
                echo
"Some command switches were found. Issuing the add command requires no switching!\n";
                echo
"netconsole>";
                return;
            }
           
            if (
                !(isset(
$commandInputs[1]))
                || !(isset(
$commandInputs[2]))
            ) {
                echo
"The add command expects a service name and a service namespace!\n" . neteol();
                return;
            }
           
           
$serviceName = $commandInputs[1];
           
$serviceNamespace = $commandInputs[2];
           
ConsoleManager::add($serviceName, $serviceNamespace);
            break;
        case
'replace':
            if (!
count($commandSwitches) == 0) {
                echo
"Some command switches were found. Issuing the replace command requires no switching!\n";
                echo
"netconsole>";
                return;
            }
           
            if (
                !(isset(
$commandInputs[1]))
                || !(isset(
$commandInputs[2]))
            ) {
                echo
"The replace command expects a service name and a service namespace!\n" . neteol();
                return;
            }
           
           
$serviceName = $commandInputs[1];
           
$serviceNamespace = $commandInputs[2];
           
ConsoleManager::replace($serviceName, $serviceNamespace);
            break;
        case
'remove':
            if (!
count($commandSwitches) == 0) {
                echo
"Some command switches were found. Issuing the remove command requires no switching!" . neteol();
                return;
            }
           
            if (
                !(isset(
$commandInputs[1]))
            ) {
                echo
"The remove command expects a service name" . neteol();
                return;
            }
           
           
$serviceName = $commandInputs[1];
           
ConsoleManager::remove($serviceName);
            break;
        case
'help':
           
//1 - command name must be set
           
if (!isset($commandInputs[1])) {
                echo
"The help command expects one command name (the Service name)" . neteol();
                return;
            }
           
            try {
               
//2 - optional switches
                //no verbosity no methodname
               
if (
                    ! isset(
$commandSwitches['v'])
                    && ! (isset(
$commandSwitches['m']))
                ) {
                   
$helpVerbosity = null;
                   
$methodName = null;
                   
$methodUsageArr = ConsoleManager::help($commandInputs[1]);
                }

               
//verbosity and method name
               
if (
                    isset(
$commandSwitches['v'])
                    && (isset(
$commandSwitches['m']))
                ) {
                   
$helpVerbosity = $commandSwitches['v'];
                   
$methodName = $commandSwitches['m'];
                   
$methodUsageArr = ConsoleManager::help($commandInputs[1], $commandSwitches['v'], $commandSwitches['m']);
                }

               
//verbosity without method name
               
if (
                    isset(
$commandSwitches['v'])
                    && ! (isset(
$commandSwitches['m']))
                ) {
                   
$helpVerbosity = $commandSwitches['v'];
                   
$methodName = null;
                   
$methodUsageArr = ConsoleManager::help($commandInputs[1], $commandSwitches['v']);
                }

               
//method name without verbosity
               
if (
                    !isset(
$commandSwitches['v'])
                    && (isset(
$commandSwitches['m']))
                ) {
                   
$helpVerbosity = null;
                   
$methodName = null;
                   
$methodUsageArr = ConsoleManager::help($commandInputs[1], 1, $commandSwitches['m']);
                }
            } catch (
NetConsoleException $ncException) {
                echo
$ncException->getMessage(). neteol();
                return;
            }
           
           
//die(print_r($methodUsageArr));
           
foreach ($methodUsageArr as $methodName => $methodUsageItem) {
               
Cursor::colorize('bold underlined');
                echo
PHP_EOL.'SERVICE NAME: ' . $commandInputs[1].PHP_EOL;
                echo
'Method Name: ' . $methodName.PHP_EOL.PHP_EOL;
               
Cursor::colorize('!bold !underlined');
               
Cursor::colorize('bold');
                echo
"USAGE:".PHP_EOL;
               
Cursor::colorize('!bold');
                echo
$methodName;

                if (
                    isset(
$methodUsageItem['commands'])
                    &&
is_array($methodUsageItem['commands'])
                ) {
                    foreach (
$methodUsageItem['commands'] as $methodUsageItemCommand) {
                        echo
' ' . $methodUsageItemCommand;
                    }
                }

                if (
                    isset(
$methodUsageItem['flags'])
                    &&
is_array($methodUsageItem['flags'])
                ) {
                    foreach (
$methodUsageItem['flags'] as $methodUsageItemFlag) {
                        if (
$methodUsageItemFlag['required'] === true) {
                           
$methodUsageItemFlagPrefix = '';
                           
$methodUsageItemFlagSuffix = '';
                        } else {
                           
$methodUsageItemFlagPrefix = '[';
                           
$methodUsageItemFlagSuffix = ']';
                        }
                        echo
' ' . $methodUsageItemFlagPrefix . $methodUsageItemFlag['flag'] . $methodUsageItemFlagSuffix;
                    }
                }

               
Cursor::colorize('underlined');
                echo
PHP_EOL . PHP_EOL . 'COMMANDS AND SWITCHES:'.PHP_EOL;
               
Cursor::colorize('!underlined');

                if (
                    isset(
$methodUsageItem['commands'])
                    &&
is_array($methodUsageItem['commands'])
                ) {
                    
Cursor::colorize('underlined');
                    echo
'* COMMANDS'.PHP_EOL.PHP_EOL;
                    
Cursor::colorize('!underlined');
                    foreach (
$methodUsageItem['commands'] as $methodUsageItemCommand) {
                       
$methodUsageItemCommandDocs = $methodUsageItem['args'][($methodUsageItemCommand)]['docs'];
                       
$verbosityLevel = $helpVerbosity;

                        if (
                           
$verbosityLevel < 0
                           
|| $verbosityLevel > count($methodUsageItemCommandDocs)
                            ||
$helpVerbosity == null
                       
) {
                           
$verbosityLevel = 1;
                        }

                        echo
$methodUsageItemCommand;

                        if (
$verbosityLevel > 0) {
                           
$methodUsageItemCommandDocsSliced = array_slice($methodUsageItemCommandDocs, 0, $verbosityLevel);
                            echo
"\t - " . implode($methodUsageItemCommandDocsSliced).PHP_EOL.PHP_EOL;
                        }
                    }
                }

                if (
                    isset(
$methodUsageItem['flags'])
                    &&
is_array($methodUsageItem['flags'])
                ) {
                    
Cursor::colorize('underlined');
                    echo
'* SWITCHES'.PHP_EOL.PHP_EOL;
                    
Cursor::colorize('!underlined');
                    foreach (
$methodUsageItem['flags'] as $methodUsageItemFlagName => $methodUsageItemFlag) {
                        if (
$methodUsageItemFlag['required'] === true) {
                           
$methodUsageItemFlagPrefix = '';
                           
$methodUsageItemFlagSuffix = '';
                        } else {
                           
$methodUsageItemFlagPrefix = '';
                           
$methodUsageItemFlagSuffix = '';
                        }

                        echo
' ' . $methodUsageItemFlagPrefix . str_replace('="..."',"",$methodUsageItemFlag['flag']) . $methodUsageItemFlagSuffix;

                       
$methodUsageItemCommandDocs = $methodUsageItem['args'][($methodUsageItemFlagName)]['docs'];
                       
$verbosityLevel = $helpVerbosity;

                        if (
                           
$verbosityLevel < 0
                           
|| $verbosityLevel > count($methodUsageItemCommandDocs)
                            ||
$helpVerbosity == null
                       
) {
                           
$verbosityLevel = 1;
                        }

                        if (
$verbosityLevel > 0) {
                           
$methodUsageItemCommandDocsSliced = array_slice($methodUsageItemCommandDocs, 0, $verbosityLevel);
                            echo
"\t - " . implode($methodUsageItemCommandDocsSliced).PHP_EOL.PHP_EOL;
                        }
                    }
                }
            }
            echo
neteol();
            break;
        case
'quit':
            echo
'netconsole say bye bye...'.PHP_EOL;
            exit();
        default:
           
//1 - service and method name must be set
           
if (
                !isset(
$commandInputs[0])
                && !isset(
$commandInputs[1])
            ) {
                echo
"Service calls expect at least the service name and one command to be input" . neteol();
                return;
            }
           
           
//allocate the flags to variables
           
$serviceName = (string) $commandInputs[0];
           
            try {
               
//route the command
               
ConsoleManager::route($serviceName, $commandInputs, $commandSwitches);
            } catch (
NetConsoleException $rtException) {
                echo
$rtException->getMessage(). neteol();
                return;
            }
        }

    return;
}

/**
 * Echo string but place prompt beforehand
 *
 * @param string $printString
 */
function netecho($printString) {
    return
' ' . $printString;
}

/**
 * Echo end of line then a netconsole prompt
 */
function neteol() {
    return
PHP_EOL . 'netconsole>';
}

/**
 * Enetconsole prompt
 */
function netprompt() {
    return
'netconsole>';
}


Details

console

package for exposing PHP services via a console interface, providing build in authentication if needed

Description

The console package allows other packages to implement an interface that allows them to provide command line functionality to their classes in with minimal duplication of code. A NetConsoleInterface aware class can be registered to the console API; which offers among other things automatic help generation as well as an authentication interface prior to accessing registered namespaces.

Installing

Install application via Composer

require "cymapgt/console" : "^1.0.0"

Usage

Overview

  • Authenticate the console user (named console) to the Service
  • Provide interface to add services to the API
  • Provide interface to remove services from the API
  • Provide interface to amend a service using the API
  • Provide interface to display usage for the API
  • Provide interface to delegate actual API calls to the registered services

Using the Console package

Writing a NetConsole aware class

The package comes with two demo Classes that implement the NetConsoleInterface. See the files src/DemoApi.php and src/DemoRpi.php for template which you can use to implement your NetConsole class. Copy the files and customize as required.

Authentication to NetConsole

The default NetConsole authentication comes with some assumptions:

1.You auth data store is a database, with a table named user; and fields for username and password

2.You have an active user named console in the datastore


If you adhere to the above, your console authentication will work out of the box (assuming as well that the NetworkBootstrap is properly configured).

If you would like to implement your own Authentication, replace the file src/helper/ConsoleCredentials.php and in it

1.Create a class named ConsoleCredentials

2.Creat a public static method named authenticate() that will implement your custom authentication logic

Core NetConsole Commands

The core of NetConsole implements the NetConsoleInterface. There are a number of reserved keywords:

1.ADD COMMAND:

add serviceName serviceNamespace

COMMANDS AND SWITCHES:

COMMANDS

serviceName - The name of the service as registered in the console, or one of the sticky services.

serviceNamespace - The fully qualified namespace for the service being registered to the netconsole API

SWITCHES

None

EXAMPLE:

add bootstrap cymapgt\core\utility\bootstrap\console\BootstrapConsole;

2.HELP COMMAND:

help serviceName [-v="..."] [-m="..."]

COMMANDS AND SWITCHES:

COMMANDS

serviceName - The name of the service as registered in the console, or one of the sticky services.

SWITCHES

-v - The verbosity level of the help documentation

-m - Specifying a method name here will filter the help to provide only docs for that specific method

EXAMPLES

help bootstrap -m=config-all -v=3

help add

3.REMOVE COMMAND:

remove serviceName

COMMANDS AND SWITCHES:

COMMANDS

serviceName - The name of the service as registered in the console, or one of the sticky services.

SWITCHES

None

EXAMPLE:

remove bootstrap

4.QUIT COMMAND:

quit

COMMANDS AND SWITCHES:

COMMANDS

None

SWITCHES

None

EXAMPLE:

quit

5.CUSTOM COMMANDS:

Your PHP services functionality is exposed by implementing the NetConsoleInterface

After this implementation, you need to register your package with NetConsole by using the add command.

Successfully adding the package will expose all of the commands and switches you defined in the console configuration. The package can thus be used for managing tasks such as application installations within a controlled environment if you are distributing your proprietary logic.

It can also be used to quickly convert PHP services to console applications.

Testing

PHPUnit Tests are provided with the package

Contribute

  • Email @rhossis or contact via Skype
  • You will be added as author for contributions

License

BSD 3-clause


  Files folder image Files  
File Role Description
Files folder imagebin (2 files)
Files folder imagesrc (4 files, 4 directories)
Files folder imagetests (2 directories)
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file composer.lock Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files  /  bin  
File Role Description
  Accessible without login Plain text file netconsole Data Auxiliary data
  Accessible without login Plain text file netconsole.php Example Example script

  Files folder image Files  /  src  
File Role Description
Files folder imageabstractclass (1 file)
Files folder imageconfig (2 files)
Files folder imageException (1 file)
Files folder imagehelper (3 files)
  Plain text file ConsoleManager.php Class Class source
  Plain text file DemoApi.php Class Class source
  Plain text file DemoRpi.php Class Class source
  Plain text file NetConsole.php Class Class source

  Files folder image Files  /  src  /  abstractclass  
File Role Description
  Plain text file NetConsoleInterface.php Class Class source

  Files folder image Files  /  src  /  config  
File Role Description
  Plain text file ConsoleConfig.php Class Class source
  Accessible without login Plain text file NamedConstant.php Aux. Auxiliary script

  Files folder image Files  /  src  /  Exception  
File Role Description
  Plain text file NetConsoleException.php Class Class source

  Files folder image Files  /  src  /  helper  
File Role Description
  Plain text file ConsoleCredentials.php Class Class source
  Plain text file ConsoleEcho.php Class Class source
  Plain text file ConsoleRegister.php Class Class source

  Files folder image Files  /  tests  
File Role Description
Files folder imagefiles (2 files)
Files folder imagesrc (2 files)

  Files folder image Files  /  tests  /  files  
File Role Description
  Accessible without login Plain text file bootstrap.php Aux. Auxiliary script
  Accessible without login Plain text file phpunit.xml Data Auxiliary data

  Files folder image Files  /  tests  /  src  
File Role Description
  Plain text file ConsoleManagerTest.php Class Class source
  Plain text file NetConsoleTest.php Class Class source

 Version Control Unique User Downloads Download Rankings  
 100%
Total:97
This week:1
All time:9,825
This week:560Up