CodeIgniter Forums
Extend core libraries to detect the request file type and load applicable view - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: Extend core libraries to detect the request file type and load applicable view (/showthread.php?tid=6281)



Extend core libraries to detect the request file type and load applicable view - El Forum - 02-21-2008

[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();
        }
    }
}



Extend core libraries to detect the request file type and load applicable view - El Forum - 02-21-2008

[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


Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

[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?


Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

[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;
}



Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

[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.


Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

[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.


Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

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


Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

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


Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

[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.



Extend core libraries to detect the request file type and load applicable view - El Forum - 03-27-2008

[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.