/** * Create test database and provide information for database access * @throws Exception */ protected function setupTestDatabase() { // create database, same name as magento database, only appending '_test' if (false === $this->createDatabase($this->config->getDbName() . '_test')) { throw new Exception('Could not create test database'); } // set access information in local.xml.phpunit $file = $this->config->getTarget() . '/app/etc/local.xml.phpunit'; $db = sprintf('<dbname><\\![CDATA[%s_test]]><\\/dbname>', $this->config->getDbName()); $cmd = sprintf('sed -i "s/<dbname>.*<\\/dbname>/%s/g" %s', $db, $file); exec($cmd, $result, $return); if (0 !== $return) { Logger::error('Failed to set db name for unit testing framework'); } // unify base url, as ecomdev/magento needs it with protocol and trailing slash given $baseUrl = ltrim($this->config->getMagentoBaseUrl(), 'http://'); $baseUrl = rtrim($baseUrl, '/'); $baseUrl = "http://{$baseUrl}/"; $baseUrl = '<base_url>' . str_replace('/', '\\/', $baseUrl) . '<\\/base_url>'; $cmd = sprintf('sed -i "s/<base_url>.*<\\/base_url>/%s/g" %s', $baseUrl, $file); exec($cmd, $result, $return); if (0 !== $return) { Logger::error('Failed to set base url for unit testing framework'); } }
public function execute() { $filename = $this->config->getTarget() . '/robots.txt'; $lines = $this->config->plugins->RobotsTxt->lines->toArray(); if (false === file_put_contents($filename, implode(PHP_EOL, $lines))) { Logger::error('An error occured while creating robots.txt', array(), false); } }
protected function modifyProduct(\Mage_Catalog_Model_Product $product, \Zend_Config $settings) { foreach ($settings as $attribute => $value) { $product->setData($attribute, $value); Logger::log('* change attribute <comment>%s</comment> of product #%d: "%s"', array($attribute, $product->getId(), $value)); } $product->save(); }
protected function _checkout($targetPath, $branch) { Logger::log('Git checkout %s', array($branch)); $command = sprintf('cd %s; git checkout %s 2>&1; cd -', $targetPath, $branch); exec($command, $result, $return); if (0 !== $return) { throw new Exception(implode(PHP_EOL, $result)); } }
public function execute() { $commands = $this->config->plugins->Cli->commands->toArray(); foreach ($commands as $command) { $cmd = escapeshellcmd($command); Logger::comment("Running custom command: {$cmd}"); exec($cmd); } }
/** * Execute the PerformanceCheck plugin */ protected function _execute() { $possiblePerformanceKillers = $this->_scanForPerformanceLeaks($this->_extensionPath); if (0 < sizeof($possiblePerformanceKillers)) { foreach ($possiblePerformanceKillers as $possiblePerformanceKiller) { Logger::setResultValue($this->_extensionPath, $this->_pluginName, $possiblePerformanceKiller, count($possiblePerformanceKillers)); IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'performance_leak', "comment" => $possiblePerformanceKiller . ' (' . count($possiblePerformanceKillers) . 'times)', "failed" => true))); } } }
public function execute() { Mage::app('admin'); \Mage_Core_Model_Resource_Setup::applyAllUpdates(); \Mage_Core_Model_Resource_Setup::applyAllDataUpdates(); try { $this->setup(); } catch (Exception $e) { $msg .= $e->getMessage() . ' (' . $e->getFile() . ' l. ' . $e->getLine() . ")\n"; Logger::error('An error occured while initializing InitGermanSetup:', array(), false); Logger::log('%s (%s, line %s)', array($e->getMessage(), $e->getFile(), $e->getLine())); } }
/** * determine which Magento versions seem to be compatible to this call * * @return array Array of Magento versions (e.g. [ 'CE 1.6.2.0', 'CE 1.7.0.2' ]) */ public function getMagentoVersions() { if ($fixedVersions = $this->_getFixedVersions()) { return $fixedVersions; } $query = 'SELECT ' . implode(', ', $this->_getFieldsToSelect()) . ' FROM [' . $this->_table . '] t INNER JOIN [' . $this->_tagType . '_signature] ts ON (t.id = ts.' . $this->_tagType . '_id) INNER JOIN [signatures] s ON (ts.signature_id = s.id) WHERE t.name = %s GROUP BY s.id'; try { /* find all signatures matching that call */ $result = dibi::query($query, $this->getName()); } catch (\DibiDriverException $e) { dibi::test($query, $this->getName()); throw $e; } $versions = array(); if (is_null($result) || 0 == count($result)) { return null; } /* get best matching signature id */ if (1 < count($result)) { $signatureIds = $this->_getBestMatching($result->fetchAll()); } else { try { $signatureIds = array_keys($result->fetchPairs()); } catch (\DibiDriverException $e) { dibi::test($query, $signatureId); throw $e; } } if (false == is_array($signatureIds) || 0 == count($signatureIds)) { Logger::warning('Could not find any matching definition of ' . $this->_name); return null; } /* fetch Magento versions */ $query = 'SELECT CONCAT(edition, " ", version) AS magento FROM [magento_signature] ms INNER JOIN [magento] m ON (ms.magento_id = m.id) WHERE ms.signature_id IN (%s) GROUP BY magento'; try { return dibi::fetchPairs($query, $signatureIds); } catch (\DibiDriverException $e) { dibi::test($query, $signatureId); throw $e; } }
public function execute() { Mage::app('admin'); if (!Mage::getSingleton('fastsimpleimport/import')) { Logger::error('Could not create dummy products. Please add extension %s to be installed', array('git://github.com/avstudnitz/AvS_FastSimpleImport.git'), false); return; } $settings = $this->config->plugins->{$this->getPluginName()}; $countOfSimpleProducts = 0; $countOfConfigurableProducts = 0; $countOfBundleProducts = 0; $countOfGroupedProducts = 0; $countOfVirtualProducts = 0; $countOfDownloadProducts = 0; if ($settings instanceof \Zend_Config) { if ($settings->simpleProducts) { $countOfSimpleProducts = $settings->simpleProducts; } if ($settings->configurableProducts) { $countOfConfigurableProducts = $settings->configurableProducts; } if ($settings->bundleProducts) { $countOfBundleProducts = $settings->bundleProducts; } if ($settings->groupedProducts) { $countOfGroupedProducts = $settings->groupedProducts; } if ($settings->virtualProducts) { $countOfVirtualProducts = $settings->virtualProducts; } if ($settings->downloadProducts) { $countOfDownloadProducts = $settings->downloadProducts; } } else { $countOfSimpleProducts = $settings; } $data = array(); $data = $this->getSimpleProducts($countOfSimpleProducts); /* * @todo $data = array_merge($data, $this->getConfigurableProducts($countOfConfigurableProducts)); $data = array_merge($data, $this->getBundleProducts($countOfBundleProducts)); $data = array_merge($data, $this->getGroupedProducts($countOfGroupedProducts)); $data = array_merge($data, $this->getVirtualProducts($countOfVirtualProducts)); $data = array_merge($data, $this->getDownloadProducts($countOfDownloadProducts)); */ $this->import($data); }
public function copy($target, $branch = 'master') { if (!file_exists($this->_source)) { throw new Exception("Source directory does not exist: '{$this->_source}'"); } // make sure that source ends with directory separator // as we want to copy its contents, not the directory itself $this->_source = rtrim($this->_source, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; Logger::log('Copy files from %s', array($this->_source)); $command = sprintf('rsync -a -h %s %s 2>&1', $this->_source, $target); Logger::log($command); exec($command, $result, $return); if (0 !== $return) { throw new Exception("Could not copy files to {$target}"); } }
public function execute() { $settings = $this->config->plugins->ApplyConfigSettings; if ($settings instanceof \Zend_Config) { foreach ($this->config->plugins->ApplyConfigSettings as $name => $setting) { if ($setting instanceof \Zend_Config && $setting->path && isset($setting->value)) { Mage::getModel('eav/entity_setup', 'core_setup')->setConfigData($setting->path, $setting->value); Logger::log('* Applied setting %s', array($name)); } else { Logger::error('Did not apply setting %s', array($name), false); } } } else { Logger::error('Invalid configuration for plugin ApplyConfigSettings', array(), false); } }
protected function _getProcesses($setting) { $processes = array(); if ($setting == 'all') { $collection = $this->_getIndexer()->getProcessesCollection(); foreach ($collection as $process) { $processes[] = $process; } } else { if (!empty($setting)) { foreach ($setting as $code) { $process = $this->_getIndexer()->getProcessByCode(trim($code)); if (!$process) { Logger::error('Unknown indexer with code %s', array(trim($code)), false); } else { $processes[] = $process; } } } } return $processes; }
/** * @see vendor/symfony/src/Symfony/Component/Console/Command/Symfony\Component\Console\Command.Command::execute() */ protected function execute(InputInterface $input, OutputInterface $output) { $this->preExecute($input, $output); $this->initMagento(); $plugins = $this->config->getPlugins(); foreach ($plugins as $name => $settings) { // check if plugin was defined in ini, but disabled if ('0' === $settings->enabled) { Logger::log('Skipping plugin "%s"', array($name)); continue; } // set path to plugin by convention $path = $this->getBasePath() . 'plugins' . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR; // load script file $file = $path . $name . '.php'; if (!file_exists($file)) { Logger::error('Could not find plugin "%s"', array($name), $stop = false); Logger::log('Expected it at path "%s"', array($path)); continue; } // load default jumpstorm config for plugin execution $pluginConfig = $this->config; $customIni = $settings->ini; if (null !== $customIni && file_exists($customIni)) { unset($settings->ini); // add custom config settings, if given $pluginConfig = new Config($customIni, null, array('allowModifications' => true)); $pluginConfig->merge($this->config); } Logger::comment(sprintf('Running plugin "%s"', $name)); $class = "{$name}\\{$name}"; $plugin = new $class($pluginConfig); $plugin->execute(); Logger::notice(sprintf('Finished running plugin "%s"', $name)); } Logger::notice('Done'); }
protected function generateResultHtml($extension) { HamlLoader::register(); $haml = new HamlGenerator('php', array('enable_escaper' => false)); $template = 'Resources/views/result.haml'; $targetFile = 'tmp/result.php'; $compiled = $haml->compileString(file_get_contents($template), $template); file_put_contents($targetFile, $compiled); // $results = $this->convertResultCommentsToHtml( // Logger::getResultArray($extension) // ); // $results = $this->convertResultCommentsToHtml(Logger::getIssueResults($extension)); $passedChecks = Logger::getPassedChecksOfIssueHandler($extension); $failedChecks = Logger::getFailedChecksOfIssueHandler($extension); // $failedChecks = $results['failedChecks']; // $score = $results['score']; ob_start(); include $targetFile; $result = ob_get_contents(); ob_end_clean(); $targetHtml = 'tmp/result.html'; file_put_contents($targetHtml, $result); }
/** * Create empty database. Any old database with the same name gets dropped. * @todo use built-in mysql commands instead of calling exec() * * @return boolean true on success, false otherwise */ protected function createDatabase($dbName) { // prepare mysql command: user, host and password $mysql = $this->prepareMysqlCommand(); // recreate database if it already exists Logger::log('Creating database %s', array($dbName)); exec(sprintf('%s -e \'DROP DATABASE IF EXISTS `%s`\'', $mysql, $dbName), $result, $return); exec(sprintf('%s -e \'CREATE DATABASE `%s`\'', $mysql, $dbName), $result, $return); return 0 === $return; }
public function __call($method, $args) { Logger::warning("Called Magento method \"{$method}\" in installer script"); return $this; }
/** * Extension files are installed to .modman directory before deployment, * so create that directory if necessary * * @return string Absolute path to extension directory */ private function createExtensionFolder() { $this->validateTarget($this->config->getTarget()); $folder = $this->getExtensionFolder(); if (!is_dir($folder)) { Logger::log('Creating extension folder %s', array($folder)); mkdir($folder); } return $folder; }
/** * Sync extension files from .modman to target directories * * @param string $alias */ protected function deployExtension($alias) { // detect location of modman file, if available $modmanFile = $this->locateModmanFile(); if ($modmanFile) { // if modman file was found, deploy via modman // alias may have to be changed to subdirectory $pattern = sprintf("|^%s/(.+)/%s\$|", $this->extensionRootDir, 'modman'); preg_match($pattern, $modmanFile, $matches); $alias = $matches[1]; Logger::log('Deploying extension %s via modman', array($alias)); $command = sprintf('cd %s; modman deploy %s --force', $this->magentoRoot, $alias); exec($command, $result, $return); } else { // deploy via rsync otherwise Logger::log('Deploying extension %s via rsync', array($alias)); $command = sprintf('rsync -a -h --exclude="doc/*" --exclude="*.git" %s %s 2>&1', $this->extensionDir . DIRECTORY_SEPARATOR, $this->magentoRoot); exec($command, $result, $return); } if (0 !== $return) { throw new Exception("Could not deploy extension {$alias}"); } }
/** * Execute the MageCompatibility plugin */ protected function _execute() { try { $this->_connectTagDatabase(); $availableVersions = dibi::query('SELECT concat( m.edition, " ", m.version ) as Magento FROM magento m ORDER BY Magento')->fetchPairs(); $supportedVersions = array(); $extension = new Extension($this->_extensionPath); $methods = $extension->getUsedMagentoMethods(); $classes = $extension->getUsedMagentoClasses(); IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => sprintf('Extension uses %d classes and %d methods of Magento core', $classes->count(), $methods->count()), "failed" => true))); $incompatibleVersions = array(); foreach ($availableVersions as $version) { $incompatibleVersions[$version] = array('classes' => array(), 'methods' => array(), 'constants' => array()); } foreach ($classes as $class) { $class->setConfig($this->_settings); $supportedVersions = $class->getMagentoVersions(); if (is_array($supportedVersions)) { $tagIncompatibleVersions = array_diff($availableVersions, $supportedVersions); foreach ($tagIncompatibleVersions as $version) { $incompatibleVersions[$version]['classes'][] = $class->getName(); } } } foreach ($methods as $method) { $isExtensionMethod = false; $context = current($method->getContext()); $method->setConfig($this->_settings); $supportedVersions = $method->getMagentoVersions(); //echo $context['class'] . '->' . $method->getName() . ' '; if (false == is_array($supportedVersions)) { continue; } $tagIncompatibleVersions = array_diff($availableVersions, $supportedVersions); foreach ($tagIncompatibleVersions as $version) { $methodName = $method->getContext('class') . '->' . $method->getName() . '(' . implode(', ', $method->getParams()) . ')'; if ($extension->hasMethod($method->getName())) { $methodName .= ' [maybe part of the extension]'; continue; } $incompatibleVersions[$version]['methods'][] = $methodName; } } $compatibleVersions = array(); foreach ($incompatibleVersions as $version => $incompatibilities) { $message = ''; $incompatibleClasses = array_unique($incompatibilities['classes']); $incompatibleMethods = array_unique($incompatibilities['methods']); $incompatibleConstants = array_unique($incompatibilities['constants']); if (0 < count($incompatibleClasses)) { $message .= sprintf("<comment>The following classes are not compatible to Magento %s:</comment>\n * %s\n", $version, implode("\n * ", $incompatibleClasses)); } if (0 < count($incompatibleMethods)) { $message .= sprintf("<comment>The following methods are not compatible to Magento %s:</comment>\n * %s\n", $version, implode("\n * ", $incompatibleMethods)); } if (0 < count($incompatibleConstants)) { $message .= sprintf("<comment>The following constants are not compatible to Magento %s:</comment>\n * %s\n", $version, implode("\n * ", $incompatibleConstants)); } if (0 < strlen($message)) { IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => sprintf("<error>Extension is not compatible to Magento %s</error>\n%s", $version, $message), "failed" => true))); } else { $compatibleVersions[] = $version; } } IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => 'Checked Magento versions: ' . implode(', ', $availableVersions) . "\n" . '* Extension seems to support following Magento versions: ' . implode(', ', $compatibleVersions), "failed" => false))); foreach (array_keys($incompatibleVersions) as $key) { if (0 == count($incompatibleVersions[$key]['classes']) && 0 == count($incompatibleVersions[$key]['methods']) && 0 == count($incompatibleVersions[$key]['constants'])) { unset($incompatibleVersions[$key]); } } if ($this->_containsNoLatestVersion(array_keys($incompatibleVersions), 'CE')) { IssueHandler::addIssue(new Issue(array("extension" => $this->_extensionPath, "checkname" => $this->_pluginName, "type" => 'mage_compatibility', "comment" => sprintf('Extension supports Magento at least from CE version %s and EE version %s', $this->_settings->min->ce, $this->_settings->min->ee), "failed" => false))); return; } } catch (\Exception $e) { $this->setUnfinishedIssue(); $message = is_array($e->getMessage()) ? $e->getMessage() : array($e->getMessage()); Logger::error(implode(PHP_EOL, $message), array(), false); return; } }
/** * Check if all prerequisites for running unit tests are fullfilled or can * be fulfilled by using Jumpstorm. * * @param string $extensionPath Path to the extension to be evaluated * @throws \Exception */ protected function _setupUnitTestEnvironment($extensionPath) { /** * getting the neccessary information like magento target from * the jumpstorm configuration even jumpstorm is not used to set up * the test environment */ if (!$this->_settings->jumpstormIniFile) { throw new \Exception("Required information missing in ini file: plugins.CodeCoverage.jumpstormIniFile"); } $jumpstormConfig = new \Zend_Config_Ini($this->_settings->jumpstormIniFile, null, array('allowModifications' => true)); // check if required ini section is given if (!$jumpstormConfig->common) { throw new \Exception("Required information missing in jumpstorm ini file: [common]"); } if ($this->_config->token) { $jumpstormConfig->common->magento->target = $jumpstormConfig->common->magento->target . '_' . $this->_config->token; $jumpstormConfig->common->db->name = $jumpstormConfig->common->db->name . '_' . $this->_config->token; } $this->_magentoTarget = rtrim($jumpstormConfig->common->magento->target, DIRECTORY_SEPARATOR); $this->_testDbName = $jumpstormConfig->common->db->name; // import test environment configuration from console: [extensions] section $jumpstormConfig->extensions = array('extension' => array('source' => $extensionPath)); // force (re)installation using jumpstorm if ($this->_settings->useJumpstorm) { $requiredSections = array('magento', 'unittesting'); foreach ($requiredSections as $section) { if (!$jumpstormConfig->{$section}) { throw new \Exception("Required information missing in jumpstorm ini file: [{$section}]"); } } $iniFile = 'tmp/jumpstorm' . (string) $this->_config->token . '.ini'; $writer = new \Zend_Config_Writer_Ini(); $writer->write($iniFile, $jumpstormConfig); $executable = 'vendor/netresearch/jumpstorm/jumpstorm'; $params = ''; if (Logger::VERBOSITY_MAX == Logger::getVerbosity()) { $params .= ' -v'; } $command = sprintf('%s magento -c %s %s', $executable, $iniFile, $params) . ' && ' . sprintf('%s unittesting -c %s %s', $executable, $iniFile, $params) . ' && ' . sprintf('%s extensions -c %s %s', $executable, $iniFile, $params); Logger::notice('Setting up Magento environment via Jumpstorm'); $output = $this->_executeCommand($command); if (Logger::VERBOSITY_MAX == Logger::getVerbosity()) { Logger::log(implode("\n", $output)); } unlink($iniFile); } }
/** * collect method calls * * @param PHPParser_Node_Stmt $stmt * @return int Number of called methods */ protected function _collectMethodCalls($stmt, $xmlTree) { $numberOfMethodCalls = 0; $methodCallXPath = '//node:Expr_MethodCall | //node:Expr_StaticCall'; $methodCalls = $xmlTree->xpath($methodCallXPath); foreach ($methodCalls as $call) { $methodName = $call->xpath('./subNode:name/scalar:string/text()'); if (false === $methodName) { continue; } $methodName = current($methodName); if (is_array($methodName)) { $methodName = current($methodName); } $variable = current($call->xpath('./subNode:var | ./subNode:class')); $object = $this->_getResultType($variable); if (false == $object) { continue; } if ($this->_isPhpMethod($object, $methodName)) { continue; } if ($this->_isCallabilityChecked($call, $object, $methodName)) { Logger::addComment($this->_extensionPath, 'MageCompatibility', sprintf('<info>Found version switch</info> for %s::%s', $object, $methodName)); continue; } if (false == $this->_isExtensionMethod($object, $methodName)) { $method = new Method((string) $methodName, $this->_getArgs($call), array('class' => $object)); ++$numberOfMethodCalls; $this->_usedMethods->add($method); } } return $numberOfMethodCalls; }
/** * @see vendor/symfony/src/Symfony/Component/Console/Command/Symfony\Component\Console\Command.Command::execute() */ protected function execute(InputInterface $input, OutputInterface $output) { $this->preExecute($input, $output); // set the path where magento should get installed $target = $this->validateTarget($this->config->getTarget()); // empty target directory if it already exists if (file_exists($target)) { Logger::comment('Delete existing Magento at %s', array($target)); exec(sprintf('rm -rf %s/*', $target)); exec(sprintf('rm -rf %s/.[a-zA-Z0-9]*', $target)); } // set the source where magento should get retrieved from $source = $this->config->getMagentoSource(); // copy files from source to target $this->installMagento($source, $target, $this->config->getMagentoBranch()); // move installed files to docroot $this->moveToDocroot($target, 'htdocs'); $this->moveToDocroot($target, 'magento'); Logger::success('Fetched Magento sources'); // create empty database with credentials from ini file if (false === $this->createDatabase($this->config->getDbName())) { throw new Exception('Could not create live database'); } // install sample data if (null !== $this->config->getMagentoSampledataSource()) { $this->installSampledata($this->config->getMagentoSampledataSource(), $target, $this->config->getMagentoSampledataBranch()); Logger::success('Installed sample data'); } // run install.php $this->runMageScript($target); // clean cache exec(sprintf('rm -rf %s/var/cache/*', $target)); Logger::success('Finished Magento installation'); }