Вход Регистрация
Файл: tyde/www/system/core/Router.php
Строк: 394
<?php
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP
 *
 * This content is released under the MIT License (MIT)
 *
 * Copyright (c) 2014 - 2016, British Columbia Institute of Technology
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * @package    CodeIgniter
 * @author    EllisLab Dev Team
 * @copyright    Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
 * @copyright    Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/)
 * @license    http://opensource.org/licenses/MIT    MIT License
 * @link    https://codeigniter.com
 * @since    Version 1.0.0
 * @filesource
 */
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Router Class
 *
 * Parses URIs and determines routing
 *
 * @package        CodeIgniter
 * @subpackage    Libraries
 * @category    Libraries
 * @author        EllisLab Dev Team
 * @link        https://codeigniter.com/user_guide/general/routing.html
 */
class CI_Router {

    
/**
     * CI_Config class object
     *
     * @var    object
     */
    
public $config;

    
/**
     * List of routes
     *
     * @var    array
     */
    
public $routes =    array();

    
/**
     * Current class name
     *
     * @var    string
     */
    
public $class =        '';

    
/**
     * Current method name
     *
     * @var    string
     */
    
public $method =    'index';

    
/**
     * Sub-directory that contains the requested controller class
     *
     * @var    string
     */
    
public $directory;

    
/**
     * Default controller (and method if specific)
     *
     * @var    string
     */
    
public $default_controller;

    
/**
     * Translate URI dashes
     *
     * Determines whether dashes in controller & method segments
     * should be automatically replaced by underscores.
     *
     * @var    bool
     */
    
public $translate_uri_dashes FALSE;

    
/**
     * Enable query strings flag
     *
     * Determines whether to use GET parameters or segment URIs
     *
     * @var    bool
     */
    
public $enable_query_strings FALSE;

    
// --------------------------------------------------------------------

    /**
     * Class constructor
     *
     * Runs the route mapping function.
     *
     * @param    array    $routing
     * @return    void
     */
    
public function __construct($routing NULL)
    {
        
$this->config =& load_class('Config''core');
        
$this->uri =& load_class('URI''core');

        
$this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE);

        
// If a directory override is configured, it has to be set before any dynamic routing logic
        
is_array($routing) && isset($routing['directory']) && $this->set_directory($routing['directory']);
        
$this->_set_routing();

        
// Set any routing overrides that may exist in the main index file
        
if (is_array($routing))
        {
            empty(
$routing['controller']) OR $this->set_class($routing['controller']);
            empty(
$routing['function'])   OR $this->set_method($routing['function']);
        }

        
log_message('info''Router Class Initialized');
    }

    
// --------------------------------------------------------------------

    /**
     * Set route mapping
     *
     * Determines what should be served based on the URI request,
     * as well as any "routes" that have been set in the routing config file.
     *
     * @return    void
     */
    
