1<?php 2/** 3 * Copyright since 2007 PrestaShop SA and Contributors 4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA 5 * 6 * NOTICE OF LICENSE 7 * 8 * This source file is subject to the Open Software License (OSL 3.0) 9 * that is bundled with this package in the file LICENSE.md. 10 * It is also available through the world-wide-web at this URL: 11 * https://opensource.org/licenses/OSL-3.0 12 * If you did not receive a copy of the license and are unable to 13 * obtain it through the world-wide-web, please send an email 14 * to license@prestashop.com so we can send you a copy immediately. 15 * 16 * DISCLAIMER 17 * 18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer 19 * versions in the future. If you wish to customize PrestaShop for your 20 * needs please refer to https://devdocs.prestashop.com/ for more information. 21 * 22 * @author PrestaShop SA and Contributors <contact@prestashop.com> 23 * @copyright Since 2007 PrestaShop SA and Contributors 24 * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) 25 */ 26 27namespace PrestaShop\PrestaShop\Core\Shop; 28 29use Configuration; 30use Context; 31use ImageManager; 32use PrestaShopException; 33use Shop; 34use Tools; 35 36/** 37 * Class LogoUploader used to manage upload of Shop logos and favicon. 38 */ 39class LogoUploader 40{ 41 /** 42 * @var Shop 43 */ 44 private $shop; 45 46 /** 47 * @var array 48 */ 49 private $errors = []; 50 51 public function __construct(Shop $shop) 52 { 53 $this->shop = $shop; 54 } 55 56 public function updateHeader() 57 { 58 if ($this->update('PS_LOGO', 'logo')) { 59 list($width, $height) = getimagesize(_PS_IMG_DIR_ . Configuration::get('PS_LOGO')); 60 Configuration::updateValue('SHOP_LOGO_HEIGHT', (int) round($height)); 61 Configuration::updateValue('SHOP_LOGO_WIDTH', (int) round($width)); 62 } 63 } 64 65 public function updateMail() 66 { 67 $this->update('PS_LOGO_MAIL', 'logo_mail'); 68 } 69 70 public function updateInvoice() 71 { 72 $this->update('PS_LOGO_INVOICE', 'logo_invoice'); 73 } 74 75 public function updateFavicon() 76 { 77 $shopId = (int) $this->shop->id; 78 if ($shopId == Configuration::get('PS_SHOP_DEFAULT')) { 79 $this->uploadIco('PS_FAVICON', _PS_IMG_DIR_ . 'favicon.ico'); 80 } 81 if ($this->uploadIco('PS_FAVICON', _PS_IMG_DIR_ . 'favicon-' . $shopId . '.ico')) { 82 Configuration::updateValue('PS_FAVICON', 'favicon-' . $shopId . '.ico'); 83 } 84 85 Configuration::updateGlobalValue('PS_FAVICON', 'favicon.ico'); 86 } 87 88 /** 89 * Generic function which allows logo upload. 90 * 91 * @param string $fieldName 92 * @param string $logoPrefix 93 * @param array<string,array<string,string>> $files[] the array of files to avoid use $_POST 94 * 95 * @return bool 96 * 97 * @throws PrestaShopException in case of upload failure 98 */ 99 public function update($fieldName, $logoPrefix, array $files = []) 100 { 101 $files = empty($files) ? $_FILES : $files; 102 103 if (isset($files[$fieldName]['tmp_name'], $files[$fieldName]['tmp_name'], $files[$fieldName]['size'])) { 104 if ($error = ImageManager::validateUpload($files[$fieldName], Tools::getMaxUploadSize())) { 105 throw new PrestaShopException($error); 106 } 107 $tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS'); 108 109 if (!$tmpName || !move_uploaded_file($files[$fieldName]['tmp_name'], $tmpName)) { 110 throw new PrestaShopException(sprintf('%Upload of temporary file to %s has failed.', $tmpName)); 111 } 112 113 $fileExtension = ($fieldName == 'PS_STORES_ICON') ? '.gif' : '.jpg'; 114 $logoName = $this->getLogoName($logoPrefix, $fileExtension); 115 116 if ($fieldName == 'PS_STORES_ICON') { 117 if (!@ImageManager::resize($tmpName, _PS_IMG_DIR_ . $logoName, null, null, 'gif', true)) { 118 throw new PrestaShopException(sprintf('An error occurred while attempting to copy shop icon %s.', $logoName)); 119 } 120 } else { 121 if (!@ImageManager::resize($tmpName, _PS_IMG_DIR_ . $logoName)) { 122 throw new PrestaShopException(sprintf('An error occurred while attempting to copy shop logo %s.', $logoName)); 123 } 124 } 125 126 $idShop = $this->shop->id; 127 $idShopGroup = null; 128 129 if (!count($this->errors) && @filemtime(_PS_IMG_DIR_ . Configuration::get($fieldName))) { 130 if (Shop::isFeatureActive()) { 131 $this->updateInMultiShopContext($idShop, $idShopGroup, $fieldName); 132 } else { 133 @unlink(_PS_IMG_DIR_ . Configuration::get($fieldName)); 134 } 135 } 136 137 Configuration::updateValue($fieldName, $logoName, false, $idShopGroup, $idShop); 138 unlink($tmpName); 139 140 return true; 141 } 142 143 return false; 144 } 145 146 private function updateInMultiShopContext(&$idShop, &$idShopGroup, $fieldName) 147 { 148 if (Shop::getContext() == Shop::CONTEXT_SHOP) { 149 $idShop = Shop::getContextShopID(); 150 $idShopGroup = Shop::getContextShopGroupID(); 151 Shop::setContext(Shop::CONTEXT_ALL); 152 $logoAll = Configuration::get($fieldName); 153 Shop::setContext(Shop::CONTEXT_GROUP); 154 $logoGroup = Configuration::get($fieldName); 155 Shop::setContext(Shop::CONTEXT_SHOP); 156 $logoShop = Configuration::get($fieldName); 157 if ($logoAll != $logoShop && $logoGroup != $logoShop && $logoShop != false) { 158 @unlink(_PS_IMG_DIR_ . Configuration::get($fieldName)); 159 } 160 } elseif (Shop::getContext() == Shop::CONTEXT_GROUP) { 161 $idShopGroup = Shop::getContextShopGroupID(); 162 Shop::setContext(Shop::CONTEXT_ALL); 163 $logoAll = Configuration::get($fieldName); 164 Shop::setContext(Shop::CONTEXT_GROUP); 165 if ($logoAll != Configuration::get($fieldName)) { 166 @unlink(_PS_IMG_DIR_ . Configuration::get($fieldName)); 167 } 168 } 169 } 170 171 public function uploadIco($name, $destination, $files = []) 172 { 173 $files = empty($files) ? $_FILES : $files; 174 175 if (isset($files[$name]['tmp_name']) && !empty($files[$name]['tmp_name'])) { 176 if ($error = ImageManager::validateIconUpload($files[$name])) { 177 throw new PrestaShopException($error); 178 } elseif (!copy($_FILES[$name]['tmp_name'], $destination)) { 179 throw new PrestaShopException(Context::getContext()->getTranslator()->trans('An error occurred while uploading the favicon: cannot copy file "%s" to folder "%s".', [$files[$name]['tmp_name'], $destination], 'Admin.Design.Notification')); 180 } 181 } 182 183 return !count($this->errors); 184 } 185 186 /** 187 * @param string $logoPrefix 188 * @param string $fileExtension 189 * 190 * @return string 191 */ 192 private function getLogoName($logoPrefix, $fileExtension) 193 { 194 $shopId = $this->shop->id; 195 196 $logoName = $logoPrefix 197 . '-' 198 . (int) Configuration::get('PS_IMG_UPDATE_TIME') 199 . (int) $shopId . $fileExtension; 200 201 if ($this->shop->getContext() == Shop::CONTEXT_ALL 202 || $shopId == 0 203 || Shop::isFeatureActive() == false 204 ) { 205 $logoName = $logoPrefix . '-' . (int) Configuration::get('PS_IMG_UPDATE_TIME') . $fileExtension; 206 } 207 208 return $logoName; 209 } 210} 211