| <?php |
| /** |
| * File containing the ezcPhpGenerator class |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| * @package PhpGenerator |
| * @version //autogen// |
| * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
| */ |
| |
| /** |
| * ezcPhpGenerator provides a simple API to generate PHP code. |
| * |
| * This class can be used to generate quick and simple PHP scripts. Typical |
| * usage would be to generate caches in the form of arrays that also require |
| * some logic. |
| * |
| * The following example shows how you can use ezcPhpGenerator to make a method |
| * that produces a Fibonacci number. |
| * |
| * <code> |
| * $generator = new ezcPhpGenerator( "~/file.php" ); |
| * $generator->appendCustomCode( 'function fibonacci( $number )' ); |
| * $generator->appendCustomCode( "{" ); |
| * |
| * $generator->appendValueAssignment( "lo", 0 ); |
| * $generator->appendValueAssignment( "hi", 1 ); |
| * $generator->appendValueAssignment( "i", 2 ); |
| * |
| * $generator->appendWhile( '$i < $number' ); |
| * $generator->appendCustomCode( '$hi = $lo + $hi;' ); |
| * $generator->appendCustomCode( '$lo = $hi - $lo;' ); |
| * $generator->appendCustomCode( '$i++;' ); |
| * $generator->appendEndWhile(); |
| * $generator->appendCustomCode( 'return $hi;' ); |
| * $generator->appendCustomCode( "}" ); |
| * $generator->finish(); |
| * </code> |
| * |
| * The above code will fill the file "~/file.php" with the following contents: |
| * <code> |
| * <?php |
| * function fibonacci( $number ) |
| * { |
| * $lo = 0; |
| * $hi = 1; |
| * $i = 2; |
| * while ( $i < $number ) |
| * { |
| * $hi = $lo + $hi; |
| * $lo = $hi - $lo; |
| * $i++; |
| * } |
| * return $hi; |
| * } |
| * ?> |
| * </code> |
| * |
| * @property int $indentLevel |
| * Contains the level of indentation. Increase or decrease by one if |
| * you want the indentation level to change. |
| * @property string $lineBreak |
| * Contains the characters to use for linebreaks. The default is |
| * "\r\n". |
| * @property bool $niceIndentation |
| * Controls whether to output the PHP nicely indented or not. The |
| * default is false. |
| * @property string $indentString |
| * Contains the characters that are indented per indentation level. |
| * The default is ' ' (two spaces). |
| * |
| * @package PhpGenerator |
| * @version //autogentag// |
| * @mainclass |
| */ |
| class ezcPhpGenerator |
| { |
| /** |
| * Normal assignment '='. |
| */ |
| const ASSIGN_NORMAL = 1; |
| |
| /** |
| * Text append assignment '.='. |
| */ |
| const ASSIGN_APPEND_TEXT = 2; |
| |
| /** |
| * Assignment with add '+='. |
| */ |
| const ASSIGN_ADD = 3; |
| |
| /** |
| * Assignment with subtraction '-='. |
| */ |
| const ASSIGN_SUBTRACT = 4; |
| |
| /** |
| * Assignment with array append $var[] ='. |
| */ |
| const ASSIGN_ARRAY_APPEND = 5; |
| |
| |
| // method control structures |
| /** |
| * 'if' program flow structure. |
| */ |
| const FLOW_IF = 'if'; |
| |
| /** |
| * 'foreach' program flow structure. |
| */ |
| const FLOW_FOREACH = 'foreach'; |
| |
| /** |
| * 'for' program flow structure. |
| */ |
| const FLOW_FOR = 'for'; |
| |
| /** |
| * 'do' program flow structure. |
| */ |
| const FLOW_DO = 'do'; |
| |
| /** |
| * 'while' program flow structure. |
| */ |
| const FLOW_WHILE = 'while'; |
| |
| |
| /** |
| * File resource pointing to the file specified by of tmpFilename. |
| * This is used to write to during execution. |
| * @var resource |
| */ |
| private $fileResource = null; |
| |
| /** |
| * ezcPhpGenerator writes to the file with this name during execution. |
| * When {@link finish()} is called this file is moved to $resultFileName. |
| * @var string |
| */ |
| private $tmpFilename = null; |
| |
| /** |
| * The name of the final result file set in the constructor. |
| * @var string |
| */ |
| private $resultFilename = null; |
| |
| /** |
| * Whether to include < ?php and ? > to the file. |
| * @var bool |
| */ |
| private $includeStartEndTags; |
| |
| /** |
| * Stack of FLOW_ constants used to check if control structures are properly nested. |
| * |
| * Each time a control structure (e.g appendWhile) is started the corresponding |
| * FLOW_ constant is pushed on the stack. When a control structure is finalized |
| * (e.g appendEndWhile) a value is popped from the stack and checked if it is of the |
| * correct type. |
| * |
| * @var array |
| */ |
| private $flowStack = array(); |
| |
| /** |
| * Holds the properties of this class. |
| * @var array |
| */ |
| private $properties = array(); |
| |
| /** |
| * Constructs a new ezcPhpGenerator. |
| * |
| * Constructs a new ezcPhpGenerator that writes to the file $fileName. If $includeStartEndTags |
| * is set the start and end PHP tags will be included. It is useful to omit these if you |
| * want to run the generated code using eval() later. $niceIndentation controls if the PHP output |
| * should be indented correctly. This option is useful if you want to debug the generated code. |
| * |
| * @throws ezcBaseFileNotFoundException if $filename does not contain a valid path. |
| * @throws ezcBaseFilePermissionException if the path specified by $filename is not writeable. |
| * @param string $filename |
| * @param bool $includeStartEndTags |
| * @param bool $niceIndentation |
| */ |
| public function __construct( $filename, $includeStartEndTags = true, $niceIndentation = false ) |
| { |
| // properties defaults |
| $this->indentLevel = 0; |
| $this->lineBreak = "\r\n"; |
| $this->niceIndentation = $niceIndentation; |
| $this->indentString = ' '; |
| |
| // other initialization |
| $this->resultFilename = $filename; |
| $this->includeStartEndTags = $includeStartEndTags; |
| |
| |
| // setup file write resource |
| $dir = dirname( $filename ); |
| if ( !file_exists( $dir ) ) |
| { |
| throw new ezcBaseFileNotFoundException( $dir ); |
| } |
| else if ( !is_writable( $dir ) ) |
| { |
| throw new ezcBaseFilePermissionException( $dir, ezcBaseFileException::WRITE ); |
| } |
| |
| $file = basename( $filename ); |
| |
| // generate a temporary name |
| $id = md5( uniqid( "ezp". getmypid(), true ) ); |
| $this->tmpFilename = $filename . $id; |
| |
| // open the file, and make it ready for writing |
| $this->fileResource = fopen( $this->tmpFilename, 'w' ); |
| if ( $this->fileResource == false ) |
| { |
| $this->tmpFilename = null; |
| $this->fileResource = null; |
| $this->resultFilename = null; |
| throw new ezcBaseFilePermissionException( $file, ezcBaseFileException::WRITE, |
| "Failed to open temporary file even though the directory was writable." ); |
| } |
| if ( $this->includeStartEndTags ) |
| { |
| $this->write( '<?php' . $this->lineBreak ); |
| } |
| } |
| |
| /** |
| * Sets the property $name to $value. |
| * |
| * @throws ezcBasePropertyNotFoundException if the property does not exist. |
| * @param string $name |
| * @param mixed $value |
| * @ignore |
| */ |
| public function __set( $name, $value ) |
| { |
| switch ( $name ) |
| { |
| case 'lineBreak': |
| $this->properties['lineBreak'] = $value; |
| break; |
| |
| case 'indentLevel': |
| $this->properties['indentLevel'] = $value; |
| break; |
| |
| case 'indentString': |
| $this->properties['indentString'] = $value; |
| break; |
| |
| case 'niceIndentation': |
| $this->properties['niceIndentation'] = $value; |
| break; |
| |
| default: |
| throw new ezcBasePropertyNotFoundException( $name ); |
| break; |
| } |
| } |
| |
| /** |
| * Returns the value of property $name. |
| * |
| * @throws ezcBasePropertyNotFoundException if the property does not exist. |
| * @param string $name |
| * @return mixed |
| * @ignore |
| */ |
| public function __get( $name ) |
| { |
| switch ( $name ) |
| { |
| case 'lineBreak': |
| case 'indentLevel': |
| case 'indentString': |
| case 'niceIndentation': |
| return $this->properties[$name]; |
| |
| default: |
| throw new ezcBasePropertyNotFoundException( $name ); |
| } |
| } |
| |
| |
| /** |
| * Destructs the object. |
| * |
| * Removes all temporary files that are in use. |
| * |
| * @return void |
| */ |
| public function __destruct() |
| { |
| $this->abort(); |
| } |
| |
| /** |
| * Completes the code generation |
| * |
| * This method must be called when you have finished generating a file. It |
| * moves the temporary file that was used for writing to the end result |
| * file and releases used resources. |
| * Subsequent calls to any methods generating code will fail. |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write to the |
| * output file or if there are any control structures (if/foreach |
| * etc.) still open. |
| * @return void |
| */ |
| public function finish() |
| { |
| $count = count( $this->flowStack ); |
| if ( $count != 0 ) |
| { |
| throw new ezcPhpGeneratorFlowException( $this->flowStack[$count-1], 'finish' ); |
| } |
| |
| if ( $this->fileResource ) |
| { |
| if ( $this->includeStartEndTags ) |
| { |
| $this->write( '?'.'>' ); |
| } |
| fclose( $this->fileResource ); |
| $this->fileResource = null; |
| |
| // Sigh, rename is also noisy if it can't rename |
| if ( @rename( $this->tmpFilename, $this->resultFilename ) === false ) |
| { |
| throw new ezcPhpGeneratorException( "ezcPhpGenerator could not open the file '{$this->resultFilename}' for writing." ); |
| } |
| } |
| } |
| |
| /** |
| * Aborts the PHP generating. Cleans up the file handler and the temporary file. |
| * |
| * Subsequent calls to any methods that generate code will fail. |
| * |
| * @return void |
| */ |
| public function abort() |
| { |
| if ( file_exists( $this->tmpFilename ) ) |
| { |
| $this->fileResource = null; |
| unlink( $this->tmpFilename ); |
| $this->tmpFilename = null; |
| } |
| } |
| |
| /** |
| * Defines the variable $name with the value $value in the generated code. |
| * |
| * The parameter $caseSensitive determines if the defined variable is case |
| * sensitive or not. Note that $name must start with a letter or |
| * underscore, followed by any number of letters, numbers, or underscores. |
| * {@link http://php.net/manual/en/language.constants.php} for more information. |
| * {@link http://php.net/manual/en/function.define.php} |
| * |
| * Example: |
| * <code> |
| * $php->addDefine( 'MY_CONSTANT', 5 ); |
| * </code> |
| * |
| * Produces: |
| * |
| * <code> |
| * define( 'MY_CONSTANT', 5 ); |
| * </code> |
| * |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the define to the output file. |
| * @param string $name |
| * @param string $value |
| * @param bool $caseInsensitive |
| * @return void |
| */ |
| public function appendDefine( $name, $value, $caseInsensitive = false ) |
| { |
| $valueData = var_export( $value, true ); |
| $case = ''; |
| if ( $caseInsensitive == true ) |
| { |
| $case = ', true'; |
| } |
| $this->write( $this->indentCode( "define( '$name', $valueData". $case . ' );' . $this->lineBreak ) ); |
| } |
| |
| /** |
| * Assigns $value to the variable $name in the generated code. |
| * |
| * $value is exported using var_export(). This allows you to use complex |
| * structures for $value. If you want to append an assignment to a variable |
| * in the generated code use appendVariableAssignment. |
| * |
| * You can control the assignment type with the $assignmentType parameter. |
| * |
| * Example: |
| * <code> |
| * $array = array( 1, 2, 3 ); |
| * $php->appendValueAssignment( 'ProducedArray', $array ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * $ProducedArray = array( 1, 2, 3 ); |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the assignment to the output file. |
| * @param string $name |
| * @param mixed $value |
| * @param int $assignmentType ezcPhpGenerator:: ASSIGN_NORMAL, ASSIGN_APPEND_TEXT, ASSIGN_ADD, |
| * ASSIGN_SUBTRACT or ASSIGN_ARRAY_APPEND. |
| * @return void |
| */ |
| public function appendValueAssignment( $name, $value, $assignmentType = ezcPhpGenerator::ASSIGN_NORMAL ) |
| { |
| switch ( $assignmentType ) |
| { |
| case self::ASSIGN_NORMAL: |
| $this->write( $this->indentCode( "\${$name} = ". var_export( $value, true). ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_APPEND_TEXT: |
| $this->write( $this->indentCode( "\${$name} .= ". var_export( $value, true). ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_ADD: |
| $this->write( $this->indentCode( "\${$name} += ". var_export( $value, true). ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_SUBTRACT: |
| $this->write( $this->indentCode( "\${$name} -= ". var_export( $value, true). ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_ARRAY_APPEND: |
| $this->write( $this->indentCode( "\${$name}[] = ". var_export( $value, true). ";{$this->lineBreak}" ) ); |
| break; |
| default: // default to ASSIGN_NORMAL |
| $this->write( $this->indentCode( "\${$name} = ". var_export( $value, true). ";{$this->lineBreak}" ) ); |
| break; |
| } |
| } |
| |
| /** |
| * Assigns the variable named $variable to the variable $name in the |
| * generated code. |
| * |
| * You can control the assignment type with the $assignmentType parameter. |
| * |
| * Example: |
| * <code> |
| * $php->addVariableAssignment( 'ProducedArray', 'otherVar' ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * $ProducedArray = $otherVar; |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the assignment to the output file. |
| * @param string $name |
| * @param mixed $variable |
| * @param int $assignmentType ezcPhpGenerator:: ASSIGN_NORMAL, ASSIGN_APPEND_TEXT, ASSIGN_ADD, |
| * ASSIGN_SUBTRACT or ASSIGN_ARRAY_APPEND. |
| * @return void |
| */ |
| public function appendVariableAssignment( $name, $variable, $assignmentType = ezcPhpGenerator::ASSIGN_NORMAL ) |
| { |
| switch ( $assignmentType ) |
| { |
| case self::ASSIGN_NORMAL: |
| $this->write( $this->indentCode( "\${$name} = ". '$' . $variable. ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_APPEND_TEXT: |
| $this->write( $this->indentCode( "\${$name} .= ". '$' .$variable . ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_ADD: |
| $this->write( $this->indentCode( "\${$name} += ". '$' .$variable . ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_SUBTRACT: |
| $this->write( $this->indentCode( "\${$name} -= ". '$' .$variable . ";{$this->lineBreak}" ) ); |
| break; |
| case self::ASSIGN_ARRAY_APPEND: |
| $this->write( $this->indentCode( "\${$name}[] = ". '$' .$variable . ";{$this->lineBreak}" ) ); |
| break; |
| default: // default to ASSIGN_NORMAL |
| $this->write( $this->indentCode( "\${$name} = ". '$' .$variable . ";{$this->lineBreak}" ) ); |
| break; |
| } |
| } |
| |
| |
| /** |
| * Unsets the variable $name in the generated code. |
| * |
| * Example: |
| * <code> |
| * $php->addVariableUnset( 'offset' ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * unset( $offset ); |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the unset to the output file. |
| * @param string $name |
| * @return void |
| */ |
| public function appendUnset( $name ) |
| { |
| $this->write( $this->indentCode( "unset( \${$name} );{$this->lineBreak}" ) ); |
| } |
| |
| /** |
| * Unsets the variable names in $list in the generated code. |
| * |
| * Example: |
| * <code> |
| * $php->addVariableUnsetList( array ( 'var1', 'var2' ) ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * unset( $var1, $var2 ); |
| * </code> |
| |
| * @see http://php.net/manual/en/function.unset.php |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the unset to the output file. |
| * @param array $list Array of variable names. |
| * @return void |
| */ |
| public function appendUnsetList( array $list ) |
| { |
| $first = true; |
| $variables = ''; |
| foreach ( $list as $item ) |
| { |
| if ( !$first ) |
| { |
| $variables .= ', '; |
| } |
| else |
| { |
| $first = false; |
| } |
| $variables .= "\${$item}"; |
| } |
| $this->write( $this->indentCode( "unset( $variables );{$this->lineBreak}" ) ); |
| } |
| |
| /** |
| * Inserts $lines number of empty lines in the generated code. |
| * |
| * Example: |
| * <code> |
| * $php->addSpace( 1 ); |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the empty lines to the output file. |
| * @param int $lines |
| * @return void |
| */ |
| public function appendEmptyLines( $lines = 1 ) |
| { |
| $this->write( str_repeat( $this->lineBreak, $lines ) ); |
| } |
| |
| /** |
| * Inserts a function call in the generated code. |
| * |
| * Inserts a call to $functionName with the parameters $parameters. |
| * Set the $returnData parameter if you want to catch the return value. |
| * |
| * Example: |
| * <code> |
| * $php->appendFunctionCall( 'str_repeat', array( new ezcPhpGeneratorParameter( 'repeat' ), |
| * new ezcPhpGeneratorParameter( 4, ezcPhpGenerator::VALUE ) ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * $var = str_repeat( $repeat, 4 ); |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the method call to the output file. |
| * @param string $functionName |
| * @param array(ezcPhpGeneratorParameter) $parameters |
| * @param ezcPhpGeneratorReturnData $returnData |
| * @return void |
| */ |
| public function appendFunctionCall( $functionName, array $parameters, ezcPhpGeneratorReturnData $returnData = null ) |
| { |
| $this->appendMethodOrFunctionCall( $functionName, $parameters, $returnData ); |
| } |
| |
| /** |
| * Inserts a method call on an object in the generated code. |
| * |
| * Inserts a call to the method $methodName on the object $objectName with |
| * parameters $parameters. |
| * Set the $returnData parameter if you want to catch the return value. |
| * |
| * Example: |
| * <code> |
| * $php->appendMethodCall( 'node', 'name', array(), new ezcPhpGeneratorReturnType( 'result' ) ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * |
| * <code> |
| * $result = $node->name(); |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the method call to the output file. |
| * @param string $objectName |
| * @param string $methodName |
| * @param array(ezcPhpGeneratorParameter) $parameters |
| * @param ezcPhpGeneratorReturnData $returnData |
| * @return void |
| */ |
| public function appendMethodCall( $objectName, $methodName, array $parameters = array(), ezcPhpGeneratorReturnData $returnData = null ) |
| { |
| $this->appendMethodOrFunctionCall( $methodName, $parameters, $returnData, $objectName ); |
| } |
| |
| /** |
| * Inserts a method or function call in the generated code. |
| * |
| * A method call is inserted if $objectName is provided. If not a function call is inserted. This |
| * method is a helper method for appendFunctionCall and appendMethodCall. See their description for |
| * further description of the parameters and examples. |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the method call to the output file. |
| * @param string $functionName |
| * @param array(ezcPhpGeneratorParameter) $parameters |
| * @param ezcPhpGeneratorReturnData $returnData |
| * @param string $objectVariable The variable name containing the object. |
| * @return void |
| */ |
| protected function appendMethodOrFunctionCall( $functionName, array $parameters, $returnData = null, |
| $objectVariable = null ) |
| { |
| // prepare the return part |
| $returnString = ''; |
| if ( $returnData != null ) |
| { |
| switch ( $returnData->type ) |
| { |
| case self::ASSIGN_NORMAL: |
| $returnString = "\${$returnData->variable} ="; |
| break; |
| case self::ASSIGN_APPEND_TEXT: |
| $returnString = "\${$returnData->variable} .="; |
| break; |
| case self::ASSIGN_ADD: |
| $returnString = "\${$returnData->variable} +="; |
| break; |
| case self::ASSIGN_SUBTRACT: |
| $returnString = "\${$returnData->variable} -="; |
| break; |
| case self::ASSIGN_ARRAY_APPEND: |
| $returnString = "\${$returnData->variable}[] ="; |
| break; |
| default: // default to ASSIGN_NORMAL |
| $returnString = "\${$returnData->variable} ="; |
| break; |
| } |
| $returnString .= ' '; // append trailing space |
| } |
| |
| // prepare the object string if this is a call to an object |
| $objectString = ''; |
| if ( $objectVariable !== null ) |
| { |
| $objectString = "\${$objectVariable}->"; |
| } |
| |
| // prepare the parameters |
| $parameterString = ''; |
| if ( is_array( $parameters ) && count( $parameters ) > 0 ) |
| { |
| $firstParam = true; |
| foreach ( $parameters as $parameter ) |
| { |
| if ( $parameter->type == ezcPhpGeneratorParameter::VALUE ) |
| { |
| $parameterString .= $firstParam ? '' : ', '; |
| $parameterString .= var_export( $parameter->variable, true ); |
| } |
| else if ( $parameter->type == ezcPhpGeneratorParameter::VARIABLE ) |
| { |
| $parameterString .= $firstParam ? '' : ', '; |
| $parameterString .= "\${$parameter->variable}"; |
| } |
| // else <-- we could have thrown an exception, but we simply ignore this |
| $firstParam = false; |
| } |
| } |
| $this->write( $this->indentCode( "$returnString$objectString$functionName( $parameterString );" . $this->lineBreak ) ); |
| } |
| |
| /** |
| * Inserts custom code into the generated code. |
| * |
| * Inserts the $code directly into the generated code. Correct indenting |
| * and a linebreak at the end of your code will be inserted automatically. |
| * |
| * Example: |
| * <code> |
| * $php->addCodePiece( "if ( \$value > 2 )" . $php->lineBreak() |
| * . '{' . $php->lineBreak() . "\$value = 2;" ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * if ( $value > 2 ) |
| * { |
| * $value = 2; |
| * } |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the custom code to the output file. |
| * @param string $code |
| * @return void |
| */ |
| public function appendCustomCode( $code ) |
| { |
| $this->write( $this->indentCode( $code . $this->lineBreak ) ); |
| } |
| |
| /** |
| * Inserts a comment into the generated code. |
| * |
| * The comment will be displayed using an end-of-line comment (//). |
| * |
| * Example: |
| * <code> |
| * $php->addComment( "This file is auto generated. Do not edit!" ); |
| * <code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * // This file is auto generated. Do not edit! |
| * </code> |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the comment to the output file. |
| * @param string $comment |
| * @return void |
| */ |
| public function appendComment( $comment ) |
| { |
| $this->write( $this->indentCode( '// ' . $comment . $this->lineBreak ) ); |
| } |
| |
| /** |
| * Inserts an if statement into the generated code. |
| * |
| * The complete condition of the if statement is provided through $condition. |
| * The if statement must be closed properly with a call to appendEndIf(). |
| * |
| * Example: |
| * <code> |
| * $php->appendIf( '$myVar === 0 ' ); |
| * $php->appendEndIf(); |
| * </code> |
| * |
| * Produces the PHP code: |
| * |
| * <code> |
| * if ( $myVar === 0 ) |
| * { |
| * } |
| * </code> |
| * |
| * @see $ezcPhpGenerator::appendElse() |
| * @see $ezcPhpGenerator::appendEndIf() |
| * @throws ezcPhpGeneratorException if it was not possible to write the if statement to the output file. |
| * @param string $condition |
| * @return void |
| */ |
| public function appendIf( $condition ) |
| { |
| $this->write( $this->indentCode( "if ( $condition )" . $this->lineBreak . '{' . $this->lineBreak ) ); |
| $this->indentLevel++; |
| $this->flowStack[] = self::FLOW_IF; |
| } |
| |
| /** |
| * Ends an if statement in the generated code. |
| * |
| * @see $ezcPhpGenerator::appendIf() |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write to the output file |
| * or if the method was not properly nested with an appendIf. |
| * @return void |
| */ |
| public function appendEndIf() |
| { |
| $this->appendEnd( self::FLOW_IF ); |
| } |
| |
| /** |
| * Inserts an else or an else if statement into the generated code. |
| * |
| * If a $condition is provided an else if statement is generated. |
| * If not, an else statement is generated. You can only call this method |
| * after calling appendIf first. |
| * |
| * Example: |
| * <code> |
| * $php->appendIf( '$myVar === 0 ' ); |
| * $php->appendElse( '$myVar2 === 0 ' ); |
| * $php->appendElse(); |
| * $php->appendEndIf(); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * if ( $myVar === 0 ) |
| * { |
| * } |
| * else if ( $myVar ) |
| * { |
| * } |
| * else |
| * { |
| * } |
| * </code> |
| * |
| * @see $ezcPhpGenerator::appendIf() |
| * @see $ezcPhpGenerator::appendEndIf() |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the if statement to the output file. |
| * @param string $condition |
| * @return void |
| */ |
| public function appendElse( $condition = '' ) |
| { |
| // check that we are in the correct flow type |
| $pop = array_pop( $this->flowStack ); |
| if ( $pop == self::FLOW_IF ) |
| { |
| $this->flowStack[] = self::FLOW_IF; // push it back |
| $this->indentLevel--; |
| if ( $condition != '' ) |
| { |
| $condition = 'if ( ' . $condition . ' )'; |
| } |
| $this->write( $this->indentCode( '}' . $this->lineBreak ) . "else $condition" . |
| $this->lineBreak . '{' . $this->lineBreak ); |
| $this->indentLevel++; |
| } |
| else |
| { |
| $this->abort(); |
| $current = $pop ? $pop : 'no control structure'; |
| throw new ezcPhpGeneratorFlowException( $current, 'else' ); |
| } |
| } |
| |
| /** |
| * Inserts a foreach statement into the generated code. |
| * |
| * The complete condition of the foreach statement is provided through $condition. |
| * The foreach statement must be closed properly with a call to appendEndForeach(). |
| * |
| * Example: |
| * <code> |
| * $php->appendForeach( '$myArray as $item ' ); |
| * $php->appendEndForeach(); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * foreach ( $myArray as $item ) |
| * { |
| * } |
| * </code> |
| * |
| * @see $ezcPhpGenerator::appendEndForeach() |
| * @throws ezcPhpGeneratorException if it was not possible to write the foreach statement to the output file. |
| * @param string $condition |
| * @return void |
| */ |
| public function appendForeach( $condition ) |
| { |
| $this->write( $this->indentCode( "foreach ( $condition )" . $this->lineBreak . '{' . $this->lineBreak ) ); |
| $this->indentLevel++; |
| $this->flowStack[] = self::FLOW_FOREACH; |
| } |
| |
| /** |
| * Ends a foreach statement in the generated code. |
| * |
| * @see $ezcPhpGenerator::appendForeach() |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write to the output file |
| * or if the method was not properly nested with an appendForeach. |
| * @return void |
| */ |
| public function appendEndForeach() |
| { |
| $this->appendEnd( self::FLOW_FOREACH ); |
| } |
| |
| /** |
| * Inserts a while statement in the generated code. |
| * |
| * The complete condition of the while statement is provided through $condition. |
| * The while statement must be closed properly with a call to appendEndWhile(). |
| * |
| * Example: |
| * <code> |
| * $php->appendWhile( '$myVar > 0' ); |
| * $php->appendEndWhile(); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * while ( $myVar > 0 ) |
| * { |
| * } |
| * </code> |
| * |
| * @see $ezcPhpGenerator::appendEndWhile() |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the while statement to the output file. |
| * @param string $condition |
| * @return void |
| */ |
| public function appendWhile( $condition ) |
| { |
| $this->write( $this->indentCode( "while ( $condition )" . $this->lineBreak . '{' . $this->lineBreak ) ); |
| $this->indentLevel++; |
| $this->flowStack[] = self::FLOW_WHILE; |
| } |
| |
| /** |
| * Ends a while statement in the generated code. |
| * |
| * @see $ezcPhpGenerator::appendWhile() |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write to the output file |
| * or if the method was not properly nested with an appendWhile. |
| * @return void |
| */ |
| public function appendEndWhile() |
| { |
| $this->appendEnd( self::FLOW_WHILE ); |
| } |
| |
| /** |
| * Inserts a do statement in the generated code. |
| * |
| * The do statement must be closed properly with a call to appendEndDo(). |
| * |
| * Example: |
| * <code> |
| * $php->appendDo(); |
| * $php->appendEndDo( '$myVar > 0' ); |
| * </code> |
| * |
| * Produces the PHP code: |
| * <code> |
| * do |
| * { |
| * } while ( $myVar > 0 ); |
| * </code> |
| * |
| * @see $ezcPhpGenerator::appendEndDo() |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write to the output file. |
| * @return void |
| */ |
| public function appendDo() |
| { |
| $this->write( $this->indentCode( 'do' . $this->lineBreak . '{' . $this->lineBreak ) ); |
| $this->indentLevel++; |
| $this->flowStack[] = self::FLOW_DO; |
| } |
| |
| /** |
| * Ends a do statement in the generated code. |
| * |
| * The complete condition of the do statement is provided through $condition. |
| * |
| * @see $ezcPhpGenerator::appendDo() |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write the do statement to the output file |
| * or if the method was not properly nested with an appendDo. |
| * @param string $condition |
| * @return void |
| */ |
| public function appendEndDo( $condition ) |
| { |
| $pop = array_pop( $this->flowStack ); |
| if ( $pop == self::FLOW_DO ) |
| { |
| $this->indentLevel--; |
| $this->write( $this->indentCode( '} while ( ' . $condition . ' );'. $this->lineBreak ) ); |
| } |
| else |
| { |
| $this->abort(); |
| throw new ezcPhpGeneratorFlowException( $pop, 'do' ); |
| } |
| } |
| |
| /** |
| * Checks that the end call is properly nested using $type and the flow stack. |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write to the output file or if a nesting |
| * error was detected. |
| * @param int $type One of the flow types FLOW_IF, FLOW_FOREACH, FLOW_WHILE or FLOW_DO. |
| * @return void |
| */ |
| private function appendEnd( $type ) |
| { |
| $pop = array_pop( $this->flowStack ); |
| if ( $pop == $type ) |
| { |
| $this->indentLevel--; |
| $this->write( $this->indentCode( '}' . $this->lineBreak ) ); |
| } |
| else |
| { |
| $this->abort(); |
| $current = $pop ? $pop : 'no control structure'; |
| throw new ezcPhpGeneratorFlowException( $current, $type ); |
| } |
| } |
| /** |
| * Writes $data to $this->fileResource |
| * |
| * @throws ezcPhpGeneratorException if it was not possible to write to the file. |
| * @param string $data |
| * @return void |
| */ |
| protected function write( $data ) |
| { |
| if ( !$this->fileResource ) |
| { |
| throw new ezcBaseFileIoException( $this->tmpFilename, ezcBaseFileException::WRITE, |
| 'ezcPhpGenerator could not write to the temporary file. It has already been closed.' ); |
| } |
| |
| if ( fwrite( $this->fileResource, $data ) === false ) |
| { |
| throw new ezcBaseFileIoException( $this->tmpFilename, ezcBaseFileException::WRITE, |
| 'ezcPhpGenerator could not write to the temporary file.' ); |
| } |
| } |
| |
| /** |
| * Returns each line in $text indented correctly if indenting is turned on. |
| * |
| * If indenting is turned off it will return $text unmodified. |
| * |
| * @param string $text |
| * @return string |
| */ |
| protected function indentCode( $text ) |
| { |
| if ( $this->niceIndentation == false || $this->indentLevel == 0 ) |
| return $text; |
| |
| $textArray = explode( $this->lineBreak, $text ); |
| $newTextArray = array(); |
| foreach ( $textArray as $text ) |
| { |
| if ( trim( $text ) != '' ) |
| { |
| $textLine = str_repeat( $this->indentString, $this->indentLevel ) . $text; |
| } |
| else |
| { |
| $textLine = $text; |
| } |
| $newTextArray[] = $textLine; |
| } |
| return implode( $this->lineBreak, $newTextArray ); |
| } |
| } |
| ?> |