methods = array(); $this->message = null; $this->messageType = 'message'; //$this->paths = array(); $this->redirect = null; $this->taskMap = array(); if (defined('JDEBUG') && JDEBUG) { JLog::addLogger(array('text_file' => 'jcontroller.log.php'), JLog::ALL, array('controller')); } if(!(vFactory::$_db)){ vFactory::getDbo(); } $this->input = vFactory::getApplication()->input; // Determine the methods to exclude from the base class. $xMethods = get_class_methods('vController'); // 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; } } // Set the view name if (empty($this->_name)) { $this->_name = $this->getName(); } $this->basePath = VMPATH_COMPONENT; //$this->addIncludePath($this->basePath . '/views','view'); $this->registerDefaultTask('display'); $this->default_view = $this->getName(); vBasicModel::addIncludePath(VMPATH_ADMIN.'/vmf/html','html'); } /** * Method to check whether an ID is in the edit list. * * @param string $context The context for the session storage. * @param integer $id The ID of the record to add to the edit list. * * @return boolean True if the ID is in the edit list. * * @since 12.2 */ protected function checkEditId($context, $id) { if ($id) { $app = vFactory::getApplication(); $values = (array) $app->getUserState($context . '.id'); $result = in_array((int) $id, $values); if (defined('JDEBUG') && JDEBUG) { JLog::add( sprintf( 'Checking edit ID %s.%s: %d %s', $context, $id, (int) $result, str_replace("\n", ' ', print_r($values, 1)) ), JLog::INFO, 'controller' ); } return $result; } else { // No id for a new item. return true; } } /** * Fallback to keep compatibility * @param $path * @return $this */ public function addViewPath($path) { self::addIncludePath($path, 'view'); return $this; } /** * Method to load and return a view object. This method first looks in the * current template directory for a match and, failing that, uses a default * set path to load the view class file. * * Note the "name, prefix, type" order of parameters, which differs from the * "name, type, prefix" order used in related public methods. * * @param string $name The name of the view. * @param string $prefix Optional prefix for the view class name. * @param string $type The type of view. * @param array $config Configuration array for the view. Optional. * * @return mixed View object on success; null or error result on failure. * * @since 12.2 * @note Replaces _createView. * @throws Exception */ //protected function createView($name, $prefix = '', $type = '', $config = array()) static public function createView($name,$prefix,$config = array()) { $type = isset($config['type'])?$config['type']:'html'; // Clean the view name $view = preg_replace('/[^A-Z0-9_]/i', '', $name); $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type); $type = strtolower($type); $prefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix); $class = $prefix . ucfirst($view); //$single = false; if(empty(self::$_loadedClasses[$class])){ //$admin =vFactory::getApplication()->isAdmin(); $manage = vRequest::getCmd ( 'managing',false); //We add the viewpath if($manage){ self::addIncludePath(VMPATH_ADMIN.'/views/'.$name,'view'); } else { self::addIncludePath(VMPATH_COMPONENT.'/views/'.$name,'view'); } if (!class_exists($class)) { self::loader('view.'.$type, 'view',$class); } if (class_exists($class)){ self::$_loadedClasses[$class] = self::getInstance($name,$prefix ); $name = strtolower($view); if($manage){ self::$_loadedClasses[$class]->addLayoutPath($name, VMPATH_ADMIN .'/views/'. $name . '/tmpl'); $unoverridable = array('category', 'manufacturer', 'user','virtuemart'); //This views have the same name and must not be overridable if(!in_array( $name, $unoverridable )) { if(!class_exists( 'VmTemplate' )) require(VMPATH_SITE.'/helpers/vmtemplate.php'); $template = VmTemplate::getDefaultTemplate(); self::$_loadedClasses[$class]->addLayoutPath( $name, VMPATH_ROOT.'/templates/'.$template['template'].'/html/com_virtuemart/'.$name, 'view' ); } } else { self::$_loadedClasses[$class]->addLayoutPath($name, VMPATH_COMPONENT.'/views/'. $name . '/tmpl'); $template = vFactory::getApplication()->getTemplate(); self::$_loadedClasses[$class]->addLayoutPath($name, VMPATH_BASE . '/templates/' . $template . '/html/com_virtuemart/'. $name); } } else { vmEcho::$echoDebug=1; vmdebug('createView '.$class.' not available' ,self::$_paths); vmWarn(vmText::sprintf('JLIB_APPLICATION_ERROR_MODELCLASS_NOT_FOUND', $class)); return false; } } return self::$_loadedClasses[$class]; } /** * 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 = vFactory::getDocument(); $viewType = $document->getType(); $viewName = $this->input->get('view', $this->default_view); $viewLayout = $this->input->get('layout', 'default', 'string'); $view = $this->getView($viewName, $viewType, '', array('base_path' => $this->basePath, 'layout' => $viewLayout)); $view->document = $document; $conf = vFactory::getConfig(); // Display the view if ($cachable && $viewType != 'feed' && $conf->get('caching') >= 1) { $option = $this->input->get('option'); $cache = vFactory::getCache($option, 'view'); if (is_array($urlparams)) { $app = vFactory::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; } /** * Execute a task by triggering a method in the derived class. * * @param string $task The task to perform. If no matching task is found, the '__default' task is executed, if defined. * * @return mixed The value returned by the called method, false in error case. * * @since 12.2 * @throws Exception */ public function execute($task) { $this->task = $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(vmText::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND', $task), 404); } // Record the actual task being fired $this->doTask = $doTask; return $this->$doTask(); } /** * Method to get the controller name * * The dispatcher name is set by default parsed using the classname, or it can be set * by passing a $config['name'] in the class constructor * * @return string The name of the dispatcher * * @since 12.2 * @throws Exception */ public function getName() { if (empty($this->_name)) { $r = null; if (!preg_match('/(.*)Controller/i', get_class($this), $r)) { throw new Exception(vmText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME'), 500); } $this->_name = strtolower($r[1]); } return $this->_name; } /** * 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; } /** * Gets the available tasks in the controller. * * @return array Array[i] of task names. * * @since 12.2 */ public function getTasks() { return $this->methods; } /** * 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 = '', $prefix = '', $config = array()) { // @note We use self so we only access stuff in this class rather than in all classes. if (!isset(self::$views)) { self::$views = array(); } if (empty($name)) { $name = $this->getName(); } if (empty($prefix)) { $prefix = $this->getName() . 'View'; } if(!class_exists('vView')) require(VMPATH_ADMIN .'/vmf/vview.php'); if (empty(self::$views[$name][$type][$prefix])) { if (self::$views[$name][$type][$prefix] = $this->createView($name,$prefix,array('type'=>$type))) { //self::$views[$name][$type][$prefix] = & $view; } else { $response = 500; $app = vFactory::getApplication(); /* * With URL rewriting enabled on the server, all client * requests for non-existent files are being forwarded to * Joomla. Return a 404 response here and assume the client * was requesting a non-existent file for which there is no * view type that matches the file's extension (the most * likely scenario). */ if ($app->get('sef_rewrite')) { $response = 404; } //throw new Exception(vmText::sprintf('JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND', $name, $type, $prefix), $response); } } return self::$views[$name][$type][$prefix]; } /** * Method to add a record ID to the edit list. * * @param string $context The context for the session storage. * @param integer $id The ID of the record to add to the edit list. * * @return void * * @since 12.2 */ protected function holdEditId($context, $id) { $app = vFactory::getApplication(); $values = (array) $app->getUserState($context . '.id'); // Add the id to the list if non-zero. if (!empty($id)) { array_push($values, (int) $id); $values = array_unique($values); $app->setUserState($context . '.id', $values); if (defined('JDEBUG') && JDEBUG) { JLog::add( sprintf( 'Holding edit ID %s.%s %s', $context, $id, str_replace("\n", ' ', print_r($values, 1)) ), JLog::INFO, 'controller' ); } } } /** * Redirects the browser or returns false if no redirect is set. * * @return boolean False if no redirect exists. * * @since 12.2 */ public function redirect() { if ($this->redirect) { $app = vFactory::getApplication(); // Enqueue the redirect message $app->enqueueMessage($this->message, $this->messageType); // Execute the redirect $app->redirect($this->redirect); } return false; } /** * 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; } /** * Method to check whether an ID is in the edit list. * * @param string $context The context for the session storage. * @param integer $id The ID of the record to add to the edit list. * * @return void * * @since 12.2 */ protected function releaseEditId($context, $id) { $app = vFactory::getApplication(); $values = (array) $app->getUserState($context . '.id'); // Do a strict search of the edit list values. $index = array_search((int) $id, $values, true); if (is_int($index)) { unset($values[$index]); $app->setUserState($context . '.id', $values); if (defined('JDEBUG') && JDEBUG) { JLog::add( sprintf( 'Releasing edit ID %s.%s %s', $context, $id, str_replace("\n", ' ', print_r($values, 1)) ), JLog::INFO, 'controller' ); } } } /** * Set a URL for browser redirection. * * @param string $url URL to redirect to. * @param string $msg Message to display on redirect. Optional, defaults to value set internally by controller, if any. * @param string $type Message type. Optional, defaults to 'message' or the type set by a previous call to setMessage. * * @return JControllerLegacy This object to support chaining. * * @since 12.2 */ public function setRedirect($url, $msg = null, $type = null) { $this->redirect = $url; if ($msg !== null) { // Controller may have set this directly $this->message = $msg; } // Ensure the type is not overwritten by a previous call to setMessage. if (empty($type)) { if (empty($this->messageType)) { $this->messageType = 'message'; } } // If the type is explicitly set, set it. else { $this->messageType = $type; } return $this; } }