[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/kernel/classes/ -> ezcodetemplate.php (source)

   1  <?php
   2  //
   3  // Definition of eZCodeTemplate class
   4  //
   5  // Created on: <18-Nov-2004 13:03:44 jb>
   6  //
   7  // SOFTWARE NAME: eZ publish
   8  // SOFTWARE RELEASE: 3.9.0
   9  // BUILD VERSION: 17785
  10  // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS
  11  // SOFTWARE LICENSE: GNU General Public License v2.0
  12  // NOTICE: >
  13  //   This program is free software; you can redistribute it and/or
  14  //   modify it under the terms of version 2.0  of the GNU General
  15  //   Public License as published by the Free Software Foundation.
  16  //
  17  //   This program is distributed in the hope that it will be useful,
  18  //   but WITHOUT ANY WARRANTY; without even the implied warranty of
  19  //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20  //   GNU General Public License for more details.
  21  //
  22  //   You should have received a copy of version 2.0 of the GNU General
  23  //   Public License along with this program; if not, write to the Free
  24  //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25  //   MA 02110-1301, USA.
  26  //
  27  //
  28  
  29  /*! \file ezcodetemplate.php
  30  */
  31  
  32  /*!
  33    \class eZCodeTemplate ezcodetemplate.php
  34    \brief Replaces or generates blocks of code according to a template file
  35  
  36  */
  37  
  38  /// There are errors in the template code
  39  define( 'EZ_CODE_TEMPLATE_STATUS_FAILED', 0 );
  40  /// Code files was succesfully updated
  41  define( 'EZ_CODE_TEMPLATE_STATUS_OK', 1 );
  42  /// Code file was updated, but no new elements has been added
  43  define( 'EZ_CODE_TEMPLATE_STATUS_NO_CHANGE', 2 );
  44  
  45  class eZCodeTemplate
  46  {
  47      /*!
  48       Constructor
  49      */
  50      function eZCodeTemplate()
  51      {
  52          $ini =& eZINI::instance( 'codetemplate.ini' );
  53          $this->Templates = array();
  54          $templates = $ini->variable( 'Files', 'Templates' );
  55          foreach ( $templates as $key => $template )
  56          {
  57              $this->Templates[$key] = array( 'filepath' => $template );
  58          }
  59      }
  60  
  61      /*!
  62        Applies template block in the file \a $filePath and writes back the new
  63        code to the same file.
  64  
  65        \return One of the EZ_CODE_TEMPLATE_STATUS_* status codes.
  66  
  67        \note It will create a backup file of the original
  68      */
  69      function apply( $filePath, $checkOnly = false )
  70      {
  71          if ( !file_exists( $filePath ) )
  72          {
  73              eZDebug::writeError( "File $filePath does not exists",
  74                                   'eZCodeTemplate::apply' );
  75              return EZ_CODE_TEMPLATE_STATUS_FAILED;
  76          }
  77  
  78          $text = file_get_contents( $filePath );
  79          $tempFile = dirname( $filePath ) . '/#' . basename( $filePath ) . '#';
  80          $fd = fopen( $tempFile, 'wb' );
  81          if ( !$fd )
  82          {
  83              eZDebug::writeError( "Failed to open temporary file $tempFile",
  84                                   'eZCodeTemplate::apply' );
  85              return EZ_CODE_TEMPLATE_STATUS_FAILED;
  86          }
  87  
  88          $createTag = 'code-template::create-block:';
  89          $createTagLen = strlen( $createTag );
  90  
  91          $error = false;
  92  
  93          $ok = true;
  94          $offset = 0;
  95          $len = strlen( $text );
  96          while ( $offset < $len )
  97          {
  98              $createPos = strpos( $text, $createTag, $offset );
  99              if ( $createPos !== false )
 100              {
 101                  $endPos = strpos( $text, "\n", $createPos + $createTagLen );
 102                  if ( $endPos === false )
 103                  {
 104                      $createText = substr( $text, $createPos + $createTagLen );
 105                      $end = $len;
 106                  }
 107                  else
 108                  {
 109                      $start = $createPos + $createTagLen;
 110                      $createText = substr( $text, $start, $endPos - $start );
 111                      $end =  $endPos + 1;
 112                  }
 113  
 114                  // Figure out how much the comments should be indented
 115                  // This just makes the code seem more natural
 116                  $indentText = '';
 117                  $subText = substr( $text, $offset, $createPos - $offset );
 118                  $startOfLine = strrpos( $subText, "\n" );
 119                  if ( $startOfLine !== false )
 120                  {
 121                      if ( preg_match( '#^([ \t]+)#', substr( $subText, $startOfLine + 1 ), $matches ) )
 122                      {
 123                          $indentText = $matches[1];
 124                      }
 125                  }
 126                  unset( $subText );
 127  
 128                  // Figure out template name and parameters
 129                  $createText = trim( $createText );
 130                  $elements = explode( ',', $createText );
 131                  if ( count( $elements ) < 1 )
 132                  {
 133                      eZDebug::writeError( "No template name found in file $filePath at offset $offset",
 134                                           'eZCodeTemplate::apply' );
 135                      $offset = $end;
 136                      $error = true;
 137                      continue;
 138                  }
 139  
 140                  $templateName = trim( $elements[0] );
 141  
 142                  $templateFile = $this->templateFile( $templateName );
 143                  if ( $templateFile === false )
 144                  {
 145                      eZDebug::writeError( "No template file for template $templateName used in file $filePath at offset $offset",
 146                                           'eZCodeTemplate::apply' );
 147                      $offset = $end;
 148                      $error = true;
 149                      continue;
 150                  }
 151  
 152                  if ( !file_exists( $templateFile ) )
 153                  {
 154                      eZDebug::writeError( "Template file $templateFile for template $templateName does not exist",
 155                                           'eZCodeTemplate::apply' );
 156                      $offset = $end;
 157                      $error = true;
 158                      continue;
 159                  }
 160  
 161                  $parameters = array_splice( $elements, 1 );
 162                  foreach ( $parameters as $key => $parameter )
 163                  {
 164                      $parameters[$key] = trim( $parameter );
 165                  }
 166  
 167                  if ( !file_exists( $templateFile ) )
 168                  {
 169                      eZDebug::writeError( "Template file $templateFile was not found while workin on $filePath at offset $offset",
 170                                           'eZCodeTemplate::apply' );
 171                      $offset = $end;
 172                      $error = true;
 173                      continue;
 174                  }
 175  
 176                  // Load the template file and split it into the blocks
 177                  // available blocks in the file
 178                  $templateText = file_get_contents( $templateFile );
 179  
 180                  $tagSplit = '#((?:<|/\*)(?:START|END):code-template::(?:[a-zA-Z]+[a-zA-Z0-9_|&-]*)(?:>|\*/)[\n]?)#';
 181                  $tagRegexp = '#(?:<|/\*)(START|END):code-template::([a-zA-Z]+[a-zA-Z0-9_|&-]*)[\n]?(?:>|\*/)#';
 182  
 183                  $split = preg_split( $tagSplit, $templateText, -1, PREG_SPLIT_DELIM_CAPTURE );
 184  
 185                  $currentBlocks = array();
 186                  $blocks = array();
 187                  $currentTag = false;
 188                  for ( $i = 0; $i < count( $split ); ++$i )
 189                  {
 190                      $part = $split[$i];
 191                      if ( ( $i % 2 ) == 1 )
 192                      {
 193                          // The tag element
 194                          if ( $currentTag === false )
 195                          {
 196                              preg_match( $tagRegexp, trim( $part ), $matches );
 197                              $currentTag = $matches[2];
 198                              if ( $matches[1] == 'END' )
 199                              {
 200                                  eZDebug::writeError( "Tag $currentTag was finished before it was started, skipping it",
 201                                                       'eZCodeTemplate::apply' );
 202                                  $currentTag = false;
 203                                  $error = true;
 204                              }
 205                              else
 206                              {
 207                                  if ( count( $currentBlocks ) > 0 )
 208                                      $blocks[] = array( 'blocks' => $currentBlocks );
 209                                  $currentBlocks = array();
 210                              }
 211                          }
 212                          else
 213                          {
 214                              preg_match( $tagRegexp, trim( $part ), $matches );
 215                              $tag = $matches[2];
 216                              if ( $matches[1] == 'END' )
 217                              {
 218                                  if ( $tag == $currentTag )
 219                                  {
 220                                      if ( count( $currentBlocks ) > 0 )
 221                                          $blocks[] = array( 'tag' => $currentTag,
 222                                                             'blocks' => $currentBlocks );
 223                                      $currentTag = false;
 224                                      $currentBlocks = array();
 225                                  }
 226                                  else
 227                                  {
 228                                      eZDebug::writeError( "End tag $tag does not match start tag $currentTag, skipping it",
 229                                                           'eZCodeTemplate::apply' );
 230                                      $error = true;
 231                                  }
 232                              }
 233                              else
 234                              {
 235                                  eZDebug::writeError( "Start tag $tag found while $currentTag is active, skipping it",
 236                                                       'eZCodeTemplate::apply' );
 237                                  $error = true;
 238                              }
 239                          }
 240                      }
 241                      else
 242                      {
 243                          // Plain text
 244                          $currentBlocks[] = $part;
 245                      }
 246                  }
 247                  if ( $currentTag === false )
 248                  {
 249                      if ( count( $currentBlocks ) > 0 )
 250                          $blocks[] = array( 'blocks' => $currentBlocks );
 251                  }
 252                  else
 253                  {
 254                      if ( count( $currentBlocks ) > 0 )
 255                          $blocks[] = array( 'tag' => $currentTag,
 256                                             'blocks' => $currentBlocks );
 257                  }
 258  
 259                  // Build new code with blocks to include
 260                  $resultText = '';
 261                  foreach ( $blocks as $block )
 262                  {
 263                      if ( isset( $block['tag'] ) )
 264                      {
 265                          $tagText = $block['tag'];
 266                          if ( strpos( $tagText, '&' ) !== false )
 267                          {
 268                              $tags = explode( '&', $tagText );
 269                              // Check if all tags are present in parameters (and match)
 270                              if ( count( array_intersect( $parameters, $tags ) ) == count( $tags ) )
 271                              {
 272                                  $resultText .= implode( '', $block['blocks'] );
 273                              }
 274                          }
 275                          else if ( strpos( $tagText, '|' ) !== false )
 276                          {
 277                              $tags = explode( '|', $tagText );
 278                              // Check if at least one tag is present in parameters (or match)
 279                              if ( count( array_intersect( $parameters, $tags ) ) == count( $tags ) )
 280                              {
 281                                  $resultText .= implode( '', $block['blocks'] );
 282                              }
 283                          }
 284                          else
 285                          {
 286                              if ( in_array( $tagText, $parameters ) )
 287                              {
 288                                  $resultText .= implode( '', $block['blocks'] );
 289                              }
 290                          }
 291                      }
 292                      else
 293                      {
 294                          $resultText .= implode( '', $block['blocks'] );
 295                      }
 296                  }
 297  
 298                  // Remove any end-of-line whitespaces unless keep-whitespace is used
 299                  if ( !in_array( 'keep-whitespace', $parameters ) )
 300                      $resultText = preg_replace( '#[ \t]+$#m', '', $resultText );
 301  
 302                  // Output text before the template-block
 303                  fwrite( $fd, substr( $text, $offset, $createPos - $offset ) );
 304                  fwrite( $fd, substr( $text, $createPos, $end - $createPos ) );
 305  
 306                  $offset = $end;
 307  
 308                  // Remove any existing auto-generated code
 309                  $autogenRegexp = '#^[ \t]*// code-template::auto-generated:START ' . $templateName . '.+[ \t]*// code-template::auto-generated:END ' . $templateName . '\n#ms';
 310                  $postText = substr( $text, $offset );
 311                  $postText = preg_replace( $autogenRegexp, '', $postText );
 312                  $text = substr( $text, 0, $offset ) . $postText;
 313                  unset( $postText );
 314  
 315                  // Output the template code with markers
 316                  fwrite( $fd, ( "$indentText// code-template::auto-generated:START $templateName\n" .
 317                                 "$indentText// This code is automatically generated from $templateFile\n" .
 318                                 "$indentText// DO NOT EDIT THIS CODE DIRECTLY, CHANGE THE TEMPLATE FILE INSTEAD\n" .
 319                                 "\n" ) );
 320  
 321                  fwrite( $fd, $resultText );
 322                  fwrite( $fd, ( "\n$indentText// This code is automatically generated from $templateFile\n" .
 323                                 "$indentText// code-template::auto-generated:END $templateName\n" ) );
 324  
 325              }
 326              else
 327              {
 328                  fwrite( $fd, substr( $text, $offset ) );
 329                  break;
 330              }
 331          }
 332  
 333          fclose( $fd );
 334          if ( !$error )
 335          {
 336              $originalMD5 = md5_file( $filePath );
 337              $updatedMD5 = md5_file( $tempFile );
 338              if ( $originalMD5 == $updatedMD5 )
 339              {
 340                  unlink( $tempFile );
 341                  return EZ_CODE_TEMPLATE_STATUS_NO_CHANGE;
 342              }
 343              else if ( $checkOnly )
 344              {
 345                  unlink( $tempFile );
 346                  return EZ_CODE_TEMPLATE_STATUS_OK;
 347              }
 348              else
 349              {
 350                  $backupFile = $filePath . eZSys::backupFilename();
 351                  // Make a backup and make the temporary file the real one
 352                  if ( file_exists( $backupFile ) )
 353                      unlink( $backupFile );
 354                  rename( $filePath, $backupFile );
 355                  rename( $tempFile, $filePath );
 356                  return EZ_CODE_TEMPLATE_STATUS_OK;
 357              }
 358          }
 359          unlink( $tempFile );
 360          return EZ_CODE_TEMPLATE_STATUS_FAILED;
 361      }
 362  
 363      /*!
 364       \return The name of the template file based on the name \a $templateName
 365               or \c false if no file is defined for the name.
 366      */
 367      function templateFile( $templateName )
 368      {
 369          if ( isset( $this->Templates[$templateName] ) )
 370          {
 371              return $this->Templates[$templateName]['filepath'];
 372          }
 373          return false;
 374      }
 375  
 376      /*!
 377       \static
 378       Finds all PHP files which must be updated and returns them as an array.
 379  
 380       The files are defined in \c codetemplate.ini in the variable \c PHPFiles
 381      */
 382      function allCodeFiles()
 383      {
 384          $ini =& eZINI::instance( 'codetemplate.ini' );
 385          return $ini->variable( 'Files', 'PHPFiles' );
 386      }
 387  
 388      /// \privatesection
 389      var $Templates;
 390  }
 391  
 392  ?>


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7