PluginProbe
FeedWordPress / 2022.0123
FeedWordPress v2022.0123
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
feedwordpress / feedwordpressparsedpostmeta.class.php

feedwordpressparsedpostmeta.class.php in FeedWordPress 2022.0123, at feedwordpressparsedpostmeta.class.php

309 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 class FeedWordPressParsedPostMeta {
3 var $s, $ptr, $ptrEOS;
4 var $delims, $delimCount, $delimPtr;
5 var $paren;
6
7 var $parsed = NULL;
8
9 function __construct ($s) {
10 $this->s = $s;
11 $this->reset();
12 }
13
14 function reset () {
15 $this->parsed = NULL;
16
17 $this->ptr = 0;
18 $this->paren = 0;
19 $this->ptrEOS = strlen($this->s);
20
21 $this->delimCount['CDATA'] = preg_match_all('/\$/', $this->s, $this->delims['CDATA'], PREG_OFFSET_CAPTURE);
22 $this->delimPtr['CDATA'] = 0;
23
24 $this->delimCount['EXPR'] = preg_match_all('/[()\s]/', $this->s, $this->delims['EXPR'], PREG_OFFSET_CAPTURE);
25 $this->delimPtr['EXPR'] = 0;
26 }
27
28 function look () { return $this->s[$this->ptr]; }
29 function drop () { $this->anchor = $this->ptr; }
30 function take () { return substr($this->s, $this->anchor, ($this->ptr - $this->anchor)); }
31 function EOS () { return ($this->ptr >= $this->ptrEOS); }
32
33 function nextDelim ($which) {
34 $N = $this->delimCount[$which]; $ptr = $this->delimPtr[$which];
35
36 $next = -1;
37 while ( ($ptr < $N) and ($next < $this->ptr) ) :
38 $next = $this->delims[$which][0][$ptr][1];
39 $ptr++;
40 endwhile;
41 $this->delimPtr[$which] = $ptr;
42
43 if ($next < $this->ptr) :
44 $next = $this->ptrEOS;
45 endif;
46 return $next;
47 }
48
49 function substitute_terms ($post, $piece, $values = NULL) {
50 $terms = array();
51 if ('EXPR'==$piece[0]) :
52 // Parameter stored in $piece[1]
53 $param = $piece[1];
54 if (is_string($param)) :
55 if (!isset($values[$param])) :
56 $values[$param] = $post->query($param);
57 endif;
58 $term = $param;
59 $results = $values[$param];
60 else :
61 list($results, $term, $values) = $this->substitute_terms($post, $piece[1], $values);
62 endif;
63
64 // Filtering function, if any, stored in $piece[2]
65 if (isset($piece[2])) :
66 $filter = $post->substitution_function(trim(strtolower($piece[2])));
67 if (!is_null($filter)) :
68 foreach ($results as $key => $result) :
69 $results[$key] = $filter($result);
70 endforeach;
71 else :
72 $results = array(
73 "[[ERR: No such function (".$piece[2].")]]",
74 );
75 endif;
76 endif;
77
78 elseif ('CDATA'==$piece[0]) :
79 // Literal string stored in $piece[1]
80 $results = array($piece[1]);
81 $term = NULL;
82 endif;
83 return array($results, $term, $values);
84 }
85
86 function do_substitutions ($post, $in = NULL, $scratchpad = NULL) {
87 if (is_null($in)) :
88 $in = $this->get();
89 endif;
90
91 if (count($in) > 0) :
92 $out = array();
93
94 // Init. results set if not already initialized.
95 if (is_null($scratchpad)) :
96 $scratchpad = array(array('', array()));
97 endif;
98
99 // Grab the first
100 $piece = array_shift($in);
101
102 foreach ($scratchpad as $key => $scratch) :
103 $line = $scratch[0];
104 $element_values = $scratch[1];
105
106 switch ($piece[0]) :
107 case 'CDATA' :
108 $subs = array($piece[1]);
109 $term = NULL;
110 break;
111 case 'EXPR' :
112 list($subs, $term, $element_values) = $this->substitute_terms($post, $piece, $element_values);
113 break;
114 endswitch;
115
116 $constrained_values = $element_values;
117 foreach ($subs as $sub) :
118
119 if (isset($term)) :
120 $constrained_values[$term] = array($sub);
121 endif;
122
123 $out[] = array($line . $sub, $constrained_values);
124 endforeach;
125
126 endforeach;
127
128 if (count($in) > 0) :
129 $out = $this->do_substitutions($post, $in, $out);
130 endif;
131 else :
132 $out = NULL;
133 endif;
134
135 // Now that we are done, strip out the namespace elements.
136 if (is_array($out)) :
137 foreach ($out as $idx => $line) :
138 if (is_array($line)) :
139 $out[$idx] = $line[0];
140 endif;
141 endforeach;
142 endif;
143
144 return $out;
145 }
146
147 function get ($idx = NULL) {
148 $ret = $this->parse();
149 if ($idx) : $ret = $ret[$idx]; endif;
150
151 return $ret;
152 }
153
154 function parse () {
155 if (is_null($this->parsed)) :
156 $out = array();
157
158 $this->reset();
159 while (!$this->EOS()) :
160 switch ($this->look()) :
161 case '$' :
162 $this->ptr++;
163 $out[] = $this->EXPR();
164 break;
165 default :
166 $out[] = $this->CDATA();
167 endswitch;
168 endwhile;
169
170 $this->parsed = $out;
171 endif;
172 return $this->parsed;
173 }
174
175 function CDATA () {
176 $this->drop();
177 $this->ptr = $this->nextDelim('CDATA');
178 return array(__FUNCTION__, $this->take());
179 } /* FeedWordPressParsedPostMeta::CDATA() */
180
181 function EXPR () {
182 $ret = array(__FUNCTION__);
183 $paren0 = $this->paren;
184 $this->drop();
185
186 $ptr0 = $this->ptr;
187
188 $complete = false;
189 while (!$this->EOS() and !$complete) :
190 $tok = $this->look();
191 switch ($tok) :
192 case '(' :
193
194 $fun = $this->take();
195
196 // We're at the open paren; skip ahead past that.
197 $this->ptr++;
198
199 // And indent us one level in.
200 $this->paren++;
201
202 $delta = $this->EXPR();
203 if (isset($delta[2])) :
204 $ret[1] = $delta;
205 else :
206 $ret[1] = $delta[1];
207 endif;
208
209 if (strlen(trim($fun)) > 0) :
210 $ret[2] = trim($fun);
211 endif;
212
213 // We should be stopped on either a close paren or on EOS.
214 $this->ptr++;
215
216 // A top level expression terminates
217 // immediately with the closing of its
218 // parens. Lower-level expressions may
219 // have whitespace wrapper, etc.
220 $complete = ($this->paren <= 0);
221
222 $this->drop();
223 break;
224
225 case ')' :
226
227 if ($this->paren > 0) :
228 $this->paren--;
229
230 $complete = ($this->paren <= $paren0);
231
232 $fun = $this->take();
233 if (strlen(trim($fun)) > 0) :
234 $ret[1] = trim($fun);
235 endif;
236
237 $this->drop();
238 else :
239 $this->ptr++;
240 endif;
241 break;
242
243 case '$' :
244 if ($ptr0 == $this->ptr) :
245 // This is an escaped literal $
246 $this->ptr++;
247 $ret = array('CDATA', $tok);
248 $this->drop();
249 $complete = true;
250 break;
251 endif;
252
253 default :
254 if (ctype_space($tok) and ($this->paren <= 0)) :
255 // A loose $ should be treated as a literal $
256 if ($ptr0 == $this->ptr) :
257 $ret = array('CDATA', '$');
258 $this->drop();
259 endif;
260 $complete = true;
261 else :
262 $next = $this->nextDelim('EXPR');
263
264 // Skip ahead to the next potentially interesting character.
265 if (!is_null($next)) :
266 $this->ptr = $next;
267 else :
268 $this->ptr = $this->ptrEOS;
269 endif;
270
271 endif;
272 endswitch;
273 endwhile;
274
275 $var = '';
276 if ($this->anchor < $this->ptr) :
277 $var = trim($this->take());
278 endif;
279 if (strlen($var) > 0) :
280 $ret[1] = $var;
281 endif;
282 return $ret;
283 } /* FeedWordPressParsedPostMeta::EXPR () */
284 } /* class FeedWordPressParsedPostMeta */
285
286 if (basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__)) :
287 $argv = $_SERVER['argv'];
288 array_shift($argv);
289 $N = reset($argv);
290 if (is_numeric($N)) :
291 array_shift($argv);
292 else :
293 $N = 1;
294 endif;
295
296 $t0 = microtime(/*float=*/ true);
297 for ($i = 0; $i < $N; $i++) :
298 $parse = new FeedWordPressParsedPostMeta(implode(" ", $argv));
299 $voo = ($parse->parse());
300 unset($parse);
301 endfor;
302 $t1 = microtime(/*float=*/ true);
303
304 echo "RESULT: "; var_dump($voo);
305 echo "ELAPSED TIME: "; print number_format(1000.0 * ($t1 - $t0)) . "ms\n";
306 echo "CONSUMED MEMORY: "; print number_format(memory_get_peak_usage() / 1024) . "KB\n";
307 endif;
308
309