[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

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

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2009 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\Component\ComponentHelper;
  14  use Joomla\CMS\Factory;
  15  use Joomla\CMS\Form\FormFactoryAwareInterface;
  16  use Joomla\CMS\Form\FormFactoryAwareTrait;
  17  use Joomla\CMS\Form\FormFactoryInterface;
  18  use Joomla\CMS\Language\Text;
  19  use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
  20  use Joomla\CMS\MVC\Model\BaseDatabaseModel;
  21  use Joomla\CMS\Router\Route;
  22  use Joomla\CMS\Uri\Uri;
  23  use Joomla\Input\Input;
  24  
  25  // phpcs:disable PSR1.Files.SideEffects
  26  \defined('JPATH_PLATFORM') or die;
  27  // phpcs:enable PSR1.Files.SideEffects
  28  
  29  /**
  30   * Controller tailored to suit most form-based admin operations.
  31   *
  32   * @since  1.6
  33   * @todo   Add ability to set redirect manually to better cope with frontend usage.
  34   */
  35  class FormController extends BaseController implements FormFactoryAwareInterface
  36  {
  37      use FormFactoryAwareTrait;
  38  
  39      /**
  40       * The context for storing internal data, e.g. record.
  41       *
  42       * @var    string
  43       * @since  1.6
  44       */
  45      protected $context;
  46  
  47      /**
  48       * The URL option for the component.
  49       *
  50       * @var    string
  51       * @since  1.6
  52       */
  53      protected $option;
  54  
  55      /**
  56       * The URL view item variable.
  57       *
  58       * @var    string
  59       * @since  1.6
  60       */
  61      protected $view_item;
  62  
  63      /**
  64       * The URL view list variable.
  65       *
  66       * @var    string
  67       * @since  1.6
  68       */
  69      protected $view_list;
  70  
  71      /**
  72       * The prefix to use with controller messages.
  73       *
  74       * @var    string
  75       * @since  1.6
  76       */
  77      protected $text_prefix;
  78  
  79      /**
  80       * Constructor.
  81       *
  82       * @param   array                 $config       An optional associative array of configuration settings.
  83       *                                              Recognized key values include 'name', 'default_task', 'model_path', and
  84       *                                              'view_path' (this list is not meant to be comprehensive).
  85       * @param   MVCFactoryInterface   $factory      The factory.
  86       * @param   CMSApplication        $app          The Application for the dispatcher
  87       * @param   Input                 $input        Input
  88       * @param   FormFactoryInterface  $formFactory  The form factory.
  89       *
  90       * @since   3.0
  91       */
  92      public function __construct(
  93          $config = array(),
  94          MVCFactoryInterface $factory = null,
  95          ?CMSApplication $app = null,
  96          ?Input $input = null,
  97          FormFactoryInterface $formFactory = null
  98      ) {
  99          parent::__construct($config, $factory, $app, $input);
 100  
 101          // Guess the option as com_NameOfController
 102          if (empty($this->option)) {
 103              $this->option = ComponentHelper::getComponentName($this, $this->getName());
 104          }
 105  
 106          // Guess the \Text message prefix. Defaults to the option.
 107          if (empty($this->text_prefix)) {
 108              $this->text_prefix = strtoupper($this->option);
 109          }
 110  
 111          // Guess the context as the suffix, eg: OptionControllerContent.
 112          if (empty($this->context)) {
 113              $r = null;
 114  
 115              $match = 'Controller';
 116  
 117              // If there is a namespace append a backslash
 118              if (strpos(\get_class($this), '\\')) {
 119                  $match .= '\\\\';
 120              }
 121  
 122              if (!preg_match('/(.*)' . $match . '(.*)/i', \get_class($this), $r)) {
 123                  throw new \Exception(Text::sprintf('JLIB_APPLICATION_ERROR_GET_NAME', __METHOD__), 500);
 124              }
 125  
 126              // Remove the backslashes and the suffix controller
 127              $this->context = str_replace(array('\\', 'controller'), '', strtolower($r[2]));
 128          }
 129  
 130          // Guess the item view as the context.
 131          if (empty($this->view_item)) {
 132              $this->view_item = $this->context;
 133          }
 134  
 135          // Guess the list view as the plural of the item view.
 136          if (empty($this->view_list)) {
 137              $this->view_list = \Joomla\String\Inflector::getInstance()->toPlural($this->view_item);
 138          }
 139  
 140          $this->setFormFactory($formFactory);
 141  
 142          // Apply, Save & New, and Save As copy should be standard on forms.
 143          $this->registerTask('apply', 'save');
 144          $this->registerTask('save2menu', 'save');
 145          $this->registerTask('save2new', 'save');
 146          $this->registerTask('save2copy', 'save');
 147          $this->registerTask('editAssociations', 'save');
 148      }
 149  
 150      /**
 151       * Method to add a new record.
 152       *
 153       * @return  boolean  True if the record can be added, false if not.
 154       *
 155       * @since   1.6
 156       */
 157      public function add()
 158      {
 159          $context = "$this->option.edit.$this->context";
 160  
 161          // Access check.
 162          if (!$this->allowAdd()) {
 163              // Set the internal error and also the redirect error.
 164              $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED'), 'error');
 165  
 166              $this->setRedirect(
 167                  Route::_(
 168                      'index.php?option=' . $this->option . '&view=' . $this->view_list
 169                      . $this->getRedirectToListAppend(),
 170                      false
 171                  )
 172              );
 173  
 174              return false;
 175          }
 176  
 177          // Clear the record edit information from the session.
 178          $this->app->setUserState($context . '.data', null);
 179  
 180          // Redirect to the edit screen.
 181          $this->setRedirect(
 182              Route::_(
 183                  'index.php?option=' . $this->option . '&view=' . $this->view_item
 184                  . $this->getRedirectToItemAppend(),
 185                  false
 186              )
 187          );
 188  
 189          return true;
 190      }
 191  
 192      /**
 193       * Method to check if you can add a new record.
 194       *
 195       * Extended classes can override this if necessary.
 196       *
 197       * @param   array  $data  An array of input data.
 198       *
 199       * @return  boolean
 200       *
 201       * @since   1.6
 202       */
 203      protected function allowAdd($data = [])
 204      {
 205          $user = $this->app->getIdentity();
 206  
 207          return $user->authorise('core.create', $this->option) || \count($user->getAuthorisedCategories($this->option, 'core.create'));
 208      }
 209  
 210      /**
 211       * Method to check if you can edit an existing record.
 212       *
 213       * Extended classes can override this if necessary.
 214       *
 215       * @param   array   $data  An array of input data.
 216       * @param   string  $key   The name of the key for the primary key; default is id.
 217       *
 218       * @return  boolean
 219       *
 220       * @since   1.6
 221       */
 222      protected function allowEdit($data = [], $key = 'id')
 223      {
 224          return $this->app->getIdentity()->authorise('core.edit', $this->option);
 225      }
 226  
 227      /**
 228       * Method to check if you can save a new or existing record.
 229       *
 230       * Extended classes can override this if necessary.
 231       *
 232       * @param   array   $data  An array of input data.
 233       * @param   string  $key   The name of the key for the primary key.
 234       *
 235       * @return  boolean
 236       *
 237       * @since   1.6
 238       */
 239      protected function allowSave($data, $key = 'id')
 240      {
 241          $recordId = $data[$key] ?? '0';
 242  
 243          if ($recordId) {
 244              return $this->allowEdit($data, $key);
 245          } else {
 246              return $this->allowAdd($data);
 247          }
 248      }
 249  
 250      /**
 251       * Method to run batch operations.
 252       *
 253       * @param   BaseDatabaseModel  $model  The model of the component being processed.
 254       *
 255       * @return  boolean  True if successful, false otherwise and internal error is set.
 256       *
 257       * @since   1.7
 258       */
 259      public function batch($model)
 260      {
 261          $vars = $this->input->post->get('batch', array(), 'array');
 262          $cid  = (array) $this->input->post->get('cid', array(), 'int');
 263  
 264          // Remove zero values resulting from input filter
 265          $cid = array_filter($cid);
 266  
 267          // Build an array of item contexts to check
 268          $contexts = array();
 269  
 270          $option = $this->extension ?? $this->option;
 271  
 272          foreach ($cid as $id) {
 273              // If we're coming from com_categories, we need to use extension vs. option
 274              $contexts[$id] = $option . '.' . $this->context . '.' . $id;
 275          }
 276  
 277          // Attempt to run the batch operation.
 278          if ($model->batch($vars, $cid, $contexts)) {
 279              $this->setMessage(Text::_('JLIB_APPLICATION_SUCCESS_BATCH'));
 280  
 281              return true;
 282          } else {
 283              $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_BATCH_FAILED', $model->getError()), 'warning');
 284  
 285              return false;
 286          }
 287      }
 288  
 289      /**
 290       * Method to cancel an edit.
 291       *
 292       * @param   string  $key  The name of the primary key of the URL variable.
 293       *
 294       * @return  boolean  True if access level checks pass, false otherwise.
 295       *
 296       * @since   1.6
 297       */
 298      public function cancel($key = null)
 299      {
 300          $this->checkToken();
 301  
 302          $model = $this->getModel();
 303          $table = $model->getTable();
 304          $context = "$this->option.edit.$this->context";
 305  
 306          if (empty($key)) {
 307              $key = $table->getKeyName();
 308          }
 309  
 310          $recordId = $this->input->getInt($key);
 311  
 312          // Attempt to check-in the current record.
 313          if ($recordId && $table->hasField('checked_out') && $model->checkin($recordId) === false) {
 314              // Check-in failed, go back to the record and display a notice.
 315              $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error');
 316  
 317              $this->setRedirect(
 318                  Route::_(
 319                      'index.php?option=' . $this->option . '&view=' . $this->view_item
 320                      . $this->getRedirectToItemAppend($recordId, $key),
 321                      false
 322                  )
 323              );
 324  
 325              return false;
 326          }
 327  
 328          // Clean the session data and redirect.
 329          $this->releaseEditId($context, $recordId);
 330          $this->app->setUserState($context . '.data', null);
 331  
 332          $url = 'index.php?option=' . $this->option . '&view=' . $this->view_list
 333              . $this->getRedirectToListAppend();
 334  
 335          // Check if there is a return value
 336          $return = $this->input->get('return', null, 'base64');
 337  
 338          if (!\is_null($return) && Uri::isInternal(base64_decode($return))) {
 339              $url = base64_decode($return);
 340          }
 341  
 342          // Redirect to the list screen.
 343          $this->setRedirect(Route::_($url, false));
 344  
 345          return true;
 346      }
 347  
 348      /**
 349       * Method to edit an existing record.
 350       *
 351       * @param   string  $key     The name of the primary key of the URL variable.
 352       * @param   string  $urlVar  The name of the URL variable if different from the primary key
 353       *                           (sometimes required to avoid router collisions).
 354       *
 355       * @return  boolean  True if access level check and checkout passes, false otherwise.
 356       *
 357       * @since   1.6
 358       */
 359      public function edit($key = null, $urlVar = null)
 360      {
 361          // Do not cache the response to this, its a redirect, and mod_expires and google chrome browser bugs cache it forever!
 362          $this->app->allowCache(false);
 363  
 364          $model = $this->getModel();
 365          $table = $model->getTable();
 366          $cid   = (array) $this->input->post->get('cid', array(), 'int');
 367          $context = "$this->option.edit.$this->context";
 368  
 369          // Determine the name of the primary key for the data.
 370          if (empty($key)) {
 371              $key = $table->getKeyName();
 372          }
 373  
 374          // To avoid data collisions the urlVar may be different from the primary key.
 375          if (empty($urlVar)) {
 376              $urlVar = $key;
 377          }
 378  
 379          // Get the previous record id (if any) and the current record id.
 380          $recordId = (int) (\count($cid) ? $cid[0] : $this->input->getInt($urlVar));
 381          $checkin = $table->hasField('checked_out');
 382  
 383          // Access check.
 384          if (!$this->allowEdit(array($key => $recordId), $key)) {
 385              $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'), 'error');
 386  
 387              $this->setRedirect(
 388                  Route::_(
 389                      'index.php?option=' . $this->option . '&view=' . $this->view_list
 390                      . $this->getRedirectToListAppend(),
 391                      false
 392                  )
 393              );
 394  
 395              return false;
 396          }
 397  
 398          // Attempt to check-out the new record for editing and redirect.
 399          if ($checkin && !$model->checkout($recordId)) {
 400              // Check-out failed, display a notice but allow the user to see the record.
 401              $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKOUT_FAILED', $model->getError()), 'error');
 402  
 403              $this->setRedirect(
 404                  Route::_(
 405                      'index.php?option=' . $this->option . '&view=' . $this->view_item
 406                      . $this->getRedirectToItemAppend($recordId, $urlVar),
 407                      false
 408                  )
 409              );
 410  
 411              return false;
 412          } else {
 413              // Check-out succeeded, push the new record id into the session.
 414              $this->holdEditId($context, $recordId);
 415              $this->app->setUserState($context . '.data', null);
 416  
 417              $this->setRedirect(
 418                  Route::_(
 419                      'index.php?option=' . $this->option . '&view=' . $this->view_item
 420                      . $this->getRedirectToItemAppend($recordId, $urlVar),
 421                      false
 422                  )
 423              );
 424  
 425              return true;
 426          }
 427      }
 428  
 429      /**
 430       * Method to get a model object, loading it if required.
 431       *
 432       * @param   string  $name    The model name. Optional.
 433       * @param   string  $prefix  The class prefix. Optional.
 434       * @param   array   $config  Configuration array for model. Optional.
 435       *
 436       * @return  BaseDatabaseModel  The model.
 437       *
 438       * @since   1.6
 439       */
 440      public function getModel($name = '', $prefix = '', $config = array('ignore_request' => true))
 441      {
 442          if (empty($name)) {
 443              $name = $this->context;
 444          }
 445  
 446          return parent::getModel($name, $prefix, $config);
 447      }
 448  
 449      /**
 450       * Gets the URL arguments to append to an item redirect.
 451       *
 452       * @param   integer  $recordId  The primary key id for the item.
 453       * @param   string   $urlVar    The name of the URL variable for the id.
 454       *
 455       * @return  string  The arguments to append to the redirect URL.
 456       *
 457       * @since   1.6
 458       */
 459      protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id')
 460      {
 461          $append = '';
 462  
 463          // Setup redirect info.
 464          if ($tmpl = $this->input->get('tmpl', '', 'string')) {
 465              $append .= '&tmpl=' . $tmpl;
 466          }
 467  
 468          if ($layout = $this->input->get('layout', 'edit', 'string')) {
 469              $append .= '&layout=' . $layout;
 470          }
 471  
 472          if ($forcedLanguage = $this->input->get('forcedLanguage', '', 'cmd')) {
 473              $append .= '&forcedLanguage=' . $forcedLanguage;
 474          }
 475  
 476          if ($recordId) {
 477              $append .= '&' . $urlVar . '=' . $recordId;
 478          }
 479  
 480          $return = $this->input->get('return', null, 'base64');
 481  
 482          if ($return) {
 483              $append .= '&return=' . $return;
 484          }
 485  
 486          return $append;
 487      }
 488  
 489      /**
 490       * Gets the URL arguments to append to a list redirect.
 491       *
 492       * @return  string  The arguments to append to the redirect URL.
 493       *
 494       * @since   1.6
 495       */
 496      protected function getRedirectToListAppend()
 497      {
 498          $append = '';
 499  
 500          // Setup redirect info.
 501          if ($tmpl = $this->input->get('tmpl', '', 'string')) {
 502              $append .= '&tmpl=' . $tmpl;
 503          }
 504  
 505          if ($forcedLanguage = $this->input->get('forcedLanguage', '', 'cmd')) {
 506              $append .= '&forcedLanguage=' . $forcedLanguage;
 507          }
 508  
 509          return $append;
 510      }
 511  
 512      /**
 513       * Function that allows child controller access to model data
 514       * after the data has been saved.
 515       *
 516       * @param   BaseDatabaseModel  $model      The data model object.
 517       * @param   array              $validData  The validated data.
 518       *
 519       * @return  void
 520       *
 521       * @since   1.6
 522       */
 523      protected function postSaveHook(BaseDatabaseModel $model, $validData = array())
 524      {
 525      }
 526  
 527      /**
 528       * Method to save a record.
 529       *
 530       * @param   string  $key     The name of the primary key of the URL variable.
 531       * @param   string  $urlVar  The name of the URL variable if different from the primary key (sometimes required to avoid router collisions).
 532       *
 533       * @return  boolean  True if successful, false otherwise.
 534       *
 535       * @since   1.6
 536       */
 537      public function save($key = null, $urlVar = null)
 538      {
 539          // Check for request forgeries.
 540          $this->checkToken();
 541  
 542          $app   = $this->app;
 543          $model = $this->getModel();
 544          $table = $model->getTable();
 545          $data  = $this->input->post->get('jform', array(), 'array');
 546          $checkin = $table->hasField('checked_out');
 547          $context = "$this->option.edit.$this->context";
 548          $task = $this->getTask();
 549  
 550          // Determine the name of the primary key for the data.
 551          if (empty($key)) {
 552              $key = $table->getKeyName();
 553          }
 554  
 555          // To avoid data collisions the urlVar may be different from the primary key.
 556          if (empty($urlVar)) {
 557              $urlVar = $key;
 558          }
 559  
 560          $recordId = $this->input->getInt($urlVar);
 561  
 562          // Populate the row id from the session.
 563          $data[$key] = $recordId;
 564  
 565          // The save2copy task needs to be handled slightly differently.
 566          if ($task === 'save2copy') {
 567              // Check-in the original row.
 568              if ($checkin && $model->checkin($data[$key]) === false) {
 569                  // Check-in failed. Go back to the item and display a notice.
 570                  $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error');
 571  
 572                  $this->setRedirect(
 573                      Route::_(
 574                          'index.php?option=' . $this->option . '&view=' . $this->view_item
 575                          . $this->getRedirectToItemAppend($recordId, $urlVar),
 576                          false
 577                      )
 578                  );
 579  
 580                  return false;
 581              }
 582  
 583              // Reset the ID, the multilingual associations and then treat the request as for Apply.
 584              $data[$key] = 0;
 585              $data['associations'] = array();
 586              $task = 'apply';
 587          }
 588  
 589          // Access check.
 590          if (!$this->allowSave($data, $key)) {
 591              $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
 592  
 593              $this->setRedirect(
 594                  Route::_(
 595                      'index.php?option=' . $this->option . '&view=' . $this->view_list
 596                      . $this->getRedirectToListAppend(),
 597                      false
 598                  )
 599              );
 600  
 601              return false;
 602          }
 603  
 604          // Validate the posted data.
 605          // Sometimes the form needs some posted data, such as for plugins and modules.
 606          $form = $model->getForm($data, false);
 607  
 608          if (!$form) {
 609              $app->enqueueMessage($model->getError(), 'error');
 610  
 611              return false;
 612          }
 613  
 614          // Send an object which can be modified through the plugin event
 615          $objData = (object) $data;
 616          $app->triggerEvent(
 617              'onContentNormaliseRequestData',
 618              array($this->option . '.' . $this->context, $objData, $form)
 619          );
 620          $data = (array) $objData;
 621  
 622          // Test whether the data is valid.
 623          $validData = $model->validate($form, $data);
 624  
 625          // Check for validation errors.
 626          if ($validData === false) {
 627              // Get the validation messages.
 628              $errors = $model->getErrors();
 629  
 630              // Push up to three validation messages out to the user.
 631              for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) {
 632                  if ($errors[$i] instanceof \Exception) {
 633                      $app->enqueueMessage($errors[$i]->getMessage(), 'warning');
 634                  } else {
 635                      $app->enqueueMessage($errors[$i], 'warning');
 636                  }
 637              }
 638  
 639              /**
 640               * We need the filtered value of calendar fields because the UTC normalisation is
 641               * done in the filter and on output. This would apply the Timezone offset on
 642               * reload. We set the calendar values we save to the processed date.
 643               */
 644              $filteredData = $form->filter($data);
 645  
 646              foreach ($form->getFieldset() as $field) {
 647                  if ($field->type === 'Calendar') {
 648                      $fieldName = $field->fieldname;
 649  
 650                      if (isset($filteredData[$fieldName])) {
 651                          $data[$fieldName] = $filteredData[$fieldName];
 652                      }
 653                  }
 654              }
 655  
 656              // Save the data in the session.
 657              $app->setUserState($context . '.data', $data);
 658  
 659              // Redirect back to the edit screen.
 660              $this->setRedirect(
 661                  Route::_(
 662                      'index.php?option=' . $this->option . '&view=' . $this->view_item
 663                      . $this->getRedirectToItemAppend($recordId, $urlVar),
 664                      false
 665                  )
 666              );
 667  
 668              return false;
 669          }
 670  
 671          if (!isset($validData['tags'])) {
 672              $validData['tags'] = array();
 673          }
 674  
 675          // Attempt to save the data.
 676          if (!$model->save($validData)) {
 677              // Save the data in the session.
 678              $app->setUserState($context . '.data', $validData);
 679  
 680              // Redirect back to the edit screen.
 681              $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error');
 682  
 683              $this->setRedirect(
 684                  Route::_(
 685                      'index.php?option=' . $this->option . '&view=' . $this->view_item
 686                      . $this->getRedirectToItemAppend($recordId, $urlVar),
 687                      false
 688                  )
 689              );
 690  
 691              return false;
 692          }
 693  
 694          // Save succeeded, so check-in the record.
 695          if ($checkin && $model->checkin($validData[$key]) === false) {
 696              // Save the data in the session.
 697              $app->setUserState($context . '.data', $validData);
 698  
 699              // Check-in failed, so go back to the record and display a notice.
 700              $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error');
 701  
 702              $this->setRedirect(
 703                  Route::_(
 704                      'index.php?option=' . $this->option . '&view=' . $this->view_item
 705                      . $this->getRedirectToItemAppend($recordId, $urlVar),
 706                      false
 707                  )
 708              );
 709  
 710              return false;
 711          }
 712  
 713          $langKey = $this->text_prefix . ($recordId === 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS';
 714          $prefix  = $this->app->getLanguage()->hasKey($langKey) ? $this->text_prefix : 'JLIB_APPLICATION';
 715  
 716          $this->setMessage(Text::_($prefix . ($recordId === 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS'));
 717  
 718          // Redirect the user and adjust session state based on the chosen task.
 719          switch ($task) {
 720              case 'apply':
 721                  // Set the record data in the session.
 722                  $recordId = $model->getState($model->getName() . '.id');
 723                  $this->holdEditId($context, $recordId);
 724                  $app->setUserState($context . '.data', null);
 725                  $model->checkout($recordId);
 726  
 727                  // Redirect back to the edit screen.
 728                  $this->setRedirect(
 729                      Route::_(
 730                          'index.php?option=' . $this->option . '&view=' . $this->view_item
 731                          . $this->getRedirectToItemAppend($recordId, $urlVar),
 732                          false
 733                      )
 734                  );
 735                  break;
 736  
 737              case 'save2new':
 738                  // Clear the record id and data from the session.
 739                  $this->releaseEditId($context, $recordId);
 740                  $app->setUserState($context . '.data', null);
 741  
 742                  // Redirect back to the edit screen.
 743                  $this->setRedirect(
 744                      Route::_(
 745                          'index.php?option=' . $this->option . '&view=' . $this->view_item
 746                          . $this->getRedirectToItemAppend(null, $urlVar),
 747                          false
 748                      )
 749                  );
 750                  break;
 751  
 752              default:
 753                  // Clear the record id and data from the session.
 754                  $this->releaseEditId($context, $recordId);
 755                  $app->setUserState($context . '.data', null);
 756  
 757                  $url = 'index.php?option=' . $this->option . '&view=' . $this->view_list
 758                      . $this->getRedirectToListAppend();
 759  
 760                  // Check if there is a return value
 761                  $return = $this->input->get('return', null, 'base64');
 762  
 763                  if (!\is_null($return) && Uri::isInternal(base64_decode($return))) {
 764                      $url = base64_decode($return);
 765                  }
 766  
 767                  // Redirect to the list screen.
 768                  $this->setRedirect(Route::_($url, false));
 769                  break;
 770          }
 771  
 772          // Invoke the postSave method to allow for the child class to access the model.
 773          $this->postSaveHook($model, $validData);
 774  
 775          return true;
 776      }
 777  
 778      /**
 779       * Method to reload a record.
 780       *
 781       * @param   string  $key     The name of the primary key of the URL variable.
 782       * @param   string  $urlVar  The name of the URL variable if different from the primary key (sometimes required to avoid router collisions).
 783       *
 784       * @return  void
 785       *
 786       * @since   3.7.4
 787       */
 788      public function reload($key = null, $urlVar = null)
 789      {
 790          // Check for request forgeries.
 791          $this->checkToken();
 792  
 793          $app     = $this->app;
 794          $model   = $this->getModel();
 795          $data    = $this->input->post->get('jform', array(), 'array');
 796  
 797          // Determine the name of the primary key for the data.
 798          if (empty($key)) {
 799              $key = $model->getTable()->getKeyName();
 800          }
 801  
 802          // To avoid data collisions the urlVar may be different from the primary key.
 803          if (empty($urlVar)) {
 804              $urlVar = $key;
 805          }
 806  
 807          $recordId = $this->input->getInt($urlVar);
 808  
 809          // Populate the row id from the session.
 810          $data[$key] = $recordId;
 811  
 812          // Check if it is allowed to edit or create the data
 813          if (($recordId && !$this->allowEdit($data, $key)) || (!$recordId && !$this->allowAdd($data))) {
 814              $this->setRedirect(
 815                  Route::_(
 816                      'index.php?option=' . $this->option . '&view=' . $this->view_list
 817                      . $this->getRedirectToListAppend(),
 818                      false
 819                  )
 820              );
 821              $this->redirect();
 822          }
 823  
 824          // The redirect url
 825          $redirectUrl = Route::_(
 826              'index.php?option=' . $this->option . '&view=' . $this->view_item .
 827              $this->getRedirectToItemAppend($recordId, $urlVar),
 828              false
 829          );
 830  
 831          /** @var \Joomla\CMS\Form\Form $form */
 832          $form = $model->getForm($data, false);
 833  
 834          /**
 835           * We need the filtered value of calendar fields because the UTC normalisation is
 836           * done in the filter and on output. This would apply the Timezone offset on
 837           * reload. We set the calendar values we save to the processed date.
 838           */
 839          $filteredData = $form->filter($data);
 840  
 841          foreach ($form->getFieldset() as $field) {
 842              if ($field->type === 'Calendar') {
 843                  $fieldName = $field->fieldname;
 844  
 845                  if ($field->group) {
 846                      if (isset($filteredData[$field->group][$fieldName])) {
 847                          $data[$field->group][$fieldName] = $filteredData[$field->group][$fieldName];
 848                      }
 849                  } else {
 850                      if (isset($filteredData[$fieldName])) {
 851                          $data[$fieldName] = $filteredData[$fieldName];
 852                      }
 853                  }
 854              }
 855          }
 856  
 857          // Save the data in the session.
 858          $app->setUserState($this->option . '.edit.' . $this->context . '.data', $data);
 859  
 860          $this->setRedirect($redirectUrl);
 861          $this->redirect();
 862      }
 863  
 864      /**
 865       * Load item to edit associations in com_associations
 866       *
 867       * @return  void
 868       *
 869       * @since   3.9.0
 870       *
 871       * @deprecated 5.0  It is handled by regular save method now.
 872       */
 873      public function editAssociations()
 874      {
 875          // Initialise variables.
 876          $app   = $this->app;
 877          $input = $app->input;
 878          $model = $this->getModel();
 879  
 880          $data = $input->get('jform', array(), 'array');
 881          $model->editAssociations($data);
 882      }
 883  }


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