ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
BasePhpFormulaLoader.php
Go to the documentation of this file.
1<?php
2
3/*
4 * This file is part of the Assetic package, an OpenSky project.
5 *
6 * (c) 2010-2014 OpenSky Project Inc
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
13
17
23abstract class BasePhpFormulaLoader implements FormulaLoaderInterface
24{
25 protected $factory;
26 protected $prototypes;
27
28 public function __construct(AssetFactory $factory)
29 {
30 $this->factory = $factory;
31 $this->prototypes = array();
32
33 foreach ($this->registerPrototypes() as $prototype => $options) {
34 $this->addPrototype($prototype, $options);
35 }
36 }
37
38 public function addPrototype($prototype, array $options = array())
39 {
40 $tokens = token_get_all('<?php '.$prototype);
41 array_shift($tokens);
42
43 $this->prototypes[$prototype] = array($tokens, $options);
44 }
45
46 public function load(ResourceInterface $resource)
47 {
48 if (!$nbProtos = count($this->prototypes)) {
49 throw new \LogicException('There are no prototypes registered.');
50 }
51
52 $buffers = array_fill(0, $nbProtos, '');
53 $bufferLevels = array_fill(0, $nbProtos, 0);
54 $buffersInWildcard = array();
55
56 $tokens = token_get_all($resource->getContent());
57 $calls = array();
58
59 while ($token = array_shift($tokens)) {
60 $current = self::tokenToString($token);
61 // loop through each prototype (by reference)
62 foreach (array_keys($this->prototypes) as $i) {
63 $prototype = & $this->prototypes[$i][0];
64 $options = $this->prototypes[$i][1];
65 $buffer = & $buffers[$i];
66 $level = & $bufferLevels[$i];
67
68 if (isset($buffersInWildcard[$i])) {
69 switch ($current) {
70 case '(': ++$level; break;
71 case ')': --$level; break;
72 }
73
74 $buffer .= $current;
75
76 if (!$level) {
77 $calls[] = array($buffer.';', $options);
78 $buffer = '';
79 unset($buffersInWildcard[$i]);
80 }
81 } elseif ($current == self::tokenToString(current($prototype))) {
82 $buffer .= $current;
83 if ('*' == self::tokenToString(next($prototype))) {
84 $buffersInWildcard[$i] = true;
85 ++$level;
86 }
87 } else {
88 reset($prototype);
89 unset($buffersInWildcard[$i]);
90 $buffer = '';
91 }
92 }
93 }
94
95 $formulae = array();
96 foreach ($calls as $call) {
97 $formulae += call_user_func_array(array($this, 'processCall'), $call);
98 }
99
100 return $formulae;
101 }
102
103 private function processCall($call, array $protoOptions = array())
104 {
105 $tmp = FilesystemUtils::createTemporaryFile('php_formula_loader');
106 file_put_contents($tmp, implode("\n", array(
107 '<?php',
108 $this->registerSetupCode(),
109 $call,
110 'echo serialize($_call);',
111 )));
112 $args = unserialize(shell_exec('php '.escapeshellarg($tmp)));
113 unlink($tmp);
114
115 $inputs = isset($args[0]) ? self::argumentToArray($args[0]) : array();
116 $filters = isset($args[1]) ? self::argumentToArray($args[1]) : array();
117 $options = isset($args[2]) ? $args[2] : array();
118
119 if (!isset($options['debug'])) {
120 $options['debug'] = $this->factory->isDebug();
121 }
122
123 if (!is_array($options)) {
124 throw new \RuntimeException('The third argument must be omitted, null or an array.');
125 }
126
127 // apply the prototype options
128 $options += $protoOptions;
129
130 if (!isset($options['name'])) {
131 $options['name'] = $this->factory->generateAssetName($inputs, $filters, $options);
132 }
133
134 return array($options['name'] => array($inputs, $filters, $options));
135 }
136
142 abstract protected function registerPrototypes();
143
149 abstract protected function registerSetupCode();
150
151 protected static function tokenToString($token)
152 {
153 return is_array($token) ? $token[1] : $token;
154 }
155
156 protected static function argumentToArray($argument)
157 {
158 return is_array($argument) ? $argument : array_filter(array_map('trim', explode(',', $argument)));
159 }
160}
The asset factory creates asset objects.
static createTemporaryFile($prefix)
Creates a temporary file.
An exception for terminatinating execution or to throw for unit testing.
A resource is something formulae can be loaded from.
if(!is_array($argv)) $options