Skip to content

Commit

Permalink
[-] BO: ThemeManager on theme upload works as expected
Browse files Browse the repository at this point in the history
  • Loading branch information
mickaelandrieu committed Feb 22, 2016
1 parent 9e6b656 commit 56028c3
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 187 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<input id="{$id|escape:'html':'UTF-8'}" type="file" name="{$name|escape:'html':'UTF-8'}{if isset ($multiple) && $multiple}[]{/if}"{if isset($multiple) && $multiple} multiple="multiple"{/if} class="hide" />
<div class="dummyfile input-group">
<span class="input-group-addon"><i class="icon-file"></i></span>
<input id="{$id|escape:'html':'UTF-8'}-name" type="text" name="filename" readonly />
<input id="{$id|escape:'html':'UTF-8'}-name" type="text" name="{$name|escape:'html':'UTF-8'}" readonly />
<span class="input-group-btn">
<button id="{$id|escape:'html':'UTF-8'}-selectbutton" type="button" name="submitAddAttachments" class="btn btn-default">
<i class="icon-folder-open"></i> {if isset($multiple) && $multiple}{l s='Add files'}{else}{l s='Add file'}{/if}
Expand Down
28 changes: 28 additions & 0 deletions classes/Tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -1923,6 +1923,34 @@ public static function file_get_contents($url, $use_include_path = false, $strea
}
}

/**
* Create a local file from url
* required because ZipArchive is unable to extract from remote files.
* @param string $url the remote location
* @return bool|string false if failure, else the local filename
*/
public static function createFileFromUrl($url)
{
$remoteFile = fopen($url, "r");
if (!$remoteFile) {
return false;
}
$localFile = fopen(basename(url), "w");
if (!$localFile) {
return false;
}

while (!feof($remoteFile)) {
$data = fread($remoteFile, 1024);
fwrite($localFile, $data, 1024);
}

fclose($remoteFile);
fclose($localFile);

return basename($url);
}

public static function simplexml_load_file($url, $class_name = null)
{
$cache_id = 'Tools::simplexml_load_file'.$url;
Expand Down
210 changes: 31 additions & 179 deletions controllers/admin/AdminThemesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
*/

use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder;
use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager;
use PrestaShop\PrestaShop\Adapter\Configuration as AdapterConfiguration;
use PrestaShop\PrestaShop\Core\Shop\LogoUploader;

/**
* @property Theme $object
Expand All @@ -41,6 +40,9 @@ class AdminThemesControllerCore extends AdminController
protected $toolbar_scroll = false;
private $img_error;

/* @var LogoUploader $logo_uploader */
private $logo_uploader;

// 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';
Expand All @@ -52,6 +54,7 @@ public function __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()
Expand Down Expand Up @@ -200,34 +203,6 @@ public function ajaxProcessGetAddonsThemes()
die(Tools::file_get_contents($addons_url));
}

private function updateImages($xml)
{
$return = array();

if (isset($xml->images->image)) {
foreach ($xml->images->image as $row) {
Db::getInstance()->delete('image_type', '`name` = \''.pSQL($row['name']).'\'');
Db::getInstance()->execute('
INSERT INTO `'._DB_PREFIX_.'image_type` (`name`, `width`, `height`, `products`, `categories`, `manufacturers`, `suppliers`)
VALUES (\''.pSQL($row['name']).'\',
'.(int)$row['width'].',
'.(int)$row['height'].',
'.($row['products'] == 'true' ? 1 : 0).',
'.($row['categories'] == 'true' ? 1 : 0).',
'.($row['manufacturers'] == 'true' ? 1 : 0).',
'.($row['suppliers'] == 'true' ? 1 : 0));

$return['ok'][] = array(
'name' => strval($row['name']),
'width' => (int)$row['width'],
'height' => (int)$row['height']
);
}
}

return $return;
}

public function renderView()
{
$this->tpl_view_vars = array(
Expand Down Expand Up @@ -257,9 +232,10 @@ public function postProcess()
$path = _PS_ALL_THEMES_DIR_.$filename;
if ($this->processUploadFile($path)) {
$this->theme_manager->install($path);
@unlink($path);
}
} elseif ($source = Tools::getValue('themearchiveUrl')) {
$this->theme_manager->install($path);
$this->theme_manager->install($source);
}
$this->redirect_after = $this->context->link->getAdminLink('AdminThemes');
} elseif (Tools::getValue('action') == 'submitConfigureLayouts') {
Expand All @@ -275,6 +251,30 @@ public function postProcess()
$this->theme_manager->reset(Tools::getValue('theme_name'));
}

if (Tools::isSubmit('submitOptionsconfiguration')) {
Configuration::updateValue('PS_IMG_UPDATE_TIME', time());

try {
if (!empty(Tools::getValue('PS_LOGO'))) {
$this->logo_uploader->updateHeader();
}
if (!empty(Tools::getValue('PS_LOGO_MAIL'))) {
$this->logo_uploader->updateMail();
}
if (!empty(Tools::getValue('PS_LOGO_INVOICE'))) {
$this->logo_uploader->updateInvoice();
}
if (!empty(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();
}
}

return parent::postProcess();
}

Expand Down Expand Up @@ -320,154 +320,6 @@ public function processUploadFile($dest)
return true;
}

/**
* Update PS_LOGO
*/
public function updateOptionPsLogo()
{
$this->updateLogo('PS_LOGO', 'logo');
}

/**
* Update PS_LOGO_MOBILE
*/
public function updateOptionPsLogoMobile()
{
$this->updateLogo('PS_LOGO_MOBILE', 'logo_mobile');
}

/**
* Update PS_LOGO_MAIL
*/
public function updateOptionPsLogoMail()
{
$this->updateLogo('PS_LOGO_MAIL', 'logo_mail');
}

/**
* Update PS_LOGO_INVOICE
*/
public function updateOptionPsLogoInvoice()
{
$this->updateLogo('PS_LOGO_INVOICE', 'logo_invoice');
}

/**
* Update PS_STORES_ICON
*/
public function updateOptionPsStoresIcon()
{
$this->updateLogo('PS_STORES_ICON', 'logo_stores');
}

/**
* Generic function which allows logo upload
*
* @param $field_name
* @param $logo_prefix
*
* @return bool
*/
protected function updateLogo($field_name, $logo_prefix)
{
$id_shop = Context::getContext()->shop->id;
if (isset($_FILES[$field_name]['tmp_name']) && $_FILES[$field_name]['tmp_name'] && $_FILES[$field_name]['size']) {
if ($error = ImageManager::validateUpload($_FILES[$field_name], Tools::getMaxUploadSize())) {
$this->errors[] = $error;
return false;
}
$tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');

if (!$tmp_name || !move_uploaded_file($_FILES[$field_name]['tmp_name'], $tmp_name)) {
return false;
}

$ext = ($field_name == 'PS_STORES_ICON') ? '.gif' : '.jpg';
$logo_name = Tools::link_rewrite(Context::getContext()->shop->name).'-'
.$logo_prefix.'-'.(int)Configuration::get('PS_IMG_UPDATE_TIME').(int)$id_shop.$ext;

if (Context::getContext()->shop->getContext() == Shop::CONTEXT_ALL || $id_shop == 0
|| Shop::isFeatureActive() == false) {
$logo_name = Tools::link_rewrite(Context::getContext()->shop->name).'-'
.$logo_prefix.'-'.(int)Configuration::get('PS_IMG_UPDATE_TIME').$ext;
}

if ($field_name == 'PS_STORES_ICON') {
if (!@ImageManager::resize($tmp_name, _PS_IMG_DIR_.$logo_name, null, null, 'gif', true)) {
$this->errors[] = Tools::displayError('An error occurred while attempting to copy your logo.');
}
} else {
if (!@ImageManager::resize($tmp_name, _PS_IMG_DIR_.$logo_name)) {
$this->errors[] = Tools::displayError('An error occurred while attempting to copy your logo.');
}
}
$id_shop = null;
$id_shop_group = null;
if (!count($this->errors) && @filemtime(_PS_IMG_DIR_.Configuration::get($field_name))) {
if (Shop::isFeatureActive()) {
if (Shop::getContext() == Shop::CONTEXT_SHOP) {
$id_shop = Shop::getContextShopID();
$id_shop_group = Shop::getContextShopGroupID();
Shop::setContext(Shop::CONTEXT_ALL);
$logo_all = Configuration::get($field_name);
Shop::setContext(Shop::CONTEXT_GROUP);
$logo_group = Configuration::get($field_name);
Shop::setContext(Shop::CONTEXT_SHOP);
$logo_shop = Configuration::get($field_name);
if ($logo_all != $logo_shop && $logo_group != $logo_shop && $logo_shop != false) {
@unlink(_PS_IMG_DIR_.Configuration::get($field_name));
}
} elseif (Shop::getContext() == Shop::CONTEXT_GROUP) {
$id_shop_group = Shop::getContextShopGroupID();
Shop::setContext(Shop::CONTEXT_ALL);
$logo_all = Configuration::get($field_name);
Shop::setContext(Shop::CONTEXT_GROUP);
if ($logo_all != Configuration::get($field_name)) {
@unlink(_PS_IMG_DIR_.Configuration::get($field_name));
}
}
} else {
@unlink(_PS_IMG_DIR_.Configuration::get($field_name));
}
}
Configuration::updateValue($field_name, $logo_name, false, $id_shop_group, $id_shop);
Hook::exec('actionAdminThemesControllerUpdate_optionsAfter');
@unlink($tmp_name);
}
}

/**
* Update PS_FAVICON
*/
public function updateOptionPsFavicon()
{
$id_shop = Context::getContext()->shop->id;
if ($id_shop == Configuration::get('PS_SHOP_DEFAULT')) {
$this->uploadIco('PS_FAVICON', _PS_IMG_DIR_.'favicon.ico');
}
if ($this->uploadIco('PS_FAVICON', _PS_IMG_DIR_.'favicon-'.(int)$id_shop.'.ico')) {
Configuration::updateValue('PS_FAVICON', 'favicon-'.(int)$id_shop.'.ico');
}

Configuration::updateGlobalValue('PS_FAVICON', 'favicon.ico');
$this->redirect_after = self::$currentIndex.'&token='.$this->token;
}

protected function uploadIco($name, $dest)
{
if (isset($_FILES[$name]['tmp_name']) && !empty($_FILES[$name]['tmp_name'])) {
// Check ico validity
if ($error = ImageManager::validateIconUpload($_FILES[$name])) {
$this->errors[] = $error;
} elseif (!copy($_FILES[$name]['tmp_name'], $dest)) {
// Copy new ico
$this->errors[] = sprintf(Tools::displayError('An error occurred while uploading the favicon: cannot copy file "%s" to folder "%s".'), $_FILES[$name]['tmp_name'], $dest);
}
}

return !count($this->errors);
}

/**
* Function used to render the options for this controller
*/
Expand Down
17 changes: 10 additions & 7 deletions src/Core/Addon/Theme/ThemeManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ public function __construct(
*/
public function install($source)
{
if ((filter_var($source, FILTER_VALIDATE_URL))) {
$source = Tools::createFileFromUrl($source);
}
if (preg_match('/\.zip$/', $source)) {
$this->installFromZip($source);
}
Expand Down Expand Up @@ -230,7 +233,7 @@ private function installFromZip($source)
Tools::ZipExtract($source, $sandboxPath);

$directories = $this->finder->directories()
->in($sandbox_path)
->in($sandboxPath)
->depth('== 0')
->exclude(['__MACOSX'])
->ignoreVCS();
Expand All @@ -243,28 +246,28 @@ private function installFromZip($source)
$directories = iterator_to_array($directories);
$theme_name = basename(current($directories)->getFileName());

$theme_data = (new Parser())->parse($sandboxPath.$theme_name.'/config/theme.yml');
$theme_data = (new Parser())->parse(file_get_contents($sandboxPath.$theme_name.'/config/theme.yml'));
$theme_data['directory'] = $sandboxPath.$theme_name;
if (!$this->themeValidator->isValid(new Theme($theme_data))) {
$this->filesystem->remove($sandboxPath);
throw new Exception("This theme is not valid for PrestaShop 1.7");
}

$module_root_dir = $this->configurator->get('_PS_MODULE_DIR_');
$modules_parent_dir = $sandbox_path.$theme_name.'/dependencies/modules';
$modules_parent_dir = $sandboxPath.$theme_name.'/dependencies/modules';
if ($this->fs->exists($modules_parent_dir)) {
$module_dirs = $this->finder->directories()
->in($modules_parent_dir)
->depth('== 0')
->exclude($theme_name);

foreach (iterator_to_array($module_dirs) as $dir) {
$dest = $module_root_dir.basename($dir->getFileName());
if (!$this->fs->exists($dest)) {
$this->fs->mkdir($dest);
$destination = $module_root_dir.basename($dir->getFileName());
if (!$this->fs->exists($destination)) {
$this->fs->mkdir($destination);
$this->fs->mirror(
$dir->getPathName(),
$dest
$destination
);
}
}
Expand Down
Loading

0 comments on commit 56028c3

Please sign in to comment.