mulertech/mterm

This application is a PHP CLI.

Installs: 3

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

Type:project

v1.0.2 2025-03-26 13:58 UTC

This package is auto-updated.

Last update: 2025-03-26 13:59:42 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub PHPStan Action Status Total Downloads Test Coverage

This class is a simple class to create a terminal interface for your application.

Installation

Two methods to install MTerm package with composer :

Add to your "composer.json" file into require section :

"mulertech/mterm": "^1.0"

and run the command :

php composer.phar update

Run the command :

php composer.phar require mulertech/mterm "^1.0"

Usage

MTerm provides a simple and elegant way to build interactive command-line interfaces in PHP. Below are the main classes and their methods with usage examples.

Basic Usage

$terminal = new Terminal();
$terminal->write('Hello, World!');
$terminal->writeLine('Hello with a new line!');

Terminal Class

The main class for interacting with the terminal.

Method Reference

Here's a comprehensive guide to all public methods in the Terminal class:

Reading Input

read(string $prompt = null): string

Reads a line of input from the terminal.

$name = $terminal->read('Enter your name: ');
$input = $terminal->read(); // No prompt
readChar(string $prompt = null): string

Reads a single character from the terminal.

$char = $terminal->readChar('Continue? (y/n): ');
if ($char === 'y') {
    // Process confirmation
}

Output Methods

write(string $text, string $color = null, bool $bold = false): void

Writes text to the terminal without a newline.

$terminal->write('Regular text ');
$terminal->write('Red text ', 'red');
$terminal->write('Bold blue ', 'blue', true);
writeLine(string $text, string $color = null, bool $bold = false): void

Writes text to the terminal followed by a newline.

$terminal->writeLine('First line');
$terminal->writeLine('Success message', 'green');
$terminal->writeLine('Error message', 'red', true);

Terminal Control

clear(): void

Clears the terminal screen.

$terminal->clear();
specialMode(): void

Sets the terminal to special mode where characters are read immediately.

$terminal->specialMode();
// Read characters without waiting for Enter
$terminal->normalMode(); // Return to standard mode
normalMode(): void

Restores the terminal to its normal mode.

$terminal->normalMode();
system(string $command): void

Executes a system command.

$terminal->system('ls -la');

Utility Methods

supportsAnsi(): bool

Checks if the terminal supports ANSI color codes.

if ($terminal->supportsAnsi()) {
    $terminal->writeLine('Colors supported', 'green');
}
inputStream(): resource

Returns the input stream resource.

$stream = $terminal->inputStream();

Available Colors

The Terminal class supports: black, red, green, yellow, blue, magenta, cyan, white.

Creating Interactive Menus

function showMenu($terminal) {
    $terminal->clear();
    $terminal->writeLine('=== MENU ===', 'blue', true);
    $terminal->writeLine('1. Option One');
    $terminal->writeLine('2. Exit');
    return $terminal->read('Select: ');
}

while (true) {
    $choice = showMenu($terminal);
    if ($choice === '2') break;
}

Command System

MTerm includes a robust command system for creating and managing terminal commands.

CommandInterface

This interface defines the basic structure for all commands.

class HelloCommand implements CommandInterface
{
    public function getName(): string
    {
        return 'hello';
    }
    
    public function getDescription(): string
    {
        return 'Greets a user';
    }
    
    public function execute(array $args = []): int
    {
        $name = $args[0] ?? 'World';
        $this->terminal->writeLine("Hello, $name!");
        return 0;
    }
}

AbstractCommand

A base class that implements basic functionality for CommandInterface.

class DateCommand extends AbstractCommand
{
    public function __construct(Terminal $terminal) 
    {
        parent::__construct($terminal);
        $this->name = 'date';
        $this->description = 'Shows date/time';
    }
    
    public function execute(array $args = []): int
    {
        $format = $args[0] ?? 'Y-m-d H:i:s';
        $this->terminal->writeLine(date($format));
        return 0;
    }
}

// Usage
$cmd = new DateCommand($terminal);
$cmd->execute(['Y-m-d']); // Shows date in specified format

CommandRegistry

Manages a collection of commands.

$registry = new CommandRegistry();

