/** * Install action callback * * @throws Exception * @param string $command * @param array $options * @param array $params * @param array $objects * @return array|null */ public function doInstall($command, $options, $params, $objects = array()) { $this->cleanupParams($params); $installFileMode = $command === 'install-file'; /** @var $ftpObj Mage_Connect_Ftp */ $ftpObj = null; $ftp = empty($options['ftp']) ? false : $options['ftp']; /** @var $packager Mage_Connect_Packager */ $packager = $this->getPackager(); /** @var $cache Mage_Connect_Singleconfig */ /** @var $config Mage_Connect_Config */ if ($ftp) { list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp); } else { $cache = $this->getSconfig(); $config = $this->config(); } try { $forceMode = isset($options['force']); $upgradeAllMode = $command == 'upgrade-all'; $upgradeMode = $command == 'upgrade' || $command == 'upgrade-all'; $noFilesInstall = isset($options['nofiles']); $withDepsMode = !isset($options['nodeps']); $ignoreModifiedMode = true || !isset($options['ignorelocalmodification']); $clearInstallMode = $command == 'install' && !$forceMode; $installAll = isset($options['install_all']); $channelAuth = isset($options['auth']) ? $options['auth'] : array(); $rest = $this->rest(); if (empty($config->magento_root)) { $config->magento_root = dirname(dirname($_SERVER['SCRIPT_FILENAME'])); } chdir($config->magento_root); $dirCache = DIRECTORY_SEPARATOR . $config->downloader_path . DIRECTORY_SEPARATOR . Mage_Connect_Config::DEFAULT_CACHE_PATH; $dirTmp = DIRECTORY_SEPARATOR . Mage_Connect_Package_Reader::PATH_TO_TEMPORARY_DIRECTORY; $dirMedia = DIRECTORY_SEPARATOR . 'media'; $isWritable = true; if ($ftp) { $cwd = $ftpObj->getcwd(); $ftpObj->mkdirRecursive($cwd . $dirCache, 0777); $ftpObj->chdir($cwd); $ftpObj->mkdirRecursive($cwd . $dirTmp, 0777); $ftpObj->chdir($cwd); $ftpObj->mkdirRecursive($cwd . $dirMedia, 0777); $ftpObj->chdir($cwd); $err = "Please check for sufficient ftp write file permissions."; } else { @mkdir($config->magento_root . $dirCache, 0777, true); @mkdir($config->magento_root . $dirTmp, 0777, true); @mkdir($config->magento_root . $dirMedia, 0777, true); $isWritable = is_writable($config->magento_root) && is_writable($config->magento_root . DIRECTORY_SEPARATOR . $config->downloader_path) && is_writable($config->magento_root . $dirCache) && is_writable($config->magento_root . $dirTmp) && is_writable($config->magento_root . $dirMedia); $err = "Please check for sufficient write file permissions."; } $isWritable = $isWritable && is_writable($config->magento_root . $dirMedia) && is_writable($config->magento_root . $dirCache) && is_writable($config->magento_root . $dirTmp); if (!$isWritable) { $this->doError($command, $err); throw new Exception('Your Magento folder does not have sufficient write permissions, which downloader requires.'); } if (!empty($channelAuth)) { $rest->getLoader()->setCredentials($channelAuth['username'], $channelAuth['password']); } if ($installFileMode) { if (count($params) < 1) { throw new Exception("Argument should be: filename"); } $filename = $params[0]; if (!@file_exists($filename)) { throw new Exception("File '{$filename}' not found"); } if (!@is_readable($filename)) { throw new Exception("File '{$filename}' is not readable"); } $package = new Mage_Connect_Package($filename); $package->setConfig($config); $package->validate(); $errors = $package->getErrors(); if (count($errors)) { throw new Exception("Package file is invalid\n" . implode("\n", $errors)); } $pChan = $package->getChannel(); $pName = $package->getName(); $pVer = $package->getVersion(); if (!($cache->isChannelName($pChan) || $cache->isChannelAlias($pChan))) { throw new Exception("The '{$pChan}' channel is not installed. Please use the MAGE shell " . "script to install the '{$pChan}' channel."); } $conflicts = $cache->hasConflicts($pChan, $pName, $pVer); if (false !== $conflicts) { $conflicts = implode(", ", $conflicts); if ($forceMode) { $this->doError($command, "Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts); } else { throw new Exception("Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts); } } $conflicts = $package->checkPhpDependencies(); if (true !== $conflicts) { $conflicts = implode(",", $conflicts); $err = "Package {$pChan}/{$pName} {$pVer} depends on PHP extensions: " . $conflicts; if ($forceMode) { $this->doError($command, $err); } else { throw new Exception($err); } } $conflicts = $package->checkPhpVersion(); if (true !== $conflicts) { $err = "Package {$pChan}/{$pName} {$pVer}: " . $conflicts; if ($forceMode) { $this->doError($command, $err); } else { throw new Exception($err); } } if (!$noFilesInstall) { if ($ftp) { $packager->processInstallPackageFtp($package, $filename, $config, $ftpObj); } else { $packager->processInstallPackage($package, $filename, $config); } } $cache->addPackage($package); $installedDeps = array(); $installedDepsAssoc = array(); $installedDepsAssoc[] = array('channel' => $pChan, 'name' => $pName, 'version' => $pVer); $installedDeps[] = array($pChan, $pName, $pVer); $title = isset($options['title']) ? $options['title'] : "Package installed: "; $out = array($command => array('data' => $installedDeps, 'assoc' => $installedDepsAssoc, 'title' => $title)); if ($ftp) { $packager->writeToRemoteCache($cache, $ftpObj); @unlink($config->getFilename()); } $this->ui()->output($out); return $out[$command]['data']; } if (!$upgradeAllMode) { if (count($params) < 2) { throw new Exception("Argument should be: channelName packageName"); } $channel = $params[0]; $package = $params[1]; $argVersionMax = isset($params[2]) ? $params[2] : false; $argVersionMin = isset($params[3]) ? $params[3] : false; $cache->checkChannel($channel, $config, $rest); $channelName = $cache->chanName($channel); $this->ui()->output("Checking dependencies of packages"); $packagesToInstall = $packager->getDependenciesList($channelName, $package, $cache, $config, $argVersionMax, $argVersionMin, $withDepsMode, false, $rest); /* * process 'failed' results */ if (count($packagesToInstall['failed'])) { $showError = !count($packagesToInstall['result']); foreach ($packagesToInstall['failed'] as $failed) { $msg = "Package {$failed['channel']}/{$failed['name']} failed: " . $failed['reason']; if ($showError) { $this->doError($command, $msg); } else { $this->ui()->output($msg); } } } $packagesToInstall = $packagesToInstall['result']; } else { if (empty($params[0])) { $channels = $cache->getChannelNames(); } else { $channel = $params[0]; if (!$cache->isChannel($channel)) { throw new Exception("'{$channel}' is not existant channel name / valid uri"); } $channels = $cache->chanName($channel); } $packagesToInstall = array(); $neededToUpgrade = $packager->getUpgradesList($channels, $cache, $config, $rest); foreach ($neededToUpgrade as $chan => $packages) { foreach ($packages as $name => $data) { $versionTo = $data['to']; $tmp = $packager->getDependenciesList($chan, $name, $cache, $config, $versionTo, $versionTo, $withDepsMode, false, $rest); if (count($tmp['result'])) { $packagesToInstall = array_merge($packagesToInstall, $tmp['result']); } } } } /** * Make installation */ $installedDeps = array(); $installedDepsAssoc = array(); foreach ($packagesToInstall as $package) { try { $pName = $package['name']; $pChan = $package['channel']; $pVer = $package['downloaded_version']; $pInstallState = $package['install_state']; $rest->setChannel($cache->chanUrl($pChan)); /** * Skip existing packages */ if ($upgradeMode && $cache->hasPackage($pChan, $pName, $pVer, $pVer) || 'already_installed' == $pInstallState && !$forceMode) { $this->ui()->output("Already installed: {$pChan}/{$pName} {$pVer}, skipping"); continue; } if ('incompartible' == $pInstallState) { $this->ui()->output("Package incompartible with installed Magento: {$pChan}/{$pName} {$pVer}, skipping"); continue; } $conflicts = $cache->hasConflicts($pChan, $pName, $pVer); if (false !== $conflicts) { $conflicts = implode(", ", $conflicts); if ($forceMode) { $this->doError($command, "Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts); } else { throw new Exception("Package {$pChan}/{$pName} {$pVer} conflicts with: " . $conflicts); } } /** * Modifications */ if (($upgradeMode || $pInstallState == 'upgrade') && !$ignoreModifiedMode) { if ($ftp) { $modifications = $packager->getRemoteModifiedFiles($pChan, $pName, $cache, $config, $ftp); } else { $modifications = $packager->getLocalModifiedFiles($pChan, $pName, $cache, $config); } if (count($modifications) > 0) { $this->ui()->output('Changed locally: '); foreach ($modifications as $row) { if (!$ftp) { $this->ui()->output($config->magento_root . DS . $row); } else { $this->ui()->output($row); } } } } if ($ftp) { $cwd = $ftpObj->getcwd(); $dir = $cwd . DIRECTORY_SEPARATOR . $config->downloader_path . DIRECTORY_SEPARATOR . Mage_Connect_Config::DEFAULT_CACHE_PATH . DIRECTORY_SEPARATOR . trim($pChan, "\\/"); $ftpObj->mkdirRecursive($dir, 0777); $ftpObj->chdir($cwd); } else { $dir = $config->getChannelCacheDir($pChan); @mkdir($dir, 0777, true); } $dir = $config->getChannelCacheDir($pChan); $packageFileName = $pName . "-" . $pVer . ".tgz"; $file = $dir . DIRECTORY_SEPARATOR . $packageFileName; if (!@file_exists($file)) { $this->ui()->output("Starting to download {$packageFileName} ..."); $rest->downloadPackageFileOfRelease($pName, $pVer, $file); $this->ui()->output(sprintf("...done: %s bytes", number_format(filesize($file)))); } /** * Remove old version package before install new */ if ($cache->hasPackage($pChan, $pName)) { if ($ftp) { $packager->processUninstallPackageFtp($pChan, $pName, $cache, $ftpObj); } else { $packager->processUninstallPackage($pChan, $pName, $cache, $config); } $cache->deletePackage($pChan, $pName); } $package = new Mage_Connect_Package($file); if ($clearInstallMode && $pInstallState != 'upgrade' && !$installAll) { $contents = $package->getContents(); $this->backup()->setFileTypes(array('csv', 'html')); $typesToBackup = $this->backup()->getFileTypes(); $this->validator()->validateContents($contents, $config, $typesToBackup); $errors = $this->validator()->getErrors(); if (count($errors)) { throw new Exception("Package '{$pName}' is invalid\n" . implode("\n", $errors)); } $targetPath = rtrim($config->magento_root, "\\/"); foreach ($contents as $filePath) { $this->backup()->addFile($filePath, $targetPath); } if ($this->backup()->getFilesCount() > 0) { $this->ui()->output('<br/>'); $this->ui()->output('Backup of following files will be created :'); $this->ui()->output('<br/>'); $this->backup()->run(); $this->ui()->output(implode('<br/>', $this->backup()->getAllFiles())); $this->ui()->output('<br/>'); $this->ui()->output($this->backup()->getFilesCount() . ' files was overwritten by installed extension.'); $this->ui()->output('<br/>'); $this->backup()->unsetAllFiles(); } } $conflicts = $package->checkPhpDependencies(); if (true !== $conflicts) { $conflicts = implode(",", $conflicts); $err = "Package {$pChan}/{$pName} {$pVer} depends on PHP extensions: " . $conflicts; if ($forceMode) { $this->doError($command, $err); } else { throw new Exception($err); } } $conflicts = $package->checkPhpVersion(); if (true !== $conflicts) { $err = "Package {$pChan}/{$pName} {$pVer}: " . $conflicts; if ($forceMode) { $this->doError($command, $err); } else { throw new Exception($err); } } if (!$noFilesInstall) { $this->ui()->output("Installing package {$pChan}/{$pName} {$pVer}"); if ($ftp) { $packager->processInstallPackageFtp($package, $file, $config, $ftpObj); } else { $packager->processInstallPackage($package, $file, $config); } $this->ui()->output("Package {$pChan}/{$pName} {$pVer} installed successfully"); } $cache->addPackage($package); $installedDepsAssoc[] = array('channel' => $pChan, 'name' => $pName, 'version' => $pVer); $installedDeps[] = array($pChan, $pName, $pVer); } catch (Exception $e) { $this->doError($command, $e->getMessage()); } } $title = isset($options['title']) ? $options['title'] : "Package installed: "; $out = array($command => array('data' => $installedDeps, 'assoc' => $installedDepsAssoc, 'title' => $title)); if ($ftp) { $packager->writeToRemoteCache($cache, $ftpObj); @unlink($config->getFilename()); } $this->ui()->output($out); return $out[$command]['data']; } catch (Exception $e) { if ($ftp) { $packager->writeToRemoteCache($cache, $ftpObj); @unlink($config->getFilename()); } return $this->doError($command, $e->getMessage()); } }
/** * Package installation to FS * @param Mage_Connect_Package $package * @param string $file * @return void * @throws Exception */ public function processInstallPackage($package, $file, $configObj) { $contents = $package->getContents(); $arc = $this->getArchiver(); $target = dirname($file) . DS . $package->getReleaseFilename(); @mkdir($target, 0777, true); $mode = $configObj->global_dir_mode; $tar = $arc->unpack($file, $target); $modeFile = $configObj->global_file_mode; $modeDir = $configObj->global_dir_mode; foreach ($contents as $file) { $fileName = basename($file); $filePath = dirname($file); $source = $tar . DS . $file; $targetPath = rtrim($configObj->magento_root, "\\/"); @mkdir($targetPath . DS . $filePath, $modeDir, true); $dest = $targetPath . DS . $filePath . DS . $fileName; if (is_file($source)) { @copy($source, $dest); if ($modeFile) { @chmod($dest, $modeFile); } } else { @mkdir($dest, $modeDir); } } Mage_System_Dirs::rm(array("-r", $target)); }
/** * Package installation to FS * @param Mage_Connect_Package $package * @param string $file * @return void * @throws Exception */ public function processInstallPackage($package, $file, $configObj) { $contents = $package->getContents(); $arc = $this->getArchiver(); $target = dirname($file) . DS . $package->getReleaseFilename(); @mkdir($target, 0777, true); $tar = $arc->unpack($file, $target); $modeFile = $this->_getFileMode($configObj); $modeDir = $this->_getDirMode($configObj); foreach ($contents as $file) { $fileName = basename($file); $filePath = dirname($file); $source = $tar . DS . $file; $targetPath = rtrim($configObj->magento_root, "\\/"); @mkdir($targetPath . DS . $filePath, $modeDir, true); $dest = $targetPath . DS . $filePath . DS . $fileName; if (is_file($source)) { @copy($source, $dest); if ($modeFile) { @chmod($dest, $modeFile); } } else { @mkdir($dest, $modeDir); } } $packageXml = $tar . Mage_Connect_Package_Reader::DEFAULT_NAME_PACKAGE; if (is_file($packageXml)) { $destDir = $targetPath . DS . Mage_Connect_Package::PACKAGE_XML_DIR; $destFile = $package->getReleaseFilename() . '.xml'; $dest = $destDir . DS . $destFile; @copy($packageXml, $dest); @chmod($dest, $modeFile); } Mage_System_Dirs::rm(array("-r", $target)); }
<?php /** * Generate modman file from Magento Connect 2.0 package.xml * * Usage: * * php package2modman.php path/to/package.xml > path/to/modman * */ require_once __DIR__ . "/../www/app/Mage.php"; $package = new Mage_Connect_Package($argv[1]); $modmanDefinition = array(); foreach ($package->getContents() as $path) { $path = preg_replace('{^\\./}', '', $path); $path = preg_replace('{^app/code/(.*?)/(.*?)/(.*?)/(.*)$}', 'app/code/$1/$2/$3', $path); $path = preg_replace('{^lib/(.*?)/(.*)$}', 'lib/$1', $path); $path = preg_replace('{^js/(.*?)/(.*?)/(.*)$}', 'js/$1', $path); $path = preg_replace('{^app/design/(.*?)/(.*?)/default/layout/(.*?)/(.*)$}', 'app/design/$1/$2/default/layout/$3', $path); $path = preg_replace('{^app/design/(.*?)/(.*?)/default/template/(.*?)/(.*)$}', 'app/design/$1/$2/default/template/$3', $path); $path = preg_replace('{^skin/(.*?)/(.*?)/default/(.*?)/(.*?)/(.*)$}', 'skin/$1/$2/default/$3/$4', $path); $modmanDefinition[$path] = $path; } foreach ($modmanDefinition as $source => $target) { printf("%s %s\n", $source, $target); }