1 <?php
2 /**
3 * @package Joomla.Legacy
4 * @subpackage Controller
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE.txt
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * Base class for a Joomla Controller
14 *
15 * Controller (Controllers are where you put all the actual code.) Provides basic
16 * functionality, such as rendering views (aka displaying templates).
17 *
18 * @since 2.5.5
19 */
20 class JControllerLegacy extends JObject
21 {
22 /**
23 * The base path of the controller
24 *
25 * @var string
26 * @since 3.0
27 */
28 protected $basePath;
29
30 /**
31 * The default view for the display method.
32 *
33 * @var string
34 * @since 3.0
35 */
36 protected $default_view;
37
38 /**
39 * The mapped task that was performed.
40 *
41 * @var string
42 * @since 3.0
43 */
44 protected $doTask;
45
46 /**
47 * Redirect message.
48 *
49 * @var string
50 * @since 3.0
51 */
52 protected $message;
53
54 /**
55 * Redirect message type.
56 *
57 * @var string
58 * @since 3.0
59 */
60 protected $messageType;
61
62 /**
63 * Array of class methods
64 *
65 * @var array
66 * @since 3.0
67 */
68 protected $methods;
69
70 /**
71 * The name of the controller
72 *
73 * @var array
74 * @since 3.0
75 */
76 protected $name;
77
78 /**
79 * The prefix of the models
80 *
81 * @var string
82 * @since 3.0
83 */
84 protected $model_prefix;
85
86 /**
87 * The set of search directories for resources (views).
88 *
89 * @var array
90 * @since 3.0
91 */
92 protected $paths;
93
94 /**
95 * URL for redirection.
96 *
97 * @var string
98 * @since 3.0
99 */
100 protected $redirect;
101
102 /**
103 * Current or most recently performed task.
104 *
105 * @var string
106 * @since 3.0
107 */
108 protected $task;
109
110 /**
111 * Array of class methods to call for a given task.
112 *
113 * @var array
114 * @since 3.0
115 */
116 protected $taskMap;
117
118 /**
119 * Hold a JInput object for easier access to the input variables.
120 *
121 * @var JInput
122 * @since 3.0
123 */
124 protected $input;
125
126 /**
127 * Instance container.
128 *
129 * @var JControllerLegacy
130 * @since 3.0
131 */
132 protected static $instance;
133
134 /**
135 * Instance container containing the views.
136 *
137 * @var JViewLegacy[]
138 * @since 3.4
139 */
140 protected static $views;
141
142 /**
143 * Adds to the stack of model paths in LIFO order.
144 *
145 * @param mixed $path The directory (string), or list of directories (array) to add.
146 * @param string $prefix A prefix for models
147 *
148 * @return void
149 *
150 * @since 3.0
151 */
152 public static function addModelPath($path, $prefix = '')
153 {
154 JModelLegacy::addIncludePath($path, $prefix);
155 }
156
157 /**
158 * Create the filename for a resource.
159 *
160 * @param string $type The resource type to create the filename for.
161 * @param array $parts An associative array of filename information. Optional.
162 *
163 * @return string The filename.
164 *
165 * @since 3.0
166 */
167 protected static function createFileName($type, $parts = array())
168 {
169 $filename = '';
170
171 switch ($type)
172 {
173 case 'controller':
174 if (!empty($parts['format']))
175 {
176 if ($parts['format'] == 'html')
177 {
178 $parts['format'] = '';
179 }
180 else
181 {
182 $parts['format'] = '.' . $parts['format'];
183 }
184 }
185 else
186 {
187 $parts['format'] = '';
188 }
189
190 $filename = strtolower($parts['name'] . $parts['format'] . '.php');
191 break;
192
193 case 'view':
194 if (!empty($parts['type']))
195 {
196 $parts['type'] = '.' . $parts['type'];
197 }
198 else
199 {
200 $parts['type'] = '';
201 }
202
203 $filename = strtolower($parts['name'] . '/view' . $parts['type'] . '.php');
204 break;
205 }
206
207 return $filename;
208 }
209
210 /**
211 * Method to get a singleton controller instance.
212 *
213 * @param string $prefix The prefix for the controller.
214 * @param array $config An array of optional constructor options.
215 *
216 * @return JControllerLegacy
217 *
218 * @since 3.0
219 * @throws Exception if the controller cannot be loaded.
220 */
221 public static function getInstance($prefix, $config = array())
222 {
223 if (is_object(self::$instance))
224 {
225 return self::$instance;
226 }
227
228 $input = JFactory::getApplication()->input;
229
230 // Get the environment configuration.
231 $basePath = array_key_exists('base_path', $config) ? $config['base_path'] : JPATH_COMPONENT;
232 $format = $input->getWord('format');
233 $command = $input->get('task', 'display');
234
235 // Check for array format.
236 $filter = JFilterInput::getInstance();
237
238 if (is_array($command))
239 {
240 $command = $filter->clean(array_pop(array_keys($command)), 'cmd');
241 }
242 else
243 {
244 $command = $filter->clean($command, 'cmd');
245 }
246
247 // Check for a controller.task command.
248 if (strpos($command, '.') !== false)
249 {
250 // Explode the controller.task command.
251 list ($type, $task) = explode('.', $command);
252
253 // Define the controller filename and path.
254 $file = self::createFileName('controller', array('name' => $type, 'format' => $format));
255 $path = $basePath . '/controllers/' . $file;
256 $backuppath = $basePath . '/controller/' . $file;
257
258 // Reset the task without the controller context.
259 $input->set('task', $task);
260 }
261 else
262 {
263 // Base controller.
264 $type = null;
265
266 // Define the controller filename and path.
267 $file = self::createFileName('controller', array('name' => 'controller', 'format' => $format));
268 $path = $basePath . '/' . $file;
269 $backupfile = self::createFileName('controller', array('name' => 'controller'));
270 $backuppath = $basePath . '/' . $backupfile;
271 }
272
273 // Get the controller class name.
274 $class = ucfirst($prefix) . 'Controller' . ucfirst($type);
275
276 // Include the class if not present.
277 if (!class_exists($class))
278 {
279 // If the controller file path exists, include it.
280 if (file_exists($path))
281 {
282 require_once $path;
283 }
284 elseif (isset($backuppath) && file_exists($backuppath))
285 {
286 require_once $backuppath;
287 }
288 else
289 {
290 throw new InvalidArgumentException(JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER', $type, $format));
291 }
292 }
293
294 // Instantiate the class.
295 if (!class_exists($class))
296 {
297 throw new InvalidArgumentException(JText::sprintf('JLIB_APPLICATION_ERROR_INVALID_CONTROLLER_CLASS', $class));
298 }
299
300 // Instantiate the class, store it to the static container, and return it
301 return self::$instance = new $class($config);
302 }
303
304 /**
305 * Constructor.
306 *
307 * @param array $config An optional associative array of configuration settings.
308 * Recognized key values include 'name', 'default_task', 'model_path', and
309 * 'view_path' (this list is not meant to be comprehensive).
310 *
311 * @since 3.0
312 */
313 public function __construct($config = array())
314 {
315 $this->methods = array();
316 $this->message = null;
317 $this->messageType = 'message';
318 $this->paths = array();
319 $this->redirect = null;
320 $this->taskMap = array();
321
322 if (defined('JDEBUG') && JDEBUG)
323 {
324 JLog::addLogger(array('text_file' => 'jcontroller.log.php'), JLog::ALL, array('controller'));
325 }
326
327 $this->input = JFactory::getApplication()->input;
328
329 // Determine the methods to exclude from the base class.
330 $xMethods = get_class_methods('JControllerLegacy');
331
332 // Get the public methods in this class using reflection.
333 $r = new ReflectionClass($this);
334 $rMethods = $r->getMethods(ReflectionMethod::IS_PUBLIC);
335
336 foreach ($rMethods as $rMethod)
337 {
338 $mName = $rMethod->getName();
339
340 // Add default display method if not explicitly declared.
341 if (!in_array($mName, $xMethods) || $mName == 'display')
342 {
343 $this->methods[] = strtolower($mName);
344
345 // Auto register the methods as tasks.
346 $this->taskMap[strtolower($mName)] = $mName;
347 }
348 }
349
350 // Set the view name
351 if (empty($this->name))
352 {
353 if (array_key_exists('name', $config))
354 {
355 $this->name = $config['name'];
356 }
357 else
358 {
359 $this->name = $this->getName();
360 }
361 }
362
363 // Set a base path for use by the controller
364 if (array_key_exists('base_path', $config))
365 {
366 $this->basePath = $config['base_path'];
367 }
368 else
369 {
370 $this->basePath = JPATH_COMPONENT;
371 }
372
373 // If the default task is set, register it as such
374 if (array_key_exists('default_task', $config))
375 {
376 $this->registerDefaultTask($config['default_task']);
377 }
378 else
379 {
380 $this->registerDefaultTask('display');
381 }
382
383 // Set the models prefix
384 if (empty($this->model_prefix))
385 {
386 if (array_key_exists('model_prefix', $config))
387 {
388 // User-defined prefix
389 $this->model_prefix = $config['model_prefix'];
390 }
391 else
392 {
393 $this->model_prefix = ucfirst($this->name) . 'Model';
394 }
395 }
396
397 // Set the default model search path
398 if (array_key_exists('model_path', $config))
399 {
400 // User-defined dirs
401 $this->addModelPath($config['model_path'], $this->model_prefix);
402 }
403 else
404 {
405 $this->addModelPath($this->basePath . '/models', $this->model_prefix);
406 }
407
408 // Set the default view search path
409 if (array_key_exists('view_path', $config))
410 {
411 // User-defined dirs
412 $this->setPath('view', $config['view_path']);
413 }
414 else
415 {
416 $this->setPath('view', $this->basePath . '/views');
417 }
418
419 // Set the default view.
420 if (array_key_exists('default_view', $config))
421 {
422 $this->default_view = $config['default_view'];
423 }
424 elseif (empty($this->default_view))
425 {
426 $this->default_view = $this->getName();
427 }
428 }
429
430 /**
431 * Adds to the search path for templates and resources.
432 *
433 * @param string $type The path type (e.g. 'model', 'view').
434 * @param mixed $path The directory string or stream array to search.
435 *
436 * @return JControllerLegacy A JControllerLegacy object to support chaining.
437 *
438 * @since 3.0
439 */
440 protected function addPath($type, $path)
441 {
442 if (!isset($this->paths[$type]))
443 {
444 $this->paths[$type] = array();
445 }
446
447 // Loop through the path directories
448 foreach ((array) $path as $dir)
449 {
450 // No surrounding spaces allowed!
451 $dir = rtrim(JPath::check($dir), '/') . '/';
452
453 // Add to the top of the search dirs
454 array_unshift($this->paths[$type], $dir);
455 }
456
457 return $this;
458 }
459
460 /**
461 * Add one or more view paths to the controller's stack, in LIFO order.
462 *
463 * @param mixed $path The directory (string) or list of directories (array) to add.
464 *
465 * @return JControllerLegacy This object to support chaining.
466 *
467 * @since 3.0
468 */
469 public function addViewPath($path)
470 {
471 return $this->addPath('view', $path);
472 }
473
474 /**
475 * Authorisation check
476 *
477 * @param string $task The ACO Section Value to check access on.
478 *
479 * @return boolean True if authorised
480 *
481 * @since 3.0
482 * @deprecated 3.0 Use JAccess instead.
483 */
484 public function authorise($task)
485 {
486 JLog::add(__METHOD__ . ' is deprecated. Use JAccess instead.', JLog::WARNING, 'deprecated');
487
488 return true;
489 }
490
491 /**
492 * Method to check whether an ID is in the edit list.
493 *
494 * @param string $context The context for the session storage.
495 * @param integer $id The ID of the record to add to the edit list.
496 *
497 * @return boolean True if the ID is in the edit list.
498 *
499 * @since 3.0
500 */
501 protected function checkEditId($context, $id)
502 {
503 if ($id)
504 {
505 $values = (array) JFactory::getApplication()->getUserState($context . '.id');
506
507 $result = in_array((int) $id, $values);
508
509 if (defined('JDEBUG') && JDEBUG)
510 {
511 JLog::add(
512 sprintf(
513 'Checking edit ID %s.%s: %d %s',
514 $context,
515 $id,
516 (int) $result,
517 str_replace("\n", ' ', print_r($values, 1))
518 ),
519 JLog::INFO,
520 'controller'
521 );
522 }
523
524 return $result;
525 }
526
527 // No id for a new item.
528 return true;
529 }
530
531 /**
532 * Method to load and return a model object.
533 *
534 * @param string $name The name of the model.
535 * @param string $prefix Optional model prefix.
536 * @param array $config Configuration array for the model. Optional.
537 *
538 * @return JModelLegacy|boolean Model object on success; otherwise false on failure.
539 *
540 * @since 3.0
541 */
542 protected function createModel($name, $prefix = '', $config = array())
543 {
544 // Clean the model name
545 $modelName = preg_replace('/[^A-Z0-9_]/i', '', $name);
546 $classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix);
547
548 return JModelLegacy::getInstance($modelName, $classPrefix, $config);
549 }
550
551 /**
552 * Method to load and return a view object. This method first looks in the
553 * current template directory for a match and, failing that, uses a default
554 * set path to load the view class file.
555 *
556 * Note the "name, prefix, type" order of parameters, which differs from the
557 * "name, type, prefix" order used in related public methods.
558 *
559 * @param string $name The name of the view.
560 * @param string $prefix Optional prefix for the view class name.
561 * @param string $type The type of view.
562 * @param array $config Configuration array for the view. Optional.
563 *
564 * @return JViewLegacy|null View object on success; null or error result on failure.
565 *
566 * @since 3.0
567 * @throws Exception
568 */
569 protected function createView($name, $prefix = '', $type = '', $config = array())
570 {
571 // Clean the view name
572 $viewName = preg_replace('/[^A-Z0-9_]/i', '', $name);
573 $classPrefix = preg_replace('/[^A-Z0-9_]/i', '', $prefix);
574 $viewType = preg_replace('/[^A-Z0-9_]/i', '', $type);
575
576 // Build the view class name
577 $viewClass = $classPrefix . $viewName;
578
579 if (!class_exists($viewClass))
580 {
581 jimport('joomla.filesystem.path');
582 $path = JPath::find($this->paths['view'], $this->createFileName('view', array('name' => $viewName, 'type' => $viewType)));
583
584 if (!$path)
585 {
586 return null;
587 }
588
589 require_once $path;
590
591 if (!class_exists($viewClass))
592 {
593 throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_CLASS_NOT_FOUND', $viewClass, $path), 500);
594 }
595 }
596
597 return new $viewClass($config);
598 }
599
600 /**
601 * Typical view method for MVC based architecture
602 *
603 * This function is provide as a default implementation, in most cases
604 * you will need to override it in your own controllers.
605 *
606 * @param boolean $cachable If true, the view output will be cached
607 * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}.
608 *
609 * @return JControllerLegacy A JControllerLegacy object to support chaining.
610 *
611 * @since 3.0
612 */
613 public function display($cachable = false, $urlparams = array())
614 {
615 $document = JFactory::getDocument();
616 $viewType = $document->getType();
617 $viewName = $this->input->get('view', $this->default_view);
618 $viewLayout = $this->input->get('layout', 'default', 'string');
619
620 $view = $this->getView($viewName, $viewType, '', array('base_path' => $this->basePath, 'layout' => $viewLayout));
621
622 // Get/Create the model
623 if ($model = $this->getModel($viewName))
624 {
625 // Push the model into the view (as default)
626 $view->setModel($model, true);
627 }
628
629 $view->document = $document;
630
631 // Display the view
632 if ($cachable && $viewType != 'feed' && JFactory::getConfig()->get('caching') >= 1)
633 {
634 $option = $this->input->get('option');
635
636 if (is_array($urlparams))
637 {
638 $app = JFactory::getApplication();
639
640 if (!empty($app->registeredurlparams))
641 {
642 $registeredurlparams = $app->registeredurlparams;
643 }
644 else
645 {
646 $registeredurlparams = new stdClass;
647 }
648
649 foreach ($urlparams as $key => $value)
650 {
651 // Add your safe URL parameters with variable type as value {@see JFilterInput::clean()}.
652 $registeredurlparams->$key = $value;
653 }
654
655 $app->registeredurlparams = $registeredurlparams;
656 }
657
658 try
659 {
660 /** @var JCacheControllerView $cache */
661 $cache = JFactory::getCache($option, 'view');
662 $cache->get($view, 'display');
663 }
664 catch (JCacheException $exception)
665 {
666 $view->display();
667 }
668 }
669 else
670 {
671 $view->display();
672 }
673
674 return $this;
675 }
676
677 /**
678 * Execute a task by triggering a method in the derived class.
679 *
680 * @param string $task The task to perform. If no matching task is found, the '__default' task is executed, if defined.
681 *
682 * @return mixed The value returned by the called method.
683 *
684 * @since 3.0
685 * @throws Exception
686 */
687 public function execute($task)
688 {
689 $this->task = $task;
690
691 $task = strtolower($task);
692
693 if (isset($this->taskMap[$task]))
694 {
695 $doTask = $this->taskMap[$task];
696 }
697 elseif (isset($this->taskMap['__default']))
698 {
699 $doTask = $this->taskMap['__default'];
700 }
701 else
702 {
703 throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND', $task), 404);
704 }
705
706 // Record the actual task being fired
707 $this->doTask = $doTask;
708
709 return $this->$doTask();
710 }
711
712 /**
713 * Method to get a model object, loading it if required.
714 *
715 * @param string $name The model name. Optional.
716 * @param string $prefix The class prefix. Optional.
717 * @param array $config Configuration array for model. Optional.
718 *
719 * @return JModelLegacy|boolean Model object on success; otherwise false on failure.
720 *
721 * @since 3.0
722 */
723 public function getModel($name = '', $prefix = '', $config = array())
724 {
725 if (empty($name))
726 {
727 $name = $this->getName();
728 }
729
730 if (empty($prefix))
731 {
732 $prefix = $this->model_prefix;
733 }
734
735 if ($model = $this->createModel($name, $prefix, $config))
736 {
737 // Task is a reserved state
738 $model->setState('task', $this->task);
739
740 // Let's get the application object and set menu information if it's available
741 $menu = JFactory::getApplication()->getMenu();
742
743 if (is_object($menu))
744 {
745 if ($item = $menu->getActive())
746 {
747 $params = $menu->getParams($item->id);
748
749 // Set default state data
750 $model->setState('parameters.menu', $params);
751 }
752 }
753 }
754
755 return $model;
756 }
757
758 /**
759 * Method to get the controller name
760 *
761 * The dispatcher name is set by default parsed using the classname, or it can be set
762 * by passing a $config['name'] in the class constructor
763 *
764 * @return string The name of the dispatcher
765 *
766 * @since 3.0
767 * @throws Exception
768 */
769 public function getName()
770 {
771 if (empty($this->name))
772 {
773 $r = null;
774
775 if (!preg_match('/(.*)Controller/i', get_class($this), $r))
776 {
777 throw new Exception(JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME'), 500);
778 }
779
780 $this->name = strtolower($r[1]);
781 }
782
783 return $this->name;
784 }
785
786 /**
787 * Get the last task that is being performed or was most recently performed.
788 *
789 * @return string The task that is being performed or was most recently performed.
790 *
791 * @since 3.0
792 */
793 public function getTask()
794 {
795 return $this->task;
796 }
797
798 /**
799 * Gets the available tasks in the controller.
800 *
801 * @return array Array[i] of task names.
802 *
803 * @since 3.0
804 */
805 public function getTasks()
806 {
807 return $this->methods;
808 }
809
810 /**
811 * Method to get a reference to the current view and load it if necessary.
812 *
813 * @param string $name The view name. Optional, defaults to the controller name.
814 * @param string $type The view type. Optional.
815 * @param string $prefix The class prefix. Optional.
816 * @param array $config Configuration array for view. Optional.
817 *
818 * @return JViewLegacy Reference to the view or an error.
819 *
820 * @since 3.0
821 * @throws Exception
822 */
823 public function getView($name = '', $type = '', $prefix = '', $config = array())
824 {
825 // @note We use self so we only access stuff in this class rather than in all classes.
826 if (!isset(self::$views))
827 {
828 self::$views = array();
829 }
830
831 if (empty($name))
832 {
833 $name = $this->getName();
834 }
835
836 if (empty($prefix))
837 {
838 $prefix = $this->getName() . 'View';
839 }
840
841 if (empty(self::$views[$name][$type][$prefix]))
842 {
843 if ($view = $this->createView($name, $prefix, $type, $config))
844 {
845 self::$views[$name][$type][$prefix] = & $view;
846 }
847 else
848 {
849 throw new Exception(JText::sprintf('JLIB_APPLICATION_ERROR_VIEW_NOT_FOUND', $name, $type, $prefix), 404);
850 }
851 }
852
853 return self::$views[$name][$type][$prefix];
854 }
855
856 /**
857 * Method to add a record ID to the edit list.
858 *
859 * @param string $context The context for the session storage.
860 * @param integer $id The ID of the record to add to the edit list.
861 *
862 * @return void
863 *
864 * @since 3.0
865 */
866 protected function holdEditId($context, $id)
867 {
868 $app = JFactory::getApplication();
869 $values = (array) $app->getUserState($context . '.id');
870
871 // Add the id to the list if non-zero.
872 if (!empty($id))
873 {
874 $values[] = (int) $id;
875 $values = array_unique($values);
876 $app->setUserState($context . '.id', $values);
877
878 if (defined('JDEBUG') && JDEBUG)
879 {
880 JLog::add(
881 sprintf(
882 'Holding edit ID %s.%s %s',
883 $context,
884 $id,
885 str_replace("\n", ' ', print_r($values, 1))
886 ),
887 JLog::INFO,
888 'controller'
889 );
890 }
891 }
892 }
893
894 /**
895 * Redirects the browser or returns false if no redirect is set.
896 *
897 * @return boolean False if no redirect exists.
898 *
899 * @since 3.0
900 */
901 public function redirect()
902 {
903 if ($this->redirect)
904 {
905 $app = JFactory::getApplication();
906
907 // Enqueue the redirect message
908 $app->enqueueMessage($this->message, $this->messageType);
909
910 // Execute the redirect
911 $app->redirect($this->redirect);
912 }
913
914 return false;
915 }
916
917 /**
918 * Register the default task to perform if a mapping is not found.
919 *
920 * @param string $method The name of the method in the derived class to perform if a named task is not found.
921 *
922 * @return JControllerLegacy A JControllerLegacy object to support chaining.
923 *
924 * @since 3.0
925 */
926 public function registerDefaultTask($method)
927 {
928 $this->registerTask('__default', $method);
929
930 return $this;
931 }
932
933 /**
934 * Register (map) a task to a method in the class.
935 *
936 * @param string $task The task.
937 * @param string $method The name of the method in the derived class to perform for this task.
938 *
939 * @return JControllerLegacy A JControllerLegacy object to support chaining.
940 *
941 * @since 3.0
942 */
943 public function registerTask($task, $method)
944 {
945 if (in_array(strtolower($method), $this->methods))
946 {
947 $this->taskMap[strtolower($task)] = $method;
948 }
949
950 return $this;
951 }
952
953 /**
954 * Unregister (unmap) a task in the class.
955 *
956 * @param string $task The task.
957 *
958 * @return JControllerLegacy This object to support chaining.
959 *
960 * @since 3.0
961 */
962 public function unregisterTask($task)
963 {
964 unset($this->taskMap[strtolower($task)]);
965
966 return $this;
967 }
968
969 /**
970 * Method to check whether an ID is in the edit list.
971 *
972 * @param string $context The context for the session storage.
973 * @param integer $id The ID of the record to add to the edit list.
974 *
975 * @return void
976 *
977 * @since 3.0
978 */
979 protected function releaseEditId($context, $id)
980 {
981 $app = JFactory::getApplication();
982 $values = (array) $app->getUserState($context . '.id');
983
984 // Do a strict search of the edit list values.
985 $index = array_search((int) $id, $values, true);
986
987 if (is_int($index))
988 {
989 unset($values[$index]);
990 $app->setUserState($context . '.id', $values);
991
992 if (defined('JDEBUG') && JDEBUG)
993 {
994 JLog::add(
995 sprintf(
996 'Releasing edit ID %s.%s %s',
997 $context,
998 $id,
999 str_replace("\n", ' ', print_r($values, 1))
1000 ),
1001 JLog::INFO,
1002 'controller'
1003 );
1004 }
1005 }
1006 }
1007
1008 /**
1009 * Sets the internal message that is passed with a redirect
1010 *
1011 * @param string $text Message to display on redirect.
1012 * @param string $type Message type. Optional, defaults to 'message'.
1013 *
1014 * @return string Previous message
1015 *
1016 * @since 3.0
1017 */
1018 public function setMessage($text, $type = 'message')
1019 {
1020 $previous = $this->message;
1021 $this->message = $text;
1022 $this->messageType = $type;
1023
1024 return $previous;
1025 }
1026
1027 /**
1028 * Sets an entire array of search paths for resources.
1029 *
1030 * @param string $type The type of path to set, typically 'view' or 'model'.
1031 * @param string $path The new set of search paths. If null or false, resets to the current directory only.
1032 *
1033 * @return void
1034 *
1035 * @since 3.0
1036 */
1037 protected function setPath($type, $path)
1038 {
1039 // Clear out the prior search dirs
1040 $this->paths[$type] = array();
1041
1042 // Actually add the user-specified directories
1043 $this->addPath($type, $path);
1044 }
1045
1046 /**
1047 * Checks for a form token in the request.
1048 *
1049 * Use in conjunction with JHtml::_('form.token') or JSession::getFormToken.
1050 *
1051 * @param string $method The request method in which to look for the token key.
1052 * @param boolean $redirect Whether to implicitly redirect user to the referrer page on failure or simply return false.
1053 *
1054 * @return boolean True if found and valid, otherwise return false or redirect to referrer page.
1055 *
1056 * @since 3.7.0
1057 * @see JSession::checkToken()
1058 */
1059 public function checkToken($method = 'post', $redirect = true)
1060 {
1061 $valid = JSession::checkToken($method);
1062
1063 if (!$valid && $redirect)
1064 {
1065 $referrer = $this->input->server->getString('HTTP_REFERER');
1066
1067 if (!JUri::isInternal($referrer))
1068 {
1069 $referrer = 'index.php';
1070 }
1071
1072 $app = JFactory::getApplication();
1073 $app->enqueueMessage(JText::_('JINVALID_TOKEN_NOTICE'), 'warning');
1074 $app->redirect($referrer);
1075 }
1076
1077 return $valid;
1078 }
1079
1080 /**
1081 * Set a URL for browser redirection.
1082 *
1083 * @param string $url URL to redirect to.
1084 * @param string $msg Message to display on redirect. Optional, defaults to value set internally by controller, if any.
1085 * @param string $type Message type. Optional, defaults to 'message' or the type set by a previous call to setMessage.
1086 *
1087 * @return JControllerLegacy This object to support chaining.
1088 *
1089 * @since 3.0
1090 */
1091 public function setRedirect($url, $msg = null, $type = null)
1092 {
1093 $this->redirect = $url;
1094
1095 if ($msg !== null)
1096 {
1097 // Controller may have set this directly
1098 $this->message = $msg;
1099 }
1100
1101 // Ensure the type is not overwritten by a previous call to setMessage.
1102 if (empty($type))
1103 {
1104 if (empty($this->messageType))
1105 {
1106 $this->messageType = 'message';
1107 }
1108 }
1109 // If the type is explicitly set, set it.
1110 else
1111 {
1112 $this->messageType = $type;
1113 }
1114
1115 return $this;
1116 }
1117 }
1118