[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |