[ 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\Controller; 12 13 use Joomla\CMS\Application\CMSApplication; 14 use Joomla\CMS\Filesystem\Path; 15 use Joomla\CMS\Filter\InputFilter; 16 use Joomla\CMS\Language\Text; 17 use Joomla\CMS\MVC\Controller\BaseController; 18 use Joomla\CMS\MVC\Factory\MVCFactoryInterface; 19 use Joomla\CMS\Plugin\PluginHelper; 20 use Joomla\CMS\Router\Route; 21 use Joomla\CMS\Session\Session; 22 use Joomla\Input\Input; 23 use Joomla\Utilities\ArrayHelper; 24 25 // phpcs:disable PSR1.Files.SideEffects 26 \defined('_JEXEC') or die; 27 // phpcs:enable PSR1.Files.SideEffects 28 29 /** 30 * Template style controller class. 31 * 32 * @since 1.6 33 */ 34 class TemplateController extends BaseController 35 { 36 /** 37 * Constructor. 38 * 39 * @param array $config An optional associative array of configuration settings. 40 * @param MVCFactoryInterface $factory The factory. 41 * @param CMSApplication $app The Application for the dispatcher 42 * @param Input $input Input 43 * 44 * @since 1.6 45 * @see BaseController 46 */ 47 public function __construct($config = array(), MVCFactoryInterface $factory = null, $app = null, $input = null) 48 { 49 parent::__construct($config, $factory, $app, $input); 50 51 $this->registerTask('apply', 'save'); 52 $this->registerTask('unpublish', 'publish'); 53 $this->registerTask('publish', 'publish'); 54 $this->registerTask('deleteOverrideHistory', 'publish'); 55 } 56 57 /** 58 * Method for closing the template. 59 * 60 * @return void 61 * 62 * @since 3.2 63 */ 64 public function cancel() 65 { 66 $this->setRedirect(Route::_('index.php?option=com_templates&view=templates', false)); 67 } 68 69 /** 70 * Method for closing a file. 71 * 72 * @return void 73 * 74 * @since 3.2 75 */ 76 public function close() 77 { 78 $file = base64_encode('home'); 79 $id = (int) $this->input->get('id', 0, 'int'); 80 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . 81 $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 82 $this->setRedirect(Route::_($url, false)); 83 } 84 85 /** 86 * Marked as Checked/Unchecked of override history. 87 * 88 * @return void 89 * 90 * @since 4.0.0 91 */ 92 public function publish() 93 { 94 // Check for request forgeries. 95 $this->checkToken(); 96 97 $file = $this->input->get('file'); 98 $id = $this->input->get('id'); 99 100 $ids = (array) $this->input->get('cid', array(), 'string'); 101 $values = array('publish' => 1, 'unpublish' => 0, 'deleteOverrideHistory' => -3); 102 $task = $this->getTask(); 103 $value = ArrayHelper::getValue($values, $task, 0, 'int'); 104 105 if (empty($ids)) { 106 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_NO_FILE_SELECTED'), 'warning'); 107 } else { 108 /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 109 $model = $this->getModel(); 110 111 // Change the state of the records. 112 if (!$model->publish($ids, $value, $id)) { 113 $this->setMessage(implode('<br>', $model->getErrors()), 'warning'); 114 } else { 115 if ($value === 1) { 116 $ntext = 'COM_TEMPLATES_N_OVERRIDE_CHECKED'; 117 } elseif ($value === 0) { 118 $ntext = 'COM_TEMPLATES_N_OVERRIDE_UNCHECKED'; 119 } elseif ($value === -3) { 120 $ntext = 'COM_TEMPLATES_N_OVERRIDE_DELETED'; 121 } 122 123 $this->setMessage(Text::plural($ntext, count($ids))); 124 } 125 } 126 127 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . 128 $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 129 $this->setRedirect(Route::_($url, false)); 130 } 131 132 /** 133 * Method for copying the template. 134 * 135 * @return boolean true on success, false otherwise 136 * 137 * @since 3.2 138 */ 139 public function copy() 140 { 141 // Check for request forgeries 142 $this->checkToken(); 143 144 $app = $this->app; 145 $this->input->set('installtype', 'folder'); 146 $newNameRaw = $this->input->get('new_name', null, 'string'); 147 // Only accept letters, numbers and underscore for template name 148 $newName = preg_replace('/[^a-zA-Z0-9_]/', '', $newNameRaw); 149 $templateID = (int) $this->input->getInt('id', 0); 150 $file = (string) $this->input->get('file', '', 'cmd'); 151 152 // Access check. 153 if (!$this->allowEdit()) { 154 $app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 155 156 return false; 157 } 158 159 $this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file); 160 161 /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 162 $model = $this->getModel('Template', 'Administrator'); 163 $model->setState('new_name', $newName); 164 $model->setState('tmp_prefix', uniqid('template_copy_')); 165 $model->setState('to_path', $app->get('tmp_path') . '/' . $model->getState('tmp_prefix')); 166 167 // Process only if we have a new name entered 168 if (strlen($newName) > 0) { 169 if (!$this->app->getIdentity()->authorise('core.create', 'com_templates')) { 170 // User is not authorised to delete 171 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error'); 172 173 return false; 174 } 175 176 // Check that new name is valid 177 if (($newNameRaw !== null) && ($newName !== $newNameRaw)) { 178 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); 179 180 return false; 181 } 182 183 // Check that new name doesn't already exist 184 if (!$model->checkNewName()) { 185 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error'); 186 187 return false; 188 } 189 190 // Check that from name does exist and get the folder name 191 $fromName = $model->getFromName(); 192 193 if (!$fromName) { 194 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); 195 196 return false; 197 } 198 199 // Call model's copy method 200 if (!$model->copy()) { 201 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error'); 202 203 return false; 204 } 205 206 // Call installation model 207 $this->input->set('install_directory', $app->get('tmp_path') . '/' . $model->getState('tmp_prefix')); 208 209 /** @var \Joomla\Component\Installer\Administrator\Model\InstallModel $installModel */ 210 $installModel = $this->app->bootComponent('com_installer') 211 ->getMVCFactory()->createModel('Install', 'Administrator'); 212 $this->app->getLanguage()->load('com_installer'); 213 214 if (!$installModel->install()) { 215 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error'); 216 217 return false; 218 } 219 220 $this->setMessage(Text::sprintf('COM_TEMPLATES_COPY_SUCCESS', $newName)); 221 $model->cleanup(); 222 223 return true; 224 } 225 226 $this->setMessage(Text::sprintf('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); 227 228 return false; 229 } 230 231 /** 232 * Method to get a model object, loading it if required. 233 * 234 * @param string $name The model name. Optional. 235 * @param string $prefix The class prefix. Optional. 236 * @param array $config Configuration array for model. Optional (note, the empty array is atypical compared to other models). 237 * 238 * @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model. 239 * 240 * @since 3.2 241 */ 242 public function getModel($name = 'Template', $prefix = 'Administrator', $config = array()) 243 { 244 return parent::getModel($name, $prefix, $config); 245 } 246 247 /** 248 * Method to check if you can add a new record. 249 * 250 * @return boolean 251 * 252 * @since 3.2 253 */ 254 protected function allowEdit() 255 { 256 return $this->app->getIdentity()->authorise('core.admin'); 257 } 258 259 /** 260 * Saves a template source file. 261 * 262 * @return void 263 * 264 * @since 3.2 265 */ 266 public function save() 267 { 268 // Check for request forgeries. 269 $this->checkToken(); 270 271 $data = $this->input->post->get('jform', array(), 'array'); 272 $task = $this->getTask(); 273 274 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 275 $model = $this->getModel(); 276 $fileName = (string) $this->input->getCmd('file', ''); 277 $explodeArray = explode(':', str_replace('//', '/', base64_decode($fileName))); 278 279 // Access check. 280 if (!$this->allowEdit()) { 281 $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 282 283 return; 284 } 285 286 // Match the stored id's with the submitted. 287 if (empty($data['extension_id']) || empty($data['filename'])) { 288 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); 289 290 return; 291 } elseif ($data['extension_id'] != $model->getState('extension.id')) { 292 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); 293 294 return; 295 } elseif (str_ends_with(end($explodeArray), Path::clean($data['filename'], '/'))) { 296 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); 297 298 return; 299 } 300 301 // Validate the posted data. 302 $form = $model->getForm(); 303 304 if (!$form) { 305 $this->setMessage($model->getError(), 'error'); 306 307 return; 308 } 309 310 $data = $model->validate($form, $data); 311 312 // Check for validation errors. 313 if ($data === false) { 314 // Get the validation messages. 315 $errors = $model->getErrors(); 316 317 // Push up to three validation messages out to the user. 318 for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { 319 if ($errors[$i] instanceof \Exception) { 320 $this->app->enqueueMessage($errors[$i]->getMessage(), 'warning'); 321 } else { 322 $this->app->enqueueMessage($errors[$i], 'warning'); 323 } 324 } 325 326 // Redirect back to the edit screen. 327 $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName . '&isMedia=' . $this->input->getInt('isMedia', 0); 328 $this->setRedirect(Route::_($url, false)); 329 330 return; 331 } 332 333 // Attempt to save the data. 334 if (!$model->save($data)) { 335 // Redirect back to the edit screen. 336 $this->setMessage(Text::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning'); 337 $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName . '&isMedia=' . $this->input->getInt('isMedia', 0); 338 $this->setRedirect(Route::_($url, false)); 339 340 return; 341 } 342 343 $this->setMessage(Text::_('COM_TEMPLATES_FILE_SAVE_SUCCESS')); 344 345 // Redirect the user based on the chosen task. 346 switch ($task) { 347 case 'apply': 348 // Redirect back to the edit screen. 349 $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName . '&isMedia=' . $this->input->getInt('isMedia', 0); 350 $this->setRedirect(Route::_($url, false)); 351 break; 352 353 default: 354 // Redirect to the list screen. 355 $file = base64_encode('home'); 356 $id = (int) $this->input->get('id', 0, 'int'); 357 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 358 $this->setRedirect(Route::_($url, false)); 359 break; 360 } 361 } 362 363 /** 364 * Method for creating override. 365 * 366 * @return void 367 * 368 * @since 3.2 369 */ 370 public function overrides() 371 { 372 // Check for request forgeries. 373 $this->checkToken('get'); 374 375 /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 376 $model = $this->getModel(); 377 $file = (string) $this->input->getCmd('file', ''); 378 $override = (string) InputFilter::getInstance( 379 [], 380 [], 381 InputFilter::ONLY_BLOCK_DEFINED_TAGS, 382 InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES 383 ) 384 ->clean(base64_decode($this->input->getBase64('folder', '')), 'path'); 385 $id = (int) $this->input->get('id', 0, 'int'); 386 387 // Access check. 388 if (!$this->allowEdit()) { 389 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 390 391 return; 392 } 393 394 $model->createOverride($override); 395 396 // Redirect back to the edit screen. 397 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 398 $this->setRedirect(Route::_($url, false)); 399 } 400 401 /** 402 * Method for deleting a file. 403 * 404 * @return void 405 * 406 * @since 3.2 407 */ 408 public function delete() 409 { 410 // Check for request forgeries 411 $this->checkToken(); 412 413 /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 414 $model = $this->getModel(); 415 $id = (int) $this->input->get('id', 0, 'int'); 416 $file = (string) $this->input->getCmd('file', ''); 417 418 // Access check. 419 if (!$this->allowEdit()) { 420 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 421 422 return; 423 } 424 425 if (base64_decode(urldecode($file)) == '/index.php') { 426 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INDEX_DELETE'), 'warning'); 427 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 428 $this->setRedirect(Route::_($url, false)); 429 } elseif (base64_decode(urldecode($file)) == '/joomla.asset.json') { 430 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_ASSET_FILE_DELETE'), 'warning'); 431 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 432 $this->setRedirect(Route::_($url, false)); 433 } elseif ($model->deleteFile($file)) { 434 $this->setMessage(Text::_('COM_TEMPLATES_FILE_DELETE_SUCCESS')); 435 $file = base64_encode('home'); 436 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 437 $this->setRedirect(Route::_($url, false)); 438 } else { 439 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_DELETE'), 'error'); 440 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 441 $this->setRedirect(Route::_($url, false)); 442 } 443 } 444 445 /** 446 * Method for creating a new file. 447 * 448 * @return void 449 * 450 * @since 3.2 451 */ 452 public function createFile() 453 { 454 // Check for request forgeries 455 $this->checkToken(); 456 457 /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 458 $model = $this->getModel(); 459 $id = (int) $this->input->get('id', 0, 'int'); 460 $file = (string) $this->input->get('file', '', 'cmd'); 461 $name = (string) $this->input->get('name', '', 'cmd'); 462 $location = (string) InputFilter::getInstance( 463 [], 464 [], 465 InputFilter::ONLY_BLOCK_DEFINED_TAGS, 466 InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES 467 ) 468 ->clean(base64_decode($this->input->getBase64('address', '')), 'path'); 469 $type = (string) $this->input->get('type', '', 'cmd'); 470 471 // Access check. 472 if (!$this->allowEdit()) { 473 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 474 475 return; 476 } 477 478 if ($type == 'null') { 479 $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_TYPE'), 'error'); 480 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 481 $this->setRedirect(Route::_($url, false)); 482 } elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) { 483 $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); 484 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 485 $this->setRedirect(Route::_($url, false)); 486 } elseif ($model->createFile($name, $type, $location)) { 487 $this->setMessage(Text::_('COM_TEMPLATES_FILE_CREATE_SUCCESS')); 488 $file = urlencode(base64_encode($location . '/' . $name . '.' . $type)); 489 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 490 $this->setRedirect(Route::_($url, false)); 491 } else { 492 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_CREATE'), 'error'); 493 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 494 $this->setRedirect(Route::_($url, false)); 495 } 496 } 497 498 /** 499 * Method for uploading a file. 500 * 501 * @return void 502 * 503 * @since 3.2 504 */ 505 public function uploadFile() 506 { 507 // Check for request forgeries 508 $this->checkToken(); 509 510 /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 511 $model = $this->getModel(); 512 $id = (int) $this->input->get('id', 0, 'int'); 513 $file = (string) $this->input->getCmd('file', ''); 514 $upload = $this->input->files->get('files'); 515 $location = (string) InputFilter::getInstance( 516 [], 517 [], 518 InputFilter::ONLY_BLOCK_DEFINED_TAGS, 519 InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES 520 ) 521 ->clean(base64_decode($this->input->getBase64('address', '')), 'path'); 522 523 // Access check. 524 if (!$this->allowEdit()) { 525 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 526 527 return; 528 } 529 530 if ($return = $model->uploadFile($upload, $location)) { 531 $this->setMessage(Text::sprintf('COM_TEMPLATES_FILE_UPLOAD_SUCCESS', $upload['name'])); 532 $redirect = base64_encode($return); 533 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $redirect . '&isMedia=' . $this->input->getInt('isMedia', 0); 534 $this->setRedirect(Route::_($url, false)); 535 } else { 536 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_UPLOAD'), 'error'); 537 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 538 $this->setRedirect(Route::_($url, false)); 539 } 540 } 541 542 /** 543 * Method for creating a new folder. 544 * 545 * @return void 546 * 547 * @since 3.2 548 */ 549 public function createFolder() 550 { 551 // Check for request forgeries 552 $this->checkToken(); 553 554 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 555 $model = $this->getModel(); 556 $id = (int) $this->input->get('id', 0, 'int'); 557 $file = (string) $this->input->getCmd('file', ''); 558 $name = $this->input->get('name'); 559 $location = (string) InputFilter::getInstance( 560 [], 561 [], 562 InputFilter::ONLY_BLOCK_DEFINED_TAGS, 563 InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES 564 ) 565 ->clean(base64_decode($this->input->getBase64('address', '')), 'path'); 566 567 // Access check. 568 if (!$this->allowEdit()) { 569 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 570 571 return; 572 } 573 574 if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $name)) { 575 $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FOLDER_NAME'), 'error'); 576 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 577 $this->setRedirect(Route::_($url, false)); 578 } elseif ($model->createFolder($name, $location)) { 579 $this->setMessage(Text::_('COM_TEMPLATES_FOLDER_CREATE_SUCCESS')); 580 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 581 $this->setRedirect(Route::_($url, false)); 582 } else { 583 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FOLDER_CREATE'), 'error'); 584 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 585 $this->setRedirect(Route::_($url, false)); 586 } 587 } 588 589 /** 590 * Method for deleting a folder. 591 * 592 * @return void 593 * 594 * @since 3.2 595 */ 596 public function deleteFolder() 597 { 598 // Check for request forgeries 599 $this->checkToken(); 600 601 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 602 $model = $this->getModel(); 603 $id = (int) $this->input->get('id', 0, 'int'); 604 $isMedia = (int) $this->input->get('isMedia', 0, 'int'); 605 $file = (string) $this->input->getCmd('file', ''); 606 $location = (string) InputFilter::getInstance( 607 [], 608 [], 609 InputFilter::ONLY_BLOCK_DEFINED_TAGS, 610 InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES 611 ) 612 ->clean(base64_decode($this->input->getBase64('address', '')), 'path'); 613 614 // Access check. 615 if (!$this->allowEdit()) { 616 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 617 618 return; 619 } 620 621 if (empty($location)) { 622 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_ROOT_DELETE'), 'warning'); 623 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia; 624 $this->setRedirect(Route::_($url, false)); 625 } elseif ($model->deleteFolder($location)) { 626 $this->setMessage(Text::_('COM_TEMPLATES_FOLDER_DELETE_SUCCESS')); 627 628 if (stristr(base64_decode($file), $location) != false) { 629 $file = base64_encode('home'); 630 } 631 632 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia; 633 $this->setRedirect(Route::_($url, false)); 634 } else { 635 $this->setMessage(Text::_('COM_TEMPLATES_FOLDER_DELETE_ERROR'), 'error'); 636 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia; 637 $this->setRedirect(Route::_($url, false)); 638 } 639 } 640 641 /** 642 * Method for renaming a file. 643 * 644 * @return void 645 * 646 * @since 3.2 647 */ 648 public function renameFile() 649 { 650 // Check for request forgeries 651 $this->checkToken(); 652 653 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 654 $model = $this->getModel(); 655 $id = (int) $this->input->get('id', 0, 'int'); 656 $isMedia = (int) $this->input->get('isMedia', 0, 'int'); 657 $file = (string) $this->input->getCmd('file', ''); 658 $newName = $this->input->get('new_name'); 659 660 // Access check. 661 if (!$this->allowEdit()) { 662 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 663 664 return; 665 } 666 667 if (base64_decode(urldecode($file)) == '/index.php') { 668 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_RENAME_INDEX'), 'warning'); 669 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia; 670 $this->setRedirect(Route::_($url, false)); 671 } elseif (base64_decode(urldecode($file)) == '/joomla.asset.json') { 672 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_RENAME_ASSET_FILE'), 'warning'); 673 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia; 674 $this->setRedirect(Route::_($url, false)); 675 } elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) { 676 $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); 677 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia; 678 $this->setRedirect(Route::_($url, false)); 679 } elseif ($rename = $model->renameFile($file, $newName)) { 680 $this->setMessage(Text::_('COM_TEMPLATES_FILE_RENAME_SUCCESS')); 681 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $rename . '&isMedia=' . $isMedia; 682 $this->setRedirect(Route::_($url, false)); 683 } else { 684 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_RENAME'), 'error'); 685 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia; 686 $this->setRedirect(Route::_($url, false)); 687 } 688 } 689 690 /** 691 * Method for cropping an image. 692 * 693 * @return void 694 * 695 * @since 3.2 696 */ 697 public function cropImage() 698 { 699 // Check for request forgeries 700 $this->checkToken(); 701 702 $id = (int) $this->input->get('id', 0, 'int'); 703 $file = (string) $this->input->get('file', '', 'cmd'); 704 $x = $this->input->get('x'); 705 $y = $this->input->get('y'); 706 $w = $this->input->get('w'); 707 $h = $this->input->get('h'); 708 709 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 710 $model = $this->getModel(); 711 712 // Access check. 713 if (!$this->allowEdit()) { 714 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 715 716 return; 717 } 718 719 if (empty($w) && empty($h) && empty($x) && empty($y)) { 720 $this->setMessage(Text::_('COM_TEMPLATES_CROP_AREA_ERROR'), 'error'); 721 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 722 $this->setRedirect(Route::_($url, false)); 723 } elseif ($model->cropImage($file, $w, $h, $x, $y)) { 724 $this->setMessage(Text::_('COM_TEMPLATES_FILE_CROP_SUCCESS')); 725 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 726 $this->setRedirect(Route::_($url, false)); 727 } else { 728 $this->setMessage(Text::_('COM_TEMPLATES_FILE_CROP_ERROR'), 'error'); 729 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 730 $this->setRedirect(Route::_($url, false)); 731 } 732 } 733 734 /** 735 * Method for resizing an image. 736 * 737 * @return void 738 * 739 * @since 3.2 740 */ 741 public function resizeImage() 742 { 743 // Check for request forgeries 744 $this->checkToken(); 745 746 $id = (int) $this->input->get('id', 0, 'int'); 747 $file = (string) $this->input->getCmd('file', ''); 748 $width = $this->input->get('width'); 749 $height = $this->input->get('height'); 750 751 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 752 $model = $this->getModel(); 753 754 // Access check. 755 if (!$this->allowEdit()) { 756 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 757 758 return; 759 } 760 761 if ($model->resizeImage($file, $width, $height)) { 762 $this->setMessage(Text::_('COM_TEMPLATES_FILE_RESIZE_SUCCESS')); 763 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 764 $this->setRedirect(Route::_($url, false)); 765 } else { 766 $this->setMessage(Text::_('COM_TEMPLATES_FILE_RESIZE_ERROR'), 'error'); 767 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 768 $this->setRedirect(Route::_($url, false)); 769 } 770 } 771 772 /** 773 * Method for copying a file. 774 * 775 * @return void 776 * 777 * @since 3.2 778 */ 779 public function copyFile() 780 { 781 // Check for request forgeries 782 $this->checkToken(); 783 784 $id = (int) $this->input->get('id', 0, 'int'); 785 $file = (string) $this->input->getCmd('file', ''); 786 $newName = $this->input->get('new_name'); 787 $location = (string) InputFilter::getInstance( 788 [], 789 [], 790 InputFilter::ONLY_BLOCK_DEFINED_TAGS, 791 InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES 792 ) 793 ->clean(base64_decode($this->input->getBase64('address', '')), 'path'); 794 795 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 796 $model = $this->getModel(); 797 798 // Access check. 799 if (!$this->allowEdit()) { 800 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 801 802 return; 803 } 804 805 if (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) { 806 $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); 807 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 808 $this->setRedirect(Route::_($url, false)); 809 } elseif ($model->copyFile($newName, $location, $file)) { 810 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 811 $this->setRedirect(Route::_($url, false)); 812 } else { 813 $this->setMessage(Text::_('COM_TEMPLATES_FILE_COPY_FAIL'), 'error'); 814 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0); 815 $this->setRedirect(Route::_($url, false)); 816 } 817 } 818 819 /** 820 * Method for extracting an archive file. 821 * 822 * @return void 823 * 824 * @since 3.2 825 */ 826 public function extractArchive() 827 { 828 // Check for request forgeries 829 $this->checkToken(); 830 831 $id = (int) $this->input->get('id', 0, 'int'); 832 $file = (string) $this->input->getCmd('file', ''); 833 834 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 835 $model = $this->getModel(); 836 837 // Access check. 838 if (!$this->allowEdit()) { 839 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 840 841 return; 842 } 843 844 if ($model->extractArchive($file)) { 845 $this->setMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_SUCCESS')); 846 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; 847 $this->setRedirect(Route::_($url, false)); 848 } else { 849 $this->setMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_FAIL'), 'error'); 850 $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; 851 $this->setRedirect(Route::_($url, false)); 852 } 853 } 854 855 /** 856 * Fetch and report updates in \JSON format, for AJAX requests 857 * 858 * @return void 859 * 860 * @since 4.0.0 861 */ 862 public function ajax() 863 { 864 $app = $this->app; 865 866 if (!Session::checkToken('get')) { 867 $app->setHeader('status', 403, true); 868 $app->sendHeaders(); 869 echo Text::_('JINVALID_TOKEN_NOTICE'); 870 $app->close(); 871 } 872 873 // Checks status of installer override plugin. 874 if (!PluginHelper::isEnabled('installer', 'override')) { 875 $error = array('installerOverride' => 'disabled'); 876 877 echo json_encode($error); 878 879 $app->close(); 880 } 881 882 /** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 883 $model = $this->getModel(); 884 885 $result = $model->getUpdatedList(true, true); 886 887 echo json_encode($result); 888 889 $app->close(); 890 } 891 892 893 /** 894 * Method for creating a child template. 895 * 896 * @return boolean true on success, false otherwise 897 * 898 * @since 4.1.0 899 */ 900 public function child() 901 { 902 // Check for request forgeries 903 $this->checkToken(); 904 905 // Access check. 906 if (!$this->allowEdit()) { 907 $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); 908 909 return false; 910 } 911 912 $this->input->set('installtype', 'folder'); 913 $newNameRaw = $this->input->get('new_name', null, 'string'); 914 915 // Only accept letters, numbers and underscore for template name 916 $newName = preg_replace('/[^a-zA-Z0-9_]/', '', $newNameRaw); 917 $templateID = (int) $this->input->getInt('id', 0); 918 $file = (string) $this->input->get('file', '', 'cmd'); 919 $extraStyles = (array) $this->input->get('style_ids', [], 'array'); 920 921 $this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file); 922 923 /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ 924 $model = $this->getModel('Template', 'Administrator'); 925 $model->setState('new_name', $newName); 926 $model->setState('tmp_prefix', uniqid('template_child_')); 927 $model->setState('to_path', $this->app->get('tmp_path') . '/' . $model->getState('tmp_prefix')); 928 929 // Process only if we have a new name entered 930 if (!strlen($newName)) { 931 $this->setMessage(Text::sprintf('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); 932 933 return false; 934 } 935 936 // Process only if user is allowed to create child template 937 if (!$this->app->getIdentity()->authorise('core.create', 'com_templates')) { 938 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error'); 939 940 return false; 941 } 942 943 // Check that new name is valid 944 if (($newNameRaw !== null) && ($newName !== $newNameRaw)) { 945 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); 946 947 return false; 948 } 949 950 // Check that new name doesn't already exist 951 if (!$model->checkNewName()) { 952 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error'); 953 954 return false; 955 } 956 957 // Check that from name does exist and get the folder name 958 $fromName = $model->getFromName(); 959 960 if (!$fromName) { 961 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); 962 963 return false; 964 } 965 966 // Call model's copy method 967 if (!$model->child()) { 968 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error'); 969 970 return false; 971 } 972 973 // Call installation model 974 $this->input->set('install_directory', $this->app->get('tmp_path') . '/' . $model->getState('tmp_prefix')); 975 976 /** @var \Joomla\Component\Installer\Administrator\Model\InstallModel $installModel */ 977 $installModel = $this->app->bootComponent('com_installer') 978 ->getMVCFactory()->createModel('Install', 'Administrator'); 979 $this->app->getLanguage()->load('com_installer'); 980 981 if (!$installModel->install()) { 982 $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error'); 983 984 return false; 985 } 986 987 $this->setMessage(Text::sprintf('COM_TEMPLATES_CHILD_SUCCESS', $newName)); 988 $model->cleanup(); 989 990 if (\count($extraStyles) > 0) { 991 $model->setState('stylesToCopy', $extraStyles); 992 $model->copyStyles(); 993 } 994 995 return true; 996 } 997 }
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 |