$registry->register(new HelloCommand($terminal));
$registry->has('hello'); // Check if exists
$command = $registry->get('date'); // Get specific command
$allCommands = $registry->getAll(); // Get all commands
$registry->execute('hello', ['User']); // Execute with arguments

Simple CLI Application

$terminal = new Terminal();
$registry = new CommandRegistry();

// Register commands
$registry->register(new HelloCommand($terminal));

// Main loop
while (true) {
    $input = $terminal->read('> ');
    $parts = explode(' ', $input);
    $commandName = array_shift($parts);
    
    if ($commandName === 'exit') break;
    
    if ($registry->has($commandName)) {
        $registry->execute($commandName, $parts);
    }
}

Application Class

The Application class implements a singleton pattern for managing terminal interactions.

Method Reference

getInstance(): Application

Gets the singleton instance of the Application class.

$app = Application::getInstance();

getTerminal(): Terminal

Returns the Terminal instance.

$terminal = $app->getTerminal();
$terminal->writeLine('Hello!');

getCommandRunner(): CommandRunner

Returns the CommandRunner instance.

$runner = $app->getCommandRunner();
$result = $runner->run('ls -la');

run(): void

Starts the application's main execution loop.

$app = Application::getInstance();
$app->run();

CommandRunner Class

The CommandRunner class provides methods to execute system commands.

Method Reference

run(string $command): array

Executes a command and returns output and return code.

$runner = new CommandRunner();
$result = $runner->run('echo "Hello"');
// Returns ['output' => ['Hello'], 'returnCode' => 0]

runWithStderr(string $command): array

Executes a command and returns stdout, stderr, and return code.

$result = $runner->runWithStderr('ls /nonexistent');
// Returns ['stdout' => '', 'stderr' => 'error message...', 'returnCode' => 1]

Combining Classes Example

$app = Application::getInstance();
$terminal = $app->getTerminal();
$runner = $app->getCommandRunner();

$command = $terminal->read('Command: ');
$result = $runner->runWithStderr($command);
$terminal->writeLine($result['stdout']);
if ($result['stderr']) {
    $terminal->writeLine($result['stderr'], 'red');
}

Form Classes

AbstractField

__construct(string $name, string $label)

Constructor for the AbstractField class.

$field = new AbstractField('username', 'Username');
$field->setDescription('Enter your username');
$field->setRequired(true);
$field->setDefault('guest');
$field->setTerminal(new Terminal());

getName(): string

Returns the name of the field.

$field->getName(); // Returns 'username'

getLabel(): string

Returns the label of the field.

$field->getLabel(); // Returns 'Username'

getDescription(): ?string

Returns the description of the field.

$field->getDescription(); // Returns 'Enter your username'

setDescription(string $description): self

Sets the description of the field.

$field->setDescription('Enter your username');

isRequired(): bool

Checks if the field is required.

$field->isRequired(); // Returns true

setRequired(bool $required = true): self

Sets whether the field is required.

$field->setRequired(true);

getDefault(): string|int|float|array|null

Returns the default value of the field.

$field->getDefault(); // Returns 'guest'

setDefault(string|int|float|array $defaultValue): self

Sets the default value of the field.

$field->setDefault('guest');

clearErrors(): void

Clears the errors of the field.

$field->clearErrors();

addValidator(ValidatorInterface $validator): self

Adds a validator to the field.

$validator = new NotEmptyValidator();
$field->addValidator($validator);

validate(string|int|float|array|null $value): array

Validates the field value.

$errors = $field->validate(''); // Returns array of errors

processInput(string $input): string|int|float|array

Processes the user input.

$value = $field->processInput('guest'); // Returns processed value

setTerminal(Terminal $terminal): self

Sets the terminal instance for the field.

$field->setTerminal(new Terminal());

CheckboxField

setCheckedValue(string $value): self

Sets the checked value for the checkbox.

$field = new CheckboxField('accept_terms', 'Accept Terms');
$field->setCheckedValue('yes');

setUncheckedValue(string $value): self

Sets the unchecked value for the checkbox.

$field->setUncheckedValue('no');

processInput(string $input): string|int|float|array

