diff options
Diffstat (limited to 'source')
34 files changed, 3636 insertions, 0 deletions
diff --git a/source/AbstractApplication.php b/source/AbstractApplication.php new file mode 100644 index 0000000..5966447 --- /dev/null +++ b/source/AbstractApplication.php @@ -0,0 +1,650 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class AbstractApplication + * This class is doing a lot. See it as class that is the + * - Application + * - Factory + * - ServiceLocator + */ +abstract class AbstractApplication +{ + /** + * @var array + */ + private $arguments = array(); + + /** + * @var array + */ + private $chatConfiguration = array(); + + /** + * @var array + */ + private $channels = array(); + + /** + * @var array + */ + private $instancePool; + + /** + * @var array + */ + private $roles = array(); + + /** + * @var array + */ + private $users = array(); + + //begin of command + /** + * @return Command_Backup + */ + public function getBackupCommand() + { + if ($this->isNotInInstancePool('command_backup')) { + $command = new Command_Backup(); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setPathConfiguration($this->getPathConfiguration()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool('command_backup', $command); + } + + return $this->getFromInstancePool('command_backup'); + } + + /** + * @return Command_Channel + */ + public function getChannelCommand() + { + if ($this->isNotInInstancePool('channel_command')) { + $command = new Command_Channel(); + $command->setApplication($this); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'channel_command', + $command + ); + } + + return $this->getFromInstancePool('channel_command'); + } + + /** + * @return Command_Channel_Add + */ + public function getChannelAddCommand() + { + if ($this->isNotInInstancePool('channel_add_command')) { + $command = new Command_Channel_Add(); + $command->setChannelFile($this->getChannelFile()); + $command->setChannels($this->getChannels()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'channel_add_command', + $command + ); + } + + return $this->getFromInstancePool('channel_add_command'); + } + + /** + * @return Command_Channel_Delete + */ + public function getChannelDeleteCommand() + { + if ($this->isNotInInstancePool('channel_delete_command')) { + $command = new Command_Channel_Delete(); + $command->setChannelFile($this->getChannelFile()); + $command->setChannels($this->getChannels()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'channel_delete_command', + $command + ); + } + + return $this->getFromInstancePool('channel_delete_command'); + } + + /** + * @return Command_Channel_Edit + */ + public function getChannelEditCommand() + { + if ($this->isNotInInstancePool('channel_edit_command')) { + $command = new Command_Channel_Edit(); + $command->setChannelFile($this->getChannelFile()); + $command->setChannels($this->getChannels()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'channel_edit_command', + $command + ); + } + + return $this->getFromInstancePool('channel_edit_command'); + } + + /** + * @return Command_Channel_List + */ + public function getChannelListCommand() + { + if ($this->isNotInInstancePool('channel_list_command')) { + $command = new Command_Channel_List(); + $command->setChannelFile($this->getChannelFile()); + $command->setChannels($this->getChannels()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'channel_list_command', + $command + ); + } + + return $this->getFromInstancePool('channel_list_command'); + } + + /** + * @return Command_Install + */ + public function getInstallCommand() + { + if ($this->isNotInInstancePool('install_command')) { + $command = new Command_Install(); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setPathConfiguration($this->getPathConfiguration()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'install_command', + $command + ); + } + + return $this->getFromInstancePool('install_command'); + } + + /** + * @return Command_Restore + */ + public function getRestoreCommand() + { + if ($this->isNotInInstancePool('restore_command')) { + $command = new Command_Restore(); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setPathConfiguration($this->getPathConfiguration()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'restore_command', + $command + ); + } + + return $this->getFromInstancePool('restore_command'); + } + + /** + * @return Command_Upgrade + */ + public function getUpgradeCommand() + { + if ($this->isNotInInstancePool('upgrade_command')) { + $command = new Command_Upgrade(); + $command->setApplication($this); + $command->setChangeLog($this->getFile($this->getPathConfiguration()->getChangeLogFilePath())); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setPathConfiguration($this->getPathConfiguration()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'upgrade_command', + $command + ); + } + + return $this->getFromInstancePool('upgrade_command'); + } + + /** + * @return Command_User + */ + public function getUserCommand() + { + if ($this->isNotInInstancePool('user_command')) { + $command = new Command_User(); + $command->setApplication($this); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setPathConfiguration($this->getPathConfiguration()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'user_command', + $command + ); + } + + return $this->getFromInstancePool('user_command'); + } + + /** + * @return Command_User_Add + */ + public function getUserAddCommand() + { + if ($this->isNotInInstancePool('user_add_command')) { + $command = new Command_User_Add(); + $command->setChannels($this->getChannels()); + $command->setOutput($this->getOutput()); + $command->setRoles($this->getRoles()); + $command->setUserFile($this->getUserFile()); + $command->setUsers($this->getUsers()); + $this->setToInstancePool( + 'user_add_command', + $command + ); + } + + return $this->getFromInstancePool('user_add_command'); + } + + /** + * @return Command_User_Edit + */ + public function getUserEditCommand() + { + if ($this->isNotInInstancePool('user_edit_command')) { + $command = new Command_User_Edit(); + $command->setChannels($this->getChannels()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $command->setRoles($this->getRoles()); + $command->setUserFile($this->getUserFile()); + $command->setUsers($this->getUsers()); + $this->setToInstancePool( + 'user_edit_command', + $command + ); + } + + return $this->getFromInstancePool('user_edit_command'); + } + + /** + * @return Command_User_Delete + */ + public function getUserDeleteCommand() + { + if ($this->isNotInInstancePool('user_delete_command')) { + $command = new Command_User_Delete(); + $command->setChannels($this->getChannels()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $command->setRoles($this->getRoles()); + $command->setUserFile($this->getUserFile()); + $command->setUsers($this->getUsers()); + $this->setToInstancePool( + 'user_delete_command', + $command + ); + } + + return $this->getFromInstancePool('user_delete_command'); + } + + /** + * @return Command_User_List + */ + public function getUserListCommand() + { + if ($this->isNotInInstancePool('user_list_command')) { + $command = new Command_User_List(); + $command->setChannels($this->getChannels()); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $command->setRoles($this->getRoles()); + $command->setUserFile($this->getUserFile()); + $command->setUsers($this->getUsers()); + $this->setToInstancePool( + 'user_list_command', + $command + ); + } + + return $this->getFromInstancePool('user_list_command'); + } + + /** + * @return Command_VerifyInstallation + */ + public function getVerifyInstallationCommand() + { + if ($this->isNotInInstancePool('validate_installation_command')) { + $command = new Command_VerifyInstallation(); + $command->setApplication($this); + $command->setInput($this->getInput()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'validate_installation_command', + $command + ); + } + + return $this->getFromInstancePool('validate_installation_command'); + } + + /** + * @return Command_VerifyInstallation_LocalFiles + */ + public function getVerifyInstallationLocalFilesCommand() + { + if ($this->isNotInInstancePool('validate_installation_local_files_command')) { + $command = new Command_VerifyInstallation_LocalFiles(); + $command->setApplication($this); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setPathConfiguration($this->getPathConfiguration()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'validate_installation_local_files_command', + $command + ); + } + + return $this->getFromInstancePool('validate_installation_local_files_command'); + } + + /** + * @return Command_VerifyInstallation_Version + */ + public function getVerifyInstallationVersionCommand() + { + if ($this->isNotInInstancePool('validate_installation_version_command')) { + $command = new Command_VerifyInstallation_Version(); + $command->setApplication($this); + $command->setFilesystem($this->getFilesystem()); + $command->setInput($this->getInput()); + $command->setPathConfiguration($this->getPathConfiguration()); + $command->setOutput($this->getOutput()); + $this->setToInstancePool( + 'validate_installation_version_command', + $command + ); + } + + return $this->getFromInstancePool('validate_installation_version_command'); + } + //end of command + + //begin of file + /** + * @return File + */ + public function getChannelFile() + { + if ($this->isNotInInstancePool('channel_file')) { + $this->setToInstancePool( + 'channel_file', + $this->getFile( + $this->getPathConfiguration()->getChatChannelsFilePath() + ) + ); + } + + return $this->getFromInstancePool('channel_file'); + } + + /** + * @return File + */ + public function getUserFile() + { + if ($this->isNotInInstancePool('user_file')) { + $this->setToInstancePool( + 'user_file', + $this->getFile( + $this->getPathConfiguration()->getChatUsersFilePath() + ) + ); + } + + return $this->getFromInstancePool('user_file'); + } + //end of file + + /** + * @return array + */ + public function getChannels() + { + if (empty($this->channels)) { + $this->setPropertyFromFile( + 'channels', + 'channels', + $this->getPathConfiguration()->getChatChannelsFilePath() + ); + } + + return $this->channels; + } + + /** + * @return array + */ + public function getChatConfiguration() + { + if (empty($this->chatConfiguration)) { + $this->setPropertyFromFile( + 'chatConfiguration', + 'config', + $this->getPathConfiguration()->getChatConfigurationFilePath() + ); + } + + return $this->chatConfiguration; + } + + /** + * @return string + */ + public function getCurrentVersion() + { + return require $this->getPathConfiguration()->getChatVersionFilePath(); + } + + /** + * @return string + */ + public function getExampleVersion() + { + return require $this->getPathConfiguration()->getExampleVersionFilePath(); + } + + /** + * @param null|string $path + * @return File + */ + public function getFile($path = null) + { + return new File($path); + } + + /** + * @return Filesystem + */ + public function getFilesystem() + { + if ($this->isNotInInstancePool('filesystem')) { + $filesystem = new Filesystem(); + $this->setToInstancePool('filesystem', $filesystem); + } + + return $this->getFromInstancePool('filesystem'); + } + + /** + * @return Input + */ + public function getInput() + { + if ($this->isNotInInstancePool('input')) { + $this->setToInstancePool( + 'input', + new Input($this->getString(), $this->arguments) + ); + } + + return $this->getFromInstancePool('input'); + } + + /** + * @return Output + */ + public function getOutput() + { + if ($this->isNotInInstancePool('output')) { + $this->setToInstancePool( + 'output', + new Output() + ); + } + + return $this->getFromInstancePool('output'); + } + + /** + * @return Configuration_Path + */ + public function getPathConfiguration() + { + if ($this->isNotInInstancePool('configuration_path')) { + $configuration = new Configuration_Path('..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR); + $this->setToInstancePool('configuration_path', $configuration); + } + + return $this->getFromInstancePool('configuration_path'); + } + + /** + * @return array + */ + public function getRoles() + { + $this->getChatConfiguration(); + if (empty($this->roles)) { + if (defined('AJAX_CHAT_GUEST')) { + $this->roles = array( + AJAX_CHAT_GUEST => 'AJAX_CHAT_GUEST', + AJAX_CHAT_USER => 'AJAX_CHAT_USER', + AJAX_CHAT_MODERATOR => 'AJAX_CHAT_MODERATOR', + AJAX_CHAT_ADMIN => 'AJAX_CHAT_ADMIN', + AJAX_CHAT_CHATBOT => 'AJAX_CHAT_CHATBOT', + AJAX_CHAT_CUSTOM => 'AJAX_CHAT_CUSTOM', + AJAX_CHAT_BANNED => 'AJAX_CHAT_BANNED' + ); + } + } + + return $this->roles; + } + + /** + * @return String + */ + public function getString() + { + if ($this->isNotInInstancePool('string')) { + $this->setToInstancePool('string', new String()); + } + + return $this->getFromInstancePool('string'); + } + + /** + * @return array + */ + public function getUsers() + { + //@todo - fix this damn call, if we remove this the needed constants are not defined + $this->getChatConfiguration(); + if (empty($this->users)) { + $this->setPropertyFromFile( + 'users', + 'users', + $this->getPathConfiguration()->getChatUsersFilePath() + ); + } + + return $this->users; + } + + /** + * @param array $arguments + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + } + + /** + * @param string $key + * @return mixed + */ + private function getFromInstancePool($key) + { + return $this->instancePool[$key]; + } + + /** + * @param string $key + * @return bool + */ + private function isNotInInstancePool($key) + { + return (!(isset($this->instancePool[$key]))); + } + + /** + * @param string $propertyName + * @param string $fileValueName + * @param string $filePath + * @throws Exception + */ + private function setPropertyFromFile($propertyName, $fileValueName, $filePath) + { + if (!is_file($filePath)) { + throw new Exception( + 'provided file path is not valid: ' . $filePath + ); + } + + require $filePath; + $this->$propertyName = $$fileValueName; + } + + /** + * @param string $key + * @param mixed $value + */ + private function setToInstancePool($key, $value) + { + $this->instancePool[$key] = $value; + } +}
\ No newline at end of file diff --git a/source/Application/Cli.php b/source/Application/Cli.php new file mode 100644 index 0000000..7c4ec19 --- /dev/null +++ b/source/Application/Cli.php @@ -0,0 +1,30 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class Application_Cli + */ +class Application_Cli extends AbstractApplication +{ + /** + * @throws Exception + */ + public function __construct() + { + global $argv; + + $isNotCalledFromCommandLineInterface = (PHP_SAPI !== 'cli'); + + if ($isNotCalledFromCommandLineInterface) { + throw new Exception( + 'command line script only ' + ); + } + $arguments = $argv; + array_shift($arguments); + $this->setArguments($arguments); + } +}
\ No newline at end of file diff --git a/source/Command/AbstractCommand.php b/source/Command/AbstractCommand.php new file mode 100644 index 0000000..55b91eb --- /dev/null +++ b/source/Command/AbstractCommand.php @@ -0,0 +1,53 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-13 + */ + +/** + * Class Command_AbstractCommand + */ +abstract class Command_AbstractCommand implements Command_CommandInterface +{ + /** + * @var Input + */ + protected $input; + + /** + * @var Output + */ + protected $output; + + /** + * @return Input + */ + public function getInput() + { + return $this->input; + } + + /** + * @param Input $input + */ + public function setInput(Input $input) + { + $this->input = $input; + } + + /** + * @return null|Output + */ + public function getOutput() + { + return $this->output; + } + + /** + * @param Output $output + */ + public function setOutput(Output $output) + { + $this->output = $output; + } +}
\ No newline at end of file diff --git a/source/Command/Backup.php b/source/Command/Backup.php new file mode 100644 index 0000000..14b74c6 --- /dev/null +++ b/source/Command/Backup.php @@ -0,0 +1,107 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-16 + */ + +/** + * Class Command_Backup + */ +class Command_Backup extends Command_AbstractCommand +{ + /** + * @var Configuration_Path + */ + private $pathConfiguration; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @param Configuration_Path $configuration + */ + public function setPathConfiguration(Configuration_Path $configuration) + { + $this->pathConfiguration = $configuration; + } + + /** + * @param Filesystem $filesystem + */ + public function setFilesystem(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * @throws Exception + */ + public function execute() + { + if (!$this->filesystem->isDirectory($this->pathConfiguration->getBackupPath())) { + $this->filesystem->createDirectory($this->pathConfiguration->getBackupPath()); + } + + $identifierToPaths = array( + 'channels' => array( + 'backup' => $this->pathConfiguration->getBackupChannelsFilePath(), + 'chat' => $this->pathConfiguration->getChatChannelsFilePath() + ), + 'application' => array( + 'backup' => $this->pathConfiguration->getBackupConfigurationFilePath(), + 'chat' => $this->pathConfiguration->getChatConfigurationFilePath() + ), + 'users' => array( + 'backup' => $this->pathConfiguration->getBackupUsersFilePath(), + 'chat' => $this->pathConfiguration->getChatUsersFilePath() + ), + 'version' => array( + 'backup' => $this->pathConfiguration->getBackupVersionFilePath(), + 'chat' => $this->pathConfiguration->getChatVersionFilePath() + ), + ); + + foreach ($identifierToPaths as $identifier => $paths) { + if ($this->filesystem->isFile($paths['backup'])) { + $this->output->addLine($identifier . ' backup file available, will delete it ...'); + $this->filesystem->deleteFile($paths['backup']); + } + } + + foreach ($identifierToPaths as $identifier => $paths) { + echo 'creating backup of ' . $identifier . ' ...' . PHP_EOL; + $this->filesystem->copy( + $paths['chat'], + $paths['backup'] + ); + } + } + + /** + * @return array + */ + public function getUsage() + { + return array(); + } + + /** + * @throws Exception + */ + public function verify() + { + if (is_null($this->pathConfiguration)) { + throw new Exception( + 'application is mandatory' + ); + } + + if (is_null($this->filesystem)) { + throw new Exception( + 'filesystem is mandatory' + ); + } + } +}
\ No newline at end of file diff --git a/source/Command/Channel.php b/source/Command/Channel.php new file mode 100644 index 0000000..aa5c235 --- /dev/null +++ b/source/Command/Channel.php @@ -0,0 +1,127 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-16 + */ + +class Command_Channel extends Command_AbstractCommand +{ + /** + * @var AbstractApplication + */ + private $application; + + /** + * @var string + */ + private $command; + + /** + * @var array + */ + private $commands = array( + 'add', + 'edit', + 'delete', + 'list' + ); + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @param AbstractApplication $application + */ + public function setApplication(AbstractApplication $application) + { + $this->application = $application; + } + + /** + * @param Filesystem $filesystem + */ + public function setFilesystem(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * @throws Exception + */ + public function execute() + { + switch ($this->command) { + case 'add': + $command = $this->application->getChannelAddCommand(); + break; + case 'edit': + $command = $this->application->getChannelEditCommand(); + break; + case 'delete': + $command = $this->application->getChannelDeleteCommand(); + break; + case 'list': + $command = $this->application->getChannelListCommand(); + break; + default: + throw new Exception( + 'unsupported command "' . $this->command . '"' + ); + } + + $command->setInput($this->input); + $command->setOutput($this->output); + + try { + $command->verify(); + } catch (Exception $exception) { + throw new Exception( + '--' . $this->command . ' ' . implode("\n", $command->getUsage()) . PHP_EOL . + PHP_EOL . + $exception->getMessage() + ); + } + $command->execute(); + } + + /** + * @return array + */ + public function getUsage() + { + return array( + '[--' . implode('|--', $this->commands) . ']' + ); + } + + /** + * @throws Exception + */ + public function verify() + { + $this->command = null; + + if ($this->input->getNumberOfArguments() < 1) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + foreach ($this->commands as $command) { + if ($this->input->hasLongOption($command)) { + $this->command = $command; + break; + } + } + + if (is_null($this->command)) { + throw new Exception( + 'invalid command provided' + ); + } + + $this->input->removeLongOption($this->command); + } +}
\ No newline at end of file diff --git a/source/Command/Channel/AbstractCommand.php b/source/Command/Channel/AbstractCommand.php new file mode 100644 index 0000000..42b6836 --- /dev/null +++ b/source/Command/Channel/AbstractCommand.php @@ -0,0 +1,37 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Class Command_Channel_AbstractCommand + */ +abstract class Command_Channel_AbstractCommand extends Command_AbstractCommand implements Command_Channel_CommandInterface +{ + /** + * @var File + */ + protected $file; + + /** + * @var array + */ + protected $channels; + + /** + * @param array $channels + */ + public function setChannels(array $channels) + { + $this->channels = $channels; + } + + /** + * @param File $file + */ + public function setChannelFile(File $file) + { + $this->file = $file; + } +}
\ No newline at end of file diff --git a/source/Command/Channel/Add.php b/source/Command/Channel/Add.php new file mode 100644 index 0000000..751970c --- /dev/null +++ b/source/Command/Channel/Add.php @@ -0,0 +1,66 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Class Command_Channel_Add + */ +class Command_Channel_Add extends Command_Channel_AbstractCommand +{ + /** + * @var string + */ + private $inputName; + + /** + * @throws Exception + */ + public function execute() + { + end($this->channels); + $nextKey = (key($this->channels) + 1); + reset($this->channels); + + $content = $this->file->read(); + + $content[] = '// added - ' . date('Y-m-d H:i:s'); + $content[] = '$channels[' . $nextKey . '] = \'' . $this->inputName . '\';'; + + $this->file->write($content); + } + + /** + * @return array + */ + public function getUsage() + { + return array( + 'name="<name>"', + ' available channels: ' . implode(',', array_keys($this->channels)), + ); + } + + /** + * @throws Exception + */ + public function verify() + { + if ($this->input->getNumberOfArguments() !== 1) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + $name = $this->input->getParameterValue('name'); + + if (is_null($name)) { + throw new Exception( + 'invalid name "' . $name . '" provided' + ); + } + + $this->inputName = $name; + } +} diff --git a/source/Command/Channel/CommandInterface.php b/source/Command/Channel/CommandInterface.php new file mode 100644 index 0000000..72af707 --- /dev/null +++ b/source/Command/Channel/CommandInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Interface Command_Channel_CommandInterface + */ +interface Command_Channel_CommandInterface extends Command_CommandInterface +{ + /** + * @param array $channels + */ + public function setChannels(array $channels); + + /** + * @param File $file + */ + public function setChannelFile(File $file); +}
\ No newline at end of file diff --git a/source/Command/Channel/Delete.php b/source/Command/Channel/Delete.php new file mode 100644 index 0000000..af7a791 --- /dev/null +++ b/source/Command/Channel/Delete.php @@ -0,0 +1,87 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Class Command_Channel_Delete + */ +class Command_Channel_Delete extends Command_Channel_AbstractCommand +{ + /** + * @var int + */ + private $inputId; + + /** + * @throws Exception + */ + public function execute() + { + reset($this->channels); + + $lines = $this->file->read(); + $content = array(); + + foreach ($lines as $line) { + if ($line == '// Sample channel list:') { + $content[] = $line; + break; + } else { + $content[] = $line; + } + } + + if (empty($this->channels)) { + throw new Exception( + 'nothing to delete' + ); + } else { + unset($this->channels[$this->inputId]); + $ids = array_values($this->channels); + + if (!empty($ids)) { + foreach ($ids as $id => $name) { + $content[] = '$channels[' . $id . '] = \'' . $name . '\';'; + } + } + + $this->file->write($content); + } + } + + /** + * @return array + */ + public function getUsage() + { + return array( + 'channel_id=<channel id>', + ' available channels: ' . implode(',', array_keys($this->channels)) + ); + } + + /** + * @throws Exception + */ + public function verify() + { + if ($this->input->getNumberOfArguments() !== 1) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + $validIds = array_keys($this->channels); + $inputId = $this->input->getParameterValue('channel_id'); + + if (!isset($validIds[$inputId])) { + throw new Exception( + 'invalid name "' . $inputId . '" provided' + ); + } + + $this->inputId = $inputId; + } +} diff --git a/source/Command/Channel/Edit.php b/source/Command/Channel/Edit.php new file mode 100644 index 0000000..fc852b6 --- /dev/null +++ b/source/Command/Channel/Edit.php @@ -0,0 +1,102 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Class Command_Channel_Edit + */ +class Command_Channel_Edit extends Command_Channel_AbstractCommand +{ + /** + * @var string + */ + private $inputName; + + /** + * @var int + */ + private $inputId; + + /** + * @throws Exception + */ + public function execute() + { + reset($this->channels); + + $lines = $this->file->read(); + $content = array(); + $contentAfterCurrentChannel = array(); + $string = new String(); + + $foundCurrentChannelLine = false; + $linePrefixToSearchFor = '$channels[' . $this->inputId . ']'; + + foreach ($lines as $line) { + if ($string->startsWith($line, $linePrefixToSearchFor)) { + $foundCurrentChannelLine = true; + } else { + if ($foundCurrentChannelLine) { + $contentAfterCurrentChannel[] = $line; + } else { + $content[] = $line; + } + } + } + + $content[] = '$channels[' . $this->inputId . '] = \'' . $this->inputName . '\';'; + + foreach ($contentAfterCurrentChannel as $line) { + $content[] = $line; + } + + $this->file->write($content); + } + + /** + * @return array + */ + public function getUsage() + { + return array( + 'id=<id> name="<name>"', + ' available channels: ' . implode(',', array_keys($this->channels)) + ); + } + + /** + * @throws Exception + */ + public function verify() + { + if ($this->input->getNumberOfArguments() !== 2) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + $name = $this->input->getParameterValue('name'); + $id = $this->input->getParameterValue('id'); + + if (is_null($name)) { + throw new Exception( + 'no name provided' + ); + } + + if (is_null($id)) { + throw new Exception( + 'no id provided' + ); + } else if (!isset($this->channels[$id])) { + throw new Exception( + 'invalid id provided' + ); + } + + $this->inputName = $name; + $this->inputId = $id; + } +}
\ No newline at end of file diff --git a/source/Command/Channel/List.php b/source/Command/Channel/List.php new file mode 100644 index 0000000..caaa445 --- /dev/null +++ b/source/Command/Channel/List.php @@ -0,0 +1,54 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Class Command_Channel_List + */ +class Command_Channel_List extends Command_Channel_AbstractCommand +{ + /** + * @throws Exception + */ + public function execute() + { + $numberOfChannels = count($this->channels); + + $this->output->addLine('number of channels: ' . $numberOfChannels); + + if ($numberOfChannels > 0) { + $this->output->addLine(); + $this->output->addLine('id | name '); + $this->output->addLine('--------'); + + foreach ($this->channels as $id => $name) { + $this->output->addLine( + implode( + ' | ', + array( + $id, + $name + ) + ) + ); + } + } + } + + /** + * @return array + */ + public function getUsage() + { + return array(); + } + + /** + * @throws Exception + */ + public function verify() + { + } +} diff --git a/source/Command/CommandInterface.php b/source/Command/CommandInterface.php new file mode 100644 index 0000000..afd9908 --- /dev/null +++ b/source/Command/CommandInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-13 + */ + +/** + * Interface Command_CommandInterface + */ +interface Command_CommandInterface extends InputDependentInterface, OutputDependentInterface +{ + /** + * @throws Exception + */ + public function execute(); + + /** + * @return array + */ + public function getUsage(); + + /** + * @throws Exception + */ + public function verify(); +}
\ No newline at end of file diff --git a/source/Command/Install.php b/source/Command/Install.php new file mode 100644 index 0000000..936ae69 --- /dev/null +++ b/source/Command/Install.php @@ -0,0 +1,96 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class Command_Install + */ +class Command_Install extends Command_AbstractCommand +{ + /** + * @var Configuration_Path + */ + private $pathConfiguration; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @param Configuration_Path $configuration + */ + public function setPathConfiguration(Configuration_Path $configuration) + { + $this->pathConfiguration = $configuration; + } + + /** + * @param Filesystem $filesystem + */ + public function setFilesystem(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * @throws Exception + * @todo implement setup of database (check if connection is available, split it up in multiple steps (Command_Install_Files, Command_Install_Database) + */ + public function execute() + { + $identifierToPaths = array( + 'channels' => array( + 'example' => $this->pathConfiguration->getExampleChannelsFilePath(), + 'chat' => $this->pathConfiguration->getChatChannelsFilePath() + ), + 'pathConfiguration' => array( + 'example' => $this->pathConfiguration->getExampleConfigurationFilePath(), + 'chat' => $this->pathConfiguration->getChatConfigurationFilePath() + ), + 'users' => array( + 'example' => $this->pathConfiguration->getExampleUsersFilePath(), + 'chat' => $this->pathConfiguration->getChatUsersFilePath() + ), + 'version' => array( + 'example' => $this->pathConfiguration->getExampleVersionFilePath(), + 'chat' => $this->pathConfiguration->getChatVersionFilePath() + ), + ); + + foreach ($identifierToPaths as $identifier => $paths) { + if (!$this->filesystem->isFile($paths['chat'])) { + $directoryPath = dirname($paths['chat']); + + if (!$this->filesystem->isDirectory($directoryPath)) { + $this->output->addLine('no directory available at "' . $directoryPath . '", will create one ...'); + $this->filesystem->createDirectory($directoryPath); + } + $this->output->addLine('no ' . $identifier . ' file available, will create one ...'); + $this->filesystem->copy( + $paths['example'], + $paths['chat'] + ); + } else { + $this->output->addLine($identifier . ' file available, nothing to do ...'); + } + } + } + + /** + * @return array + */ + public function getUsage() + { + return array(); + } + + /** + * @throws Exception + */ + public function verify() + { + } +}
\ No newline at end of file diff --git a/source/Command/Restore.php b/source/Command/Restore.php new file mode 100644 index 0000000..60c78a7 --- /dev/null +++ b/source/Command/Restore.php @@ -0,0 +1,152 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class Command_Restore + */ +class Command_Restore extends Command_AbstractCommand +{ + /** + * @var string + */ + private $command; + + /** + * @var array + */ + private $commands = array( + 'all', + 'channels', + 'application', + 'users', + 'version' + ); + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var Configuration_Path + */ + private $pathConfiguration; + + /** + * @param Configuration_Path $configuration + */ + public function setPathConfiguration(Configuration_Path $configuration) + { + $this->pathConfiguration = $configuration; + } + + /** + * @param Filesystem $filesystem + */ + public function setFilesystem(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * @throws Exception + */ + public function execute() + { + $identifiers = array(); + + switch ($this->command) { + case 'all': + $identifiers = array( + 'channels', + 'pathConfiguration', + 'users', + 'version' + ); + break; + case 'channels': + $identifiers[] = 'channels'; + break; + case 'pathConfiguration': + $identifiers[] = 'pathConfiguration'; + break; + case 'users': + $identifiers[] = 'users'; + break; + case 'version': + $identifiers[] = 'version'; + break; + } + + $identifierToPaths = array( + 'channels' => array( + 'backup' => $this->pathConfiguration->getBackupChannelsFilePath(), + 'chat' => $this->pathConfiguration->getChatChannelsFilePath() + ), + 'pathConfiguration' => array( + 'backup' => $this->pathConfiguration->getBackupConfigurationFilePath(), + 'chat' => $this->pathConfiguration->getChatConfigurationFilePath() + ), + 'users' => array( + 'backup' => $this->pathConfiguration->getBackupUsersFilePath(), + 'chat' => $this->pathConfiguration->getChatUsersFilePath() + ), + 'version' => array( + 'backup' => $this->pathConfiguration->getBackupVersionFilePath(), + 'chat' => $this->pathConfiguration->getChatVersionFilePath() + ), + ); + + foreach ($identifiers as $identifier) { + if ($this->filesystem->isFile($identifierToPaths[$identifier]['backup'])) { + $this->output->addLine($identifier . ' backup file available, will restore it ...'); + $this->filesystem->copy( + $identifierToPaths[$identifier]['backup'], + $identifierToPaths[$identifier]['chat'] + ); + } else { + $this->output->addLine('no ' . $identifier .' backup file available ...'); + } + } + } + + /** + * @return array + */ + public function getUsage() + { + return array( + '[--' . implode('|--', $this->commands) . ']' + ); + } + + /** + * @throws Exception + */ + public function verify() + { + if ($this->input->getNumberOfArguments() !== 1) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + foreach ($this->commands as $command) { + if ($this->input->hasLongOption($command)) { + $this->command = $command; + break; + } + } + + if (is_null($this->command)) { + throw new Exception( + 'invalid command provided' + ); + } + + $this->command = $command; + } +}
\ No newline at end of file diff --git a/source/Command/Upgrade.php b/source/Command/Upgrade.php new file mode 100644 index 0000000..16ac2e6 --- /dev/null +++ b/source/Command/Upgrade.php @@ -0,0 +1,227 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class Command_Upgrade + */ +class Command_Upgrade extends Command_AbstractCommand +{ + /** + * @var AbstractApplication + */ + private $application; + + /** + * @var File + */ + private $changeLog; + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var Configuration_Path + */ + private $pathConfiguration; + + /** + * @param AbstractApplication $application + */ + public function setApplication(AbstractApplication $application) + { + $this->application = $application; + } + + /** + * @param File $file + */ + public function setChangeLog(File $file) + { + $this->changeLog = $file; + } + + /** + * @param Configuration_Path $configuration + */ + public function setPathConfiguration(Configuration_Path $configuration) + { + $this->pathConfiguration = $configuration; + } + + /** + * @param Filesystem $filesystem + */ + public function setFilesystem(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * @throws Exception + */ + public function execute() + { + //__process + $currentVersion = $this->application->getCurrentVersion(); + $finalVersion = $this->application->getExampleVersion(); + $releases = $this->fetchReleasesToProcess($currentVersion, $finalVersion); + + if (empty($releases)) { + $this->output->addLine('nothing to do ...'); + } else { + $pathToIndexPhp = $this->pathConfiguration->getChatPath() . DIRECTORY_SEPARATOR . 'index.php'; + $pathToBackupOfIndexPhp = $pathToIndexPhp . '.backup'; + + $this->backup(); + $this->executePreUpdateTasks($pathToIndexPhp, $pathToBackupOfIndexPhp); + $this->upgrade($releases); + $this->executePostUpdateTasks($pathToIndexPhp, $pathToBackupOfIndexPhp); + + $this->output->addLine('upgraded from "' . $currentVersion . '" to "' . $finalVersion . '"'); + } + } + + /** + * @return array + */ + public function getUsage() + { + return array(); + } + + /** + * @throws Exception + */ + public function verify() + { + } + + /** + * @throws Exception + */ + private function backup() + { + $command = $this->application->getBackupCommand(); + + $this->input->setArguments(array('--all')); + + $command->setInput($this->input); + $command->setOutput($this->output); + $command->verify(); + $command->execute(); + } + + /** + * @param string $pathToIndexPhp + * @param string $pathToBackupOfIndexPhp + * @throws Exception + */ + private function executePreUpdateTasks($pathToIndexPhp, $pathToBackupOfIndexPhp) + { + $this->filesystem->move($pathToIndexPhp, $pathToBackupOfIndexPhp); + $file = $this->filesystem->createFile($pathToIndexPhp); + $file->write(array( + '<?php', + 'echo \'updating system, back soon\';' + )); + } + + /** + * @param string $pathToIndexPhp + * @param string $pathToBackupOfIndexPhp + * @throws Exception + */ + private function executePostUpdateTasks($pathToIndexPhp, $pathToBackupOfIndexPhp) + { + $this->filesystem->move($pathToBackupOfIndexPhp, $pathToIndexPhp); + $this->filesystem->copy( + $this->pathConfiguration->getExampleVersionFilePath(), + $this->pathConfiguration->getChatVersionFilePath() + ); + } + + private function upgrade(array $releases) + { + foreach ($releases as $release) { + $path = $this->pathConfiguration->getReleasePath() . DIRECTORY_SEPARATOR . $release; + $files = $this->fetchUpdatesFilesFromRelease($path); + foreach ($files as $file) { + $this->executeUpdateFile($file); + $this->changeLog->append( + '[' . date('Y-m-d H:i:s', time()) . '] ' . + $file + ); + } + } + } + + /** + * @param string $currentVersion + * @param string $finalVersion + * @return array + * @throws Exception + */ + private function fetchReleasesToProcess($currentVersion, $finalVersion) + { + if (!is_dir($this->pathConfiguration->getReleasePath())) { + throw new Exception( + 'no directory found:' . PHP_EOL . + $this->pathConfiguration->getReleasePath() + ); + } + + $releases = $this->filesystem->getDirectories( + $this->pathConfiguration->getReleasePath(), + array('upcoming'), + false + ); + $releasesToProcess = array(); + foreach ($releases as $release) { + $isNewer = version_compare($release, $currentVersion, '>'); + if ($isNewer) { + $releasesToProcess[] = $release; + } + } + natsort($releasesToProcess); + + return $releasesToProcess; + } + + /** + * @param string $path + * @return array + * @throws Exception + */ + private function fetchUpdatesFilesFromRelease($path) + { + if (!is_dir($path)) { + throw new Exception( + 'provided release path is not a directory: ' . PHP_EOL . $path + ); + } + + $files = $this->filesystem->getFiles($path); + + return $files; + } + + /** + * @param string $file + * @throws Exception + */ + private function executeUpdateFile($file) + { + if (!is_file($file)) { + throw new Exception( + 'provided path "' . $file . '" is not a file' + ); + } + + require $file; + } +}
\ No newline at end of file diff --git a/source/Command/User.php b/source/Command/User.php new file mode 100644 index 0000000..616eb85 --- /dev/null +++ b/source/Command/User.php @@ -0,0 +1,144 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class Command_User + */ +class Command_User extends Command_AbstractCommand +{ + /** + * @var AbstractApplication + */ + private $application; + + /** + * @var string + */ + private $command; + + /** + * @var array + */ + private $commands = array( + 'add', + 'edit', + 'delete', + 'list' + ); + + /** + * @var Filesystem + */ + private $filesystem; + + /** + * @var Configuration_Path + */ + private $pathConfiguration; + + /** + * @param AbstractApplication $application + */ + public function setApplication(AbstractApplication $application) + { + $this->application = $application; + } + + /** + * @param Configuration_Path $configuration + */ + public function setPathConfiguration(Configuration_Path $configuration) + { + $this->pathConfiguration = $configuration; + } + + /** + * @param \Filesystem $filesystem + */ + public function setFilesystem(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * @throws Exception + */ + public function execute() + { + switch ($this->command) { + case 'add': + $command = $this->application->getUserAddCommand(); + break; + case 'edit': + $command = $this->application->getUserEditCommand(); + break; + case 'delete': + $command = $this->application->getUserDeleteCommand(); + break; + case 'list': + $command = $this->application->getUserListCommand(); + break; + default: + throw new Exception( + 'unsupported command "' . $this->command . '"' + ); + } + + $command->setInput($this->input); + $command->setOutput($this->output); + + try { + $command->verify(); + } catch (Exception $exception) { + throw new Exception( + '--' . $this->command . ' ' . implode("\n", $command->getUsage()) . PHP_EOL . + PHP_EOL . + $exception->getMessage() + ); + } + $command->execute(); + } + + /** + * @return array + */ + public function getUsage() + { + return array( + '[--' . implode('|--', $this->commands) . ']' + ); + } + + /** + * @throws Exception + */ + public function verify() + { + $this->command = null; + + if ($this->input->getNumberOfArguments() < 1) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + + foreach ($this->commands as $command) { + if ($this->input->hasLongOption($command)) { + $this->command = $command; + break; + } + } + + if (is_null($this->command)) { + throw new Exception( + 'invalid command provided' + ); + } + + $this->input->removeLongOption($this->command); + } +}
\ No newline at end of file diff --git a/source/Command/User/AbstractCommand.php b/source/Command/User/AbstractCommand.php new file mode 100644 index 0000000..00512c2 --- /dev/null +++ b/source/Command/User/AbstractCommand.php @@ -0,0 +1,63 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Class Command_User_AbstractCommand + */ +abstract class Command_User_AbstractCommand extends Command_AbstractCommand implements Command_User_CommandInterface +{ + /** + * @var array + */ + protected $channels; + + /** + * @var array + */ + protected $roles; + + /** + * @var File + */ + protected $file; + + /** + * @var array + */ + protected $users; + + /** + * @param array $channels + */ + public function setChannels(array $channels) + { + $this->channels = $channels; + } + + /** + * @param array $roles + */ + public function setRoles(array $roles) + { + $this->roles = $roles; + } + + /** + * @param \File $userFile + */ + public function setUserFile(File $userFile) + { + $this->file = $userFile; + } + + /** + * @param array $users + */ + public function setUsers(array $users) + { + $this->users = $users; + } +}
\ No newline at end of file diff --git a/source/Command/User/Add.php b/source/Command/User/Add.php new file mode 100644 index 0000000..088feef --- /dev/null +++ b/source/Command/User/Add.php @@ -0,0 +1,124 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-12 + */ + +/** + * Class Command_User_Add + */ +class Command_User_Add extends Command_User_AbstractCommand +{ + /** + * @var array + */ + private $inputChannels; + + /** + * @var string + */ + private $inputName; + + /** + * @var string + */ + private $inputPassword; + + /** + * @var string + */ + private $inputRole; + + /** + * @throws Exception + */ + public function execute() + { + end($this->users); + $nextKey = (key($this->users) + 1); + reset($this->users); + + $content = $this->file->read(); + + $content[] = '// added - ' . date('Y-m-d H:i:s'); + $content[] = '$users[' . $nextKey . '] = array();'; + $content[] = '$users[' . $nextKey . '][\'userRole\'] = ' . $this->roles[$this->inputRole] . ';'; + $content[] = '$users[' . $nextKey . '][\'userName\'] = \'' . $this->inputName . '\';'; + $content[] = '$users[' . $nextKey . '][\'password\'] = \'' . $this->inputPassword . '\';'; + $content[] = '$users[' . $nextKey . '][\'channels\'] = array(' . implode(',', $this->inputChannels) . ');'; + + $this->file->write($content); + } + + /** + * @return array + */ + public function getUsage() + { + return array( + 'name="<name>" password="<password>" role=<id> channels="<id>[,<id>[...]]"', + ' available channels: ' . implode(',', array_keys($this->channels)), + ' available roles: ' . implode(',', array_keys($this->roles)) + ); + } + + /** + * @throws Exception + */ + public function verify() + { + if ($this->input->getNumberOfArguments() !== 4) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + $channels = explode(',', $this->input->getParameterValue('channels', '')); + $name = $this->input->getParameterValue('name'); + $password = $this->input->getParameterValue('password'); + $role = $this->input->getParameterValue('role'); + + if (is_null($name)) { + throw new Exception( + 'no name "' . $name . '" provided' + ); + } + + if (is_null($role)) { + throw new Exception( + 'no role "' . $role . '" provided' + ); + } else { + if (!isset($this->roles[$role])) { + throw new Exception( + 'invalid role "' . $role . '" provided' + ); + } + } + + if (is_null($password)) { + throw new Exception( + 'no password "' . $password . '" provided' + ); + } + + if (empty($channels)) { + throw new Exception( + 'no channels provided' + ); + } + + foreach ($channels as $channel) { + if (!isset($this->channels[$channel])) { + throw new Exception( + 'invalid channel "' . $channel . '" provided' + ); + } + } + + $this->inputChannels = $channels; + $this->inputName = $name; + $this->inputPassword = $password; + $this->inputRole = $role; + } +} diff --git a/source/Command/User/CommandInterface.php b/source/Command/User/CommandInterface.php new file mode 100644 index 0000000..b8aa332 --- /dev/null +++ b/source/Command/User/CommandInterface.php @@ -0,0 +1,31 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-14 + */ + +/** + * Interface Command_User_CommandInterface + */ +interface Command_User_CommandInterface extends Command_CommandInterface +{ + /** + * @param array $channels + */ + public function setChannels(array $channels); + + /** + * @param array $roles + */ + public function setRoles(array $roles); + + /** + * @param \File $userFile + */ + public function setUserFile(File $userFile); + + /** + * @param array $users + */ + public function setUsers(array $users); +}
\ No newline at end of file diff --git a/source/Command/User/Delete.php b/source/Command/User/Delete.php new file mode 100644 index 0000000..aeed24a --- /dev/null +++ b/source/Command/User/Delete.php @@ -0,0 +1,105 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-12 + */ + +/** + * Class Command_User_Delete + */ +class Command_User_Delete extends Command_User_AbstractCommand +{ + /** + * @var int + */ + private $inputId; + + /** + * @throws Exception + */ + public function execute() + { + reset($this->users); + + $lines = $this->file->read(); + $content = array(); + + foreach ($lines as $line) { + if ($line == '$users[0][\'channels\'] = array(0);') { + $content[] = $line; + $content[] = ''; + break; + } else { + $content[] = $line; + } + } + + unset($this->users[0]); + + if (empty($this->users)) { + throw new Exception( + 'nothing to delete' + ); + } else { + unset($this->users[$this->inputId]); + $idToUser = array_values($this->users); + + if (!empty($idToUser)) { + foreach ($idToUser as $id => $user) { + ++$id; //we have to increase by one since we have to prevent overwriting the "0" user + $content[] = '// updated - ' . date('Y-m-d H:i:s'); + $content[] = '$users[' . $id . '] = array();'; + $content[] = '$users[' . $id . '][\'userRole\'] = ' . $this->roles[$user['userRole']] . ';'; + $content[] = '$users[' . $id . '][\'userName\'] = \'' . $user['userName'] . '\';'; + $content[] = '$users[' . $id . '][\'password\'] = \'' . $user['password'] . '\';'; + $content[] = '$users[' . $id . '][\'channels\'] = array(' . implode(',', $user['channels']) . ');'; + } + } + + $this->file->write($content); + } + } + + /** + * @return array + */ + public function getUsage() + { + $users = $this->users; + unset($users[0]); + + return array( + 'userid=<id>', + ' available users: ' . implode(',', array_keys($users)) + ); + } + + /** + * @throws Exception + */ + public function verify() + { + if ($this->input->getNumberOfArguments() !== 1) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + $validIds = array_keys($this->users); + $userId = $this->input->getParameterValue('user_id'); + + if (!isset($validIds[$userId])) { + throw new Exception( + 'invalid id "' . $userId . '" provided' + ); + } + + if ($userId === 0) { + throw new Exception( + 'you are not allowed to delete id "' . $userId . '"' + ); + } + + $this->inputId = $userId; + } +} diff --git a/source/Command/User/Edit.php b/source/Command/User/Edit.php new file mode 100644 index 0000000..72467ee --- /dev/null +++ b/source/Command/User/Edit.php @@ -0,0 +1,161 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-13 + */ + +/** + * Class Command_User_Edit + */ +class Command_User_Edit extends Command_User_AbstractCommand +{ + /** + * @var array + */ + private $inputChannels; + + /** + * @var string + */ + private $inputName; + + /** + * @var string + */ + private $inputPassword; + + /** + * @var string + */ + private $inputRole; + + /** + * @var int + */ + private $inputId; + + /** + * @throws Exception + */ + public function execute() + { + reset($this->users); + + $lines = $this->file->read(); + $content = array(); + $contentAfterCurrentUser = array(); + $string = new String(); + + $foundCurrentUserContent = false; + $linePrefixToSearchFor = '$users[' . $this->inputId . ']['; + + foreach ($lines as $line) { + if ($string->startsWith($line, $linePrefixToSearchFor)) { + $foundCurrentUserContent = true; + } else { + if ($foundCurrentUserContent) { + $contentAfterCurrentUser[] = $line; + } else { + $content[] = $line; + } + } + } + + $content[] = '$users[' . $this->inputId . '][\'userRole\'] = ' . $this->roles[$this->inputRole] . ';'; + $content[] = '$users[' . $this->inputId . '][\'userName\'] = \'' . $this->inputName . '\';'; + $content[] = '$users[' . $this->inputId . '][\'password\'] = \'' . $this->inputPassword . '\';'; + $content[] = '$users[' . $this->inputId . '][\'channels\'] = array(' . implode(',', $this->inputChannels) . ');'; + + foreach ($contentAfterCurrentUser as $line) { + $content[] = $line; + } + + $this->file->write($content); + } + + /** + * @return array + */ + public function getUsage() + { + return array( + 'user_id=<id> name="<name>" password="<password>" role=<id> channels="<id>[,<id>[...]]"', + ' available channels: ' . implode(',', array_keys($this->channels)), + ' available roles: ' . implode(',', array_keys($this->roles)), + ' available users: ' . implode(',', array_keys($this->users)) + ); + } + + /** + * @throws Exception + */ + public function verify() + { + if ($this->input->getNumberOfArguments() !== 5) { + throw new Exception( + 'invalid number of arguments provided' + ); + } + + $channels = explode(',', $this->input->getParameterValue('channels', '')); + $name = $this->input->getParameterValue('name'); + $password = $this->input->getParameterValue('password'); + $role = $this->input->getParameterValue('role'); + $userId = $this->input->getParameterValue('user_id'); + $validIds = array_keys($this->users); + + if (is_null($name)) { + throw new Exception( + 'no name provided' + ); + } + + if (is_null($role)) { + throw new Exception( + 'no role provided' + ); + } else { + if (!isset($this->roles[$role])) { + throw new Exception( + 'invalid role "' . $role . '" provided' + ); + } + } + + if (is_null($password)) { + throw new Exception( + 'no password provided' + ); + } + + if (empty($channels)) { + throw new Exception( + 'no channels provided' + ); + } + + foreach ($channels as $channel) { + if (!isset($this->channels[$channel])) { + throw new Exception( + 'invalid channel "' . $channel . '" provided' + ); + } + } + + if (($userId === 0)) { + throw new Exception( + 'no id provided' + ); + } else if (!isset($validIds[$userId])) { + throw new Exception( + 'invalid id provided' + ); + } + + $this->inputChannels = $channels; + $this->inputName = $name; + $this->inputPassword = $password; + $this->inputRole = $role; + $this->inputId = $userId; + } +}
\ No newline at end of file diff --git a/source/Command/User/List.php b/source/Command/User/List.php new file mode 100644 index 0000000..130e842 --- /dev/null +++ b/source/Command/User/List.php @@ -0,0 +1,58 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-12 + */ + +/** + * Class Command_User_List + */ +class Command_User_List extends Command_User_AbstractCommand +{ + /** + * @throws Exception + */ + public function execute() + { + unset($this->users[0]); + //remove initial user since we are not allowed to remove this user + $numberOfUsers = count($this->users); + + $this->output->addLine('number of users: ' . $numberOfUsers); + + if ($numberOfUsers > 0) { + $this->output->addLine(); + $this->output->addLine('id | name | role | channels'); + $this->output->addLine('----------------'); + + foreach ($this->users as $id => $user) { + $this->output->addLine( + implode( + ' | ', + array( + $id, + $user['userName'], + $user['userRole'], + implode(',', $user['channels']) + ) + ) + ); + } + } + } + + /** + * @return array + */ + public function getUsage() + { + return array(); + } + + /** + * @throws Exception + */ + public function verify() + { + } +} diff --git a/source/Command/VerifyInstallation.php b/source/Command/VerifyInstallation.php new file mode 100644 index 0000000..0abd881 --- /dev/null +++ b/source/Command/VerifyInstallation.php @@ -0,0 +1,69 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class Command_VerifyInstallation + */ +class Command_VerifyInstallation extends Command_AbstractCommand +{ + /** + * @var AbstractApplication + */ + protected $application; + + /** + * @param AbstractApplication $application + */ + public function setApplication(AbstractApplication $application) + { + $this->application = $application; + } + + /** + * @throws Exception + */ + public function execute() + { + $this->verifyLocalFiles($this->application, $this->input, $this->output); + $this->verifyVersion($this->application, $this->input, $this->output); + //@todo fetch current version from url + } + + /** + * @param AbstractApplication $application + */ + private function verifyLocalFiles(AbstractApplication $application) + { + $command = $application->getVerifyInstallationLocalFilesCommand(); + $command->verify(); + $command->execute(); + } + + /** + * @param AbstractApplication $application + */ + private function verifyVersion(AbstractApplication $application) + { + $command = $application->getVerifyInstallationVersionCommand(); + $command->verify(); + $command->execute(); + } + + /** + * @return array + */ + public function getUsage() + { + return array(); + } + + /** + * @throws Exception + */ + public function verify() + { + } +}
\ No newline at end of file diff --git a/source/Command/VerifyInstallation/AbstractCommand.php b/source/Command/VerifyInstallation/AbstractCommand.php new file mode 100644 index 0000000..d64a680 --- /dev/null +++ b/source/Command/VerifyInstallation/AbstractCommand.php @@ -0,0 +1,50 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-21 + */ + +/** + * Class Command_VerifyInstallation_AbstractCommand + */ +abstract class Command_VerifyInstallation_AbstractCommand extends Command_AbstractCommand +{ + /** + * @var AbstractApplication + */ + protected $application; + + /** + * @var Filesystem + */ + protected $filesystem; + + /** + * @var Configuration_Path + */ + protected $pathConfiguration; + + /** + * @param AbstractApplication $application + */ + public function setApplication(AbstractApplication $application) + { + $this->application = $application; + } + + /** + * @param Filesystem $filesystem + */ + public function setFilesystem(Filesystem $filesystem) + { + $this->filesystem = $filesystem; + } + + /** + * @param Configuration_Path $configuration + */ + public function setPathConfiguration(Configuration_Path $configuration) + { + $this->pathConfiguration = $configuration; + } +}
\ No newline at end of file diff --git a/source/Command/VerifyInstallation/LocalFiles.php b/source/Command/VerifyInstallation/LocalFiles.php new file mode 100644 index 0000000..dafd44a --- /dev/null +++ b/source/Command/VerifyInstallation/LocalFiles.php @@ -0,0 +1,70 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-21 + */ + +/** + * Class Command_VerifyInstallation_LocalFiles + */ +class Command_VerifyInstallation_LocalFiles extends Command_VerifyInstallation_AbstractCommand +{ + /** + * @throws Exception + */ + public function execute() + { + $pathToLibDirectory = $this->pathConfiguration->getChatPath() . DIRECTORY_SEPARATOR . 'lib'; + + if (!$this->filesystem->isDirectory($pathToLibDirectory)) { + throw new Exception( + 'directory "lib" is missing, installation needed' + ); + } + + $pathToDataDirectory = $pathToLibDirectory . DIRECTORY_SEPARATOR . 'data'; + + if (!$this->filesystem->isDirectory($pathToDataDirectory)) { + throw new Exception( + 'directory "data" is missing, installation needed' + ); + } + + $identifierToPublicPath = array( + 'channels' => $this->pathConfiguration->getChatChannelsFilePath(), + 'pathConfiguration' => $this->pathConfiguration->getChatConfigurationFilePath(), + 'users' => $this->pathConfiguration->getChatUsersFilePath(), + 'version' => $this->pathConfiguration->getChatVersionFilePath() + ); + + foreach ($identifierToPublicPath as $identifier => $path) { + if (!$this->filesystem->isFile($path)) { + throw new Exception( + 'file "' . $identifier . '" is missing, installation needed' + ); + } + } + + $pathToInstallPhp = $this->pathConfiguration->getChatPath() . DIRECTORY_SEPARATOR . 'install.php'; + + if ($this->filesystem->isFile($pathToInstallPhp)) { + throw new Exception( + 'file "' . $pathToInstallPhp . '" still available' + ); + } + } + + /** + * @return array + */ + public function getUsage() + { + } + + /** + * @throws Exception + */ + public function verify() + { + } +}
\ No newline at end of file diff --git a/source/Command/VerifyInstallation/Version.php b/source/Command/VerifyInstallation/Version.php new file mode 100644 index 0000000..a2f592b --- /dev/null +++ b/source/Command/VerifyInstallation/Version.php @@ -0,0 +1,40 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-21 + */ + +/** + * Class Command_VerifyInstallation_Version + */ +class Command_VerifyInstallation_Version extends Command_VerifyInstallation_AbstractCommand +{ + /** + * @throws Exception + */ + public function execute() + { + $exampleVersion = $this->application->getExampleVersion(); + $currentVersion = $this->application->getCurrentVersion(); + + if ($exampleVersion !== $currentVersion) { + throw new Exception( + 'current version "' . $currentVersion . '" and code version "' . $exampleVersion . '" differs, update needed' + ); + } + } + + /** + * @return array + */ + public function getUsage() + { + } + + /** + * @throws Exception + */ + public function verify() + { + } +}
\ No newline at end of file diff --git a/source/Configuration/Path.php b/source/Configuration/Path.php new file mode 100644 index 0000000..06917f5 --- /dev/null +++ b/source/Configuration/Path.php @@ -0,0 +1,220 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-17 + */ + +/** + * Class Configuration_Path + */ +class Configuration_Path +{ + /** + * @var string + */ + private $pathToRootDirectory; + + /** + * @param string $relativePathToRootDirectory - relative path from Configuration_Path file + * @throws Exception + */ + public function __construct($relativePathToRootDirectory) + { + $this->pathToRootDirectory = realpath(__DIR__ . DIRECTORY_SEPARATOR . $relativePathToRootDirectory); + + if (!is_dir($relativePathToRootDirectory)) { + throw new Exception( + 'provided root path is not a directory: ' . PHP_EOL . + '"' . $this->pathToRootDirectory . '"' + ); + } + } + + //begin of path + /** + * @return string + */ + public function getBackupPath() + { + return $this->pathToRootDirectory . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup'; + } + + /** + * @return string + */ + public function getBackupChannelsFilePath() + { + return $this->getBackupPath() . DIRECTORY_SEPARATOR . $this->getChannelsFileName(); + } + + /** + * @return string + */ + public function getBackupConfigurationFilePath() + { + return $this->getBackupPath() . DIRECTORY_SEPARATOR . $this->getConfigurationFileName(); + } + + /** + * @return string + */ + public function getBackupUsersFilePath() + { + return $this->getBackupPath() . DIRECTORY_SEPARATOR . $this->getUsersFileName(); + } + + /** + * @return string + */ + public function getBackupVersionFilePath() + { + return $this->getBackupPath() . DIRECTORY_SEPARATOR . $this->getVersionFileName(); + } + + /** + * @return string + */ + public function getExamplePath() + { + return $this->pathToRootDirectory . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'example'; + } + + /** + * @return string + */ + public function getExampleChannelsFilePath() + { + return $this->getExamplePath() . DIRECTORY_SEPARATOR . $this->getChannelsFileName(); + } + + /** + * @return string + */ + public function getExampleConfigurationFilePath() + { + return $this->getChatPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . $this->getConfigurationFileName() . '.example'; + } + + /** + * @return string + */ + public function getExampleUsersFilePath() + { + return $this->getExamplePath() . DIRECTORY_SEPARATOR . $this->getUsersFileName(); + } + + /** + * @return string + */ + public function getExampleVersionFilePath() + { + return $this->getExamplePath() . DIRECTORY_SEPARATOR . $this->getVersionFileName(); + } + + /** + * @return string + */ + public function getChatPath() + { + return $this->pathToRootDirectory . DIRECTORY_SEPARATOR . 'chat'; + } + + /** + * @return string + */ + public function getChatChannelsFilePath() + { + return $this->getChatPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $this->getChannelsFileName(); + } + + /** + * @return string + */ + public function getChatClassesFilePath() + { + return $this->getChatPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . $this->getClassesFileName(); + } + + /** + * @return string + */ + public function getChatConfigurationFilePath() + { + return $this->getChatPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . $this->getConfigurationFileName(); + } + + /** + * @return string + */ + public function getChatUsersFilePath() + { + return $this->getChatPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $this->getUsersFileName(); + } + + /** + * @return string + */ + public function getChatVersionFilePath() + { + return $this->getChatPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $this->getVersionFileName(); + } + + /** + * @return string + */ + public function getReleasePath() + { + return $this->pathToRootDirectory . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'release'; + } + + /** + * @return string + */ + public function getChangeLogFilePath() + { + return $this->pathToRootDirectory . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'change.log'; + } + //end of path + + //begin of file name + /** + * @return string + */ + public function getChannelsFileName() + { + return 'channels.php'; + } + + /** + * @return string + */ + public function getClassesFileName() + { + return 'classes.php'; + } + + /** + * @return string + */ + public function getConfigurationFileName() + { + return 'config.php'; + } + + /** + * @return string + */ + public function getUsersFileName() + { + return 'users.php'; + } + + /** + * @return string + */ + public function getVersionFileName() + { + return 'version.php'; + } + //end of file name +}
\ No newline at end of file diff --git a/source/File.php b/source/File.php new file mode 100644 index 0000000..076592c --- /dev/null +++ b/source/File.php @@ -0,0 +1,122 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-13 + */ + +/** + * Class File + */ +class File +{ + /** + * @var string + */ + private $path; + + /** + * @param null|string $path + */ + public function __construct($path = null) + { + if (!is_null($path)) { + $this->setPath($path); + } + } + + /** + * @param string|array $content + * @throws Exception + */ + public function append($content) + { + if (is_array($content)) { + $content = implode(PHP_EOL, $content); + } else { + $content .= PHP_EOL; + } + + $numberOfBytes = file_put_contents($this->getPath(), $content, FILE_APPEND); + + if ($numberOfBytes === false) { + throw new Exception( + 'can not append content to file "' . $this->getPath() . '"' + ); + } + } + + /** + * @param string $path + * @throws Exception + */ + public function copy($path) + { + $couldBeCopied = copy($this->getPath(), $path); + + if ($couldBeCopied === false) { + throw new Exception( + 'could not copy file from path "' . $this->getPath() . '" to "' . $path . '"' + ); + } + } + + /** + * @return bool + * @throws Exception + */ + public function exists() + { + return (is_file($this->getPath())); + } + + /** + * @return string + * @throws Exception + */ + public function getPath() + { + if (is_null($this->path)) { + throw new Exception( + 'no path set' + ); + } + + return $this->path; + } + + /** + * @return array + * @throws Exception + */ + public function read() + { + return explode("\n", file_get_contents($this->getPath())); + } + + /** + * @param string $path + */ + public function setPath($path) + { + $this->path = (string) $path; + } + + /** + * @param string|array $content + * @throws Exception + */ + public function write($content) + { + if (is_array($content)) { + $content = implode("\n", $content); + } + + $numberOfBytes = file_put_contents($this->getPath(), $content); + + if ($numberOfBytes === false) { + throw new Exception( + 'can not append content to file "' . $this->getPath() . '"' + ); + } + } +}
\ No newline at end of file diff --git a/source/Filesystem.php b/source/Filesystem.php new file mode 100644 index 0000000..2847d25 --- /dev/null +++ b/source/Filesystem.php @@ -0,0 +1,203 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-15 + */ + +/** + * Class Filesystem + */ +class Filesystem +{ + /** + * @param string $source + * @param string $target + * @throws Exception + */ + public function copy($source, $target) + { + if (copy($source, $target) === false) { + throw new Exception( + 'can not copy "' . $source . '" to "' . $target . '"' + ); + } + } + + /** + * @param string $path + * @param int $mode + * @param bool $recursive + * @throws Exception + */ + public function createDirectory($path, $mode = 0777, $recursive = false) + { + if (mkdir($path, $mode, $recursive) === false) { + throw new Exception( + 'can not create directory "' . $path . '"' + ); + } + } + + /** + * @param string $path + * @return File + * @throws Exception + */ + public function createFile($path) + { + if (touch($path) === false) { + throw new Exception( + 'can not create file "' . $path . '"' + ); + } + + return $this->getFile($path); + } + + /** + * @param string $path + * @throws Exception + */ + public function deleteDirectory($path) + { + if (rmdir($path) === false) { + throw new Exception( + 'can not delete directory "' . $path . '"' + ); + } + } + + /** + * @param string $path + * @throws Exception + */ + public function deleteFile($path) + { + if (unlink($path) === false) { + throw new Exception( + 'can not unlink "' . $path . '"' + ); + } + } + + /** + * This method is not bulletproof, it simple checks if $path is a directory + * @param string $path + * @return File + * @throws Exception + */ + public function getFile($path) + { + if ($this->isDirectory($path)) { + throw new Exception( + 'provided path "' . $path . '" is a directory' + ); + } + + $file = new File(); + $file->setPath($path); + + return $file; + } + + /** + * taken from: https://github.com/stevleibelt/examples/blob/master/php/filesystem/listFilesInDirectory.php + * @param string $path + * @param array $blackList + * @param bool $addPathToName + * @return array + */ + public function getDirectories($path, array $blackList = array(), $addPathToName = true) + { + $blackList = array_merge( + $blackList, + array( + '.', + '..' + ) + ); + $directories = array(); + + if (is_dir($path)) { + if ($directoryHandle = opendir($path)) { + while (false !== ($directory = readdir($directoryHandle))) { + if (is_dir($path . DIRECTORY_SEPARATOR . $directory)) { + if (!in_array($directory, $blackList)) { + if ($addPathToName) { + $directories[] = $path . DIRECTORY_SEPARATOR . $directory; + } else { + $directories[] = $directory; + } + } + } + } + closedir($directoryHandle); + } + } + + return $directories; + } + + /** + * taken from: https://github.com/stevleibelt/examples/blob/master/php/filesystem/listFilesInDirectory.php + * @param string $path + * @param array $blackList + * @param bool $addPathToName + * @return array + */ + public function getFiles($path, array $blackList = array(), $addPathToName = true) + { + $files = array(); + + if (is_dir($path)) { + if ($directoryHandle = opendir($path)) { + while (false !== ($file = readdir($directoryHandle))) { + if (is_file($path . DIRECTORY_SEPARATOR . $file)) { + if (!in_array($file, $blackList)) { + if ($addPathToName) { + $files[] = $path . DIRECTORY_SEPARATOR . $file; + } else { + $files[] = $file; + } + } + } + } + closedir($directoryHandle); + } + } + + return $files; + } + + /** + * @param string $path + * @return bool + */ + public function isDirectory($path) + { + return is_dir($path); + } + + /** + * @param string $path + * @return bool + */ + public function isFile($path) + { + return is_file($path); + } + + /** + * @param string $source + * @param string $target + * @throws Exception + */ + public function move($source, $target) + { + if (rename($source, $target) === false) { + throw new Exception( + 'can not move "' . $source . '" to "' . $target . '"' + ); + } + } +}
\ No newline at end of file diff --git a/source/Input.php b/source/Input.php new file mode 100644 index 0000000..dd4911a --- /dev/null +++ b/source/Input.php @@ -0,0 +1,204 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-20 + */ + +/** + * Class Input + */ +class Input +{ + /** + * @var array + */ + private $arguments; + + /** + * @var array + */ + private $longOptions; + + /** + * @var int + */ + private $numberOfArguments; + + /** + * @var array + */ + private $parameters; + + /** + * @var array + */ + private $shortOptions; + + /** + * @var String + */ + private $string; + + /** + * @param String $string + * @param array $arguments + */ + public function __construct(String $string, array $arguments = array()) + { + $this->longOptions = array(); + $this->parameters = array(); + $this->shortOptions = array(); + $this->string = $string; + + $this->setArguments($arguments); + } + + /** + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * @return int + */ + public function getNumberOfArguments() + { + return $this->numberOfArguments; + } + + /** + * @param string $name + * @param null $default + * @return null + */ + public function getParameterValue($name, $default = null) + { + if ($this->hasParameter($name)) { + $value = $this->parameters[$name]; + } else { + $value = $default; + } + + return $value; + } + + /** + * @param string $name + * @return bool + */ + public function hasParameter($name) + { + return (isset($this->parameters[$name])); + } + + /** + * @param string $name + */ + public function removeParameters($name) + { + if ($this->hasParameter($name)) { + unset($this->parameters[$name]); + $this->update(); + } + } + + /** + * @param $name + * @return bool + */ + public function hasLongOption($name) + { + return (isset($this->longOptions[$name])); + } + + /** + * @param $longOrShortName + * @return bool + */ + public function hasOption($longOrShortName) + { + $hasOption = $this->hasLongOption($longOrShortName); + + if (!$hasOption) { + $hasOption = $this->hasShortOption($longOrShortName); + } + + return $hasOption; + } + + /** + * @param $name + * @return bool + */ + public function hasShortOption($name) + { + return (isset($this->shortOptions[$name])); + } + + /** + * @param string $name + */ + public function removeLongOption($name) + { + if ($this->hasLongOption($name)) { + unset($this->longOptions[$name]); + $this->update(); + } + } + + /** + * @param string $longOrShortName + */ + public function removeOption($longOrShortName) + { + if ($this->hasLongOption($longOrShortName)) { + unset($this->longOptions[$longOrShortName]); + $this->update(); + } else if ($this->hasShortOption($longOrShortName)) { + unset($this->shortOptions[$longOrShortName]); + $this->update(); + } + } + + /** + * @param string $name + */ + public function removeShortOption($name) + { + if ($this->hasShortOption($name)) { + unset($this->shortOptions[$name]); + $this->update(); + } + } + + /** + * @param array $arguments + */ + public function setArguments(array $arguments) + { + foreach ($arguments as $argument) { + if ($this->string->startsWith($argument, '--')) { + $this->longOptions[$this->string->cut($argument, 2)] = true; + } else if ($this->string->startsWith($argument, '-')) { + $this->shortOptions[$this->string->cut($argument, 1)] = true; + } else { + $parts = explode('=', $argument); + if (count($parts) > 1) { + $name = array_shift($parts); + $this->parameters[$name] = implode('=', $parts); + } + } + } + + $this->update(); + } + + private function update() + { + $this->arguments = array_merge($this->parameters, $this->shortOptions, $this->longOptions); + $this->numberOfArguments = count($this->arguments); + } +}
\ No newline at end of file diff --git a/source/InputDependentInterface.php b/source/InputDependentInterface.php new file mode 100644 index 0000000..0d65b0b --- /dev/null +++ b/source/InputDependentInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-20 + */ + +/** + * Interface InputDependentInterface + */ +interface InputDependentInterface +{ + /** + * @return Input + */ + public function getInput(); + + /** + * @param Input $input + */ + public function setInput(Input $input); +}
\ No newline at end of file diff --git a/source/Output.php b/source/Output.php new file mode 100644 index 0000000..f05383a --- /dev/null +++ b/source/Output.php @@ -0,0 +1,57 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-19 + */ + +/** + * Class Output + */ +class Output +{ + /** + * @var array + */ + private $content; + + /** + * @var string + */ + private $indention; + + public function __construct() + { + $this->content = array(); + $this->indention = ' '; + } + + public function __clone() + { + $this->content = array(); + } + + /** + * @param string $line + * @param int $numberOfIndention + */ + public function addLine($line = '', $numberOfIndention = 0) + { + $this->content[] = (str_repeat($this->indention, $numberOfIndention)) . $line; + } + + /** + * @param string $indention + */ + public function setIndention($indention) + { + $this->indention = (string) $indention; + } + + /** + * @return array + */ + public function toArray() + { + return $this->content; + } +}
\ No newline at end of file diff --git a/source/OutputDependentInterface.php b/source/OutputDependentInterface.php new file mode 100644 index 0000000..29d4fe3 --- /dev/null +++ b/source/OutputDependentInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-19 + */ + +/** + * Interface OutputDependentInterface + */ +interface OutputDependentInterface +{ + /** + * @return null|Output + */ + public function getOutput(); + + /** + * @param Output $output + */ + public function setOutput(Output $output); +}
\ No newline at end of file diff --git a/source/String.php b/source/String.php new file mode 100644 index 0000000..64cc541 --- /dev/null +++ b/source/String.php @@ -0,0 +1,38 @@ +<?php +/** + * @author stev leibelt <artodeto@bazzline.net> + * @since 2014-08-13 + */ + +/** + * Class String + */ +class String +{ + /** + * @param string $string + * @param string $prefix + * @return bool + */ + public function startsWith($string, $prefix) + { + return (strncmp($string, $prefix, strlen($prefix)) === 0); + } + + /** + * @param string $string + * @param int $start + * @param null|int $length + * @return string + */ + public function cut($string, $start = 0, $length = 0) + { + if (($length === 0)) { + $part = substr($string, $start); + } else { + $part = substr($string, $start, $length); + } + + return $part; + } +}
\ No newline at end of file |