first commit
This commit is contained in:
12
administrator/components/com_templates/access.xml
Normal file
12
administrator/components/com_templates/access.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<access component="com_templates">
|
||||
<section name="component">
|
||||
<action name="core.admin" title="JACTION_ADMIN" />
|
||||
<action name="core.options" title="JACTION_OPTIONS" />
|
||||
<action name="core.manage" title="JACTION_MANAGE" />
|
||||
<action name="core.create" title="JACTION_CREATE" />
|
||||
<action name="core.delete" title="JACTION_DELETE" />
|
||||
<action name="core.edit" title="JACTION_EDIT" />
|
||||
<action name="core.edit.state" title="JACTION_EDITSTATE" />
|
||||
</section>
|
||||
</access>
|
||||
99
administrator/components/com_templates/config.xml
Normal file
99
administrator/components/com_templates/config.xml
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config>
|
||||
<help key="Template:_Options"/>
|
||||
<inlinehelp button="show"/>
|
||||
<fieldset
|
||||
name="templates"
|
||||
label="COM_TEMPLATES_SUBMENU_TEMPLATES"
|
||||
description="COM_TEMPLATES_CONFIG_FIELDSET_DESC">
|
||||
|
||||
<field
|
||||
name="template_positions_display"
|
||||
type="radio"
|
||||
label="COM_TEMPLATES_CONFIG_POSITIONS_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
>
|
||||
<option value="0">JDISABLED</option>
|
||||
<option value="1">JENABLED</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="upload_limit"
|
||||
type="number"
|
||||
label="COM_TEMPLATES_CONFIG_UPLOAD_LABEL"
|
||||
default="10"
|
||||
extension="com_templates"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="spacer"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="image_formats"
|
||||
type="text"
|
||||
label="COM_TEMPLATES_CONFIG_IMAGE_LABEL"
|
||||
default="gif,bmp,jpg,jpeg,png,webp"
|
||||
extension="com_templates"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="source_formats"
|
||||
type="text"
|
||||
label="COM_TEMPLATES_CONFIG_SOURCE_LABEL"
|
||||
default="txt,less,ini,xml,js,php,css,sass,scss,json"
|
||||
extension="com_templates"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="font_formats"
|
||||
type="text"
|
||||
label="COM_TEMPLATES_CONFIG_FONT_LABEL"
|
||||
default="woff,woff2,ttf,otf"
|
||||
extension="com_templates"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="compressed_formats"
|
||||
type="hidden"
|
||||
default="zip"
|
||||
extension="com_templates"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="spacer2"
|
||||
type="spacer"
|
||||
hr="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="difference"
|
||||
type="radio"
|
||||
label="COM_TEMPLATES_DIFF_OPTIONS"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="SideBySide"
|
||||
>
|
||||
<option value="Inline">COM_TEMPLATES_DIFF_OPTIONS_INLINE</option>
|
||||
<option value="SideBySide">COM_TEMPLATES_DIFF_OPTIONS_SIDE</option>
|
||||
</field>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<fieldset
|
||||
name="permissions"
|
||||
label="JCONFIG_PERMISSIONS_LABEL"
|
||||
>
|
||||
<field
|
||||
name="rules"
|
||||
type="rules"
|
||||
label="JCONFIG_PERMISSIONS_LABEL"
|
||||
filter="rules"
|
||||
validate="rules"
|
||||
component="com_templates"
|
||||
section="component"
|
||||
/>
|
||||
</fieldset>
|
||||
</config>
|
||||
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form addfieldprefix="Joomla\Component\Templates\Administrator\Field">
|
||||
<field
|
||||
name="client_id"
|
||||
type="list"
|
||||
label="JSITEADMIN"
|
||||
filtermode="selector"
|
||||
class="js-select-reset-on-change"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JSITE</option>
|
||||
<option value="1">JADMINISTRATOR</option>
|
||||
</field>
|
||||
<fields name="filter">
|
||||
<field
|
||||
name="search"
|
||||
type="text"
|
||||
inputmode="search"
|
||||
label="JSEARCH_FILTER"
|
||||
description="COM_TEMPLATES_STYLES_FILTER_SEARCH_DESC"
|
||||
hint="JSEARCH_FILTER"
|
||||
noresults="COM_TEMPLATES_MSG_MANAGE_NO_STYLES"
|
||||
/>
|
||||
<field
|
||||
name="menuitem"
|
||||
type="menuitem"
|
||||
label="COM_TEMPLATES_OPTION_SELECT_MENU_ITEM"
|
||||
disable="separator,alias,heading,url"
|
||||
showon="client_id:0"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">COM_TEMPLATES_OPTION_SELECT_MENU_ITEM</option>
|
||||
<option value="-1">COM_TEMPLATES_OPTION_NONE</option>
|
||||
</field>
|
||||
<field
|
||||
name="template"
|
||||
type="templatename"
|
||||
label="JOPTION_SELECT_TEMPLATE"
|
||||
class="js-select-submit-on-change"
|
||||
>
|
||||
<option value="">JOPTION_SELECT_TEMPLATE</option>
|
||||
</field>
|
||||
</fields>
|
||||
<fields name="list">
|
||||
<field
|
||||
name="fullordering"
|
||||
type="list"
|
||||
label="JGLOBAL_SORT_BY"
|
||||
class="js-select-submit-on-change"
|
||||
default="a.template ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_SORT_BY</option>
|
||||
<option value="a.title ASC">COM_TEMPLATES_HEADING_STYLE_ASC</option>
|
||||
<option value="a.title DESC">COM_TEMPLATES_HEADING_STYLE_DESC</option>
|
||||
<option value="a.home ASC">COM_TEMPLATES_HEADING_DEFAULT_ASC</option>
|
||||
<option value="a.home DESC">COM_TEMPLATES_HEADING_DEFAULT_DESC</option>
|
||||
<option value="a.template ASC">COM_TEMPLATES_HEADING_TEMPLATE_ASC</option>
|
||||
<option value="a.template DESC">COM_TEMPLATES_HEADING_TEMPLATE_DESC</option>
|
||||
<option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
|
||||
<option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
|
||||
</field>
|
||||
<field
|
||||
name="limit"
|
||||
type="limitbox"
|
||||
label="JGLOBAL_LIST_LIMIT"
|
||||
default="25"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fields>
|
||||
</form>
|
||||
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<field
|
||||
name="client_id"
|
||||
type="list"
|
||||
label="JSITEADMIN"
|
||||
filtermode="selector"
|
||||
class="js-select-reset-on-change"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JSITE</option>
|
||||
<option value="1">JADMINISTRATOR</option>
|
||||
</field>
|
||||
<fields name="filter">
|
||||
<field
|
||||
name="search"
|
||||
type="text"
|
||||
inputmode="search"
|
||||
label="JSEARCH_FILTER"
|
||||
description="COM_TEMPLATES_TEMPLATES_FILTER_SEARCH_DESC"
|
||||
hint="JSEARCH_FILTER"
|
||||
noresults="COM_TEMPLATES_MSG_MANAGE_NO_TEMPLATES"
|
||||
/>
|
||||
</fields>
|
||||
<fields name="list">
|
||||
<field
|
||||
name="fullordering"
|
||||
type="list"
|
||||
label="JGLOBAL_SORT_BY"
|
||||
class="js-select-submit-on-change"
|
||||
default="a.element ASC"
|
||||
validate="options"
|
||||
>
|
||||
<option value="">JGLOBAL_SORT_BY</option>
|
||||
<option value="a.element ASC">COM_TEMPLATES_HEADING_TEMPLATE_ASC</option>
|
||||
<option value="a.element DESC">COM_TEMPLATES_HEADING_TEMPLATE_DESC</option>
|
||||
</field>
|
||||
<field
|
||||
name="limit"
|
||||
type="limitbox"
|
||||
label="JGLOBAL_LIST_LIMIT"
|
||||
default="25"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
</fields>
|
||||
</form>
|
||||
61
administrator/components/com_templates/forms/source.xml
Normal file
61
administrator/components/com_templates/forms/source.xml
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset>
|
||||
<field
|
||||
name="extension_id"
|
||||
type="hidden"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="filename"
|
||||
type="hidden"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="source"
|
||||
type="editor"
|
||||
label="COM_TEMPLATES_FIELD_SOURCE_LABEL"
|
||||
editor="codemirror|none"
|
||||
buttons="no"
|
||||
rows="40"
|
||||
cols="80"
|
||||
syntax="php"
|
||||
filter="raw"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="core"
|
||||
type="editor"
|
||||
label="COM_TEMPLATES_FIELD_SOURCE_LABEL"
|
||||
editor="codemirror|none"
|
||||
buttons="no"
|
||||
rows="40"
|
||||
cols="80"
|
||||
syntax="php"
|
||||
filter="raw"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="show_core"
|
||||
type="radio"
|
||||
label="COM_TEMPLATES_LAYOUTS_DIFFVIEW_CORE"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
|
||||
<field
|
||||
name="show_diff"
|
||||
type="radio"
|
||||
label="COM_TEMPLATES_LAYOUTS_DIFFVIEW_DIFF"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</form>
|
||||
54
administrator/components/com_templates/forms/style.xml
Normal file
54
administrator/components/com_templates/forms/style.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset>
|
||||
<field
|
||||
name="id"
|
||||
type="number"
|
||||
label="JGLOBAL_FIELD_ID_LABEL"
|
||||
default="0"
|
||||
readonly="true"
|
||||
class="readonly"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="template"
|
||||
type="text"
|
||||
label="COM_TEMPLATES_FIELD_TEMPLATE_LABEL"
|
||||
class="readonly"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="client_id"
|
||||
type="hidden"
|
||||
label="COM_TEMPLATES_FIELD_CLIENT_LABEL"
|
||||
class="readonly"
|
||||
default="0"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="title"
|
||||
type="text"
|
||||
label="COM_TEMPLATES_FIELD_TITLE_LABEL"
|
||||
required="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="assigned"
|
||||
type="hidden"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="inheritable"
|
||||
type="hidden"
|
||||
readonly="true"
|
||||
/>
|
||||
|
||||
<field
|
||||
name="parent"
|
||||
type="hidden"
|
||||
readonly="true"
|
||||
/>
|
||||
</fieldset>
|
||||
</form>
|
||||
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset>
|
||||
<field
|
||||
name="home"
|
||||
type="radio"
|
||||
label="COM_TEMPLATES_FIELD_HOME_LABEL"
|
||||
layout="joomla.form.field.radio.switcher"
|
||||
default="0"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JYES</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</form>
|
||||
15
administrator/components/com_templates/forms/style_site.xml
Normal file
15
administrator/components/com_templates/forms/style_site.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form>
|
||||
<fieldset>
|
||||
<field
|
||||
name="home"
|
||||
type="contentlanguage"
|
||||
label="COM_TEMPLATES_FIELD_HOME_LABEL"
|
||||
default="0"
|
||||
validate="options"
|
||||
>
|
||||
<option value="0">JNO</option>
|
||||
<option value="1">JALL</option>
|
||||
</field>
|
||||
</fieldset>
|
||||
</form>
|
||||
27
administrator/components/com_templates/helpers/template.php
Normal file
27
administrator/components/com_templates/helpers/template.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
|
||||
*/
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template Helper class.
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
* Use \Joomla\Component\Templates\Administrator\Helper\TemplateHelper instead
|
||||
*/
|
||||
abstract class TemplateHelper extends \Joomla\Component\Templates\Administrator\Helper\TemplateHelper
|
||||
{
|
||||
}
|
||||
27
administrator/components/com_templates/helpers/templates.php
Normal file
27
administrator/components/com_templates/helpers/templates.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
|
||||
*/
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Templates component helper.
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
* Use \Joomla\Component\Templates\Administrator\Helper\TemplatesHelper instead
|
||||
*/
|
||||
class TemplatesHelper extends \Joomla\Component\Templates\Administrator\Helper\TemplatesHelper
|
||||
{
|
||||
}
|
||||
55
administrator/components/com_templates/services/provider.php
Normal file
55
administrator/components/com_templates/services/provider.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
|
||||
use Joomla\CMS\Extension\ComponentInterface;
|
||||
use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
|
||||
use Joomla\CMS\Extension\Service\Provider\MVCFactory;
|
||||
use Joomla\CMS\HTML\Registry;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\Component\Templates\Administrator\Extension\TemplatesComponent;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
/**
|
||||
* The templates service provider.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Registers the service provider with a DI container.
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container->registerServiceProvider(new MVCFactory('\\Joomla\\Component\\Templates'));
|
||||
$container->registerServiceProvider(new ComponentDispatcherFactory('\\Joomla\\Component\\Templates'));
|
||||
|
||||
$container->set(
|
||||
ComponentInterface::class,
|
||||
function (Container $container) {
|
||||
$component = new TemplatesComponent($container->get(ComponentDispatcherFactoryInterface::class));
|
||||
|
||||
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
|
||||
$component->setRegistry($container->get(Registry::class));
|
||||
|
||||
return $component;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Templates manager display controller.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
/**
|
||||
* @var string The default view.
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $default_view = 'styles';
|
||||
|
||||
/**
|
||||
* Method to display a view.
|
||||
*
|
||||
* @param boolean $cachable If true, the view output will be cached
|
||||
* @param boolean $urlparams An array of safe URL parameters and their variable types.
|
||||
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
|
||||
*
|
||||
* @return static|boolean This object to support chaining or false on failure.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public function display($cachable = false, $urlparams = false)
|
||||
{
|
||||
$view = $this->input->get('view', 'styles');
|
||||
$layout = $this->input->get('layout', 'default');
|
||||
$id = $this->input->getInt('id');
|
||||
|
||||
// For JSON requests
|
||||
if ($this->app->getDocument()->getType() == 'json') {
|
||||
return parent::display();
|
||||
}
|
||||
|
||||
// Check for edit form.
|
||||
if ($view == 'style' && $layout == 'edit' && !$this->checkEditId('com_templates.edit.style', $id)) {
|
||||
// Somehow the person just went to the form - we don't allow that.
|
||||
if (!\count($this->app->getMessageQueue())) {
|
||||
$this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
|
||||
}
|
||||
|
||||
$this->setRedirect(Route::_('index.php?option=com_templates&view=styles', false));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::display();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\FormController;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template style controller class.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class StyleController extends FormController
|
||||
{
|
||||
/**
|
||||
* The prefix to use with controller messages.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $text_prefix = 'COM_TEMPLATES_STYLE';
|
||||
|
||||
/**
|
||||
* Method to save a template style.
|
||||
*
|
||||
* @param string $key The name of the primary key of the URL variable.
|
||||
* @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions).
|
||||
*
|
||||
* @return boolean True if successful, false otherwise.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function save($key = null, $urlVar = null)
|
||||
{
|
||||
$this->checkToken();
|
||||
|
||||
if ($this->app->getDocument()->getType() === 'json') {
|
||||
$model = $this->getModel('Style', 'Administrator');
|
||||
$table = $model->getTable();
|
||||
$data = $this->input->post->get('params', [], 'array');
|
||||
$checkin = $table->hasField('checked_out');
|
||||
$context = $this->option . '.edit.' . $this->context;
|
||||
|
||||
$item = $model->getItem($this->app->getTemplate(true)->id);
|
||||
|
||||
// Setting received params
|
||||
$item->set('params', $data);
|
||||
|
||||
$data = $item->getProperties();
|
||||
unset($data['xml']);
|
||||
|
||||
$key = $table->getKeyName();
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowSave($data, $key)) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Form::addFormPath(JPATH_ADMINISTRATOR . '/components/com_templates/forms');
|
||||
|
||||
// Validate the posted data.
|
||||
// Sometimes the form needs some posted data, such as for plugins and modules.
|
||||
$form = $model->getForm($data, false);
|
||||
|
||||
if (!$form) {
|
||||
$this->app->enqueueMessage($model->getError(), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test whether the data is valid.
|
||||
$validData = $model->validate($form, $data);
|
||||
|
||||
if ($validData === false) {
|
||||
// Get the validation messages.
|
||||
$errors = $model->getErrors();
|
||||
|
||||
// Push up to three validation messages out to the user.
|
||||
for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) {
|
||||
if ($errors[$i] instanceof \Exception) {
|
||||
$this->app->enqueueMessage($errors[$i]->getMessage(), 'warning');
|
||||
} else {
|
||||
$this->app->enqueueMessage($errors[$i], 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
// Save the data in the session.
|
||||
$this->app->setUserState($context . '.data', $data);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($validData['tags'])) {
|
||||
$validData['tags'] = null;
|
||||
}
|
||||
|
||||
// Attempt to save the data.
|
||||
if (!$model->save($validData)) {
|
||||
// Save the data in the session.
|
||||
$this->app->setUserState($context . '.data', $validData);
|
||||
|
||||
$this->app->enqueueMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save succeeded, so check-in the record.
|
||||
if ($checkin && $model->checkin($validData[$key]) === false) {
|
||||
// Save the data in the session.
|
||||
$this->app->setUserState($context . '.data', $validData);
|
||||
|
||||
// Check-in failed, so go back to the record and display a notice.
|
||||
$this->app->enqueueMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Redirect the user and adjust session state
|
||||
// Set the record data in the session.
|
||||
$recordId = $model->getState($this->context . '.id');
|
||||
$this->holdEditId($context, $recordId);
|
||||
$this->app->setUserState($context . '.data', null);
|
||||
$model->checkout($recordId);
|
||||
|
||||
// Invoke the postSave method to allow for the child class to access the model.
|
||||
$this->postSaveHook($model, $validData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::save($key, $urlVar);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\AdminController;
|
||||
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template styles list controller class.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class StylesController extends AdminController
|
||||
{
|
||||
/**
|
||||
* Method to clone and existing template style.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function duplicate()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
$pks = (array) $this->input->post->get('cid', [], 'int');
|
||||
|
||||
// Remove zero values resulting from input filter
|
||||
$pks = array_filter($pks);
|
||||
|
||||
try {
|
||||
if (empty($pks)) {
|
||||
throw new \Exception(Text::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED'));
|
||||
}
|
||||
|
||||
$model = $this->getModel();
|
||||
$model->duplicate($pks);
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_SUCCESS_DUPLICATED'));
|
||||
} catch (\Exception $e) {
|
||||
$this->app->enqueueMessage($e->getMessage(), 'error');
|
||||
}
|
||||
|
||||
$this->setRedirect('index.php?option=com_templates&view=styles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for getModel.
|
||||
*
|
||||
* @param string $name The model name. Optional.
|
||||
* @param string $prefix The class prefix. Optional.
|
||||
* @param array $config Configuration array for model. Optional.
|
||||
*
|
||||
* @return BaseDatabaseModel
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getModel($name = 'Style', $prefix = 'Administrator', $config = [])
|
||||
{
|
||||
return parent::getModel($name, $prefix, ['ignore_request' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set the home template for a client.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function setDefault()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
$pks = (array) $this->input->post->get('cid', [], 'int');
|
||||
|
||||
// Remove zero values resulting from input filter
|
||||
$pks = array_filter($pks);
|
||||
|
||||
try {
|
||||
if (empty($pks)) {
|
||||
throw new \Exception(Text::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED'));
|
||||
}
|
||||
|
||||
// Pop off the first element.
|
||||
$id = array_shift($pks);
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\StyleModel $model */
|
||||
$model = $this->getModel();
|
||||
$model->setHome($id);
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_SUCCESS_HOME_SET'));
|
||||
} catch (\Exception $e) {
|
||||
$this->setMessage($e->getMessage(), 'warning');
|
||||
}
|
||||
|
||||
$this->setRedirect('index.php?option=com_templates&view=styles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to unset the default template for a client and for a language
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function unsetDefault()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken('request');
|
||||
|
||||
$pks = (array) $this->input->get->get('cid', [], 'int');
|
||||
|
||||
// Remove zero values resulting from input filter
|
||||
$pks = array_filter($pks);
|
||||
|
||||
try {
|
||||
if (empty($pks)) {
|
||||
throw new \Exception(Text::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED'));
|
||||
}
|
||||
|
||||
// Pop off the first element.
|
||||
$id = array_shift($pks);
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\StyleModel $model */
|
||||
$model = $this->getModel();
|
||||
$model->unsetHome($id);
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_SUCCESS_HOME_UNSET'));
|
||||
} catch (\Exception $e) {
|
||||
$this->setMessage($e->getMessage(), 'warning');
|
||||
}
|
||||
|
||||
$this->setRedirect('index.php?option=com_templates&view=styles');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,999 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Controller;
|
||||
|
||||
use Joomla\CMS\Application\CMSApplication;
|
||||
use Joomla\CMS\Filter\InputFilter;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\Filesystem\Path;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template style controller class.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class TemplateController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
* @param CMSApplication $app The Application for the dispatcher
|
||||
* @param Input $input Input
|
||||
*
|
||||
* @since 1.6
|
||||
* @see BaseController
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null, $app = null, $input = null)
|
||||
{
|
||||
parent::__construct($config, $factory, $app, $input);
|
||||
|
||||
$this->registerTask('apply', 'save');
|
||||
$this->registerTask('unpublish', 'publish');
|
||||
$this->registerTask('publish', 'publish');
|
||||
$this->registerTask('deleteOverrideHistory', 'publish');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for closing the template.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
$this->setRedirect(Route::_('index.php?option=com_templates&view=templates', false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for closing a file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$file = base64_encode('home');
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' .
|
||||
$file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Marked as Checked/Unchecked of override history.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function publish()
|
||||
{
|
||||
// Check for request forgeries.
|
||||
$this->checkToken();
|
||||
|
||||
$file = $this->input->get('file');
|
||||
$id = $this->input->get('id');
|
||||
|
||||
$ids = (array) $this->input->get('cid', [], 'string');
|
||||
$values = ['publish' => 1, 'unpublish' => 0, 'deleteOverrideHistory' => -3];
|
||||
$task = $this->getTask();
|
||||
$value = ArrayHelper::getValue($values, $task, 0, 'int');
|
||||
|
||||
if (empty($ids)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_NO_FILE_SELECTED'), 'warning');
|
||||
} else {
|
||||
/* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
|
||||
// Change the state of the records.
|
||||
if (!$model->publish($ids, $value, $id)) {
|
||||
$this->setMessage(implode('<br>', $model->getErrors()), 'warning');
|
||||
} else {
|
||||
if ($value === 1) {
|
||||
$ntext = 'COM_TEMPLATES_N_OVERRIDE_CHECKED';
|
||||
} elseif ($value === 0) {
|
||||
$ntext = 'COM_TEMPLATES_N_OVERRIDE_UNCHECKED';
|
||||
} elseif ($value === -3) {
|
||||
$ntext = 'COM_TEMPLATES_N_OVERRIDE_DELETED';
|
||||
}
|
||||
|
||||
$this->setMessage(Text::plural($ntext, \count($ids)));
|
||||
}
|
||||
}
|
||||
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' .
|
||||
$file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for copying the template.
|
||||
*
|
||||
* @return boolean true on success, false otherwise
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function copy()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
$app = $this->app;
|
||||
$this->input->set('installtype', 'folder');
|
||||
$newNameRaw = $this->input->get('new_name', null, 'string');
|
||||
// Only accept letters, numbers and underscore for template name
|
||||
$newName = preg_replace('/[^a-zA-Z0-9_]/', '', $newNameRaw);
|
||||
$templateID = (int) $this->input->getInt('id', 0);
|
||||
$file = (string) $this->input->get('file', '', 'cmd');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file);
|
||||
|
||||
/* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel('Template', 'Administrator');
|
||||
$model->setState('new_name', $newName);
|
||||
$model->setState('tmp_prefix', uniqid('template_copy_'));
|
||||
$model->setState('to_path', $app->get('tmp_path') . '/' . $model->getState('tmp_prefix'));
|
||||
|
||||
// Process only if we have a new name entered
|
||||
if (\strlen($newName) > 0) {
|
||||
if (!$this->app->getIdentity()->authorise('core.create', 'com_templates')) {
|
||||
// User is not authorised to delete
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that new name is valid
|
||||
if (($newNameRaw !== null) && ($newName !== $newNameRaw)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that new name doesn't already exist
|
||||
if (!$model->checkNewName()) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that from name does exist and get the folder name
|
||||
$fromName = $model->getFromName();
|
||||
|
||||
if (!$fromName) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call model's copy method
|
||||
if (!$model->copy()) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call installation model
|
||||
$this->input->set('install_directory', $app->get('tmp_path') . '/' . $model->getState('tmp_prefix'));
|
||||
|
||||
/** @var \Joomla\Component\Installer\Administrator\Model\InstallModel $installModel */
|
||||
$installModel = $this->app->bootComponent('com_installer')
|
||||
->getMVCFactory()->createModel('Install', 'Administrator');
|
||||
$this->app->getLanguage()->load('com_installer');
|
||||
|
||||
if (!$installModel->install()) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setMessage(Text::sprintf('COM_TEMPLATES_COPY_SUCCESS', $newName));
|
||||
$model->cleanup();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->setMessage(Text::sprintf('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a model object, loading it if required.
|
||||
*
|
||||
* @param string $name The model name. Optional.
|
||||
* @param string $prefix The class prefix. Optional.
|
||||
* @param array $config Configuration array for model. Optional (note, the empty array is atypical compared to other models).
|
||||
*
|
||||
* @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function getModel($name = 'Template', $prefix = 'Administrator', $config = [])
|
||||
{
|
||||
return parent::getModel($name, $prefix, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check if you can add a new record.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
protected function allowEdit()
|
||||
{
|
||||
return $this->app->getIdentity()->authorise('core.admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a template source file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
// Check for request forgeries.
|
||||
$this->checkToken();
|
||||
|
||||
$data = $this->input->post->get('jform', [], 'array');
|
||||
$task = $this->getTask();
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$fileName = (string) $this->input->getCmd('file', '');
|
||||
$explodeArray = explode(':', str_replace('//', '/', base64_decode($fileName)));
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Match the stored id's with the submitted.
|
||||
if (empty($data['extension_id']) || empty($data['filename'])) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($data['extension_id'] != $model->getState('extension.id')) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error');
|
||||
|
||||
return;
|
||||
} elseif (str_ends_with(end($explodeArray), Path::clean($data['filename'], '/'))) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the posted data.
|
||||
$form = $model->getForm();
|
||||
|
||||
if (!$form) {
|
||||
$this->setMessage($model->getError(), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $model->validate($form, $data);
|
||||
|
||||
// Check for validation errors.
|
||||
if ($data === false) {
|
||||
// Get the validation messages.
|
||||
$errors = $model->getErrors();
|
||||
|
||||
// Push up to three validation messages out to the user.
|
||||
for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) {
|
||||
if ($errors[$i] instanceof \Exception) {
|
||||
$this->app->enqueueMessage($errors[$i]->getMessage(), 'warning');
|
||||
} else {
|
||||
$this->app->enqueueMessage($errors[$i], 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect back to the edit screen.
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt to save the data.
|
||||
if (!$model->save($data)) {
|
||||
// Redirect back to the edit screen.
|
||||
$this->setMessage(Text::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_SAVE_SUCCESS'));
|
||||
|
||||
// Redirect the user based on the chosen task.
|
||||
switch ($task) {
|
||||
case 'apply':
|
||||
// Redirect back to the edit screen.
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Redirect to the list screen.
|
||||
$file = base64_encode('home');
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for creating override.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function overrides()
|
||||
{
|
||||
// Check for request forgeries.
|
||||
$this->checkToken('get');
|
||||
|
||||
/* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
$override = (string) InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilter::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
)
|
||||
->clean(base64_decode($this->input->getBase64('folder', '')), 'path');
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$model->createOverride($override);
|
||||
|
||||
// Redirect back to the edit screen.
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for deleting a file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
/* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (base64_decode(urldecode($file)) == '/index.php') {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_INDEX_DELETE'), 'warning');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif (base64_decode(urldecode($file)) == '/joomla.asset.json') {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_ASSET_FILE_DELETE'), 'warning');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif ($model->deleteFile($file)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_DELETE_SUCCESS'));
|
||||
$file = base64_encode('home');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_DELETE'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for creating a new file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function createFile()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
/* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->get('file', '', 'cmd');
|
||||
$name = (string) $this->input->get('name', '', 'cmd');
|
||||
$location = (string) InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilter::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
)
|
||||
->clean(base64_decode($this->input->getBase64('address', '')), 'path');
|
||||
$type = (string) $this->input->get('type', '', 'cmd');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type == 'null') {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_TYPE'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif (!preg_match('/^(?!\.)(?!.*\.$)(?!.*\.\.)[a-zA-Z0-9_.-]+$/', $name)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif ($model->createFile($name, $type, $location)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_CREATE_SUCCESS'));
|
||||
$file = urlencode(base64_encode($location . '/' . $name . '.' . $type));
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_CREATE'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for uploading a file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function uploadFile()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
/* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
$upload = $this->input->files->get('files');
|
||||
$location = (string) InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilter::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
)
|
||||
->clean(base64_decode($this->input->getBase64('address', '')), 'path');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($return = $model->uploadFile($upload, $location)) {
|
||||
$this->setMessage(Text::sprintf('COM_TEMPLATES_FILE_UPLOAD_SUCCESS', $upload['name']));
|
||||
$redirect = base64_encode($return);
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $redirect . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_UPLOAD'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for creating a new folder.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function createFolder()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
$name = $this->input->get('name');
|
||||
$location = (string) InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilter::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
)
|
||||
->clean(base64_decode($this->input->getBase64('address', '')), 'path');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $name)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FOLDER_NAME'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif ($model->createFolder($name, $location)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FOLDER_CREATE_SUCCESS'));
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_FOLDER_CREATE'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for deleting a folder.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function deleteFolder()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$isMedia = (int) $this->input->get('isMedia', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
$location = (string) InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilter::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
)
|
||||
->clean(base64_decode($this->input->getBase64('address', '')), 'path');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($location)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_ROOT_DELETE'), 'warning');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif ($model->deleteFolder($location)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FOLDER_DELETE_SUCCESS'));
|
||||
|
||||
if (stristr(base64_decode($file), $location) != false) {
|
||||
$file = base64_encode('home');
|
||||
}
|
||||
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FOLDER_DELETE_ERROR'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for renaming a file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function renameFile()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$isMedia = (int) $this->input->get('isMedia', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
$newName = $this->input->get('new_name');
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (base64_decode(urldecode($file)) == '/index.php') {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_RENAME_INDEX'), 'warning');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif (base64_decode(urldecode($file)) == '/joomla.asset.json') {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_RENAME_ASSET_FILE'), 'warning');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif (!preg_match('/^(?!\.)(?!.*\.$)(?!.*\.\.)[a-zA-Z0-9_.-]+$/', $newName)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif ($rename = $model->renameFile($file, $newName)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_RENAME_SUCCESS'));
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $rename . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_RENAME'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $isMedia;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for cropping an image.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function cropImage()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->get('file', '', 'cmd');
|
||||
$x = $this->input->get('x');
|
||||
$y = $this->input->get('y');
|
||||
$w = $this->input->get('w');
|
||||
$h = $this->input->get('h');
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($w) && empty($h) && empty($x) && empty($y)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_CROP_AREA_ERROR'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif ($model->cropImage($file, $w, $h, $x, $y)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_CROP_SUCCESS'));
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_CROP_ERROR'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for resizing an image.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function resizeImage()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
$width = $this->input->get('width');
|
||||
$height = $this->input->get('height');
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($model->resizeImage($file, $width, $height)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_RESIZE_SUCCESS'));
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_RESIZE_ERROR'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for copying a file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function copyFile()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
$newName = $this->input->get('new_name');
|
||||
$location = (string) InputFilter::getInstance(
|
||||
[],
|
||||
[],
|
||||
InputFilter::ONLY_BLOCK_DEFINED_TAGS,
|
||||
InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES
|
||||
)
|
||||
->clean(base64_decode($this->input->getBase64('address', '')), 'path');
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} elseif ($model->copyFile($newName, $location, $file)) {
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_COPY_FAIL'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file . '&isMedia=' . $this->input->getInt('isMedia', 0);
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for extracting an archive file.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public function extractArchive()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
$id = (int) $this->input->get('id', 0, 'int');
|
||||
$file = (string) $this->input->getCmd('file', '');
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($model->extractArchive($file)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_SUCCESS'));
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
} else {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_FAIL'), 'error');
|
||||
$url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file;
|
||||
$this->setRedirect(Route::_($url, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and report updates in \JSON format, for AJAX requests
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function ajax()
|
||||
{
|
||||
$app = $this->app;
|
||||
|
||||
if (!Session::checkToken('get')) {
|
||||
$app->setHeader('status', 403, true);
|
||||
$app->sendHeaders();
|
||||
echo Text::_('JINVALID_TOKEN_NOTICE');
|
||||
$app->close();
|
||||
}
|
||||
|
||||
// Checks status of installer override plugin.
|
||||
if (!PluginHelper::isEnabled('installer', 'override')) {
|
||||
$error = ['installerOverride' => 'disabled'];
|
||||
|
||||
echo json_encode($error);
|
||||
|
||||
$app->close();
|
||||
}
|
||||
|
||||
/** @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel();
|
||||
|
||||
$result = $model->getUpdatedList(true, true);
|
||||
|
||||
echo json_encode($result);
|
||||
|
||||
$app->close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method for creating a child template.
|
||||
*
|
||||
* @return boolean true on success, false otherwise
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
public function child()
|
||||
{
|
||||
// Check for request forgeries
|
||||
$this->checkToken();
|
||||
|
||||
// Access check.
|
||||
if (!$this->allowEdit()) {
|
||||
$this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->input->set('installtype', 'folder');
|
||||
$newNameRaw = $this->input->get('new_name', null, 'string');
|
||||
|
||||
// Only accept letters, numbers and underscore for template name
|
||||
$newName = preg_replace('/[^a-zA-Z0-9_]/', '', $newNameRaw);
|
||||
$templateID = (int) $this->input->getInt('id', 0);
|
||||
$file = (string) $this->input->get('file', '', 'cmd');
|
||||
$extraStyles = (array) $this->input->get('style_ids', [], 'array');
|
||||
|
||||
$this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file);
|
||||
|
||||
/* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */
|
||||
$model = $this->getModel('Template', 'Administrator');
|
||||
$model->setState('new_name', $newName);
|
||||
$model->setState('tmp_prefix', uniqid('template_child_'));
|
||||
$model->setState('to_path', $this->app->get('tmp_path') . '/' . $model->getState('tmp_prefix'));
|
||||
|
||||
// Process only if we have a new name entered
|
||||
if (!\strlen($newName)) {
|
||||
$this->setMessage(Text::sprintf('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Process only if user is allowed to create child template
|
||||
if (!$this->app->getIdentity()->authorise('core.create', 'com_templates')) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that new name is valid
|
||||
if (($newNameRaw !== null) && ($newName !== $newNameRaw)) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that new name doesn't already exist
|
||||
if (!$model->checkNewName()) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that from name does exist and get the folder name
|
||||
$fromName = $model->getFromName();
|
||||
|
||||
if (!$fromName) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call model's copy method
|
||||
if (!$model->child()) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call installation model
|
||||
$this->input->set('install_directory', $this->app->get('tmp_path') . '/' . $model->getState('tmp_prefix'));
|
||||
|
||||
/** @var \Joomla\Component\Installer\Administrator\Model\InstallModel $installModel */
|
||||
$installModel = $this->app->bootComponent('com_installer')
|
||||
->getMVCFactory()->createModel('Install', 'Administrator');
|
||||
$this->app->getLanguage()->load('com_installer');
|
||||
|
||||
if (!$installModel->install()) {
|
||||
$this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setMessage(Text::sprintf('COM_TEMPLATES_CHILD_SUCCESS', $newName));
|
||||
$model->cleanup();
|
||||
|
||||
if (\count($extraStyles) > 0) {
|
||||
$model->setState('stylesToCopy', $extraStyles);
|
||||
$model->copyStyles();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Extension;
|
||||
|
||||
use Joomla\CMS\Extension\BootableExtensionInterface;
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
use Joomla\CMS\HTML\HTMLRegistryAwareTrait;
|
||||
use Joomla\Component\Templates\Administrator\Service\HTML\Templates;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Component class for com_templates
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class TemplatesComponent extends MVCComponent implements BootableExtensionInterface
|
||||
{
|
||||
use HTMLRegistryAwareTrait;
|
||||
|
||||
/**
|
||||
* Booting the extension. This is the function to set up the environment of the extension like
|
||||
* registering new class loaders, etc.
|
||||
*
|
||||
* If required, some initial set up can be done from services of the container, eg.
|
||||
* registering HTML services.
|
||||
*
|
||||
* @param ContainerInterface $container The container
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function boot(ContainerInterface $container)
|
||||
{
|
||||
$this->getRegistry()->register('templates', new Templates());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2015 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
use Joomla\Component\Templates\Administrator\Helper\TemplatesHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template Location field.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
class TemplatelocationField extends ListField
|
||||
{
|
||||
/**
|
||||
* The form field type.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.5
|
||||
*/
|
||||
protected $type = 'TemplateLocation';
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
$options = TemplatesHelper::getClientOptions();
|
||||
|
||||
return array_merge(parent::getOptions(), $options);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2015 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Field;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Field\ListField;
|
||||
use Joomla\Component\Templates\Administrator\Helper\TemplatesHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template Name field.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
class TemplatenameField extends ListField
|
||||
{
|
||||
/**
|
||||
* The form field type.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.5
|
||||
*/
|
||||
protected $type = 'TemplateName';
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
// Get the client_id filter from the user state.
|
||||
$clientId = Factory::getApplication()->getUserStateFromRequest('com_templates.styles.client_id', 'client_id', '0', 'string');
|
||||
|
||||
// Get the templates for the selected client_id.
|
||||
$options = TemplatesHelper::getTemplateOptions($clientId);
|
||||
|
||||
// Merge into the parent options.
|
||||
return array_merge(parent::getOptions(), $options);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Helper;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Filesystem\File;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template Helper class.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
abstract class TemplateHelper
|
||||
{
|
||||
/**
|
||||
* Checks if the file is an image
|
||||
*
|
||||
* @param string $fileName The filename
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function getTypeIcon($fileName)
|
||||
{
|
||||
// Get file extension
|
||||
return strtolower(substr($fileName, strrpos($fileName, '.') + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the file can be uploaded
|
||||
*
|
||||
* @param array $file File information
|
||||
* @param string $err An error message to be returned
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public static function canUpload($file, $err = '')
|
||||
{
|
||||
$params = ComponentHelper::getParams('com_templates');
|
||||
|
||||
if (empty($file['name'])) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_UPLOAD_INPUT'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Media file names should never have executable extensions buried in them.
|
||||
$executable = [
|
||||
'exe', 'phtml','java', 'perl', 'py', 'asp','dll', 'go', 'jar',
|
||||
'ade', 'adp', 'bat', 'chm', 'cmd', 'com', 'cpl', 'hta', 'ins', 'isp',
|
||||
'jse', 'lib', 'mde', 'msc', 'msp', 'mst', 'pif', 'scr', 'sct', 'shb',
|
||||
'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh',
|
||||
];
|
||||
$explodedFileName = explode('.', $file['name']);
|
||||
|
||||
if (\count($explodedFileName) > 2) {
|
||||
foreach ($executable as $extensionName) {
|
||||
if (\in_array($extensionName, $explodedFileName)) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_EXECUTABLE'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($file['name'] !== File::makeSafe($file['name']) || preg_match('/\s/', File::makeSafe($file['name']))) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNFILENAME'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$format = strtolower(File::getExt($file['name']));
|
||||
|
||||
$imageTypes = explode(',', $params->get('image_formats', 'gif,bmp,jpg,jpeg,png,webp'));
|
||||
$sourceTypes = explode(',', $params->get('source_formats', 'txt,less,ini,xml,js,php,css,scss,sass,json'));
|
||||
$fontTypes = explode(',', $params->get('font_formats', 'woff,woff2,ttf,otf'));
|
||||
$archiveTypes = explode(',', $params->get('compressed_formats', 'zip'));
|
||||
|
||||
$allowable = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes);
|
||||
|
||||
if ($format == '' || $format == false || (!\in_array($format, $allowable))) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNFILETYPE'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (\in_array($format, $archiveTypes)) {
|
||||
$zip = new \ZipArchive();
|
||||
|
||||
if ($zip->open($file['tmp_name']) === true) {
|
||||
for ($i = 0; $i < $zip->numFiles; $i++) {
|
||||
$entry = $zip->getNameIndex($i);
|
||||
$endString = substr($entry, -1);
|
||||
|
||||
if ($endString != DIRECTORY_SEPARATOR) {
|
||||
$explodeArray = explode('.', $entry);
|
||||
$ext = end($explodeArray);
|
||||
|
||||
if (!\in_array($ext, $allowable)) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_UNSUPPORTED_ARCHIVE'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Max upload size set to 10 MB for Template Manager
|
||||
$maxSize = (int) ($params->get('upload_limit') * 1024 * 1024);
|
||||
|
||||
if ($maxSize > 0 && (int) $file['size'] > $maxSize) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNFILETOOLARGE'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$xss_check = file_get_contents($file['tmp_name'], false, null, -1, 256);
|
||||
$html_tags = [
|
||||
'abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink', 'blockquote',
|
||||
'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del', 'dfn', 'dir', 'div',
|
||||
'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
|
||||
'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext', 'link', 'listing',
|
||||
'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object', 'ol', 'optgroup', 'option',
|
||||
'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar', 'small', 'spacer', 'span', 'strike',
|
||||
'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', 'wbr', 'xml',
|
||||
'xmp', '!DOCTYPE', '!--',
|
||||
];
|
||||
|
||||
foreach ($html_tags as $tag) {
|
||||
// A tag is '<tagname ', so we need to add < and a space or '<tagname>'
|
||||
if (stristr($xss_check, '<' . $tag . ' ') || stristr($xss_check, '<' . $tag . '>')) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNIEXSS'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Helper;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Installer\Installer;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Filesystem\Path;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Templates component helper.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class TemplatesHelper
|
||||
{
|
||||
/**
|
||||
* Get a list of filter options for the application clients.
|
||||
*
|
||||
* @return array An array of HtmlOption elements.
|
||||
*/
|
||||
public static function getClientOptions()
|
||||
{
|
||||
// Build the filter options.
|
||||
$options = [];
|
||||
$options[] = HTMLHelper::_('select.option', '0', Text::_('JSITE'));
|
||||
$options[] = HTMLHelper::_('select.option', '1', Text::_('JADMINISTRATOR'));
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of filter options for the templates with styles.
|
||||
*
|
||||
* @param mixed $clientId The CMS client id (0:site | 1:administrator) or '*' for all.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getTemplateOptions($clientId = '*')
|
||||
{
|
||||
// Build the filter options.
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select($db->quoteName('element', 'value'))
|
||||
->select($db->quoteName('name', 'text'))
|
||||
->select($db->quoteName('extension_id', 'e_id'))
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('type') . ' = ' . $db->quote('template'))
|
||||
->where($db->quoteName('enabled') . ' = 1')
|
||||
->order($db->quoteName('client_id') . ' ASC')
|
||||
->order($db->quoteName('name') . ' ASC');
|
||||
|
||||
if ($clientId != '*') {
|
||||
$clientId = (int) $clientId;
|
||||
$query->where($db->quoteName('client_id') . ' = :clientid')
|
||||
->bind(':clientid', $clientId, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
$db->setQuery($query);
|
||||
$options = $db->loadObjectList();
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $templateBaseDir
|
||||
* @param string $templateDir
|
||||
*
|
||||
* @return boolean|CMSObject
|
||||
*/
|
||||
public static function parseXMLTemplateFile($templateBaseDir, $templateDir)
|
||||
{
|
||||
$data = new CMSObject();
|
||||
|
||||
// Check of the xml file exists
|
||||
$filePath = Path::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml');
|
||||
|
||||
if (is_file($filePath)) {
|
||||
$xml = Installer::parseXMLInstallFile($filePath);
|
||||
|
||||
if ($xml['type'] != 'template') {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($xml as $key => $value) {
|
||||
$data->set($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $clientId
|
||||
* @param string $templateDir
|
||||
*
|
||||
* @return boolean|array
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getPositions($clientId, $templateDir)
|
||||
{
|
||||
$positions = [];
|
||||
|
||||
$templateBaseDir = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE;
|
||||
$filePath = Path::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml');
|
||||
|
||||
if (is_file($filePath)) {
|
||||
// Read the file to see if it's a valid component XML file
|
||||
$xml = simplexml_load_file($filePath);
|
||||
|
||||
if (!$xml) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for a valid XML root tag.
|
||||
|
||||
// Extensions use 'extension' as the root tag. Languages use 'metafile' instead
|
||||
|
||||
if ($xml->getName() != 'extension' && $xml->getName() != 'metafile') {
|
||||
unset($xml);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$positions = (array) $xml->positions;
|
||||
|
||||
if (isset($positions['position'])) {
|
||||
$positions = (array) $positions['position'];
|
||||
} else {
|
||||
$positions = [];
|
||||
}
|
||||
}
|
||||
|
||||
return $positions;
|
||||
}
|
||||
}
|
||||
794
administrator/components/com_templates/src/Model/StyleModel.php
Normal file
794
administrator/components/com_templates/src/Model/StyleModel.php
Normal file
@ -0,0 +1,794 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Multilanguage;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\AdminModel;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Filesystem\Path;
|
||||
use Joomla\Registry\Registry;
|
||||
use Joomla\String\StringHelper;
|
||||
use Joomla\Utilities\ArrayHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template style model.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class StyleModel extends AdminModel
|
||||
{
|
||||
/**
|
||||
* The help screen key for the module.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $helpKey = 'Templates:_Edit_Style';
|
||||
|
||||
/**
|
||||
* The help screen base URL for the module.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $helpURL;
|
||||
|
||||
/**
|
||||
* Item cache.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.6
|
||||
*/
|
||||
private $_cache = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
*
|
||||
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
* @since 3.2
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null)
|
||||
{
|
||||
$config = array_merge(
|
||||
[
|
||||
'event_before_delete' => 'onExtensionBeforeDelete',
|
||||
'event_after_delete' => 'onExtensionAfterDelete',
|
||||
'event_before_save' => 'onExtensionBeforeSave',
|
||||
'event_after_save' => 'onExtensionAfterSave',
|
||||
'events_map' => ['delete' => 'extension', 'save' => 'extension'],
|
||||
],
|
||||
$config
|
||||
);
|
||||
|
||||
parent::__construct($config, $factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* @note Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState()
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Load the User state.
|
||||
$pk = $app->getInput()->getInt('id');
|
||||
$this->setState('style.id', $pk);
|
||||
|
||||
// Load the parameters.
|
||||
$params = ComponentHelper::getParams('com_templates');
|
||||
$this->setState('params', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to delete rows.
|
||||
*
|
||||
* @param array &$pks An array of item ids.
|
||||
*
|
||||
* @return boolean Returns true on success, false on failure.
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete(&$pks)
|
||||
{
|
||||
$pks = (array) $pks;
|
||||
$user = $this->getCurrentUser();
|
||||
$table = $this->getTable();
|
||||
$context = $this->option . '.' . $this->name;
|
||||
|
||||
PluginHelper::importPlugin($this->events_map['delete']);
|
||||
|
||||
// Iterate the items to delete each one.
|
||||
foreach ($pks as $pk) {
|
||||
if ($table->load($pk)) {
|
||||
// Access checks.
|
||||
if (!$user->authorise('core.delete', 'com_templates')) {
|
||||
throw new \Exception(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED'));
|
||||
}
|
||||
|
||||
// You should not delete a default style
|
||||
if ($table->home != '0') {
|
||||
Factory::getApplication()->enqueueMessage(Text::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE'), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Trigger the before delete event.
|
||||
$result = Factory::getApplication()->triggerEvent($this->event_before_delete, [$context, $table]);
|
||||
|
||||
if (\in_array(false, $result, true) || !$table->delete($pk)) {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Trigger the after delete event.
|
||||
Factory::getApplication()->triggerEvent($this->event_after_delete, [$context, $table]);
|
||||
} else {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean cache
|
||||
$this->cleanCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to duplicate styles.
|
||||
*
|
||||
* @param array &$pks An array of primary key IDs.
|
||||
*
|
||||
* @return boolean True if successful.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function duplicate(&$pks)
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
// Access checks.
|
||||
if (!$user->authorise('core.create', 'com_templates')) {
|
||||
throw new \Exception(Text::_('JERROR_CORE_CREATE_NOT_PERMITTED'));
|
||||
}
|
||||
|
||||
$context = $this->option . '.' . $this->name;
|
||||
|
||||
// Include the plugins for the save events.
|
||||
PluginHelper::importPlugin($this->events_map['save']);
|
||||
|
||||
$table = $this->getTable();
|
||||
|
||||
foreach ($pks as $pk) {
|
||||
if ($table->load($pk, true)) {
|
||||
// Reset the id to create a new record.
|
||||
$table->id = 0;
|
||||
|
||||
// Reset the home (don't want dupes of that field).
|
||||
$table->home = 0;
|
||||
|
||||
// Alter the title.
|
||||
$m = null;
|
||||
$table->title = $this->generateNewTitle(null, null, $table->title);
|
||||
|
||||
if (!$table->check()) {
|
||||
throw new \Exception($table->getError());
|
||||
}
|
||||
|
||||
// Trigger the before save event.
|
||||
$result = Factory::getApplication()->triggerEvent($this->event_before_save, [$context, &$table, true]);
|
||||
|
||||
if (\in_array(false, $result, true) || !$table->store()) {
|
||||
throw new \Exception($table->getError());
|
||||
}
|
||||
|
||||
// Trigger the after save event.
|
||||
Factory::getApplication()->triggerEvent($this->event_after_save, [$context, &$table, true]);
|
||||
} else {
|
||||
throw new \Exception($table->getError());
|
||||
}
|
||||
}
|
||||
|
||||
// Clean cache
|
||||
$this->cleanCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to change the title.
|
||||
*
|
||||
* @param integer $categoryId The id of the category.
|
||||
* @param string $alias The alias.
|
||||
* @param string $title The title.
|
||||
*
|
||||
* @return string New title.
|
||||
*
|
||||
* @since 1.7.1
|
||||
*/
|
||||
protected function generateNewTitle($categoryId, $alias, $title)
|
||||
{
|
||||
// Alter the title
|
||||
$table = $this->getTable();
|
||||
|
||||
while ($table->load(['title' => $title])) {
|
||||
$title = StringHelper::increment($title);
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the record form.
|
||||
*
|
||||
* @param array $data An optional array of data for the form to interrogate.
|
||||
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
|
||||
*
|
||||
* @return Form A Form object on success, false on failure
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
// The folder and element vars are passed when saving the form.
|
||||
if (empty($data)) {
|
||||
$item = $this->getItem();
|
||||
$clientId = $item->client_id;
|
||||
$template = $item->template;
|
||||
} else {
|
||||
$clientId = ArrayHelper::getValue($data, 'client_id');
|
||||
$template = ArrayHelper::getValue($data, 'template');
|
||||
}
|
||||
|
||||
// Add the default fields directory
|
||||
$baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE;
|
||||
Form::addFieldPath($baseFolder . '/templates/' . $template . '/field');
|
||||
|
||||
// These variables are used to add data from the plugin XML files.
|
||||
$this->setState('item.client_id', $clientId);
|
||||
$this->setState('item.template', $template);
|
||||
|
||||
// Get the form.
|
||||
$form = $this->loadForm('com_templates.style', 'style', ['control' => 'jform', 'load_data' => $loadData]);
|
||||
|
||||
if (empty($form)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Modify the form based on access controls.
|
||||
if (!$this->canEditState((object) $data)) {
|
||||
// Disable fields for display.
|
||||
$form->setFieldAttribute('home', 'disabled', 'true');
|
||||
|
||||
// Disable fields while saving.
|
||||
// The controller has already verified this is a record you can edit.
|
||||
$form->setFieldAttribute('home', 'filter', 'unset');
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the data that should be injected in the form.
|
||||
*
|
||||
* @return mixed The data for the form.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function loadFormData()
|
||||
{
|
||||
// Check the session for previously entered form data.
|
||||
$data = Factory::getApplication()->getUserState('com_templates.edit.style.data', []);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
}
|
||||
|
||||
$this->preprocessData('com_templates.style', $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a single record.
|
||||
*
|
||||
* @param integer $pk The id of the primary key.
|
||||
*
|
||||
* @return mixed Object on success, false on failure.
|
||||
*/
|
||||
public function getItem($pk = null)
|
||||
{
|
||||
$pk = (!empty($pk)) ? $pk : (int) $this->getState('style.id');
|
||||
|
||||
if (!isset($this->_cache[$pk])) {
|
||||
// Get a row instance.
|
||||
$table = $this->getTable();
|
||||
|
||||
// Attempt to load the row.
|
||||
$return = $table->load($pk);
|
||||
|
||||
// Check for a table object error.
|
||||
if ($return === false && $table->getError()) {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert to the \Joomla\CMS\Object\CMSObject before adding other data.
|
||||
$properties = $table->getProperties(1);
|
||||
$this->_cache[$pk] = ArrayHelper::toObject($properties, CMSObject::class);
|
||||
|
||||
// Convert the params field to an array.
|
||||
$registry = new Registry($table->params);
|
||||
$this->_cache[$pk]->params = $registry->toArray();
|
||||
|
||||
// Get the template XML.
|
||||
$client = ApplicationHelper::getClientInfo($table->client_id);
|
||||
$path = Path::clean($client->path . '/templates/' . $table->template . '/templateDetails.xml');
|
||||
|
||||
if (file_exists($path)) {
|
||||
$this->_cache[$pk]->xml = simplexml_load_file($path);
|
||||
} else {
|
||||
$this->_cache[$pk]->xml = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_cache[$pk];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to allow derived classes to preprocess the form.
|
||||
*
|
||||
* @param Form $form A Form object.
|
||||
* @param mixed $data The data expected for the form.
|
||||
* @param string $group The name of the plugin group to import (defaults to "content").
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
* @throws \Exception if there is an error in the form event.
|
||||
*/
|
||||
protected function preprocessForm(Form $form, $data, $group = 'content')
|
||||
{
|
||||
$clientId = $this->getState('item.client_id');
|
||||
$template = $this->getState('item.template');
|
||||
$lang = Factory::getLanguage();
|
||||
$client = ApplicationHelper::getClientInfo($clientId);
|
||||
|
||||
if (!$form->loadFile('style_' . $client->name, true)) {
|
||||
throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
|
||||
}
|
||||
|
||||
$formFile = Path::clean($client->path . '/templates/' . $template . '/templateDetails.xml');
|
||||
|
||||
// Load the core and/or local language file(s).
|
||||
// Default to using parent template language constants
|
||||
$lang->load('tpl_' . $data->parent, $client->path)
|
||||
|| $lang->load('tpl_' . $data->parent, $client->path . '/templates/' . $data->parent);
|
||||
|
||||
// Apply any, optional, overrides for child template language constants
|
||||
$lang->load('tpl_' . $template, $client->path)
|
||||
|| $lang->load('tpl_' . $template, $client->path . '/templates/' . $template);
|
||||
|
||||
if (file_exists($formFile)) {
|
||||
// Get the template form.
|
||||
if (!$form->loadFile($formFile, false, '//config')) {
|
||||
throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
|
||||
}
|
||||
}
|
||||
|
||||
// Disable home field if it is default style
|
||||
|
||||
if (
|
||||
(\is_array($data) && \array_key_exists('home', $data) && $data['home'] == '1')
|
||||
|| (\is_object($data) && isset($data->home) && $data->home == '1')
|
||||
) {
|
||||
$form->setFieldAttribute('home', 'readonly', 'true');
|
||||
}
|
||||
|
||||
if ($client->name === 'site' && !Multilanguage::isEnabled()) {
|
||||
$form->setFieldAttribute('home', 'type', 'radio');
|
||||
$form->setFieldAttribute('home', 'layout', 'joomla.form.field.radio.switcher');
|
||||
}
|
||||
|
||||
// Attempt to load the xml file.
|
||||
if (!$xml = simplexml_load_file($formFile)) {
|
||||
throw new \Exception(Text::_('JERROR_LOADFILE_FAILED'));
|
||||
}
|
||||
|
||||
// Get the help data from the XML file if present.
|
||||
$help = $xml->xpath('/extension/help');
|
||||
|
||||
if (!empty($help)) {
|
||||
$helpKey = trim((string) $help[0]['key']);
|
||||
$helpURL = trim((string) $help[0]['url']);
|
||||
|
||||
$this->helpKey = $helpKey ?: $this->helpKey;
|
||||
$this->helpURL = $helpURL ?: $this->helpURL;
|
||||
}
|
||||
|
||||
// Trigger the default form events.
|
||||
parent::preprocessForm($form, $data, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to save the form data.
|
||||
*
|
||||
* @param array $data The form data.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
// Detect disabled extension
|
||||
$extension = Table::getInstance('Extension', 'Joomla\\CMS\\Table\\');
|
||||
|
||||
if ($extension->load(['enabled' => 0, 'type' => 'template', 'element' => $data['template'], 'client_id' => $data['client_id']])) {
|
||||
$this->setError(Text::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$app = Factory::getApplication();
|
||||
$table = $this->getTable();
|
||||
$pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('style.id');
|
||||
$isNew = true;
|
||||
|
||||
// Include the extension plugins for the save events.
|
||||
PluginHelper::importPlugin($this->events_map['save']);
|
||||
|
||||
// Load the row if saving an existing record.
|
||||
if ($pk > 0) {
|
||||
$table->load($pk);
|
||||
$isNew = false;
|
||||
}
|
||||
|
||||
if ($app->getInput()->get('task') == 'save2copy') {
|
||||
$data['title'] = $this->generateNewTitle(null, null, $data['title']);
|
||||
$data['home'] = 0;
|
||||
$data['assigned'] = '';
|
||||
}
|
||||
|
||||
// Bind the data.
|
||||
if (!$table->bind($data)) {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepare the row for saving
|
||||
$this->prepareTable($table);
|
||||
|
||||
// Check the data.
|
||||
if (!$table->check()) {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Trigger the before save event.
|
||||
$result = Factory::getApplication()->triggerEvent($this->event_before_save, ['com_templates.style', &$table, $isNew]);
|
||||
|
||||
// Store the data.
|
||||
if (\in_array(false, $result, true) || !$table->store()) {
|
||||
$this->setError($table->getError());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
if ($user->authorise('core.edit', 'com_menus') && $table->client_id == 0) {
|
||||
$n = 0;
|
||||
$db = $this->getDatabase();
|
||||
$user = $this->getCurrentUser();
|
||||
$tableId = (int) $table->id;
|
||||
$userId = (int) $user->id;
|
||||
|
||||
if (!empty($data['assigned']) && \is_array($data['assigned'])) {
|
||||
$data['assigned'] = ArrayHelper::toInteger($data['assigned']);
|
||||
|
||||
// Update the mapping for menu items that this style IS assigned to.
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__menu'))
|
||||
->set($db->quoteName('template_style_id') . ' = :newtsid')
|
||||
->whereIn($db->quoteName('id'), $data['assigned'])
|
||||
->where($db->quoteName('template_style_id') . ' != :tsid')
|
||||
->where('(' . $db->quoteName('checked_out') . ' IS NULL OR ' . $db->quoteName('checked_out') . ' = :userid)')
|
||||
->bind(':userid', $userId, ParameterType::INTEGER)
|
||||
->bind(':newtsid', $tableId, ParameterType::INTEGER)
|
||||
->bind(':tsid', $tableId, ParameterType::INTEGER);
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
$n += $db->getAffectedRows();
|
||||
}
|
||||
|
||||
// Remove style mappings for menu items this style is NOT assigned to.
|
||||
// If unassigned then all existing maps will be removed.
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__menu'))
|
||||
->set($db->quoteName('template_style_id') . ' = 0');
|
||||
|
||||
if (!empty($data['assigned'])) {
|
||||
$query->whereNotIn($db->quoteName('id'), $data['assigned']);
|
||||
}
|
||||
|
||||
$query->where($db->quoteName('template_style_id') . ' = :templatestyleid')
|
||||
->where('(' . $db->quoteName('checked_out') . ' IS NULL OR ' . $db->quoteName('checked_out') . ' = :userid)')
|
||||
->bind(':userid', $userId, ParameterType::INTEGER)
|
||||
->bind(':templatestyleid', $tableId, ParameterType::INTEGER);
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
$n += $db->getAffectedRows();
|
||||
|
||||
if ($n > 0) {
|
||||
$app->enqueueMessage(Text::plural('COM_TEMPLATES_MENU_CHANGED', $n));
|
||||
}
|
||||
}
|
||||
|
||||
// Clean the cache.
|
||||
$this->cleanCache();
|
||||
|
||||
// Trigger the after save event.
|
||||
Factory::getApplication()->triggerEvent($this->event_after_save, ['com_templates.style', &$table, $isNew]);
|
||||
|
||||
$this->setState('style.id', $table->id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set a template style as home.
|
||||
*
|
||||
* @param integer $id The primary key ID for the style.
|
||||
*
|
||||
* @return boolean True if successful.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setHome($id = 0)
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
$db = $this->getDatabase();
|
||||
|
||||
// Access checks.
|
||||
if (!$user->authorise('core.edit.state', 'com_templates')) {
|
||||
throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
|
||||
}
|
||||
|
||||
$style = $this->getTable();
|
||||
|
||||
if (!$style->load((int) $id)) {
|
||||
throw new \Exception(Text::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND'));
|
||||
}
|
||||
|
||||
// Detect disabled extension
|
||||
$extension = Table::getInstance('Extension', 'Joomla\\CMS\\Table\\');
|
||||
|
||||
if ($extension->load(['enabled' => 0, 'type' => 'template', 'element' => $style->template, 'client_id' => $style->client_id])) {
|
||||
throw new \Exception(Text::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE'));
|
||||
}
|
||||
|
||||
$clientId = (int) $style->client_id;
|
||||
$id = (int) $id;
|
||||
|
||||
// Reset the home fields for the client_id.
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__template_styles'))
|
||||
->set($db->quoteName('home') . ' = ' . $db->quote('0'))
|
||||
->where($db->quoteName('client_id') . ' = :clientid')
|
||||
->where($db->quoteName('home') . ' = ' . $db->quote('1'))
|
||||
->bind(':clientid', $clientId, ParameterType::INTEGER);
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
// Set the new home style.
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__template_styles'))
|
||||
->set($db->quoteName('home') . ' = ' . $db->quote('1'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
// Clean the cache.
|
||||
$this->cleanCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to unset a template style as default for a language.
|
||||
*
|
||||
* @param integer $id The primary key ID for the style.
|
||||
*
|
||||
* @return boolean True if successful.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function unsetHome($id = 0)
|
||||
{
|
||||
$user = $this->getCurrentUser();
|
||||
$db = $this->getDatabase();
|
||||
|
||||
// Access checks.
|
||||
if (!$user->authorise('core.edit.state', 'com_templates')) {
|
||||
throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
|
||||
}
|
||||
|
||||
$id = (int) $id;
|
||||
|
||||
// Lookup the client_id.
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['client_id', 'home']))
|
||||
->from($db->quoteName('#__template_styles'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
$db->setQuery($query);
|
||||
$style = $db->loadObject();
|
||||
|
||||
if (!is_numeric($style->client_id)) {
|
||||
throw new \Exception(Text::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND'));
|
||||
}
|
||||
|
||||
if ($style->home == '1') {
|
||||
throw new \Exception(Text::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE'));
|
||||
}
|
||||
|
||||
// Set the new home style.
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__template_styles'))
|
||||
->set($db->quoteName('home') . ' = ' . $db->quote('0'))
|
||||
->where($db->quoteName('id') . ' = :id')
|
||||
->bind(':id', $id, ParameterType::INTEGER);
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
// Clean the cache.
|
||||
$this->cleanCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the necessary data to load an item help screen.
|
||||
*
|
||||
* @return object An object with key, url, and local properties for loading the item help screen.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getHelp()
|
||||
{
|
||||
return (object) ['key' => $this->helpKey, 'url' => $this->helpURL];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the back end template for the given style.
|
||||
*
|
||||
* @param int $styleId The style id
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function getAdminTemplate(int $styleId): \stdClass
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['s.template', 's.params', 's.inheritable', 's.parent']))
|
||||
->from($db->quoteName('#__template_styles', 's'))
|
||||
->join(
|
||||
'LEFT',
|
||||
$db->quoteName('#__extensions', 'e'),
|
||||
$db->quoteName('e.type') . ' = ' . $db->quote('template')
|
||||
. ' AND ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('s.template')
|
||||
. ' AND ' . $db->quoteName('e.client_id') . ' = ' . $db->quoteName('s.client_id')
|
||||
)
|
||||
->where(
|
||||
[
|
||||
$db->quoteName('s.client_id') . ' = 1',
|
||||
$db->quoteName('s.home') . ' = ' . $db->quote('1'),
|
||||
]
|
||||
);
|
||||
|
||||
if ($styleId) {
|
||||
$query->extendWhere(
|
||||
'OR',
|
||||
[
|
||||
$db->quoteName('s.client_id') . ' = 1',
|
||||
$db->quoteName('s.id') . ' = :style',
|
||||
$db->quoteName('e.enabled') . ' = 1',
|
||||
]
|
||||
)
|
||||
->bind(':style', $styleId, ParameterType::INTEGER);
|
||||
}
|
||||
|
||||
$query->order($db->quoteName('s.home'));
|
||||
$db->setQuery($query);
|
||||
|
||||
return $db->loadObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the front end templates.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public function getSiteTemplates(): array
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName(['id', 'home', 'template', 's.params', 'inheritable', 'parent']))
|
||||
->from($db->quoteName('#__template_styles', 's'))
|
||||
->where(
|
||||
[
|
||||
$db->quoteName('s.client_id') . ' = 0',
|
||||
$db->quoteName('e.enabled') . ' = 1',
|
||||
]
|
||||
)
|
||||
->join(
|
||||
'LEFT',
|
||||
$db->quoteName('#__extensions', 'e'),
|
||||
$db->quoteName('e.element') . ' = ' . $db->quoteName('s.template')
|
||||
. ' AND ' . $db->quoteName('e.type') . ' = ' . $db->quote('template')
|
||||
. ' AND ' . $db->quoteName('e.client_id') . ' = ' . $db->quoteName('s.client_id')
|
||||
);
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
return $db->loadObjectList('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom clean cache method
|
||||
*
|
||||
* @param string $group The cache group
|
||||
* @param integer $clientId No longer used, will be removed without replacement
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function cleanCache($group = null, $clientId = 0)
|
||||
{
|
||||
parent::cleanCache('com_templates');
|
||||
parent::cleanCache('_system');
|
||||
}
|
||||
}
|
||||
258
administrator/components/com_templates/src/Model/StylesModel.php
Normal file
258
administrator/components/com_templates/src/Model/StylesModel.php
Normal file
@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\String\StringHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Methods supporting a list of template style records.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class StylesModel extends ListModel
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
*
|
||||
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
* @since 3.2
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null)
|
||||
{
|
||||
if (empty($config['filter_fields'])) {
|
||||
$config['filter_fields'] = [
|
||||
'id', 'a.id',
|
||||
'title', 'a.title',
|
||||
'template', 'a.template',
|
||||
'home', 'a.home',
|
||||
'menuitem',
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($config, $factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @param string $ordering An optional ordering field.
|
||||
* @param string $direction An optional direction (asc|desc).
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState($ordering = 'a.template', $direction = 'asc')
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
|
||||
if (!$app->isClient('api')) {
|
||||
// Load the filter state.
|
||||
$this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string'));
|
||||
$this->setState('filter.template', $this->getUserStateFromRequest($this->context . '.filter.template', 'filter_template', '', 'string'));
|
||||
$this->setState('filter.menuitem', $this->getUserStateFromRequest($this->context . '.filter.menuitem', 'filter_menuitem', '', 'cmd'));
|
||||
|
||||
// Special case for the client id.
|
||||
$clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int');
|
||||
$clientId = !\in_array($clientId, [0, 1]) ? 0 : $clientId;
|
||||
$this->setState('client_id', $clientId);
|
||||
}
|
||||
|
||||
// Load the parameters.
|
||||
$params = ComponentHelper::getParams('com_templates');
|
||||
$this->setState('params', $params);
|
||||
|
||||
// List state information.
|
||||
parent::populateState($ordering, $direction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id A prefix for the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= ':' . $this->getState('client_id');
|
||||
$id .= ':' . $this->getState('filter.search');
|
||||
$id .= ':' . $this->getState('filter.template');
|
||||
$id .= ':' . $this->getState('filter.menuitem');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an SQL query to load the list data.
|
||||
*
|
||||
* @return \Joomla\Database\DatabaseQuery
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
$clientId = (int) $this->getState('client_id');
|
||||
|
||||
// Create a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Select the required fields from the table.
|
||||
$query->select(
|
||||
$this->getState(
|
||||
'list.select',
|
||||
[
|
||||
$db->quoteName('a.id'),
|
||||
$db->quoteName('a.template'),
|
||||
$db->quoteName('a.title'),
|
||||
$db->quoteName('a.home'),
|
||||
$db->quoteName('a.client_id'),
|
||||
$db->quoteName('l.title', 'language_title'),
|
||||
$db->quoteName('l.image'),
|
||||
$db->quoteName('l.sef', 'language_sef'),
|
||||
]
|
||||
)
|
||||
)
|
||||
->select(
|
||||
[
|
||||
'COUNT(' . $db->quoteName('m.template_style_id') . ') AS assigned',
|
||||
$db->quoteName('extension_id', 'e_id'),
|
||||
]
|
||||
)
|
||||
->from($db->quoteName('#__template_styles', 'a'))
|
||||
->where($db->quoteName('a.client_id') . ' = :clientid')
|
||||
->bind(':clientid', $clientId, ParameterType::INTEGER);
|
||||
|
||||
// Join on menus.
|
||||
$query->join('LEFT', $db->quoteName('#__menu', 'm'), $db->quoteName('m.template_style_id') . ' = ' . $db->quoteName('a.id'))
|
||||
->group(
|
||||
[
|
||||
$db->quoteName('a.id'),
|
||||
$db->quoteName('a.template'),
|
||||
$db->quoteName('a.title'),
|
||||
$db->quoteName('a.home'),
|
||||
$db->quoteName('a.client_id'),
|
||||
$db->quoteName('l.title'),
|
||||
$db->quoteName('l.image'),
|
||||
$db->quoteName('l.sef'),
|
||||
$db->quoteName('e.extension_id'),
|
||||
]
|
||||
);
|
||||
|
||||
// Join over the language.
|
||||
$query->join('LEFT', $db->quoteName('#__languages', 'l'), $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.home'));
|
||||
|
||||
// Filter by extension enabled.
|
||||
$query->join(
|
||||
'LEFT',
|
||||
$db->quoteName('#__extensions', 'e'),
|
||||
$db->quoteName('e.element') . ' = ' . $db->quoteName('a.template')
|
||||
. ' AND ' . $db->quoteName('e.client_id') . ' = ' . $db->quoteName('a.client_id')
|
||||
)
|
||||
->where(
|
||||
[
|
||||
$db->quoteName('e.enabled') . ' = 1',
|
||||
$db->quoteName('e.type') . ' = ' . $db->quote('template'),
|
||||
]
|
||||
);
|
||||
|
||||
// Filter by template.
|
||||
if ($template = $this->getState('filter.template')) {
|
||||
$query->where($db->quoteName('a.template') . ' = :template')
|
||||
->bind(':template', $template);
|
||||
}
|
||||
|
||||
// Filter by menuitem.
|
||||
$menuItemId = $this->getState('filter.menuitem');
|
||||
|
||||
if ($clientId === 0 && is_numeric($menuItemId)) {
|
||||
// If user selected the templates styles that are not assigned to any page.
|
||||
if ((int) $menuItemId === -1) {
|
||||
// Only custom template styles overrides not assigned to any menu item.
|
||||
$query->where(
|
||||
[
|
||||
$db->quoteName('a.home') . ' = ' . $db->quote('0'),
|
||||
$db->quoteName('m.id') . ' IS NULL',
|
||||
]
|
||||
);
|
||||
} else {
|
||||
// If user selected the templates styles assigned to particular pages.
|
||||
// Subquery to get the language of the selected menu item.
|
||||
$menuItemId = (int) $menuItemId;
|
||||
$menuItemLanguageSubQuery = $db->getQuery(true);
|
||||
$menuItemLanguageSubQuery->select($db->quoteName('language'))
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where($db->quoteName('id') . ' = :menuitemid');
|
||||
$query->bind(':menuitemid', $menuItemId, ParameterType::INTEGER);
|
||||
|
||||
// Subquery to get the language of the selected menu item.
|
||||
$templateStylesMenuItemsSubQuery = $db->getQuery(true);
|
||||
$templateStylesMenuItemsSubQuery->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__menu'))
|
||||
->where($db->quoteName('template_style_id') . ' = ' . $db->quoteName('a.id'));
|
||||
|
||||
// Main query where clause.
|
||||
$query->where('(' .
|
||||
// Default template style (fallback template style to all menu items).
|
||||
$db->quoteName('a.home') . ' = ' . $db->quote('1') . ' OR ' .
|
||||
// Default template style for specific language (fallback template style to the selected menu item language).
|
||||
$db->quoteName('a.home') . ' IN (' . $menuItemLanguageSubQuery . ') OR ' .
|
||||
// Custom template styles override (only if assigned to the selected menu item).
|
||||
'(' . $db->quoteName('a.home') . ' = ' . $db->quote('0') . ' AND ' . $menuItemId . ' IN (' . $templateStylesMenuItemsSubQuery . '))' .
|
||||
')');
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by search in title.
|
||||
if ($search = $this->getState('filter.search')) {
|
||||
if (stripos($search, 'id:') === 0) {
|
||||
$ids = (int) substr($search, 3);
|
||||
$query->where($db->quoteName('a.id') . ' = :id');
|
||||
$query->bind(':id', $ids, ParameterType::INTEGER);
|
||||
} else {
|
||||
$search = '%' . StringHelper::strtolower($search) . '%';
|
||||
$query->extendWhere(
|
||||
'AND',
|
||||
[
|
||||
'LOWER(' . $db->quoteName('a.template') . ') LIKE :templatesearch',
|
||||
'LOWER(' . $db->quoteName('a.title') . ') LIKE :title',
|
||||
],
|
||||
'OR'
|
||||
)
|
||||
->bind(':templatesearch', $search)
|
||||
->bind(':title', $search);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list ordering clause.
|
||||
$query->order($db->escape($this->getState('list.ordering', 'a.template')) . ' ' . $db->escape($this->getState('list.direction', 'ASC')));
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
2073
administrator/components/com_templates/src/Model/TemplateModel.php
Normal file
2073
administrator/components/com_templates/src/Model/TemplateModel.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Model;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\MVC\Model\ListModel;
|
||||
use Joomla\Component\Templates\Administrator\Helper\TemplatesHelper;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\String\StringHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Methods supporting a list of template extension records.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class TemplatesModel extends ListModel
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config An optional associative array of configuration settings.
|
||||
* @param MVCFactoryInterface $factory The factory.
|
||||
*
|
||||
* @see \Joomla\CMS\MVC\Model\BaseDatabaseModel
|
||||
* @since 3.2
|
||||
*/
|
||||
public function __construct($config = [], MVCFactoryInterface $factory = null)
|
||||
{
|
||||
if (empty($config['filter_fields'])) {
|
||||
$config['filter_fields'] = [
|
||||
'id', 'a.id',
|
||||
'name', 'a.name',
|
||||
'folder', 'a.folder',
|
||||
'element', 'a.element',
|
||||
'checked_out', 'a.checked_out',
|
||||
'checked_out_time', 'a.checked_out_time',
|
||||
'state', 'a.state',
|
||||
'enabled', 'a.enabled',
|
||||
'ordering', 'a.ordering',
|
||||
];
|
||||
}
|
||||
|
||||
parent::__construct($config, $factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent getItems to add extra XML metadata.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
$items = parent::getItems();
|
||||
|
||||
foreach ($items as &$item) {
|
||||
$client = ApplicationHelper::getClientInfo($item->client_id);
|
||||
$item->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $item->element);
|
||||
$num = $this->updated($item->extension_id);
|
||||
|
||||
if ($num) {
|
||||
$item->updated = $num;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if template extension have any updated override.
|
||||
*
|
||||
* @param integer $exid Extension id of template.
|
||||
*
|
||||
* @return boolean False if records not found/else integer.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public function updated($exid)
|
||||
{
|
||||
$db = $this->getDatabase();
|
||||
|
||||
// Select the required fields from the table
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('template'))
|
||||
->from($db->quoteName('#__template_overrides'))
|
||||
->where($db->quoteName('extension_id') . ' = :extensionid')
|
||||
->where($db->quoteName('state') . ' = 0')
|
||||
->bind(':extensionid', $exid, ParameterType::INTEGER);
|
||||
|
||||
// Reset the query.
|
||||
$db->setQuery($query);
|
||||
|
||||
// Load the results as a list of stdClass objects.
|
||||
$num = \count($db->loadObjectList());
|
||||
|
||||
if ($num > 0) {
|
||||
return $num;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an SQL query to load the list data.
|
||||
*
|
||||
* @return \Joomla\Database\DatabaseQuery
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function getListQuery()
|
||||
{
|
||||
// Create a new query object.
|
||||
$db = $this->getDatabase();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Select the required fields from the table.
|
||||
$query->select(
|
||||
$this->getState(
|
||||
'list.select',
|
||||
'a.extension_id, a.name, a.element, a.client_id'
|
||||
)
|
||||
);
|
||||
$clientId = (int) $this->getState('client_id');
|
||||
$query->from($db->quoteName('#__extensions', 'a'))
|
||||
->where($db->quoteName('a.client_id') . ' = :clientid')
|
||||
->where($db->quoteName('a.enabled') . ' = 1')
|
||||
->where($db->quoteName('a.type') . ' = ' . $db->quote('template'))
|
||||
->bind(':clientid', $clientId, ParameterType::INTEGER);
|
||||
|
||||
// Filter by search in title.
|
||||
if ($search = $this->getState('filter.search')) {
|
||||
if (stripos($search, 'id:') === 0) {
|
||||
$ids = (int) substr($search, 3);
|
||||
$query->where($db->quoteName('a.id') . ' = :id');
|
||||
$query->bind(':id', $ids, ParameterType::INTEGER);
|
||||
} else {
|
||||
$search = '%' . StringHelper::strtolower($search) . '%';
|
||||
$query->extendWhere(
|
||||
'AND',
|
||||
[
|
||||
'LOWER(' . $db->quoteName('a.element') . ') LIKE :element',
|
||||
'LOWER(' . $db->quoteName('a.name') . ') LIKE :name',
|
||||
],
|
||||
'OR'
|
||||
)
|
||||
->bind(':element', $search)
|
||||
->bind(':name', $search);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list ordering clause.
|
||||
$query->order($db->escape($this->getState('list.ordering', 'a.element')) . ' ' . $db->escape($this->getState('list.direction', 'ASC')));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a store id based on model configuration state.
|
||||
*
|
||||
* This is necessary because the model is used by the component and
|
||||
* different modules that might need different sets of data or different
|
||||
* ordering requirements.
|
||||
*
|
||||
* @param string $id A prefix for the store id.
|
||||
*
|
||||
* @return string A store id.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function getStoreId($id = '')
|
||||
{
|
||||
// Compile the store id.
|
||||
$id .= ':' . $this->getState('client_id');
|
||||
$id .= ':' . $this->getState('filter.search');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
* Note. Calling getState in this method will result in recursion.
|
||||
*
|
||||
* @param string $ordering An optional ordering field.
|
||||
* @param string $direction An optional direction (asc|desc).
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function populateState($ordering = 'a.element', $direction = 'asc')
|
||||
{
|
||||
// Load the filter state.
|
||||
$this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string'));
|
||||
|
||||
// Special case for the client id.
|
||||
$clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int');
|
||||
$clientId = (!\in_array($clientId, [0, 1])) ? 0 : $clientId;
|
||||
$this->setState('client_id', $clientId);
|
||||
|
||||
// Load the parameters.
|
||||
$params = ComponentHelper::getParams('com_templates');
|
||||
$this->setState('params', $params);
|
||||
|
||||
// List state information.
|
||||
parent::populateState($ordering, $direction);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Service\HTML;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
use Joomla\Component\Templates\Administrator\Helper\TemplatesHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Html helper class.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class Templates
|
||||
{
|
||||
/**
|
||||
* Display the thumb for the template.
|
||||
*
|
||||
* @param string|object $template The name of the template or the template object.
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
* The argument $template must be an object only
|
||||
* @param integer $clientId No longer used, will be removed without replacement
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
*
|
||||
* @return string The html string
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function thumb($template, $clientId = 0)
|
||||
{
|
||||
if (\is_string($template)) {
|
||||
return HTMLHelper::_('image', 'template_thumbnail.png', Text::_('COM_TEMPLATES_PREVIEW'), [], true, -1);
|
||||
}
|
||||
|
||||
$client = ApplicationHelper::getClientInfo($template->client_id);
|
||||
|
||||
if (!isset($template->xmldata)) {
|
||||
$template->xmldata = TemplatesHelper::parseXMLTemplateFile($client->id === 0 ? JPATH_ROOT : JPATH_ROOT . '/administrator', $template->name);
|
||||
}
|
||||
|
||||
if ((isset($template->xmldata->inheritable) && (bool) $template->xmldata->inheritable) || isset($template->xmldata->parent)) {
|
||||
if (isset($template->xmldata->parent) && (string) $template->xmldata->parent !== '' && file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . (string) $template->xmldata->parent . '/images/template_thumbnail.png')) {
|
||||
if (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_preview.png')) {
|
||||
$html = HTMLHelper::_('image', 'media/templates/' . $client->name . '/' . $template->element . '/images/template_thumbnail.png', Text::_('COM_TEMPLATES_PREVIEW'));
|
||||
$html = '<button type="button" data-bs-target="#' . $template->element . '-Modal" class="thumbnail" data-bs-toggle="modal" title="' . Text::_('COM_TEMPLATES_CLICK_TO_ENLARGE') . '">' . $html . '</button>';
|
||||
} elseif ((file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . (string) $template->xmldata->parent . '/images/template_preview.png'))) {
|
||||
$html = HTMLHelper::_('image', 'media/templates/' . $client->name . '/' . (string) $template->xmldata->parent . '/images/template_thumbnail.png', Text::_('COM_TEMPLATES_PREVIEW'));
|
||||
$html = '<button type="button" data-bs-target="#' . $template->element . '-Modal" class="thumbnail" data-bs-toggle="modal" title="' . Text::_('COM_TEMPLATES_CLICK_TO_ENLARGE') . '">' . $html . '</button>';
|
||||
} else {
|
||||
$html = HTMLHelper::_('image', 'template_thumb.svg', Text::_('COM_TEMPLATES_PREVIEW'), ['style' => 'width:200px; height:120px;']);
|
||||
}
|
||||
} elseif (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_thumbnail.png')) {
|
||||
$html = HTMLHelper::_('image', 'media/templates/' . $client->name . '/' . $template->element . '/images/template_thumbnail.png', Text::_('COM_TEMPLATES_PREVIEW'));
|
||||
|
||||
if (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_preview.png')) {
|
||||
$html = '<button type="button" data-bs-target="#' . $template->element . '-Modal" class="thumbnail" data-bs-toggle="modal" title="' . Text::_('COM_TEMPLATES_CLICK_TO_ENLARGE') . '">' . $html . '</button>';
|
||||
}
|
||||
} else {
|
||||
$html = HTMLHelper::_('image', 'template_thumb.svg', Text::_('COM_TEMPLATES_PREVIEW'), ['style' => 'width:200px; height:120px;']);
|
||||
}
|
||||
} elseif (file_exists($client->path . '/templates/' . $template->element . '/template_thumbnail.png')) {
|
||||
$html = HTMLHelper::_('image', (($template->client_id == 0) ? Uri::root(true) : Uri::root(true) . '/administrator/') . '/templates/' . $template->element . '/template_thumbnail.png', Text::_('COM_TEMPLATES_PREVIEW'), [], false, -1);
|
||||
|
||||
if (file_exists($client->path . '/templates/' . $template->element . '/template_preview.png')) {
|
||||
$html = '<button type="button" data-bs-target="#' . $template->element . '-Modal" class="thumbnail" data-bs-toggle="modal" title="' . Text::_('COM_TEMPLATES_CLICK_TO_ENLARGE') . '">' . $html . '</button>';
|
||||
}
|
||||
} else {
|
||||
$html = HTMLHelper::_('image', 'template_thumb.svg', Text::_('COM_TEMPLATES_PREVIEW'), ['style' => 'width:200px; height:120px;']);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the html for the modal linked to thumb.
|
||||
*
|
||||
* @param string|object $template The name of the template or the template object.
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
* The argument $template must be an object only
|
||||
* @param integer $clientId No longer used, will be removed without replacement
|
||||
* @deprecated 4.3 will be removed in 6.0
|
||||
*
|
||||
* @return string The html string
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public function thumbModal($template, $clientId = 0)
|
||||
{
|
||||
if (\is_string($template)) {
|
||||
return HTMLHelper::_('image', 'template_thumbnail.png', Text::_('COM_TEMPLATES_PREVIEW'), [], true, -1);
|
||||
}
|
||||
|
||||
$html = '';
|
||||
$thumb = '';
|
||||
$preview = '';
|
||||
$client = ApplicationHelper::getClientInfo($template->client_id);
|
||||
|
||||
if (!isset($template->xmldata)) {
|
||||
$template->xmldata = TemplatesHelper::parseXMLTemplateFile($client->id === 0 ? JPATH_ROOT : JPATH_ROOT . '/administrator', $template->name);
|
||||
}
|
||||
|
||||
if ((isset($template->xmldata->inheritable) && (bool) $template->xmldata->inheritable) || isset($template->xmldata->parent)) {
|
||||
if (isset($template->xmldata->parent) && (string) $template->xmldata->parent !== '') {
|
||||
if (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_thumbnail.png')) {
|
||||
$thumb = ($template->client_id == 0 ? Uri::root(true) : Uri::root(true) . 'administrator') . 'media/templates/' . $client->name . '/' . $template->element . '/images/template_thumbnail.png';
|
||||
|
||||
if (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_preview.png')) {
|
||||
$preview = ($template->client_id == 0 ? Uri::root(true) : Uri::root(true) . '/administrator') . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_preview.png';
|
||||
}
|
||||
} else {
|
||||
$thumb = ($template->client_id == 0 ? Uri::root(true) : Uri::root(true) . 'administrator') . 'media/templates/' . $client->name . '/' . (string) $template->xmldata->parent . '/images/template_thumbnail.png';
|
||||
|
||||
if (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . (string) $template->xmldata->parent . '/images/template_preview.png')) {
|
||||
$preview = ($template->client_id == 0 ? Uri::root(true) : Uri::root(true) . '/administrator') . '/media/templates/' . $client->name . '/' . (string) $template->xmldata->parent . '/images/template_preview.png';
|
||||
}
|
||||
}
|
||||
} elseif (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_thumbnail.png')) {
|
||||
$thumb = ($template->client_id == 0 ? Uri::root(true) : Uri::root(true) . '/administrator') . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_thumbnail.png';
|
||||
|
||||
if (file_exists(JPATH_ROOT . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_preview.png')) {
|
||||
$preview = Uri::root(true) . '/media/templates/' . $client->name . '/' . $template->element . '/images/template_preview.png';
|
||||
}
|
||||
}
|
||||
} elseif (file_exists($client->path . '/templates/' . $template->element . '/template_thumbnail.png')) {
|
||||
$thumb = (($template->client_id == 0) ? Uri::root(true) : Uri::root(true) . 'administrator') . '/templates/' . $template->element . '/template_thumbnail.png';
|
||||
|
||||
if (file_exists($client->path . '/templates/' . $template->element . '/template_preview.png')) {
|
||||
$preview = (($template->client_id == 0) ? Uri::root(true) : Uri::root(true) . '/administrator') . '/templates/' . $template->element . '/template_preview.png';
|
||||
}
|
||||
}
|
||||
|
||||
if ($thumb !== '' && $preview !== '') {
|
||||
$footer = '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">'
|
||||
. Text::_('JTOOLBAR_CLOSE') . '</button>';
|
||||
|
||||
$html .= HTMLHelper::_(
|
||||
'bootstrap.renderModal',
|
||||
$template->element . '-Modal',
|
||||
[
|
||||
'title' => Text::sprintf('COM_TEMPLATES_SCREENSHOT', ucfirst($template->name)),
|
||||
'height' => '500px',
|
||||
'width' => '800px',
|
||||
'footer' => $footer,
|
||||
],
|
||||
'<div><img src="' . $preview . '" class="mw-100" alt="' . $template->name . '"></div>'
|
||||
);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
159
administrator/components/com_templates/src/Table/StyleTable.php
Normal file
159
administrator/components/com_templates/src/Table/StyleTable.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\Table;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Table\Table;
|
||||
use Joomla\Database\DatabaseDriver;
|
||||
use Joomla\Database\ParameterType;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* Template style table class.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class StyleTable extends Table
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DatabaseDriver $db Database connector object
|
||||
* @param ?DispatcherInterface $dispatcher Event dispatcher for this table
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function __construct(DatabaseDriver $db, DispatcherInterface $dispatcher = null)
|
||||
{
|
||||
parent::__construct('#__template_styles', 'id', $db, $dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded bind function to pre-process the params.
|
||||
*
|
||||
* @param array $array Named array
|
||||
* @param mixed $ignore An optional array or space separated list of properties to ignore while binding.
|
||||
*
|
||||
* @return null|string null if operation was satisfactory, otherwise returns an error
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function bind($array, $ignore = '')
|
||||
{
|
||||
if (isset($array['params']) && \is_array($array['params'])) {
|
||||
$registry = new Registry($array['params']);
|
||||
$array['params'] = (string) $registry;
|
||||
}
|
||||
|
||||
// Verify that the default style is not unset
|
||||
if ($array['home'] == '0' && $this->home == '1') {
|
||||
$this->setError(Text::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::bind($array, $ignore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded check method to ensure data integrity.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
try {
|
||||
parent::check();
|
||||
} catch (\Exception $e) {
|
||||
$this->setError($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($this->title)) {
|
||||
$this->setError(Text::_('COM_TEMPLATES_ERROR_STYLE_REQUIRES_TITLE'));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded store method to ensure unicity of default style.
|
||||
*
|
||||
* @param boolean $updateNulls True to update fields even if they are null.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function store($updateNulls = false)
|
||||
{
|
||||
if ($this->home != '0') {
|
||||
$clientId = (int) $this->client_id;
|
||||
$query = $this->_db->getQuery(true)
|
||||
->update($this->_db->quoteName('#__template_styles'))
|
||||
->set($this->_db->quoteName('home') . ' = ' . $this->_db->quote('0'))
|
||||
->where($this->_db->quoteName('client_id') . ' = :clientid')
|
||||
->where($this->_db->quoteName('home') . ' = :home')
|
||||
->bind(':clientid', $clientId, ParameterType::INTEGER)
|
||||
->bind(':home', $this->home);
|
||||
$this->_db->setQuery($query);
|
||||
$this->_db->execute();
|
||||
}
|
||||
|
||||
return parent::store($updateNulls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloaded store method to unsure existence of a default style for a template.
|
||||
*
|
||||
* @param mixed $pk An optional primary key value to delete. If not set the instance property value is used.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function delete($pk = null)
|
||||
{
|
||||
$k = $this->_tbl_key;
|
||||
$pk = \is_null($pk) ? $this->$k : $pk;
|
||||
|
||||
if (!\is_null($pk)) {
|
||||
$clientId = (int) $this->client_id;
|
||||
$query = $this->_db->getQuery(true)
|
||||
->select($this->_db->quoteName('id'))
|
||||
->from($this->_db->quoteName('#__template_styles'))
|
||||
->where($this->_db->quoteName('client_id') . ' = :clientid')
|
||||
->where($this->_db->quoteName('template') . ' = :template')
|
||||
->bind(':template', $this->template)
|
||||
->bind(':clientid', $clientId, ParameterType::INTEGER);
|
||||
$this->_db->setQuery($query);
|
||||
$results = $this->_db->loadColumn();
|
||||
|
||||
if (\count($results) == 1 && $results[0] == $pk) {
|
||||
$this->setError(Text::_('COM_TEMPLATES_ERROR_CANNOT_DELETE_LAST_STYLE'));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::delete($pk);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\View\Style;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View to edit a template style.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The CMSObject (on success, false on failure)
|
||||
*
|
||||
* @var CMSObject
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* The form object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The actions the user is authorised to perform
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $canDo;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->item = $this->get('Item');
|
||||
$this->state = $this->get('State');
|
||||
$this->form = $this->get('Form');
|
||||
$this->canDo = ContentHelper::getActions('com_templates');
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
Factory::getApplication()->getInput()->set('hidemainmenu', true);
|
||||
|
||||
$isNew = ($this->item->id == 0);
|
||||
$canDo = $this->canDo;
|
||||
$toolbar = Toolbar::getInstance();
|
||||
|
||||
ToolbarHelper::title(
|
||||
$isNew ? Text::_('COM_TEMPLATES_MANAGER_ADD_STYLE')
|
||||
: Text::_('COM_TEMPLATES_MANAGER_EDIT_STYLE'),
|
||||
'paint-brush thememanager'
|
||||
);
|
||||
|
||||
// If not checked out, can save the item.
|
||||
if ($canDo->get('core.edit')) {
|
||||
$toolbar->apply('style.apply');
|
||||
}
|
||||
|
||||
$saveGroup = $toolbar->dropdownButton('save-group');
|
||||
|
||||
$saveGroup->configure(
|
||||
function (Toolbar $childBar) use ($canDo, $isNew) {
|
||||
// If not checked out, can save the item.
|
||||
if ($canDo->get('core.edit')) {
|
||||
$childBar->save('style.save');
|
||||
}
|
||||
|
||||
// If an existing item, can save to a copy.
|
||||
if (!$isNew && $canDo->get('core.create')) {
|
||||
$childBar->save2copy('style.save2copy');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (empty($this->item->id)) {
|
||||
$toolbar->cancel('style.cancel', 'JTOOLBAR_CANCEL');
|
||||
} else {
|
||||
$toolbar->cancel('style.cancel');
|
||||
}
|
||||
|
||||
$toolbar->divider();
|
||||
|
||||
// Get the help information for the template item.
|
||||
$lang = $this->getLanguage();
|
||||
$help = $this->get('Help');
|
||||
|
||||
if ($lang->hasKey($help->url)) {
|
||||
$debug = $lang->setDebug(false);
|
||||
$url = Text::_($help->url);
|
||||
$lang->setDebug($debug);
|
||||
} else {
|
||||
$url = null;
|
||||
}
|
||||
|
||||
$toolbar->help($help->key, false, $url);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\View\Style;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Object\CMSObject;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View to edit a template style.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class JsonView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The CMSObject (on success, false on failure)
|
||||
*
|
||||
* @var CMSObject
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* The form object
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return mixed A string if successful, otherwise an Error object.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
try {
|
||||
$this->item = $this->get('Item');
|
||||
} catch (\Exception $e) {
|
||||
$app = Factory::getApplication();
|
||||
$app->enqueueMessage($e->getMessage(), 'error');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$paramsList = $this->item->getProperties();
|
||||
|
||||
unset($paramsList['xml']);
|
||||
|
||||
$paramsList = json_encode($paramsList);
|
||||
|
||||
return $paramsList;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\View\Styles;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View class for a list of template styles.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* An array of items
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* The pagination object
|
||||
*
|
||||
* @var \Joomla\CMS\Pagination\Pagination
|
||||
*/
|
||||
protected $pagination;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Form object for search filters
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public $filterForm;
|
||||
|
||||
/**
|
||||
* The active search filters
|
||||
*
|
||||
* @var array
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public $activeFilters;
|
||||
|
||||
/**
|
||||
* Is the parameter enabled to show template positions in the frontend?
|
||||
*
|
||||
* @var boolean
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public $preview;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
$this->state = $this->get('State');
|
||||
$this->total = $this->get('Total');
|
||||
$this->filterForm = $this->get('FilterForm');
|
||||
$this->activeFilters = $this->get('ActiveFilters');
|
||||
$this->preview = ComponentHelper::getParams('com_templates')->get('template_positions_display');
|
||||
|
||||
// Remove the menu item filter for administrator styles.
|
||||
if ((int) $this->state->get('client_id') !== 0) {
|
||||
unset($this->activeFilters['menuitem']);
|
||||
$this->filterForm->removeField('menuitem', 'filter');
|
||||
}
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
$canDo = ContentHelper::getActions('com_templates');
|
||||
$clientId = (int) $this->get('State')->get('client_id');
|
||||
$toolbar = Toolbar::getInstance();
|
||||
|
||||
// Add a shortcut to the templates list view.
|
||||
$toolbar->linkButton('templates', 'COM_TEMPLATES_MANAGER_TEMPLATES')
|
||||
->url('index.php?option=com_templates&view=templates&client_id=' . $clientId)
|
||||
->icon('icon-code thememanager');
|
||||
|
||||
// Set the title.
|
||||
if ($clientId === 1) {
|
||||
ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_STYLES_ADMIN'), 'paint-brush thememanager');
|
||||
} else {
|
||||
ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_STYLES_SITE'), 'paint-brush thememanager');
|
||||
}
|
||||
|
||||
if ($canDo->get('core.edit.state')) {
|
||||
$toolbar->makeDefault('styles.setDefault', 'COM_TEMPLATES_TOOLBAR_SET_HOME');
|
||||
$toolbar->divider();
|
||||
}
|
||||
|
||||
if ($canDo->get('core.create')) {
|
||||
$toolbar->standardButton('duplicate', 'JTOOLBAR_DUPLICATE', 'styles.duplicate')
|
||||
->listCheck(true)
|
||||
->icon('icon-copy');
|
||||
$toolbar->divider();
|
||||
}
|
||||
|
||||
if ($canDo->get('core.delete')) {
|
||||
$toolbar->delete('styles.delete')
|
||||
->message('JGLOBAL_CONFIRM_DELETE')
|
||||
->listCheck(true);
|
||||
$toolbar->divider();
|
||||
}
|
||||
|
||||
if ($canDo->get('core.admin') || $canDo->get('core.options')) {
|
||||
$toolbar->preferences('com_templates');
|
||||
$toolbar->divider();
|
||||
}
|
||||
|
||||
$toolbar->help('Templates:_Styles');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,413 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\View\Template;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Filter\InputFilter;
|
||||
use Joomla\CMS\Form\Form;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Toolbar\Button\DropdownButton;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View to edit a template.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The Model state
|
||||
*
|
||||
* @var \Joomla\Registry\Registry
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* The template details
|
||||
*
|
||||
* @var \stdClass|false
|
||||
*/
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* For loading the source form
|
||||
*
|
||||
* @var Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* For loading source file contents
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $source;
|
||||
|
||||
/**
|
||||
* Extension id
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Encrypted file path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* List of available overrides
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $overridesList;
|
||||
|
||||
/**
|
||||
* Name of the present file
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fileName;
|
||||
|
||||
/**
|
||||
* Type of the file - image, source, font
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* For loading image information
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
/**
|
||||
* Template id for showing preview button
|
||||
*
|
||||
* @var \stdClass
|
||||
*/
|
||||
protected $preview;
|
||||
|
||||
/**
|
||||
* For loading font information
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $font;
|
||||
|
||||
/**
|
||||
* A nested array containing list of files and folders
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* An array containing a list of compressed files
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $archive;
|
||||
|
||||
/**
|
||||
* The state of installer override plugin.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $pluginState;
|
||||
|
||||
/**
|
||||
* A nested array containing list of files and folders in the media folder
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
protected $mediaFiles;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void|boolean
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$this->file = $app->getInput()->get('file', '');
|
||||
$this->fileName = InputFilter::getInstance()->clean(base64_decode($this->file), 'string');
|
||||
$explodeArray = explode('.', $this->fileName);
|
||||
$ext = end($explodeArray);
|
||||
$this->files = $this->get('Files');
|
||||
$this->mediaFiles = $this->get('MediaFiles');
|
||||
$this->state = $this->get('State');
|
||||
$this->template = $this->get('Template');
|
||||
$this->preview = $this->get('Preview');
|
||||
$this->pluginState = PluginHelper::isEnabled('installer', 'override');
|
||||
$this->updatedList = $this->get('UpdatedList');
|
||||
$this->styles = $this->get('AllTemplateStyles');
|
||||
$this->stylesHTML = '';
|
||||
|
||||
$params = ComponentHelper::getParams('com_templates');
|
||||
$imageTypes = explode(',', $params->get('image_formats', 'gif,bmp,jpg,jpeg,png,webp'));
|
||||
$sourceTypes = explode(',', $params->get('source_formats', 'txt,less,ini,xml,js,php,css,scss,sass,json'));
|
||||
$fontTypes = explode(',', $params->get('font_formats', 'woff,woff2,ttf,otf'));
|
||||
$archiveTypes = explode(',', $params->get('compressed_formats', 'zip'));
|
||||
|
||||
if (\in_array($ext, $sourceTypes)) {
|
||||
$this->form = $this->get('Form');
|
||||
$this->form->setFieldAttribute('source', 'syntax', $ext);
|
||||
$this->source = $this->get('Source');
|
||||
$this->type = 'file';
|
||||
} elseif (\in_array($ext, $imageTypes)) {
|
||||
try {
|
||||
$this->image = $this->get('Image');
|
||||
$this->type = 'image';
|
||||
} catch (\RuntimeException $exception) {
|
||||
$app->enqueueMessage(Text::_('COM_TEMPLATES_GD_EXTENSION_NOT_AVAILABLE'));
|
||||
$this->type = 'home';
|
||||
}
|
||||
} elseif (\in_array($ext, $fontTypes)) {
|
||||
$this->font = $this->get('Font');
|
||||
$this->type = 'font';
|
||||
} elseif (\in_array($ext, $archiveTypes)) {
|
||||
$this->archive = $this->get('Archive');
|
||||
$this->type = 'archive';
|
||||
} else {
|
||||
$this->type = 'home';
|
||||
}
|
||||
|
||||
$this->overridesList = $this->get('OverridesList');
|
||||
$this->id = $this->state->get('extension.id');
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
$app->enqueueMessage(implode("\n", $errors));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
if (!$this->getCurrentUser()->authorise('core.admin')) {
|
||||
$this->setLayout('readonly');
|
||||
}
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
$app = Factory::getApplication();
|
||||
$user = $this->getCurrentUser();
|
||||
$toolbar = Toolbar::getInstance('toolbar');
|
||||
$app->getInput()->set('hidemainmenu', true);
|
||||
|
||||
// User is global SuperUser
|
||||
$isSuperUser = $user->authorise('core.admin');
|
||||
$explodeArray = explode('.', $this->fileName);
|
||||
$ext = end($explodeArray);
|
||||
|
||||
ToolbarHelper::title(Text::sprintf('COM_TEMPLATES_MANAGER_VIEW_TEMPLATE', ucfirst($this->template->name)), 'icon-code thememanager');
|
||||
|
||||
// Only show file edit buttons for global SuperUser
|
||||
if ($isSuperUser) {
|
||||
// Add an Apply and save button
|
||||
if ($this->type === 'file') {
|
||||
$toolbar->apply('template.apply');
|
||||
$toolbar->save('template.save');
|
||||
} elseif ($this->type === 'image') {
|
||||
// Add a Crop and Resize button
|
||||
$toolbar->standardButton('crop', 'COM_TEMPLATES_BUTTON_CROP', 'template.cropImage')
|
||||
->listCheck(false)
|
||||
->icon('icon-crop');
|
||||
ToolbarHelper::modal('resizeModal', 'icon-expand', 'COM_TEMPLATES_BUTTON_RESIZE');
|
||||
} elseif ($this->type === 'archive') {
|
||||
// Add an extract button
|
||||
$toolbar->standardButton('extract', 'COM_TEMPLATES_BUTTON_EXTRACT_ARCHIVE', 'template.extractArchive')
|
||||
->listCheck(false)
|
||||
->icon('icon-chevron-down');
|
||||
} elseif ($this->type === 'home') {
|
||||
// Add a copy/child template button
|
||||
if (isset($this->template->xmldata->inheritable) && (string) $this->template->xmldata->inheritable === '1') {
|
||||
ToolbarHelper::modal('childModal', 'icon-copy', 'COM_TEMPLATES_BUTTON_TEMPLATE_CHILD');
|
||||
} elseif (empty($this->template->xmldata->parent) && empty($this->template->xmldata->namespace)) {
|
||||
// We can't copy parent templates nor namespaced templates
|
||||
ToolbarHelper::modal('copyModal', 'icon-copy', 'COM_TEMPLATES_BUTTON_COPY_TEMPLATE');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a Template preview button
|
||||
if ($this->type === 'home') {
|
||||
$client = (int) $this->preview->client_id === 1 ? 'administrator/' : '';
|
||||
$toolbar->linkButton('preview', 'COM_TEMPLATES_BUTTON_PREVIEW')
|
||||
->url(Uri::root() . $client . 'index.php?tp=1&templateStyle=' . $this->preview->id)
|
||||
->icon('icon-image')
|
||||
->attributes(['target' => '_new']);
|
||||
}
|
||||
|
||||
// Only show file manage buttons for global SuperUser
|
||||
if ($isSuperUser) {
|
||||
if ($this->type === 'home') {
|
||||
// Add Manage folders button
|
||||
ToolbarHelper::modal('folderModal', 'icon-folder icon white', 'COM_TEMPLATES_BUTTON_FOLDERS');
|
||||
|
||||
// Add a new file button
|
||||
ToolbarHelper::modal('fileModal', 'icon-file', 'COM_TEMPLATES_BUTTON_FILE');
|
||||
} else {
|
||||
// Add a Rename file Button
|
||||
ToolbarHelper::modal('renameModal', 'icon-sync', 'COM_TEMPLATES_BUTTON_RENAME_FILE');
|
||||
|
||||
// Add a Delete file Button
|
||||
ToolbarHelper::modal('deleteModal', 'icon-times', 'COM_TEMPLATES_BUTTON_DELETE_FILE', 'btn-danger');
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($this->updatedList) !== 0 && $this->pluginState && $this->type === 'home') {
|
||||
/** @var DropdownButton $dropdown */
|
||||
$dropdown = $toolbar->dropdownButton('override-group', 'COM_TEMPLATES_BUTTON_CHECK')
|
||||
->toggleSplit(false)
|
||||
->icon('icon-ellipsis-h')
|
||||
->buttonClass('btn btn-action')
|
||||
->form('updateForm')
|
||||
->listCheck(true);
|
||||
|
||||
$childBar = $dropdown->getChildToolbar();
|
||||
|
||||
$childBar->publish('template.publish')
|
||||
->text('COM_TEMPLATES_BUTTON_CHECK_LIST_ENTRY')
|
||||
->form('updateForm')
|
||||
->listCheck(true);
|
||||
$childBar->unpublish('template.unpublish')
|
||||
->text('COM_TEMPLATES_BUTTON_UNCHECK_LIST_ENTRY')
|
||||
->form('updateForm')
|
||||
->listCheck(true);
|
||||
$childBar->unpublish('template.deleteOverrideHistory')
|
||||
->text('COM_TEMPLATES_BUTTON_DELETE_LIST_ENTRY')
|
||||
->form('updateForm')
|
||||
->listCheck(true);
|
||||
}
|
||||
|
||||
if ($this->type === 'home') {
|
||||
$toolbar->cancel('template.cancel');
|
||||
} else {
|
||||
$toolbar->cancel('template.close', 'COM_TEMPLATES_BUTTON_CLOSE_FILE');
|
||||
}
|
||||
|
||||
$toolbar->divider();
|
||||
$toolbar->help('Templates:_Customise');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for creating the collapsible tree.
|
||||
*
|
||||
* @param array $array The value of the present node for recursion
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @note Uses recursion
|
||||
* @since 3.2
|
||||
*/
|
||||
protected function directoryTree($array)
|
||||
{
|
||||
$temp = $this->files;
|
||||
$this->files = $array;
|
||||
$txt = $this->loadTemplate('tree');
|
||||
$this->files = $temp;
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for listing the folder tree in modals.
|
||||
*
|
||||
* @param array $array The value of the present node for recursion
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @note Uses recursion
|
||||
* @since 3.2
|
||||
*/
|
||||
protected function folderTree($array)
|
||||
{
|
||||
$temp = $this->files;
|
||||
$this->files = $array;
|
||||
$txt = $this->loadTemplate('folders');
|
||||
$this->files = $temp;
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for creating the collapsible tree.
|
||||
*
|
||||
* @param array $array The value of the present node for recursion
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @note Uses recursion
|
||||
* @since 4.1.0
|
||||
*/
|
||||
protected function mediaTree($array)
|
||||
{
|
||||
$temp = $this->mediaFiles;
|
||||
$this->mediaFiles = $array;
|
||||
$txt = $this->loadTemplate('tree_media');
|
||||
$this->mediaFiles = $temp;
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for listing the folder tree in modals.
|
||||
*
|
||||
* @param array $array The value of the present node for recursion
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @note Uses recursion
|
||||
* @since 4.1.0
|
||||
*/
|
||||
protected function mediaFolderTree($array)
|
||||
{
|
||||
$temp = $this->mediaFiles;
|
||||
$this->mediaFiles = $array;
|
||||
$txt = $this->loadTemplate('media_folders');
|
||||
$this->mediaFiles = $temp;
|
||||
|
||||
return $txt;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\Templates\Administrator\View\Templates;
|
||||
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Helper\ContentHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\MVC\View\GenericDataException;
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\CMS\Toolbar\Toolbar;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
// phpcs:disable PSR1.Files.SideEffects
|
||||
\defined('_JEXEC') or die;
|
||||
// phpcs:enable PSR1.Files.SideEffects
|
||||
|
||||
/**
|
||||
* View class for a list of templates.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
/**
|
||||
* The list of templates
|
||||
*
|
||||
* @var array
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* The pagination object
|
||||
*
|
||||
* @var object
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $pagination;
|
||||
|
||||
/**
|
||||
* The model state
|
||||
*
|
||||
* @var object
|
||||
* @since 1.6
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @since 3.2
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* Form object for search filters
|
||||
*
|
||||
* @var \Joomla\CMS\Form\Form
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public $filterForm;
|
||||
|
||||
/**
|
||||
* The active search filters
|
||||
*
|
||||
* @var array
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public $activeFilters;
|
||||
|
||||
/**
|
||||
* Is the parameter enabled to show template positions in the frontend?
|
||||
*
|
||||
* @var boolean
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public $preview;
|
||||
|
||||
/**
|
||||
* The state of installer override plugin.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
protected $pluginState;
|
||||
|
||||
/**
|
||||
* Execute and display a template script.
|
||||
*
|
||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public function display($tpl = null)
|
||||
{
|
||||
$this->items = $this->get('Items');
|
||||
$this->pagination = $this->get('Pagination');
|
||||
$this->state = $this->get('State');
|
||||
$this->total = $this->get('Total');
|
||||
$this->filterForm = $this->get('FilterForm');
|
||||
$this->activeFilters = $this->get('ActiveFilters');
|
||||
$this->preview = ComponentHelper::getParams('com_templates')->get('template_positions_display');
|
||||
$this->file = base64_encode('home');
|
||||
$this->pluginState = PluginHelper::isEnabled('installer', 'override');
|
||||
|
||||
// Check for errors.
|
||||
if (\count($errors = $this->get('Errors'))) {
|
||||
throw new GenericDataException(implode("\n", $errors), 500);
|
||||
}
|
||||
|
||||
$this->addToolbar();
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the page title and toolbar.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected function addToolbar()
|
||||
{
|
||||
$canDo = ContentHelper::getActions('com_templates');
|
||||
$clientId = (int) $this->get('State')->get('client_id');
|
||||
$toolbar = Toolbar::getInstance();
|
||||
|
||||
// Add a shortcut to the styles list view.
|
||||
$toolbar->linkButton('', 'COM_TEMPLATES_MANAGER_STYLES_BUTTON')
|
||||
->url('index.php?option=com_templates&view=styles&client_id=' . $clientId)
|
||||
->icon('icon-brush thememanager');
|
||||
|
||||
// Set the title.
|
||||
if ($clientId === 1) {
|
||||
ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_TEMPLATES_ADMIN'), 'icon-code thememanager');
|
||||
} else {
|
||||
ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_TEMPLATES_SITE'), 'icon-code thememanager');
|
||||
}
|
||||
|
||||
if ($canDo->get('core.admin') || $canDo->get('core.options')) {
|
||||
$toolbar->preferences('com_templates');
|
||||
$toolbar->divider();
|
||||
}
|
||||
|
||||
$toolbar->help('Templates:_Templates');
|
||||
}
|
||||
}
|
||||
34
administrator/components/com_templates/templates.xml
Normal file
34
administrator/components/com_templates/templates.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension type="component" method="upgrade">
|
||||
<name>com_templates</name>
|
||||
<author>Joomla! Project</author>
|
||||
<creationDate>2006-04</creationDate>
|
||||
<copyright>(C) 2006 Open Source Matters, Inc.</copyright>
|
||||
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
|
||||
<authorEmail>admin@joomla.org</authorEmail>
|
||||
<authorUrl>www.joomla.org</authorUrl>
|
||||
<version>4.0.0</version>
|
||||
<description>COM_TEMPLATES_XML_DESCRIPTION</description>
|
||||
<namespace path="src">Joomla\Component\Templates</namespace>
|
||||
<media destination="com_templates" folder="media">
|
||||
<folder>css</folder>
|
||||
<folder>js</folder>
|
||||
</media>
|
||||
<administration>
|
||||
<files folder="admin">
|
||||
<filename>access.xml</filename>
|
||||
<filename>config.xml</filename>
|
||||
<filename>templates.xml</filename>
|
||||
<folder>forms</folder>
|
||||
<folder>helpers</folder>
|
||||
<folder>services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
<languages folder="admin">
|
||||
<language tag="en-GB">language/en-GB/com_templates.ini</language>
|
||||
<language tag="en-GB">language/en-GB/com_templates.sys.ini</language>
|
||||
</languages>
|
||||
</administration>
|
||||
</extension>
|
||||
|
||||
116
administrator/components/com_templates/tmpl/style/edit.php
Normal file
116
administrator/components/com_templates/tmpl/style/edit.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('keepalive')
|
||||
->useScript('form.validate');
|
||||
|
||||
$this->useCoreUI = true;
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&layout=edit&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="style-form" aria-label="<?php echo Text::_('COM_TEMPLATES_STYLE_FORM_EDIT'); ?>" class="form-validate">
|
||||
|
||||
<?php echo LayoutHelper::render('joomla.edit.title_alias', $this); ?>
|
||||
|
||||
<div class="main-card">
|
||||
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'details', 'recall' => true, 'breakpoint' => 768]); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'details', Text::_('JDETAILS')); ?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
<h2>
|
||||
<?php echo Text::_($this->item->template); ?>
|
||||
</h2>
|
||||
<div class="info-labels">
|
||||
<span class="badge bg-secondary">
|
||||
<?php echo $this->item->client_id == 0 ? Text::_('JSITE') : Text::_('JADMINISTRATOR'); ?>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p><?php echo Text::_($this->item->xml->description); ?></p>
|
||||
<?php
|
||||
$this->fieldset = 'description';
|
||||
$description = LayoutHelper::render('joomla.edit.fieldset', $this);
|
||||
?>
|
||||
<?php if ($description) : ?>
|
||||
<p class="readmore">
|
||||
<a href="#" onclick="document.querySelector('#tab-description').click();">
|
||||
<?php echo Text::_('JGLOBAL_SHOW_FULL_DESCRIPTION'); ?>
|
||||
</a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
$this->fieldset = 'basic';
|
||||
$html = LayoutHelper::render('joomla.edit.fieldset', $this);
|
||||
echo $html ? '<hr>' . $html : '';
|
||||
?>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
<?php
|
||||
// Set main fields.
|
||||
$this->fields = [
|
||||
'home',
|
||||
'client_id',
|
||||
'template'
|
||||
];
|
||||
?>
|
||||
<?php echo LayoutHelper::render('joomla.edit.global', $this); ?>
|
||||
<?php echo $this->form->renderField('inheritable'); ?>
|
||||
<?php echo $this->form->renderField('parent'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
|
||||
<?php if ($description) : ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'description', Text::_('JGLOBAL_FIELDSET_DESCRIPTION')); ?>
|
||||
<fieldset id="fieldset-description" class="options-form">
|
||||
<legend><?php echo Text::_('JGLOBAL_FIELDSET_DESCRIPTION'); ?></legend>
|
||||
<div>
|
||||
<?php echo $description; ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$this->fieldsets = [];
|
||||
$this->ignore_fieldsets = ['basic', 'description'];
|
||||
echo LayoutHelper::render('joomla.edit.params', $this);
|
||||
?>
|
||||
|
||||
<?php if ($user->authorise('core.edit', 'com_menus') && $this->item->client_id == 0 && $this->canDo->get('core.edit.state')) : ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'assignment', Text::_('COM_TEMPLATES_MENUS_ASSIGNMENT')); ?>
|
||||
<fieldset id="fieldset-assignment" class="options-form">
|
||||
<legend><?php echo Text::_('COM_TEMPLATES_MENUS_ASSIGNMENT'); ?></legend>
|
||||
<div>
|
||||
<?php echo $this->loadTemplate('assignment'); ?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\Component\Menus\Administrator\Helper\MenusHelper;
|
||||
|
||||
// Initialise related data.
|
||||
$menuTypes = MenusHelper::getMenuLinks();
|
||||
$user = $this->getCurrentUser();
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('com_templates.admin-template-toggle-assignment');
|
||||
|
||||
?>
|
||||
<label id="jform_menuselect-lbl" for="jform_menuselect"><?php echo Text::_('JGLOBAL_MENU_SELECTION'); ?></label>
|
||||
<div class="btn-toolbar">
|
||||
<button class="btn btn-sm btn-secondary jform-rightbtn" type="button" onclick="Joomla.toggleAll()">
|
||||
<span class="icon-square" aria-hidden="true"></span> <?php echo Text::_('JGLOBAL_SELECTION_INVERT_ALL'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="menu-assignment" class="menu-assignment">
|
||||
<ul class="menu-links">
|
||||
|
||||
<?php foreach ($menuTypes as &$type) : ?>
|
||||
<li>
|
||||
<div class="menu-links-block">
|
||||
<button class="btn btn-sm btn-secondary jform-rightbtn mb-2" type="button" onclick='Joomla.toggleMenutype("<?php echo $type->menutype; ?>")'>
|
||||
<span class="icon-square" aria-hidden="true"></span> <?php echo Text::_('JGLOBAL_SELECTION_INVERT'); ?>
|
||||
</button>
|
||||
<h5><?php echo $type->title ?: $type->menutype; ?></h5>
|
||||
|
||||
<?php foreach ($type->links as $link) : ?>
|
||||
<label class="checkbox small" for="link<?php echo (int) $link->value; ?>" >
|
||||
<input type="checkbox" name="jform[assigned][]" value="<?php echo (int) $link->value; ?>" id="link<?php echo (int) $link->value; ?>"<?php if ($link->template_style_id == $this->item->id) :
|
||||
?> checked="checked"<?php
|
||||
endif; ?><?php if ($link->checked_out && $link->checked_out != $user->id) :
|
||||
?> disabled="disabled"<?php
|
||||
else :
|
||||
?> class="form-check-input chk-menulink menutype-<?php echo $type->menutype; ?>"<?php
|
||||
endif; ?> />
|
||||
<?php echo LayoutHelper::render('joomla.html.treeprefix', ['level' => $link->level]) . $link->text; ?>
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</div>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
153
administrator/components/com_templates/tmpl/styles/default.php
Normal file
153
administrator/components/com_templates/tmpl/styles/default.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('table.columns')
|
||||
->useScript('multiselect');
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
$clientId = (int) $this->state->get('client_id', 0);
|
||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||
?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=styles'); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="j-main-container" class="j-main-container">
|
||||
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this, 'options' => ['selectorFieldName' => 'client_id']]); ?>
|
||||
<?php if ($this->total > 0) : ?>
|
||||
<table class="table" id="styleList">
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_TEMPLATES_STYLES_TABLE_CAPTION'); ?>,
|
||||
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
|
||||
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('grid.checkall'); ?>
|
||||
</td>
|
||||
<th scope="col">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_TEMPLATES_HEADING_STYLE', 'a.title', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-5 text-center">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_PREVIEW'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-12 text-center">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_TEMPLATES_HEADING_DEFAULT', 'a.home', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<?php if ($clientId === 0) : ?>
|
||||
<th scope="col" class="w-12 d-none d-md-table-cell">
|
||||
<?php echo Text::_('COM_TEMPLATES_HEADING_PAGES'); ?>
|
||||
</th>
|
||||
<?php endif; ?>
|
||||
<th scope="col" class="w-12 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_TEMPLATES_HEADING_TEMPLATE', 'a.template', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-5 d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($this->items as $i => $item) :
|
||||
$canCreate = $user->authorise('core.create', 'com_templates');
|
||||
$canEdit = $user->authorise('core.edit', 'com_templates');
|
||||
$canChange = $user->authorise('core.edit.state', 'com_templates');
|
||||
?>
|
||||
<tr class="row<?php echo $i % 2; ?>">
|
||||
<td class="w-1 text-center">
|
||||
<?php echo HTMLHelper::_('grid.id', $i, $item->id, false, 'cid', 'cb', $item->title); ?>
|
||||
</td>
|
||||
<th scope="row">
|
||||
<?php if ($canEdit) : ?>
|
||||
<a href="<?php echo Route::_('index.php?option=com_templates&task=style.edit&id=' . (int) $item->id); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?> <?php echo $this->escape($item->title); ?>">
|
||||
<?php echo $this->escape($item->title); ?></a>
|
||||
<?php else : ?>
|
||||
<?php echo $this->escape($item->title); ?>
|
||||
<?php endif; ?>
|
||||
</th>
|
||||
<td class="text-center">
|
||||
<?php if ($this->preview) : ?>
|
||||
<?php $client = (int) $item->client_id === 1 ? 'administrator' : 'site'; ?>
|
||||
<!-- external link icon generated by css -->
|
||||
<a href="<?php echo Route::link($client, 'index.php?tp=1&templateStyle=' . (int) $item->id); ?>" target="_blank" class="jgrid" aria-labelledby="preview-<?php echo (int) $item->id; ?>"></a>
|
||||
<div role="tooltip" id="preview-<?php echo (int) $item->id; ?>"><?php echo Text::sprintf('COM_TEMPLATES_TEMPLATE_NEW_PREVIEW', $item->title); ?></div>
|
||||
<?php else : ?>
|
||||
<span class="icon-eye-slash" aria-labelledby="nopreview-<?php echo (int) $item->id; ?>" aria-hidden="true"></span>
|
||||
<div role="tooltip" id="nopreview-<?php echo (int) $item->id; ?>"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_NO_PREVIEW'); ?></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<?php if ($item->home == '0' || $item->home == '1') : ?>
|
||||
<?php echo HTMLHelper::_('jgrid.isdefault', $item->home != '0', $i, 'styles.', $canChange && $item->home != '1'); ?>
|
||||
<?php elseif ($canChange) :?>
|
||||
<a href="<?php echo Route::_('index.php?option=com_templates&task=styles.unsetDefault&cid[]=' . $item->id . '&' . Session::getFormToken() . '=1'); ?>">
|
||||
<?php if ($item->image) : ?>
|
||||
<?php echo HTMLHelper::_('image', 'mod_languages/' . $item->image . '.gif', $item->language_title, ['title' => Text::sprintf('COM_TEMPLATES_GRID_UNSET_LANGUAGE', $item->language_title)], true); ?>
|
||||
<?php else : ?>
|
||||
<span class="badge bg-secondary" title="<?php echo Text::sprintf('COM_TEMPLATES_GRID_UNSET_LANGUAGE', $item->language_title); ?>"><?php echo $item->home; ?></span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<?php if ($item->image) : ?>
|
||||
<?php echo HTMLHelper::_('image', 'mod_languages/' . $item->image . '.gif', $item->language_title, ['title' => $item->language_title], true); ?>
|
||||
<?php else : ?>
|
||||
<span class="badge bg-secondary" title="<?php echo $item->language_title; ?>"><?php echo $item->home; ?></span>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php if ($clientId === 0) : ?>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<?php if ($item->home == '1') : ?>
|
||||
<?php echo Text::_('COM_TEMPLATES_STYLES_PAGES_ALL'); ?>
|
||||
<?php elseif ($item->home != '0' && $item->home != '1') : ?>
|
||||
<?php echo Text::sprintf('COM_TEMPLATES_STYLES_PAGES_ALL_LANGUAGE', $this->escape($item->language_title)); ?>
|
||||
<?php elseif ($item->assigned > 0) : ?>
|
||||
<?php echo Text::plural('COM_TEMPLATES_STYLES_PAGES_SELECTED', $this->escape($item->assigned)); ?>
|
||||
<?php else : ?>
|
||||
<?php echo Text::_('COM_TEMPLATES_STYLES_PAGES_NONE'); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
<td class="small d-none d-md-table-cell">
|
||||
<a href="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . (int) $item->e_id); ?>">
|
||||
<?php echo ucfirst($this->escape($item->template)); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td class="d-none d-md-table-cell">
|
||||
<?php echo (int) $item->id; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php // load the pagination. ?>
|
||||
<?php echo $this->pagination->getListFooter(); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_TEMPLATES_STYLE_VIEW_DEFAULT_TITLE">
|
||||
<message>
|
||||
<![CDATA[COM_TEMPLATES_STYLE_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
475
administrator/components/com_templates/tmpl/template/default.php
Normal file
475
administrator/components/com_templates/tmpl/template/default.php
Normal file
@ -0,0 +1,475 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Jfcherng\Diff\DiffHelper;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Session\Session;
|
||||
|
||||
HTMLHelper::_('behavior.multiselect', 'updateForm');
|
||||
HTMLHelper::_('bootstrap.modal');
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$input = Factory::getApplication()->getInput();
|
||||
|
||||
// Enable assets
|
||||
$wa->useScript('form.validate')
|
||||
->useScript('keepalive')
|
||||
->useScript('com_templates.admin-template-toggle-switch')
|
||||
->useScript('com_templates.admin-templates')
|
||||
->useStyle('com_templates.admin-templates');
|
||||
|
||||
// No access if not global SuperUser
|
||||
if (!$this->getCurrentUser()->authorise('core.admin')) {
|
||||
Factory::getApplication()->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'danger');
|
||||
}
|
||||
|
||||
if ($this->type == 'image') {
|
||||
$wa->usePreset('cropperjs');
|
||||
}
|
||||
|
||||
if ($this->type == 'font') {
|
||||
$wa->addInlineStyle("
|
||||
@font-face {
|
||||
font-family: previewFont;
|
||||
src: url('" . $this->font['address'] . "')
|
||||
}
|
||||
.font-preview {
|
||||
font-family: previewFont !important;
|
||||
}
|
||||
");
|
||||
}
|
||||
?>
|
||||
<div class="main-card">
|
||||
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'editor', 'recall' => true, 'breakpoint' => 768]); ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'editor', Text::_('COM_TEMPLATES_TAB_EDITOR')); ?>
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-8" id="conditional-section">
|
||||
<?php if ($this->type != 'home') : ?>
|
||||
<p class="lead"><?php echo Text::sprintf('COM_TEMPLATES_TEMPLATE_FILENAME', '‎' . ($input->get('isMedia', 0) ? '/media/templates/' . ($this->template->client_id === 0 ? 'site' : 'administrator') . '/' . $this->template->element . str_replace('//', '/', base64_decode($this->file)) : '/' . ($this->template->client_id === 0 ? '' : 'administrator/') . 'templates/' . $this->template->element . str_replace('//', '/', base64_decode($this->file))), $this->template->element); ?></p>
|
||||
<p class="lead path hidden"><?php echo $this->source->filename; ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($this->type == 'file' && !empty($this->source->coreFile)) : ?>
|
||||
<div class="col-md-4 text-end">
|
||||
<div id="toggle-buttons">
|
||||
<?php echo $this->form->renderField('show_core'); ?>
|
||||
<?php echo $this->form->renderField('show_diff'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div id="treeholder" class="col-md-3 tree-holder">
|
||||
<div class="mt-2 mb-2">
|
||||
<ul class="directory-tree treeselect">
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="" href="">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php echo ($this->template->client_id === 0 ? '/' : '/administrator/') . 'templates/' . $this->template->element; ?>
|
||||
</a>
|
||||
<?php echo $this->loadTemplate('tree'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
<?php if (count($this->mediaFiles)) : ?>
|
||||
<ul class="directory-tree treeselect">
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="" href="">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php echo '/media/templates/' . ($this->template->client_id === 0 ? 'site/' : 'administrator/') . $this->template->element; ?>
|
||||
</a>
|
||||
<?php echo $this->loadTemplate('tree_media'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<fieldset class="options-form">
|
||||
<?php if ($this->type == 'home') : ?>
|
||||
<legend><?php echo Text::_('COM_TEMPLATES_HOME_HEADING'); ?></legend>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0)); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
<p><?php echo Text::_('COM_TEMPLATES_HOME_TEXT'); ?></p>
|
||||
<p>
|
||||
<a href="https://docs.joomla.org/Special:MyLanguage/J4.x:Template_Overrides" target="_blank" rel="noopener" class="btn btn-primary btn-lg">
|
||||
<?php echo Text::_('COM_TEMPLATES_HOME_BUTTON'); ?>
|
||||
</a>
|
||||
</p>
|
||||
</form>
|
||||
<?php elseif ($this->type == 'file') : ?>
|
||||
<div class="row">
|
||||
<div class="col-md-12" id="override-pane">
|
||||
<?php $overrideCheck = explode(DIRECTORY_SEPARATOR, $this->source->filename); ?>
|
||||
<?php if (!empty($this->source->coreFile)) : ?>
|
||||
<h2><?php echo Text::_('COM_TEMPLATES_FILE_OVERRIDE_PANE'); ?></h2>
|
||||
<?php endif; ?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0)); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<input type="hidden" name="isMedia" value="<?php echo $input->get('isMedia', 0); ?>">
|
||||
<div class="editor-border">
|
||||
<?php echo $this->form->getInput('source'); ?>
|
||||
</div>
|
||||
<input type="hidden" name="task" value="" />
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
<?php echo $this->form->getInput('extension_id'); ?>
|
||||
<?php echo $this->form->getInput('filename'); ?>
|
||||
</form>
|
||||
</div>
|
||||
<?php if (!empty($this->source->coreFile)) : ?>
|
||||
<div class="col-md-12" id="core-pane">
|
||||
<h2><?php echo Text::_('COM_TEMPLATES_FILE_CORE_PANE'); ?></h2>
|
||||
<div class="editor-border">
|
||||
<?php echo $this->form->getInput('core'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$difference = DiffHelper::calculateFiles(
|
||||
$this->source->coreFile,
|
||||
$this->source->filePath,
|
||||
ComponentHelper::getParams('com_templates')->get('difference', 'SideBySide'),
|
||||
[
|
||||
'context' => 1,
|
||||
'ignoreLineEnding' => true,
|
||||
],
|
||||
[
|
||||
'language' => [
|
||||
'old_version' => Text::_('COM_TEMPLATES_DIFF_CORE'),
|
||||
'new_version' => Text::_('COM_TEMPLATES_DIFF_OVERRIDE'),
|
||||
'differences' => Text::_('COM_TEMPLATES_DIFF_DIFFERENCES'),
|
||||
],
|
||||
'resultForIdenticals' => Text::_('COM_TEMPLATES_DIFF_IDENTICAL'),
|
||||
'detailLevel' => 'word',
|
||||
'spaceToHtmlTag' => true,
|
||||
'wrapperClasses' => ['diff-wrapper', 'columns-order-ignore'],
|
||||
]
|
||||
);
|
||||
?>
|
||||
<div class="col-md-12" id="diff-main">
|
||||
<h2><?php echo Text::_('COM_TEMPLATES_FILE_COMPARE_PANE'); ?></h2>
|
||||
<div class="diff-pane">
|
||||
<div id="diff"><?php echo $difference; ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php elseif ($this->type == 'archive') : ?>
|
||||
<legend><?php echo Text::_('COM_TEMPLATES_FILE_CONTENT_PREVIEW'); ?></legend>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0)); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<ul class="nav flex-column well">
|
||||
<?php foreach ($this->archive as $file) : ?>
|
||||
<li>
|
||||
<?php if (substr($file, -1) === DIRECTORY_SEPARATOR) : ?>
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span> <?php echo $file; ?>
|
||||
<?php endif; ?>
|
||||
<?php if (substr($file, -1) != DIRECTORY_SEPARATOR) : ?>
|
||||
<span class="icon-file icon-fw" aria-hidden="true"></span> <?php echo $file; ?>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
<?php elseif ($this->type == 'image') : ?>
|
||||
<legend><?php echo $this->escape(basename($this->image['address'])); ?></legend>
|
||||
<img id="image-crop" src="<?php echo $this->image['address'] . '?' . time(); ?>" style="max-width: 100%">
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0)); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<fieldset class="adminform">
|
||||
<input type="hidden" id="x" name="x">
|
||||
<input type="hidden" id="y" name="y">
|
||||
<input type="hidden" id="h" name="h">
|
||||
<input type="hidden" id="w" name="w">
|
||||
<input type="hidden" id="imageWidth" value="<?php echo $this->image['width']; ?>">
|
||||
<input type="hidden" id="imageHeight" value="<?php echo $this->image['height']; ?>">
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</fieldset>
|
||||
</form>
|
||||
<?php elseif ($this->type == 'font') : ?>
|
||||
<div class="font-preview">
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0)); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<fieldset class="adminform">
|
||||
<h1>H1. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</h1>
|
||||
<h2>H2. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</h2>
|
||||
<h3>H3. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</h3>
|
||||
<h4>H4. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</h4>
|
||||
<h5>H5. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</h5>
|
||||
<h6>H6. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</h6>
|
||||
<p><strong>Bold. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</strong></p>
|
||||
<p><em>Italics. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML</em></p>
|
||||
<p>Unordered List</p>
|
||||
<ul>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
<li>Item<br>
|
||||
<ul>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
<li>Item<br>
|
||||
<ul>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="lead">Ordered List</p>
|
||||
<ol>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
<li>Item<br>
|
||||
<ul>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
<li>Item<br>
|
||||
<ul>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
<li>Item</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'overrides', Text::_('COM_TEMPLATES_TAB_OVERRIDES')); ?>
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-3">
|
||||
<fieldset class="options-form">
|
||||
<legend><?php echo Text::_('COM_TEMPLATES_OVERRIDES_MODULES'); ?></legend>
|
||||
<ul class="list-unstyled">
|
||||
<?php $token = Session::getFormToken() . '=' . 1; ?>
|
||||
<?php foreach ($this->overridesList['modules'] as $module) : ?>
|
||||
<li>
|
||||
<?php
|
||||
$overrideLinkUrl = 'index.php?option=com_templates&view=template&task=template.overrides&folder=' . $module->path
|
||||
. '&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0) . '&' . $token;
|
||||
?>
|
||||
<a href="<?php echo Route::_($overrideLinkUrl); ?>">
|
||||
<span class="icon-copy" aria-hidden="true"></span> <?php echo $module->name; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<fieldset class="options-form">
|
||||
<legend><?php echo Text::_('COM_TEMPLATES_OVERRIDES_COMPONENTS'); ?></legend>
|
||||
<ul class="list-unstyled">
|
||||
<?php $token = Session::getFormToken() . '=' . 1; ?>
|
||||
<?php foreach ($this->overridesList['components'] as $key => $value) : ?>
|
||||
<li class="component-folder">
|
||||
<a href="#" class="component-folder-url">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span> <?php echo $key; ?>
|
||||
</a>
|
||||
<ul class="list-unstyled">
|
||||
<?php foreach ($value as $view) : ?>
|
||||
<li>
|
||||
<?php
|
||||
$overrideLinkUrl = 'index.php?option=com_templates&view=template&task=template.overrides&folder=' . $view->path
|
||||
. '&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0) . '&' . $token;
|
||||
?>
|
||||
<a class="component-file-url" href="<?php echo Route::_($overrideLinkUrl); ?>">
|
||||
<span class="icon-copy" aria-hidden="true"></span> <?php echo $view->name; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<fieldset class="options-form">
|
||||
<legend><?php echo Text::_('COM_TEMPLATES_OVERRIDES_PLUGINS'); ?></legend>
|
||||
<ul class="list-unstyled">
|
||||
<?php $token = Session::getFormToken() . '=' . 1; ?>
|
||||
<?php foreach ($this->overridesList['plugins'] as $key => $group) : ?>
|
||||
<li class="plugin-folder">
|
||||
<a href="#" class="plugin-folder-url">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span> <?php echo $key; ?>
|
||||
</a>
|
||||
<ul class="list-unstyled">
|
||||
<?php foreach ($group as $plugin) : ?>
|
||||
<li>
|
||||
<?php
|
||||
$overrideLinkUrl = 'index.php?option=com_templates&view=template&task=template.overrides&folder=' . $plugin->path
|
||||
. '&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0) . '&' . $token;
|
||||
?>
|
||||
<a class="plugin-file-url" href="<?php echo Route::_($overrideLinkUrl); ?>">
|
||||
<span class="icon-copy" aria-hidden="true"></span> <?php echo $plugin->name; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<fieldset class="options-form">
|
||||
<legend><?php echo Text::_('COM_TEMPLATES_OVERRIDES_LAYOUTS'); ?></legend>
|
||||
<ul class="list-unstyled">
|
||||
<?php $token = Session::getFormToken() . '=' . 1; ?>
|
||||
<?php foreach ($this->overridesList['layouts'] as $key => $value) : ?>
|
||||
<li class="layout-folder">
|
||||
<a href="#" class="layout-folder-url">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span> <?php echo $key; ?>
|
||||
</a>
|
||||
<ul class="list-unstyled">
|
||||
<?php foreach ($value as $layout) : ?>
|
||||
<li>
|
||||
<?php
|
||||
$overrideLinkUrl = 'index.php?option=com_templates&view=template&task=template.overrides&folder=' . $layout->path
|
||||
. '&id=' . $input->getInt('id') . '&file=' . $this->file . '&' . $token . '&isMedia=' . $input->get('isMedia', 0);
|
||||
?>
|
||||
<a href="<?php echo Route::_($overrideLinkUrl); ?>">
|
||||
<span class="icon-copy" aria-hidden="true"></span> <?php echo $layout->name; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
|
||||
<?php if ($this->pluginState) : ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'files', Text::_('COM_TEMPLATES_TAB_UPDATED_FILES')); ?>
|
||||
<?php echo $this->loadTemplate('updated_files'); ?>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'description', Text::_('COM_TEMPLATES_TAB_DESCRIPTION')); ?>
|
||||
<div class="row mt-2">
|
||||
<div class="col-12">
|
||||
<?php echo $this->loadTemplate('description'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
|
||||
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
|
||||
|
||||
<?php // Collapse Modal
|
||||
$taskName = isset($this->template->xmldata->inheritable) && (string) $this->template->xmldata->inheritable === '1' ? 'child' : 'copy';
|
||||
$copyModalData = [
|
||||
'selector' => $taskName . 'Modal',
|
||||
'params' => [
|
||||
'title' => Text::_('COM_TEMPLATES_TEMPLATE_' . strtoupper($taskName)),
|
||||
'footer' => $this->loadTemplate('modal_' . $taskName . '_footer')
|
||||
],
|
||||
'body' => $this->loadTemplate('modal_' . $taskName . '_body')
|
||||
];
|
||||
?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&task=template.' . $taskName . '&id=' . $input->getInt('id') . '&file=' . $this->file); ?>" method="post">
|
||||
<?php echo LayoutHelper::render('libraries.html.bootstrap.modal.main', $copyModalData); ?>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
<?php if ($this->type != 'home') : ?>
|
||||
<?php // Rename Modal
|
||||
$renameModalData = [
|
||||
'selector' => 'renameModal',
|
||||
'params' => [
|
||||
'title' => Text::sprintf('COM_TEMPLATES_RENAME_FILE', str_replace('//', '/', $this->fileName)),
|
||||
'footer' => $this->loadTemplate('modal_rename_footer')
|
||||
],
|
||||
'body' => $this->loadTemplate('modal_rename_body')
|
||||
];
|
||||
?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&task=template.renameFile&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0)); ?>" method="post">
|
||||
<?php echo LayoutHelper::render('libraries.html.bootstrap.modal.main', $renameModalData); ?>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php if ($this->type != 'home') : ?>
|
||||
<?php // Delete Modal
|
||||
$deleteModalData = [
|
||||
'selector' => 'deleteModal',
|
||||
'params' => [
|
||||
'title' => Text::_('COM_TEMPLATES_ARE_YOU_SURE'),
|
||||
'footer' => $this->loadTemplate('modal_delete_footer')
|
||||
],
|
||||
'body' => $this->loadTemplate('modal_delete_body')
|
||||
];
|
||||
?>
|
||||
<?php echo LayoutHelper::render('libraries.html.bootstrap.modal.main', $deleteModalData); ?>
|
||||
<?php endif; ?>
|
||||
<?php // File Modal
|
||||
$fileModalData = [
|
||||
'selector' => 'fileModal',
|
||||
'params' => [
|
||||
'title' => Text::_('COM_TEMPLATES_NEW_FILE_HEADER'),
|
||||
'footer' => $this->loadTemplate('modal_file_footer'),
|
||||
'height' => '400px',
|
||||
'width' => '800px',
|
||||
'bodyHeight' => 70,
|
||||
'modalWidth' => 80,
|
||||
],
|
||||
'body' => $this->loadTemplate('modal_file_body')
|
||||
];
|
||||
?>
|
||||
<?php echo LayoutHelper::render('libraries.html.bootstrap.modal.main', $fileModalData); ?>
|
||||
<?php // Folder Modal
|
||||
$folderModalData = [
|
||||
'selector' => 'folderModal',
|
||||
'params' => [
|
||||
'title' => Text::_('COM_TEMPLATES_MANAGE_FOLDERS'),
|
||||
'footer' => $this->loadTemplate('modal_folder_footer'),
|
||||
'height' => '400px',
|
||||
'width' => '800px',
|
||||
'bodyHeight' => 70,
|
||||
'modalWidth' => 80,
|
||||
],
|
||||
'body' => $this->loadTemplate('modal_folder_body')
|
||||
];
|
||||
?>
|
||||
<?php echo LayoutHelper::render('libraries.html.bootstrap.modal.main', $folderModalData); ?>
|
||||
<?php if ($this->type == 'image') : ?>
|
||||
<?php // Resize Modal
|
||||
$resizeModalData = [
|
||||
'selector' => 'resizeModal',
|
||||
'params' => [
|
||||
'title' => Text::_('COM_TEMPLATES_RESIZE_IMAGE'),
|
||||
'footer' => $this->loadTemplate('modal_resize_footer')
|
||||
],
|
||||
'body' => $this->loadTemplate('modal_resize_body')
|
||||
];
|
||||
?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&task=template.resizeImage&id=' . $input->getInt('id') . '&file=' . $this->file . '&isMedia=' . $input->get('isMedia', 0)); ?>" method="post">
|
||||
<?php echo LayoutHelper::render('libraries.html.bootstrap.modal.main', $resizeModalData); ?>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Application\ApplicationHelper;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\Component\Templates\Administrator\Helper\TemplatesHelper;
|
||||
|
||||
?>
|
||||
|
||||
<div class="clearfix">
|
||||
<div class="float-start me-3 text-center">
|
||||
<?php echo HTMLHelper::_('templates.thumb', $this->template); ?>
|
||||
<?php echo HTMLHelper::_('templates.thumbModal', $this->template); ?>
|
||||
</div>
|
||||
<h2><?php echo ucfirst($this->template->element); ?></h2>
|
||||
<?php $client = ApplicationHelper::getClientInfo($this->template->client_id); ?>
|
||||
<p><?php $this->template->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $this->template->element); ?></p>
|
||||
<p><?php echo Text::_($this->template->xmldata->get('description')); ?></p>
|
||||
</div>
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
ksort($this->files, SORT_STRING);
|
||||
?>
|
||||
|
||||
<ul class="directory-tree treeselect">
|
||||
<?php foreach ($this->files as $key => $value) : ?>
|
||||
<?php if (is_array($value)) : ?>
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="<?php echo base64_encode($key); ?>" href="" data-base="template">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php $explodeArray = explode('/', rtrim($key, '\\'));
|
||||
echo $this->escape(end($explodeArray)); ?>
|
||||
</a>
|
||||
<?php echo $this->folderTree($value); ?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
// Legacy is the default
|
||||
if (!count($this->mediaFiles)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ksort($this->mediaFiles, SORT_STRING);
|
||||
?>
|
||||
<ul class="directory-tree treeselect">
|
||||
<?php foreach ($this->mediaFiles as $key => $value) : ?>
|
||||
<?php if (is_array($value)) : ?>
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="<?php echo base64_encode($key); ?>" href="" data-base="media">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php $explodeArray = explode('/', rtrim($key, '\\'));
|
||||
echo $this->escape(end($explodeArray)); ?>
|
||||
</a>
|
||||
<?php echo $this->mediaFolderTree($value); ?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
|
||||
Factory::getDocument()->getWebAssetManager()->usePreset('choicesjs');
|
||||
|
||||
// Generate a list of styles for the child creation modal
|
||||
$options = [];
|
||||
|
||||
if (count($this->styles) > 0) {
|
||||
foreach ($this->styles as $style) {
|
||||
$options[] = HTMLHelper::_('select.option', $style->id, $style->title, 'value', 'text');
|
||||
}
|
||||
}
|
||||
|
||||
$fancySelectData = [
|
||||
'autocomplete' => 'off',
|
||||
'autofocus' => false,
|
||||
'class' => '',
|
||||
'description' => '',
|
||||
'disabled' => false,
|
||||
'group' => false,
|
||||
'id' => 'style_ids',
|
||||
'hidden' => false,
|
||||
'hint' => '',
|
||||
'label' => '',
|
||||
'labelclass' => '',
|
||||
'onchange' => '',
|
||||
'onclick' => '',
|
||||
'multiple' => true,
|
||||
'pattern' => '',
|
||||
'readonly' => false,
|
||||
'repeat' => false,
|
||||
'required' => false,
|
||||
'size' => 4,
|
||||
'spellcheck' => false,
|
||||
'validate' => '',
|
||||
'value' => '0',
|
||||
'options' => $options,
|
||||
'dataAttributes' => [],
|
||||
'dataAttribute' => '',
|
||||
'name' => 'style_ids[]',
|
||||
];
|
||||
?>
|
||||
<div id="template-manager-copy" class="container-fluid">
|
||||
<div class="mt-2">
|
||||
<div class="col-md-12">
|
||||
<div class="control-group">
|
||||
<div class="control-label">
|
||||
<label for="new_name">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_CHILD_NAME_LABEL'); ?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<input class="form-control" type="text" id="new_name" name="new_name" required>
|
||||
<small class="form-text">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_NEW_NAME_DESC'); ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="control-label">
|
||||
<label for="style_ids">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_CHILD_STYLE_LABEL'); ?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<?php echo LayoutHelper::render('joomla.form.field.list-fancy-select', $fancySelectData); ?>
|
||||
<small class="form-text">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_NEW_STYLE_DESC'); ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_CLOSE'); ?></button>
|
||||
<button type="submit" class="btn btn-primary"><?php echo Text::_('COM_TEMPLATES_BUTTON_TEMPLATE_CHILD'); ?></button>
|
||||
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<div id="template-manager-copy" class="container-fluid">
|
||||
<div class="mt-2">
|
||||
<div class="col-md-12">
|
||||
<div class="control-group">
|
||||
<div class="control-label">
|
||||
<label for="new_name">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_NEW_NAME_LABEL'); ?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<input class="form-control" type="text" id="new_name" name="new_name" required>
|
||||
<small class="form-text">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_NEW_NAME_DESC'); ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_CLOSE'); ?></button>
|
||||
<button type="submit" class="btn btn-primary"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_COPY'); ?></button>
|
||||
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<div id="template-manager-delete" class="container-fluid">
|
||||
<div class="mt-2">
|
||||
<div class="col-md-12">
|
||||
<p><?php echo Text::sprintf('COM_TEMPLATES_MODAL_FILE_DELETE', str_replace('//', '/', $this->fileName)); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
$input = Factory::getApplication()->getInput();
|
||||
?>
|
||||
<form method="post" action="">
|
||||
<input type="hidden" name="option" value="com_templates">
|
||||
<input type="hidden" name="task" value="template.delete">
|
||||
<input type="hidden" name="id" value="<?php echo $input->getInt('id'); ?>">
|
||||
<input type="hidden" name="file" value="<?php echo $this->file; ?>">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_CLOSE'); ?></button>
|
||||
<button type="submit" class="btn btn-danger"><?php echo Text::_('COM_TEMPLATES_BUTTON_DELETE'); ?></button>
|
||||
</form>
|
||||
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use Joomla\CMS\Utility\Utility;
|
||||
|
||||
$input = Factory::getApplication()->getInput();
|
||||
?>
|
||||
<div id="#template-manager-file" class="container-fluid">
|
||||
<div class="mt-2 p-2">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="tree-holder">
|
||||
<ul class="directory-tree treeselect root">
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="" href="" data-base="template">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php echo ($this->template->client_id === 0 ? '/' : '/administrator/') . 'templates/' . $this->template->element; ?>
|
||||
</a>
|
||||
<?php echo $this->loadTemplate('folders'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
<?php if (count($this->mediaFiles)) : ?>
|
||||
<ul class="directory-tree treeselect">
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="" href="" data-base="media">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php echo '/media/templates/' . ($this->template->client_id === 0 ? 'site/' : 'administrator/') . $this->template->element; ?>
|
||||
</a>
|
||||
<?php echo $this->loadTemplate('media_folders'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<form method="post" action="<?php echo Route::_('index.php?option=com_templates&task=template.createFile&id=' . $input->getInt('id') . '&file=' . $this->file); ?>" class="mb-4">
|
||||
<div class="form-group">
|
||||
<label for="file_name"><?php echo Text::_('COM_TEMPLATES_FILE_NAME'); ?></label>
|
||||
<input type="text" name="name" id="file_name" class="form-control" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="type"><?php echo Text::_('COM_TEMPLATES_NEW_FILE_TYPE'); ?></label>
|
||||
<select class="form-select" data-chosen="true" name="type" id="type" required>
|
||||
<option value="">- <?php echo Text::_('COM_TEMPLATES_NEW_FILE_SELECT'); ?> -</option>
|
||||
<option value="css">.css</option>
|
||||
<option value="php">.php</option>
|
||||
<option value="js">.js</option>
|
||||
<option value="xml">.xml</option>
|
||||
<option value="ini">.ini</option>
|
||||
<option value="less">.less</option>
|
||||
<option value="sass">.sass</option>
|
||||
<option value="scss">.scss</option>
|
||||
<option value="txt">.txt</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="hidden" class="address" name="address">
|
||||
<input type="hidden" name="isMedia" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
<button type="submit" class="btn btn-primary"><?php echo Text::_('COM_TEMPLATES_BUTTON_CREATE'); ?></button>
|
||||
</form>
|
||||
<hr class="mb-4">
|
||||
<form method="post" action="<?php echo Route::_('index.php?option=com_templates&task=template.uploadFile&id=' . $input->getInt('id') . '&file=' . $this->file); ?>" enctype="multipart/form-data" class="mb-4">
|
||||
<input type="hidden" class="address" name="address">
|
||||
<input type="hidden" name="isMedia" value="0">
|
||||
<div class="input-group">
|
||||
<input type="file" name="files" aria-labelledby="upload" class="form-control" required>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
<button type="submit" class="btn btn-primary" id="upload"><?php echo Text::_('COM_TEMPLATES_BUTTON_UPLOAD'); ?></button>
|
||||
</div>
|
||||
<?php $cMax = $this->state->get('params')->get('upload_limit'); ?>
|
||||
<?php $maxSize = HTMLHelper::_('number.bytes', Utility::getMaxUploadSize($cMax . 'MB')); ?>
|
||||
<span class="mt-2"><?php echo Text::sprintf('JGLOBAL_MAXIMUM_UPLOAD_SIZE_LIMIT', '‎' . $maxSize); ?></span>
|
||||
</form>
|
||||
<?php if ($this->type != 'home') : ?>
|
||||
<hr class="mb-4">
|
||||
<form method="post" action="<?php echo Route::_('index.php?option=com_templates&task=template.copyFile&id=' . $input->getInt('id') . '&file=' . $this->file); ?>" enctype="multipart/form-data" class="mb-4">
|
||||
<div class="form-group">
|
||||
<input type="hidden" class="address" name="address">
|
||||
<input type="hidden" name="isMedia" value="0">
|
||||
<label for="new_name">
|
||||
<?php echo Text::_('COM_TEMPLATES_FILE_NEW_NAME_LABEL') ?>
|
||||
</label>
|
||||
<input class="form-control" type="text" id="new_name" name="new_name" required>
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><?php echo Text::_('COM_TEMPLATES_BUTTON_COPY_FILE'); ?></button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_CLOSE'); ?></button>
|
||||
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
$input = Factory::getApplication()->getInput();
|
||||
?>
|
||||
<div id="#template-manager-folder" class="container-fluid">
|
||||
<div class="mt-2 p-2">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="tree-holder">
|
||||
<ul class="directory-tree treeselect root">
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="" href="" data-base="template">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php echo ($this->template->client_id === 0 ? '/' : '/administrator/') . 'templates/' . $this->template->element; ?>
|
||||
</a>
|
||||
<?php echo $this->loadTemplate('folders'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
<?php if (count($this->mediaFiles)) : ?>
|
||||
<ul class="directory-tree treeselect">
|
||||
<li class="folder-select">
|
||||
<a class="folder-url" data-id="" href="" data-base="media">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span>
|
||||
<?php echo '/media/templates/' . ($this->template->client_id === 0 ? 'site/' : 'administrator/') . $this->template->element; ?>
|
||||
</a>
|
||||
<?php echo $this->loadTemplate('media_folders'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<form method="post" action="<?php echo Route::_('index.php?option=com_templates&task=template.createFolder&id=' . $input->getInt('id') . '&file=' . $this->file); ?>">
|
||||
<div class="form-group">
|
||||
<label for="folder_name"><?php echo Text::_('COM_TEMPLATES_FOLDER_NAME'); ?></label>
|
||||
<input type="text" name="name" id="folder_name" class="form-control" required>
|
||||
<input type="hidden" class="address" name="address">
|
||||
<input type="hidden" name="isMedia" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary"><?php echo Text::_('COM_TEMPLATES_BUTTON_CREATE'); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
$input = Factory::getApplication()->getInput();
|
||||
?>
|
||||
<form id="deleteFolder" method="post" action="<?php echo Route::_('index.php?option=com_templates&task=template.deleteFolder&id=' . $input->getInt('id') . '&file=' . $this->file); ?>">
|
||||
<fieldset>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_CLOSE'); ?></button>
|
||||
<input type="hidden" class="address" name="address">
|
||||
<input type="hidden" name="isMedia" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
<button type="submit" class="btn btn-danger"><?php echo Text::_('COM_TEMPLATES_BUTTON_DELETE'); ?></button>
|
||||
</fieldset>
|
||||
</form>
|
||||
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Filesystem\File;
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<div id="template-manager-rename" class="container-fluid">
|
||||
<div class="mt-2">
|
||||
<div class="col-md-12">
|
||||
<div class="control-group">
|
||||
<div class="control-label">
|
||||
<label for="new_name">
|
||||
<?php echo Text::_('COM_TEMPLATES_NEW_FILE_NAME')?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" name="new_name" id="new_name" required>
|
||||
<span class="input-group-text">.<?php echo File::getExt($this->fileName); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_CLOSE'); ?></button>
|
||||
<button type="submit" class="btn btn-primary"><?php echo Text::_('COM_TEMPLATES_BUTTON_RENAME'); ?></button>
|
||||
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<div id="template-manager-resize" class="container-fluid">
|
||||
<div class="mt-2">
|
||||
<div class="col-md-12">
|
||||
<div class="control-group">
|
||||
<div class="control-label">
|
||||
<label for="height">
|
||||
<?php echo Text::_('COM_TEMPLATES_IMAGE_HEIGHT')?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<input class="form-control" type="number" name="height" id="height" placeholder="<?php echo $this->image['height']; ?> px" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="control-label">
|
||||
<label for="width">
|
||||
<?php echo Text::_('COM_TEMPLATES_IMAGE_WIDTH')?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<input class="form-control" type="number" name="width" id="width" placeholder="<?php echo $this->image['width']; ?> px" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Language\Text;
|
||||
|
||||
?>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo Text::_('COM_TEMPLATES_TEMPLATE_CLOSE'); ?></button>
|
||||
<button type="submit" class="btn btn-primary"><?php echo Text::_('COM_TEMPLATES_BUTTON_RESIZE'); ?></button>
|
||||
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
ksort($this->files, SORT_NATURAL);
|
||||
?>
|
||||
|
||||
<ul class="directory-tree treeselect">
|
||||
<?php foreach ($this->files as $key => $value) : ?>
|
||||
<?php if (is_array($value)) : ?>
|
||||
<?php
|
||||
$keyArray = explode('/', rtrim($key, '\\'));
|
||||
$fileArray = explode('/', $this->fileName);
|
||||
$count = 0;
|
||||
|
||||
$keyArrayCount = count($keyArray);
|
||||
|
||||
if (count($fileArray) >= $keyArrayCount) {
|
||||
for ($i = 0; $i < $keyArrayCount; $i++) {
|
||||
if ($keyArray[$i] === $fileArray[$i]) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($count === $keyArrayCount) {
|
||||
$class = 'folder show';
|
||||
} else {
|
||||
$class = 'folder';
|
||||
}
|
||||
} else {
|
||||
$class = 'folder';
|
||||
}
|
||||
|
||||
?>
|
||||
<li class="<?php echo $class; ?>">
|
||||
<a class="folder-url" href="">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span> <?php $explodeArray = explode('/', $key);
|
||||
echo $this->escape(end($explodeArray)); ?>
|
||||
</a>
|
||||
<?php echo $this->directoryTree($value); ?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if (is_object($value)) : ?>
|
||||
<li>
|
||||
<a class="file" href='<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $this->id . '&file=' . $value->id . '&isMedia=0'); ?>'>
|
||||
<span class="icon-file-alt" aria-hidden="true"></span> <?php echo $this->escape($value->name); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
// Legacy is the default
|
||||
if (!count($this->mediaFiles)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ksort($this->mediaFiles, SORT_STRING);
|
||||
?>
|
||||
|
||||
<ul class="directory-tree treeselect">
|
||||
<?php foreach ($this->mediaFiles as $key => $value) : ?>
|
||||
<?php if (is_array($value)) : ?>
|
||||
<?php
|
||||
$keyArray = explode('/', rtrim($key, '\\'));
|
||||
$fileArray = explode('/', $this->fileName);
|
||||
$count = 0;
|
||||
|
||||
$keyArrayCount = count($keyArray);
|
||||
|
||||
if (count($fileArray) >= $keyArrayCount) {
|
||||
for ($i = 0; $i < $keyArrayCount; $i++) {
|
||||
if ($keyArray[$i] === $fileArray[$i]) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($count === $keyArrayCount) {
|
||||
$class = 'folder show';
|
||||
} else {
|
||||
$class = 'folder';
|
||||
}
|
||||
} else {
|
||||
$class = 'folder';
|
||||
}
|
||||
|
||||
?>
|
||||
<li class="<?php echo $class; ?>">
|
||||
<a class="folder-url" href="">
|
||||
<span class="icon-folder icon-fw" aria-hidden="true"></span> <?php $explodeArray = explode('/', $key);
|
||||
echo $this->escape(end($explodeArray)); ?>
|
||||
</a>
|
||||
<?php echo $this->mediaTree($value); ?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if (is_object($value)) : ?>
|
||||
<li>
|
||||
<a class="file" href="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $this->id . '&file=' . $value->id . '&isMedia=1'); ?>">
|
||||
<span class="icon-file-alt" aria-hidden="true"></span> <?php echo $this->escape($value->name); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
HTMLHelper::_('bootstrap.dropdown', '.dropdown-toggle');
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('table.columns');
|
||||
|
||||
$input = Factory::getApplication()->getInput();
|
||||
?>
|
||||
|
||||
<?php if (count($this->updatedList) === 0) : ?>
|
||||
<div class="alert alert-success">
|
||||
<span class="icon-check-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('NOTICE'); ?></span>
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_UPTODATE'); ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="alert alert-info">
|
||||
<span class="icon-info-circle" aria-hidden="true"></span><span class="visually-hidden"><?php echo Text::_('INFO'); ?></span>
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_NOT_UPTODATE'); ?>
|
||||
</div>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $input->getInt('id') . '&file=' . $this->file); ?>" method="post" name="updateForm" id="updateForm">
|
||||
<div class="row mt-2">
|
||||
<div class="col-md-12">
|
||||
<table class="table">
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_UPDATED_FILES_CAPTION'); ?>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="w-5 text-center">
|
||||
<?php echo HTMLHelper::_('grid.checkall'); ?>
|
||||
</td>
|
||||
<th scope="col" class="w-7">
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_CHECKED'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-30">
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_TEMPLATE_FILE'); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_CREATED_DATE'); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_MODIFIED_DATE'); ?>
|
||||
</th>
|
||||
<th scope="col">
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDE_SOURCE'); ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($this->updatedList as $i => $value) : ?>
|
||||
<tr class="row<?php echo $i % 2; ?>">
|
||||
<td class="text-center">
|
||||
<?php echo HTMLHelper::_('grid.id', $i, $value->hash_id, false, 'cid', 'cb', '', 'updateForm'); ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo HTMLHelper::_('jgrid.published', $value->state, $i, 'template.', 1, 'cb', null, null, 'updateForm'); ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . (int) $value->extension_id . '&file=' . $value->hash_id); ?>" title="<?php echo Text::_('JACTION_EDIT'); ?>"><?php echo base64_decode($value->hash_id); ?></a>
|
||||
</td>
|
||||
<td>
|
||||
<?php $created_date = $value->created_date; ?>
|
||||
<?php echo $created_date > 0 ? HTMLHelper::_('date', $created_date, Text::_('DATE_FORMAT_FILTER_DATETIME')) : '-'; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if (is_null($value->modified_date)) : ?>
|
||||
<span class="badge bg-warning text-dark"><?php echo Text::_('COM_TEMPLATES_OVERRIDE_CORE_REMOVED'); ?></span>
|
||||
<?php else : ?>
|
||||
<?php echo HTMLHelper::_('date', $value->modified_date, Text::_('DATE_FORMAT_FILTER_DATETIME')); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-info"><?php echo $value->action; ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2015 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
$input = Factory::getApplication()->getInput();
|
||||
?>
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . $input->getInt('id') . '&file=' . $this->file); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<?php echo HTMLHelper::_('uitab.startTabSet', 'myTab', ['active' => 'description', 'recall' => true, 'breakpoint' => 768]); ?>
|
||||
<?php echo HTMLHelper::_('uitab.addTab', 'myTab', 'description', Text::_('COM_TEMPLATES_TAB_DESCRIPTION')); ?>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<?php echo $this->loadTemplate('description'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php echo HTMLHelper::_('uitab.endTab'); ?>
|
||||
<?php echo HTMLHelper::_('uitab.endTabSet'); ?>
|
||||
<input type="hidden" name="task" value="">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</form>
|
||||
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Joomla.Administrator
|
||||
* @subpackage com_templates
|
||||
*
|
||||
* @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\HTML\HTMLHelper;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
|
||||
/** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->document->getWebAssetManager();
|
||||
$wa->useScript('table.columns')
|
||||
->useScript('multiselect');
|
||||
|
||||
$user = $this->getCurrentUser();
|
||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||
?>
|
||||
|
||||
<form action="<?php echo Route::_('index.php?option=com_templates&view=templates'); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div id="j-main-container" class="j-main-container">
|
||||
<?php echo LayoutHelper::render('joomla.searchtools.default', ['view' => $this, 'options' => ['selectorFieldName' => 'client_id']]); ?>
|
||||
<?php if ($this->total > 0) : ?>
|
||||
<table class="table" id="templateList">
|
||||
<caption class="visually-hidden">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATES_TABLE_CAPTION'); ?>,
|
||||
<span id="orderedBy"><?php echo Text::_('JGLOBAL_SORTED_BY'); ?> </span>,
|
||||
<span id="filteredBy"><?php echo Text::_('JGLOBAL_FILTERED_BY'); ?></span>
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="w-20 col1template d-none d-md-table-cell">
|
||||
<?php echo Text::_('COM_TEMPLATES_HEADING_IMAGE'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-30">
|
||||
<?php echo HTMLHelper::_('searchtools.sort', 'COM_TEMPLATES_HEADING_TEMPLATE', 'a.element', $listDirn, $listOrder); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell text-center">
|
||||
<?php echo Text::_('JVERSION'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell text-center">
|
||||
<?php echo Text::_('JDATE'); ?>
|
||||
</th>
|
||||
<th scope="col" class="w-25 d-none d-md-table-cell text-center">
|
||||
<?php echo Text::_('JAUTHOR'); ?>
|
||||
</th>
|
||||
<?php if ($this->pluginState) : ?>
|
||||
<th scope="col" class="w-10 d-none d-md-table-cell text-center">
|
||||
<?php echo Text::_('COM_TEMPLATES_OVERRIDES'); ?>
|
||||
</th>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($this->items as $i => $item) : ?>
|
||||
<tr class="row<?php echo $i % 2; ?>">
|
||||
<td class="text-center d-none d-md-table-cell">
|
||||
<?php echo HTMLHelper::_('templates.thumb', $item); ?>
|
||||
<?php echo HTMLHelper::_('templates.thumbModal', $item); ?>
|
||||
</td>
|
||||
<th scope="row" class="template-name">
|
||||
<a href="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . (int) $item->extension_id . '&file=' . $this->file); ?>">
|
||||
<?php echo Text::sprintf('COM_TEMPLATES_TEMPLATE_DETAILS', ucfirst($item->name)); ?></a>
|
||||
<div>
|
||||
<?php if ($this->preview) : ?>
|
||||
<?php $client = (int) $item->client_id === 1 ? 'administrator' : 'site'; ?>
|
||||
<a href="<?php echo Route::link($client, 'index.php?tp=1&template=' . $item->element); ?>" target="_blank" aria-labelledby="preview-<?php echo $item->extension_id; ?>">
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_PREVIEW'); ?>
|
||||
</a>
|
||||
<div role="tooltip" id="preview-<?php echo $item->extension_id; ?>"><?php echo Text::sprintf('COM_TEMPLATES_TEMPLATE_NEW_PREVIEW', $item->name); ?></div>
|
||||
<?php else : ?>
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_NO_PREVIEW'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if (isset($item->xmldata->inheritable) && $item->xmldata->inheritable) : ?>
|
||||
<div class="badge bg-primary">
|
||||
<span class="fas fa-link text-light" aria-hidden="true"></span>
|
||||
<?php echo Text::_('COM_TEMPLATES_TEMPLATE_IS_PARENT'); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($item->xmldata->parent) && (string) $item->xmldata->parent !== '') : ?>
|
||||
<div class="badge bg-info text-light">
|
||||
<span class="fas fa-clone text-light" aria-hidden="true"></span>
|
||||
<?php echo Text::sprintf('COM_TEMPLATES_TEMPLATE_IS_CHILD_OF', (string) $item->xmldata->parent); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</th>
|
||||
<td class="small d-none d-md-table-cell text-center">
|
||||
<?php echo $this->escape($item->xmldata->get('version')); ?>
|
||||
</td>
|
||||
<td class="small d-none d-md-table-cell text-center">
|
||||
<?php echo $this->escape($item->xmldata->get('creationDate')); ?>
|
||||
</td>
|
||||
<td class="d-none d-md-table-cell text-center">
|
||||
<?php if ($author = $item->xmldata->get('author')) : ?>
|
||||
<div><?php echo $this->escape($author); ?></div>
|
||||
<?php else : ?>
|
||||
—
|
||||
<?php endif; ?>
|
||||
<?php if ($email = $item->xmldata->get('authorEmail')) : ?>
|
||||
<div><?php echo $this->escape($email); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($url = $item->xmldata->get('authorUrl')) : ?>
|
||||
<div><a href="<?php echo $this->escape($url); ?>"><?php echo $this->escape($url); ?></a></div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php if ($this->pluginState) : ?>
|
||||
<td class="d-none d-md-table-cell text-center">
|
||||
<?php if (!empty($item->updated)) : ?>
|
||||
<a href="<?php echo Route::_('index.php?option=com_templates&view=template&id=' . (int) $item->extension_id . '#files'); ?>">
|
||||
<span class="badge bg-warning text-dark"><?php echo Text::plural('COM_TEMPLATES_N_CONFLICT', $item->updated); ?></span>
|
||||
</a>
|
||||
<?php else : ?>
|
||||
<span class="badge bg-success"><?php echo Text::_('COM_TEMPLATES_UPTODATE'); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php // load the pagination. ?>
|
||||
<?php echo $this->pagination->getListFooter(); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<input type="hidden" name="task" value="">
|
||||
<input type="hidden" name="boxchecked" value="0">
|
||||
<?php echo HTMLHelper::_('form.token'); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<layout title="COM_TEMPLATES_TEMPLATES_VIEW_DEFAULT_TITLE">
|
||||
<message>
|
||||
<![CDATA[COM_TEMPLATES_TEMPLATES_VIEW_DEFAULT_DESC]]>
|
||||
</message>
|
||||
</layout>
|
||||
</metadata>
|
||||
Reference in New Issue
Block a user