<?php

if (!defined('BASEPATH')) {
    exit('No direct script access allowed');
}

/**
 * Description of page_parser
 *
 * @author Igor Ratsun
 */
class Ciext_parser
{

    protected $parsers = array();
    protected $l_delim = '{{';
    protected $r_delim = '}}';

    public function __construct()
    {
        $ci = & get_instance();
        $ci->load->allBootstrap();
        foreach ($ci->config->item('ciext_parser_alias_callback') as $alias => $callback) {
            $this->add_parser($alias, $callback);
        }
    }

    public function add_parser($alias, $callback)
    {
        $this->parsers[$alias] = $callback;
    }

    public function parse($string = '')
    {
        $matches = array();
        $pattern = '/' . $this->l_delim . '\s*(.*?)\((.*?)\)\s*' . $this->r_delim . '/';
        preg_match_all($pattern, $string, $matches);
        if (!empty($matches)) {
            foreach ($matches[0] as $k => $v) {
                $string = $this->replace($v, $matches[1][$k], $matches[2][$k], $string);
            }
        }

        return $string;
    }

    protected function replace($search, $parser_alias, $parser_params, $subject)
    {
        if (empty($this->parsers[$parser_alias])) {

            return $subject;
        }
        // Prepare params
        $params = array_map(function($v) {
            return trim(trim(trim($v), '"'), "'");
        }, explode('\',\'', preg_replace('([\'"]\s*,\s*[\'"])', '\',\'', $parser_params)));

        $callback = (!is_callable($this->parsers[$parser_alias])) ? array(get_instance()->load->library($this->parsers[$parser_alias]), 'parse') : $this->parsers[$parser_alias];

        return str_replace($search, (string) call_user_func_array($callback, $params), $subject);
    }

}
