Files
bio-concept-labo/web/controllers/admin/AdminThemesController.php
2019-11-20 07:44:43 +01:00

1121 lines
43 KiB
PHP

<?php
/**
* 2007-2018 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager;
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder;
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeRepository;
use PrestaShop\PrestaShop\Core\Shop\LogoUploader;
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
/**
* @property Theme $object
*/
class AdminThemesControllerCore extends AdminController
{
// temp
const CACHE_FILE_CUSTOMER_THEMES_LIST = '/config/xml/customer_themes_list.xml';
const CACHE_FILE_MUST_HAVE_THEMES_LIST = '/config/xml/must_have_themes_list.xml';
/**
* @var ThemeManager
*/
public $theme_manager;
/**
* @var ThemeRepository
*/
protected $theme_repository;
protected $toolbar_scroll = false;
protected $authAccesses = array();
private $img_error;
/* @var LogoUploader $logo_uploader */
private $logo_uploader;
public function __construct()
{
$this->bootstrap = true;
parent::__construct();
$this->theme_manager = (new ThemeManagerBuilder($this->context, Db::getInstance()))->build();
$this->theme_repository = (new ThemeManagerBuilder($this->context, Db::getInstance()))->buildRepository();
$this->logo_uploader = new LogoUploader($this->context->shop);
}
public function init()
{
// No cache for auto-refresh uploaded logo
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
parent::init();
$this->can_display_themes = (!Shop::isFeatureActive() || Shop::getContext() == Shop::CONTEXT_SHOP);
if (Tools::getValue('display') == 'configureLayouts') {
$this->initConfigureLayouts();
} elseif (Tools::getValue('action') == 'importtheme') {
$this->display = 'importtheme';
}
libxml_use_internal_errors(true);
}
public function downloadAddonsThemes()
{
if (!$this->logged_on_addons) {
return false;
}
try {
$this->validateAddAuthorization();
} catch (Exception $e) {
return false;
}
if (!$this->isFresh(self::CACHE_FILE_CUSTOMER_THEMES_LIST, 86400)) {
file_put_contents(
_PS_ROOT_DIR_ . self::CACHE_FILE_CUSTOMER_THEMES_LIST,
Tools::addonsRequest('customer_themes')
);
}
$customer_themes_list = file_get_contents(_PS_ROOT_DIR_ . self::CACHE_FILE_CUSTOMER_THEMES_LIST);
if (!empty($customer_themes_list) && $customer_themes_list_xml = @simplexml_load_string($customer_themes_list)) {
foreach ($customer_themes_list_xml->theme as $addons_theme) {
//get addons theme if folder does not exist
$ids_themes = Tools::unSerialize(Configuration::get('PS_ADDONS_THEMES_IDS'));
if (!is_array($ids_themes) || (is_array($ids_themes) && !in_array((string) $addons_theme->id, $ids_themes))) {
$zip_content = Tools::addonsRequest(
'module',
array(
'id_module' => pSQL($addons_theme->id),
'username_addons' => pSQL(trim($this->context->cookie->username_addons)),
'password_addons' => pSQL(trim($this->context->cookie->password_addons)),
)
);
$uniqid = uniqid();
$sandbox = _PS_CACHE_DIR_ . 'sandbox' . DIRECTORY_SEPARATOR . $uniqid . DIRECTORY_SEPARATOR;
mkdir($sandbox);
file_put_contents($sandbox . (string) $addons_theme->getName() . '.zip', $zip_content);
if ($this->extractTheme($sandbox . (string) $addons_theme->getName() . '.zip', $sandbox)) {
if ($theme_directory = $this->installTheme(self::UPLOADED_THEME_DIR_NAME, $sandbox, false)) {
$ids_themes[$theme_directory] = (string) $addons_theme->id;
}
}
Tools::deleteDirectory($sandbox);
}
Configuration::updateValue('PS_ADDONS_THEMES_IDS', serialize($ids_themes));
}
}
}
protected function processUpdateOptions()
{
parent::processUpdateOptions();
if (!count($this->errors)) {
Tools::redirectAdmin(Context::getContext()->link->getAdminLink('AdminThemes') . '&conf=6');
}
}
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar();
if (empty($this->display)) {
if ($this->isAddGranted()) {
$this->page_header_toolbar_btn['import_theme'] = array(
'href' => self::$currentIndex . '&action=importtheme&token=' . $this->token,
'desc' => $this->trans('Add new theme', array(), 'Admin.Design.Feature'),
'icon' => 'process-icon-new',
);
$this->page_header_toolbar_btn['export_theme'] = array(
'href' => self::$currentIndex . '&action=exporttheme&token=' . $this->token,
'desc' => $this->trans('Export current theme', array(), 'Admin.Design.Feature'),
'icon' => 'process-icon-export',
);
}
if ($this->context->mode) {
unset($this->toolbar_btn['new']);
}
}
if ($this->display == 'importtheme') {
$this->toolbar_title[] = $this->trans('Import theme', array(), 'Admin.Design.Feature');
} else {
$this->toolbar_title[] = $this->trans('Theme', array(), 'Admin.Design.Feature');
}
$title = implode(' ' . Configuration::get('PS_NAVIGATION_PIPE') . ' ', $this->toolbar_title);
$this->page_header_toolbar_title = $title;
}
public function initContent()
{
if ($this->display == 'list') {
$this->display = '';
}
if (isset($this->display) && method_exists($this, 'render' . $this->display)) {
$this->content .= $this->initPageHeaderToolbar();
$this->content .= $this->{'render' . $this->display}();
$this->context->smarty->assign(array(
'content' => $this->content,
'show_page_header_toolbar' => $this->show_page_header_toolbar,
'page_header_toolbar_title' => $this->page_header_toolbar_title,
'page_header_toolbar_btn' => $this->page_header_toolbar_btn,
));
} else {
$content = '';
if (Configuration::hasKey('PS_LOGO') && trim(Configuration::get('PS_LOGO')) != ''
&& file_exists(_PS_IMG_DIR_ . Configuration::get('PS_LOGO')) && filesize(_PS_IMG_DIR_ . Configuration::get('PS_LOGO'))) {
list($width, $height, $type, $attr) = getimagesize(_PS_IMG_DIR_ . Configuration::get('PS_LOGO'));
Configuration::updateValue('SHOP_LOGO_HEIGHT', (int) round($height));
Configuration::updateValue('SHOP_LOGO_WIDTH', (int) round($width));
}
$this->content .= $content;
return parent::initContent();
}
}
/**
* Ajax request handler for displaying theme catalog from the marketplace.
* Not used anymore.
*
* @deprecated since 1.7.4.0
*/
public function ajaxProcessGetAddonsThemes()
{
$parent_domain = Tools::getHttpHost(true) . substr($_SERVER['REQUEST_URI'], 0, -1 * strlen(basename($_SERVER['REQUEST_URI'])));
$iso_lang = $this->context->language->iso_code;
$iso_currency = $this->context->currency->iso_code;
$iso_country = $this->context->country->iso_code;
$activity = Configuration::get('PS_SHOP_ACTIVITY');
$addons_url = Tools::getCurrentUrlProtocolPrefix() . 'addons.prestashop.com/iframe/search-1.7.php?psVersion=' . _PS_VERSION_ . '&onlyThemes=1&isoLang=' . $iso_lang . '&isoCurrency=' . $iso_currency . '&isoCountry=' . $iso_country . '&activity=' . (int) $activity . '&parentUrl=' . $parent_domain;
die(Tools::file_get_contents($addons_url));
}
public function renderView()
{
$this->tpl_view_vars = array(
'doc' => $this->doc,
'theme_name' => $this->theme_name,
'img_error' => $this->img_error,
'modules_errors' => $this->modules_errors,
'back_link' => Context::getContext()->link->getAdminLink('AdminThemes'),
'image_link' => Context::getContext()->link->getAdminLink('AdminImages'),
);
return parent::renderView();
}
/**
* This functions make checks about AdminThemes configuration edition only.
*
* @since 1.4
*/
public function postProcess()
{
if (isset($_GET['error'])) {
$this->errors[] = $this->trans(
'You do not have permission to edit this.',
array(),
'Admin.Notifications.Error'
);
}
// done here, because if it is true, $_FILES & $_POST are empty, so we don't have any message.
try {
$this->validateUploadSize();
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
/* Specific processes, depending on action and/or submitted form */
switch (Tools::getValue('action')) {
case 'importtheme':
if (Tools::isSubmit('submitAddconfiguration')) {
$this->postProcessSubmitAddConfiguration();
}
break;
case 'exporttheme':
if (false === $this->postProcessExportTheme()) {
return false;
}
break;
case 'enableTheme':
$this->postProcessEnableTheme();
break;
case 'deleteTheme':
$this->postProcessDeleteTheme();
break;
case 'resetToDefaults':
$this->postProcessResetToDefaults();
break;
case 'submitConfigureLayouts':
$this->postProcessSubmitConfigureLayouts();
break;
// Main Theme page
default:
if (Tools::isSubmit('submitGenerateRTL')) {
$this->postProcessSubmitGenerateRTL();
}
if (Tools::isSubmit('submitOptionsconfiguration')) {
$this->postProcessSubmitOptionsConfiguration();
}
}
return parent::postProcess();
}
public function processUploadFile($dest)
{
try {
$this->validateAddAuthorization();
} catch (Exception $e) {
$this->errors[] = $this->trans(
'You do not have permission to upload this.',
array(),
'Admin.Notifications.Error'
);
return false;
}
switch ($_FILES['themearchive']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
$this->errors[] = $this->trans('The uploaded file is too large.', array(), 'Admin.Design.Notification');
return false;
default:
$this->errors[] = $this->trans('Unknown error.', array(), 'Admin.Notifications.Error');
return false;
}
$tmp_name = $_FILES['themearchive']['tmp_name'];
$mimeType = false;
$goodMimeType = false;
if (function_exists('finfo_open')) {
$finfo = @finfo_open(FILEINFO_MIME);
$mimeType = @finfo_file($finfo, $tmp_name);
@finfo_close($finfo);
} elseif (function_exists('mime_content_type')) {
$mimeType = @mime_content_type($tmp_name);
} elseif (function_exists('exec')) {
$mimeType = trim(@exec('file -b --mime-type ' . escapeshellarg($tmp_name)));
if (!$mimeType) {
$mimeType = trim(@exec('file --mime ' . escapeshellarg($tmp_name)));
}
if (!$mimeType) {
$mimeType = trim(@exec('file -bi ' . escapeshellarg($tmp_name)));
}
}
if (!empty($mimeType)) {
preg_match('#application/zip#', $mimeType, $matches);
if (!empty($matches)) {
$goodMimeType = true;
}
}
if (false === $goodMimeType) {
$this->errors[] = $this->trans('Invalid file format.', array(), 'Admin.Design.Notification');
return false;
}
$name = $_FILES['themearchive']['name'];
if (!Validate::isFileName($name)) {
$dest = _PS_ALL_THEMES_DIR_ . sha1_file($tmp_name) . '.zip';
}
if (!move_uploaded_file(
$_FILES['themearchive']['tmp_name'],
$dest
)) {
$this->errors[] = $this->trans('Failed to move uploaded file.', array(), 'Admin.Design.Notification');
return false;
}
return $dest;
}
/**
* Function used to render the options for this controller.
*/
public function renderOptions()
{
// Download user themes from Addons
if ($this->logged_on_addons) {
$this->downloadAddonsThemes();
}
// Employee languages used for link and utm_source
$lang = new Language($this->context->language->id);
$iso_lang_uc = strtoupper($lang->iso_code);
$url = 'https://addons.prestashop.com/create-favicon.php?pab=1';
$this->fields_options = array(
'appearance' => array(
'title' => $this->trans('Your current theme', array(), 'Admin.Design.Feature'),
'icon' => 'icon-html5',
'tabs' => array(
'logo' => $this->trans('Logo', array(), 'Admin.Global'),
'logo2' => $this->trans('Invoice & Email Logos', array(), 'Admin.Design.Feature'),
'icons' => $this->trans('Favicons', array(), 'Admin.Design.Feature'),
),
'fields' => array(
'PS_LOGO' => array(
'title' => $this->trans('Header logo', array(), 'Admin.Design.Feature'),
'hint' => $this->trans('Will appear on main page. Recommended size for the default theme: height %height% and width %width%.',
array(
'%height%' => '40px',
'%width%' => '200px',
),
'Admin.Design.Help'),
'type' => 'file',
'name' => 'PS_LOGO',
'tab' => 'logo',
'thumb' => _PS_IMG_ . Configuration::get('PS_LOGO'),
),
'PS_LOGO_MAIL' => array(
'title' => $this->trans('Mail logo', array(), 'Admin.Design.Feature'),
'desc' => ((Configuration::get('PS_LOGO_MAIL') === false) ? '<span class="light-warning">' . $this->trans('Warning: if no email logo is available, the main logo will be used instead.', array(), 'Admin.Design.Notification') . '</span><br />' : ''),
'hint' => $this->trans('Will appear on email headers. If undefined, the header logo will be used.', array(), 'Admin.Design.Help'),
'type' => 'file',
'name' => 'PS_LOGO_MAIL',
'tab' => 'logo2',
'thumb' => (Configuration::get('PS_LOGO_MAIL') !== false && file_exists(_PS_IMG_DIR_ . Configuration::get('PS_LOGO_MAIL'))) ? _PS_IMG_ . Configuration::get('PS_LOGO_MAIL') : _PS_IMG_ . Configuration::get('PS_LOGO'),
),
'PS_LOGO_INVOICE' => array(
'title' => $this->trans('Invoice logo', array(), 'Admin.Design.Feature'),
'desc' => ((Configuration::get('PS_LOGO_INVOICE') === false) ? '<span class="light-warning">' . $this->trans('Warning: if no invoice logo is available, the main logo will be used instead.', array(), 'Admin.Design.Help') . '</span><br />' : ''),
'hint' => $this->trans('Will appear on invoice headers.', array(), 'Admin.Design.Help') . ' ' . $this->trans('Warning: you can use a PNG file for transparency, but it can take up to 1 second per page for processing. Please consider using JPG instead.', array(), 'Admin.Design.Help'),
'type' => 'file',
'name' => 'PS_LOGO_INVOICE',
'tab' => 'logo2',
'thumb' => (Configuration::get('PS_LOGO_INVOICE') !== false && file_exists(_PS_IMG_DIR_ . Configuration::get('PS_LOGO_INVOICE'))) ? _PS_IMG_ . Configuration::get('PS_LOGO_INVOICE') : _PS_IMG_ . Configuration::get('PS_LOGO'),
),
'PS_FAVICON' => array(
'title' => $this->trans('Favicon', array(), 'Admin.Design.Feature'),
'desc' => $this->trans('Use our [1]favicon generator on PrestaShop Marketplace[/1] to boost your brand image!', array('[1]' => '<a href="' . $url . '" target="_blank">', '[/1]' => '</a>'), 'Admin.Design.Help'),
'hint' => $this->trans('It is the small icon that appears in browser tabs, next to the web address', array(), 'Admin.Design.Help'),
'type' => 'file',
'name' => 'PS_FAVICON',
'tab' => 'icons',
'thumb' => _PS_IMG_ . Configuration::get('PS_FAVICON') . (Tools::getValue('conf') ? sprintf('?%04d', rand(0, 9999)) : ''),
),
),
'after_tabs' => array(
'cur_theme' => $this->context->shop->theme,
),
'submit' => array('title' => $this->trans('Save', array(), 'Admin.Actions')),
'buttons' => array(
'storeLink' => array(
'id' => 'visit-theme-catalog-link',
'title' => $this->trans('Visit the theme catalog', array(), 'Admin.Design.Feature'),
'icon' => 'process-icon-themes',
'href' => Tools::getCurrentUrlProtocolPrefix() . 'addons.prestashop.com/en/3-templates-prestashop'
. '?utm_source=back-office&utm_medium=theme-button'
. '&utm_campaign=back-office-' . $iso_lang_uc
. '&utm_content=' . (defined('_PS_HOST_MODE_') ? 'cloud' : 'download'),
'js' => 'return !window.open(this.href)',
),
),
),
);
if (in_array('1', array_column($this->_languages, 'is_rtl'))) {
$themes_list = array();
$allThemes = $this->theme_repository->getList();
foreach ($allThemes as $theme) {
$themeName = $theme->getName();
$themes_list[] = array('theme' => $themeName, 'name' => $themeName);
}
$this->fields_options['RTL'] = array(
'title' => $this->trans('Adaptation to Right-to-Left languages', array(), 'Admin.Design.Feature'),
'description' => $this->trans('Be careful! Please check your theme in an RTL language before generating the RTL stylesheet: your theme could be already adapted to RTL.\nOnce you click on "Adapt to RTL", any RTL-specific file that you might have added to your theme might be deleted by the created stylesheet.', array(), 'Admin.Design.Help'),
'fields' => array(
'PS_THEMES_LIST' => array(
'title' => $this->trans('Theme to adapt', array(), 'Admin.Design.Feature'),
'type' => 'select',
'identifier' => 'theme',
'list' => $themes_list,
),
'PS_GENERATE_RTL' => array(
'title' => $this->trans('Generate RTL stylesheet', array(), 'Admin.Design.Feature'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool',
'default' => 0,
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
'name' => 'submitGenerateRTL',
),
);
}
$other_themes = $this->theme_repository->getListExcluding([$this->context->shop->theme->getName()]);
if (!empty($other_themes)) {
$this->fields_options['theme'] = array(
'title' => $this->trans('Select a theme for the "%name%" shop', array('%name%' => $this->context->shop->name), 'Admin.Design.Feature'),
'description' => (!$this->can_display_themes) ? $this->trans('You must select a shop from the above list if you wish to choose a theme.', array(), 'Admin.Design.Help') : '',
'fields' => array(
'theme_for_shop' => array(
'type' => 'theme',
'themes' => $other_themes,
'can_display_themes' => $this->can_display_themes,
'can_delete_themes' => $this->isDeleteGranted(),
'no_multishop_checkbox' => true,
),
),
);
}
if (isset($this->display) && method_exists($this, 'render' . $this->display)) {
return $this->{'render' . $this->display}();
}
if ($this->fields_options && is_array($this->fields_options)) {
$helper = new HelperOptions($this);
$this->setHelperDisplay($helper);
$helper->toolbar_scroll = true;
$helper->title = $this->trans('Theme appearance', array(), 'Admin.Design.Feature');
$helper->toolbar_btn = array(
'save' => array(
'href' => '#',
'desc' => $this->trans('Save', array(), 'Admin.Actions'),
),
);
$helper->id = $this->id;
$helper->tpl_vars = $this->tpl_option_vars;
$options = $helper->generateOptions($this->fields_options);
return $options;
}
}
public function renderImportTheme()
{
try {
$this->validateAddAuthorization(true);
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
return false;
}
$fields_form = array();
$toolbar_btn['save'] = array(
'href' => '#',
'desc' => $this->trans('Save', array(), 'Admin.Actions'),
);
if ($this->context->mode != Context::MODE_HOST) {
$fields_form[0] = array(
'form' => array(
'tinymce' => false,
'legend' => array(
'title' => $this->trans('Import from your computer', array(), 'Admin.Design.Feature'),
'icon' => 'icon-picture',
),
'input' => array(
array(
'type' => 'file',
'label' => $this->trans('Zip file', array(), 'Admin.Design.Feature'),
'desc' => $this->trans('Browse your computer files and select the Zip file for your new theme.', array(), 'Admin.Design.Help'),
'name' => 'themearchive',
),
),
'submit' => array(
'id' => 'zip',
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
),
);
$fields_form[1] = array(
'form' => array(
'tinymce' => false,
'legend' => array(
'title' => $this->trans('Import from the web', array(), 'Admin.Design.Feature'),
'icon' => 'icon-picture',
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Archive URL', array(), 'Admin.Design.Feature'),
'desc' => $this->trans('Indicate the complete URL to an online Zip file that contains your new theme. For instance, "http://example.com/files/theme.zip".', array(), 'Admin.Design.Help'),
'name' => 'themearchiveUrl',
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
),
);
$theme_archive_server = array();
$files = scandir(_PS_ALL_THEMES_DIR_, SCANDIR_SORT_NONE);
$theme_archive_server[] = '-';
foreach ($files as $file) {
if (is_file(_PS_ALL_THEMES_DIR_ . $file) && substr(_PS_ALL_THEMES_DIR_ . $file, -4) == '.zip') {
$theme_archive_server[] = array(
'id' => basename(_PS_ALL_THEMES_DIR_ . $file),
'name' => basename(_PS_ALL_THEMES_DIR_ . $file),
);
}
}
$fields_form[2] = array(
'form' => array(
'tinymce' => false,
'legend' => array(
'title' => $this->trans('Import from FTP', array(), 'Admin.Design.Feature'),
'icon' => 'icon-picture',
),
'input' => array(
array(
'type' => 'select',
'label' => $this->trans('Select the archive', array(), 'Admin.Design.Feature'),
'name' => 'theme_archive_server',
'desc' => $this->trans('This selector lists the Zip files that you uploaded in the \'/themes\' folder.', array(), 'Admin.Design.Help'),
'options' => array(
'id' => 'id',
'name' => 'name',
'query' => $theme_archive_server,
),
),
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
),
),
);
}
$this->context->smarty->assign(
array(
'import_theme' => true,
'logged_on_addons' => $this->logged_on_addons,
'iso_code' => $this->context->language->iso_code,
)
);
$helper = new HelperForm();
$helper->currentIndex = $this->context->link->getAdminLink('AdminThemes', false) . '&action=importtheme';
$helper->token = Tools::getAdminTokenLite('AdminThemes');
$helper->show_toolbar = true;
$helper->toolbar_btn = $toolbar_btn;
$helper->fields_value['themearchiveUrl'] = '';
$helper->fields_value['theme_archive_server'] = array();
$helper->multiple_fieldsets = true;
$helper->override_folder = $this->tpl_folder;
$helper->languages = $this->getLanguages();
$helper->default_form_language = (int) $this->context->language->id;
return $helper->generateForm($fields_form);
}
public function setMedia($isNewTheme = false)
{
parent::setMedia($isNewTheme);
$this->addJS(_PS_JS_DIR_ . 'admin/themes.js');
if ($this->context->mode == Context::MODE_HOST && Tools::getValue('action') == 'importtheme') {
$this->addJS(_PS_JS_DIR_ . 'admin/addons.js');
}
}
public function initConfigureLayouts()
{
$theme = $this->theme_repository->getInstanceByName($this->context->shop->theme->getName());
$this->context->smarty->assign([
'pages' => Meta::getAllMeta($this->context->language->id),
'default_layout' => $this->translateAttributes($theme->getDefaultLayout()),
'page_layouts' => $theme->getPageLayouts(),
'available_layouts' => $this->translateAttributes($theme->getAvailableLayouts()),
]);
$this->setTemplate('controllers/themes/configurelayouts.tpl');
}
/**
* Translate attributes (from yml).
*
* @param $attributes
*
* @return mixed
*/
private function translateAttributes($attributes)
{
if (!empty($attributes)) {
foreach ($attributes as $key => &$layout) {
// layout can be an array of array, or just an array :/ we just translate name & description, see theme.dist.yml
if (is_array($layout)) {
if (array_key_exists('name', $layout)) {
$layout['name'] = $this->translator->trans($layout['name'], array(), 'Admin.Design.Feature');
}
if (array_key_exists('description', $layout)) {
$layout['description'] = $this->translator->trans($layout['description'], array(), 'Admin.Design.Feature');
}
} else {
if (in_array($key, array('name', 'description'))) {
$attributes[$key] = $this->translator->trans($layout, array(), 'Admin.Design.Feature');
}
}
}
}
return $attributes;
}
public function processSubmitConfigureLayouts()
{
if ($this->isAllGranted()) {
$this->context->shop->theme->setPageLayouts(Tools::getValue('layouts'));
$this->theme_manager->saveTheme($this->context->shop->theme);
}
Tools::clearCache();
}
/**
* Verify if all actions are authorized in this controller.
*
* @return bool true if access is granted
*/
protected function isAllGranted()
{
// Delete access is the highest access level
return $this->isDeleteGranted();
}
/**
* Verify if delete is authorized in this controller.
*
* @return bool true if delete access is granted
*/
protected function isDeleteGranted()
{
return $this->isAccessGranted(AdminController::LEVEL_DELETE);
}
/**
* Verify if add is authorized in this controller.
*
* @return bool true if add access is granted
*/
protected function isAddGranted()
{
return $this->isAccessGranted(AdminController::LEVEL_ADD);
}
/**
* Verify if edit is authorized in this controller.
*
* @return bool true if edit access is granted
*/
protected function isEditGranted()
{
return $this->isAccessGranted(AdminController::LEVEL_EDIT);
}
/**
* Verify if view is authorized in this controller.
*
* @return bool true if view access is granted
*/
protected function isViewGranted()
{
return $this->isAccessGranted(AdminController::LEVEL_VIEW);
}
/**
* Verify if $accessLevel is granted for this controller.
*
* @param int $accessLevel Access level to be verified
*
* @return bool true if this access level is granted for this controller
*/
protected function isAccessGranted($accessLevel)
{
$accessLevel = (int) $accessLevel;
if (!in_array(
$accessLevel,
array(
AdminController::LEVEL_VIEW,
AdminController::LEVEL_EDIT,
AdminController::LEVEL_ADD,
AdminController::LEVEL_DELETE,
)
)) {
throw new InvalidArgumentException('Unknown access level : ' . $accessLevel);
}
if (empty($this->authAccesses[$accessLevel])) {
$this->authAccesses[$accessLevel] = $this->authorizationLevel() >= (int) $accessLevel;
}
return $this->authAccesses[$accessLevel];
}
/**
* Validate access for all action types.
*
* If access is not granted, the thrown Exception's error message contains the translated rejection message.
*
* @param bool $allowDemoMode Should we grant access in demo mode ?
*
* @throws Exception
*/
protected function validateAllAuthorizations($allowDemoMode = false)
{
// DELETE level is the max possible level. If it is granted, everything else is granted.
if ((_PS_MODE_DEMO_ && !$allowDemoMode)
|| !$this->isDeleteGranted()
) {
throw new Exception(
$this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error')
);
}
}
/**
* Validate delete access.
*
* If access is not granted, the thrown Exception's error message contains the translated rejection message.
*
* @param bool $allowDemoMode Should we grant access in demo mode ?
*
* @throws Exception
*/
protected function validateDeleteAuthorization($allowDemoMode = false)
{
if ((_PS_MODE_DEMO_ && !$allowDemoMode)
|| !$this->isDeleteGranted()
) {
throw new Exception(
$this->trans('You do not have permission to delete this.', array(), 'Admin.Notifications.Error')
);
}
}
/**
* Validate add access.
*
* If access is not granted, the thrown Exception's error message contains the translated rejection message.
*
* @param bool $allowDemoMode Should we grant access in demo mode ?
*
* @throws Exception
*/
protected function validateAddAuthorization($allowDemoMode = false)
{
if ((_PS_MODE_DEMO_ && !$allowDemoMode)
|| !$this->isAddGranted()
) {
throw new Exception(
$this->trans('You do not have permission to add this.', array(), 'Admin.Notifications.Error')
);
}
}
/**
* Validate edit access.
*
* If access is not granted, the thrown Exception's error message contains the translated rejection message.
*
* @param bool $allowDemoMode Should we grant access in demo mode ?
*
* @throws Exception
*/
protected function validateEditAuthorization($allowDemoMode = false)
{
if ((_PS_MODE_DEMO_ && !$allowDemoMode)
|| !$this->isEditGranted()
) {
throw new Exception(
$this->trans('You do not have permission to edit this.', array(), 'Admin.Notifications.Error')
);
}
}
/**
* Validate view access.
*
* If access is not granted, the thrown Exception's error message contains the translated rejection message.
*
* @param bool $allowDemoMode Should we grant access in demo mode ?
*
* @throws Exception
*/
protected function validateViewAuthorization($allowDemoMode = false)
{
if ((_PS_MODE_DEMO_ && !$allowDemoMode)
|| !$this->isViewGranted()
) {
throw new Exception(
$this->trans('You do not have permission to view this.', array(), 'Admin.Notifications.Error')
);
}
}
protected function validateUploadSize()
{
$post_max_size = Tools::getMaxUploadSize();
if ($post_max_size
&& isset($_SERVER['CONTENT_LENGTH'])
&& $_SERVER['CONTENT_LENGTH']
&& $_SERVER['CONTENT_LENGTH'] > $post_max_size
) {
throw new Exception($this->trans('The uploaded file is too large.', array(), 'Admin.Design.Notification'));
}
}
/**
* Set redirect_after to same URL, but with an "&error" flag.
*/
protected function addErrorToRedirectAfter()
{
$this->redirect_after = self::$currentIndex . '&token=' . $this->token . '&error';
}
/**
* Specific postProcess for "exporttheme" action.
*
* @return bool false if access not granted
*/
protected function postProcessExportTheme()
{
try {
$this->validateAddAuthorization(true);
} catch (Exception $e) {
$this->errors[] = $this->trans(
'You do not have permission to edit this.',
array(),
'Admin.Notifications.Error'
);
return false;
}
$exporter = SymfonyContainer::getInstance()->get('prestashop.core.addon.theme.exporter');
$path = $exporter->export($this->context->shop->theme);
$this->confirmations[] = $this->trans(
'Your theme has been correctly exported: %path%',
['%path%' => $path],
'Admin.Notifications.Success'
);
return true;
}
/**
* Specific postProcess for "submitAddconfiguration" action.
*/
protected function postProcessSubmitAddConfiguration()
{
try {
$this->validateAddAuthorization();
if ($filename = Tools::getValue('theme_archive_server')) {
$path = _PS_ALL_THEMES_DIR_ . $filename;
$this->theme_manager->install($path);
} elseif ($filename = Tools::getValue('themearchive')) {
$path = _PS_ALL_THEMES_DIR_ . $filename;
$destination = $this->processUploadFile($path);
if (!empty($destination)) {
$this->theme_manager->install($destination);
@unlink($destination);
}
} elseif ($source = Tools::getValue('themearchiveUrl')) {
$this->theme_manager->install($source);
}
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
if (empty($this->errors)) {
$this->redirect_after = $this->context->link->getAdminLink('AdminThemes');
}
}
/**
* Specific postProcess for "submitConfigureLayouts" action.
*/
protected function postProcessSubmitConfigureLayouts()
{
try {
$this->validateEditAuthorization();
$this->processSubmitConfigureLayouts();
$this->redirect_after = $this->context->link->getAdminLink('AdminThemes');
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
}
/**
* Specific postProcess for "enableTheme" action.
*/
protected function postProcessEnableTheme()
{
try {
$this->validateEditAuthorization();
$isThemeEnabled = $this->theme_manager->enable(Tools::getValue('theme_name'));
// get errors if theme wasn't enabled
if (!$isThemeEnabled) {
$this->errors[] = $this->theme_manager->getErrors(Tools::getValue('theme_name'));
} else {
Tools::clearSmartyCache();
Tools::clearCache();
$this->redirect_after = $this->context->link->getAdminLink('AdminThemes');
}
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
}
/**
* Specific postProcess for "deleteTheme" action.
*/
protected function postProcessDeleteTheme()
{
try {
$this->validateDeleteAuthorization();
$this->theme_manager->uninstall(Tools::getValue('theme_name'));
$this->redirect_after = $this->context->link->getAdminLink('AdminThemes');
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
}
/**
* Specific postProcess for "submitGenerateRTL" action.
*/
protected function postProcessSubmitGenerateRTL()
{
try {
$this->validateEditAuthorization();
if ((bool) Tools::getValue('PS_GENERATE_RTL')) {
Language::getRtlStylesheetProcessor()
->setProcessFOThemes(array(Tools::getValue('PS_THEMES_LIST')))
->setRegenerate(true)
->process();
$this->confirmations[] = $this->trans(
'Your RTL stylesheets has been generated successfully',
array(),
'Admin.Design.Notification'
);
}
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
}
/**
* Specific postProcess for "resetToDefaults" action.
*/
protected function postProcessResetToDefaults()
{
try {
$this->validateEditAuthorization();
if ($this->theme_manager->reset(Tools::getValue('theme_name'))) {
$this->confirmations[] = $this->trans(
'Your theme has been correctly reset to its default settings. You may want to regenerate your images. See the Improve > Design > Images Settings screen for the \'Regenerate thumbnails\' button.',
array(),
'Admin.Design.Notification'
);
}
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
}
/**
* Specific postProcess for "submitOptionsconfiguration" action.
*/
protected function postProcessSubmitOptionsConfiguration()
{
try {
$this->validateEditAuthorization();
Configuration::updateValue('PS_IMG_UPDATE_TIME', time());
if (Tools::getValue('PS_LOGO')) {
$this->logo_uploader->updateHeader();
}
if (Tools::getValue('PS_LOGO_MAIL')) {
$this->logo_uploader->updateMail();
}
if (Tools::getValue('PS_LOGO_INVOICE')) {
$this->logo_uploader->updateInvoice();
}
if (Tools::getValue('PS_FAVICON')) {
$this->logo_uploader->updateFavicon();
$this->redirect_after = self::$currentIndex . '&token=' . $this->token;
}
Hook::exec('actionAdminThemesControllerUpdate_optionsAfter');
} catch (PrestaShopException $e) {
$this->errors[] = $e->getMessage();
$this->addErrorToRedirectAfter();
} catch (Exception $e) {
$this->errors[] = $e->getMessage();
}
}
}