Skip to content

Instantly share code, notes, and snippets.

@joomdonation
Created May 15, 2013 02:33
Show Gist options
  • Select an option

  • Save joomdonation/5581273 to your computer and use it in GitHub Desktop.

Select an option

Save joomdonation/5581273 to your computer and use it in GitHub Desktop.
Base controller for RAD for Joomla CMS
<?php
/**
* Base Controller Class
*
* Note: Concrete controllers must have a singular name
*
* @author Joomla
* @package RAD_Controller
*/
class RADController extends JControllerBase
{
/**
* Array which holde all the controllers has been created
* @var Array
*/
protected static $instances;
/**
* Full name of the component being dispatchaed com_foobar
* @var Array
*/
protected static $option;
/**
* Name of the component, use as prefix for controller, model and view classes
* @var string
*/
protected $component;
/**
* Current or most recently performed task.
*
* @var string
*/
protected $task;
/**
* Array of class methods to call for a given action.
*
* @var array
*/
protected $taskMap = array();
/**
* The path to component folder
* @var string
*/
protected $basePath;
/**
* Constructor.
*
* @param Array An optional Array with configuration options.
*/
/**
* Constructor.
*
* @param array $config An optional associative array of configuration settings.
* Recognized key values include 'name', 'default_task', 'model_path', and
* 'view_path' (this list is not meant to be comprehensive).
*
* @since 12.2
*/
public function __construct(JInput $input = null, JApplicationBase $app = null, $config = array())
{
parent::__construct($input, $app);
$this->taskMap = array();
// Determine the methods to exclude from the base class.
$xMethods = get_class_methods('RADController');
// Get the public methods in this class using reflection.
$r = new ReflectionClass($this);
$rMethods = $r->getMethods(ReflectionMethod::IS_PUBLIC);
foreach ($rMethods as $rMethod)
{
$mName = $rMethod->getName();
// Add default display method if not explicitly declared.
if (!in_array($mName, $xMethods) || $mName == 'display')
{
$this->methods[] = strtolower($mName);
// Auto register the methods as tasks.
$this->taskMap[strtolower($mName)] = $mName;
}
}
$this->basePath = $config['base_path'];
$this->component = $config['component'];
$this->task = $this->input->get('task', 'display');
// If the default task is set, register it as such
if (array_key_exists('default_task', $config))
{
$this->registerTask('__default', $config['default_task']);
}
else
{
$this->registerTask('__default', 'display');
}
// Set the default view.
if (array_key_exists('default_view', $config))
{
$this->default_view = $config['default_view'];
}
elseif (empty($this->default_view))
{
$this->default_view = $this->component;
}
}
/**
* Method to get a singleton controller instance.
*
* @param string $prefix The prefix for the controller.
* @param array $config An array of optional constructor options.
*
* @return JControllerLegacy
*
* @since 12.2
* @throws Exception if the controller cannot be loaded.
*/
public static function getInstance($config = array())
{
if (isset($config['app']))
$app = $config['app'];
else
$app = JFactory::getApplication();
if (isset($config['input']))
$input = $config['input'];
else
$input = $app->input;
$option = $input->get('option');
$view = $input->get('view');
if (!isset(self::$instances[$component . $view]))
{
if (isset($config['base_path']))
{
$basePath = $config['base_path'];
}
else
{
if ($app->isSite())
$basePath = JPATH_ROOT . '/components/' . $option;
else
$basePath = JPATH_ROOT . '/administrator/components/' . $option;
$config['base_path'] = $basePath;
}
$component = substr($option, 4);
$config['component'] = $component;
if ($view)
{
$class = ucfirst($component) . 'Controller' . ucfirst(JStringInflector::getInstance()->toSingular($view));
}
else
{
$class = ucfirst($component) . 'Controller';
}
//Fallback to default class
if (!class_exists($class))
{
if (isset($config['default_controller']))
$class = $config['default_controller'];
else
{
if ($app->isAdmin())
$class = 'RADControllerAdmin';
else
$class = 'RADController';
}
}
self::$instances[$option . $view] = $class($input, $app, $config);
}
return self::$instances[$option . $view];
}
/**
* Execute the task
* @see JController::execute()
*/
public function execute()
{
$task = $this->task;
$task = strtolower($task);
if (isset($this->taskMap[$task]))
{
$doTask = $this->taskMap[$task];
}
elseif (isset($this->taskMap['__default']))
{
$doTask = $this->taskMap['__default'];
}
else
{
throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND', $task), 404);
}
// Record the actual task being fired
$this->doTask = $doTask;
return $this->$doTask();
}
/**
* Typical view method for MVC based architecture
*
* This function is provide as a default implementation, in most cases
* you will need to override it in your own controllers.
*
* @param boolean $cachable If true, the view output will be cached
* @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}.
*
* @return JControllerLegacy A JControllerLegacy object to support chaining.
*
* @since 12.2
*/
public function display($cachable = false, $urlparams = array())
{
$document = JFactory::getDocument();
$viewType = $document->getType();
$viewName = $this->input->get('view', $this->default_view);
$viewLayout = $this->input->get('layout', 'default');
$view = $this->getView($viewName, $viewType, '', array('base_path' => $this->basePath, 'layout' => $viewLayout));
// Get/Create the model
if ($model = $this->getModel($viewName))
{
// Push the model into the view (as default)
$view->setModel($model, true);
}
$view->document = $document;
$conf = JFactory::getConfig();
// Display the view
if ($cachable && $viewType != 'feed' && $conf->get('caching') >= 1)
{
$option = $this->input->get('option');
$cache = JFactory::getCache($option, 'view');
if (is_array($urlparams))
{
$app = JFactory::getApplication();
if (!empty($app->registeredurlparams))
{
$registeredurlparams = $app->registeredurlparams;
}
else
{
$registeredurlparams = new stdClass();
}
foreach ($urlparams as $key => $value)
{
// Add your safe url parameters with variable type as value {@see JFilterInput::clean()}.
$registeredurlparams->$key = $value;
}
$app->registeredurlparams = $registeredurlparams;
}
$cache->get($view, 'display');
}
else
{
$view->display();
}
return $this;
}
/**
* Set the request information
*
* @param array An associative array of request information
* @return KControllerBread
*/
public function setInput(JInput $input)
{
$this->input = $input;
return $this;
}
/**
* Method to get a model object, loading it if required.
*
* @param string $name The model name. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for model. Optional.
*
* @return object The model.
*
* @since 12.2
*/
public function getModel($name = '', $config = array())
{
if (empty($name))
{
$name = $this->getName();
}
// We will call RADModel::getInstance to init the model here
$model = new RADModel();
//TODO:Decide whether we need the block of code below or not
$model->setState('task', $this->task);
// Let's get the application object and set menu information if it's available
$app = JFactory::getApplication();
$menu = $app->getMenu();
if (is_object($menu))
{
if ($item = $menu->getActive())
{
$params = $menu->getParams($item->id);
// Set default state data
$model->setState('parameters.menu', $params);
}
}
return $model;
}
/**
* Method to get a reference to the current view and load it if necessary.
*
* @param string $name The view name. Optional, defaults to the controller name.
* @param string $type The view type. Optional.
* @param string $prefix The class prefix. Optional.
* @param array $config Configuration array for view. Optional.
*
* @return JViewLegacy Reference to the view or an error.
*
* @since 12.2
* @throws Exception
*/
public function getView($name = '', $type, $config = array())
{
if (empty($name))
$name = $this->component;
//Call RADView::getInstance to get an instance of the view
//TODO: Should we get the model and add it to the view here?
}
/**
* Get the last task that is being performed or was most recently performed.
*
* @return string The task that is being performed or was most recently performed.
*
* @since 12.2
*/
public function getTask()
{
return $this->task;
}
/**
* Register the default task to perform if a mapping is not found.
*
* @param string $method The name of the method in the derived class to perform if a named task is not found.
*
* @return JControllerLegacy A JControllerLegacy object to support chaining.
*
* @since 12.2
*/
public function registerDefaultTask($method)
{
$this->registerTask('__default', $method);
return $this;
}
/**
* Register (map) a task to a method in the class.
*
* @param string $task The task.
* @param string $method The name of the method in the derived class to perform for this task.
*
* @return JControllerLegacy A JControllerLegacy object to support chaining.
*
* @since 12.2
*/
public function registerTask($task, $method)
{
if (in_array(strtolower($method), $this->methods))
{
$this->taskMap[strtolower($task)] = $method;
}
return $this;
}
/**
* Unregister (unmap) a task in the class.
*
* @param string $task The task.
*
* @return JControllerLegacy This object to support chaining.
*
* @since 12.2
*/
public function unregisterTask($task)
{
unset($this->taskMap[strtolower($task)]);
return $this;
}
/**
* Set a request properties
*
* @param string The property name.
* @param mixed The property value.
*/
public function __set($property, $value)
{
$this->input->$property = $value;
}
/**
* Get a request property
*
* @param string The property name.
* @return string The property value.
*/
public function __get($property)
{
$result = null;
if (isset($this->input->$property))
{
$result = $this->input->$property;
}
return $result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment