/Nette/common/Callback.php

https://github.com/langpavel/nette · PHP · 192 lines · 88 code · 40 blank · 64 comment · 15 complexity · 5677051fdb57d9293251688841491fa3 MD5 · raw file

  1. <?php
  2. /**
  3. * This file is part of the Nette Framework (http://nette.org)
  4. *
  5. * Copyright (c) 2004, 2011 David Grudl (http://davidgrudl.com)
  6. *
  7. * For the full copyright and license information, please view
  8. * the file license.txt that was distributed with this source code.
  9. */
  10. namespace Nette;
  11. use Nette;
  12. /**
  13. * PHP callback encapsulation.
  14. *
  15. * @author David Grudl
  16. */
  17. final class Callback extends Object
  18. {
  19. /** @var string|array|\Closure */
  20. private $cb;
  21. /**
  22. * Do not call directly, use callback() function.
  23. * @param mixed class, object, function, callback
  24. * @param string method
  25. */
  26. public function __construct($t, $m = NULL)
  27. {
  28. if ($m === NULL) {
  29. if (is_string($t)) {
  30. $t = explode('::', $t, 2);
  31. $this->cb = isset($t[1]) ? $t : $t[0];
  32. } elseif (is_object($t)) {
  33. $this->cb = $t instanceof \Closure ? $t : array($t, '__invoke');
  34. } else {
  35. $this->cb = $t;
  36. }
  37. } else {
  38. $this->cb = array($t, $m);
  39. }
  40. /*5.2*
  41. // remove class namespace
  42. if (is_string($this->cb) && $a = strrpos($this->cb, '\\')) {
  43. $this->cb = substr($this->cb, $a + 1);
  44. } elseif (is_array($this->cb) && is_string($this->cb[0]) && $a = strrpos($this->cb[0], '\\')) {
  45. $this->cb[0] = substr($this->cb[0], $a + 1);
  46. }
  47. */
  48. if (!is_callable($this->cb, TRUE)) {
  49. throw new InvalidArgumentException("Invalid callback.");
  50. }
  51. }
  52. /**
  53. * Invokes callback. Do not call directly.
  54. * @return mixed
  55. */
  56. public function __invoke()
  57. {
  58. if (!is_callable($this->cb)) {
  59. throw new InvalidStateException("Callback '$this' is not callable.");
  60. }
  61. $args = func_get_args();
  62. return call_user_func_array($this->cb, $args);
  63. }
  64. /**
  65. * Invokes callback.
  66. * @return mixed
  67. */
  68. public function invoke()
  69. {
  70. if (!is_callable($this->cb)) {
  71. throw new InvalidStateException("Callback '$this' is not callable.");
  72. }
  73. $args = func_get_args();
  74. return call_user_func_array($this->cb, $args);
  75. }
  76. /**
  77. * Invokes callback with an array of parameters.
  78. * @param array
  79. * @return mixed
  80. */
  81. public function invokeArgs(array $args)
  82. {
  83. if (!is_callable($this->cb)) {
  84. throw new InvalidStateException("Callback '$this' is not callable.");
  85. }
  86. return call_user_func_array($this->cb, $args);
  87. }
  88. /**
  89. * Invokes callback using named parameters.
  90. * @param array
  91. * @return mixed
  92. */
  93. public function invokeNamedArgs(array $args)
  94. {
  95. $ref = $this->toReflection();
  96. if (is_array($this->cb)) {
  97. return $ref->invokeNamedArgs(is_object($this->cb[0]) ? $this->cb[0] : NULL, $args);
  98. } else {
  99. return $ref->invokeNamedArgs($args);
  100. }
  101. }
  102. /**
  103. * Verifies that callback can be called.
  104. * @return bool
  105. */
  106. public function isCallable()
  107. {
  108. return is_callable($this->cb);
  109. }
  110. /**
  111. * Returns PHP callback pseudotype.
  112. * @return string|array|\Closure
  113. */
  114. public function getNative()
  115. {
  116. return $this->cb;
  117. }
  118. /**
  119. * Returns callback reflection.
  120. * @return Nette\Reflection\GlobalFunction|Nette\Reflection\Method
  121. */
  122. public function toReflection()
  123. {
  124. if (is_array($this->cb)) {
  125. return new Nette\Reflection\Method($this->cb[0], $this->cb[1]);
  126. } else {
  127. return new Nette\Reflection\GlobalFunction($this->cb);
  128. }
  129. }
  130. /**
  131. * @return bool
  132. */
  133. public function isStatic()
  134. {
  135. return is_array($this->cb) ? is_string($this->cb[0]) : is_string($this->cb);
  136. }
  137. /**
  138. * @return string
  139. */
  140. public function __toString()
  141. {
  142. if ($this->cb instanceof \Closure) {
  143. return '{closure}';
  144. } elseif (is_string($this->cb) && $this->cb[0] === "\0") {
  145. return '{lambda}';
  146. } else {
  147. is_callable($this->cb, TRUE, $textual);
  148. return $textual;
  149. }
  150. }
  151. }