Processes the user input for the checkbox.

$value = $field->processInput('yes'); // Returns 'yes'

ColorField

validate(string|int|float|array|null $value): array

Validates the color field value.

$field = new ColorField('favorite_color', 'Favorite Color');
$errors = $field->validate('red'); // Returns array of errors

DateField

setFormat(string $format): self

Sets the date format.

$field = new DateField('birthdate', 'Birthdate');
$field->setFormat('Y-m-d');

getFormat(): string

Returns the date format.

$field->getFormat(); // Returns 'Y-m-d'

processInput(string $input): string|int|float|array

Processes the user input for the date field.

$value = $field->processInput('2022-01-01'); // Returns processed value

validate(string|int|float|array|null $value): array

Validates the date field value.

$errors = $field->validate('2022-01-01'); // Returns array of errors

EmailField

validate(string|int|float|array|null $value): array

Validates the email field value.

$field = new EmailField('email', 'Email');
$errors = $field->validate('user@example.com'); // Returns array of errors

FieldInterface

getName(): string

Returns the name of the field.

getLabel(): string

Returns the label of the field.

getDescription(): ?string

Returns the description of the field.

setDescription(string $description): self

Sets the description of the field.

isRequired(): bool

Checks if the field is required.

setRequired(bool $required = true): self

Sets whether the field is required.

clearErrors(): void

Clears the errors of the field.

setDefault(string|int|float|array $defaultValue): self

Sets the default value of the field.

getDefault(): string|int|float|array|null

Returns the default value of the field.

processInput(string $input): string|int|float|array

Processes the user input.

validate(string|int|float|array|null $value): array

Validates the field value.

setTerminal(Terminal $terminal): self

Sets the terminal instance for the field.

FileField

setAllowedExtensions(array $extensions): self

Sets the allowed file extensions.

$field = new FileField('profile_picture', 'Profile Picture');
$field->setAllowedExtensions(['jpg', 'png']);

setMaxSize(int $bytes): self

Sets the maximum file size.

$field->setMaxSize(1048576); // 1 MB

processInput(string $input): string|int|float|array

Processes the user input for the file field.

$value = $field->processInput('path/to/file.jpg'); // Returns processed value

validate(string|int|float|array|null $value): array

Validates the file field value.

$errors = $field->validate('path/to/file.jpg'); // Returns array of errors

NumberField

setMin(?float $min): self

Sets the minimum value for the number field.

$field = new NumberField('age', 'Age');
$field->setMin(18);

setMax(?float $max): self

Sets the maximum value for the number field.

$field->setMax(99);

setAllowFloat(bool $allowFloat): self

Sets whether to allow floating-point numbers.

$field->setAllowFloat(false);

processInput(string $input): string|int|float|array

Processes the user input for the number field.

$value = $field->processInput('25'); // Returns processed value

validate(string|int|float|array|null $value): array

Validates the number field value.

$errors = $field->validate('25'); // Returns array of errors

PasswordField

isMaskInput(): bool

Checks if the input should be masked.

$field = new PasswordField('password', 'Password');
$field->isMaskInput(); // Returns true

setMaskInput(bool $maskInput = true): self

Sets whether the input should be masked.

$field->setMaskInput(true);

getMaskChar(): string

Returns the mask character.

$field->getMaskChar(); // Returns '*'

setMaskChar(string $maskChar): self

Sets the mask character.

$field->setMaskChar('*');

parseInput(string $input): string

Parses the user input.

$value = $field->parseInput('password'); // Returns parsed value

processInput(string $input = ''): string

Processes the user input for the password field.

$value = $field->processInput('password'); // Returns processed value

RadioField

__construct(string $name, string $label)

Constructor for the RadioField class.

$field = new RadioField('gender', 'Gender');

setMultipleSelection(bool $multipleSelection = true): self

Sets whether multiple selection is allowed.

$field->setMultipleSelection(false);

RangeField

__construct(string $name, string $label)

Constructor for the RangeField class.

$field = new RangeField('rating', 'Rating');

setStep(int $step): self

Sets the step value for the range field.

$field->setStep(1);

getStep(): int

Returns the step value for the range field.

