| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 | 
							- <?php
 - 
 - /*
 -  * This file is part of the Doctrine Bundle
 -  *
 -  * The code was originally distributed inside the Symfony framework.
 -  *
 -  * (c) Fabien Potencier <fabien@symfony.com>
 -  * (c) Doctrine Project, Benjamin Eberlei <kontakt@beberlei.de>
 -  *
 -  * For the full copyright and license information, please view the LICENSE
 -  * file that was distributed with this source code.
 -  */
 - 
 - namespace Doctrine\Bundle\DoctrineBundle\Twig;
 - 
 - use Symfony\Component\DependencyInjection\ContainerInterface;
 - 
 - /**
 -  * This class contains the needed functions in order to do the query highlighting
 -  *
 -  * @author Florin Patan <florinpatan@gmail.com>
 -  * @author Christophe Coevoet <stof@notk.org>
 -  */
 - class DoctrineExtension extends \Twig_Extension
 - {
 -     /**
 -      * Number of maximum characters that one single line can hold in the interface
 -      *
 -      * @var int
 -      */
 -     private $maxCharWidth = 100;
 - 
 -     /**
 -      * Define our functions
 -      *
 -      * @return array
 -      */
 -     public function getFilters()
 -     {
 -         return array(
 -             'doctrine_minify_query' => new \Twig_Filter_Method($this, 'minifyQuery'),
 -             'doctrine_pretty_query' => new \Twig_Filter_Function('SqlFormatter::format'),
 -             'doctrine_replace_query_parameters' => new \Twig_Filter_Method($this, 'replaceQueryParameters'),
 -         );
 -     }
 - 
 -     /**
 -      * Get the possible combinations of elements from the given array
 -      *
 -      * @param array $elements
 -      * @param integer $combinationsLevel
 -      *
 -      * @return array
 -      */
 -     private function getPossibleCombinations($elements, $combinationsLevel)
 -     {
 -         $baseCount = count($elements);
 -         $result = array();
 - 
 -         if ($combinationsLevel == 1) {
 -             foreach ($elements as $element) {
 -                 $result[] = array($element);
 -             }
 - 
 -             return $result;
 -         }
 - 
 -         $nextLevelElements = $this->getPossibleCombinations($elements, $combinationsLevel - 1);
 - 
 -         foreach ($nextLevelElements as $nextLevelElement) {
 -             $lastElement = $nextLevelElement[$combinationsLevel - 2];
 -             $found = false;
 - 
 -             foreach ($elements as $key => $element) {
 -                 if ($element == $lastElement) {
 -                     $found = true;
 -                     continue;
 -                 }
 - 
 -                 if ($found == true && $key < $baseCount) {
 -                     $tmp = $nextLevelElement;
 -                     $newCombination = array_slice($tmp, 0);
 -                     $newCombination[] = $element;
 -                     $result[] = array_slice($newCombination, 0);
 -                 }
 -             }
 -         }
 - 
 -         return $result;
 -     }
 - 
 -     /**
 -      * Shrink the values of parameters from a combination
 -      *
 -      * @param array $parameters
 -      * @param array $combination
 -      *
 -      * @return string
 -      */
 -     private function shrinkParameters($parameters, $combination)
 -     {
 -         array_shift($parameters);
 -         $result = '';
 - 
 -         $maxLength = $this->maxCharWidth;
 -         $maxLength -= count($parameters) * 5;
 -         $maxLength = $maxLength / count($parameters);
 - 
 -         foreach ($parameters as $key => $value) {
 -             $isLarger = false;
 - 
 -             if (strlen($value) > $maxLength) {
 -                 $value = wordwrap($value, $maxLength, "\n", true);
 -                 $value = explode("\n", $value);
 -                 $value = $value[0];
 - 
 -                 $isLarger = true;
 -             }
 -             $value = self::escapeFunction($value);
 - 
 -             if (!is_numeric($value)) {
 -                 $value = substr($value, 1, -1);
 -             }
 - 
 -             if ($isLarger) {
 -                 $value .= ' [...]';
 -             }
 - 
 - 
 -             $result .= ' ' . $combination[$key] . ' ' . $value;
 -         }
 - 
 -         return trim($result);
 -     }
 - 
 -     /**
 -      * Attempt to compose the best scenario minified query so that a user could find it without expanding it
 -      *
 -      * @param string $query
 -      * @param array $keywords
 -      * @param integer $required
 -      *
 -      * @return string
 -      */
 -     private function composeMiniQuery($query, $keywords = array(), $required = 1)
 -     {
 -         // Extract the mandatory keywords and consider the rest as optional keywords
 -         $mandatoryKeywords = array_splice($keywords, 0, $required);
 - 
 -         $combinations = array();
 -         $combinationsCount = count($keywords);
 - 
 -         // Compute all the possible combinations of keywords to match the query for
 -         while ($combinationsCount > 0) {
 -             $combinations = array_merge($combinations, $this->getPossibleCombinations($keywords, $combinationsCount));
 -             $combinationsCount--;
 -         }
 - 
 -         // Try and match the best case query pattern
 -         foreach ($combinations as $combination) {
 -             $combination = array_merge($mandatoryKeywords, $combination);
 - 
 -             $regexp = implode('(.*) ', $combination) . ' (.*)';
 -             $regexp = '/^' . $regexp . '/is';
 - 
 -             if (preg_match($regexp, $query, $matches)) {
 - 
 -                 $result = $this->shrinkParameters($matches, $combination);
 - 
 -                 return $result;
 -             }
 -         }
 - 
 -         // Try and match the simplest query form that contains only the mandatory keywords
 -         $regexp = implode(' (.*)', $mandatoryKeywords) . ' (.*)';
 -         $regexp = '/^' . $regexp . '/is';
 - 
 -         if (preg_match($regexp, $query, $matches)) {
 -             $result = $this->shrinkParameters($matches, $mandatoryKeywords);
 - 
 -             return $result;
 -         }
 - 
 -         // Fallback in case we didn't managed to find any good match (can we actually have that happen?!)
 -         $result = substr($query, 0, $this->maxCharWidth);
 - 
 -         return $result;
 -     }
 - 
 -     /**
 -      * Minify the query
 -      *
 -      * @param string $query
 -      *
 -      * @return string
 -      */
 -     public function minifyQuery($query)
 -     {
 -         $result = '';
 -         $keywords = array();
 -         $required = 1;
 - 
 -         // Check if we can match the query against any of the major types
 -         switch (true) {
 -             case stripos($query, 'SELECT') !== false:
 -                 $keywords = array('SELECT', 'FROM', 'WHERE', 'HAVING', 'ORDER BY', 'LIMIT');
 -                 $required = 2;
 -                 break;
 - 
 -             case stripos($query, 'DELETE') !== false :
 -                 $keywords = array('DELETE', 'FROM', 'WHERE', 'ORDER BY', 'LIMIT');
 -                 $required = 2;
 -                 break;
 - 
 -             case stripos($query, 'UPDATE') !== false :
 -                 $keywords = array('UPDATE', 'SET', 'WHERE', 'ORDER BY', 'LIMIT');
 -                 $required = 2;
 -                 break;
 - 
 -             case stripos($query, 'INSERT') !== false :
 -                 $keywords = array('INSERT', 'INTO', 'VALUE', 'VALUES');
 -                 $required = 2;
 -                 break;
 - 
 -             // If there's no match so far just truncate it to the maximum allowed by the interface
 -             default:
 -                 $result = substr($query, 0, $this->maxCharWidth);
 -         }
 - 
 -         // If we had a match then we should minify it
 -         if ($result == '') {
 -             $result = $this->composeMiniQuery($query, $keywords, $required);
 -         }
 - 
 -         // Remove unneeded boilerplate HTML
 -         $result = str_replace(array("<pre style='background:white;'", "</pre>"), array("<span", "</span>"), $result);
 - 
 -         return $result;
 -     }
 - 
 -     /**
 -      * Escape parameters of a SQL query
 -      * DON'T USE THIS FUNCTION OUTSIDE ITS INTEDED SCOPE
 -      *
 -      * @internal
 -      *
 -      * @param mixed $parameter
 -      *
 -      * @return string
 -      */
 -     static public function escapeFunction($parameter)
 -     {
 -         $result = $parameter;
 - 
 -         switch (true) {
 -             case is_string($result) :
 -                 $result = "'" . addslashes($result) . "'";
 -                 break;
 - 
 -             case is_array($result) :
 -                 foreach ($result as &$value) {
 -                     $value = static::escapeFunction($value);
 -                 }
 - 
 -                 $result = implode(', ', $result);
 -                 break;
 - 
 -             case is_object($result) :
 -                 $result = addslashes((string) $result);
 -                 break;
 -         }
 - 
 -         return $result;
 -     }
 - 
 -     /**
 -      * Return a query with the parameters replaced
 -      *
 -      * @param string $query
 -      * @param array $parameters
 -      *
 -      * @return string
 -      */
 -     public function replaceQueryParameters($query, $parameters)
 -     {
 -         $i = 0;
 - 
 -         $result = preg_replace_callback(
 -             '/\?|(:[a-z0-9_]+)/i',
 -             function ($matches) use ($parameters, &$i) {
 -                 $key = substr($matches[0], 1);
 -                 if (!isset($parameters[$i]) && !isset($parameters[$key])) {
 -                     return $matches[0];
 -                 }
 - 
 -                 $value = isset($parameters[$i]) ? $parameters[$i] : $parameters[$key];
 -                 $result = DoctrineExtension::escapeFunction($value);
 -                 $i++;
 - 
 -                 return $result;
 -             },
 -             $query
 -         );
 - 
 -         $result = \SqlFormatter::highlight($result);
 -         $result = str_replace(array("<pre ", "</pre>"), array("<span ", "</span>"), $result);
 - 
 -         return $result;
 -     }
 - 
 -     /**
 -      * Get the name of the extension
 -      *
 -      * @return string
 -      */
 -     public function getName()
 -     {
 -         return 'doctrine_extension';
 -     }
 - 
 - }
 
 
  |