ExpressionFunction.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\ExpressionLanguage;
  11. /**
  12. * Represents a function that can be used in an expression.
  13. *
  14. * A function is defined by two PHP callables. The callables are used
  15. * by the language to compile and/or evaluate the function.
  16. *
  17. * The "compiler" function is used at compilation time and must return a
  18. * PHP representation of the function call (it receives the function
  19. * arguments as arguments).
  20. *
  21. * The "evaluator" function is used for expression evaluation and must return
  22. * the value of the function call based on the values defined for the
  23. * expression (it receives the values as a first argument and the function
  24. * arguments as remaining arguments).
  25. *
  26. * @author Fabien Potencier <fabien@symfony.com>
  27. */
  28. class ExpressionFunction
  29. {
  30. private $name;
  31. private $compiler;
  32. private $evaluator;
  33. /**
  34. * @param string $name The function name
  35. * @param callable $compiler A callable able to compile the function
  36. * @param callable $evaluator A callable able to evaluate the function
  37. */
  38. public function __construct($name, callable $compiler, callable $evaluator)
  39. {
  40. $this->name = $name;
  41. $this->compiler = $compiler;
  42. $this->evaluator = $evaluator;
  43. }
  44. public function getName()
  45. {
  46. return $this->name;
  47. }
  48. public function getCompiler()
  49. {
  50. return $this->compiler;
  51. }
  52. public function getEvaluator()
  53. {
  54. return $this->evaluator;
  55. }
  56. /**
  57. * Creates an ExpressionFunction from a PHP function name.
  58. *
  59. * @param string $phpFunctionName The PHP function name
  60. * @param string|null $expressionFunctionName The expression function name (default: same than the PHP function name)
  61. *
  62. * @return self
  63. *
  64. * @throws \InvalidArgumentException if given PHP function name does not exist
  65. * @throws \InvalidArgumentException if given PHP function name is in namespace
  66. * and expression function name is not defined
  67. */
  68. public static function fromPhp($phpFunctionName, $expressionFunctionName = null)
  69. {
  70. $phpFunctionName = ltrim($phpFunctionName, '\\');
  71. if (!\function_exists($phpFunctionName)) {
  72. throw new \InvalidArgumentException(sprintf('PHP function "%s" does not exist.', $phpFunctionName));
  73. }
  74. $parts = explode('\\', $phpFunctionName);
  75. if (!$expressionFunctionName && \count($parts) > 1) {
  76. throw new \InvalidArgumentException(sprintf('An expression function name must be defined when PHP function "%s" is namespaced.', $phpFunctionName));
  77. }
  78. $compiler = function () use ($phpFunctionName) {
  79. return sprintf('\%s(%s)', $phpFunctionName, implode(', ', \func_get_args()));
  80. };
  81. $evaluator = function () use ($phpFunctionName) {
  82. $args = \func_get_args();
  83. return \call_user_func_array($phpFunctionName, array_splice($args, 1));
  84. };
  85. return new self($expressionFunctionName ?: end($parts), $compiler, $evaluator);
  86. }
  87. }