Ejemplo n.º 1
0
 /**
  * Constructor
  *
  * @param Zend_Db_Adapter_Abstract $adapter
  */
 public function __construct(Zend_Db_Adapter_Abstract $adapter = null)
 {
     return parent::__construct($adapter);
 }
Ejemplo n.º 2
0
 /**
  * Converts PHP code into SQL code
  *
  * @param string $phpCode	Code to convert
  * @return string
  */
 private function _convertToSql($phpCode)
 {
     // Some fast cleaning
     $phpCode = str_replace('return ', '', $phpCode);
     $phpCode = str_replace(';', '', $phpCode);
     // Adapter functions
     $adapterFunctions = $this->_adapter->getFunctions();
     // Go parse!
     $tokens = token_get_all('<?php ' . $phpCode . '?>');
     $stack = array();
     $tokenId = 0;
     $depth = 0;
     for ($i = 0; $i < count($tokens); $i++) {
         // Ignore token?
         $ignoreToken = false;
         // Token details
         $previousToken = $i > 0 ? $tokens[$i - 1] : null;
         $token = $tokens[$i];
         $nextToken = $i < count($tokens) - 1 ? $tokens[$i + 1] : null;
         // Parse token
         if (is_array($token)) {
             switch ($token[0]) {
                 case T_OPEN_TAG:
                 case T_CLOSE_TAG:
                     $ignoreToken = true;
                     break;
                 case T_STRING:
                     if (in_array($token[1], $adapterFunctions)) {
                         // It is an adapter function!
                         $stack[$tokenId]['token'] = '$this->_adapter->' . $token[1];
                         $stack[$tokenId]['type'] = self::T_FUNCTION;
                     } else {
                         if (in_array($token[1], self::$_internalFunctions)) {
                             // If it is a PHP function, let's take a lucky
                             // shot and expect the syntax to be the same...
                             $stack[$tokenId]['token'] = $token[1];
                             $stack[$tokenId]['type'] = self::T_FUNCTION;
                         } else {
                             // Probably some sort of constant / property name
                             if (!is_null($previousToken) && is_array($previousToken) && $previousToken[0] == T_OBJECT_OPERATOR) {
                                 $stack[$tokenId]['token'] = $this->_adapter->quoteIdentifier($token[1]) . '\'';
                                 $stack[$tokenId]['type'] = self::T_PROPERTY;
                             } else {
                                 $stack[$tokenId]['token'] = '\'' . $token[1] . '\'';
                                 $stack[$tokenId]['type'] = self::T_CONSTANT;
                             }
                         }
                     }
                     break;
                 case T_VARIABLE:
                     $stack[$tokenId]['token'] = $this->_adapter->quote($token[1]);
                     $stack[$tokenId]['type'] = self::T_VARIABLE;
                     break;
                 case T_OBJECT_OPERATOR:
                     if (!is_null($previousToken) && is_array($previousToken) && $previousToken[0] == T_VARIABLE) {
                         $stack[$tokenId - 1]['token'] = '\'' . addslashes($stack[$tokenId - 1]['token']) . '.';
                         $ignoreToken = true;
                     } else {
                         $stack[$tokenId]['token'] = '\'.\'';
                     }
                     $stack[$tokenId]['type'] = self::T_OBJECT_OPERATOR;
                     break;
                 case T_IS_IDENTICAL:
                 case T_IS_EQUAL:
                     $stack[$tokenId]['token'] = '\' ' . $this->_adapter->operator('=') . ' \'';
                     $stack[$tokenId]['type'] = self::T_OPERATOR;
                     break;
                 case T_IS_NOT_EQUAL:
                 case T_IS_NOT_IDENTICAL:
                     $stack[$tokenId]['token'] = '\' ' . $this->_adapter->operator('!=') . ' \'';
                     $stack[$tokenId]['type'] = self::T_OPERATOR;
                     break;
                 case T_IS_GREATER_OR_EQUAL:
                     $stack[$tokenId]['token'] = '\' ' . $this->_adapter->operator('>=') . ' \'';
                     $stack[$tokenId]['type'] = self::T_OPERATOR;
                     break;
                 case T_IS_SMALLER_OR_EQUAL:
                     $stack[$tokenId]['token'] = '\' ' . $this->_adapter->operator('<=') . ' \'';
                     $stack[$tokenId]['type'] = self::T_OPERATOR;
                     break;
                 case T_BOOLEAN_AND:
                 case T_LOGICAL_AND:
                     $stack[$tokenId]['token'] = '\' ' . $this->_adapter->operand('AND') . ' \'';
                     $stack[$tokenId]['type'] = self::T_OPERAND;
                     break;
                 case T_BOOLEAN_OR:
                 case T_LOGICAL_OR:
                     $stack[$tokenId]['token'] = '\' ' . $this->_adapter->operand('OR') . ' \'';
                     $stack[$tokenId]['type'] = self::T_OPERAND;
                     break;
                 default:
                     $stack[$tokenId]['token'] = '\'' . $token[1] . '\'';
                     $stack[$tokenId]['type'] = self::T_DEFAULT;
                     break;
             }
         } else {
             // Simple token
             if ($token != '(' && $token != ')') {
                 $stack[$tokenId]['token'] = $token;
                 $stack[$tokenId]['type'] = self::T_SIMPLE;
                 if ($token == ',') {
                     $stack[$tokenId]['type'] = self::T_ARGUMENT;
                 } else {
                     if ($token == '+' || $token == '-' || $token == '*' || $token == '/' || $token == '%' || $token == '.') {
                         $stack[$tokenId]['token'] = '\'' . $this->_adapter->operator($token) . '\'';
                         $stack[$tokenId]['type'] = self::T_ARITHMETIC;
                     } else {
                         if ($token == '>' || $token == '<') {
                             $stack[$tokenId]['token'] = '\' ' . $this->_adapter->operator($token) . ' \'';
                             $stack[$tokenId]['type'] = self::T_OPERATOR;
                         }
                     }
                 }
             } else {
                 $stack[$tokenId]['token'] = '';
                 $stack[$tokenId]['type'] = self::T_START_STOP;
             }
         }
         // Token metadata
         if (!$ignoreToken) {
             // Depth
             if (!is_array($token) && $token == '(') {
                 $depth++;
             }
             if (!is_array($token) && $token == ')') {
                 $depth--;
             }
             $stack[$tokenId]['depth'] = $depth;
             // Identifier
             $tokenId++;
         }
     }
     // Display tree
     /*
     foreach ($stack as $node) {
     	for ($i = 0; $i <= $node['depth']; $i++) {
     		echo "| ";
     	}
     	
     	echo $node['type'] . ' - ' . $node['token'] . "\r\n";
     }
     die();
     */
     // Build compilation string
     $compileCode = '';
     $functionDepth = array();
     $depth = 0;
     for ($i = 0; $i < count($stack); $i++) {
         // Token details
         $previousToken = $i > 0 ? $stack[$i - 1] : null;
         $token = $stack[$i];
         $nextToken = $i < count($stack) - 1 ? $stack[$i + 1] : null;
         // Regular token
         if ($token['depth'] == $depth && $token['type'] != self::T_START_STOP) {
             $compileCode .= $token['token'];
         }
         // Start/stop
         if ($token['depth'] > $depth && $token['type'] == self::T_START_STOP && !is_null($previousToken) && $previousToken['type'] == self::T_FUNCTION) {
             $compileCode .= '(';
             $functionDepth[$depth] = self::T_FUNCTION;
         } else {
             if ($token['depth'] < $depth && $token['type'] == self::T_START_STOP && $functionDepth[$token['depth']] == self::T_FUNCTION) {
                 $compileCode .= ')';
             } else {
                 if ($token['depth'] > $depth && $token['type'] == self::T_START_STOP) {
                     $compileCode .= '\'(\'';
                     $functionDepth[$depth] = self::T_START_STOP;
                 } else {
                     if ($token['depth'] < $depth && $token['type'] == self::T_START_STOP) {
                         $compileCode .= '\')\'';
                     }
                 }
             }
         }
         // Next token needs concatenation?
         if (!is_null($nextToken) && $nextToken['type'] != self::T_ARGUMENT) {
             if (!($token['type'] == self::T_FUNCTION && $nextToken['type'] == self::T_START_STOP) && !(!is_null($previousToken) && $previousToken['type'] == self::T_FUNCTION && $token['type'] == self::T_START_STOP) && !($token['type'] == self::T_ARGUMENT) && !(!is_null($nextToken) && $nextToken['type'] == self::T_START_STOP && isset($functionDepth[$nextToken['depth']]) && $functionDepth[$nextToken['depth']] == self::T_FUNCTION) && !($token['type'] == self::T_VARIABLE && !is_null($nextToken) && $nextToken['type'] == self::T_PROPERTY)) {
                 $compileCode .= ' . ';
             }
         }
         // Depth
         if ($token['depth'] < $depth) {
             unset($functionDepth[$token['depth']]);
         }
         $depth = $token['depth'];
     }
     // Compile
     $compileCode = '$compileCode = ' . $compileCode . ';';
     eval($compileCode);
     return $compileCode;
 }