From b67c6846b852b53c32dde23d75349d6f6c375b2d Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Sat, 26 Mar 2016 01:23:29 +0100 Subject: [PATCH 1/9] [TASK] update version of development branch --- changes.txt | 4 ++++ src/N98/Magento/Application.php | 2 +- version.txt | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/changes.txt b/changes.txt index 60eff40c7..4db969214 100644 --- a/changes.txt +++ b/changes.txt @@ -2,6 +2,10 @@ RECENT CHANGES ************** +======= +1.97.17 +======= + ======= 1.97.16 ======= diff --git a/src/N98/Magento/Application.php b/src/N98/Magento/Application.php index b13eec666..3ba298319 100644 --- a/src/N98/Magento/Application.php +++ b/src/N98/Magento/Application.php @@ -37,7 +37,7 @@ class Application extends BaseApplication /** * @var string */ - const APP_VERSION = '1.97.16'; + const APP_VERSION = '1.97.17'; /** * @var int diff --git a/version.txt b/version.txt index 2402651d2..65cd38ff6 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.97.16 +1.97.17 From a01062eb739c7fcfafe67728d47967c5b4a80daf Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Wed, 23 Mar 2016 07:44:20 +0100 Subject: [PATCH 2/9] [FIX] Fix diverse code-style issues - Uninitialized parameter - CS related, caused some refractions. - Line length - Space before closure parameter list - Final class b/c of private ctor - Import order - Space after cast operator - Typehint optional parameters with null --- build/bin/files.php | 23 +++--- .../Util/Console/Helper/DatabaseHelper.php | 45 ++++++----- .../Util/Console/Helper/ParameterHelper.php | 81 +++++++++++-------- src/N98/Util/WindowsSystem.php | 2 +- 4 files changed, 84 insertions(+), 67 deletions(-) diff --git a/build/bin/files.php b/build/bin/files.php index f356841bb..62c306c30 100755 --- a/build/bin/files.php +++ b/build/bin/files.php @@ -17,8 +17,8 @@ ] JSON_URLS; -$urlHeaders = function($url) { - return function($name = null) use ($url) { +$urlHeaders = function ($url) { + return function ($name = null) use ($url) { static $response; $response || $response = shell_exec(sprintf('curl -sI %s', escapeshellarg($url))); @@ -35,28 +35,28 @@ }; }; -$box = function($title) { - $len = strlen($title); +$box = function ($title) { + $len = strlen($title); $buffer = str_repeat("=", $len + 4); $buffer .= "\n= $title =\n"; $buffer .= str_repeat("=", $len + 4); + return $buffer . "\n"; }; -$bytes = function($count) { +$bytes = function ($count) { return sprintf('%s (bytes)', number_format($count, 0, '.', ' ')); }; $urls = json_decode($urls, false, 16, null); -$main = function($urls) use ($urlHeaders, $box, $bytes) -{ +$main = function ($urls) use ($urlHeaders, $box, $bytes) { foreach ($urls as $url) { $title = sprintf("%s: %s", $url->channel, $url->url); echo $box($title); $headers = $urlHeaders($url->url); - printf("Status..: %s\n", $headers(TRUE)); + printf("Status..: %s\n", $headers(true)); printf("Size....: %s\n", $bytes($headers('Content-Length'))); printf("Modified: %s\n", $headers('Last-Modified')); @@ -71,10 +71,9 @@ unlink($tempFile); } file_put_contents($tempFile, fopen($url->url, 'r')); - printf( - "%'.-8s: %s\n MD5.: %s\n", ucfirst($url->channel), rtrim(`php -f "{$tempFile}" -- --no-ansi --version`), - md5_file($tempFile, false) - ); + $magerunVersion = rtrim(`php -f "{$tempFile}" -- --no-ansi --version`); + $md5File = md5_file($tempFile, false); + printf("%'.-8s: %s\n MD5.: %s\n", ucfirst($url->channel), $magerunVersion, $md5File); clearstatcache(null, $tempFile); printf(" Size: %s\n", $bytes(filesize($tempFile))); unlink($tempFile); diff --git a/src/N98/Util/Console/Helper/DatabaseHelper.php b/src/N98/Util/Console/Helper/DatabaseHelper.php index afaf250e3..b39e22a57 100644 --- a/src/N98/Util/Console/Helper/DatabaseHelper.php +++ b/src/N98/Util/Console/Helper/DatabaseHelper.php @@ -3,13 +3,13 @@ namespace N98\Util\Console\Helper; use InvalidArgumentException; +use N98\Magento\Application; use N98\Magento\DbSettings; use PDO; use PDOStatement; use RuntimeException; use Symfony\Component\Console\Application as BaseApplication; use Symfony\Component\Console\Helper\Helper as AbstractHelper; -use N98\Magento\Application; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface; @@ -170,7 +170,7 @@ public function getMysqlVariable($name, $type = null) if (null === $type) { $type = "@@"; } else { - $type = (string) $type; + $type = (string)$type; } if (!in_array($type, array("@@", "@"), true)) { @@ -180,10 +180,10 @@ public function getMysqlVariable($name, $type = null) } $quoted = '`' . strtr($name, array('`' => '``')) . '`'; - $query = "SELECT {$type}{$quoted};"; + $query = "SELECT {$type}{$quoted};"; $connection = $this->getConnection(); - $statement = $connection->query($query, PDO::FETCH_COLUMN, 0); + $statement = $connection->query($query, PDO::FETCH_COLUMN, 0); if ($statement instanceof PDOStatement) { $result = $statement->fetchColumn(0); } else { @@ -253,12 +253,12 @@ public function resolveTables(array $list, array $definitions = array(), array $ } if (!isset($resolved[$code])) { $resolved[$code] = true; - $tables = $this->resolveTables( + $tables = $this->resolveTables( explode(' ', $definitions[$code]['tables']), $definitions, $resolved ); - $resolvedList = array_merge($resolvedList, $tables); + $resolvedList = array_merge($resolvedList, $tables); } continue; } @@ -266,7 +266,7 @@ public function resolveTables(array $list, array $definitions = array(), array $ // resolve wildcards if (strpos($entry, '*') !== false) { $connection = $this->getConnection(); - $sth = $connection->prepare( + $sth = $connection->prepare( 'SHOW TABLES LIKE :like', array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) ); @@ -302,19 +302,19 @@ public function resolveTables(array $list, array $definitions = array(), array $ */ public function getTables($withoutPrefix = null) { - $withoutPrefix = (bool) $withoutPrefix; + $withoutPrefix = (bool)$withoutPrefix; - $db = $this->getConnection(); + $db = $this->getConnection(); $prefix = $this->dbSettings['prefix']; $length = strlen($prefix); $columnName = 'table_name'; - $column = $columnName; + $column = $columnName; $input = array(); if ($withoutPrefix && $length) { - $column = sprintf('SUBSTRING(%1$s FROM 1 + CHAR_LENGTH(:name)) %1$s', $columnName); + $column = sprintf('SUBSTRING(%1$s FROM 1 + CHAR_LENGTH(:name)) %1$s', $columnName); $input[':name'] = $prefix; } @@ -326,14 +326,15 @@ public function getTables($withoutPrefix = null) $input[':like'] = $this->quoteLike($prefix, $escape) . '%'; } - $query = sprintf('SELECT %s FROM information_schema.tables WHERE %s;', $column, $condition); + $query = sprintf('SELECT %s FROM information_schema.tables WHERE %s;', $column, $condition); $statement = $db->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); - $result = $statement->execute($input); + $result = $statement->execute($input); if (!$result) { // @codeCoverageIgnoreStart $this->throwRuntimeException( - $statement, sprintf('Failed to obtain tables from database: %s', var_export($query, true)) + $statement, + sprintf('Failed to obtain tables from database: %s', var_export($query, true)) ); } // @codeCoverageIgnoreEnd @@ -346,7 +347,7 @@ public function getTables($withoutPrefix = null) * throw a runtime exception and provide error info for the statement if available * * @param PDOStatement $statement - * @param string $message + * @param string $message * * @throws RuntimeException */ @@ -393,7 +394,7 @@ private function quoteLike($string, $escape = '=') */ public function getTablesStatus($withoutPrefix = false) { - $db = $this->getConnection(); + $db = $this->getConnection(); $prefix = $this->dbSettings['prefix']; if (strlen($prefix) > 0) { $statement = $db->prepare('SHOW TABLE STATUS LIKE :like', array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); @@ -479,8 +480,8 @@ public function dropDatabase($output) public function dropTables($output) { $result = $this->getTables(); - $query = 'SET FOREIGN_KEY_CHECKS = 0; '; - $count = 0; + $query = 'SET FOREIGN_KEY_CHECKS = 0; '; + $count = 0; foreach ($result as $tableName) { $query .= 'DROP TABLE IF EXISTS `' . $tableName . '`; '; $count++; @@ -502,8 +503,8 @@ public function createDatabase($output) } /** - * @param string $command example: 'VARIABLES', 'STATUS' - * @param string $variable [optional] + * @param string $command example: 'VARIABLES', 'STATUS' + * @param string|null $variable [optional] * * @return array */ @@ -538,7 +539,7 @@ private function runShowCommand($command, $variable = null) } /** - * @param string $variable [optional] + * @param string|null $variable [optional] * * @return array */ @@ -548,7 +549,7 @@ public function getGlobalVariables($variable = null) } /** - * @param string $variable [optional] + * @param string|null $variable [optional] * * @return array */ diff --git a/src/N98/Util/Console/Helper/ParameterHelper.php b/src/N98/Util/Console/Helper/ParameterHelper.php index 8cf333cb4..7f2a3494b 100644 --- a/src/N98/Util/Console/Helper/ParameterHelper.php +++ b/src/N98/Util/Console/Helper/ParameterHelper.php @@ -4,6 +4,7 @@ use Exception; use InvalidArgumentException; +use Mage_Core_Model_Website; use N98\Util\Validator\FakeMetadataFactory; use RuntimeException; use Symfony\Component\Console\Helper\DialogHelper; @@ -109,52 +110,68 @@ function ($typeInput) use ($stores) { * * @return mixed * @throws InvalidArgumentException - * @throws RuntimeException */ public function askWebsite(InputInterface $input, OutputInterface $output, $argumentName = 'website') { /* @var $storeManager \Mage_Core_Model_App */ $storeManager = \Mage::app(); - try { - if ($input->getArgument($argumentName) === null) { - throw new RuntimeException('No website given'); + $website = null; + $argumentValue = $input->getArgument($argumentName); + $hasArgument = $argumentValue !== null; + + if ($hasArgument) { + try { + /* @var $website Mage_Core_Model_Website */ + $website = $storeManager->getWebsite($argumentValue); + return $website; + } catch (Exception $e) { + // catch all exceptions } - /** @var $website \Mage_Core_Model_Website */ - $website = $storeManager->getWebsite($input->getArgument($argumentName)); - } catch (Exception $e) { - $i = 0; - $websites = array(); - foreach ($storeManager->getWebsites() as $website) { - $websites[$i] = $website->getId(); - $question[] = sprintf( - '[%d] ' . $website->getCode() . ' - ' . $website->getName() . PHP_EOL, - ++$i - ); - } - if (count($websites) == 1) { - return $storeManager->getWebsite($websites[0]); + } + + list($websites, $question) = $this->websitesQuestion($storeManager); + if (count($websites) === 1) { + return $storeManager->getWebsite($websites[0]); + } + + $question[] = 'Please select a website: '; + $callback = function ($typeInput) use ($websites) { + if (!isset($websites[$typeInput - 1])) { + throw new InvalidArgumentException('Invalid website'); } - $question[] = 'Please select a website: '; - - $websiteId = $this->askAndValidate( - $output, - $question, - function ($typeInput) use ($websites) { - if (!isset($websites[$typeInput - 1])) { - throw new InvalidArgumentException('Invalid store'); - } - return $websites[$typeInput - 1]; - } - ); + return $websites[$typeInput - 1]; + }; - $website = $storeManager->getWebsite($websiteId); - } + $websiteId = $this->askAndValidate($output, $question, $callback); + $website = $storeManager->getWebsite($websiteId); return $website; } + /** + * @see askWebsite + * @return array websites (integers if website IDs, 0-indexed) and question array (strings) + */ + private function websitesQuestion($storeManager) + { + $i = 0; + $websites = array(); + $question = array(); + foreach ($storeManager->getWebsites() as $website) { + /* @var $website Mage_Core_Model_Website */ + $value = $website->getId(); + $label = sprintf('%s - %s', $website->getCode(), $website->getName()); + $position = $i + 1; + + $websites[$i] = $value; + $question[$i] = sprintf('[%d] %s' . PHP_EOL, $position, $label); + } + + return array($websites, $question); + } + /** * @param InputInterface $input * @param OutputInterface $output diff --git a/src/N98/Util/WindowsSystem.php b/src/N98/Util/WindowsSystem.php index 137c55447..538a8b911 100644 --- a/src/N98/Util/WindowsSystem.php +++ b/src/N98/Util/WindowsSystem.php @@ -13,7 +13,7 @@ * * @package N98\Util */ -class WindowsSystem +final class WindowsSystem { const PATH_SEPARATOR = ';'; From c514c734270ba2ab428d937e0b0696361a542eb6 Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Sun, 27 Mar 2016 13:49:58 +0200 Subject: [PATCH 3/9] [FIX] Extract bootstrap class Extract/move temporary class into file of its own to address coding- standards. Additionally provide backtrace with --verbose and similar command-line- options when an exception is thrown when bootstrapping the application. --- src/N98/MagerunBootstrap.php | 60 ++++++++++++++++++++++++++++++++++++ src/bootstrap.php | 39 +++++------------------ 2 files changed, 67 insertions(+), 32 deletions(-) create mode 100644 src/N98/MagerunBootstrap.php diff --git a/src/N98/MagerunBootstrap.php b/src/N98/MagerunBootstrap.php new file mode 100644 index 000000000..05ed7ebab --- /dev/null +++ b/src/N98/MagerunBootstrap.php @@ -0,0 +1,60 @@ + + */ +namespace N98; + +use Composer\Autoload\ClassLoader; +use ErrorException; + +class MagerunBootstrap +{ + /** + * @param ClassLoader|null $loader [optional] + * @return Magento\Application + * @throws ErrorException + */ + public static function createApplication(ClassLoader $loader = null) + { + if (null === $loader) { + $loader = self::getLoader(); + } + + $application = new Magento\Application($loader); + + return $application; + } + + /** + * @throws ErrorException + * @return ClassLoader + */ + public static function getLoader() + { + if ( + !($loader = self::includeIfExists(__DIR__ . '/../../vendor/autoload.php')) + && !($loader = self::includeIfExists(__DIR__ . '/../../../../autoload.php')) + ) { + throw new ErrorException( + 'You must set up the project dependencies, run the following commands:' . PHP_EOL . + 'curl -s http://getcomposer.org/installer | php' . PHP_EOL . + 'php composer.phar install' . PHP_EOL + ); + } + + return $loader; + } + + /** + * @param string $file + * @return mixed + */ + public static function includeIfExists($file) + { + if (file_exists($file)) { + return include $file; + } + } +} diff --git a/src/bootstrap.php b/src/bootstrap.php index 0aa9c99c9..b3d8b81b3 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -1,40 +1,15 @@ getMessage(); + printf("%s: %s\n", get_class($e), $e->getMessage()); + if (array_intersect(array('-vvv', '-vv', '-v', '--verbose'), $argv)) { + printf("%s\n", $e->getTraceAsString()); + } exit(1); } From d8f495298b176ed1e7a81f76d8a5c0ddc8b89dce Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Sun, 3 Apr 2016 01:02:04 +0200 Subject: [PATCH 4/9] [FIX] Use custom-file-name-property Within ConfigurationLoader::loadPluginConfig() the file-name was used hardencoded. This also resulted into a problem when streamlining with MR2. This fix is done after the hotfix that did break master. Reference: 4396b4a --- src/N98/Magento/Application/ConfigurationLoader.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/N98/Magento/Application/ConfigurationLoader.php b/src/N98/Magento/Application/ConfigurationLoader.php index f94b61614..3103c0a3a 100644 --- a/src/N98/Magento/Application/ConfigurationLoader.php +++ b/src/N98/Magento/Application/ConfigurationLoader.php @@ -214,13 +214,14 @@ public function loadPluginConfig($config, $magentoRootFolder) if ($this->_pluginConfig == null) { $this->_pluginConfig = array(); $moduleBaseFolders = array(); + $customFilename = $this->_customConfigFilename; if (OperatingSystem::isWindows()) { - $config['plugin']['folders'][] = getenv('WINDIR') . '/n98-magerun/modules'; - $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/n98-magerun/modules'; + $config['plugin']['folders'][] = getenv('WINDIR') . '/' . $customFilename . '/modules'; + $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/' . $customFilename . '/modules'; } else { - $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/.n98-magerun/modules'; + $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/.' . $customFilename . '/modules'; } - $config['plugin']['folders'][] = $magentoRootFolder . '/lib/n98-magerun/modules'; + $config['plugin']['folders'][] = $magentoRootFolder . '/lib/' . $customFilename . '/modules'; foreach ($config['plugin']['folders'] as $folder) { if (is_dir($folder)) { $moduleBaseFolders[] = $folder; @@ -238,7 +239,7 @@ public function loadPluginConfig($config, $magentoRootFolder) ->depth(2) ->followLinks() ->ignoreUnreadableDirs(true) - ->name($this->_customConfigFilename) + ->name($customFilename) ->in($this->getVendorDir()); foreach ($finder as $file) { @@ -256,7 +257,7 @@ public function loadPluginConfig($config, $magentoRootFolder) ->depth(1) ->followLinks() ->ignoreUnreadableDirs(true) - ->name($this->_customConfigFilename) + ->name($customFilename) ->in($moduleBaseFolders); foreach ($finder as $file) { From 50ffa8c97eb74d556cd6deed67fbedcad77f0a86 Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Sat, 2 Apr 2016 23:05:42 +0200 Subject: [PATCH 5/9] [FIX] Fix __halt_compiler keyword case Additionally add newline at end of file. --- bin/n98-magerun | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/n98-magerun b/bin/n98-magerun index 8c8cc1870..72ce9b8dd 100755 --- a/bin/n98-magerun +++ b/bin/n98-magerun @@ -5,4 +5,4 @@ $application = require __DIR__.'/../src/bootstrap.php'; $application->run(); -__HALT_COMPILER(); +__halt_compiler(); From 77df9c2b7110b370cfb6608aed333e0777951622 Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Thu, 7 Apr 2016 17:43:01 +0200 Subject: [PATCH 6/9] Fix config:delete The config:delete command did not delete any entries unles --all was used. Issue was caused by variable misuse. --- changes.txt | 2 + .../Command/Config/AbstractConfigCommand.php | 47 +++++- .../Magento/Command/Config/DeleteCommand.php | 155 +++++++++--------- src/N98/Magento/Command/Config/GetCommand.php | 11 +- src/N98/Magento/Command/Config/SetCommand.php | 9 - 5 files changed, 126 insertions(+), 98 deletions(-) diff --git a/changes.txt b/changes.txt index 4db969214..53ea6a6e5 100644 --- a/changes.txt +++ b/changes.txt @@ -6,6 +6,8 @@ RECENT CHANGES 1.97.17 ======= +* #805 Fix config:delete (by Tom Klingenberg) + ======= 1.97.16 ======= diff --git a/src/N98/Magento/Command/Config/AbstractConfigCommand.php b/src/N98/Magento/Command/Config/AbstractConfigCommand.php index 3b35c1d56..a874815f2 100644 --- a/src/N98/Magento/Command/Config/AbstractConfigCommand.php +++ b/src/N98/Magento/Command/Config/AbstractConfigCommand.php @@ -7,6 +7,15 @@ abstract class AbstractConfigCommand extends AbstractMagentoCommand { + /** + * @var array strings of configuration scopes + */ + protected $_scopes = array( + 'default', + 'websites', + 'stores', + ); + /** * @return \Mage_Core_Model_Encryption */ @@ -45,28 +54,44 @@ protected function _formatValue($value, $encryptionType) /** * @param string $scope + * + * @return string */ protected function _validateScopeParam($scope) { if (!in_array($scope, $this->_scopes)) { throw new InvalidArgumentException( - 'Invalid scope parameter. It must be one of ' . implode(',', $this->_scopes) + sprintf('Invalid scope parameter, must be one of: %s.', implode(', ', $this->_scopes)) ); } + + return $scope; } /** * @param string $scope * @param string $scopeId * - * @return string + * @return string non-negative integer number */ protected function _convertScopeIdParam($scope, $scopeId) { + if ($scope === 'default') { + if ("$scopeId" !== "0") { + throw new InvalidArgumentException( + sprintf("Invalid scope ID %d in scope '%s', must be 0", $scopeId, $scope) + ); + } + + return $scopeId; + } + if ($scope == 'websites' && !is_numeric($scopeId)) { $website = \Mage::app()->getWebsite($scopeId); if (!$website) { - throw new InvalidArgumentException('Invalid scope parameter. Website does not exist.'); + throw new InvalidArgumentException( + sprintf("Invalid scope parameter, website '%s' does not exist.", $scopeId) + ); } return $website->getId(); @@ -75,12 +100,26 @@ protected function _convertScopeIdParam($scope, $scopeId) if ($scope == 'stores' && !is_numeric($scopeId)) { $store = \Mage::app()->getStore($scopeId); if (!$store) { - throw new InvalidArgumentException('Invalid scope parameter. Store does not exist.'); + throw new InvalidArgumentException( + sprintf("Invalid scope parameter. store '%s' does not exist.", $scopeId) + ); } return $store->getId(); } + if ($scopeId !== (string)(int)$scopeId) { + throw new InvalidArgumentException( + sprintf("Invalid scope parameter, %s is not an integer value", var_export($scopeId, true)) + ); + } + + if (0 >= (int)$scopeId) { + throw new InvalidArgumentException( + sprintf("Invalid scope parameter, %s is not a positive integer value", var_export($scopeId, true)) + ); + } + return $scopeId; } diff --git a/src/N98/Magento/Command/Config/DeleteCommand.php b/src/N98/Magento/Command/Config/DeleteCommand.php index a4a1643c0..36a5924ed 100644 --- a/src/N98/Magento/Command/Config/DeleteCommand.php +++ b/src/N98/Magento/Command/Config/DeleteCommand.php @@ -9,15 +9,6 @@ class DeleteCommand extends AbstractConfigCommand { - /** - * @var array - */ - protected $_scopes = array( - 'default', - 'websites', - 'stores', - ); - protected function configure() { $this @@ -50,38 +41,26 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { $this->detectMagento($output, true); - if ($this->initMagento()) { - $config = $this->_getConfigModel(); - - $this->_validateScopeParam($input->getOption('scope')); - $scopeId = $this->_convertScopeIdParam($input->getOption('scope'), $input->getOption('scope-id')); - $deleted = array(); + if (!$this->initMagento()) { + return; + } - $path = $input->getArgument('path'); - $pathArray = array(); - if (strstr($path, '*')) { - /* @var $collection \Mage_Core_Model_Resource_Db_Collection_Abstract */ - $collection = $this->_getConfigDataModel()->getCollection(); + $deleted = array(); - $searchPath = str_replace('*', '%', $path); - $collection->addFieldToFilter('path', array('like' => $searchPath)); + $scope = $this->_validateScopeParam($input->getOption('scope')); + $scopeId = $this->_convertScopeIdParam($scope, $input->getOption('scope-id')); - if ($scopeId = $input->getOption('scope')) { - $collection->addFieldToFilter('scope', array('eq' => $scopeId)); - } - $collection->addOrder('path', 'ASC'); + $path = $input->getArgument('path'); - foreach ($collection as $item) { - $pathArray[] = $item->getPath(); - } - } else { - $pathArray[] = $path; - } + if (false !== strstr($path, '*')) { + $paths = $this->expandPathPattern($input, $path); + } else { + $paths = array($path); + } - foreach ($pathArray as $pathToDelete) { - $deleted = array_merge($deleted, $this->_deletePath($input, $config, $pathToDelete, $scopeId)); - } + foreach ($paths as $path) { + $deleted = array_merge($deleted, $this->_deletePath($input, $path, $scopeId)); } if (count($deleted) > 0) { @@ -94,71 +73,83 @@ protected function execute(InputInterface $input, OutputInterface $output) /** * @param InputInterface $input - * @param $config - * @param $path - * @param $scopeId + * @param string $path + * @param string $scopeId * * @return array */ - protected function _deletePath(InputInterface $input, $config, $path, $scopeId) + protected function _deletePath(InputInterface $input, $path, $scopeId) { $deleted = array(); if ($input->getOption('all')) { - // Default - $config->deleteConfig( - $path, - 'default', - 0 - ); - - $deleted[] = array( - 'path' => $path, - 'scope' => 'default', - 'scopeId' => 0, - ); + $deleted[] = $this->deleteConfigEntry($path, 'default', 0); // Delete websites foreach (\Mage::app()->getWebsites() as $website) { - $config->deleteConfig( - $path, - 'websites', - $website->getId() - ); - $deleted[] = array( - 'path' => $path, - 'scope' => 'websites', - 'scopeId' => $website->getId(), - ); + $deleted[] = $this->deleteConfigEntry($path, 'websites', $website->getId()); } // Delete stores foreach (\Mage::app()->getStores() as $store) { - $config->deleteConfig( - $path, - 'stores', - $store->getId() - ); - $deleted[] = array( - 'path' => $path, - 'scope' => 'stores', - 'scopeId' => $store->getId(), - ); + $deleted[] = $this->deleteConfigEntry($path, 'stores', $store->getId()); } } else { - $config->deleteConfig( - $path, - $input->getOption('scope'), - $scopeId - ); - - $deleted[] = array( - 'path' => $path, - 'scope' => $input->getOption('scope'), - 'scopeId' => $scopeId, - ); + $deleted[] = $this->deleteConfigEntry($path, $input->getOption('scope'), $scopeId); } return $deleted; } + + /** + * @param string $pattern + * @return array + */ + private function expandPathPattern($input, $pattern) + { + $paths = array(); + + /* @var $collection \Mage_Core_Model_Resource_Db_Collection_Abstract */ + $collection = $this->_getConfigDataModel()->getCollection(); + + $likePattern = str_replace('*', '%', $pattern); + $collection->addFieldToFilter('path', array('like' => $likePattern)); + + if ($scope = $input->getOption('scope')) { + $collection->addFieldToFilter('scope', array('eq' => $scope)); + } + $collection->addOrder('path', 'ASC'); + + foreach ($collection as $item) { + $paths[] = $item->getPath(); + } + + return $paths; + } + + /** + * Delete concrete entry from config table specified by path, scope and scope-id + * + * @param string $path + * @param string $scope + * @param int $scopeId + * + * @return array + */ + private function deleteConfigEntry($path, $scope, $scopeId) + { + $config = $this->_getConfigModel(); + + $config->deleteConfig( + $path, + $scope, + $scopeId + ); + + return array( + 'path' => $path, + 'scope' => $scope, + 'scopeId' => $scopeId, + ); + } } diff --git a/src/N98/Magento/Command/Config/GetCommand.php b/src/N98/Magento/Command/Config/GetCommand.php index 5644d4149..782a3a581 100644 --- a/src/N98/Magento/Command/Config/GetCommand.php +++ b/src/N98/Magento/Command/Config/GetCommand.php @@ -28,7 +28,12 @@ protected function configure() EOT ) ->addArgument('path', InputArgument::OPTIONAL, 'The config path') - ->addOption('scope', null, InputOption::VALUE_REQUIRED, 'The config value\'s scope') + ->addOption( + 'scope', + null, + InputOption::VALUE_REQUIRED, + 'The config value\'s scope (default, websites, stores)' + ) ->addOption('scope-id', null, InputOption::VALUE_REQUIRED, 'The config value\'s scope ID') ->addOption( 'decrypt', @@ -77,8 +82,8 @@ protected function execute(InputInterface $input, OutputInterface $output) 'like' => str_replace('*', '%', $searchPath) )); - if ($scopeId = $input->getOption('scope')) { - $collection->addFieldToFilter('scope', array('eq' => $scopeId)); + if ($scope = $input->getOption('scope')) { + $collection->addFieldToFilter('scope', array('eq' => $scope)); } if ($scopeId = $input->getOption('scope-id')) { diff --git a/src/N98/Magento/Command/Config/SetCommand.php b/src/N98/Magento/Command/Config/SetCommand.php index 32479ab33..61fb02035 100644 --- a/src/N98/Magento/Command/Config/SetCommand.php +++ b/src/N98/Magento/Command/Config/SetCommand.php @@ -9,15 +9,6 @@ class SetCommand extends AbstractConfigCommand { - /** - * @var array - */ - protected $_scopes = array( - 'default', - 'websites', - 'stores', - ); - protected function configure() { $this From 8aa6c6256b051495927aa9e0ab8187930e5ea89c Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Sun, 3 Apr 2016 12:59:04 +0200 Subject: [PATCH 7/9] Fix typos --- build/local/test_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/local/test_setup.sh b/build/local/test_setup.sh index e96105ceb..ec5cf07e5 100755 --- a/build/local/test_setup.sh +++ b/build/local/test_setup.sh @@ -22,7 +22,7 @@ installed_magerun_cmd() { echo "${magerun_cmd}" } -# obtain installed vesion of the test-setup +# obtain installed version of the test-setup installed_version() { local magerun_cmd="$(installed_magerun_cmd)" local directory="${test_setup_directory}" @@ -35,7 +35,7 @@ installed_version() { fi } -# checks befor starting the setup +# checks before starting the setup ensure_environment() { local magerun_cmd="$(installed_magerun_cmd)" local directory="${test_setup_directory}" From 580cc2357d951f9dd8e39e54a9e914ac61980598 Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Thu, 7 Apr 2016 19:01:44 +0200 Subject: [PATCH 8/9] Prepare sharing --- build/local/test_setup.sh | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/build/local/test_setup.sh b/build/local/test_setup.sh index ec5cf07e5..fa9bf60da 100755 --- a/build/local/test_setup.sh +++ b/build/local/test_setup.sh @@ -44,6 +44,10 @@ ensure_environment() { if [ ! -d "${directory}" ]; then mkdir -p "${directory}" + # create .gitignore one-up if it does not yet exists to allow having the install within an existing git repo + if [ ! -e "${directory}/../.gitignore" ]; then + echo "*" > "${directory}/../.gitignore" + fi fi; buildecho "directory: '${directory}'" } @@ -77,11 +81,9 @@ ensure_magento() { local install_sample_data="${2:-no}" local magerun_cmd="${test_setup_magerun_cmd}" + local version="$(installed_version)" - local magento_local_xml="${directory}/app/etc/local.xml" - - if [ -e "${magento_local_xml}" ]; then - local version="$(php -dmemory_limit=1g -f "${magerun_cmd}" -- --root-dir="${directory}" sys:info -- "version")" + if [ "" != "$version" ]; then buildecho "version '${version}' already installed, skipping setup" else php -dmemory_limit=1g -f "${magerun_cmd}" -- install \ @@ -90,14 +92,6 @@ ensure_magento() { --installSampleData="${install_sample_data}" --useDefaultConfigParams=yes \ --baseUrl="http://dev.magento.local/" buildecho "magento version '${magento_version}' installed." - - # automatically ignore the test installation directory as this is a local and interactive development env - local gitignore="${directory}/.gitignore" - if [ ! -e "${gitignore}" ]; then - touch "${gitignore}" - fi - - echo '*' > "${gitignore}" fi } @@ -111,11 +105,10 @@ test_setup_db_name="magento_magerun_test" if [ "" != "$(installed_version)" ]; then buildecho "version '$(installed_version)' already installed, skipping setup" - exit 0 +else + ensure_environment + ensure_mysql_db + ensure_magento "magento-mirror-1.9.2.3" fi -ensure_environment -ensure_mysql_db -ensure_magento "magento-mirror-1.9.2.3" - buildecho "export N98_MAGERUN_TEST_MAGENTO_ROOT='${test_setup_directory}'" From 98934b5e0c9621f3f5488e51e5b2fe6c368bdd3a Mon Sep 17 00:00:00 2001 From: Tom Klingenberg Date: Fri, 8 Apr 2016 12:02:54 +0200 Subject: [PATCH 9/9] Fix module loader Ref: 94d9430 --- changes.txt | 1 + src/N98/Magento/Application/ConfigurationLoader.php | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/changes.txt b/changes.txt index 53ea6a6e5..5c1e710be 100644 --- a/changes.txt +++ b/changes.txt @@ -6,6 +6,7 @@ RECENT CHANGES 1.97.17 ======= +* Fix: Fix module loader (reported by Matthias Walter, fixed by TK) * #805 Fix config:delete (by Tom Klingenberg) ======= diff --git a/src/N98/Magento/Application/ConfigurationLoader.php b/src/N98/Magento/Application/ConfigurationLoader.php index 3103c0a3a..0a7e7a164 100644 --- a/src/N98/Magento/Application/ConfigurationLoader.php +++ b/src/N98/Magento/Application/ConfigurationLoader.php @@ -215,13 +215,14 @@ public function loadPluginConfig($config, $magentoRootFolder) $this->_pluginConfig = array(); $moduleBaseFolders = array(); $customFilename = $this->_customConfigFilename; + $customName = pathinfo($customFilename, PATHINFO_FILENAME); if (OperatingSystem::isWindows()) { - $config['plugin']['folders'][] = getenv('WINDIR') . '/' . $customFilename . '/modules'; - $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/' . $customFilename . '/modules'; + $config['plugin']['folders'][] = getenv('WINDIR') . '/' . $customName . '/modules'; + $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/' . $customName . '/modules'; } else { - $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/.' . $customFilename . '/modules'; + $config['plugin']['folders'][] = OperatingSystem::getHomeDir() . '/.' . $customName . '/modules'; } - $config['plugin']['folders'][] = $magentoRootFolder . '/lib/' . $customFilename . '/modules'; + $config['plugin']['folders'][] = $magentoRootFolder . '/lib/' . $customName . '/modules'; foreach ($config['plugin']['folders'] as $folder) { if (is_dir($folder)) { $moduleBaseFolders[] = $folder;