Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable using commands containing underscores #1365

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 57 additions & 6 deletions src/Telegram.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,18 +283,17 @@ public function getCommandsList(): array

foreach ($files as $file) {
//Remove "Command.php" from filename
$command = $this->sanitizeCommand(substr($file->getFilename(), 0, -11));
$command_name = mb_strtolower($command);
$command = $this->classNameToCommandName(substr($file->getFilename(), 0, -4));

if (array_key_exists($command_name, $commands)) {
if (array_key_exists($command, $commands)) {
continue;
}

require_once $file->getPathname();

$command_obj = $this->getCommandObject($command, $file->getPathname());
if ($command_obj instanceof Command) {
$commands[$command_name] = $command_obj;
$commands[$command] = $command_obj;
}
}
} catch (Exception $e) {
Expand Down Expand Up @@ -334,7 +333,7 @@ public function getCommandClassName(string $auth, string $command, string $filep
return null;
}

$command_class = $command_namespace . '\\' . $this->ucFirstUnicode($command) . 'Command';
$command_class = $command_namespace . '\\' . $this->commandNameToClassName($command);

if (class_exists($command_class)) {
return $command_class;
Expand Down Expand Up @@ -678,7 +677,7 @@ public function executeCommand(string $command): ServerResponse
}

/**
* Sanitize Command
* @deprecated
*
* @param string $command
*
Expand Down Expand Up @@ -1285,4 +1284,56 @@ public function getUpdateFilter(): ?callable
{
return $this->update_filter;
}

/**
* Converts the name of a class into the name of a command.
*
* @param string $class For example FooBarCommand
*
* @return string for example foo_bar. In case of errors, returns an empty string
*/
protected function classNameToCommandName(string $class): string
{
if (!preg_match('/^(.+)Command$/', $class, $matches)) {
mlocati marked this conversation as resolved.
Show resolved Hide resolved
return '';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning an empty string if no command is found, is not good style. Should return null instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning an empty string if no command is found, is not good style.

I usually agree, except the cases when an empty string is not a valid value (like this case).
To check if the return value is valid we'd need to check if it's not null OR is an empty string: by avoiding null we simply have to check for empty strings.

}
$temp = $matches[1];
$chunks = [];
$currentUpperCaseLetter = '';
while ($temp !== '') {
if (!preg_match('/\p{Lu}/u', $temp, $match, PREG_OFFSET_CAPTURE)) {
break;
}
// $match[0][0] contains first upper case character
// $match[0][1] contains the start position (in bytes) of the first upper case character
[$upperCaseLetter, $upperCaseLetterOffset] = $match[0];
if ($upperCaseLetterOffset > 0) {
$chunks[] = $currentUpperCaseLetter . substr($temp, 0, $upperCaseLetterOffset);
} elseif ($currentUpperCaseLetter !== '') {
$chunks[] = $currentUpperCaseLetter;
}
$temp = substr($temp, $upperCaseLetterOffset + strlen($upperCaseLetter));
$currentUpperCaseLetter = $upperCaseLetter;
}
$lastChunk = $currentUpperCaseLetter . $temp;
if ($lastChunk !== '') {
$chunks[] = $lastChunk;
}
return implode('_', array_map('mb_strtolower', $chunks));
mlocati marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Converts a command name into the name of a class.
*
* @param string $command For example foo_bar
*
* @return string for example FooBarCommand. In case of errors, returns an empty string
*/
protected function commandNameToClassName(string $command): string
{
if ($command === '') {
return '';
}
return str_replace(' ', '', $this->ucWordsUnicode(str_replace('_', ' ', $command))) . 'Command';
}
}
6 changes: 3 additions & 3 deletions tests/Unit/Commands/CustomTestCommands/DummyAdminCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
use Longman\TelegramBot\Request;

/**
* Test "/dummyadmin" command
* Test "/dummy_admin" command
*/
class DummyAdminCommand extends AdminCommand
{
/**
* @var string
*/
protected $name = 'dummyadmin';
protected $name = 'dummy_admin';

/**
* @var string
Expand All @@ -33,7 +33,7 @@ class DummyAdminCommand extends AdminCommand
/**
* @var string
*/
protected $usage = '/dummyadmin';
protected $usage = '/dummy_admin';

/**
* Command execute method
Expand Down
6 changes: 3 additions & 3 deletions tests/Unit/Commands/CustomTestCommands/DummySystemCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
use Longman\TelegramBot\Request;

/**
* Test "/dummysystem" command
* Test "/dummy_system" command
*/
class DummySystemCommand extends SystemCommand
{
/**
* @var string
*/
protected $name = 'dummysystem';
protected $name = 'dummy_system';

/**
* @var string
Expand All @@ -33,7 +33,7 @@ class DummySystemCommand extends SystemCommand
/**
* @var string
*/
protected $usage = '/dummysystem';
protected $usage = '/dummy_system';

/**
* Command execute method
Expand Down
6 changes: 3 additions & 3 deletions tests/Unit/Commands/CustomTestCommands/DummyUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
use Longman\TelegramBot\Request;

/**
* Test "/dummyuser" command
* Test "/dummy_user" command
*/
class DummyUserCommand extends UserCommand
{
/**
* @var string
*/
protected $name = 'dummyuser';
protected $name = 'dummy_user';

/**
* @var string
Expand All @@ -33,7 +33,7 @@ class DummyUserCommand extends UserCommand
/**
* @var string
*/
protected $usage = '/dummyuser';
protected $usage = '/dummy_user';

/**
* Command execute method
Expand Down
6 changes: 3 additions & 3 deletions tests/Unit/TelegramTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ public function testAddCustomCommandsClass(): void
]);

$command_classes = $tg->getCommandClasses();
self::assertCount(1, $command_classes['System']);
self::assertCount(1, $command_classes['Admin']);
self::assertCount(1, $command_classes['User']);
self::assertSame(['dummy_system' => 'Dummy\SystemCommands\DummySystemCommand'], $command_classes['System']);
self::assertSame(['dummy_admin' => 'Dummy\AdminCommands\DummyAdminCommand'], $command_classes['Admin']);
self::assertSame(['dummy_user' => 'Dummy\UserCommands\DummyUserCommand'], $command_classes['User']);
}

public function testSettingDownloadUploadPaths(): void
Expand Down