$list) { foreach ($list as $filename) { $basename = basename($filename); $basename = preg_replace('/\.(tpl|xml)$/', '', $basename); list($subtype, $name) = explode('_', $basename, 2); $template_array[$type][$subtype] = strtolower($name); } } return $template_array; } /** * This is very-very-very simple template engine (or not simple?), * only some basic conversions and uses Mustache/CTemplate syntax. * * no cache/logging and others, for now support only this tags: * standart php comments * {{! %^ }} - intext comments * {{var}} - escaped var * {{{var}}} - unescaped var * {{var.subvar}} - dot notation vars * {{.}} - implicit iterator * {{#var}} some text {{/var}} - if/list condition * {{^var}} some text {{/var}} - inverted (negative) if condition * options: * 'is_file', if set to TRUE, than get template from file $config['install_dir']/includes/templates/$template.tpl * if set to FALSE (default), than use template from variable. */ // NOTE, do NOT use this function for generate pages, as adama said! function simple_template($template, $tags, $options = array('is_file' => FALSE, 'use_cache' => FALSE)) { if (!is_string($template) || !is_array($tags)) { // Return false if template not string (or filename) and tags not array return FALSE; } if (isset($options['is_file']) && $options['is_file']) { // Get template from file $template = get_template('notification', $template); // Return false if no file content or false file read if (!$template) { return FALSE; } } // Cache disabled for now, i think this can generate huge array /** $use_cache = isset($options['use_cache']) && $options['use_cache'] && $tags; if ($use_cache) { global $cache; $timestamp = time(); $template_csum = md5($template); $tags_csum = md5(json_encode($tags)); if (isset($cache['templates'][$template_csum][$tags_csum])) { if (($timestamp - $cache['templates'][$template_csum][$tags_csum]['timestamp']) < 600) { return $cache['templates'][$template_csum][$tags_csum]['string']; } } } */ // convert windows end lines to unix $string = preg_replace('/\r\n/', "\n", $template); // Removes multi-line comments and does not create // a blank line, also treats white spaces/tabs $string = preg_replace('![ \t]*/\*.*?\*/[ \t]*[\r\n]?!s', '', $string); // Removes single line '//' comments, treats blank characters $string = preg_replace('![ \t]*//.*[ \t]*[\r\n]?!', '', $string); // Removes in-text comments {{! any text }} $string = preg_replace('/{{!.*?}}/', '', $string); // Strip blank lines //$string = preg_replace('/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', PHP_EOL, $string); // Replace keys, loops and other template syntax $string = simple_template_replace($string, $tags); /** if ($use_cache) { $cache['templates'][$template_csum][$tags_csum] = array('timestamp' => $timestamp, 'string' => $string); } */ return $string; } function simple_template_replace($string, $tags) { // Note for future: to match Unix LF (\n), MacOS<9 CR (\r), Windows CR+LF (\r\n) and rare LF+CR (\n\r) // EOL patern should be: /((\r?\n)|(\n?\r))/ $patterns = array( // {{#var}} some text {{/var}} 'list_condition' => '![ \t]*{{#[ \t]*([ \w[:punct:]]+?)[ \t]*}}[ \t]*[\r\n]?(.*?){{/[ \t]*\1[ \t]*}}[ \t]*([\r\n]?)!s', // {{^var}} some text {{/var}} 'negative_condition' => '![ \t]*{{\^[ \t]*([ \w[:punct:]]+?)[ \t]*}}[ \t]*[\r\n]?(.*?){{/[ \t]*\1[ \t]*}}[ \t]*([\r\n]?)!s', // {{{var}}} 'var_noescape' => '!{{{[ \t]*([^}{#\^\?/]+?)[ \t]*}}}!', // {{var}} 'var_escape' => '!{{[ \t]*([^}{#\^\?/]+?)[ \t]*}}!', ); // Main loop foreach ($patterns as $condition => $pattern) { switch ($condition) { // LIST condition first! case 'list_condition': // NEGATIVE condition second! case 'negative_condition': if (preg_match_all($pattern, $string, $matches)) { foreach ($matches[1] as $key => $var) { $test_tags = isset($tags[$var]) && $tags[$var]; if (($condition == 'list_condition' && $test_tags) || ($condition == 'negative_condition' && !$test_tags)) { $replace = preg_replace('/[\t\ ]+$/', '', $matches[2][$key]); //if (!$matches[3][$key]) //{ // // Remove last newline if condition at EOF // $replace = preg_replace('/[\r\n]$/', '', $replace); //} if ($condition == 'list_condition' && is_array($tags[$var])) { // Additional remove first newline if pressent $replace = preg_replace('/^[\r\n]/', '', $matches[2][$key]); // If tag is array, use recurcive repeater $repeate = array(); foreach ($tags[$var] as $item => $entry) { $repeate[] = simple_template_replace($replace, $entry); } $replace = implode('', $repeate); } } else { $replace = ''; } $string = str_replace($matches[0][$key], $replace, $string); } } break; // Next var not escaped case 'var_noescape': // Next var escaped case 'var_escape': if (preg_match_all($pattern, $string, $matches)) { foreach ($matches[1] as $key => $var) { if ($var === '.' && is_string($tags)) { // This conversion for implicit iterator {{.}} $tags = array('.' => $tags); $subvars = array(); } else { $subvars = explode('.', $var); } if (isset($tags[$var])) { // {{ var }}, {{{ var_noescape }}} $replace = ($condition === 'var_noescape' ? $tags[$var] : htmlspecialchars($tags[$var], ENT_QUOTES, 'UTF-8')); } else if (count($subvars) > 1 && is_array($tags[$subvars[0]])) { // {{ var.with.iterator }}, {{{ var.with.iterator.noescape }}} $replace = $tags[$subvars[0]]; array_shift($subvars); foreach ($subvars as $subvar) { if (isset($replace[$subvar])) { $replace = $replace[$subvar]; } else { unset($replace); break; } } $replace = ($condition === 'var_noescape' ? $replace : htmlspecialchars($replace, ENT_QUOTES, 'UTF-8')); } else { // By default if tag not exist, remove var from template $replace = ''; } $string = str_replace($matches[0][$key], $replace, $string); } } break; } } //var_dump($string); return $string; } /** * This function convert array based group/alerts to observium xml based template * * Template attributes: * type - Type (ie: alert, group, notification) * description - Description * version - Template format version * created - Created date * observium - Used observium version * id - Unique template id, based on conditions/associations/text * * Template params: * entity - Type of entity * name - Unique name for current set of params * description - Description for current set of params * message - Text message * conditions - Set of conditions * conditions_and - 1 - require all conditions, 0 - require any condition * conditions_complex - oneline conditions set (not used for now) * associations - Set of associations * device - Set of device associations * entity - Set of entity associations * * @param string $type Current template type for generate (alert or group) * @param array $params * @param boolean $as_xml_object If set to TRUE, return template as SimpleXMLElement object * * @return mixed XML based template (as string or SimpleXMLElement object if $as_xml_object set to true) */ function generate_template($type, $params, $as_xml_object = FALSE) { if (!check_extension_exists('SimpleXML', 'SimpleXML php extension not found, it\'s required for generate templates.')) { return ''; } // r($params); var_export($params); $type = strtolower(trim($type, " '\"\t\n\r\0\x0B")); // Clean template type $template_xml = new SimpleXMLElement('