diff --git a/PHP/Beautifier.php b/PHP/Beautifier.php index ee63c16ac330..ee35a701c6c3 100644 --- a/PHP/Beautifier.php +++ b/PHP/Beautifier.php @@ -19,7 +19,7 @@ * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id:$ */ -error_reporting(E_ALL); +// error_reporting(E_ALL); // Before all, test the tokenizer extension if (!extension_loaded('tokenizer')) { throw new Exception("Compile php with tokenizer extension. Use --enable-tokenizer or don't use --disable-all on configure."); @@ -82,7 +82,7 @@ class PHP_Beautifier implements PHP_Beautifier_Interface { // public - + /** * Tokens created by the tokenizer * @var array @@ -143,7 +143,7 @@ class PHP_Beautifier implements PHP_Beautifier_Interface * Level of ternary operator nesting * @var int */ - public $iTernary = 0; + public $iTernary = 0; /** * Level of parenthesis nesting * @var int @@ -185,7 +185,7 @@ class PHP_Beautifier implements PHP_Beautifier_Interface */ public $aAssocs = array(); // private - + /** * type of file */ @@ -217,7 +217,7 @@ class PHP_Beautifier implements PHP_Beautifier_Interface * List of Control for parenthesis */ private $aControlParenthesis = array(); - /** + /** * List of construct that end control structures */ private $aControlStructuresEnd = array(); @@ -232,13 +232,13 @@ class PHP_Beautifier implements PHP_Beautifier_Interface /** Activate or deactivate 'no delete previous space' */ private $bNdps = false; // Methods - + /** * Constructor. * Assing values to {@link $aControlStructures},{@link $aControlStructuresEnd}, * {@link $aTokenFunctions} */ - public function __construct() + public function __construct() { $this->aControlStructures = array( T_CLASS, @@ -372,7 +372,7 @@ public function __construct() $this->addFilter('Default'); $this->oLog = PHP_Beautifier_Common::getLog(); } - public function getTokenName($iToken) + public function getTokenName($iToken) { if(!$iToken) { throw new Exception("Token $iToken doesn't exists"); @@ -384,7 +384,7 @@ public function getTokenName($iToken) * @param string filename * @param int debug level. See {@link Log} */ - public function startLog($sFile = 'php_beautifier.log', $iLevel = PEAR_LOG_DEBUG) + public function startLog($sFile = 'php_beautifier.log', $iLevel = PEAR_LOG_DEBUG) { @unlink($sFile); $oLogFile = Log::factory('file', $sFile, 'php_beautifier', array() , PEAR_LOG_DEBUG); @@ -395,7 +395,7 @@ public function startLog($sFile = 'php_beautifier.log', $iLevel = PEAR_LOG_DEBUG * @param string path to directory * @throws Exception */ - public function addFilterDirectory($sDir) + public function addFilterDirectory($sDir) { $sDir = PHP_Beautifier_Common::normalizeDir($sDir); if (file_exists($sDir)) { @@ -408,11 +408,11 @@ public function addFilterDirectory($sDir) * Return an array with all the Filter Dirs * @return array List of Filter Directories */ - public function getFilterDirectories() + public function getFilterDirectories() { return $this->aFilterDirs; } - private function addFilterObject(PHP_Beautifier_Filter $oFilter) + private function addFilterObject(PHP_Beautifier_Filter $oFilter) { array_unshift($this->aFilters, $oFilter); return true; @@ -426,7 +426,7 @@ private function addFilterObject(PHP_Beautifier_Filter $oFilter) * @return bool true if Filter is loaded, false if the same filter was loaded previously * @throws Exception */ - public function addFilter($mFilter, $aSettings = array()) + public function addFilter($mFilter, $aSettings = array()) { if ($mFilter instanceOf PHP_Beautifier_Filter) { return $this->addFilterObject($mFilter); @@ -450,7 +450,7 @@ public function addFilter($mFilter, $aSettings = array()) * @param string name of the filter * @return bool true if Filter is removed, false otherwise */ - public function removeFilter($sFilter) + public function removeFilter($sFilter) { $sFilterName = strtolower('PHP_Beautifier_Filter_' . $sFilter); foreach($this->aFilters as $sId => $oFilter) { @@ -467,7 +467,7 @@ public function removeFilter($sFilter) * @param string name of the filter * @return mixed string or false */ - public function getFilterDescription($sFilter) + public function getFilterDescription($sFilter) { $aFilters = $this->getFilterListTotal(); if (in_array($sFilter, $aFilters)) { @@ -487,7 +487,7 @@ public function getFilterDescription($sFilter) * @return bool * @throws Exception */ - private function addFilterFile($sFilter) + private function addFilterFile($sFilter) { $sFilterClass = 'PHP_Beautifier_Filter_' . $sFilter; if (class_exists($sFilterClass)) { @@ -510,7 +510,7 @@ private function addFilterFile($sFilter) * Get the names of the loaded filters * @return array list of Filters */ - public function getFilterList() + public function getFilterList() { foreach($this->aFilters as $oFilter) { $aOut[] = $oFilter->getName(); @@ -521,7 +521,7 @@ public function getFilterList() * Get the list of all available Filters in all the include Dirs * @return array list of Filters */ - public function getFilterListTotal() + public function getFilterListTotal() { $aFilterFiles = array(); foreach($this->aFilterDirs as $sDir) { @@ -538,20 +538,20 @@ public function getFilterListTotal() /** * Receive a path to a filter and replace it with the name of filter */ - private function getFilterList_FilterName(&$sFile) + private function getFilterList_FilterName(&$sFile) { preg_match("/\/([^\/]*?)\.filter\.php/", $sFile, $aMatch); $sFile = $aMatch[1]; } - public function getIndentChar() + public function getIndentChar() { return $this->sIndentChar; } - public function getIndentNumber() + public function getIndentNumber() { return $this->iIndentNumber; } - public function getNewLine() + public function getNewLine() { return $this->sNewLine; } @@ -559,7 +559,7 @@ public function getNewLine() * Character used for indentation * @param string usually ' ' or "\t" */ - public function setIndentChar($sChar) + public function setIndentChar($sChar) { $this->sIndentChar = $sChar; } @@ -567,7 +567,7 @@ public function setIndentChar($sChar) * Number of characters for indentation * @param int ussualy 4 for space or 1 for tabs */ - public function setIndentNumber($iIndentNumber) + public function setIndentNumber($iIndentNumber) { $this->iIndentNumber = $iIndentNumber; } @@ -575,7 +575,7 @@ public function setIndentNumber($iIndentNumber) * Character used as a new line * @param string ussualy "\n", "\r\n" or "\r" */ - public function setNewLine($sNewLine) + public function setNewLine($sNewLine) { $this->sNewLine = $sNewLine; } @@ -584,7 +584,7 @@ public function setNewLine($sNewLine) * @param string path to file * @throws Exception */ - public function setInputFile($sFile) + public function setInputFile($sFile) { $bCli = (php_sapi_name() == 'cli'); if (strpos($sFile, '://') === FALSE and !file_exists($sFile) and !($bCli and $sFile == STDIN)) { @@ -610,7 +610,7 @@ public function setInputFile($sFile) * Set the output file for beautify * @param string path to file */ - public function setOutputFile($sFile) + public function setOutputFile($sFile) { $this->sOutputFile = $sFile; } @@ -620,7 +620,7 @@ public function setOutputFile($sFile) * @see setOutputFile(); * @throws Exception */ - public function save($sFile = null) + public function save($sFile = null) { $bCli = (php_sapi_name() == 'cli'); if (!$sFile) { @@ -646,14 +646,14 @@ public function save($sFile = null) * Set a string for beautify * @param string Must be preceded by open tag */ - public function setInputString($sText) + public function setInputString($sText) { $this->sText = $sText; } /** * Reset all properties */ - private function resetProperties() + private function resetProperties() { $aProperties = array( 'aTokens' => array() , @@ -683,7 +683,7 @@ private function resetProperties() * @return bool true on success * @throws Exception */ - public function process() + public function process() { $this->oLog->log('Init process of ' . (($this->sInputFile) ? 'file ' . $this->sInputFile : 'string') , PEAR_LOG_DEBUG); $this->resetProperties(); @@ -774,7 +774,7 @@ public function process() * @param int token number * @return mixed false array or false if token doesn't exists */ - public function getTokenAssoc($iIndex) + public function getTokenAssoc($iIndex) { return (array_key_exists($iIndex, $this->aAssocs)) ? $this->aAssocs[$iIndex] : false; } @@ -783,7 +783,7 @@ public function getTokenAssoc($iIndex) * @param int token number * @return mixed string or false if token doesn't exists */ - public function getTokenAssocText($iIndex) + public function getTokenAssocText($iIndex) { if (!($aAssoc = $this->getTokenAssoc($iIndex))) { return false; @@ -796,7 +796,7 @@ public function getTokenAssocText($iIndex) * @param string replace text * @return bool */ - public function replaceTokenAssoc($iIndex, $sText) + public function replaceTokenAssoc($iIndex, $sText) { if (!($aAssoc = $this->getTokenAssoc($iIndex))) { return false; @@ -812,7 +812,7 @@ public function replaceTokenAssoc($iIndex, $sText) * @param mixed token constant or string * @return mixed name of function or false */ - public function getTokenFunction($sTokenType) + public function getTokenFunction($sTokenType) { return (array_key_exists($sTokenType, $this->aTokenFunctions)) ? strtolower($this->aTokenFunctions[$sTokenType]) : false; } @@ -822,7 +822,7 @@ public function getTokenFunction($sTokenType) * @return bool * @uses controlToken() */ - private function processCallback($aMatch) + private function processCallback($aMatch) { if (stristr('php_beautifier', $aMatch[1]) and method_exists($this, $aMatch[3])) { if (preg_match("/^(set|add)/i", $aMatch[3]) and !stristr('file', $aMatch[3])) { @@ -843,7 +843,7 @@ private function processCallback($aMatch) * Assign value for some variables with the information of the token * @param array current token */ - private function controlToken($aCurrentToken) + private function controlToken($aCurrentToken) { // is a control structure opener? if (in_array($aCurrentToken[0], $this->aControlStructures)) { @@ -922,7 +922,7 @@ private function controlToken($aCurrentToken) * Assign value for some variables with the information of the token, after processing * @param array current token */ - private function controlTokenPost($aCurrentToken) + private function controlTokenPost($aCurrentToken) { switch ($aCurrentToken[0]) { case ')': @@ -960,7 +960,7 @@ private function controlTokenPost($aCurrentToken) * Push a control construct to the stack * @param array current token */ - private function pushControlSeq($aToken) + private function pushControlSeq($aToken) { $this->oLog->log('Push Control:' . $aToken[0] . "->" . $aToken[1], PEAR_LOG_DEBUG); array_push($this->aControlSeq, $aToken[0]); @@ -969,7 +969,7 @@ private function pushControlSeq($aToken) * Pop a control construct from the stack * @return int token constant */ - private function popControlSeq() + private function popControlSeq() { $aEl = array_pop($this->aControlSeq); $this->oLog->log('Pop Control:' . $this->getTokenName($aEl) , PEAR_LOG_DEBUG); @@ -978,7 +978,7 @@ private function popControlSeq() /** * Push a new Control Instruction on the stack */ - private function pushControlParenthesis() + private function pushControlParenthesis() { $iPrevious = $this->getPreviousTokenConstant(); $this->oLog->log("Push Parenthesis: $iPrevious ->" . $this->getPreviousTokenContent() , PEAR_LOG_DEBUG); @@ -988,7 +988,7 @@ private function pushControlParenthesis() * Pop the last Control instruction for parenthesis from the stack * @return int constant */ - private function popControlParenthesis() + private function popControlParenthesis() { $iPop = array_pop($this->aControlParenthesis); $this->oLog->log('Pop Parenthesis:' . $iPop, PEAR_LOG_DEBUG); @@ -998,7 +998,7 @@ private function popControlParenthesis() * Set the filetype * @param string */ - public function setFileType($sType) + public function setFileType($sType) { $this->sFileType = $sType; } @@ -1006,14 +1006,14 @@ public function setFileType($sType) * Set the Beautifier on or off * @param bool */ - public function setBeautify($sFlag) + public function setBeautify($sFlag) { $this->bBeautify = (bool)$sFlag; } /** * Show the beautified code */ - public function show() + public function show() { echo $this->get(); } @@ -1026,7 +1026,7 @@ public function show() * @see removeWhitespace() * @see PHP_Beautifier_Filter_NewLines */ - function setNoDeletePreviousSpaceHack($bFlag = true) + function setNoDeletePreviousSpaceHack($bFlag = true) { $this->bNdps = $bFlag; } @@ -1035,7 +1035,7 @@ function setNoDeletePreviousSpaceHack($bFlag = true) * @see setNoDeletePreviousSpaceHack() * @return string */ - public function get() + public function get() { if (!$this->bNdps) { return implode('', $this->aOut); @@ -1048,7 +1048,7 @@ public function get() * @param string Name of the setting * @return mixed Value of the settings or false */ - public function getSetting($sKey) + public function getSetting($sKey) { return (array_key_exists($sKey, $this->aSettings)) ? $this->aSettings[$sKey] : false; } @@ -1057,7 +1057,7 @@ public function getSetting($sKey) * @param int current token -'x' *@ return mixed token constant or false */ - public function getControlSeq($iRet = 0) + public function getControlSeq($iRet = 0) { $iIndex = count($this->aControlSeq) -$iRet-1; return ($iIndex >= 0) ? $this->aControlSeq[$iIndex] : false; @@ -1067,7 +1067,7 @@ public function getControlSeq($iRet = 0) * @param int current token -'x' * @return mixed token constant or false */ - public function getControlParenthesis($iRet = 0) + public function getControlParenthesis($iRet = 0) { $iIndex = count($this->aControlParenthesis) -$iRet-1; return ($iIndex >= 0) ? $this->aControlParenthesis[$iIndex] : false; @@ -1075,12 +1075,12 @@ public function getControlParenthesis($iRet = 0) //// // Mode methods //// - + /** * Set a mode to true * @param string name of the mode */ - public function setMode($sKey) + public function setMode($sKey) { $this->aModes[$sKey] = true; } @@ -1088,7 +1088,7 @@ public function setMode($sKey) * Set a mode to false * @param string name of the mode */ - public function unsetMode($sKey) + public function unsetMode($sKey) { $this->aModes[$sKey] = false; } @@ -1097,19 +1097,19 @@ public function unsetMode($sKey) * @param string name of the mode * @return bool */ - public function getMode($sKey) + public function getMode($sKey) { return array_key_exists($sKey, $this->aModes) ? $this->aModes[$sKey] : false; } ///// // Filter methods ///// - + /** * Add a string to the output * @param string */ - public function add($token) + public function add($token) { $this->aOut[] = $token; } @@ -1118,7 +1118,7 @@ public function add($token) * @param int number of outputs to drop * @deprecated */ - public function pop($iReps = 1) + public function pop($iReps = 1) { for ($x = 0 ; $x < $iReps ; $x++) { $sLast = array_pop($this->aOut); @@ -1131,7 +1131,7 @@ public function pop($iReps = 1) * @see $iIndentNumber * @see $iIndent */ - public function addIndent() + public function addIndent() { $this->aOut[] = str_repeat($this->sIndentChar, $this->iIndent); } @@ -1140,7 +1140,7 @@ public function addIndent() * You could use this to put a standard comment after some sentences * or to add extra newlines */ - public function setBeforeNewLine($sText) + public function setBeforeNewLine($sText) { $this->sBeforeNewLine = $sText; } @@ -1148,7 +1148,7 @@ public function setBeforeNewLine($sText) * Add a new line to the output * @see $sNewLine */ - public function addNewLine() + public function addNewLine() { if (!is_null($this->sBeforeNewLine)) { $this->aOut[] = $this->sBeforeNewLine; @@ -1163,7 +1163,7 @@ public function addNewLine() * @see $iIndent * @see $sNewLine */ - public function addNewLineIndent() + public function addNewLineIndent() { if (!is_null($this->sBeforeNewLine)) { $this->aOut[] = $this->sBeforeNewLine; @@ -1177,7 +1177,7 @@ public function addNewLineIndent() * If param omitted, used {@link iIndentNumber } * @param int increment indent in x chars */ - public function incIndent($iIncr = false) + public function incIndent($iIncr = false) { if (!$iIncr) { $iIncr = $this->iIndentNumber; @@ -1188,7 +1188,7 @@ public function incIndent($iIncr = false) /** * Decrements the indent. */ - public function decIndent() + public function decIndent() { if (count($this->aIndentStack > 1)) { $iLastIndent = array_pop($this->aIndentStack); @@ -1200,13 +1200,13 @@ public function decIndent() // Methods to lookup previous, next tokens //// // - + /** * Get the 'x' significant (non whitespace)previous token * @param int current-x token * @return mixed array or false */ - private function getPreviousToken($iPrev = 1) + private function getPreviousToken($iPrev = 1) { for ($x = $this->iCount-1 ; $x >= 0 ; $x--) { $aToken = &$this->getToken($x); @@ -1223,7 +1223,7 @@ private function getPreviousToken($iPrev = 1) * @param int current+x token * @return array */ - private function getNextToken($iNext = 1) + private function getNextToken($iNext = 1) { for ($x = $this->iCount+1 ; $x < (count($this->aTokens) -1) ; $x++) { $aToken = &$this->getToken($x); @@ -1240,7 +1240,7 @@ private function getNextToken($iNext = 1) * @param mixed int (constant) or array of constants * @return bool */ - public function isPreviousTokenConstant($mValue, $iPrev = 1) + public function isPreviousTokenConstant($mValue, $iPrev = 1) { if (!is_array($mValue)) { $mValue = array( @@ -1255,7 +1255,7 @@ public function isPreviousTokenConstant($mValue, $iPrev = 1) * @param mixed string (content) or array of contents * @return bool */ - public function isPreviousTokenContent($mValue, $iPrev = 1) + public function isPreviousTokenContent($mValue, $iPrev = 1) { if (!is_array($mValue)) { $mValue = array( @@ -1270,7 +1270,7 @@ public function isPreviousTokenContent($mValue, $iPrev = 1) * @param mixed int (constant) or array of constants * @return bool */ - public function isNextTokenConstant($mValue, $iPrev = 1) + public function isNextTokenConstant($mValue, $iPrev = 1) { if (!is_array($mValue)) { $mValue = array( @@ -1285,7 +1285,7 @@ public function isNextTokenConstant($mValue, $iPrev = 1) * @param mixed string (content) or array of contents * @return bool */ - public function isNextTokenContent($mValue, $iPrev = 1) + public function isNextTokenContent($mValue, $iPrev = 1) { if (!is_array($mValue)) { $mValue = array( @@ -1300,7 +1300,7 @@ public function isNextTokenContent($mValue, $iPrev = 1) * @param int current-x token * @return int */ - public function getPreviousTokenConstant($iPrev = 1) + public function getPreviousTokenConstant($iPrev = 1) { $sToken = $this->getPreviousToken($iPrev); return $sToken[0]; @@ -1310,12 +1310,12 @@ public function getPreviousTokenConstant($iPrev = 1) * @param int current-x token * @return string */ - public function getPreviousTokenContent($iPrev = 1) + public function getPreviousTokenContent($iPrev = 1) { $mToken = $this->getPreviousToken($iPrev); return (is_string($mToken)) ? $mToken : $mToken[1]; } - public function getNextTokenNonCommentConstant($iPrev = 1) + public function getNextTokenNonCommentConstant($iPrev = 1) { do { $aToken = $this->getNextToken($iPrev); @@ -1329,7 +1329,7 @@ public function getNextTokenNonCommentConstant($iPrev = 1) * @param int current+x token * @return int */ - public function getNextTokenConstant($iPrev = 1) + public function getNextTokenConstant($iPrev = 1) { $sToken = $this->getNextToken($iPrev); return $sToken[0]; @@ -1339,7 +1339,7 @@ public function getNextTokenConstant($iPrev = 1) * @param int current+x token * @return int */ - public function getNextTokenContent($iNext = 1) + public function getNextTokenContent($iNext = 1) { $mToken = $this->getNextToken($iNext); return (is_string($mToken)) ? $mToken : $mToken[1]; @@ -1352,7 +1352,7 @@ public function getNextTokenContent($iNext = 1) * @todo implements a more economic way to handle this. * @return string previous whitespace */ - public function getPreviousWhitespace() + public function getPreviousWhitespace() { $sWhiteSpace = ''; for ($x = $this->iCount-1 ; $x >= 0 ; $x--) { @@ -1383,7 +1383,7 @@ public function getPreviousWhitespace() * (don't remove ws) * true anything else. */ - public function removeWhitespace() + public function removeWhitespace() { // if the previous token was // - a short comment @@ -1414,7 +1414,7 @@ public function removeWhitespace() * @param int number of the token * @return array */ - public function &getToken($iIndex) + public function &getToken($iIndex) { if ($iIndex < 0 or $iIndex > count($this->aTokens)) { return false; diff --git a/_ORIGINAL_/PHP/Beautifier.php b/_ORIGINAL_/PHP/Beautifier.php new file mode 100644 index 000000000000..d82c9bd8632b --- /dev/null +++ b/_ORIGINAL_/PHP/Beautifier.php @@ -0,0 +1,1429 @@ + + * @copyright 2004-2006 Claudio Bustos + * @link http://pear.php.net/package/PHP_Beautifier + * @link http://beautifyphp.sourceforge.net + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version CVS: $Id:$ + */ +error_reporting(E_ALL); +// Before all, test the tokenizer extension +if (!extension_loaded('tokenizer')) { + throw new Exception("Compile php with tokenizer extension. Use --enable-tokenizer or don't use --disable-all on configure."); +} +include_once 'PEAR.php'; +include_once 'PEAR/Exception.php'; +/** + * Require PHP_Beautifier_Filter + */ +include_once 'Beautifier/Filter.php'; +/** + * Require PHP_Beautifier_Filter_Default + */ +include_once 'Beautifier/Filter/Default.filter.php'; +/** + * Require PHP_Beautifier_Common + */ +include_once 'Beautifier/Common.php'; +/** + * Require Log + */ +include_once 'Log.php'; +/** + * Require Exceptions + */ +include_once 'Beautifier/Exception.php'; +/** + * Require StreamWrapper + */ +include_once 'Beautifier/StreamWrapper.php'; +/** + * PHP_Beautifier + * + * Class to beautify php code + * How to use: + * # Create a instance of the object + * # Define the input and output files + * # Optional: Set one or more Filter. They are processed in LIFO order (last in, first out) + * # Process the file + * # Get it, save it or show it. + * + * + * $oToken = new PHP_Beautifier(); // create a instance + * $oToken->addFilter('ArraySimple'); + * $oToken->addFilter('ListClassFunction'); // add one or more filters + * $oToken->setInputFile(__FILE__); // nice... process the same file + * $oToken->process(); // required + * $oToken->show(); + * + * @todo create a web interface. + * @category PHP + * @package PHP_Beautifier + * @author Claudio Bustos + * @copyright 2004-2006 Claudio Bustos + * @link http://pear.php.net/package/PHP_Beautifier + * @link http://beautifyphp.sourceforge.net + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version Release: 0.1.14 + */ +class PHP_Beautifier implements PHP_Beautifier_Interface +{ + // public + + /** + * Tokens created by the tokenizer + * @var array + */ + public $aTokens = array(); + /** + * Tokens codes assigned to method on Filter + * @var array + */ + public $aTokenFunctions = array(); + /** + * Token Names + * @var array + */ + public $aTokenNames = Array(); + /** + * Stores the output + * @var array + */ + public $aOut = array(); + /** + * Contains the assigment of modes + * @var array + * @see setMode() + * @see unsetMode() + * @see getMode() + */ + public $aModes = array(); + /** + * List of availables modes + * @var array + */ + public $aModesAvailable = array( + 'ternary_operator', + 'double_quote' + ); + /** + * Settings for the class + * @var array + */ + public $aSettings = array(); + /** + * Index of current token + * @var int + */ + public $iCount = 0; + /** + * Chars for indentation + * @var int + */ + public $iIndentNumber = 4; + /** + * Level of array nesting + * @var int + */ + public $iArray = 0; + /** + * Level of ternary operator nesting + * @var int + */ + public $iTernary = 0; + /** + * Level of parenthesis nesting + * @var int + */ + public $iParenthesis = 0; + /** + * Level of verbosity (debug) + * @var int + */ + public $iVerbose = false; + /** + * Name of input file + * @var string + */ + public $sInputFile = ''; + /** + * Name of output file + * @var string + */ + public $sOutputFile = ''; + /** + * Type of newline + * @var string + */ + public $sNewLine = PHP_EOL; + /** + * Type of whitespace to use for indent + * @var string + */ + public $sIndentChar = ' '; + /** + * Save the last whitespace used. Use only for Filter! (i miss friends of C++ :( ) + * @var string + */ + public $currentWhitespace = ''; + /** + * Association $aTokens=>$aOut + * @var string + */ + public $aAssocs = array(); + // private + + /** + * type of file + */ + private $sFileType = 'php'; + /** + * Chars of indent + * @var int + */ + private $iIndent = 0; + /** + * @var int + */ + private $aIndentStack = array(); + /** Text to beautify */ + private $sText = ''; + /** Constant for last Control */ + private $iControlLast; + /** References to PHP_Beautifier_Filter's */ + private $aFilters = array(); + /** + * Stack with control construct + */ + private $aControlSeq = array(); + /** + * List of construct that start control structures + */ + private $aControlStructures = array(); + /** + * List of Control for parenthesis + */ + private $aControlParenthesis = array(); + /** + * List of construct that end control structures + */ + private $aControlStructuresEnd = array(); + /** Dirs for Filters */ + private $aFilterDirs = array(); + /** Flag for beautify/no beautify mode */ + private $bBeautify = true; + /** Log */ + private $oLog; + /** Before new line holder */ + private $sBeforeNewLine = null; + /** Activate or deactivate 'no delete previous space' */ + private $bNdps = false; + // Methods + + /** + * Constructor. + * Assing values to {@link $aControlStructures},{@link $aControlStructuresEnd}, + * {@link $aTokenFunctions} + */ + public function __construct() + { + $this->aControlStructures = array( + T_CLASS, + T_FUNCTION, + T_IF, + T_ELSE, + T_ELSEIF, + T_WHILE, + T_DO, + T_FOR, + T_FOREACH, + T_SWITCH, + T_DECLARE, + T_TRY, + T_CATCH + ); + $this->aControlStructuresEnd = array( + T_ENDWHILE, + T_ENDFOREACH, + T_ENDFOR, + T_ENDDECLARE, + T_ENDSWITCH, + T_ENDIF + ); + $aPreTokens = preg_grep('/^T_/', array_keys(get_defined_constants())); + foreach($aPreTokens as $sToken) { + $this->aTokenNames[constant($sToken) ] = $sToken; + $this->aTokenFunctions[constant($sToken) ] = $sToken; + } + $aTokensToChange = array( + /* QUOTES */ + '"' => "T_DOUBLE_QUOTE", + "'" => "T_SINGLE_QUOTE", + /* PUNCTUATION */ + '(' => 'T_PARENTHESIS_OPEN', + ')' => 'T_PARENTHESIS_CLOSE', + ';' => 'T_SEMI_COLON', + '{' => 'T_OPEN_BRACE', + '}' => 'T_CLOSE_BRACE', + ',' => 'T_COMMA', + '?' => 'T_QUESTION', + ':' => 'T_COLON', + '=' => 'T_ASSIGMENT', + '<' => 'T_EQUAL', + '>' => 'T_EQUAL', + '.' => 'T_DOT', + '[' => 'T_OPEN_SQUARE_BRACE', + ']' => 'T_CLOSE_SQUARE_BRACE', + /* OPERATOR*/ + '+' => 'T_OPERATOR', + '-' => 'T_OPERATOR', + '*' => 'T_OPERATOR', + '/' => 'T_OPERATOR', + '%' => 'T_OPERATOR', + '&' => 'T_OPERATOR', + '|' => 'T_OPERATOR', + '^' => 'T_OPERATOR', + '~' => 'T_OPERATOR', + T_SL => 'T_OPERATOR', + T_SR => 'T_OPERATOR', + T_OBJECT_OPERATOR => 'T_OBJECT_OPERATOR', + /* INCLUDE */ + T_INCLUDE => 'T_INCLUDE', + T_INCLUDE_ONCE => 'T_INCLUDE', + T_REQUIRE => 'T_INCLUDE', + T_REQUIRE_ONCE => 'T_INCLUDE', + /* LANGUAGE CONSTRUCT */ + T_FUNCTION => 'T_LANGUAGE_CONSTRUCT', + T_PRINT => 'T_LANGUAGE_CONSTRUCT', + T_RETURN => 'T_LANGUAGE_CONSTRUCT', + T_ECHO => 'T_LANGUAGE_CONSTRUCT', + T_NEW => 'T_LANGUAGE_CONSTRUCT', + T_CLASS => 'T_LANGUAGE_CONSTRUCT', + T_VAR => 'T_LANGUAGE_CONSTRUCT', + T_GLOBAL => 'T_LANGUAGE_CONSTRUCT', + T_THROW => 'T_LANGUAGE_CONSTRUCT', + /* CONTROL */ + T_IF => 'T_CONTROL', + T_DO => 'T_CONTROL', + T_WHILE => 'T_CONTROL', + T_SWITCH => 'T_CONTROL', + /* ELSE */ + T_ELSEIF => 'T_ELSE', + T_ELSE => 'T_ELSE', + /* ACCESS PHP 5 */ + T_INTERFACE => 'T_ACCESS', + T_FINAL => 'T_ACCESS', + T_ABSTRACT => 'T_ACCESS', + T_PRIVATE => 'T_ACCESS', + T_PUBLIC => 'T_ACCESS', + T_PROTECTED => 'T_ACCESS', + T_CONST => 'T_ACCESS', + T_STATIC => 'T_ACCESS', + /* COMPARATORS */ + T_PLUS_EQUAL => 'T_ASSIGMENT_PRE', + T_MINUS_EQUAL => 'T_ASSIGMENT_PRE', + T_MUL_EQUAL => 'T_ASSIGMENT_PRE', + T_DIV_EQUAL => 'T_ASSIGMENT_PRE', + T_CONCAT_EQUAL => 'T_ASSIGMENT_PRE', + T_MOD_EQUAL => 'T_ASSIGMENT_PRE', + T_AND_EQUAL => 'T_ASSIGMENT_PRE', + T_OR_EQUAL => 'T_ASSIGMENT_PRE', + T_XOR_EQUAL => 'T_ASSIGMENT_PRE', + T_DOUBLE_ARROW => 'T_ASSIGMENT', + T_SL_EQUAL => 'T_EQUAL', + T_SR_EQUAL => 'T_EQUAL', + T_IS_EQUAL => 'T_EQUAL', + T_IS_NOT_EQUAL => 'T_EQUAL', + T_IS_IDENTICAL => 'T_EQUAL', + T_IS_NOT_IDENTICAL => 'T_EQUAL', + T_IS_SMALLER_OR_EQUAL => 'T_EQUAL', + T_IS_GREATER_OR_EQUAL => 'T_EQUAL', + /* LOGICAL*/ + T_LOGICAL_OR => 'T_LOGICAL', + T_LOGICAL_XOR => 'T_LOGICAL', + T_LOGICAL_AND => 'T_LOGICAL', + T_BOOLEAN_OR => 'T_LOGICAL', + T_BOOLEAN_AND => 'T_LOGICAL', + /* SUFIX END */ + T_ENDWHILE => 'T_END_SUFFIX', + T_ENDFOREACH => 'T_END_SUFFIX', + T_ENDFOR => 'T_END_SUFFIX', + T_ENDDECLARE => 'T_END_SUFFIX', + T_ENDSWITCH => 'T_END_SUFFIX', + T_ENDIF => 'T_END_SUFFIX', + ); + foreach($aTokensToChange as $iToken => $sFunction) { + $this->aTokenFunctions[$iToken] = $sFunction; + } + $this->addFilterDirectory(dirname(__FILE__) . '/Beautifier/Filter'); + $this->addFilter('Default'); + $this->oLog = PHP_Beautifier_Common::getLog(); + } + public function getTokenName($iToken) + { + if(!$iToken) { + throw new Exception("Token $iToken doesn't exists"); + } + return $this->aTokenNames[$iToken]; + } + /** + * Start the log for debug + * @param string filename + * @param int debug level. See {@link Log} + */ + public function startLog($sFile = 'php_beautifier.log', $iLevel = PEAR_LOG_DEBUG) + { + @unlink($sFile); + $oLogFile = Log::factory('file', $sFile, 'php_beautifier', array() , PEAR_LOG_DEBUG); + $this->oLog->addChild($oLogFile); + } + /** + * Add a filter directory + * @param string path to directory + * @throws Exception + */ + public function addFilterDirectory($sDir) + { + $sDir = PHP_Beautifier_Common::normalizeDir($sDir); + if (file_exists($sDir)) { + array_push($this->aFilterDirs, $sDir); + } else { + throw new Exception_PHP_Beautifier_Filter("Path '$sDir' doesn't exists"); + } + } + /** + * Return an array with all the Filter Dirs + * @return array List of Filter Directories + */ + public function getFilterDirectories() + { + return $this->aFilterDirs; + } + private function addFilterObject(PHP_Beautifier_Filter $oFilter) + { + array_unshift($this->aFilters, $oFilter); + return true; + } + /** + * Add a Filter to the Beautifier + * The first argument is the name of the file of the Filter. + * @tutorial PHP_Beautifier/Filter/Filter2.pkg#use + * @param string name of the Filter + * @param array settings for the Filter + * @return bool true if Filter is loaded, false if the same filter was loaded previously + * @throws Exception + */ + public function addFilter($mFilter, $aSettings = array()) + { + if ($mFilter instanceOf PHP_Beautifier_Filter) { + return $this->addFilterObject($mFilter); + } + $sFilterClass = 'PHP_Beautifier_Filter_' . $mFilter; + if (!class_exists($sFilterClass)) { + $this->addFilterFile($mFilter); + } + $oTemp = new $sFilterClass($this, $aSettings); + // verify if same Filter is loaded + if (in_array($oTemp, $this->aFilters, TRUE)) { + return false; + } elseif ($oTemp instanceof PHP_Beautifier_Filter) { + $this->addFilterObject($oTemp); + } else { + throw new Exception_PHP_Beautifier_Filter("'$sFilterClass' isn't a subclass of 'Filter'"); + } + } + /** + * Removes a Filter + * @param string name of the filter + * @return bool true if Filter is removed, false otherwise + */ + public function removeFilter($sFilter) + { + $sFilterName = strtolower('PHP_Beautifier_Filter_' . $sFilter); + foreach($this->aFilters as $sId => $oFilter) { + if (strtolower(get_class($oFilter)) == $sFilterName) { + unset($this->aFilters[$sId]); + return true; + } + } + return false; + } + /** + * Return the Filter Description + * @see PHP_Beautifier_Filter::__toString(); + * @param string name of the filter + * @return mixed string or false + */ + public function getFilterDescription($sFilter) + { + $aFilters = $this->getFilterListTotal(); + if (in_array($sFilter, $aFilters)) { + $this->addFilterFile($sFilter); + $sFilterClass = 'PHP_Beautifier_Filter_' . $sFilter; + $oTemp = new $sFilterClass($this, array()); + return $oTemp; + } else { + return false; + } + } + /** + * Add a new filter to the processor. + * The system will process the filter in LIFO order + * @param string name of filter + * @see process() + * @return bool + * @throws Exception + */ + private function addFilterFile($sFilter) + { + $sFilterClass = 'PHP_Beautifier_Filter_' . $sFilter; + if (class_exists($sFilterClass)) { + return true; + } + foreach($this->aFilterDirs as $sDir) { + $sFile = $sDir . $sFilter . '.filter.php'; + if (file_exists($sFile)) { + include_once $sFile; + if (class_exists($sFilterClass)) { + return true; + } else { + throw new Exception_PHP_Beautifier_Filter("File '$sFile' exists,but doesn't exists filter '$sFilterClass'"); + } + } + } + throw new Exception_PHP_Beautifier_Filter("Doesn't exists filter '$sFilter'"); + } + /** + * Get the names of the loaded filters + * @return array list of Filters + */ + public function getFilterList() + { + foreach($this->aFilters as $oFilter) { + $aOut[] = $oFilter->getName(); + } + return $aOut; + } + /** + * Get the list of all available Filters in all the include Dirs + * @return array list of Filters + */ + public function getFilterListTotal() + { + $aFilterFiles = array(); + foreach($this->aFilterDirs as $sDir) { + $aFiles = PHP_Beautifier_Common::getFilesByPattern($sDir, ".*?\.filter\.php"); + array_walk($aFiles, array( + $this, + 'getFilterList_FilterName' + )); + $aFilterFiles = array_merge($aFilterFiles, $aFiles); + } + sort($aFilterFiles); + return $aFilterFiles; + } + /** + * Receive a path to a filter and replace it with the name of filter + */ + private function getFilterList_FilterName(&$sFile) + { + preg_match("/\/([^\/]*?)\.filter\.php/", $sFile, $aMatch); + $sFile = $aMatch[1]; + } + public function getIndentChar() + { + return $this->sIndentChar; + } + public function getIndentNumber() + { + return $this->iIndentNumber; + } + public function getNewLine() + { + return $this->sNewLine; + } + /** + * Character used for indentation + * @param string usually ' ' or "\t" + */ + public function setIndentChar($sChar) + { + $this->sIndentChar = $sChar; + } + /** + * Number of characters for indentation + * @param int ussualy 4 for space or 1 for tabs + */ + public function setIndentNumber($iIndentNumber) + { + $this->iIndentNumber = $iIndentNumber; + } + /** + * Character used as a new line + * @param string ussualy "\n", "\r\n" or "\r" + */ + public function setNewLine($sNewLine) + { + $this->sNewLine = $sNewLine; + } + /** + * Set the file for beautify + * @param string path to file + * @throws Exception + */ + public function setInputFile($sFile) + { + $bCli = (php_sapi_name() == 'cli'); + if (strpos($sFile, '://') === FALSE and !file_exists($sFile) and !($bCli and $sFile == STDIN)) { + throw new Exception("File '$sFile' doesn't exists"); + } + $this->sText = ''; + $this->sInputFile = $sFile; + $fp = ($bCli and $sFile == STDIN) ? STDIN : fopen($sFile, 'r'); + do { + $data = fread($fp, 8192); + if (strlen($data) == 0) { + break; + } + $this->sText.= $data; + } + while (true); + if (!($bCli and $fp == STDIN)) { + fclose($fp); + } + return true; + } + /** + * Set the output file for beautify + * @param string path to file + */ + public function setOutputFile($sFile) + { + $this->sOutputFile = $sFile; + } + /** + * Save the beautified code to output file + * @param string path to file. If null, {@link $sOutputFile} if exists, throw exception otherwise + * @see setOutputFile(); + * @throws Exception + */ + public function save($sFile = null) + { + $bCli = (php_sapi_name() == 'cli'); + if (!$sFile) { + if (!$this->sOutputFile) { + throw new Exception("Can't save without a output file"); + } else { + $sFile = $this->sOutputFile; + } + } + $sText = $this->get(); + $fp = ($bCli and $sFile == STDOUT) ? STDOUT : @fopen($sFile, "w"); + if (!$fp) { + throw new Exception("Can't save file $sFile"); + } + fputs($fp, $sText, strlen($sText)); + if (!($bCli and $sFile == STDOUT)) { + fclose($fp); + } + $this->oLog->log("Success: $sFile saved", PEAR_LOG_INFO); + return true; + } + /** + * Set a string for beautify + * @param string Must be preceded by open tag + */ + public function setInputString($sText) + { + $this->sText = $sText; + } + /** + * Reset all properties + */ + private function resetProperties() + { + $aProperties = array( + 'aTokens' => array() , + 'aOut' => array() , + 'aModes' => array() , + 'iCount' => 0, + 'iIndent' => 0 + /*$this->iIndentNumber*/ + , + 'aIndentStack' => array( + /*$this->iIndentNumber*/ + ) , + 'iArray' => 0, + 'iParenthesis' => 0, + 'currentWhitespace' => '', + 'aAssocs' => array() , + 'iControlLast' => null, + 'aControlSeq' => array() , + 'bBeautify' => true + ); + foreach($aProperties as $sProperty => $sValue) { + $this->$sProperty = $sValue; + } + } + /** + * Process the string or file to beautify + * @return bool true on success + * @throws Exception + */ + public function process() + { + $this->oLog->log('Init process of ' . (($this->sInputFile) ? 'file ' . $this->sInputFile : 'string') , PEAR_LOG_DEBUG); + $this->resetProperties(); + // if file type is php, use token_get_all + // else, use a class named PHP_Beautifier_Tokenizer_XXX + // instanced with the text and get the tokens with + // getTokens() + if ($this->sFileType == 'php') { + $this->aTokens = token_get_all($this->sText); + } else { + $sClass = 'PHP_Beautifier_Tokeniker_' . ucfirst($this->sFileType); + if (class_exists($sClass)) { + $oTokenizer = new $sClass($this->sText); + $this->aTokens = $oTokenizer->getTokens(); + } else { + throw new Exception("File type " . $this->sFileType . " not implemented"); + } + } + $this->aOut = array(); + $iTotal = count($this->aTokens); + $iPrevAssoc = false; + // Send a signal to the filter, announcing the init of the processing of a file + foreach($this->aFilters as $oFilter) { + $oFilter->preProcess(); + } + for ($this->iCount = 0 ; $this->iCount < $iTotal ; $this->iCount++) { + $aCurrentToken = $this->aTokens[$this->iCount]; + if (is_string($aCurrentToken)) { + $aCurrentToken = array( + 0 => $aCurrentToken, + 1 => $aCurrentToken + ); + } + // ArrayNested->off(); + $sTextLog = PHP_Beautifier_Common::wsToString($aCurrentToken[1]); + // ArrayNested->on(); + $sTokenName = (is_numeric($aCurrentToken[0])) ? token_name($aCurrentToken[0]) : ''; + $this->oLog->log("Token:" . $sTokenName . "[" . $sTextLog . "]", PEAR_LOG_DEBUG); + $this->controlToken($aCurrentToken); + $iFirstOut = count($this->aOut); //5 + $bError = false; + if ($this->bBeautify) { + foreach($this->aFilters as $oFilter) { + $bError = true; + if ($oFilter->handleToken($aCurrentToken) !== FALSE) { + $this->oLog->log('Filter:' . $oFilter->getName() , PEAR_LOG_DEBUG); + $bError = false; + break; + } + } + } else { + $this->add($aCurrentToken[1]); + } + $this->controlTokenPost($aCurrentToken); + $iLastOut = count($this->aOut); + // set the assoc + if (($iLastOut-$iFirstOut) > 0) { + $this->aAssocs[$this->iCount] = array( + 'offset' => $iFirstOut + ); + if ($iPrevAssoc !== FALSE) { + $this->aAssocs[$iPrevAssoc]['length'] = $iFirstOut-$this->aAssocs[$iPrevAssoc]['offset']; + } + $iPrevAssoc = $this->iCount; + } + if ($bError) { + throw new Exception("Can'process token: " . var_dump($aCurrentToken)); + } + } // ~for + // generate the last assoc + if (count($this->aOut) == 0) { + if ($this->sFile) { + throw new Exception("Nothing on output for " . $this->sFile . "!"); + } else { + throw new Exception("Nothing on output!"); + } + } + $this->aAssocs[$iPrevAssoc]['length'] = (count($this->aOut) -1) -$this->aAssocs[$iPrevAssoc]['offset']; + // Post-processing + foreach($this->aFilters as $oFilter) { + $oFilter->postProcess(); + } + $this->oLog->log('End process', PEAR_LOG_DEBUG); + return true; + } + /** + * Get the reference to {@link $aOut}, based on the number of the token + * @param int token number + * @return mixed false array or false if token doesn't exists + */ + public function getTokenAssoc($iIndex) + { + return (array_key_exists($iIndex, $this->aAssocs)) ? $this->aAssocs[$iIndex] : false; + } + /** + * Get the output for the specified token + * @param int token number + * @return mixed string or false if token doesn't exists + */ + public function getTokenAssocText($iIndex) + { + if (!($aAssoc = $this->getTokenAssoc($iIndex))) { + return false; + } + return (implode('', array_slice($this->aOut, $aAssoc['offset'], $aAssoc['length']))); + } + /** + * Replace the output for specified token + * @param int token number + * @param string replace text + * @return bool + */ + public function replaceTokenAssoc($iIndex, $sText) + { + if (!($aAssoc = $this->getTokenAssoc($iIndex))) { + return false; + } + $this->aOut[$aAssoc['offset']] = $sText; + for ($x = 0 ; $x < $aAssoc['length']-1 ; $x++) { + $this->aOut[$aAssoc['offset']+$x+1] = ''; + } + return true; + } + /** + * Return the function for a token constant or string. + * @param mixed token constant or string + * @return mixed name of function or false + */ + public function getTokenFunction($sTokenType) + { + return (array_key_exists($sTokenType, $this->aTokenFunctions)) ? strtolower($this->aTokenFunctions[$sTokenType]) : false; + } + /** + * Process a callback from the code to beautify + * @param array third parameter from preg_match + * @return bool + * @uses controlToken() + */ + private function processCallback($aMatch) + { + if (stristr('php_beautifier', $aMatch[1]) and method_exists($this, $aMatch[3])) { + if (preg_match("/^(set|add)/i", $aMatch[3]) and !stristr('file', $aMatch[3])) { + eval('$this->' . $aMatch[2] . ";"); + return true; + } + } else { + foreach($this->aFilters as $iIndex => $oFilter) { + if (strtolower(get_class($oFilter)) == 'php_beautifier_filter_' . strtolower($aMatch[1]) and method_exists($oFilter, $aMatch[3])) { + eval('$this->aFilters[' . $iIndex . ']->' . $aMatch[2] . ";"); + return true; + } + } + } + return false; + } + /** + * Assign value for some variables with the information of the token + * @param array current token + */ + private function controlToken($aCurrentToken) + { + // is a control structure opener? + if (in_array($aCurrentToken[0], $this->aControlStructures)) { + $this->pushControlSeq($aCurrentToken); + $this->iControlLast = $aCurrentToken[0]; + } + // is a control structure closer? + if (in_array($aCurrentToken[0], $this->aControlStructuresEnd)) { + $this->popControlSeq(); + } + switch ($aCurrentToken[0]) { + case T_COMMENT: + // callback! + if (preg_match("/\/\/\s*(.*?)->((.*)\((.*)\))/", $aCurrentToken[1], $aMatch)) { + try { + $this->processCallback($aMatch); + } + catch(Exception $oExp) { + } + } + break; + + case T_FUNCTION: + $this->setMode('function'); + break; + + case T_CLASS: + $this->setMode('class'); + break; + + case T_ARRAY: + $this->iArray++; + break; + + case T_WHITESPACE: + $this->currentWhitespace = $aCurrentToken[1]; + break; + + case '{': + if ($this->isPreviousTokenConstant(T_VARIABLE) or ($this->isPreviousTokenConstant(T_STRING) and $this->getPreviousTokenConstant(2) == T_OBJECT_OPERATOR) or $this->isPreviousTokenConstant(T_OBJECT_OPERATOR)) { + $this->setMode('string_index'); + } + break; + + case '(': + $this->iParenthesis++; + $this->pushControlParenthesis(); + break; + + case ')': + $this->iParenthesis--; + break; + + case '?': + $this->setMode('ternary_operator'); + $this->iTernary++; + break; + + case '"': + ($this->getMode('double_quote')) ? $this->unsetMode('double_quote') : $this->setMode('double_quote'); + break; + + case T_START_HEREDOC: + $this->setMode('double_quote'); + break; + + case T_END_HEREDOC: + $this->unsetMode('double_quote'); + break; + } + if ($this->getTokenFunction($aCurrentToken[0]) == 't_include') { + $this->setMode('include'); + } + } + /** + * Assign value for some variables with the information of the token, after processing + * @param array current token + */ + private function controlTokenPost($aCurrentToken) + { + switch ($aCurrentToken[0]) { + case ')': + if ($this->iArray) { + $this->iArray--; + } + $this->popControlParenthesis(); + break; + + case '}': + if ($this->getMode('string_index')) { + $this->unsetMode('string_index'); + } else { + $this->oLog->log('end bracket:' . $this->getPreviousTokenContent() , PEAR_LOG_DEBUG); + if ($this->getPreviousTokenContent() == ';' or $this->getPreviousTokenContent() == '}' or $this->getPreviousTokenContent() == '{') { + $this->popControlSeq(); + } + } + break; + + case '{': + $this->unsetMode('function'); + break; + } + if ($this->getTokenFunction($aCurrentToken[0]) == 't_colon') { + if ($this->iTernary) { + $this->iTernary--; + } + if(!$this->iTernary) { + $this->unsetMode('ternary_operator'); + } + } + } + /** + * Push a control construct to the stack + * @param array current token + */ + private function pushControlSeq($aToken) + { + $this->oLog->log('Push Control:' . $aToken[0] . "->" . $aToken[1], PEAR_LOG_DEBUG); + array_push($this->aControlSeq, $aToken[0]); + } + /** + * Pop a control construct from the stack + * @return int token constant + */ + private function popControlSeq() + { + $aEl = array_pop($this->aControlSeq); + $this->oLog->log('Pop Control:' . $this->getTokenName($aEl) , PEAR_LOG_DEBUG); + return $aEl; + } + /** + * Push a new Control Instruction on the stack + */ + private function pushControlParenthesis() + { + $iPrevious = $this->getPreviousTokenConstant(); + $this->oLog->log("Push Parenthesis: $iPrevious ->" . $this->getPreviousTokenContent() , PEAR_LOG_DEBUG); + array_push($this->aControlParenthesis, $iPrevious); + } + /** + * Pop the last Control instruction for parenthesis from the stack + * @return int constant + */ + private function popControlParenthesis() + { + $iPop = array_pop($this->aControlParenthesis); + $this->oLog->log('Pop Parenthesis:' . $iPop, PEAR_LOG_DEBUG); + return $iPop; + } + /** + * Set the filetype + * @param string + */ + public function setFileType($sType) + { + $this->sFileType = $sType; + } + /** + * Set the Beautifier on or off + * @param bool + */ + public function setBeautify($sFlag) + { + $this->bBeautify = (bool)$sFlag; + } + /** + * Show the beautified code + */ + public function show() + { + echo $this->get(); + } + /** + * Activate or deactivate this ominous hack + * If you need to maintain some special whitespace + * you can activate this hack and use (delete the space between * and /) + * /**ndps** / + * in {@link get()}, this text will be erased. + * @see removeWhitespace() + * @see PHP_Beautifier_Filter_NewLines + */ + function setNoDeletePreviousSpaceHack($bFlag = true) + { + $this->bNdps = $bFlag; + } + /** + * Returns the beautified code + * @see setNoDeletePreviousSpaceHack() + * @return string + */ + public function get() + { + if (!$this->bNdps) { + return implode('', $this->aOut); + } else { + return str_replace('/**ndps**/', '', implode('', $this->aOut)); + } + } + /** + * Returns the value of a settings + * @param string Name of the setting + * @return mixed Value of the settings or false + */ + public function getSetting($sKey) + { + return (array_key_exists($sKey, $this->aSettings)) ? $this->aSettings[$sKey] : false; + } + /** + * Get the token constant for the current control construct + * @param int current token -'x' + *@ return mixed token constant or false + */ + public function getControlSeq($iRet = 0) + { + $iIndex = count($this->aControlSeq) -$iRet-1; + return ($iIndex >= 0) ? $this->aControlSeq[$iIndex] : false; + } + /** + * Get the token constant for the current Parenthesis + * @param int current token -'x' + * @return mixed token constant or false + */ + public function getControlParenthesis($iRet = 0) + { + $iIndex = count($this->aControlParenthesis) -$iRet-1; + return ($iIndex >= 0) ? $this->aControlParenthesis[$iIndex] : false; + } + //// + // Mode methods + //// + + /** + * Set a mode to true + * @param string name of the mode + */ + public function setMode($sKey) + { + $this->aModes[$sKey] = true; + } + /** + * Set a mode to false + * @param string name of the mode + */ + public function unsetMode($sKey) + { + $this->aModes[$sKey] = false; + } + /** + * Get the state of a mode + * @param string name of the mode + * @return bool + */ + public function getMode($sKey) + { + return array_key_exists($sKey, $this->aModes) ? $this->aModes[$sKey] : false; + } + ///// + // Filter methods + ///// + + /** + * Add a string to the output + * @param string + */ + public function add($token) + { + $this->aOut[] = $token; + } + /** + * Delete the last added output(s) + * @param int number of outputs to drop + * @deprecated + */ + public function pop($iReps = 1) + { + for ($x = 0 ; $x < $iReps ; $x++) { + $sLast = array_pop($this->aOut); + } + return $sLast; + } + /** + * Add Indent to the output + * @see $sIndentChar + * @see $iIndentNumber + * @see $iIndent + */ + public function addIndent() + { + $this->aOut[] = str_repeat($this->sIndentChar, $this->iIndent); + } + /** + * Set a string to put before a new line + * You could use this to put a standard comment after some sentences + * or to add extra newlines + */ + public function setBeforeNewLine($sText) + { + $this->sBeforeNewLine = $sText; + } + /** + * Add a new line to the output + * @see $sNewLine + */ + public function addNewLine() + { + if (!is_null($this->sBeforeNewLine)) { + $this->aOut[] = $this->sBeforeNewLine; + $this->sBeforeNewLine = null; + } + $this->aOut[] = $this->sNewLine; + } + /** + * Add a new line and a indent to output + * @see $sIndentChar + * @see $iIndentNumber + * @see $iIndent + * @see $sNewLine + */ + public function addNewLineIndent() + { + if (!is_null($this->sBeforeNewLine)) { + $this->aOut[] = $this->sBeforeNewLine; + $this->sBeforeNewLine = null; + } + $this->aOut[] = $this->sNewLine; + $this->aOut[] = str_repeat($this->sIndentChar, $this->iIndent); + } + /** + * Increments the indent in X chars. + * If param omitted, used {@link iIndentNumber } + * @param int increment indent in x chars + */ + public function incIndent($iIncr = false) + { + if (!$iIncr) { + $iIncr = $this->iIndentNumber; + } + array_push($this->aIndentStack, $iIncr); + $this->iIndent+= $iIncr; + } + /** + * Decrements the indent. + */ + public function decIndent() + { + if (count($this->aIndentStack > 1)) { + $iLastIndent = array_pop($this->aIndentStack); + $this->iIndent-= $iLastIndent; + } + } + // + //// + // Methods to lookup previous, next tokens + //// + // + + /** + * Get the 'x' significant (non whitespace)previous token + * @param int current-x token + * @return mixed array or false + */ + private function getPreviousToken($iPrev = 1) + { + for ($x = $this->iCount-1 ; $x >= 0 ; $x--) { + $aToken = &$this->getToken($x); + if ($aToken[0] != T_WHITESPACE) { + $iPrev--; + if (!$iPrev) { + return $aToken; + } + } + } + } + /** + * Get the 'x' significant (non whitespace) next token + * @param int current+x token + * @return array + */ + private function getNextToken($iNext = 1) + { + for ($x = $this->iCount+1 ; $x < (count($this->aTokens) -1) ; $x++) { + $aToken = &$this->getToken($x); + if ($aToken[0] != T_WHITESPACE) { + $iNext--; + if (!$iNext) { + return $aToken; + } + } + } + } + /** + * Return true if any of the constant defined is param 1 is the previous 'x' constant + * @param mixed int (constant) or array of constants + * @return bool + */ + public function isPreviousTokenConstant($mValue, $iPrev = 1) + { + if (!is_array($mValue)) { + $mValue = array( + $mValue + ); + } + $iPrevious = $this->getPreviousTokenConstant($iPrev); + return in_array($iPrevious, $mValue); + } + /** + * Return true if any of the content defined is param 1 is the previous 'x' content + * @param mixed string (content) or array of contents + * @return bool + */ + public function isPreviousTokenContent($mValue, $iPrev = 1) + { + if (!is_array($mValue)) { + $mValue = array( + $mValue + ); + } + $iPrevious = $this->getPreviousTokenContent($iPrev); + return in_array($iPrevious, $mValue); + } + /** + * Return true if any of the constant defined in param 1 is the next 'x' content + * @param mixed int (constant) or array of constants + * @return bool + */ + public function isNextTokenConstant($mValue, $iPrev = 1) + { + if (!is_array($mValue)) { + $mValue = array( + $mValue + ); + } + $iNext = $this->getNextTokenConstant($iPrev); + return in_array($iNext, $mValue); + } + /** + * Return true if any of the content defined is param 1 is the next 'x' content + * @param mixed string (content) or array of contents + * @return bool + */ + public function isNextTokenContent($mValue, $iPrev = 1) + { + if (!is_array($mValue)) { + $mValue = array( + $mValue + ); + } + $iNext = $this->getNextTokenContent($iPrev); + return in_array($iNext, $mValue); + } + /** + * Get the 'x' significant (non whitespace) previous token constant + * @param int current-x token + * @return int + */ + public function getPreviousTokenConstant($iPrev = 1) + { + $sToken = $this->getPreviousToken($iPrev); + return $sToken[0]; + } + /** + * Get the 'x' significant (non whitespace) previous token text + * @param int current-x token + * @return string + */ + public function getPreviousTokenContent($iPrev = 1) + { + $mToken = $this->getPreviousToken($iPrev); + return (is_string($mToken)) ? $mToken : $mToken[1]; + } + public function getNextTokenNonCommentConstant($iPrev = 1) + { + do { + $aToken = $this->getNextToken($iPrev); + $iPrev++; + } + while ($aToken[0] == T_COMMENT); + return $aToken[0]; + } + /** + * Get the 'x' significant (non whitespace) next token constant + * @param int current+x token + * @return int + */ + public function getNextTokenConstant($iPrev = 1) + { + $sToken = $this->getNextToken($iPrev); + return $sToken[0]; + } + /** + * Get the 'x' significant (non whitespace) next token text + * @param int current+x token + * @return int + */ + public function getNextTokenContent($iNext = 1) + { + $mToken = $this->getNextToken($iNext); + return (is_string($mToken)) ? $mToken : $mToken[1]; + } + /** + * Return the whitespace previous to current token + * Ex.: You have + * ' if($a)' + * if you call this funcion on 'if', you get ' ' + * @todo implements a more economic way to handle this. + * @return string previous whitespace + */ + public function getPreviousWhitespace() + { + $sWhiteSpace = ''; + for ($x = $this->iCount-1 ; $x >= 0 ; $x--) { + $this->oLog->log("sp n:$x", PEAR_LOG_DEBUG); + $aToken = $this->getToken($x); + if (is_array($aToken)) { + if ($aToken[0] == T_WHITESPACE) { + $sWhiteSpace.= $aToken[1]; + } elseif (preg_match("/([\s\r\n]+)$/", $aToken[1], $aMatch)) { + $sWhiteSpace.= $aMatch[0]; + // ArrayNested->off(); + $this->oLog->log("+space-token-with-sp:[" . PHP_Beautifier_Common::wsToString($sWhiteSpace) . "]", PEAR_LOG_DEBUG); + // ArrayNested->on(); + return $sWhiteSpace; + } + } else { + $this->oLog->log("+space-token-without-sp:[" . PHP_Beautifier_Common::wsToString($sWhiteSpace) . "]", PEAR_LOG_DEBUG); + return $sWhiteSpace; + } + } + // Strange, but... + $this->oLog->log("+space:[" . PHP_Beautifier_Common::wsToString($sWhiteSpace) . "]", PEAR_LOG_DEBUG); + return $sWhiteSpace; + } + /** + * Remove all whitespace from the previous tag + * @return bool false if previous token was short comment or heredoc + * (don't remove ws) + * true anything else. + */ + public function removeWhitespace() + { + // if the previous token was + // - a short comment + // - heredoc + // don't remove whitespace! + // + if ($this->isPreviousTokenConstant(T_COMMENT) and preg_match("/^(\/\/|#)/", $this->getPreviousTokenContent())) { // Here for short comment + return false; + } elseif ($this->getPreviousTokenConstant(2) == T_END_HEREDOC) { // And here for heredoc + return false; + } + $pop = 0; + for ($i = count($this->aOut) -1 ; $i >= 0 ; $i--) { // go backwards + $cNow = &$this->aOut[$i]; + if (strlen(trim($cNow)) == 0) { // only space + array_pop($this->aOut); // delete it! + $pop++; + } else { // we find something! + $cNow = rtrim($cNow); // rtrim out + break; + } + } + $this->oLog->log("-space $pop", PEAR_LOG_DEBUG); + return true; + } + /** + * Get a token by number + * @param int number of the token + * @return array + */ + public function &getToken($iIndex) + { + if ($iIndex < 0 or $iIndex > count($this->aTokens)) { + return false; + } else { + return $this->aTokens[$iIndex]; + } + } + public function openBraceDontProcess() { + return $this->isPreviousTokenConstant(T_VARIABLE) or $this->isPreviousTokenConstant(T_OBJECT_OPERATOR) or ($this->isPreviousTokenConstant(T_STRING) and $this->getPreviousTokenConstant(2) == T_OBJECT_OPERATOR) or $this->getMode('double_quote'); + } +} +?> \ No newline at end of file