[ Index ] |
PHP Cross Reference of PHK Manager |
[Summary view] [Print] [Text view]
1 <?php 2 //============================================================================= 3 // 4 // Copyright Francois Laupretre <phk@tekwire.net> 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 // 18 //============================================================================= 19 /** 20 * @copyright Francois Laupretre <phk@tekwire.net> 21 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, V 2.0 22 * @category PHK 23 * @package PHK 24 *///========================================================================== 25 26 namespace PHK\Build { 27 28 if (!class_exists('PHK\Build\Creator',false)) 29 { 30 //============================================================================ 31 /** 32 * The package creator class 33 * 34 * Note: If this file is part of a PHK package (usual case), it is 35 * absolutely mandatory that Automap and PHK classes as package's files 36 * are the same as the Automap and PHK classes included in the prolog. Which 37 * means that the package must be generated from its files. If it is not the 38 * case, packages generated from this creator package will display wrong version 39 * information. 40 * 41 * API status: Public 42 * Included in the PHK PHP runtime: No 43 * Implemented in the extension: No 44 *///========================================================================== 45 46 class Creator extends \PHK\Base 47 { 48 const MIN_RUNTIME_VERSION='3.0.0'; // The minimum version of PHK runtime able to 49 // understand the packages I produce. Checked against PHK\Base::RUNTIME_VERSION 50 // or, if PECL, PHP_PHK_VERSION. 51 52 //----- 53 54 public $prolog=null; 55 public $code=null; 56 private $interp=''; 57 58 //----- 59 // init a new empty package. 60 61 public function __construct($mnt,$path,$flags) 62 { 63 parent::__construct(null,$mnt,$path,$flags,time()); 64 65 $this->options=array(); 66 $this->buildInfo=array('build_timestamp' => time()); 67 } 68 69 //--------- 70 71 public function ftree() 72 { 73 return $this->proxy()->ftree(); 74 } 75 76 //--------- 77 78 public function setOptions($opt) 79 { 80 $this->options=$opt; 81 } 82 83 //--------- 84 85 public function updateOption($name,$a) 86 { 87 $this->options[$name]=$a; 88 } 89 90 //--------- 91 92 public function updateBuildInfo($name,$a) 93 { 94 $this->buildInfo[$name]=$a; 95 } 96 97 //--------- 98 // Allows to use an alternate prolog 99 100 public function setProlog($data) 101 { 102 $this->prolog=$data; 103 } 104 105 //--------- 106 107 private function processPhpCode(&$buffer) 108 { 109 $buffer=str_replace('?><?php','',$buffer); 110 $buffer=str_replace("?>\n<?php",'',$buffer); 111 112 foreach (array('creator','plain_file') as $pcode) 113 { 114 if (!$this->option("prolog_code_$pcode")) 115 { 116 $token=strtoupper($pcode); 117 while (($pos=strpos($buffer,'<'.$token.'>'))!==false) 118 { 119 if (($pos2=strpos($buffer,'</'.$token.'>',$pos))===false) 120 throw new \Exception('Cannot find end of <'.$token.'> section'); 121 $buffer=substr_replace($buffer,'',$pos,$pos2-$pos+15); 122 } 123 } 124 } 125 126 // Strip whitespaces from the prolog 127 128 if (!$this->option('plain_prolog')) 129 { 130 $buffer=\PHK\Virtual\File::stripWhitespaces($buffer); 131 } 132 } 133 134 //--------- 135 // Build runtime PHP code 136 //-- $dir= base dir where files are stored. In a package, it is the package's 137 //-- base URI, otherwise, it is the base of the source tree. 138 139 public function buildPhpCode($dir) 140 { 141 \Phool\Display::trace('Building PHP runtime'); 142 143 $this->code=''; 144 145 $automap_base=$dir; 146 if (! \PHK\Mgr::isPhkUri(__FILE__)) $automap_base .= '/external/automap'; 147 $this->code .= \PHK\Tools\Util::readFile($automap_base.'/src/Automap/Mgr.php'); 148 $this->code .= \PHK\Tools\Util::readFile($automap_base.'/src/Automap/Tools/Display.php'); 149 $this->code .= \PHK\Tools\Util::readFile($automap_base.'/src/Automap/Map.php'); 150 $this->code .= \PHK\Tools\Util::readFile($automap_base.'/src/Automap/Tools/Check.php'); 151 152 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Tools/Util.php'); 153 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/PkgFile.php'); 154 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Cache.php'); 155 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Proxy.php'); 156 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Mgr.php'); 157 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Base.php'); 158 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK.php'); 159 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Backend.php'); 160 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Stream/Wrapper.php'); 161 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Stream/Backend.php'); 162 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Virtual/DC.php'); 163 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Virtual/Tree.php'); 164 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Virtual/Node.php'); 165 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Virtual/Dir.php'); 166 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Virtual/File.php'); 167 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/Web/Info.php'); 168 $this->code .= \PHK\Tools\Util::readFile($dir.'/src/PHK/UnitTest/PHPUnit.php'); 169 170 $this->processPhpCode($this->code); 171 172 $this->code=str_replace('<?php','',$this->code); 173 $this->code=str_replace('?>','',$this->code); 174 } 175 176 //--------- 177 //-- Build prolog code 178 //-- $dir= base dir where files are stored 179 180 public function buildProlog($dir) 181 { 182 \Phool\Display::trace('Building prolog'); 183 184 $this->prolog = \PHK\Tools\Util::readFile($dir.'/scripts/prolog.php'); 185 186 //-- The four FF chars turn unicode detection off (see PHP bug #42396) 187 188 $this->prolog .= '<?php __halt_compiler(); ?>'.str_repeat(chr(255),4); 189 190 $this->processPhpCode($this->prolog); 191 } 192 193 //--------- 194 // Create a new section and fill it with some data 195 196 public function addSection($name,$data,$modifiers=array()) 197 { 198 \Phool\Display::trace("Adding section <$name>"); 199 200 $this->proxy()->stree()->mkfile($name,$data,$modifiers); 201 } 202 203 //--------- 204 205 public function dump($path=null) 206 { 207 if (is_null($path)) $path=$this->path(); 208 \Phool\Display::trace("Writing package to disk ($path)"); 209 210 $base_dir=dirname(dirname(dirname(__DIR__))); 211 $this->buildPhpCode($base_dir); 212 213 //-- Get creator version 214 215 if (\PHK\Mgr::isPhkUri(__FILE__)) 216 { 217 $pkg=\PHK\Mgr::instance(\PHK\Mgr::uriToMnt(__FILE__)); 218 $creatorVersion=$pkg->option('version'); 219 } 220 else 221 { 222 $creatorVersion=getenv('SOFTWARE_VERSION'); 223 } 224 if (!is_string($creatorVersion)) 225 throw new \Exception('Cannot determine creator version'); 226 227 //-- Build prolog if not already set 228 229 if (is_null($this->prolog)) $this->buildProlog($base_dir); 230 231 //-- Build FILES part and FTREE section 232 // Build map, strip sources, etc... 233 234 $needed_extensions=new \PHK\Tools\ItemLister; 235 $this->proxy()->ftree()->walk('getNeededExtensions',$this,$needed_extensions); 236 237 $map=new \Automap\Build\Creator(); 238 list($files_structure,$files_data)=$this->proxy()->ftree()->export($this,$map); 239 240 $this->addSection('FTREE',$files_structure); 241 unset($files_structure); 242 243 //-- Build Automap section 244 245 if ($map->symbolCount()) 246 $this->addSection(\PHK\Proxy::AUTOMAP_SECTION,$map->serialize()); 247 248 $this->updateBuildInfo('map_defined',($map->symbolCount()!=0)); 249 250 //-- Tabs sections / PHK icon 251 252 foreach(array('tabs/left.gif','tabs/right.gif','tabs/bottom.gif' 253 ,'tabs/tabs.css.php','phk_logo.png') as $f) 254 { 255 $source=$base_dir.'/etc/'.$f; 256 $this->addSection('STATIC/'.$f,\PHK\Tools\Util::readFile($source)); 257 } 258 259 //-- Build info 260 261 $this->updateBuildInfo('phk_creator_version',$creatorVersion); 262 $this->updateBuildInfo('automap_creator_version',\Automap\Build\Creator::VERSION); 263 $this->updateBuildInfo('automap_minVersion',\Automap\Build\Creator::MIN_RUNTIME_VERSION); 264 265 //-- Record the user-specified needed extensions 266 267 foreach(\PHK\Tools\Util::mkArray($this->option('required_extensions')) as $ext) 268 { 269 if ($ext!=='') $needed_extensions->add($ext,true); 270 } 271 272 //-- Flush sections 273 //-- Add the uncompress needed extensions to the user required extensions 274 275 $this->proxy()->stree()->walk('getNeededExtensions',$this,$needed_extensions); 276 277 $ext=array_keys($needed_extensions->get()); 278 if (count($ext)) $this->updateOption('required_extensions',$ext); 279 280 //-- Ensure mime_types, if present, is an array 281 282 if (!is_null($this->option('mime_types'))) 283 $this->updateOption('mime_types' 284 ,\PHK\Tools\Util::mkArray($this->option('mime_types'))); 285 286 $this->addSection('OPTIONS',serialize($this->options())); 287 288 // Add build info section 289 290 $this->addSection('BUILD_INFO',serialize($this->buildInfo())); 291 292 // Now, dump the section tree 293 294 \PHK\Tools\Util::trace('--- Sections'); 295 296 list($sections_structure,$sections_data)=$this->proxy()->stree()->export($this); 297 298 //--- 299 300 $prolog_offset=\PHK\Proxy::INTERP_LEN+\PHK\Proxy::MAGIC_LINE_LEN; 301 $code_offset=$prolog_offset+strlen($this->prolog); 302 $sections_structure_offset=$code_offset+strlen($this->code); 303 $sections_offset=$sections_structure_offset+strlen($sections_structure); 304 $files_offset=$sections_offset+strlen($sections_data); 305 $sig_offset=$files_offset+strlen($files_data); 306 $file_size=$sig_offset; 307 308 $buf=\PHK\Proxy::fixCrc(\PHK\Proxy::interpBlock($this->interp) 309 .'<?php '.\PHK\Proxy::MAGIC_STRING 310 .' M' .str_pad(self::MIN_RUNTIME_VERSION,\PHK\Proxy::VERSION_SIZE) 311 .' V' .str_pad($creatorVersion,\PHK\Proxy::VERSION_SIZE) 312 .' FS' .str_pad($file_size,\PHK\Proxy::OFFSET_SIZE) 313 .' PO' .str_pad($prolog_offset,\PHK\Proxy::OFFSET_SIZE) 314 .' SSO'.str_pad($sections_structure_offset,\PHK\Proxy::OFFSET_SIZE) 315 .' STO'.str_pad($sections_offset,\PHK\Proxy::OFFSET_SIZE) 316 .' FTO'.str_pad($files_offset,\PHK\Proxy::OFFSET_SIZE) 317 .' SIO'.str_pad($sig_offset,\PHK\Proxy::OFFSET_SIZE) 318 .' CRC00000000' 319 .' PCO'.str_pad($code_offset,\PHK\Proxy::OFFSET_SIZE) 320 .' PCS'.str_pad(strlen($this->code),\PHK\Proxy::OFFSET_SIZE) 321 .' ?>' 322 .$this->prolog.$this->code.$sections_structure.$sections_data.$files_data); 323 324 \PHK\Tools\Util::trace('Writing PHK file to '.$path); 325 \PHK\Tools\Util::atomicWrite($path,$buf); 326 } 327 328 //--- 329 } // End of class 330 //=========================================================================== 331 } // End of class_exists 332 //=========================================================================== 333 } // End of namespace 334 //=========================================================================== 335 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jun 4 18:33:15 2015 | Cross-referenced by PHPXref 0.7.1 |