protected function _set_routing()
    {
        
// Load the routes.php file. It would be great if we could
        // skip this for enable_query_strings = TRUE, but then
        // default_controller would be empty ...
        
if (file_exists(APPPATH.'config/routes.php'))
        {
            include(
APPPATH.'config/routes.php');
        }

        if (
file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
        {
            include(
APPPATH.'config/'.ENVIRONMENT.'/routes.php');
        }

        
// Validate & get reserved routes
        
if (isset($route) && is_array($route))
        {
            isset(
$route['default_controller']) && $this->default_controller $route['default_controller'];
            isset(
$route['translate_uri_dashes']) && $this->translate_uri_dashes $route['translate_uri_dashes'];
            unset(
$route['default_controller'], $route['translate_uri_dashes']);
            
$this->routes $route;
        }

        
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
        // since URI segments are more search-engine friendly, but they can optionally be used.
        // If this feature is enabled, we will gather the directory/class/method a little differently
        
if ($this->enable_query_strings)
        {
            
// If the directory is set at this time, it means an override exists, so skip the checks
            
if ( ! isset($this->directory))
            {
                
$_d $this->config->item('directory_trigger');
                
$_d = isset($_GET[$_d]) ? trim($_GET[$_d], " tnrx0B/") : '';

                if (
$_d !== '')
                {
                    
$this->uri->filter_uri($_d);
                    
$this->set_directory($_d);
                }
            }

            
$_c trim($this->config->item('controller_trigger'));
            if ( ! empty(
$_GET[$_c]))
            {
                
$this->uri->filter_uri($_GET[$_c]);
                
$this->set_class($_GET[$_c]);

                
$_f trim($this->config->item('function_trigger'));
                if ( ! empty(
$_GET[$_f]))
                {
                    
$this->uri->filter_uri($_GET[$_f]);
                    
$this->set_method($_GET[$_f]);
                }

                
$this->uri->rsegments = array(
                    
=> $this->class,
                    
=> $this->method
                
);
            }
            else
            {
                
$this->_set_default_controller();
            }

            
// Routing rules don't apply to query strings and we don't need to detect
            // directories, so we're done here
            
return;
        }

        
// Is there anything to parse?
        
if ($this->uri->uri_string !== '')
        {
            
$this->_parse_routes();
        }
        else
        {
            
$this->_set_default_controller();
        }
    }

    
// --------------------------------------------------------------------

    /**
     * Set request route
     *
     * Takes an array of URI segments as input and sets the class/method
     * to be called.
     *
     * @used-by    CI_Router::_parse_routes()
     * @param    array    $segments    URI segments
     * @return    void
     */
    
protected function _set_request($segments = array())
    {
        
$segments $this->_validate_request($segments);
        
// If we don't have any segments left - try the default controller;
        // WARNING: Directories get shifted out of the segments array!
        
if (empty($segments))
        {
            
$this->_set_default_controller();
            return;
        }

        if (
$this->translate_uri_dashes === TRUE)
        {
            
$segments[0] = str_replace('-''_'$segments[0]);
            if (isset(
$segments[1]))
            {
                
$segments[1] = str_replace('-''_'$segments[1]);
            }
        }

        
$this->set_class($segments[0]);
        if (isset(
$segments[1]))
        {
            
$this->set_method($segments[1]);
        }
        else
        {
            
$segments[1] = 'index';
        }

        
array_unshift($segmentsNULL);
        unset(
$segments[0]);
        
$this->uri->rsegments $segments;
    }

    
// --------------------------------------------------------------------

    /**
     * Set default controller
     *
     * @return    void
     */
    
protected function _set_default_controller()
    {
        if (empty(
$this->default_controller))
        {
            
show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
        }

        
// Is the method being specified?
        
if (sscanf($this->default_controller'%[^/]/%s'$class$method) !== 2)
        {
            
$method 'index';
        }

        if ( ! 
file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php'))
        {
            
// This will trigger 404 later
            
return;
        }

        
$this->set_class($class);
        
$this->set_method($method);

        
// Assign routed segments, index starting from 1
        
$this->uri->rsegments = array(
            
=> $class,
            
=> $method
        
);

        
log_message('debug''No URI present. Default controller set.');
    }

    
// --------------------------------------------------------------------

    /**
     * Validate request
     *
     * Attempts validate the URI request and determine the controller path.
     *
     * @used-by    CI_Router::_set_request()
     * @param    array    $segments    URI segments
     * @return    mixed    URI segments
     */
    
protected function _validate_request($segments)
    {
        
$c count($segments);
        
$directory_override = isset($this->directory);

        
// Loop through our segments and return as soon as a controller
        // is found or when such a directory doesn't exist
        
while ($c-- > 0)
        {
            
$test $this->directory
                
.ucfirst($this->translate_uri_dashes === TRUE str_replace('-''_'$segments[0]) : $segments[0]);

            if ( ! 
file_exists(APPPATH.'controllers/'.$test.'.php')
                && 
$directory_override === FALSE
                
&& is_dir(APPPATH.'controllers/'.$this->directory.$segments[0])
            )
            {
                
$this->set_directory(array_shift($segments), TRUE);
                continue;
            }

            return 
$segments;
        }

        
// This means that all segments were actually directories
        
return $segments;
    }

    
// --------------------------------------------------------------------

    /**
     * Parse Routes
     *
     * Matches any routes that may exist in the config/routes.php file
     * against the URI to determine if the class/method need to be remapped.
     *
     * @return    void
     */
    
protected function _parse_routes()
    {
        
// Turn the segment array into a URI string
        
$uri implode('/'$this->uri->segments);

        
// Get HTTP verb
        
$http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli';

        
// Loop through the route array looking for wildcards
        
foreach ($this->routes as $key => $val)
        {
            
// Check if route format is using HTTP verbs
            
if (is_array($val))
            {
                
$val array_change_key_case($valCASE_LOWER);
                if (isset(
$val[$http_verb]))
                {
                    
$val $val[$http_verb];
                }
                else
                {
                    continue;
                }
            }

            
// Convert wildcards to RegEx
            
$key str_replace(array(':any'':num'), array('[^/]+''[0-9]+'), $key);

            
// Does the RegEx match?
            
if (preg_match('#^'.$key.'$#'$uri$matches))
            {
                
// Are we using callbacks to process back-references?
                
if ( ! is_string($val) && is_callable($val))
                {
                    
// Remove the original string from the matches array.
                    
array_shift($matches);

                    
// Execute the callback using the values in matches as its parameters.
                    
$val call_user_func_array($val$matches);
                }
                
// Are we using the default routing method for back-references?
                
elseif (strpos($val'$') !== FALSE && strpos($key'(') !== FALSE)
                {
                    
$val preg_replace('#^'.$key.'$#'$val$uri);
                }

                
$this->_set_request(explode('/'$val));
                return;
            }
        }

        
// If we got this far it means we didn't encounter a
        // matching route so we'll set the site default route
        
$this->_set_request(array_values($this->uri->segments));
    }

    
// --------------------------------------------------------------------

    /**
     * Set class name
     *
     * @param    string    $class    Class name
     * @return    void
     */
    
public function set_class($class)
    {
        
$this->class str_replace(array('/''.'), ''$class);
    }

    
// --------------------------------------------------------------------

    /**
     * Fetch the current class
     *
     * @deprecated    3.0.0    Read the 'class' property instead
     * @return    string
     */
    
public function fetch_class()
    {
        return 
$this->class;
    }

    
// --------------------------------------------------------------------

    /**
     * Set method name
     *
     * @param    string    $method    Method name
     * @return    void
     */
    
public function set_method($method)
    {
        
$this->method $method;
    }

    
// --------------------------------------------------------------------

    /**
     * Fetch the current method
     *
     * @deprecated    3.0.0    Read the 'method' property instead
     * @return    string
     */
    
public function fetch_method()
    {
        return 
$this->method;
    }

    
// --------------------------------------------------------------------

    /**
     * Set directory name
     *
     * @param    string    $dir    Directory name
     * @param    bool    $append    Whether we're appending rather than setting the full value
     * @return    void
     */
    
public function set_directory($dir$append FALSE)
    {
        if (
$append !== TRUE OR empty($this->directory))
        {
            
$this->directory str_replace('.'''trim($dir'/')).'/';
        }
        else
        {
            
$this->directory .= str_replace('.'''trim($dir'/')).'/';
        }
    }

    
// --------------------------------------------------------------------

    /**
     * Fetch directory
     *
     * Feches the sub-directory (if any) that contains the requested
     * controller class.
     *
     * @deprecated    3.0.0    Read the 'directory' property instead
     * @return    string
     */
    
public function fetch_directory()
    {
        return 
$this->directory;
    }

}
Онлайн: 0
Реклама