[ Index ]

PHP Cross Reference of PHK Manager

title

Body

[close]

/PHK/Virtual/ -> File.php (source)

   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\Virtual {
  27  
  28  if (!class_exists('PHK\Virtual\File',false))
  29  {
  30  //=============================================================================
  31  /**
  32  * A virtual file
  33  *
  34  * API status: Private
  35  * Included in the PHK PHP runtime: Yes
  36  * Implemented in the extension: No
  37  *///==========================================================================
  38  
  39  class File extends Node // Regular file
  40  {
  41  
  42  private $dc;    // Data container
  43  
  44  //---
  45  
  46  public function type() { return 'file'; }
  47  public function mode() { return 0100444; }
  48  
  49  //---
  50  // If a method is unknown, forward to the DC (poor man's multiple inheritance :)
  51  
  52  public function __call($method,$args)
  53  {
  54  try { return call_user_func_array(array($this->dc,$method),$args); }
  55  catch (\Exception $e)
  56      { throw new \Exception($this->path.': '.$e->getMessage()); }
  57  }
  58  
  59  //---
  60  // Must be defined as __call() is tried after \PHK\Virtual\Node methods, and read()
  61  // has a default in \PHK\Virtual\Node.
  62  
  63  public function read()
  64  {
  65  return $this->dc->read();
  66  }
  67  
  68  //---
  69  
  70  public function flagString()
  71  {
  72  $string=parent::flagString().','.$this->dc->flagString();
  73  $string=trim($string,',');
  74  
  75  return $string;
  76  }
  77  
  78  //---
  79  
  80  public function displayPackage($html)
  81  {
  82  if ($this->flags & self::TN_PKG) $this->display($html);
  83  }
  84  
  85  //---
  86  // In HTML, create an hyperlink only for files, not for sections
  87  
  88  public function display($html,$link=false)
  89  {
  90  $flagString=$this->flagString();
  91  $path=$this->path;
  92  
  93  if ($html)
  94      {
  95      if ($this->flags & self::TN_PKG) $link=false;
  96      $field= ($link ? '<a href="'.\PHK::subpathURL('/view/'
  97          .trim($path,'/')).'">'.$path.'</a>' : $path);
  98      echo '<tr><td nowrap>F</td><td nowrap>'.$field.'</td><td nowrap>'
  99          .$this->size().'</td><td nowrap>'.$flagString.'</td></tr>';
 100      }
 101  else
 102      {
 103      if ($flagString!='') $flagString = ' ('.$flagString.')';
 104      echo 'F '.str_pad($this->size(),11).' '.$path.$flagString."\n";
 105      }
 106  }
 107  
 108  //---
 109  
 110  public function dump($base)
 111  {
 112  $path=$base.$this->path;
 113  if (file_put_contents($path,$this->read())===false)
 114      throw new \Exception($path.': cannot dump file');
 115  }
 116  
 117  //---
 118  
 119  public function __construct($path,$tree)
 120  {
 121  parent::__construct($path,$tree);
 122  
 123  $this->dc=new DC();
 124  $this->dc->setFspace($tree->fspace);
 125  }
 126  
 127  //---
 128  
 129  public function import($edata)
 130  {
 131  $this->dc->import(parent::import($edata));
 132  }
 133  
 134  //---
 135  
 136  public function setFlags($flags)
 137  {
 138  parent::setFlags($flags);
 139  $this->dc->setFlags($flags);
 140  }
 141  
 142  //---
 143  // <CREATOR> //---------------
 144  
 145  // If PHK Package, move required extensions up
 146  // Don't umount the package, it will be used later.
 147  
 148  public function getNeededExtensions(\PHK\Build\Creator $phk
 149      ,\PHK\Tools\ItemLister $item_lister)
 150  {
 151  if (\PHK::dataIsPackage($this->read()))
 152      {
 153      $mnt=require($phk->uri($this->path));
 154      $source_phk=\PHK\Mgr::instance($mnt);
 155      if (!is_null($elist=$source_phk->option('required_extensions')))
 156          {
 157          foreach ($elist as $ext) $item_lister->add($ext,true);
 158          }
 159      
 160      }
 161  
 162  return $this->dc->getNeededExtensions($phk,$item_lister);    // Now, ask DC
 163  }
 164  
 165  //---------------
 166  // Process PHP scripts (Automap and source stripping)
 167  // Register Automap symbols only if $map is non-null
 168  // Distinction between files and sections: for files, $map is not null
 169  
 170  public function export(\PHK\Build\Creator $phk,\PHK\Build\DataStacker $stacker,$map)
 171  {
 172  $path=$this->path;
 173  $rpath=substr($path,1); // Remove leading '/';
 174  
 175  \PHK\Tools\Util::trace('Processing '.$path);
 176  
 177  if (!is_null($map)) // This is a real file
 178      {
 179      if (getenv('PHK_NO_STRIP')!==false)    $this->flags &= ~self::TN_STRIP_SOURCE;
 180  
 181      if (\PHK::dataIsPackage($this->read()))    //-- Package ?
 182          {
 183          //-- Set 'package' flag, clear 'strip source', and keep autoload
 184          $this->flags |= self::TN_PKG;
 185          $this->flags &= ~self::TN_STRIP_SOURCE;
 186          }
 187  
 188      //-- If it is a sub-package and autoload is true, merge its symbols
 189      //-- in the current map, but with different values.
 190  
 191      if ($this->flags & self::TN_PKG)
 192          {
 193          if (!($this->flags & self::TN_NO_AUTOLOAD))
 194              {
 195              \PHK\Tools\Util::trace("Registering Automap symbols from PHK package");
 196              $map->registerPhkPkg($phk->uri($path),$rpath);
 197              }
 198          }
 199      elseif ($phk->isPHPSourcePath($path))
 200          {
 201          //--- Register in automap
 202          if (!($this->flags & self::TN_NO_AUTOLOAD))
 203              {
 204              \PHK\Tools\Util::trace("    Registering Automap symbols");
 205              $map->registerScriptFile($phk->uri($path),$rpath);
 206              }
 207  
 208          $this->processPHPScript();    //--- Script pre-processor
 209          }
 210      else
 211          {
 212          $this->flags = ($this->flags & ~self::TN_STRIP_SOURCE) 
 213              | self::TN_NO_AUTOLOAD;
 214          }
 215      }
 216  
 217  return $this->nodeExport($this->dc->export($phk,$stacker));
 218  }
 219  
 220  //---------------
 221  // Called only for PHP scripts. Replaces current data buffer
 222  
 223  const ST_OUT=0;
 224  const ST_ADD=1;
 225  const ST_IGNORE=2;
 226  
 227  private function processPHPScript()
 228  {
 229  $buf=$this->read();
 230  
 231  //--- Normalize line breaks (Unix-style)
 232  
 233  $buf=preg_replace("/\r+\n/","\n",$buf);
 234  $buf=str_replace("\r","\n",$buf);
 235  
 236  //--- Process '// <PHK:' directives
 237  
 238  $rbuf=$buf;
 239  $buf='';
 240  $lnum=0;
 241  $state=self::ST_OUT;
 242  $regs=null;
 243  foreach(explode("\n",$rbuf) as $line)
 244      {
 245      $lnum++;
 246      if (preg_match(',^\s*//\s*<PHK:(\S+)>,',$line,$regs))
 247          {
 248          $keyword=strtolower($regs[1]);
 249          switch ($keyword)
 250              {
 251              case 'end':
 252                  $state=self::ST_OUT;
 253                  break;
 254              case 'ignore':
 255                  $state=self::ST_IGNORE;
 256                  break;
 257              case 'add':
 258                  $state=self::ST_ADD;
 259                  break;
 260              default:
 261                  throw new \Exception($this->path."($lnum): Unknown preprocessor keyword: $keyword - valid keywords are ignore, add, end - ignoring line");
 262              }
 263          continue;
 264          }
 265      if ($state==self::ST_IGNORE) continue;
 266      if ($state==self::ST_ADD)
 267          {
 268          $line=ltrim($line);
 269          if (strlen($line)!=0) // Ignore empty lines
 270              {
 271              if ((strlen($line)>=2)&&(substr($line,0,2)==='//'))
 272                  $line=substr($line,2);
 273              else throw new \Exception($this->path."($lnum): in an 'add' block, line should start with '//' - copying line as-is");
 274              }
 275          }
 276      $buf .= $line."\n";
 277      }
 278  $buf=substr($buf,0,-1);
 279  
 280  //--- Strip
 281  
 282  if ($this->flags & self::TN_STRIP_SOURCE)
 283      {
 284      // \PHK\Tools\Util::msg("    Stripping script");
 285      $buf=self::stripWhitespaces($buf);
 286      }
 287  
 288  $this->setData($buf);
 289  }
 290  
 291  //---------------
 292  
 293  /**
 294  * Removes whitespace from a PHP source string while preserving line numbers.
 295  *
 296  * Taken from composer
 297  *
 298  * @param  string $source A PHP string
 299  * @return string The PHP string with the whitespace removed
 300  */
 301  
 302  public static function stripWhitespaces($source)
 303  {
 304  $output = '';
 305  
 306  foreach (token_get_all($source) as $token)
 307      {
 308      if (is_string($token))
 309          {
 310          $output .= $token;
 311          }
 312      elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT)))
 313          {
 314          $output .= str_repeat("\n", substr_count($token[1], "\n"));
 315          }
 316      elseif (T_WHITESPACE === $token[0])
 317          {
 318          // reduce wide spaces
 319          $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
 320          // normalize newlines to \n
 321          $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
 322          // trim leading spaces
 323          $whitespace = preg_replace('{\n +}', "\n", $whitespace);
 324          $output .= $whitespace;
 325          }
 326      else
 327          {
 328          $output .= $token[1];
 329          }
 330      }
 331  
 332  return $output;
 333  }
 334  
 335  // </CREATOR> //---------------
 336  
 337  //---
 338  } // End of class
 339  //===========================================================================
 340  } // End of class_exists
 341  //===========================================================================
 342  } // End of namespace
 343  //===========================================================================
 344  ?>


Generated: Thu Jun 4 18:33:15 2015 Cross-referenced by PHPXref 0.7.1