PageRenderTime 10ms CodeModel.GetById 16ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/core/model/modx/filters/modoutputfilter.class.php

https://github.com/harunpehlivan/revolution
PHP | 681 lines | 548 code | 41 blank | 92 comment | 120 complexity | 8481ff257e8bbae1d0bffe059bca8784 MD5 | raw file
  1<?php
  2/*
  3 * MODX Revolution
  4 *
  5 * Copyright 2006-2014 by MODX, LLC.
  6 * All rights reserved.
  7 *
  8 * This program is free software; you can redistribute it and/or modify it under
  9 * the terms of the GNU General Public License as published by the Free Software
 10 * Foundation; either version 2 of the License, or (at your option) any later
 11 * version.
 12 *
 13 * This program is distributed in the hope that it will be useful, but WITHOUT
 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 16 * details.
 17 *
 18 * You should have received a copy of the GNU General Public License along with
 19 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 20 * Place, Suite 330, Boston, MA 02111-1307 USA
 21 */
 22
 23/**
 24 * Provides the default output filter implementation for modElement processing.
 25 * @package modx
 26 * @subpackage filters
 27 */
 28
 29/**
 30 * Base output filter implementation for modElement processing, based on phX.
 31 *
 32 * @package modx
 33 * @subpackage filters
 34 */
 35class modOutputFilter {
 36    /**
 37     * @var modX A reference to the modX instance
 38     */
 39    public $modx= null;
 40
 41    /**
 42     * @param modX $modx A reference to the modX instance
 43     * @return modOutputFilter A new instance of the modOutputFilter class
 44     */
 45    function __construct(modX &$modx) {
 46        $this->modx= &$modx;
 47    }
 48
 49    /**
 50     * Filters the output
 51     * 
 52     * @param modElement $element The element to filter
 53     */
 54    public function filter(&$element) {
 55        $usemb = function_exists('mb_strlen') && (boolean)$this->modx->getOption('use_multibyte',null,false);
 56        $encoding = $this->modx->getOption('modx_charset',null,'UTF-8');
 57
 58        $output= & $element->_output;
 59        $inputFilter = $element->getInputFilter();
 60        if ($inputFilter !== null && $inputFilter->hasCommands()) {
 61            $modifier_cmd = $inputFilter->getCommands();
 62            $modifier_value = $inputFilter->getModifiers();
 63            $count = count($modifier_cmd);
 64            $condition = array();
 65
 66            for ($i= 0; $i < $count; $i++) {
 67
 68                $m_cmd = $modifier_cmd[$i];
 69                $m_val = $modifier_value[$i];
 70
 71                $this->log('Processing Modifier: ' . $m_cmd . ' (parameters: ' . $m_val . ')');
 72
 73                $output = trim($output);
 74
 75                try {
 76                    switch ($m_cmd) {
 77                        /* conditional operators */
 78                        /* @todo these conditionals should be removed because there are cleaner ways to do this now */
 79                        case 'input':
 80                        case 'if':
 81                            $output= $m_val;
 82                            break;
 83                        case 'eq':
 84                        case 'is':
 85                        case 'equals':
 86                        case 'equalto':
 87                        case 'isequal':
 88                        case 'isequalto':
 89                            $condition[]= intval(($output == $m_val));
 90                            break;
 91                        case 'ne':
 92                        case 'neq':
 93                        case 'isnot':
 94                        case 'isnt':
 95                        case 'notequals':
 96                        case 'notequalto':
 97                            $condition[]= intval(($output != $m_val));
 98                            break;
 99                        case 'gte':
100                        case 'isgte':
101                        case 'eg':
102                        case 'ge':
103                        case 'equalorgreaterthan':
104                        case 'greaterthanorequalto':
105                            $condition[]= intval(($output >= $m_val));
106                            break;
107                        case 'lte':
108                        case 'islte':
109                        case 'le':
110                        case 'el':
111                        case 'lessthanorequalto':
112                        case 'equaltoorlessthan':
113                            $condition[]= intval(($output <= $m_val));
114                            break;
115                        case 'gt':
116                        case 'isgt':
117                        case 'greaterthan':
118                        case 'isgreaterthan':
119                            $condition[]= intval(($output > $m_val));
120                            break;
121                        case 'lt':
122                        case 'islt':
123                        case 'lessthan':
124                        case 'lowerthan':
125                        case 'islessthan':
126                        case 'islowerthan':
127                            $condition[]= intval(($output < $m_val));
128                            break;
129                        case 'contains':
130                            $condition[]= intval(stripos($output, $m_val) !== false);
131                            break;
132                        case 'containsnot':
133                            $condition[]= intval(stripos($output, $m_val) === false);;
134                            break;
135                        case 'ismember':
136                        case 'memberof':
137                        case 'mo': /* Is Member Of  (same as inrole but this one can be stringed as a conditional) */
138                            if (empty($output) || $output == "&_PHX_INTERNAL_&") {
139                                $output= $this->modx->user->get('id');
140                            }
141                            $grps= (strlen($m_val) > 0) ? explode(',', $m_val) : array ();
142                            /** @var $user modUser */
143                            $user = $this->modx->getObject('modUser',$output);
144                            if ($user && is_object($user) && $user instanceof modUser) {
145                                $condition[]= $user->isMember($grps);
146                            } else {
147                                $condition[] = false;
148                            }
149                            break;
150                        case 'or':
151                            $condition[]= "||";
152                            break;
153                        case 'and':
154                            $condition[]= "&&";
155                            break;
156                        case 'hide':
157                            $conditional = join(' ', $condition);
158                            try {
159                                $m_con = @eval("return (" . $conditional . ");");
160                                $m_con = intval($m_con);
161                                if ($m_con) {
162                                    $output= null;
163                                }
164                            } catch (Exception $e) {}
165                            break;
166                        case 'show':
167                            $conditional = join(' ', $condition);
168                            try {
169                                $m_con = @eval("return (" . $conditional . ");");
170                                $m_con = intval($m_con);
171                                if (!$m_con) {
172                                    $output= null;
173                                }
174                            } catch (Exception $e) {}
175                            break;
176                        case 'then':
177                            $output = null;
178                            $conditional = join(' ', $condition);
179                            try {
180                                $m_con = @eval("return (" . $conditional . ");");
181                                $m_con = intval($m_con);
182                                if ($m_con) {
183                                    $output= $m_val;
184                                }
185                            } catch (Exception $e) {}
186                            break;
187                        case 'else':
188                            $conditional = join(' ', $condition);
189                            try {
190                                $m_con = @eval("return (" . $conditional . ");");
191                                $m_con = intval($m_con);
192                                if (!$m_con) {
193                                    $output= $m_val;
194                                }
195                            } catch (Exception $e) {}
196                            break;
197                        case 'select':
198                            $raw= explode("&", $m_val);
199                            $map= array ();
200                            for ($m= 0; $m < (count($raw)); $m++) {
201                                $mi= explode("=", $raw[$m]);
202                                $map[$mi[0]]= $mi[1];
203                            }
204                            $output= $map[$output];
205                            break;
206                            /* #####  End of Conditional Modifiers */
207
208                        /* #####  String Modifiers */
209                        case 'cat': /* appends the options value (if not empty) to the input value */
210                            if (!empty($m_val))
211                                $output = $output . $m_val;
212                            break;
213                        case 'lcase':
214                        case 'lowercase':
215                        case 'strtolower':
216                            /* See PHP's strtolower - http://www.php.net/manual/en/function.strtolower.php */
217                            $output = $usemb ? mb_strtolower($output,$encoding) : strtolower($output);
218                            break;
219                        case 'ucase':
220                        case 'uppercase':
221                        case 'strtoupper':
222                            /* See PHP's strtoupper - http://www.php.net/manual/en/function.strtoupper.php */
223                            $output = $usemb ? mb_strtoupper($output,$encoding) : strtoupper($output);
224                            break;
225                        case 'ucwords':
226                            /* See PHP's ucwords - http://www.php.net/manual/en/function.ucwords.php */
227                            $output = $usemb ? mb_convert_case($output,MB_CASE_TITLE,$encoding) : ucwords($output);
228                            break;
229                        case 'ucfirst':
230                            /* See PHP's ucfirst - http://www.php.net/manual/en/function.ucfirst.php */
231                            if ($usemb) {
232                                $output = mb_strtoupper(mb_substr($output,0,1)) . mb_substr($output, 1);
233                            } else {
234                                $output = ucfirst($output);
235                            }
236                            break;
237                        case 'htmlent':
238                        case 'htmlentities':
239                            /* See PHP's htmlentities - http://www.php.net/manual/en/function.htmlentities.php */
240                            $output = htmlentities($output,ENT_QUOTES,$encoding);
241                            break;
242                        case 'esc':
243                        case 'escape':
244                            $output = preg_replace("/&amp;(#[0-9]+|[a-z]+);/i", "&$1;", htmlspecialchars($output));
245                            $output = str_replace(array ("[", "]", "`"), array ("&#91;", "&#93;", "&#96;"), $output);
246                            break;
247                        case 'strip':
248                            /* Replaces all linebreaks, tabs and multiple spaces with just one space */
249                            $output= preg_replace("/\s+/"," ",$output);
250                            break;
251                        case 'stripString':
252                            /* strips string of this value */
253                            $output= str_replace($m_val,'',$output);
254                            break;
255                        case 'replace':
256                            /* replaces one value with another */
257                            $opt = explode('==',$m_val);
258                            if (count($opt) >= 2) {
259                                $output = str_replace($opt[0],$opt[1],$output);
260                            }
261                            break;
262                        case 'notags':
263                        case 'striptags':
264                        case 'stripTags':
265                        case 'strip_tags':
266                            /* See PHP's strip_tags - http://www.php.net/manual/en/function.strip_tags.php */
267                            if (!empty($m_val)) {
268                                $output= strip_tags($output,$m_val);
269                            } else {
270                                $output= strip_tags($output);
271                            }
272                            break;
273                        case 'length':
274                        case 'len':
275                        case 'strlen':
276                            /* See PHP's strlen - http://www.php.net/manual/en/function.strlen.php */
277                            $output = $usemb ? mb_strlen($output,$encoding) : strlen($output);
278                            break;
279                        case 'reverse':
280                        case 'strrev':
281                            /* See PHP's strrev - http://www.php.net/manual/en/function.strrev.php */
282                            if ($usemb) {
283                                $ar = array();
284                                preg_match_all('/(\d+)?./us', $output, $ar);
285                                $output = join('',array_reverse($ar[0]));
286                            } else {
287                                $output = strrev($output);
288                            }
289                            break;
290                        case 'wordwrap':
291                            /* See PHP's wordwrap - http://www.php.net/manual/en/function.wordwrap.php */
292                            $wrapat= intval($m_val);
293                            if ($wrapat) {
294                                $output= wordwrap($output, $wrapat,"<br />\n ", 0);
295                            } else {
296                                $output= wordwrap($output, 70,"<br />\n", 0);
297                            }
298                            break;
299                        case 'wordwrapcut':
300                            /* See PHP's wordwrap - http://www.php.net/manual/en/function.wordwrap.php */
301                            $wrapat= intval($m_val);
302                            if ($wrapat) {
303                                $output= wordwrap($output, $wrapat,"<br />\n ", 1);
304                            } else {
305                                $output= wordwrap($output, 70,"<br />\n", 1);
306                            }
307                            break;
308                        case 'limit':
309                            /* default: 100 */
310                            $limit= intval($m_val) ? intval($m_val) : 100;
311                            /* ensure that filter correctly counts special chars */
312                            $str = html_entity_decode($output,ENT_COMPAT,$encoding);
313                            if ($usemb) {
314                                $output= mb_substr($str,0,$limit,$encoding);
315                            } else {
316                                $output= substr($str,0,$limit);
317                            }
318                            break;
319                        case 'ellipsis':
320                            $limit= intval($m_val) ? intval($m_val) : 100;
321                            $pad = $this->modx->getOption('ellipsis_filter_pad',null,'&#8230;');
322
323                            /* ensure that filter correctly counts special chars */
324                            $output = html_entity_decode($output,ENT_COMPAT,$encoding);
325                            $len = $usemb ? mb_strlen($output,$encoding) : strlen($output);
326                            if ($limit > $len) $limit = $len;
327                            if ($limit < 0) $limit = 0;
328                            $breakpoint = $usemb ? mb_strpos($output," ",$limit,$encoding) : strpos($output, " ", $limit);
329                            if (false !== $breakpoint) {
330                                if ($breakpoint < $len - 1) {
331                                    $partial = $usemb ? mb_substr($output, 0, $breakpoint,$encoding) : substr($output, 0, $breakpoint);
332                                    $output = $partial . $pad;
333                                }
334                            }
335
336                            $opened = array();
337                            if (preg_match_all("/<(\/?[a-z]+)>?/i", $output, $matches)) {
338                                foreach ($matches[1] as $tag) {
339                                    if (preg_match("/^[a-z]+$/i", $tag, $regs)) {
340                                        $strLower = $usemb ? mb_strtolower($regs[0],$encoding) : strtolower($regs[0]);
341                                        if ($strLower != 'br' || $strLower != 'hr') {
342                                            $opened[] = $regs[0];
343                                        }
344                                    } elseif (preg_match("/^\/([a-z]+)$/i", $tag, $regs)) {
345                                        $tmpArray = array_keys($opened, (string) $regs[1]);
346                                        $tmpVar = array_pop($tmpArray);
347                                        if ($tmpVar !== null) {
348                                            unset($opened[$tmpVar]);
349                                        }
350                                    }
351                                }
352                            }
353                            if ($opened) {
354                                $tagstoclose = array_reverse($opened);
355                                foreach ($tagstoclose as $tag) $output .= "</$tag>";
356                            }
357                            break;
358                        /* #####  Special functions */
359
360                        case 'tag':
361                            /* Displays the raw element tag without :tag */
362                            $tag = $element->_tag;
363                            $tag = htmlentities($tag,ENT_QUOTES,$encoding);
364                            $tag = str_replace(array ("[", "]", "`"), array ("&#91;", "&#93;", "&#96;"), $tag);
365                            $tag = str_replace(":tag","",$tag);
366                            $output = $tag;
367                            break;
368
369                        case 'add':
370                        case 'increment':
371                        case 'incr':
372                            /* Returns input incremented by option (default: +1) */
373                            if (empty($m_val) && $m_val !== 0 && $m_val !== '0') {
374                                $m_val = 1;
375                            }
376                            $output = (float)$output + (float)$m_val;
377                            break;
378
379                        case 'subtract':
380                        case 'decrement':
381                        case 'decr':
382                            /* Returns input decremented by option (default: -1) */
383                            if (empty($m_val) && $m_val !== 0 && $m_val !== '0') {
384                                $m_val = 1;
385                            }
386                            $output = (float)$output - (float)$m_val;
387                            break;
388
389                        case 'multiply':
390                        case 'mpy':
391                            /* Returns input multiplied by option (default: *2) */
392                            if (empty($m_val) && $m_val !== 0 && $m_val !== '0') {
393                                $m_val = 1;
394                            }
395                            $output = (float)$output * (float)$m_val;
396                            break;
397
398                        case 'divide':
399                        case 'div':
400                            /* Returns input divided by option (default: /2) */
401                            if (empty($m_val)) {
402                                $m_val = 2;
403                            }
404                            if (!empty($output)) {
405                                $output = (float)$output / (float)$m_val;
406                            } else {
407                                $output = 0;
408                            }
409                            break;
410
411                        case 'modulus':
412                        case 'mod':
413                            /* Returns the option modulus on input (default: %2, returns 0 or 1) */
414                            if (empty($m_val))
415                                $m_val = 2;
416                            $output = (float)$output % (float)$m_val;
417                            break;
418
419                        case 'default':
420                        case 'ifempty':
421                        case 'isempty':
422                        case 'empty':
423                            /* Returns the input value if empty */
424                            if (empty($output))
425                                $output= $m_val;
426                            break;
427
428                        case 'ifnotempty':
429                        case 'isnotempty':
430                        case 'notempty':
431                        case '!empty':
432                            /* returns input value if not empty */
433                            if (!empty($output))
434                                $output= $m_val;
435                            break;
436
437                        case 'nl2br':
438                            /* See PHP's nl2br - http://www.php.net/manual/en/function.nl2br.php */
439                            $output= nl2br($output);
440                            break;
441
442                        case 'date':
443                            /* See PHP's strftime - http://www.php.net/manual/en/function.strftime.php */
444                            if (empty($m_val))
445                                $m_val = "%A, %d %B %Y %H:%M:%S"; /* @todo this should be modx default date/time format? Lexicon? */
446                            $value = 0 + $output;
447                            if ($value != 0 && $value != -1) {
448                                $output= strftime($m_val,$value);
449                            } else {
450                                $output= '';
451                            }
452                            break;
453
454                        case 'strtotime':
455                            /* See PHP's strtotime() function - http://www.php.net/strtotime */
456                            if (!empty($output)) {
457                                $output = strtotime($output);
458                            } else {
459                                $output = '';
460                            }
461                            break;
462                        case 'fuzzydate':
463                            /* displays a "fuzzy" date reference */
464                            if (empty($this->modx->lexicon)) $this->modx->getService('lexicon','modLexicon');
465                            $this->modx->lexicon->load('filters');
466                            if (empty($m_val)) $m_val= '%b %e';
467                            if (!empty($output)) {
468                                $time = strtotime($output);
469                                if ($time >= strtotime('today')) {
470                                    $output = $this->modx->lexicon('today_at',array('time' => strftime('%I:%M %p',$time)));
471                                } elseif ($time >= strtotime('yesterday')) {
472                                    $output = $this->modx->lexicon('yesterday_at',array('time' => strftime('%I:%M %p',$time)));
473                                } else {
474                                    $output = strftime($m_val, $time);
475                                }
476                            } else {
477                                $output = '&mdash;';
478                            }
479                            break;
480                        case 'ago':
481                            /* calculates relative time ago from a timestamp */
482                            if (empty($output)) break;
483                            if (empty($this->modx->lexicon)) $this->modx->getService('lexicon','modLexicon');
484                            $this->modx->lexicon->load('filters');
485
486                            $agoTS = array();
487                            $uts['start'] = strtotime($output);
488                            $uts['end'] = time();
489                            if( $uts['start']!==-1 && $uts['end']!==-1 ) {
490                              if( $uts['end'] >= $uts['start'] ) {
491                                $diff = $uts['end'] - $uts['start'];
492
493                                $years = intval((floor($diff/31536000)));
494                                if ($years) $diff = $diff % 31536000;
495
496                                $months = intval((floor($diff/2628000)));
497                                if ($months) $diff = $diff % 2628000;
498
499                                $weeks = intval((floor($diff/604800)));
500                                if ($weeks) $diff = $diff % 604800;
501
502                                $days = intval((floor($diff/86400)));
503                                if ($days) $diff = $diff % 86400;
504
505                                $hours = intval((floor($diff/3600)));
506                                if ($hours) $diff = $diff % 3600;
507
508                                $minutes = intval((floor($diff/60)));
509                                if ($minutes) $diff = $diff % 60;
510
511                                $diff = intval($diff);
512                                $agoTS = array(
513                                  'years' => $years,
514                                  'months' => $months,
515                                  'weeks' => $weeks,
516                                  'days' => $days,
517                                  'hours' => $hours,
518                                  'minutes' => $minutes,
519                                  'seconds' => $diff,
520                                );
521                              }
522                            }
523
524                            $ago = array();
525                            if (!empty($agoTS['years'])) {
526                              $ago[] = $this->modx->lexicon(($agoTS['years'] > 1 ? 'ago_years' : 'ago_year'),array('time' => $agoTS['years']));
527                            }
528                            if (!empty($agoTS['months'])) {
529                              $ago[] = $this->modx->lexicon(($agoTS['months'] > 1 ? 'ago_months' : 'ago_month'),array('time' => $agoTS['months']));
530                            }
531                            if (!empty($agoTS['weeks']) && empty($agoTS['years'])) {
532                              $ago[] = $this->modx->lexicon(($agoTS['weeks'] > 1 ? 'ago_weeks' : 'ago_week'),array('time' => $agoTS['weeks']));
533                            }
534                            if (!empty($agoTS['days']) && empty($agoTS['months']) && empty($agoTS['years'])) {
535                              $ago[] = $this->modx->lexicon(($agoTS['days'] > 1 ? 'ago_days' : 'ago_day'),array('time' => $agoTS['days']));
536                            }
537                            if (!empty($agoTS['hours']) && empty($agoTS['weeks']) && empty($agoTS['months']) && empty($agoTS['years'])) {
538                              $ago[] = $this->modx->lexicon(($agoTS['hours'] > 1 ? 'ago_hours' : 'ago_hour'),array('time' => $agoTS['hours']));
539                            }
540                            if (!empty($agoTS['minutes']) && empty($agoTS['days']) && empty($agoTS['weeks']) && empty($agoTS['months']) && empty($agoTS['years'])) {
541                                $ago[] = $this->modx->lexicon($agoTS['minutes'] == 1 ? 'ago_minute' : 'ago_minutes' ,array('time' => $agoTS['minutes']));
542                            }
543                            if (empty($ago)) { /* handle <1 min */
544                              $ago[] = $this->modx->lexicon('ago_seconds',array('time' => !empty($agoTS['seconds']) ? $agoTS['seconds'] : 0));
545                            }
546                            $output = implode(', ',$ago);
547                            $output = $this->modx->lexicon('ago',array('time' => $output));
548                            break;
549                        case 'md5':
550                            /* See PHP's md5 - http://www.php.net/manual/en/function.md5.php */
551                            $output= md5($output);
552                            break;
553                        case 'cdata':
554                            if ($usemb) {
555                                $len = mb_strlen($output,$encoding);
556                                if (mb_strpos($output,'[',0,$encoding) === 0) { $output = ' '.$output; }
557                                if (mb_strpos($output,']',0,$encoding) === $len) { $output = $output.' '; }
558                            } else {
559                                $len = strlen($output);
560                                if (strpos($output,'[') === 0) { $output = ' '.$output; }
561                                if (strpos($output,']') === $len) { $output = $output.' '; }
562                            }
563                            $output= "<![CDATA[{$output}]]>";
564                            break;
565
566                        case 'userinfo':
567                            /* Returns the requested modUser or modUserProfile data (input: user id) */
568                            if (!empty($output)) {
569                                $key = (!empty($m_val)) ? $m_val : 'username';
570                                $userInfo= null;
571                                /** @var modUser $user */
572                                if ($user= $this->modx->getObjectGraph('modUser', '{"Profile":{}}', $output)) {
573                                    $userData = array_merge($user->toArray(), $user->Profile->toArray());
574                                    unset($userData['cachepwd'], $userData['salt'], $userData['sessionid'], $userData['password'], $userData['session_stale']);
575                                    if (strpos($key, 'extended.') === 0 && isset($userData['extended'][substr($key, 9)])) {
576                                        $userInfo = $userData['extended'][substr($key, 9)];
577                                    } elseif (strpos($key, 'remote_data.') === 0 && isset($userData['remote_data'][substr($key, 12)])) {
578                                        $userInfo = $userData['remote_data'][substr($key, 12)];
579                                    } elseif (isset($userData[$key])) {
580                                        $userInfo = $userData[$key];
581                                    }
582                                }
583                                $output = $userInfo;
584                            } else {
585                                $output = null;
586                            }
587                            break;
588
589                        case 'isloggedin':
590                            /* returns true if user is logged in to the specified context or by default the current context */
591                            $ctxkey = (!empty($m_val)) ? $m_val : $this->modx->context->get('key');
592                            $output= $this->modx->user->isAuthenticated($ctxkey);
593                            $output= $output ? true : false;
594                            break;
595
596                        case 'isnotloggedin':
597                            /* returns true if user is not logged in to the specified context or by default the current context */
598                            $ctxkey = (!empty($m_val)) ? $m_val : $this->modx->context->get('key');
599                            $output= $this->modx->user->isAuthenticated($ctxkey);
600                            $output= $output ? false : true;
601                            break;
602
603                        case 'urlencode':
604                            $output = urlencode($output);
605                            break;
606                        case 'urldecode':
607                            $output = urldecode($output);
608                            break;
609
610                        case 'toPlaceholder':
611                            $this->modx->toPlaceholder($m_val,$output);
612                            $output = '';
613                            break;
614                        case 'cssToHead':
615                            $this->modx->regClientCSS($output);
616                            $output = '';
617                            break;
618                        case 'htmlToHead':
619                            $this->modx->regClientStartupHTMLBlock($output);
620                            $output = '';
621                            break;
622                        case 'htmlToBottom':
623                            $this->modx->regClientHTMLBlock($output);
624                            $output = '';
625                            break;
626                        case 'jsToHead':
627                            if (empty($m_val)) $m_val = false;
628                            $this->modx->regClientStartupScript($output,$m_val);
629                            $output = '';
630                            break;
631                        case 'jsToBottom':
632                            if (empty($m_val)) $m_val = false;
633                            $this->modx->regClientScript($output,$m_val);
634                            $output = '';
635                            break;
636                        case 'in':
637                        case 'IN':
638                        case 'inarray':
639                        case 'inArray':
640                            if (empty($m_val)) $m_val = false;
641                            $haystack = explode(',', $m_val);
642                            $condition[]= intval(in_array($output, $haystack));
643                            break;
644
645
646                        /* Default, custom modifier (run snippet with modifier name) */
647                        default:
648                            /*@todo Possibility to only look for snippet names prefixed with 'filter:' */
649                            /*@todo Maybe pass whole element by reference instead of token/tag/name? */
650                            $params = array (
651                                'input' => $output,
652                                'options' => $m_val,
653                                'token' => $element->_token, /* type of parent element */
654                                'name' => $element->get('name'), /* name of the parent element */
655                                'tag' => $element->getTag() /* complete parent tag */
656                            );
657                            $this->log('This modifier is custom running as snippet.');
658                            $tmp = $this->modx->runSnippet($m_cmd, $params);
659                            if ($tmp!='') $output = $tmp;
660                            break;
661                    }
662                } catch (Exception $e) {
663                    $this->modx->log(modX::LOG_LEVEL_ERROR,$e->getMessage());
664                }
665            }
666            // convert $output to string if there were any processing
667            $output = (string)$output;
668        }
669    }
670
671    /**
672     * Send a log message to the message logger
673     * @param string $msg
674     * @return void
675     */
676    public function log($msg) {
677         if ($this->modx->getDebug() === true) {
678             $this->modx->log(modX::LOG_LEVEL_DEBUG, $msg);
679         }
680    }
681}