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
Requires
- php: ^8.2
- ext-mbstring: *
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3
- mulertech/docker-tests: ^1
- phpstan/phpstan: ^2
- phpunit/phpunit: ^11
- roave/security-advisories: dev-latest
README
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);