00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 require_once 'Varien/Pear/Package.php';
00028
00029 class Mage_Adminhtml_Model_Extension extends Varien_Object
00030 {
00031 protected $_roles;
00032
00033 public function getPear()
00034 {
00035 return Varien_Pear::getInstance();
00036 }
00037
00038 public function generatePackageXml()
00039 {
00040 Mage::getSingleton('adminhtml/session')
00041 ->setLocalExtensionPackageFormData($this->getData());
00042
00043 Varien_Pear::$reloadOnRegistryUpdate = false;
00044 $pkg = new Varien_Pear_Package;
00045 #$pkg->getPear()->runHtmlConsole(array('command'=>'list-channels'));
00046 $pfm = $pkg->getPfm();
00047 $pfm->setOptions(array(
00048 'packagedirectory'=>'.',
00049 'baseinstalldir'=>'.',
00050 'simpleoutput'=>true,
00051 ));
00052
00053 $this->_setPackage($pfm);
00054 $this->_setRelease($pfm);
00055 $this->_setMaintainers($pfm);
00056 $this->_setDependencies($pfm);
00057 $this->_setContents($pfm);
00058 #echo "<pre>".print_r($pfm,1)."</pre>";
00059 if (!$pfm->validate(PEAR_VALIDATE_NORMAL)) {
00060
00061
00062
00063 $message = $pfm->getValidationWarnings();
00064
00065 throw Mage::exception('Mage_Adminhtml', Mage::helper('adminhtml')->__($message[0]['message']));
00066
00067 return $this;
00068 }
00069
00070 $this->setPackageXml($pfm->getDefaultGenerator()->toXml(PEAR_VALIDATE_NORMAL));
00071 return $this;
00072 }
00073
00074 protected function _setPackage($pfm)
00075 {
00076 $pfm->setPackageType('php');
00077 $pfm->setChannel($this->getData('channel'));
00078
00079 $pfm->setLicense($this->getData('license'), $this->getData('license_uri'));
00080
00081 $pfm->setPackage($this->getData('name'));
00082 $pfm->setSummary($this->getData('summary'));
00083 $pfm->setDescription($this->getData('description'));
00084 }
00085
00086 protected function _setRelease($pfm)
00087 {
00088 $pfm->addRelease();
00089 $pfm->setDate(date('Y-m-d'));
00090
00091 $pfm->setAPIVersion($this->getData('api_version'));
00092 $pfm->setReleaseVersion($this->getData('release_version'));
00093 $pfm->setAPIStability($this->getData('api_stability'));
00094 $pfm->setReleaseStability($this->getData('release_stability'));
00095 $pfm->setNotes($this->getData('notes'));
00096 }
00097
00098 protected function _setMaintainers($pfm)
00099 {
00100 $maintainers = $this->getData('maintainers');
00101 foreach ($maintainers['role'] as $i=>$role) {
00102 if (0===$i) {
00103 continue;
00104 }
00105 $handle = $maintainers['handle'][$i];
00106 $name = $maintainers['name'][$i];
00107 $email = $maintainers['email'][$i];
00108 $active = !empty($maintainers['active'][$i]) ? 'yes' : 'no';
00109 $pfm->addMaintainer($role, $handle, $name, $email, $active);
00110 }
00111 }
00112
00113 protected function _setDependencies($pfm)
00114 {
00115 $pfm->clearDeps();
00116 $exclude = $this->getData('depends_php_exclude')!=='' ? explode(',', $this->getData('depends_php_exclude')) : false;
00117 $pfm->setPhpDep($this->getData('depends_php_min'), $this->getData('depends_php_max'), $exclude);
00118 $pfm->setPearinstallerDep('1.6.2');
00119
00120 foreach ($this->getData('depends') as $deptype=>$deps) {
00121 foreach ($deps['type'] as $i=>$type) {
00122 if (0===$i) {
00123 continue;
00124 }
00125 $name = $deps['name'][$i];
00126 $min = !empty($deps['min'][$i]) ? $deps['min'][$i] : false;
00127 $max = !empty($deps['max'][$i]) ? $deps['max'][$i] : false;
00128 $recommended = !empty($deps['recommended'][$i]) ? $deps['recommended'][$i] : false;
00129 $exclude = !empty($deps['exclude'][$i]) ? explode(',', $deps['exclude'][$i]) : false;
00130 if ($deptype!=='extension') {
00131 $channel = !empty($deps['channel'][$i]) ? $deps['channel'][$i] : 'connect.magentocommerce.com/core';
00132 }
00133 switch ($deptype) {
00134 case 'package':
00135 if ($type==='conflicts') {
00136 $pfm->addConflictingPackageDepWithChannel(
00137 $name, $channel, false, $min, $max, $recommended, $exclude);
00138 } else {
00139 $pfm->addPackageDepWithChannel(
00140 $type, $name, $channel, $min, $max, $recommended, $exclude);
00141 }
00142 break;
00143
00144 case 'subpackage':
00145 if ($type==='conflicts') {
00146 Mage::throwException(Mage::helper('adminhtml')->__("Subpackage can't be conflicting"));
00147 }
00148 $pfm->addSubpackageDepWithChannel(
00149 $type, $name, $channel, $min, $max, $recommended, $exclude);
00150 break;
00151
00152 case 'extension':
00153 $pfm->addExtensionDep(
00154 $type, $name, $min, $max, $recommended, $exclude);
00155 break;
00156 }
00157 }
00158 }
00159 }
00160
00161 protected function _setContents($pfm)
00162 {
00163 $baseDir = $this->getRoleDir('mage').DS;
00164
00165 $pfm->clearContents();
00166 $contents = $this->getData('contents');
00167 $usesRoles = array();
00168 foreach ($contents['role'] as $i=>$role) {
00169 if (0===$i) {
00170 continue;
00171 }
00172
00173 $usesRoles[$role] = 1;
00174
00175 $roleDir = $this->getRoleDir($role).DS;
00176 $fullPath = $roleDir.$contents['path'][$i];
00177
00178 switch ($contents['type'][$i]) {
00179 case 'file':
00180 if (!is_file($fullPath)) {
00181 Mage::throwException(Mage::helper('adminhtml')->__("Invalid file: %s", $fullPath));
00182 }
00183 $pfm->addFile('/', $contents['path'][$i], array('role'=>$role, 'md5sum'=>md5_file($fullPath)));
00184 break;
00185
00186 case 'dir':
00187 if (!is_dir($fullPath)) {
00188 Mage::throwException(Mage::helper('adminhtml')->__("Invalid directory: %s", $fullPath));
00189 }
00190 $path = $contents['path'][$i];
00191 $include = $contents['include'][$i];
00192 $ignore = $contents['ignore'][$i];
00193 $this->_addDir($pfm, $role, $roleDir, $path, $include, $ignore);
00194 break;
00195 }
00196 }
00197
00198 $pearRoles = $this->getRoles();
00199 #echo "<pre>".print_r($usesRoles,1)."</pre>";
00200 foreach ($usesRoles as $role=>$dummy) {
00201 if (empty($pearRoles[$role]['package'])) {
00202 continue;
00203 }
00204 $pfm->addUsesrole($role, $pearRoles[$role]['package']);
00205 }
00206 }
00207
00208 protected function _addDir($pfm, $role, $roleDir, $path, $include, $ignore)
00209 {
00210 $roleDirLen = strlen($roleDir);
00211 $entries = @glob($roleDir.$path.DS."*");
00212 if (!empty($entries)) {
00213 foreach ($entries as $entry) {
00214 $filePath = substr($entry, $roleDirLen);
00215 if (!empty($include) && !preg_match($include, $filePath)) {
00216 continue;
00217 }
00218 if (!empty($ignore) && preg_match($ignore, $filePath)) {
00219 continue;
00220 }
00221 if (is_dir($entry)) {
00222 $baseName = basename($entry);
00223 if ('.'===$baseName || '..'===$baseName) {
00224 continue;
00225 }
00226 $this->_addDir($pfm, $role, $roleDir, $filePath, $include, $ignore);
00227 } elseif (is_file($entry)) {
00228 $pfm->addFile('/', $filePath, array('role'=>$role, 'md5sum'=>md5_file($entry)));
00229 }
00230 }
00231 }
00232 }
00233
00234 public function getRoles()
00235 {
00236 if (!$this->_roles) {
00237 $frontend = $this->getPear()->getFrontend();
00238 $config = $this->getPear()->getConfig();
00239 $pearMage = new PEAR_Command_Mage($frontend, $config);
00240 $this->_roles = $pearMage->getRoles();
00241 }
00242 return $this->_roles;
00243 }
00244
00245 public function getRoleDir($role)
00246 {
00247 $roles = $this->getRoles();
00248 return Varien_Pear::getInstance()->getConfig()->get($roles[$role]['dir_config']);
00249 }
00250
00251 public function getMaintainerRoles()
00252 {
00253 return array(
00254 'lead'=>'Lead',
00255 'developer'=>'Developer',
00256 'contributor'=>'Contributor',
00257 'helper'=>'Helper'
00258 );
00259 }
00260
00261 public function savePackage()
00262 {
00263 if ($this->getData('file_name') != '') {
00264 $fileName = $this->getData('file_name');
00265 $this->unsetData('file_name');
00266 } else {
00267 $fileName = $this->getName();
00268 }
00269
00270 if (!preg_match('/^[a-z0-9]+[a-z0-9\-\_\.]*([\/\\\\]{1}[a-z0-9]+[a-z0-9\-\_\.]*)*$/i', $fileName)) {
00271 return false;
00272 }
00273
00274 if (!$this->getPackageXml()) {
00275 $this->generatePackageXml();
00276 }
00277 if (!$this->getPackageXml()) {
00278 return false;
00279 }
00280
00281 $pear = Varien_Pear::getInstance();
00282 $dir = Mage::getBaseDir('var').DS.'pear';
00283 if (!@file_put_contents($dir.DS.'package.xml', $this->getPackageXml())) {
00284 return false;
00285 }
00286
00287 $pkgver = $this->getName().'-'.$this->getReleaseVersion();
00288 $this->unsPackageXml();
00289 $this->unsRoles();
00290 $xml = Mage::helper('core')->assocToXml($this->getData());
00291 $xml = new Varien_Simplexml_Element($xml->asXML());
00292
00293
00294 $parts = explode(DS, $fileName);
00295 array_pop($parts);
00296 $newDir = implode(DS, $parts);
00297 if ((!empty($newDir)) && (!is_dir($dir . DS . $newDir))) {
00298 if (!@mkdir($dir . DS . $newDir, 0777, true)) {
00299 return false;
00300 }
00301 }
00302
00303 if (!@file_put_contents($dir . DS . $fileName . '.xml', $xml->asNiceXml())) {
00304 return false;
00305 }
00306
00307 return true;
00308 }
00309
00310 public function createPackage()
00311 {
00312 $pear = Varien_Pear::getInstance();
00313 $dir = Mage::getBaseDir('var').DS.'pear';
00314 if (!Mage::getConfig()->createDirIfNotExists($dir)) {
00315 return false;
00316 }
00317 $curDir = getcwd();
00318 chdir($dir);
00319 $result = $pear->run('mage-package', array(), array('package.xml'));
00320 chdir($curDir);
00321 if ($result instanceof PEAR_Error) {
00322 return $result;
00323 }
00324 return true;
00325 }
00326
00327
00328 public function getStabilityOptions()
00329 {
00330 return array(
00331 'devel'=>'Development',
00332 'alpha'=>'Alpha',
00333 'beta'=>'Beta',
00334 'stable'=>'Stable',
00335 );
00336 }
00337
00338 public function getKnownChannels()
00339 {
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 $arr = array(
00353 'connect.magentocommerce.com/core' => 'Magento Core Team',
00354 'connect.magentocommerce.com/community' => 'Magento Community',
00355 #'pear.php.net' => 'PEAR',
00356 #'pear.phpunit.de' => 'PHPUnit',
00357 );
00358 return $arr;
00359 }
00360
00361 public function loadLocal($package, $options=array())
00362 {
00363 $pear = $this->getPear();
00364
00365 $pear->getFrontend()->clear();
00366
00367 $result = $pear->run('info', $options, array($package));
00368 if ($result instanceof PEAR_Error) {
00369 Mage::throwException($result->message);
00370 break;
00371 }
00372
00373 $output = $pear->getOutput();
00374 $pkg = new PEAR_PackageFile_v2;
00375 $pkg->fromArray($output[0]['output']['raw']);
00376
00377 return $pkg;
00378 }
00379
00380 public function loadRemote($package, $options=array())
00381 {
00382 $pear = $this->getPear();
00383
00384 $pear->getFrontend()->clear();
00385
00386 $result = $pear->run('remote-info', $options, array($package));
00387 if ($result instanceof PEAR_Error) {
00388 Mage::throwException($result->message);
00389 break;
00390 }
00391
00392 $output = $pear->getOutput();
00393 $this->setData($output[0]['output']);
00394
00395 return $this;
00396 }
00397 }