Пример #1
0
/**
 * Deals with the [macro parameters] substitutions
 *
 * See the macroList plugin for details
 *
 * @param string $text
 * @return string
 */
function applyMacros($text)
{
    $content_macros = getMacros();
    preg_match_all('/\\[(\\w+)(.*?)\\]/i', $text, $instances);
    foreach ($instances[0] as $instance => $macro_instance) {
        $macroname = strtoupper($instances[1][$instance]);
        if (array_key_exists($macroname, $content_macros)) {
            $macro = $content_macros[$macroname];
            $p = $instances[2][$instance];
            $data = NULL;
            $class = $macro['class'];
            if ($p) {
                $p = trim(utf8::sanitize(str_replace(" ", ' ', strip_tags($p))));
                //	remove hard spaces and invalid characters
                $p = preg_replace("~\\s+=\\s+(?=(?:[^\"]*+\"[^\"]*+\")*+[^\"]*+\$)~", "=", $p);
                //	deblank assignment operator
                preg_match_all("~'[^'\"]++'|\"[^\"]++\"|[^\\s]++~", $p, $l);
                //	parse the parameter list
                $parms = array();
                $k = 0;
                foreach ($l[0] as $s) {
                    if ($s != ',') {
                        $parms[$k++] = trim($s, '\'"');
                        //	remove any quote marks
                    }
                }
            } else {
                $parms = array();
            }
            $parameters = array();
            if (!empty($macro['params'])) {
                $err = false;
                foreach ($macro['params'] as $key => $type) {
                    $data = false;
                    if (array_key_exists($key, $parms)) {
                        switch (trim($type, '*')) {
                            case 'int':
                                if (is_numeric($parms[$key])) {
                                    $parameters[] = (int) $parms[$key];
                                } else {
                                    $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d should be a number.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
                                    $class = 'error';
                                }
                                break;
                            case 'string':
                                if (is_string($parms[$key])) {
                                    $parameters[] = $parms[$key];
                                } else {
                                    $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d should be a string.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
                                    $class = 'error';
                                }
                                break;
                            case 'bool':
                                switch (strtolower($parms[$key])) {
                                    case "true":
                                        $parameters[] = true;
                                        break;
                                    case "false":
                                        $parameters[] = false;
                                        break;
                                    default:
                                        $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d should be <code>true</code> or <code>false</code>.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
                                        $class = 'error';
                                        break;
                                }
                                break;
                            case 'array':
                                $l = array_slice($parms, $key);
                                $parms = array();
                                foreach ($l as $key => $p) {
                                    $x = explode('=', $p);
                                    if (count($x) == 2) {
                                        $parms[$x[0]] = $x[1];
                                    } else {
                                        $parms[$key] = $x[0];
                                    }
                                }
                                $parameters[] = $parms;
                                break;
                            default:
                                $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d is incorrectly defined.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
                                $class = 'error';
                                break;
                        }
                    } else {
                        if (strpos($type, '*') === false) {
                            $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> parameter %2$d is missing.'), trim($macro_instance, '[]'), $key + 1) . '</span>';
                            $class = 'error';
                        }
                        break;
                    }
                }
            } else {
                if (!empty($p)) {
                    $class = 'error';
                    $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> macro does not take parameters'), trim($macro_instance, '[]')) . '</span>';
                }
            }
            switch ($class) {
                case 'error':
                    break;
                case 'function':
                case 'procedure':
                    if (is_callable($macro['value'])) {
                        if ($class == 'function') {
                            ob_start();
                            $data = call_user_func_array($macro['value'], $parameters);
                            if (empty($data)) {
                                $data = ob_get_contents();
                            }
                            ob_end_clean();
                        } else {
                            ob_start();
                            call_user_func_array($macro['value'], $parameters);
                            $data = ob_get_contents();
                            ob_end_clean();
                        }
                        if (empty($data)) {
                            $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> retuned no data'), trim($macro_instance, '[]')) . '</span>';
                        } else {
                            $data = "\n<!--Begin " . $macroname . "-->\n" . $data . "\n<!--End " . $macroname . "-->\n";
                        }
                    } else {
                        $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> <code>%2$s</code> is not callable'), trim($macro_instance, '[]'), $macro['value']) . '</span>';
                    }
                    break;
                case 'constant':
                    $data = "\n<!--Begin " . $macroname . "-->\n" . $macro['value'] . "\n<!--End " . $macroname . "-->\n";
                    break;
                case 'expression':
                    $expression = '$data = ' . $macro['value'];
                    $parms = array_reverse($parms, true);
                    preg_match_all('/\\$\\d+/', $macro['value'], $replacements);
                    foreach ($replacements as $rkey => $v) {
                        if (empty($v)) {
                            unset($replacements[$rkey]);
                        }
                    }
                    if (count($parms) == count($replacements)) {
                        foreach ($parms as $key => $value) {
                            $key++;
                            $expression = preg_replace('/\\$' . $key . '/', db_quote($value), $expression);
                        }
                        eval($expression);
                        if (!isset($data) || is_null($data)) {
                            $data = '<span class="error">' . sprintf(gettext('<em>[%1$s]</em> retuned no data'), trim($macro_instance, '[]')) . '</span>';
                        } else {
                            $data = "\n<!--Begin " . $macroname . "-->\n" . $data . "\n<!--End " . $macroname . "-->\n";
                        }
                    } else {
                        $data = '<span class="error">' . sprintf(ngettext('<em>[%1$s]</em> takes %2$d parameter', '<em>[%1$s]</em> takes %2$d parameters', count($replacements)), trim($macro_instance, '[]'), count($replacements)) . '</span>';
                    }
                    break;
            }
            $text = str_replace($macro_instance, $data, $text);
        }
    }
    return $text;
}