Index: branches/5.3.x/composer.json =================================================================== --- branches/5.3.x/composer.json +++ branches/5.3.x/composer.json @@ -1,5 +1,9 @@ { "name": "In-Portal", + "require": { + "symfony/console": "~2.6", + "stecman/symfony-console-completion": "~0.5" + }, "require-dev": { "aik099/coding-standard": "dev-in-portal", "nikic/php-parser": "~1.2" Index: branches/5.3.x/composer.lock =================================================================== --- branches/5.3.x/composer.lock +++ branches/5.3.x/composer.lock @@ -4,8 +4,112 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "746788fc49ab32d05ca2bd837e9f0a1f", - "packages": [], + "hash": "0084b5c04f49b47e81eff44c0343b57f", + "packages": [ + { + "name": "stecman/symfony-console-completion", + "version": "0.5.1", + "source": { + "type": "git", + "url": "https://github.com/stecman/symfony-console-completion.git", + "reference": "1a9fc7ab4820cd1aabbdc584c6b25d221e7b6cb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stecman/symfony-console-completion/zipball/1a9fc7ab4820cd1aabbdc584c6b25d221e7b6cb5", + "reference": "1a9fc7ab4820cd1aabbdc584c6b25d221e7b6cb5", + "shasum": "" + }, + "require": { + "php": ">=5.3.2", + "symfony/console": "~2.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Stecman\\Component\\Symfony\\Console\\BashCompletion\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Holdaway", + "email": "stephen@stecman.co.nz" + } + ], + "description": "Automatic BASH completion for Symfony Console Component based applications.", + "time": "2015-05-07 12:21:50" + }, + { + "name": "symfony/console", + "version": "v2.6.7", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/ebc5679854aa24ed7d65062e9e3ab0b18a917272", + "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2015-05-02 15:18:45" + } + ], "packages-dev": [ { "name": "aik099/coding-standard", @@ -13,12 +117,12 @@ "source": { "type": "git", "url": "https://github.com/aik099/CodingStandard.git", - "reference": "3680b3926f0e936dc95de82dece9310b97c73e97" + "reference": "a47f2b767c99a33f437802b3315179887018e114" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/3680b3926f0e936dc95de82dece9310b97c73e97", - "reference": "3680b3926f0e936dc95de82dece9310b97c73e97", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/a47f2b767c99a33f437802b3315179887018e114", + "reference": "a47f2b767c99a33f437802b3315179887018e114", "shasum": "" }, "require-dev": { @@ -45,20 +149,20 @@ "PHP_CodeSniffer", "codesniffer" ], - "time": "2015-04-10 07:05:51" + "time": "2015-05-06 08:54:38" }, { "name": "nikic/php-parser", - "version": "v1.2.2", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "08f97eb4efa029e2fafb6d8c98b71731bf0cf621" + "reference": "dff239267fd1befa1cd40430c9ed12591aa720ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/08f97eb4efa029e2fafb6d8c98b71731bf0cf621", - "reference": "08f97eb4efa029e2fafb6d8c98b71731bf0cf621", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dff239267fd1befa1cd40430c9ed12591aa720ca", + "reference": "dff239267fd1befa1cd40430c9ed12591aa720ca", "shasum": "" }, "require": { @@ -68,7 +172,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -90,7 +194,7 @@ "parser", "php" ], - "time": "2015-04-03 14:33:59" + "time": "2015-05-02 15:40:40" } ], "aliases": [], Index: branches/5.3.x/core/install/cache/class_structure.php =================================================================== --- branches/5.3.x/core/install/cache/class_structure.php +++ branches/5.3.x/core/install/cache/class_structure.php @@ -2,7 +2,7 @@ // @codingStandardsIgnoreFile /** - * This file is automatically @generated. Use 'php tools/build_class_map.php' to rebuild it. + * This file is automatically @generated. Please use 'in-portal classmap:rebuild' command to rebuild it. */ return array( 'cache_format' => 2, @@ -82,6 +82,15 @@ 'ImagesItem' => '/core/units/images/images.php', 'InPortalPrerequisites' => '/core/install/prerequisites.php', 'InpCustomFieldsHelper' => '/core/units/helpers/custom_fields_helper.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand' => '/core/kernel/Console/Command/AbstractCommand.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\BuildClassMapCommand' => '/core/kernel/Console/Command/BuildClassMapCommand.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\CompletionCommand' => '/core/kernel/Console/Command/CompletionCommand.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand' => '/core/kernel/Console/Command/IConsoleCommand.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\ResetCacheCommand' => '/core/kernel/Console/Command/ResetCacheCommand.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\RunEventCommand' => '/core/kernel/Console/Command/RunEventCommand.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleApplication' => '/core/kernel/Console/ConsoleApplication.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleCommandProvider' => '/core/kernel/Console/ConsoleCommandProvider.php', + 'Intechnic\\InPortal\\Core\\kernel\\Console\\IConsoleCommandProvider' => '/core/kernel/Console/IConsoleCommandProvider.php', 'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\ClassDetector' => '/core/kernel/utility/ClassDiscovery/ClassDetector.php', 'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\ClassMapBuilder' => '/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php', 'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\CodeFolderFilterIterator' => '/core/kernel/utility/ClassDiscovery/CodeFolderFilterIterator.php', @@ -836,6 +845,66 @@ 0 => 'kHelper', ), ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand' => array( + 'type' => 1, + 'modifiers' => 1, + 'extends' => array( + 0 => 'Symfony\\Component\\Console\\Command\\Command', + 1 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand', + ), + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\BuildClassMapCommand' => array( + 'type' => 1, + 'modifiers' => 0, + 'extends' => array( + 0 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand', + 1 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\Completion\\CompletionAwareInterface', + ), + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\CompletionCommand' => array( + 'type' => 1, + 'modifiers' => 0, + 'extends' => array( + 0 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\CompletionCommand', + 1 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand', + ), + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand' => array( + 'type' => 2, + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\ResetCacheCommand' => array( + 'type' => 1, + 'modifiers' => 0, + 'extends' => array( + 0 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand', + ), + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\RunEventCommand' => array( + 'type' => 1, + 'modifiers' => 0, + 'extends' => array( + 0 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand', + 1 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\Completion\\CompletionAwareInterface', + ), + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleApplication' => array( + 'type' => 1, + 'modifiers' => 0, + 'extends' => array( + 0 => 'Symfony\\Component\\Console\\Application', + ), + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleCommandProvider' => array( + 'type' => 1, + 'modifiers' => 0, + 'extends' => array( + 0 => 'kBase', + 1 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\IConsoleCommandProvider', + ), + ), + 'Intechnic\\InPortal\\Core\\kernel\\Console\\IConsoleCommandProvider' => array( + 'type' => 2, + ), 'Intechnic\\InPortal\\Core\\kernel\\utility\\ClassDiscovery\\ClassDetector' => array( 'type' => 1, 'modifiers' => 0, Index: branches/5.3.x/core/kernel/Console/Command/AbstractCommand.php =================================================================== --- branches/5.3.x/core/kernel/Console/Command/AbstractCommand.php +++ branches/5.3.x/core/kernel/Console/Command/AbstractCommand.php @@ -0,0 +1,79 @@ +Application = $application->getKernelApplication(); + $this->Conn =& $this->Application->GetADODBConnection(); + } + } + + /** + * Perform additional validation of the input. + * + * @param InputInterface $input An InputInterface instance. + * @param OutputInterface $output An OutputInterface instance. + * + * @return void + * @throws \RuntimeException When not all required arguments were passed. + */ + protected function initialize(InputInterface $input, OutputInterface $output) + { + $arguments = array_filter($input->getArguments()); + + // Consider required arguments passed with empty values as an error. + if ( count($arguments) < $this->getDefinition()->getArgumentRequiredCount() ) { + throw new \RuntimeException('Not enough arguments.'); + } + } + +} Index: branches/5.3.x/core/kernel/Console/Command/BuildClassMapCommand.php =================================================================== --- branches/5.3.x/core/kernel/Console/Command/BuildClassMapCommand.php +++ branches/5.3.x/core/kernel/Console/Command/BuildClassMapCommand.php @@ -0,0 +1,136 @@ +setName('classmap:rebuild') + ->setDescription('Rebuilds the class map') + ->addOption( + 'module', + null, + InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, + 'Module name to build class map for' + ); + } + + /** + * Executes the current command. + * + * @param InputInterface $input An InputInterface instance. + * @param OutputInterface $output An OutputInterface instance. + * + * @return null|integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $user_modules = $input->getOption('module'); + + if ( $user_modules ) { + $modules_filter = array(); + $valid_modules = $this->getModules(); + + foreach ( $user_modules as $module_name ) { + if ( !in_array($module_name, $valid_modules) ) { + throw new \InvalidArgumentException('Module "' . $module_name . '" not found or installed'); + } + + $modules_filter[$module_name] = $this->Application->ModuleInfo[$module_name]; + } + } + else { + $modules_filter = null; + } + + $table_rows = array(); + + foreach ( ClassMapBuilder::createBuilders($modules_filter) as $class_map_builder ) { + $table_rows[] = $class_map_builder->build(); + } + + // Needed because we aggregate class map from installed modules in unit config cache. + $this->Application->HandleEvent(new \kEvent('adm:OnResetParsedData')); + + $table = $this->getHelper('table'); + $table + ->setHeaders(array('Path', 'Scanned in', 'Parsed in')) + ->setRows($table_rows); + $table->render($output); + + return 0; + } + + /** + * Return possible values for the named option + * + * @param string $optionName Option name. + * @param CompletionContext $context Completion context. + * + * @return array + */ + public function completeOptionValues($optionName, CompletionContext $context) + { + if ( $optionName === 'module' ) { + return $this->getModules(); + } + + return array(); + } + + /** + * Returns possible module names. + * + * @return array + */ + protected function getModules() + { + $modules = array_keys($this->Application->ModuleInfo); + + return array_diff($modules, array('In-Portal')); + } + + /** + * Return possible values for the named argument. + * + * @param string $argumentName Argument name. + * @param CompletionContext $context Completion context. + * + * @return array + */ + public function completeArgumentValues($argumentName, CompletionContext $context) + { + return array(); + } + +} Index: branches/5.3.x/core/kernel/Console/Command/CompletionCommand.php =================================================================== --- branches/5.3.x/core/kernel/Console/Command/CompletionCommand.php +++ branches/5.3.x/core/kernel/Console/Command/CompletionCommand.php @@ -0,0 +1,89 @@ +Application = $application->getKernelApplication(); + $this->Conn =& $this->Application->GetADODBConnection(); + } + } + + /** + * Configure the CompletionHandler instance before it is run + * + * @param CompletionHandler $handler Completion handler. + * + * @return void + */ + protected function configureCompletion(CompletionHandler $handler) + { + // This can be removed once https://github.com/stecman/symfony-console-completion v0.5.2 will be released. + $handler->addHandler( + new Completion( + 'help', + 'command_name', + Completion::TYPE_ARGUMENT, + array_keys($this->getApplication()->all()) + ) + ); + + $handler->addHandler( + new Completion( + 'list', + 'namespace', + Completion::TYPE_ARGUMENT, + $this->getApplication()->getNamespaces() + ) + ); + } + +} Index: branches/5.3.x/core/kernel/Console/Command/IConsoleCommand.php =================================================================== --- branches/5.3.x/core/kernel/Console/Command/IConsoleCommand.php +++ branches/5.3.x/core/kernel/Console/Command/IConsoleCommand.php @@ -0,0 +1,23 @@ + array( + 'short' => 'd', + 'description' => 'Reset Parsed and Cached System Data', + 'event' => 'adm:OnResetParsedData', + ), + 'unit-files' => array( + 'short' => 'f', + 'description' => 'Reset Configs Files Cache and Parsed System Data', + 'event' => 'adm:OnResetConfigsCache', + ), + 'admin-sections' => array( + 'short' => 's', + 'description' => 'Reset Admin Console Sections', + 'event' => 'adm:OnResetSections', + ), + 'mod-rewrite' => array( + 'short' => 'r', + 'description' => 'Reset ModRewrite Cache', + 'event' => 'adm:OnResetModRwCache', + ), + 'sms-menu' => array( + 'short' => 'm', + 'description' => 'Reset SMS Menu Cache', + 'event' => 'c:OnResetCMSMenuCache', + ), + 'templates' => array( + 'short' => 't', + 'description' => 'Clear Templates Cache', + 'event' => 'adm:OnDeleteCompiledTemplates', + ), + 'all-keys' => array( + 'short' => 'k', + 'description' => 'Reset All Keys', + 'event' => 'adm:OnResetMemcache', + ), + ); + + /** + * Configures the current command. + * + * @return void + */ + protected function configure() + { + $this + ->setName('cache:reset') + ->setDescription('Resets the cache'); + + foreach ( $this->optionMap as $option_name => $option_data ) { + $this->addOption( + $option_name, + $option_data['short'], + InputOption::VALUE_NONE, + $option_data['description'] + ); + } + } + + /** + * Executes the current command. + * + * @param InputInterface $input An InputInterface instance. + * @param OutputInterface $output An OutputInterface instance. + * + * @return null|integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $success_count = 0; + $error_count = 0; + + foreach ( $this->optionMap as $option_name => $option_data ) { + if ( !$input->getOption($option_name) ) { + continue; + } + + $success_count++; + $output->write('- ' . $option_data['description'] . ' ... '); + + $event = new \kEvent($option_data['event']); + $this->Application->HandleEvent($event); + + if ( $event->getRedirectParam('action_completed') ) { + $output->writeln('OK'); + } + else { + $error_count++; + $output->writeln('FAILED'); + } + } + + if ( $success_count === 0 ) { + throw new \RuntimeException('Please specify at least one reset option'); + } + + return $error_count == 0 ? 0 : 64; + } + +} Index: branches/5.3.x/core/kernel/Console/Command/RunEventCommand.php =================================================================== --- branches/5.3.x/core/kernel/Console/Command/RunEventCommand.php +++ branches/5.3.x/core/kernel/Console/Command/RunEventCommand.php @@ -0,0 +1,126 @@ +setName('event:run') + ->setDescription('Executes an event') + ->addArgument( + 'event_name', + InputArgument::REQUIRED, + 'Event name (e.g. "adm:OnDoSomething")' + ); + } + + /** + * Executes the current command. + * + * @param InputInterface $input An InputInterface instance. + * @param OutputInterface $output An OutputInterface instance. + * + * @return null|integer + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $event_name = $input->getArgument('event_name'); + + $run_event = new \kEvent($event_name); + $this->Application->HandleEvent($run_event); + + return $run_event->status == \kEvent::erSUCCESS ? 0 : 64; + } + + /** + * Return possible values for the named option + * + * @param string $optionName Option name. + * @param CompletionContext $context Completion context. + * + * @return array + */ + public function completeOptionValues($optionName, CompletionContext $context) + { + return array(); + } + + /** + * Return possible values for the named argument. + * + * @param string $argumentName Argument name. + * @param CompletionContext $context Completion context. + * + * @return array + */ + public function completeArgumentValues($argumentName, CompletionContext $context) + { + if ( $argumentName === 'event_name' ) { + $event_name = $context->getCurrentWord(); + + // Suggest unit config prefixes. + if ( strpos($event_name, ':') === false ) { + return $this->Application->UnitConfigReader->getPrefixes(false); + } + + try { + $event = new \kEvent($event_name); + } + catch ( \InvalidArgumentException $e ) { + // Invalid event name. + return array(); + } + + // Unknown unit. + if ( !$this->Application->prefixRegistred($event->Prefix) ) { + return array(); + } + + // Suggest event names. + $suggestions = array(); + $reflection = new \ReflectionClass( + $this->Application->makeClass($event->Prefix . '_EventHandler') + ); + + foreach ( $reflection->getMethods() as $method ) { + if ( substr($method->getName(), 0, 2) === 'On' ) { + $suggestions[] = $event->Prefix . ':' . $method->getName(); + } + } + + return $suggestions; + } + + return array(); + } + +} Index: branches/5.3.x/core/kernel/Console/ConsoleApplication.php =================================================================== --- branches/5.3.x/core/kernel/Console/ConsoleApplication.php +++ branches/5.3.x/core/kernel/Console/ConsoleApplication.php @@ -0,0 +1,89 @@ +Application =& \kApplication::Instance(); + $this->Conn =& $this->Application->GetADODBConnection(); + + parent::__construct( + 'In-Portal CLI', + $this->Application->ModuleInfo['Core']['Version'] . ' (PHP v' . phpversion() . ')' + ); + } + + /** + * Returns Kernel Application instance. + * + * @return \kApplication + */ + public function getKernelApplication() + { + return $this->Application; + } + + /** + * Gets the default commands that should always be available. + * + * @return Command[] An array of default Command instances + */ + protected function getDefaultCommands() + { + $default_commands = parent::getDefaultCommands(); + + $command_provider_classes = $this->Application->getSubClasses( + 'Intechnic\InPortal\Core\kernel\Console\IConsoleCommandProvider' + ); + + foreach ( $command_provider_classes as $command_provider_class ) { + /** @var IConsoleCommandProvider $command_provider */ + $command_provider = new $command_provider_class(); + $default_commands = array_merge($default_commands, $command_provider->getConsoleCommands()); + } + + return $default_commands; + } + +} Index: branches/5.3.x/core/kernel/Console/ConsoleCommandProvider.php =================================================================== --- branches/5.3.x/core/kernel/Console/ConsoleCommandProvider.php +++ branches/5.3.x/core/kernel/Console/ConsoleCommandProvider.php @@ -0,0 +1,42 @@ +Application->getSubClasses( + 'Intechnic\InPortal\Core\kernel\Console\Command\IConsoleCommand' + ); + + foreach ( $command_classes as $command_class ) { + $commands[] = new $command_class(); + } + + return $commands; + } + +} Index: branches/5.3.x/core/kernel/Console/IConsoleCommandProvider.php =================================================================== --- branches/5.3.x/core/kernel/Console/IConsoleCommandProvider.php +++ branches/5.3.x/core/kernel/Console/IConsoleCommandProvider.php @@ -0,0 +1,30 @@ +makeClass('Intechnic\InPortal\Core\kernel\Console\ConsoleApplication'); + } + + /** * Only renders template * * @see kDBEventHandler::_errorNotFound() Index: branches/5.3.x/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php =================================================================== --- branches/5.3.x/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php +++ branches/5.3.x/core/kernel/utility/ClassDiscovery/ClassMapBuilder.php @@ -173,7 +173,7 @@ /** * Builds class map. * - * @return void + * @return array * @throws \RuntimeException When PHP parser not found. */ public function build() @@ -184,16 +184,17 @@ throw new \RuntimeException($error_msg); } + $table_output = array(); $scan_path = preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '...', $this->scanPath, 1); - echo $this->strPad('path "' . $scan_path . '"', 40); + $table_output[] = $scan_path; // The "Path" column. $this->load(self::CACHE_FILE_STRUCTURE, true); $this->load(self::CACHE_FILE_HASHES, true); $start = microtime(true); $files = $this->scan(); - echo $this->strPad('scanned in ' . sprintf('%.4f', microtime(true) - $start) . 's', 25); + $table_output[] = sprintf('%.4f', microtime(true) - $start) . 's'; // The "Scanned in" column. $start = microtime(true); @@ -203,8 +204,7 @@ $this->parseFile($file); } - echo $this->strPad('parsed in ' . sprintf('%.4f', microtime(true) - $start) . 's', 25); - echo PHP_EOL; + $table_output[] = sprintf('%.4f', microtime(true) - $start) . 's'; // The "Parsed in" column. ksort($this->classToFileMap); ksort($this->fileHashes); @@ -212,19 +212,8 @@ $this->store(self::CACHE_FILE_STRUCTURE); $this->store(self::CACHE_FILE_HASHES); - } - /** - * Pads text with spaces from right side. - * - * @param string $text Text. - * @param integer $length Pad length. - * - * @return string - */ - protected function strPad($text, $length) - { - return str_pad($text, $length, ' ', STR_PAD_RIGHT); + return $table_output; } /** @@ -385,7 +374,7 @@ // {$at}codingStandardsIgnoreFile /** - * This file is automatically {$at}generated. Use 'php tools/build_class_map.php' to rebuild it. + * This file is automatically {$at}generated. Please use 'in-portal classmap:rebuild' command to rebuild it. */ return {$cache}; Index: branches/5.3.x/core/kernel/utility/event.php =================================================================== --- branches/5.3.x/core/kernel/utility/event.php +++ branches/5.3.x/core/kernel/utility/event.php @@ -134,39 +134,41 @@ * Parameter $params could be be an an array with following keys: "prefix", "special" (optional), "name". * Parameter $params could be a string in format: "prefix:name" or "prefix.special:name". * - * @param mixed $params - * @param Array $specific_params event specific params (none by default) - * @return kEvent - * @access public + * @param mixed $params Params. + * @param array $specific_params Event specific params (none by default). + * + * @throws InvalidArgumentException When incorrect event string given. */ public function __construct($params = Array(), $specific_params = null) { parent::__construct(); - if ($params) { + if ( $params ) { if ( is_array($params) ) { $prefix = isset($params['prefix']) ? $params['prefix'] : false; $special = isset($params['special']) ? $params['special'] : false; - if ($prefix) { + if ( $prefix ) { $this->Init($prefix, $special); } $this->Name = isset($params['name']) ? $params['name'] : ''; } elseif ( is_string($params) ) { - if (preg_match('/([^.:]*)[.]{0,1}([^:]*):(.*)/', $params, $regs)) { + if ( preg_match('/([^.:]*)[.]{0,1}([^:]*):(.*)/', $params, $regs) ) { $prefix = $regs[1]; $special = $regs[2]; - if ($prefix) { + if ( $prefix ) { $this->Init($prefix, $special); } $this->Name = $regs[3]; } else { - throw new Exception('Invalid event string: "' . $params . '". Should be in "prefix[.special]:OnEvent" format'); + $error_msg = 'Invalid event string: "' . $params . '". '; + $error_msg .= 'Should be in "prefix[.special]:OnEvent" format'; + throw new InvalidArgumentException($error_msg); } } } @@ -445,4 +447,4 @@ { return $this->getPrefixSpecial() . ':' . $this->Name; } - } \ No newline at end of file + } Index: branches/5.3.x/core/kernel/utility/factory.php =================================================================== --- branches/5.3.x/core/kernel/utility/factory.php +++ branches/5.3.x/core/kernel/utility/factory.php @@ -347,7 +347,7 @@ { if ( !isset($this->realClasses[$pseudo_class]) ) { $error_msg = 'RealClass not defined for "' . $pseudo_class . '" pseudo_class.'; - $error_msg .= ' Please use "php tools/build_class_map.php" to discover new classes.'; + $error_msg .= ' Please use "in-portal classmap:rebuild" command to discover new classes.'; if ( $this->Application->isInstalled() ) { throw new kFactoryException($error_msg); Index: branches/5.3.x/core/kernel/utility/unit_config_reader.php =================================================================== --- branches/5.3.x/core/kernel/utility/unit_config_reader.php +++ branches/5.3.x/core/kernel/utility/unit_config_reader.php @@ -641,13 +641,19 @@ } /** - * Returns prefixes of unit configs, that were registered + * Returns prefixes of unit configs, that were registered. * - * @return Array + * @param boolean $loaded_only Only return prefixes, that were loaded till now. + * + * @return array */ - public function getPrefixes() + public function getPrefixes($loaded_only = true) { - return array_keys($this->configData); + if ( $loaded_only ) { + return array_keys($this->configData); + } + + return array_keys($this->prefixFiles); } /** @@ -721,12 +727,14 @@ * @param string $prefix Unit config prefix. * * @return string - * @throws Exception When unit config is not found. + * @throws InvalidArgumentException When unit config is not found. */ public function getPrefixFile($prefix) { if ( !isset($this->prefixFiles[$prefix]) ) { - throw new Exception('Configuration file for prefix "' . $prefix . '" is unknown'); + throw new InvalidArgumentException( + 'Configuration file for prefix "' . $prefix . '" is unknown' + ); } return $this->prefixFiles[$prefix]; Index: branches/5.3.x/in-portal =================================================================== --- branches/5.3.x/in-portal +++ branches/5.3.x/in-portal @@ -0,0 +1,40 @@ +#!/usr/bin/env php +Init(); + +// Assume user with all privileges, because nobody is doing authentication from CLI. +$application->StoreVar('user_id', USER_ROOT, true); + +$application->getConsoleApplication()->run(); +$application->Done(); + +$end = microtime(true); Index: branches/5.3.x/tools/bash_completion.sh =================================================================== --- branches/5.3.x/tools/bash_completion.sh +++ branches/5.3.x/tools/bash_completion.sh @@ -0,0 +1,35 @@ + +function _in-portal_d41351fc9a70c756_complete { + + + local CMDLINE_CONTENTS="$COMP_LINE" + local CMDLINE_CURSOR_INDEX="$COMP_POINT" + local CMDLINE_WORDBREAKS="$COMP_WORDBREAKS"; + + export CMDLINE_CONTENTS CMDLINE_CURSOR_INDEX CMDLINE_WORDBREAKS + + local RESULT STATUS; + + # this is custom line + RESULT=$(${1} _completion); # complete + STATUS=$?; + + local cur; + _get_comp_words_by_ref -n : cur; + + + if [ $STATUS -eq 200 ]; then + _filedir; + return 0; + + elif [ $STATUS -ne 0 ]; then + echo -e "$RESULT"; + return $?; + fi; + + COMPREPLY=(`compgen -W "$RESULT" -- $cur`); + + __ltrim_colon_completions "$cur"; +}; + +complete -F _in-portal_d41351fc9a70c756_complete in-portal; Index: branches/5.3.x/tools/build_class_map.php =================================================================== --- branches/5.3.x/tools/build_class_map.php +++ branches/5.3.x/tools/build_class_map.php @@ -1,19 +0,0 @@ -Init(); - -foreach ( ClassMapBuilder::createBuilders() as $class_map_builder ) { - $class_map_builder->build(); -} Index: branches/5.3.x/tools/run_event.php =================================================================== --- branches/5.3.x/tools/run_event.php +++ branches/5.3.x/tools/run_event.php @@ -2,7 +2,7 @@ /** * @version $Id$ * @package In-Portal -* @copyright Copyright (C) 1997 - 2011 Intechnic. All rights reserved. +* @copyright Copyright (C) 1997 - 2015 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant @@ -12,50 +12,22 @@ * See http://www.in-portal.org/license for copyright notices and details. */ -exit_code(1, 'This script needs to be enabled manually !'); - -if ( php_sapi_name() != 'cli' ) { - exit_code(2, 'This script is intended to be used from command-line only !'); +if ( PHP_SAPI !== 'cli' ) { + echo 'This script is intended to be used from command-line only !'; + exit(64); } -$start = microtime(true); - -define('CRON', 1); -define('ADMIN', 1); define('FULL_PATH', realpath(dirname(__FILE__) . '/..')); -define('DBG_SKIP_REPORTING', 1); - -$_SERVER['HTTP_USER_AGENT'] = 'gecko'; - -// in command line, then 2nd argument is password -$password = isset($argv) && isset($argv[2]) ? $argv[2] : ''; - -if ( $password != 'b674006f3edb1d9cd4d838c150b0567d' ) { - exit_code(3, 'Bad key'); -} - -include_once(FULL_PATH . '/core/kernel/startup.php'); - -$application =& kApplication::Instance(); -$application->Init(); - -$application->StoreVar('user_id', USER_ROOT, true); - -$run_event = new kEvent($argv[1]); // event name in form "prefix[.special]:event_name" -$application->HandleEvent($run_event); - -$application->Done(); +/* + * Arguments: + * 1 - event name + * 2 - password + * 3 - ip address for deployment (not handled) + */ + +$exit_code = 0; +$event_name = isset($argv[1]) ? $argv[1] : ''; +passthru(FULL_PATH . '/in-portal event:run ' . escapeshellarg($event_name), $exit_code); +exit($exit_code); $end = microtime(true); - -exit_code($run_event->status == kEvent::erSUCCESS ? 0 : 4); - -function exit_code($code, $msg = '') -{ - if ( $msg ) { - echo $msg . PHP_EOL; - } - - exit($code); -} -$end = microtime(true); \ No newline at end of file