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 
24 {
25  protected $factory;
26  protected $prototypes;
27 
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 }
static createTemporaryFile($prefix)
Creates a temporary file.
getContent()
Returns the content of the resource.
registerPrototypes()
Returns an array of prototypical calls and options.
A resource is something formulae can be loaded from.
processCall($call, array $protoOptions=array())
registerSetupCode()
Returns setup code for the reflection scriptlet.
if(!is_array($argv)) $options
addPrototype($prototype, array $options=array())
load(ResourceInterface $resource)
Loads formulae from a resource.
Create styles array
The data for the language used.
The asset factory creates asset objects.
Loads asset formulae from PHP files.