1: <?php
2: /**
3: * PHP version 5
4: * @package generalDriver
5: * @author Christian Schiffler <c.schiffler@cyberspectrum.de>
6: * @author Stefan Heimes <stefan_heimes@hotmail.com>
7: * @author Tristan Lins <tristan.lins@bit3.de>
8: * @copyright The MetaModels team.
9: * @license LGPL.
10: * @filesource
11: */
12:
13: namespace DcGeneral\Contao\Callback;
14:
15: use DcGeneral\Exception\DcGeneralRuntimeException;
16:
17: /**
18: * Class Callbacks.
19: *
20: * Static callback emitting class.
21: *
22: * @package DcGeneral\Contao\Callback
23: */
24: class Callbacks
25: {
26: /**
27: * Call a Contao style callback.
28: *
29: * @param array|callable $callback The callback to invoke.
30: *
31: * @param mixed $_ List of arguments to pass to the callback [optional].
32: *
33: * @return mixed
34: */
35: public static function call($callback, $_ = null)
36: {
37: // Get method parameters as callback parameters.
38: $args = func_get_args();
39: // But skip $callback.
40: array_shift($args);
41:
42: return static::callArgs($callback, $args);
43: }
44:
45: /**
46: * Call a Contao style callback.
47: *
48: * @param array|callable $callback The callback to invoke.
49: *
50: * @param array $args List of arguments to pass to the callback.
51: *
52: * @return mixed
53: *
54: * @throws DcGeneralRuntimeException When the callback throws an exception.
55: */
56: public static function callArgs($callback, array $args = array())
57: {
58: try {
59: $callback = static::evaluateCallback($callback);
60:
61: return call_user_func_array($callback, $args);
62: }
63: catch(\Exception $e) {
64: $message = $e->getMessage();
65: }
66:
67: if (is_array($callback) && is_object($callback[0]))
68: {
69: $callback[0] = get_class($callback[0]);
70: }
71:
72: throw new DcGeneralRuntimeException(
73: sprintf(
74: 'Execute callback %s failed - Exception message: %s',
75: (is_array($callback) ? implode('::', $callback) : $callback),
76: $message
77: ),
78: 0
79: );
80: }
81:
82: /**
83: * Evaluate the callback and create an object instance if required and possible.
84: *
85: * @param array|callable $callback The callback to invoke.
86: *
87: * @return array|callable
88: */
89: protected static function evaluateCallback($callback)
90: {
91: if (is_array($callback) && count($callback) == 2 && is_string($callback[0]) && is_string($callback[1]))
92: {
93: $class = new \ReflectionClass($callback[0]);
94:
95: // Ff the method is static, do not create an instance.
96: if ($class->hasMethod($callback[1]) && $class->getMethod($callback[1])->isStatic())
97: {
98: return $callback;
99: }
100:
101: // Fetch singleton instance.
102: if ($class->hasMethod('getInstance'))
103: {
104: $getInstanceMethod = $class->getMethod('getInstance');
105:
106: if ($getInstanceMethod->isStatic())
107: {
108: $callback[0] = $getInstanceMethod->invoke(null);
109: return $callback;
110: }
111: }
112:
113: // Create a new instance.
114: $callback[0] = $class->newInstance();
115: }
116:
117: return $callback;
118: }
119: }
120: