PluginProbe
FeedWordPress / trunk
FeedWordPress vtrunk
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 trunk, at feedwordpressparsedpostmeta.class.php

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