Welcome Guest, Not a member yet? Register   Sign In
Template parser and helper functions
#1

[eluser]MarkoM[/eluser]
Hello!

I'm trying to use the Parser library included in CodeIgniter to parse my templates.

Everything works fine for placeholders like {test}, but how can I replace calls to helper functions, like these:
Code:
<link rel="stylesheet" href="<?php echo get_css_file('system'); ?>" type="text/css" />
<link rel="stylesheet" href="<?php echo get_css_file('general'); ?>" type="text/css" />
<link rel="stylesheet" href="<?php echo get_css_file('style'); ?>" type="text/css" />
<link rel="stylesheet" href="<?php echo get_css_file('color-green'); ?>" type="text/css" />

I'm trying to avoid having any php code in my view files.

Thank you!
#2

[eluser]Aken[/eluser]
Without modifying the Parser library, you'll need to set up those CSS file as normal tags, just like {test} and others.

Otherwise, to call the function inside the tag, you'll need to extend the Parser library and add your own functionality.
#3

[eluser]Ewout[/eluser]
A) Either put the css file locations in your passed data array to the view-file, so they can be accessed as variables.

B) As Aken stated, extend the Parser class to check for your function.
#4

[eluser]Aken[/eluser]
Thank you for repeating exactly what I said...
#5

[eluser]MarkoM[/eluser]
Thank you both for your input. I have extended parser library to include two more options:
a) parse stuff like {currentUser[Username]} , where $data["currentUser"] = get_object_vars($this->User_model->get_entity(1));
b) parse stuff like:
Code:
<link rel="stylesheet" href="{|get_css_file|(system)}" type="text/css" />

My implementation is here:
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Extends CodeIgniter's parser in order to enable parsing of unidimensional
* arrays and functions.
*
* @author Marko Marjanović
*/
class MY_Parser extends CI_Parser
{
    
    function _parse($template, $data, $return = FALSE)
    {
        if ($template == '')
        {
            return FALSE;
        }

        foreach ($data as $key => $val)
        {
            if (is_array($val))
            {
                if (!$this->is_multidimensional_array($val))
                {
                    $template = $this->_parse_onedimensional($key, $val, $template);
                }
                else
                {
                    $template = $this->_parse_pair($key, $val, $template);
                }
            }
            else
            {
                $template = $this->_parse_single($key, (string) $val, $template);
            }
        }

        // Now we seek to find any function placeholders to run
        $test = "|" . preg_quote($this->l_delim) . "\|(.+?)\|\((.*?)\)" . preg_quote($this->r_delim) . "|s";
        if ( preg_match_all($test, $template, $match))
        {
            if (is_array($match))
            {
                for ($a = 0; $a < count($match[0]); $a++)
                {
                    $func = $match[1][$a];
                    $params = explode (',', $match[2][$a]);
                    
                    $val = call_user_func_array($func, $params);
                    
                    $template = str_replace($match[0][$a], $val, $template);
                }
            }
        }
        
        if ($return == FALSE)
        {
            $CI = & get_instance();
            $CI->output->append_output($template);
        }

        return $template;
    }

    function _parse_onedimensional($mainKey, $data_array, $template)
    {
        foreach ($data_array as $key => $val)
        {
            $template = $this->_parse_single($mainKey . '[' . $key . ']', (string) $val, $template);
        }
        
        return $template;
    }
    
    /**
     * Checks if array is multidimensional
     *
     * @param type $a
     * @return boolean
     */
    private function is_multidimensional_array($val)
    {
        if (is_array($val))
        {
            foreach ($val as $v)
            {
                if (is_array($v))
                    return true;
            }
        }
        
        return false;
    }
}

Now, I'm very new at CodeIgniter (and php for that matter), so I don't know if this is a valid solution to my problem, so please comment on that.

Second thing that bothers me is that by implementing this extension, I've opened a giant security hole in my application...

Potentially, users could input "function call placeholder" into forum post text or anywhere else where they have right to enter some data.
While it's a very cool feature for some users to have access to (admins) and I wouldn't want to lose it, I need some way of escaping such input from normal users.

What is the best way of doing so? Is there a better way to implement such a simple extension to the parser?

Thank you!
#6

[eluser]MarkoM[/eluser]
Anyone?




Theme © iAndrew 2016 - Forum software by © MyBB