[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/MVC/Controller/ -> BaseController.php (source)

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


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer