Welcome Guest, Not a member yet? Register   Sign In
Extend core libraries to detect the request file type and load applicable view
#1

[eluser]Unknown[/eluser]
I extend core libraries to detect the request file type and load applicable view.

What I want to do is that if user request 'http://localhost/ci/blogs/index.xml', it will try to load a view for XML. In other cases:
If request 'blogs/index', load 'views/index.php' to render HTML document (default type).
If request 'blogs/index.xml', load 'views/index.xml.php' to render XML document.
If request 'blogs/index.pdf', load 'views/index.pdf.php' to render PDF document.
and so on.

Code:
class MY_URI extends CI_URI {
    var $requestExt = false;   // The request extension name.

    function _explode_segments()
    {
        foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
        {
            // Filter segments for security
            $val = trim($this->_filter_uri($val));
            
            if ($val != '')
                $this->segments[] = $val;
        }

        $refLastSegment =& $this->segments[count($this->segments)-1];
        if ( preg_match('/(.+)\.(\w+)$/', $refLastSegment, $matches) ) {
            $refLastSegment = $matches[1];
            $this->requestExt = strtolower($matches[2]);
        }
    }

    /**
     * Fetch the file extension.
     *
     * If user request 'http://localhost/ci_test/index.php/control/index.xml',
     * this will return 'xml'.              
     *
     * @access    public
     * @return    string
     */
    function extension()
    {
        return $this->requestExt;
    }
}

Code:
class MY_Loader extends CI_Loader {
    function _ci_load($_ci_data)
    {
        $CI =& get_instance();
        @include(APPPATH.'config/mimes'.EXT);
        $docExt = $CI->uri->extension();

        // Set the default data variables
        foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
        {
            $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
        }

        // Set the path to the requested file
        $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
        if ($_ci_path == '')
        {
            //$_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;
            if ($_ci_ext == '') {
                $_ci_file = $_ci_view
                    . ($docExt ? '.' . $docExt : '')
                    . EXT;
            }
            else {
                $_ci_file = $_ci_view;
            }
            
            $_ci_path = $this->_ci_view_path . $_ci_file;
            
            if ( !file_exists($_ci_path) and $docExt == 'html') {
                $_ci_path = $this->_ci_view_path . $_ci_view . EXT;
            }
        }
        else
        {
            $_ci_x = explode('/', $_ci_path);
            $_ci_file = end($_ci_x);
        }
        
        if ( ! file_exists($_ci_path))
        {
            show_error('Unable to load the requested file: '.$_ci_file);
        }
    
        if ( $docExt and !isset($mimes[$docExt]) ) {
            show_error('The requested document type is not accepted: '.$docExt);
        }

        if ( $docExt and $_ci_ext == '') {
            $mimeType = $mimes[$docExt];
            $CI->output->set_header('Content-type: ' . $mimeType);
            log_message('debug', 'File MIME Type: ' . $mimeType);
        }

        if ($this->_ci_is_instance())
        {
            $_ci_CI =& get_instance();
            foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
            {
                if ( ! isset($this->$_ci_key))
                {
                    $this->$_ci_key =& $_ci_CI->$_ci_key;
                }
            }
        }

        if (is_array($_ci_vars))
        {
            $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
        }
        extract($this->_ci_cached_vars);
                
        ob_start();
                
        if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
        {
            echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))).'<?php ');
        }
        else
        {
            include($_ci_path);
        }
        
        log_message('debug', 'File loaded: '.$_ci_path);
        
        // Return the file data if requested
        if ($_ci_return === TRUE)
        {        
            $buffer = ob_get_contents();
            @ob_end_clean();
            return $buffer;
        }

        if (ob_get_level() > $this->_ci_ob_level + 1)
        {
            ob_end_flush();
        }
        else
        {
            // PHP 4 requires that we use a global
            global $OUT;
            $OUT->append_output(ob_get_contents());
            @ob_end_clean();
        }
    }
}
#2

[eluser]wiredesignz[/eluser]
I dislike core hacks for such a trivial thing. The same thing can be acheived using routes and the _remap() function, I have tested and _remap() gets passed the page.ext value from the url. its then easy to determine the extension and do your stuff. Wink
#3

[eluser]Spockz[/eluser]
Could you eleborate that? I want to use a very similar functionality. Instead of using *.extension.php I want to use extension/*.php.

How would you accomplish this?
#4

[eluser]xwero[/eluser]
Why not use /blogs, /blogs/xml, /blogs/pdf if the only task is to serve a different file type. In your controller you do
Code:
// fetch data
$type = $this->uri->segment(2);
switch($type)
{
   case 'xml': break;
   case 'pdf': break;
   case FALSE: break;
}
#5

[eluser]louis w[/eluser]
I have been thinking of doing something like this. I think I am going to use the routes to change output format

http://localhost/blogs/view/1234 or http://localhost/_html/blogs/view/1234 >> output normally/html
http://localhost/_xml/blogs/view/1234 >> output as xml
http://localhost/_pdf/blogs/view/1234 >> output as pdf
http://localhost/_json/blogs/view/1234 >> output as json

It's only an idea at this point, not fully realized.
#6

[eluser]xwero[/eluser]
Why make it hard when it can be easy?

shirock wants urls like blogs/index, blogs/index.xml, blogs/index.pdf. CI makes it possible not to use the default function which means less typing for the users.

Louis w the extension is located at the end so why do you want to add it as a prefix?

Coding standards state make everything as readable and as short as possible this is also the case when you set up a url schema.
#7

[eluser]louis w[/eluser]
How would you switch the output on the extension? _remap?
#8

[eluser]xwero[/eluser]
check response 3 of this thread.
#9

[eluser]louis w[/eluser]
You are contradicting yourself - #3 says to test against uri segment, but you say this in post #5

Quote:shirock wants urls like blogs/index, blogs/index.xml, blogs/index.pdf. CI makes it possible not to use the default function which means less typing for the users.
#10

[eluser]xwero[/eluser]
By that sentence i mean you can remove index from the url. You only need to add the extension if you want another output than the default output.




Theme © iAndrew 2016 - Forum software by © MyBB