NaszvadiG
4/17/2014 - 8:35 AM

MY_Router.php

<?php (defined('BASEPATH')) OR exit('No direct script access allowed');

// Load HMVC Router
require APPPATH . 'third_party/MX/Router.php';

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

/**
 * HMVC Router extension to support multilevel controller subfolders.
 *
 * @package		CodeIgniter
 * @author		Sepehr Lajevardi <me@sepehr.ws>
 * @copyright	Copyright (c) 2012 Sepehr Lajevardi.
 * @license		http://codeigniter.com/user_guide/license.html
 * @link		https://github.com/sepehr/ci-maestro
 * @version 	Version 1.0
 * @filesource
 */

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

/**
 * HMVC Router extension to support multilevel controller subfolders.
 *
 * @package 	CodeIgniter
 * @subpackage	Libraries
 * @category	Libraries
 * @author		Sepehr Lajevardi <me@sepehr.ws>
 * @link		https://github.com/sepehr/ci-maestro
 */
class MY_Router extends MX_Router {

	/**
	 * Routes URI segments to the proper module/app controller.
	 *
	 * NOTE: It's a override of MX_Router's locate() method
	 * to support multilevel controller subfolders.
	 *
	 * @param array $segments URI segments
	 * @return array
	 */
	public function locate($segments)
	{
		$this->module = $this->directory = '';
		$ext = $this->config->item('controller_suffix') . EXT;

		// Use module route if available
		if (isset($segments[0]) AND $routes = Modules::parse_routes($segments[0], implode('/', $segments)))
		{
			$segments = $routes;
		}

		// Get the segments array elements
		list($module, $directory, $controller) = array_pad($segments, 3, NULL);

		// ------------------------------------------------------------------------
		// 1. Check modules (recursive)
		// ------------------------------------------------------------------------
		foreach (Modules::$locations as $location => $offset)
		{
			// Module controllers/ exists?
			if (is_dir($source = $location . $module . '/controllers/'))
			{
				$this->module    = $module;
				$this->directory = $offset . $module . '/controllers/';

				// Temporary helper variables
				$base_directory = $this->directory;
				$segments_copy  = array_slice($segments, 1);

				do {
					// Update directory, if not in the first round
					if (isset($segments_copy[0]) AND $directory !== $segments_copy[0])
					{
						$this->directory  = $base_directory . $directory . '/';
						$directory       .= '/' . $segments_copy[0];
					}

					// Check if controller file exists
					if ($directory AND is_file($source . $directory . $ext))
					{
						return $segments_copy;
					}

					// Move forward through the segments
					$segments_copy = array_slice($segments_copy, 1);
				}
				while ( ! empty($segments_copy) AND $directory AND is_dir($source . $directory . '/'));

				// Check for default module-named controller
				if (is_file($source . $module . $ext))
				{
					$this->directory = $base_directory;
					return $segments;
				}
		 	}
		} // foreach

		// ------------------------------------------------------------------------
		// 2. Check app controllers in APPPATH/controllers/
		// ------------------------------------------------------------------------
		if (is_file(APPPATH . 'controllers/' . $module . $ext))
		{
			return $segments;
		}

		// Application sub-directory controller exists?
		if ($directory AND is_file(APPPATH . 'controllers/' . $module . '/' . $directory . $ext))
		{
			$this->directory = $module . '/';
			return array_slice($segments, 1);
		}

		// ------------------------------------------------------------------------
		// 4. Check multilevel sub-directories in APPPATH/controllers/
		// ------------------------------------------------------------------------
		if ($directory)
		{
			$dir = '';

			do {
				// Go forward in segments to check for directories
				empty($dir) OR $dir .= '/';
				$dir .= $segments[0];

				// Update segments array
				$segments = array_slice($segments, 1);
			}
			while (count($segments) > 0 AND is_dir(APPPATH . 'controllers/' . $dir . '/' . $segments[0]));

			// Set the directory and remove it from the segments array
			$this->directory = str_replace('.', '', $dir) . '/';

			// If no controller found, use 'default_controller' as defined in 'config/routes.php'
			if (count($segments) > 0
				AND ! file_exists(APPPATH . 'controllers/' . $this->fetch_directory() . $segments[0] . EXT))
			{
				array_unshift($segments, $this->default_controller);
			}
			else if (empty($segments) AND is_dir(APPPATH . 'controllers/' . $this->directory))
			{
				$segments = array($this->default_controller);
			}

			if (count($segments) > 0)
			{
				// Does the requested controller exist in the sub-folder?
				if ( ! file_exists(APPPATH . 'controllers/' . $this->fetch_directory() . $segments[0] . EXT))
				{
					$this->directory = '';
				}
			}

			if ($this->directory . $segments[0] != $module . '/' . $this->default_controller
				AND count($segments) > 0
				AND file_exists(APPPATH . 'controllers/' . $this->fetch_directory() . $segments[0] . EXT ) )
			{
				return $segments;
			}
		}

		// ------------------------------------------------------------------------
		// 5. Check application sub-directory default controller
		// ------------------------------------------------------------------------
		if (is_file(APPPATH . 'controllers/' . $module . '/' . $this->default_controller . $ext))
		{
			$this->directory = $module . '/';
			return array($this->default_controller);
		}
	}

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

}
// End of MY_Router class

/* End of file MY_Router.php */
/* Location: ./application/core/MY_Router.php */