Aggregate Code Coverage for all tests
1 : <?php 2 : /** 3 : * PEAR2_Pyrus_Registry_Xml 4 : * 5 : * PHP version 5 6 : * 7 : * @category PEAR2 8 : * @package PEAR2_Pyrus 9 : * @author Greg Beaver <cellog@php.net> 10 : * @copyright 2008 The PEAR Group 11 : * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 12 : * @version SVN: $Id$ 13 : * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ 14 : */ 15 : 16 : /** 17 : * This is the central registry, that is used for all installer options, 18 : * stored in xml files 19 : * 20 : * @category PEAR2 21 : * @package PEAR2_Pyrus 22 : * @author Greg Beaver <cellog@php.net> 23 : * @copyright 2008 The PEAR Group 24 : * @license http://www.opensource.org/licenses/bsd-license.php New BSD License 25 : * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ 26 : */ 27 1 : class PEAR2_Pyrus_Registry_Xml implements PEAR2_Pyrus_IRegistry 28 : { 29 : protected $readonly; 30 : private $_path; 31 : 32 : function __construct($path, $readonly = false) 33 : { 34 1 : $this->_path = $path; 35 1 : $this->readonly = $readonly; 36 1 : } 37 : 38 : private function _nameRegistryPath(PEAR2_Pyrus_PackageFile_v2 $info = null, 39 : $channel = null, $package = null, $version = null) 40 : { 41 : $channel = $info !== null ? $info->channel : $channel; 42 : $package = $info !== null ? $info->name : $package; 43 : $path = $this->_namePath($channel, $package); 44 : $version = $info !== null ? $info->version['release'] : $version; 45 : return $path . DIRECTORY_SEPARATOR . $version . '-package.xml'; 46 : } 47 : 48 : private function _namePath($channel, $package) 49 : { 50 : return PEAR2_Pyrus_Config::current()->path . DIRECTORY_SEPARATOR . 51 : '.registry' . DIRECTORY_SEPARATOR . 52 : str_replace('/', '!', $channel) . 53 : DIRECTORY_SEPARATOR . $package; 54 : } 55 : 56 : /** 57 : * Create the Channel!PackageName-Version-package.xml file 58 : * 59 : * @param PEAR2_Pyrus_PackageFile_v2 $pf 60 : */ 61 : function install(PEAR2_Pyrus_PackageFile_v2 $info) 62 : { 63 : if ($this->readonly) { 64 : throw new PEAR2_Pyrus_Registry_Exception('Cannot install package, registry is read-only'); 65 : } 66 : // remove previously installed version for upgrade 67 : $this->uninstall($info->name, $info->channel); 68 : $packagefile = $this->_nameRegistryPath($info); 69 : if (!@is_dir(dirname($packagefile))) { 70 : mkdir(dirname($packagefile), 0777, true); 71 : } 72 : file_put_contents($packagefile, (string) $info); 73 : } 74 : 75 : function uninstall($package, $channel) 76 : { 77 : if ($this->readonly) { 78 : throw new PEAR2_Pyrus_Registry_Exception('Cannot install package, registry is read-only'); 79 : } 80 : $packagefile = $this->_nameRegistryPath(null, $channel, $package); 81 : @unlink($packagefile); 82 : @rmdir(dirname($packagefile)); 83 : } 84 : 85 : public function exists($package, $channel) 86 : { 87 : $packagefile = $this->_namePath($package, $channel); 88 : return @file_exists($packagefile) && @is_dir($packagefile); 89 : } 90 : 91 : public function info($package, $channel, $field) 92 : { 93 : if (!$this->exists($package, $channel)) { 94 : throw new PEAR2_Pyrus_Registry_Exception('Unknown package ' . $channel . 95 : '/' . $package); 96 : } 97 : $packagefile = glob($this->_namePath($package, $channel) . 98 : DIRECTORY_SEPARATOR . '*.xml'); 99 : if (!$packagefile || !isset($packagefile[0])) { 100 : throw new PEAR2_Pyrus_Registry_Exception('Cannot find registry for package ' . 101 : $channel . '/' . $package); 102 : } 103 : // create packagefile v2 here 104 : if ($field === null) { 105 : return $pf; 106 : } 107 : 108 : if ($field == 'version') { 109 : $field = 'release-version'; 110 : } elseif ($field == 'installedfiles') { 111 : $ret = array(); 112 : try { 113 : $config = new PEAR2_Pyrus_Config_Snapshot($pf->date . ' ' . $pf->time); 114 : } catch (Exception $e) { 115 : throw new PEAR2_Pyrus_Registry_Exception('Cannot retrieve files, config ' . 116 : 'snapshot could not be processed', $e); 117 : } 118 : $roles = array(); 119 : foreach (PEAR2_Pyrus_Installer_Role::getValidRoles($info->getPackageType()) as $role) { 120 : // set up a list of file role => configuration variable 121 : // for storing in the registry 122 : $roles[$role] = 123 : PEAR2_Pyrus_Installer_Role::factory($info, $role)->getLocationConfig(); 124 : } 125 : $ret = array(); 126 : foreach ($pf->files as $path => $info) { 127 : $ret[] = $config->{$roles[$info['role']]} . DIRECTORY_SEPARATOR . $path; 128 : } 129 : return $ret; 130 : } elseif ($field == 'dirtree') { 131 : $files = $this->installedfiles; 132 : $ret = array(); 133 : foreach ($files as $file) { 134 : $ret[dirname($file)] = true; 135 : } 136 : return $ret; 137 : } 138 : 139 : return $pf->$field; 140 : } 141 : 142 : public function listPackages($channel) 143 : { 144 : $dir = $this->_namePath($channel, ''); 145 : if (!@file_exists($dir)) { 146 : return array(); 147 : } 148 : $ret = array(); 149 : try { 150 : $parser = new PEAR2_Pyrus_XMLParser; 151 : foreach (new DirectoryIterator($dir) as $file) { 152 : if ($file->isDot()) continue; 153 : try { 154 : $a = $parser->parse($file->getPathName()); 155 : $ret[] = $a['package']['name']; 156 : } catch (Exception $e) { 157 : PEAR2_Pyrus_Log::log(0, 'Warning: corrupted XML registry entry: ' . 158 : $file->getPathName() . ': ' . $e); 159 : } 160 : } 161 : } catch (Exception $e) { 162 : throw new PEAR2_Pyrus_Registry_Exception('Could not open channel directory for ' . 163 : 'channel ' . $channel, $e); 164 : } 165 : return $ret; 166 : } 167 : 168 : public function toPackageFile($package, $channel) 169 : { 170 : if (!$this->exists($package, $channel)) { 171 : throw new PEAR2_Pyrus_Registry_Exception('Cannot retrieve package file object ' . 172 : 'for package ' . $package . '/' . $channel . ', it is not installed'); 173 : } 174 : $packagefile = $this->_nameRegistryPath(null, $channel, $package); 175 : $x = new PEAR2_Pyrus_PackageFile($packagefile); 176 : return $x->info; 177 : } 178 : 179 : public function __get($var) 180 : { 181 : if ($var == 'package') { 182 : return new PEAR2_Pyrus_Registry_Xml_Package($this); 183 : } 184 : if ($var == 'channel') { 185 : return new PEAR2_Pyrus_Registry_Xml_Channel($this); 186 : } 187 : } 188 : 189 : /** 190 : * Don't even try - sqlite is the only one that can reliably implement this 191 : */ 192 : public function getDependentPackages(PEAR2_Pyrus_Registry_Base $package) 193 : { 194 : return array(); 195 : } 196 : }