[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Administrator 5 * @subpackage com_templates 6 * 7 * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> 8 * @license GNU General Public License version 2 or later; see LICENSE.txt 9 */ 10 11 namespace Joomla\Component\Templates\Administrator\Model; 12 13 use Joomla\CMS\Application\ApplicationHelper; 14 use Joomla\CMS\Component\ComponentHelper; 15 use Joomla\CMS\Factory; 16 use Joomla\CMS\Filesystem\Path; 17 use Joomla\CMS\Form\Form; 18 use Joomla\CMS\Language\Multilanguage; 19 use Joomla\CMS\Language\Text; 20 use Joomla\CMS\MVC\Factory\MVCFactoryInterface; 21 use Joomla\CMS\MVC\Model\AdminModel; 22 use Joomla\CMS\Object\CMSObject; 23 use Joomla\CMS\Plugin\PluginHelper; 24 use Joomla\CMS\Table\Table; 25 use Joomla\Database\ParameterType; 26 use Joomla\Registry\Registry; 27 use Joomla\String\StringHelper; 28 use Joomla\Utilities\ArrayHelper; 29 use stdClass; 30 31 // phpcs:disable PSR1.Files.SideEffects 32 \defined('_JEXEC') or die; 33 // phpcs:enable PSR1.Files.SideEffects 34 35 /** 36 * Template style model. 37 * 38 * @since 1.6 39 */ 40 class StyleModel extends AdminModel 41 { 42 /** 43 * The help screen key for the module. 44 * 45 * @var string 46 * @since 1.6 47 */ 48 protected $helpKey = 'Templates:_Edit_Style'; 49 50 /** 51 * The help screen base URL for the module. 52 * 53 * @var string 54 * @since 1.6 55 */ 56 protected $helpURL; 57 58 /** 59 * Item cache. 60 * 61 * @var array 62 * @since 1.6 63 */ 64 private $_cache = array(); 65 66 /** 67 * Constructor. 68 * 69 * @param array $config An optional associative array of configuration settings. 70 * @param MVCFactoryInterface $factory The factory. 71 * 72 * @see \Joomla\CMS\MVC\Model\BaseDatabaseModel 73 * @since 3.2 74 */ 75 public function __construct($config = array(), MVCFactoryInterface $factory = null) 76 { 77 $config = array_merge( 78 array( 79 'event_before_delete' => 'onExtensionBeforeDelete', 80 'event_after_delete' => 'onExtensionAfterDelete', 81 'event_before_save' => 'onExtensionBeforeSave', 82 'event_after_save' => 'onExtensionAfterSave', 83 'events_map' => array('delete' => 'extension', 'save' => 'extension') 84 ), 85 $config 86 ); 87 88 parent::__construct($config, $factory); 89 } 90 91 /** 92 * Method to auto-populate the model state. 93 * 94 * @note Calling getState in this method will result in recursion. 95 * 96 * @return void 97 * 98 * @since 1.6 99 */ 100 protected function populateState() 101 { 102 $app = Factory::getApplication(); 103 104 // Load the User state. 105 $pk = $app->input->getInt('id'); 106 $this->setState('style.id', $pk); 107 108 // Load the parameters. 109 $params = ComponentHelper::getParams('com_templates'); 110 $this->setState('params', $params); 111 } 112 113 /** 114 * Method to delete rows. 115 * 116 * @param array &$pks An array of item ids. 117 * 118 * @return boolean Returns true on success, false on failure. 119 * 120 * @since 1.6 121 * @throws \Exception 122 */ 123 public function delete(&$pks) 124 { 125 $pks = (array) $pks; 126 $user = Factory::getUser(); 127 $table = $this->getTable(); 128 $context = $this->option . '.' . $this->name; 129 130 PluginHelper::importPlugin($this->events_map['delete']); 131 132 // Iterate the items to delete each one. 133 foreach ($pks as $pk) { 134 if ($table->load($pk)) { 135 // Access checks. 136 if (!$user->authorise('core.delete', 'com_templates')) { 137 throw new \Exception(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED')); 138 } 139 140 // You should not delete a default style 141 if ($table->home != '0') { 142 Factory::getApplication()->enqueueMessage(Text::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE'), 'error'); 143 144 return false; 145 } 146 147 // Trigger the before delete event. 148 $result = Factory::getApplication()->triggerEvent($this->event_before_delete, array($context, $table)); 149 150 if (in_array(false, $result, true) || !$table->delete($pk)) { 151 $this->setError($table->getError()); 152 153 return false; 154 } 155 156 // Trigger the after delete event. 157 Factory::getApplication()->triggerEvent($this->event_after_delete, array($context, $table)); 158 } else { 159 $this->setError($table->getError()); 160 161 return false; 162 } 163 } 164 165 // Clean cache 166 $this->cleanCache(); 167 168 return true; 169 } 170 171 /** 172 * Method to duplicate styles. 173 * 174 * @param array &$pks An array of primary key IDs. 175 * 176 * @return boolean True if successful. 177 * 178 * @throws \Exception 179 */ 180 public function duplicate(&$pks) 181 { 182 $user = Factory::getUser(); 183 184 // Access checks. 185 if (!$user->authorise('core.create', 'com_templates')) { 186 throw new \Exception(Text::_('JERROR_CORE_CREATE_NOT_PERMITTED')); 187 } 188 189 $context = $this->option . '.' . $this->name; 190 191 // Include the plugins for the save events. 192 PluginHelper::importPlugin($this->events_map['save']); 193 194 $table = $this->getTable(); 195 196 foreach ($pks as $pk) { 197 if ($table->load($pk, true)) { 198 // Reset the id to create a new record. 199 $table->id = 0; 200 201 // Reset the home (don't want dupes of that field). 202 $table->home = 0; 203 204 // Alter the title. 205 $m = null; 206 $table->title = $this->generateNewTitle(null, null, $table->title); 207 208 if (!$table->check()) { 209 throw new \Exception($table->getError()); 210 } 211 212 // Trigger the before save event. 213 $result = Factory::getApplication()->triggerEvent($this->event_before_save, array($context, &$table, true)); 214 215 if (in_array(false, $result, true) || !$table->store()) { 216 throw new \Exception($table->getError()); 217 } 218 219 // Trigger the after save event. 220 Factory::getApplication()->triggerEvent($this->event_after_save, array($context, &$table, true)); 221 } else { 222 throw new \Exception($table->getError()); 223 } 224 } 225 226 // Clean cache 227 $this->cleanCache(); 228 229 return true; 230 } 231 232 /** 233 * Method to change the title. 234 * 235 * @param integer $categoryId The id of the category. 236 * @param string $alias The alias. 237 * @param string $title The title. 238 * 239 * @return string New title. 240 * 241 * @since 1.7.1 242 */ 243 protected function generateNewTitle($categoryId, $alias, $title) 244 { 245 // Alter the title 246 $table = $this->getTable(); 247 248 while ($table->load(array('title' => $title))) { 249 $title = StringHelper::increment($title); 250 } 251 252 return $title; 253 } 254 255 /** 256 * Method to get the record form. 257 * 258 * @param array $data An optional array of data for the form to interrogate. 259 * @param boolean $loadData True if the form is to load its own data (default case), false if not. 260 * 261 * @return Form A Form object on success, false on failure 262 * 263 * @since 1.6 264 */ 265 public function getForm($data = array(), $loadData = true) 266 { 267 // The folder and element vars are passed when saving the form. 268 if (empty($data)) { 269 $item = $this->getItem(); 270 $clientId = $item->client_id; 271 $template = $item->template; 272 } else { 273 $clientId = ArrayHelper::getValue($data, 'client_id'); 274 $template = ArrayHelper::getValue($data, 'template'); 275 } 276 277 // Add the default fields directory 278 $baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; 279 Form::addFieldPath($baseFolder . '/templates/' . $template . '/field'); 280 281 // These variables are used to add data from the plugin XML files. 282 $this->setState('item.client_id', $clientId); 283 $this->setState('item.template', $template); 284 285 // Get the form. 286 $form = $this->loadForm('com_templates.style', 'style', array('control' => 'jform', 'load_data' => $loadData)); 287 288 if (empty($form)) { 289 return false; 290 } 291 292 // Modify the form based on access controls. 293 if (!$this->canEditState((object) $data)) { 294 // Disable fields for display. 295 $form->setFieldAttribute('home', 'disabled', 'true'); 296 297 // Disable fields while saving. 298 // The controller has already verified this is a record you can edit. 299 $form->setFieldAttribute('home', 'filter', 'unset'); 300 } 301 302 return $form; 303 } 304 305 /** 306 * Method to get the data that should be injected in the form. 307 * 308 * @return mixed The data for the form. 309 * 310 * @since 1.6 311 */ 312 protected function loadFormData() 313 { 314 // Check the session for previously entered form data. 315 $data = Factory::getApplication()->getUserState('com_templates.edit.style.data', array()); 316 317 if (empty($data)) { 318 $data = $this->getItem(); 319 } 320 321 $this->preprocessData('com_templates.style', $data); 322 323 return $data; 324 } 325 326 /** 327 * Method to get a single record. 328 * 329 * @param integer $pk The id of the primary key. 330 * 331 * @return mixed Object on success, false on failure. 332 */ 333 public function getItem($pk = null) 334 { 335 $pk = (!empty($pk)) ? $pk : (int) $this->getState('style.id'); 336 337 if (!isset($this->_cache[$pk])) { 338 // Get a row instance. 339 $table = $this->getTable(); 340 341 // Attempt to load the row. 342 $return = $table->load($pk); 343 344 // Check for a table object error. 345 if ($return === false && $table->getError()) { 346 $this->setError($table->getError()); 347 348 return false; 349 } 350 351 // Convert to the \Joomla\CMS\Object\CMSObject before adding other data. 352 $properties = $table->getProperties(1); 353 $this->_cache[$pk] = ArrayHelper::toObject($properties, CMSObject::class); 354 355 // Convert the params field to an array. 356 $registry = new Registry($table->params); 357 $this->_cache[$pk]->params = $registry->toArray(); 358 359 // Get the template XML. 360 $client = ApplicationHelper::getClientInfo($table->client_id); 361 $path = Path::clean($client->path . '/templates/' . $table->template . '/templateDetails.xml'); 362 363 if (file_exists($path)) { 364 $this->_cache[$pk]->xml = simplexml_load_file($path); 365 } else { 366 $this->_cache[$pk]->xml = null; 367 } 368 } 369 370 return $this->_cache[$pk]; 371 } 372 373 /** 374 * Method to allow derived classes to preprocess the form. 375 * 376 * @param Form $form A Form object. 377 * @param mixed $data The data expected for the form. 378 * @param string $group The name of the plugin group to import (defaults to "content"). 379 * 380 * @return void 381 * 382 * @since 1.6 383 * @throws \Exception if there is an error in the form event. 384 */ 385 protected function preprocessForm(Form $form, $data, $group = 'content') 386 { 387 $clientId = $this->getState('item.client_id'); 388 $template = $this->getState('item.template'); 389 $lang = Factory::getLanguage(); 390 $client = ApplicationHelper::getClientInfo($clientId); 391 392 if (!$form->loadFile('style_' . $client->name, true)) { 393 throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); 394 } 395 396 $formFile = Path::clean($client->path . '/templates/' . $template . '/templateDetails.xml'); 397 398 // Load the core and/or local language file(s). 399 $lang->load('tpl_' . $template, $client->path) 400 || (!empty($data->parent) && $lang->load('tpl_' . $data->parent, $client->path)) 401 || (!empty($data->parent) && $lang->load('tpl_' . $data->parent, $client->path . '/templates/' . $data->parent)) 402 || $lang->load('tpl_' . $template, $client->path . '/templates/' . $template); 403 404 if (file_exists($formFile)) { 405 // Get the template form. 406 if (!$form->loadFile($formFile, false, '//config')) { 407 throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); 408 } 409 } 410 411 // Disable home field if it is default style 412 413 if ( 414 (is_array($data) && array_key_exists('home', $data) && $data['home'] == '1') 415 || (is_object($data) && isset($data->home) && $data->home == '1') 416 ) { 417 $form->setFieldAttribute('home', 'readonly', 'true'); 418 } 419 420 if ($client->name === 'site' && !Multilanguage::isEnabled()) { 421 $form->setFieldAttribute('home', 'type', 'radio'); 422 $form->setFieldAttribute('home', 'layout', 'joomla.form.field.radio.switcher'); 423 } 424 425 // Attempt to load the xml file. 426 if (!$xml = simplexml_load_file($formFile)) { 427 throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); 428 } 429 430 // Get the help data from the XML file if present. 431 $help = $xml->xpath('/extension/help'); 432 433 if (!empty($help)) { 434 $helpKey = trim((string) $help[0]['key']); 435 $helpURL = trim((string) $help[0]['url']); 436 437 $this->helpKey = $helpKey ?: $this->helpKey; 438 $this->helpURL = $helpURL ?: $this->helpURL; 439 } 440 441 // Trigger the default form events. 442 parent::preprocessForm($form, $data, $group); 443 } 444 445 /** 446 * Method to save the form data. 447 * 448 * @param array $data The form data. 449 * 450 * @return boolean True on success. 451 */ 452 public function save($data) 453 { 454 // Detect disabled extension 455 $extension = Table::getInstance('Extension', 'Joomla\\CMS\\Table\\'); 456 457 if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $data['template'], 'client_id' => $data['client_id']))) { 458 $this->setError(Text::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); 459 460 return false; 461 } 462 463 $app = Factory::getApplication(); 464 $table = $this->getTable(); 465 $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('style.id'); 466 $isNew = true; 467 468 // Include the extension plugins for the save events. 469 PluginHelper::importPlugin($this->events_map['save']); 470 471 // Load the row if saving an existing record. 472 if ($pk > 0) { 473 $table->load($pk); 474 $isNew = false; 475 } 476 477 if ($app->input->get('task') == 'save2copy') { 478 $data['title'] = $this->generateNewTitle(null, null, $data['title']); 479 $data['home'] = 0; 480 $data['assigned'] = ''; 481 } 482 483 // Bind the data. 484 if (!$table->bind($data)) { 485 $this->setError($table->getError()); 486 487 return false; 488 } 489 490 // Prepare the row for saving 491 $this->prepareTable($table); 492 493 // Check the data. 494 if (!$table->check()) { 495 $this->setError($table->getError()); 496 497 return false; 498 } 499 500 // Trigger the before save event. 501 $result = Factory::getApplication()->triggerEvent($this->event_before_save, array('com_templates.style', &$table, $isNew)); 502 503 // Store the data. 504 if (in_array(false, $result, true) || !$table->store()) { 505 $this->setError($table->getError()); 506 507 return false; 508 } 509 510 $user = Factory::getUser(); 511 512 if ($user->authorise('core.edit', 'com_menus') && $table->client_id == 0) { 513 $n = 0; 514 $db = $this->getDatabase(); 515 $user = Factory::getUser(); 516 $tableId = (int) $table->id; 517 $userId = (int) $user->id; 518 519 if (!empty($data['assigned']) && is_array($data['assigned'])) { 520 $data['assigned'] = ArrayHelper::toInteger($data['assigned']); 521 522 // Update the mapping for menu items that this style IS assigned to. 523 $query = $db->getQuery(true) 524 ->update($db->quoteName('#__menu')) 525 ->set($db->quoteName('template_style_id') . ' = :newtsid') 526 ->whereIn($db->quoteName('id'), $data['assigned']) 527 ->where($db->quoteName('template_style_id') . ' != :tsid') 528 ->where('(' . $db->quoteName('checked_out') . ' IS NULL OR ' . $db->quoteName('checked_out') . ' = :userid)') 529 ->bind(':userid', $userId, ParameterType::INTEGER) 530 ->bind(':newtsid', $tableId, ParameterType::INTEGER) 531 ->bind(':tsid', $tableId, ParameterType::INTEGER); 532 $db->setQuery($query); 533 $db->execute(); 534 $n += $db->getAffectedRows(); 535 } 536 537 // Remove style mappings for menu items this style is NOT assigned to. 538 // If unassigned then all existing maps will be removed. 539 $query = $db->getQuery(true) 540 ->update($db->quoteName('#__menu')) 541 ->set($db->quoteName('template_style_id') . ' = 0'); 542 543 if (!empty($data['assigned'])) { 544 $query->whereNotIn($db->quoteName('id'), $data['assigned']); 545 } 546 547 $query->where($db->quoteName('template_style_id') . ' = :templatestyleid') 548 ->where('(' . $db->quoteName('checked_out') . ' IS NULL OR ' . $db->quoteName('checked_out') . ' = :userid)') 549 ->bind(':userid', $userId, ParameterType::INTEGER) 550 ->bind(':templatestyleid', $tableId, ParameterType::INTEGER); 551 $db->setQuery($query); 552 $db->execute(); 553 554 $n += $db->getAffectedRows(); 555 556 if ($n > 0) { 557 $app->enqueueMessage(Text::plural('COM_TEMPLATES_MENU_CHANGED', $n)); 558 } 559 } 560 561 // Clean the cache. 562 $this->cleanCache(); 563 564 // Trigger the after save event. 565 Factory::getApplication()->triggerEvent($this->event_after_save, array('com_templates.style', &$table, $isNew)); 566 567 $this->setState('style.id', $table->id); 568 569 return true; 570 } 571 572 /** 573 * Method to set a template style as home. 574 * 575 * @param integer $id The primary key ID for the style. 576 * 577 * @return boolean True if successful. 578 * 579 * @throws \Exception 580 */ 581 public function setHome($id = 0) 582 { 583 $user = Factory::getUser(); 584 $db = $this->getDatabase(); 585 586 // Access checks. 587 if (!$user->authorise('core.edit.state', 'com_templates')) { 588 throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); 589 } 590 591 $style = $this->getTable(); 592 593 if (!$style->load((int) $id)) { 594 throw new \Exception(Text::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); 595 } 596 597 // Detect disabled extension 598 $extension = Table::getInstance('Extension', 'Joomla\\CMS\\Table\\'); 599 600 if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $style->template, 'client_id' => $style->client_id))) { 601 throw new \Exception(Text::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); 602 } 603 604 $clientId = (int) $style->client_id; 605 $id = (int) $id; 606 607 // Reset the home fields for the client_id. 608 $query = $db->getQuery(true) 609 ->update($db->quoteName('#__template_styles')) 610 ->set($db->quoteName('home') . ' = ' . $db->quote('0')) 611 ->where($db->quoteName('client_id') . ' = :clientid') 612 ->where($db->quoteName('home') . ' = ' . $db->quote('1')) 613 ->bind(':clientid', $clientId, ParameterType::INTEGER); 614 $db->setQuery($query); 615 $db->execute(); 616 617 // Set the new home style. 618 $query = $db->getQuery(true) 619 ->update($db->quoteName('#__template_styles')) 620 ->set($db->quoteName('home') . ' = ' . $db->quote('1')) 621 ->where($db->quoteName('id') . ' = :id') 622 ->bind(':id', $id, ParameterType::INTEGER); 623 $db->setQuery($query); 624 $db->execute(); 625 626 // Clean the cache. 627 $this->cleanCache(); 628 629 return true; 630 } 631 632 /** 633 * Method to unset a template style as default for a language. 634 * 635 * @param integer $id The primary key ID for the style. 636 * 637 * @return boolean True if successful. 638 * 639 * @throws \Exception 640 */ 641 public function unsetHome($id = 0) 642 { 643 $user = Factory::getUser(); 644 $db = $this->getDatabase(); 645 646 // Access checks. 647 if (!$user->authorise('core.edit.state', 'com_templates')) { 648 throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); 649 } 650 651 $id = (int) $id; 652 653 // Lookup the client_id. 654 $query = $db->getQuery(true) 655 ->select($db->quoteName(['client_id', 'home'])) 656 ->from($db->quoteName('#__template_styles')) 657 ->where($db->quoteName('id') . ' = :id') 658 ->bind(':id', $id, ParameterType::INTEGER); 659 $db->setQuery($query); 660 $style = $db->loadObject(); 661 662 if (!is_numeric($style->client_id)) { 663 throw new \Exception(Text::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); 664 } elseif ($style->home == '1') { 665 throw new \Exception(Text::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE')); 666 } 667 668 // Set the new home style. 669 $query = $db->getQuery(true) 670 ->update($db->quoteName('#__template_styles')) 671 ->set($db->quoteName('home') . ' = ' . $db->quote('0')) 672 ->where($db->quoteName('id') . ' = :id') 673 ->bind(':id', $id, ParameterType::INTEGER); 674 $db->setQuery($query); 675 $db->execute(); 676 677 // Clean the cache. 678 $this->cleanCache(); 679 680 return true; 681 } 682 683 /** 684 * Get the necessary data to load an item help screen. 685 * 686 * @return object An object with key, url, and local properties for loading the item help screen. 687 * 688 * @since 1.6 689 */ 690 public function getHelp() 691 { 692 return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); 693 } 694 695 /** 696 * Returns the back end template for the given style. 697 * 698 * @param int $styleId The style id 699 * 700 * @return stdClass 701 * 702 * @since 4.2.0 703 */ 704 public function getAdminTemplate(int $styleId): stdClass 705 { 706 $db = $this->getDatabase(); 707 $query = $db->getQuery(true) 708 ->select($db->quoteName(['s.template', 's.params', 's.inheritable', 's.parent'])) 709 ->from($db->quoteName('#__template_styles', 's')) 710 ->join( 711 'LEFT', 712 $db->quoteName('#__extensions', 'e'), 713 $db->quoteName('e.type') . ' = ' . $db->quote('template') 714 . ' AND ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('s.template') 715 . ' AND ' . $db->quoteName('e.client_id') . ' = ' . $db->quoteName('s.client_id') 716 ) 717 ->where( 718 [ 719 $db->quoteName('s.client_id') . ' = 1', 720 $db->quoteName('s.home') . ' = ' . $db->quote('1'), 721 ] 722 ); 723 724 if ($styleId) { 725 $query->extendWhere( 726 'OR', 727 [ 728 $db->quoteName('s.client_id') . ' = 1', 729 $db->quoteName('s.id') . ' = :style', 730 $db->quoteName('e.enabled') . ' = 1', 731 ] 732 ) 733 ->bind(':style', $styleId, ParameterType::INTEGER); 734 } 735 736 $query->order($db->quoteName('s.home')); 737 $db->setQuery($query); 738 739 return $db->loadObject(); 740 } 741 742 /** 743 * Returns the front end templates. 744 * 745 * @return array 746 * 747 * @since 4.2.0 748 */ 749 public function getSiteTemplates(): array 750 { 751 $db = $this->getDatabase(); 752 $query = $db->getQuery(true) 753 ->select($db->quoteName(['id', 'home', 'template', 's.params', 'inheritable', 'parent'])) 754 ->from($db->quoteName('#__template_styles', 's')) 755 ->where( 756 [ 757 $db->quoteName('s.client_id') . ' = 0', 758 $db->quoteName('e.enabled') . ' = 1', 759 ] 760 ) 761 ->join( 762 'LEFT', 763 $db->quoteName('#__extensions', 'e'), 764 $db->quoteName('e.element') . ' = ' . $db->quoteName('s.template') 765 . ' AND ' . $db->quoteName('e.type') . ' = ' . $db->quote('template') 766 . ' AND ' . $db->quoteName('e.client_id') . ' = ' . $db->quoteName('s.client_id') 767 ); 768 769 $db->setQuery($query); 770 771 return $db->loadObjectList('id'); 772 } 773 774 /** 775 * Custom clean cache method 776 * 777 * @param string $group The cache group 778 * @param integer $clientId @deprecated 5.0 No longer used. 779 * 780 * @return void 781 * 782 * @since 1.6 783 */ 784 protected function cleanCache($group = null, $clientId = 0) 785 { 786 parent::cleanCache('com_templates'); 787 parent::cleanCache('_system'); 788 } 789 }
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 |