$field->getStep(); // Returns 1

validate(string|int|float|array|null $value): array

Validates the range field value.

$errors = $field->validate(5); // Returns array of errors

SelectField

__construct(string $name, string $label, bool $multipleSelection = false)

Constructor for the SelectField class.

$field = new SelectField('country', 'Country');

setOptions(array $options): self

Sets the options for the select field.

$field->setOptions(['USA', 'Canada', 'UK']);

setMultipleSelection(bool $multipleSelection = true): self

Sets whether multiple selection is allowed.

$field->setMultipleSelection(false);

isMultipleSelection(): bool

Checks if multiple selection is allowed.

$field->isMultipleSelection(); // Returns false

parseInput(string $input): string

Parses the user input.

$value = $field->parseInput('USA'); // Returns parsed value

processInput(string $input = ''): string|array

Processes the user input for the select field.

$value = $field->processInput('USA'); // Returns processed value

renderSelectMultipleField(Terminal $terminal): array

Renders the select field for multiple selection.

$options = $field->renderSelectMultipleField(new Terminal()); // Returns array of options

renderSelectSingleField(Terminal $terminal): string

Renders the select field for single selection.

$option = $field->renderSelectSingleField(new Terminal()); // Returns selected option

validate(string|int|float|array|null $value): array

Validates the select field value.

$errors = $field->validate('USA'); // Returns array of errors

getCurrentOption(): string

Returns the current selected option.

$field->getCurrentOption(); // Returns 'USA'

TextField

setMinLength(int $minLength): self

Sets the minimum length for the text field.

$field = new TextField('username', 'Username');
$field->setMinLength(3);

setMaxLength(?int $maxLength): self

Sets the maximum length for the text field.

$field->setMaxLength(20);

validate(string|int|float|array|null $value): array

Validates the text field value.

$errors = $field->validate('guest'); // Returns array of errors

UrlField

validate(string|int|float|array|null $value): array

Validates the URL field value.

$field = new UrlField('website', 'Website');
$errors = $field->validate('https://example.com'); // Returns array of errors

Form

__construct(Terminal $terminal)

Constructor for the Form class.

$form = new Form(new Terminal());

addField(FieldInterface $field): self

Adds a field to the form.

$field = new TextField('username', 'Username');
$form->addField($field);

handle(): void

Handles the form submission.

$form->handle();

isSubmitted(): bool

Checks if the form has been submitted.

$form->isSubmitted(); // Returns true or false

isValid(): bool

Checks if the form is valid.

$form->isValid(); // Returns true or false

getValues(): array

Returns all form values.

$values = $form->getValues(); // Returns array of values

getValue(string $fieldName): string|int|float|array|null

Returns a specific form value.

$value = $form->getValue('username'); // Returns value of 'username' field

FormRenderer

__construct(Terminal $terminal)

Constructor for the FormRenderer class.

$renderer = new FormRenderer(new Terminal());

renderField(FieldInterface $field): string|array

Renders a field.

$field = new TextField('username', 'Username');
$output = $renderer->renderField($field); // Returns rendered field

renderErrors(array $errors): void

Renders the errors.

$renderer->renderErrors(['Error 1', 'Error 2']);

clear(): void

Clears the terminal screen.

$renderer->clear();

ValidatorInterface

validate(mixed $value): ?string

Validates a value.

class CustomValidator implements ValidatorInterface
{
    public function validate($value): ?string
    {
        return $value === 'valid' ? null : 'Invalid value';
    }
}

AbstractValidator

__construct(string $errorMessage)

Constructor for the AbstractValidator class.

class CustomValidator extends AbstractValidator
{
    public function __construct()
    {
        parent::__construct('Invalid value');
    }
    
    public function validate($value): ?string
    {
        return $value === 'valid' ? null : $this->getErrorMessage();
    }
}

getErrorMessage(): string

Returns the error message.

$validator = new CustomValidator();
$errorMessage = $validator->getErrorMessage(); // Returns 'Invalid value'

ChoiceValidator

__construct(array $choices, bool $strict = true, string $errorMessage = "Selected value is not a valid choice.")

Constructor for the ChoiceValidator class.

$validator = new ChoiceValidator(['option1', 'option2']);

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('option1'); // Returns null (valid)
$error = $validator->validate('invalid'); // Returns error message (invalid)

DateValidator

__construct(string $format = 'Y-m-d', ?DateTimeInterface $minDate = null, ?DateTimeInterface $maxDate = null, ?string $errorMessage = null)

Constructor for the DateValidator class.

$validator = new DateValidator('Y-m-d');

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('2022-01-01'); // Returns null (valid)
$error = $validator->validate('invalid-date'); // Returns error message (invalid)

EmailValidator

__construct(string $errorMessage = "Please enter a valid email address.")

Constructor for the EmailValidator class.

$validator = new EmailValidator();

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('user@example.com'); // Returns null (valid)
$error = $validator->validate('invalid-email'); // Returns error message (invalid)

IpAddressValidator

__construct(bool $allowIPv4 = true, bool $allowIPv6 = true, bool $allowPrivate = true, bool $allowReserved = true, string $errorMessage = "Please enter a valid IP address.")

Constructor for the IpAddressValidator class.

$validator = new IpAddressValidator();

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('192.168.0.1'); // Returns null (valid)
$error = $validator->validate('invalid-ip'); // Returns error message (invalid)

LengthValidator

__construct(?int $min = null, ?int $max = null, ?string $errorMessage = null)

Constructor for the LengthValidator class.

$validator = new LengthValidator(3, 20);

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('valid'); // Returns null (valid)
$error = $validator->validate(''); // Returns error message (invalid)

NotEmptyValidator

__construct(string $errorMessage = "This value cannot be empty.")

Constructor for the NotEmptyValidator class.

$validator = new NotEmptyValidator();

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('valid'); // Returns null (valid)
$error = $validator->validate(''); // Returns error message (invalid)

NumericRangeValidator

__construct(?float $min = null, ?float $max = null, ?string $errorMessage = null)

Constructor for the NumericRangeValidator class.

$validator = new NumericRangeValidator(1, 100);

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate(50); // Returns null (valid)
$error = $validator->validate(200); // Returns error message (invalid)

PatternValidator

__construct(string $pattern, string $errorMessage = "Value does not match required pattern.")

Constructor for the PatternValidator class.

$validator = new PatternValidator('/^[a-z]+$/');

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('valid'); // Returns null (valid)
$error = $validator->validate('123'); // Returns error message (invalid)

RegexValidator

__construct(string $pattern, string $errorMessage = "This value is not valid.")

Constructor for the RegexValidator class.

$validator = new RegexValidator('/^[a-z]+$/');

validate(mixed $value): ?string

Validates a value.

$error = $validator->validate('valid'); // Returns null (valid)
$error = $validator->validate('123'); // Returns error message (invalid)

Utils Classes

ProgressBar

__construct(Terminal $terminal, int $total = 100, int $width = 50, string $completeChar = '=', string $incompleteChar = '-', string $color = Terminal::COLORS['green'])

Constructor for the ProgressBar class.

$terminal = new Terminal();
$progressBar = new ProgressBar($terminal, 100, 50, '=', '-', 'green');

start(): void

Starts the progress bar.

$progressBar->start();

advance(int $step = 1): void

Advances the progress bar by a specific amount.

$progressBar->advance(10);

setProgress(int $current): void

Sets the progress to a specific value.

$progressBar->setProgress(50);

finish(): void

Finishes the progress bar.

$progressBar->finish();

TableFormatter

__construct(Terminal $terminal, string $headerColor = Terminal::COLORS['green'], string $borderColor = Terminal::COLORS['blue'], string $cellColor = Terminal::COLORS['white'], int $padding = 1)

Constructor for the TableFormatter class.

$terminal = new Terminal();
$tableFormatter = new TableFormatter($terminal, 'green', 'blue', 'white', 1);

renderTable(array $headers, array $rows): void

Formats and renders a table.

$headers = ['Name', 'Age', 'Country'];
$rows = [
    ['John', 25, 'USA'],
    ['Jane', 30, 'Canada'],
    ['Doe', 22, 'UK']
];

$tableFormatter->renderTable($headers, $rows);