[performance] MC-37459: Support by Magento Catalog (#6223)

* MC-37459: Support by Magento Catalog
This commit is contained in:
Andrii Lugovyi authored and GitHub committed 2020-10-22 16:21:34 -05:00
1 parent 8953e85031
commit 640cad5300
97 files changed
+1045 -1954

No files matched your search

+7 -393
View File
@@ -1,393 +1,7 @@
############################################
## overrides deployment configuration mode value
## use command bin/magento deploy:mode:set to switch modes
# SetEnv MAGE_MODE developer
############################################
## uncomment these lines for CGI mode
## make sure to specify the correct cgi php binary file name
## it might be /cgi-bin/php-cgi
# Action php5-cgi /cgi-bin/php5-cgi
# AddHandler php5-cgi .php
############################################
## GoDaddy specific options
# Options -MultiViews
## you might also need to add this line to php.ini
## cgi.fix_pathinfo = 1
## if it still doesn't work, rename php.ini to php5.ini
############################################
## this line is specific for 1and1 hosting
#AddType x-mapp-php5 .php
#AddHandler x-mapp-php5 .php
############################################
## enable usage of methods arguments in backtrace
SetEnv MAGE_DEBUG_SHOW_ARGS 1
############################################
## default index file
DirectoryIndex index.php
<IfModule mod_php7.c>
############################################
## adjust memory limit
php_value memory_limit 756M
php_value max_execution_time 18000
############################################
## disable automatic session start
## before autoload was initialized
php_flag session.auto_start off
############################################
## enable resulting html compression
#php_flag zlib.output_compression on
###########################################
## disable user agent verification to not break multiple image upload
php_flag suhosin.session.cryptua off
</IfModule>
<IfModule mod_security.c>
###########################################
## disable POST processing to not break multiple image upload
SecFilterEngine Off
SecFilterScanPOST Off
</IfModule>
<IfModule mod_deflate.c>
############################################
## enable apache served files compression
## http://developer.yahoo.com/performance/rules.html#gzip
# Insert filter on all content
###SetOutputFilter DEFLATE
# Insert filter on selected content types only
#AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript application/json image/svg+xml
# Netscape 4.x has some problems...
#BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
#BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
#BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# Don't compress images
#SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
# Make sure proxies don't deliver the wrong content
#Header append Vary User-Agent env=!dont-vary
</IfModule>
<IfModule mod_ssl.c>
############################################
## make HTTPS env vars available for CGI mode
SSLOptions StdEnvVars
</IfModule>
############################################
## workaround for Apache 2.4.6 CentOS build when working via ProxyPassMatch with HHVM (or any other)
## Please, set it on virtual host configuration level
## SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
############################################
<IfModule mod_rewrite.c>
############################################
## enable rewrites
Options +FollowSymLinks
RewriteEngine on
############################################
## you can put here your magento root folder
## path relative to web root
#RewriteBase /magento/
############################################
## workaround for HTTP authorization
## in CGI environment
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
############################################
## TRACE and TRACK HTTP methods disabled to prevent XSS attacks
RewriteCond %{REQUEST_METHOD} ^TRAC[EK]
RewriteRule .* - [L,R=405]
############################################
## redirect for mobile user agents
#RewriteCond %{REQUEST_URI} !^/mobiledirectoryhere/.*$
#RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC]
#RewriteRule ^(.*)$ /mobiledirectoryhere/ [L,R=302]
############################################
## never rewrite for existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
############################################
## rewrite everything else to index.php
RewriteRule .* index.php [L]
</IfModule>
############################################
## Prevent character encoding issues from server overrides
## If you still have problems, use the second line instead
AddDefaultCharset Off
#AddDefaultCharset UTF-8
AddType 'text/html; charset=UTF-8' html
<IfModule mod_expires.c>
############################################
## Add default Expires header
## http://developer.yahoo.com/performance/rules.html#expires
ExpiresDefault "access plus 1 year"
ExpiresByType text/html A0
ExpiresByType text/plain A0
</IfModule>
###########################################
## Deny access to root files to hide sensitive application information
RedirectMatch 403 /\.git
<Files composer.json>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files composer.lock>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files .gitignore>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files .htaccess>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files .htaccess.sample>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files .php_cs.dist>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files CHANGELOG.md>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files COPYING.txt>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files Gruntfile.js>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files LICENSE.txt>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files LICENSE_AFL.txt>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files nginx.conf.sample>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files package.json>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files php.ini.sample>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files README.md>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files magento_umask>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files auth.json>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
<Files .user.ini>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
# For 404s and 403s that aren't handled by the application, show plain 404 response
ErrorDocument 404 /pub/errors/404.php
ErrorDocument 403 /pub/errors/404.php
################################
## If running in cluster environment, uncomment this
## http://developer.yahoo.com/performance/rules.html#etags
#FileETag none
# ######################################################################
# # INTERNET EXPLORER #
# ######################################################################
# ----------------------------------------------------------------------
# | Document modes |
# ----------------------------------------------------------------------
# Force Internet Explorer 8/9/10 to render pages in the highest mode
# available in the various cases when it may not.
#
# https://hsivonen.fi/doctype/#ie8
#
# (!) Starting with Internet Explorer 11, document modes are deprecated.
# If your business still relies on older web apps and services that were
# designed for older versions of Internet Explorer, you might want to
# consider enabling `Enterprise Mode` throughout your company.
#
# https://msdn.microsoft.com/en-us/library/ie/bg182625.aspx#docmode
# http://blogs.msdn.com/b/ie/archive/2014/04/02/stay-up-to-date-with-enterprise-mode-for-internet-explorer-11.aspx
<IfModule mod_headers.c>
Header set X-UA-Compatible "IE=edge"
# `mod_headers` cannot match based on the content-type, however,
# the `X-UA-Compatible` response header should be send only for
# HTML documents and not for the other resources.
<FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ico|jpe?g|js|json(ld)?|m4[av]|manifest|map|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xml|xpi)$">
Header unset X-UA-Compatible
</FilesMatch>
</IfModule>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/pub/
RewriteCond %{REQUEST_URI} !^/setup/
RewriteCond %{REQUEST_URI} !^/update/
RewriteCond %{REQUEST_URI} !^/dev/
RewriteRule .* /pub/$0 [L]
DirectoryIndex index.php
@@ -90,7 +90,7 @@ class LinkProviderTest extends TestCase
public function testGet()
{
$baseUrl = 'http://magento.local/pub/media/';
$baseUrl = 'http://magento.local/media/';
$fileInfoPath = 'analytics/data.tgz';
$fileInitializationVector = 'er312esq23eqq';
$this->fileInfoManagerMock->expects($this->once())
+70 -19
View File
@@ -11,6 +11,7 @@ use League\Flysystem\AwsS3v3\AwsS3Adapter;
use League\Flysystem\Config;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem\DriverInterface;
use Magento\Framework\Phrase;
/**
* Driver for AWS S3 IO operations.
@@ -232,14 +233,14 @@ class AwsS3 implements DriverInterface
*/
public function getAbsolutePath($basePath, $path, $scheme = null)
{
$basePath = $this->normalizeRelativePath((string)$basePath);
$path = $this->normalizeRelativePath((string)$path);
if ($basePath && $path && 0 === strpos($path, $basePath)) {
return $this->normalizeAbsolutePath(
$this->normalizeRelativePath($path)
);
return $this->normalizeAbsolutePath($path);
}
if ($basePath && $basePath !== '/') {
return $basePath . ltrim((string)$path, '/');
$path = $basePath . ltrim((string)$path, '/');
}
return $this->normalizeAbsolutePath($path);
@@ -328,7 +329,10 @@ class AwsS3 implements DriverInterface
$path = rtrim($path, '/') . '/';
return $this->adapter->has($path) && $this->adapter->getMetadata($path)['type'] === self::TYPE_DIR;
if ($this->adapter->has($path) && ($meta = $this->adapter->getMetadata($path))) {
return ($meta['type'] ?? null) === self::TYPE_DIR;
}
return false;
}
/**
@@ -383,7 +387,7 @@ class AwsS3 implements DriverInterface
$metaInfo = $this->adapter->getMetadata($path);
if (!$metaInfo) {
throw new FileSystemException(__('Cannot gather stats! %1', (array)$path));
throw new FileSystemException(__('Cannot gather stats! %1', [$this->getWarningMessage()]));
}
return [
@@ -486,7 +490,16 @@ class AwsS3 implements DriverInterface
*/
public function fileReadLine($resource, $length, $ending = null): string
{
throw new FileSystemException(__('Method %1 is not supported', __METHOD__));
// phpcs:disable
$result = @stream_get_line($resource, $length, $ending);
// phpcs:enable
if (false === $result) {
throw new FileSystemException(
new Phrase('File cannot be read %1', [$this->getWarningMessage()])
);
}
return $result;
}
/**
@@ -521,7 +534,13 @@ class AwsS3 implements DriverInterface
*/
public function fileTell($resource): int
{
throw new FileSystemException(__('Method %1 is not supported', __METHOD__));
$result = @ftell($resource);
if ($result === null) {
throw new FileSystemException(
new Phrase('An error occurred during "%1" execution.', [$this->getWarningMessage()])
);
}
return $result;
}
/**
@@ -529,7 +548,16 @@ class AwsS3 implements DriverInterface
*/
public function fileSeek($resource, $offset, $whence = SEEK_SET): int
{
throw new FileSystemException(__('Method %1 is not supported', __METHOD__));
$result = @fseek($resource, $offset, $whence);
if ($result === -1) {
throw new FileSystemException(
new Phrase(
'An error occurred during "%1" fileSeek execution.',
[$this->getWarningMessage()]
)
);
}
return $result;
}
/**
@@ -537,7 +565,7 @@ class AwsS3 implements DriverInterface
*/
public function endOfFile($resource): bool
{
throw new FileSystemException(__('Method %1 is not supported', __METHOD__));
return feof($resource);
}
/**
@@ -554,7 +582,16 @@ class AwsS3 implements DriverInterface
*/
public function fileFlush($resource): bool
{
throw new FileSystemException(__('Method %1 is not supported', __METHOD__));
$result = @fflush($resource);
if (!$result) {
throw new FileSystemException(
new Phrase(
'An error occurred during "%1" fileFlush execution.',
[$this->getWarningMessage()]
)
);
}
return $result;
}
/**
@@ -562,7 +599,16 @@ class AwsS3 implements DriverInterface
*/
public function fileLock($resource, $lockMode = LOCK_EX): bool
{
throw new FileSystemException(__('Method %1 is not supported', __METHOD__));
$result = @flock($resource, $lockMode);
if (!$result) {
throw new FileSystemException(
new Phrase(
'An error occurred during "%1" fileLock execution.',
[$this->getWarningMessage()]
)
);
}
return $result;
}
/**
@@ -570,7 +616,16 @@ class AwsS3 implements DriverInterface
*/
public function fileUnlock($resource): bool
{
throw new FileSystemException(__('Method %1 is not supported', __METHOD__));
$result = @flock($resource, LOCK_UN);
if (!$result) {
throw new FileSystemException(
new Phrase(
'An error occurred during "%1" fileUnlock execution.',
[$this->getWarningMessage()]
)
);
}
return $result;
}
/**
@@ -627,15 +682,11 @@ class AwsS3 implements DriverInterface
if (!isset($this->streams[$path])) {
$this->streams[$path] = tmpfile();
if ($this->adapter->has($path)) {
$file = tmpfile();
//phpcs:ignore Magento2.Functions.DiscouragedFunction
fwrite($file, $this->adapter->read($path)['contents']);
fwrite($this->streams[$path], $this->adapter->read($path)['contents']);
//phpcs:ignore Magento2.Functions.DiscouragedFunction
fseek($file, 0);
} else {
$file = tmpfile();
rewind($this->streams[$path]);
}
$this->streams[$path] = $file;
}
return $this->streams[$path];
@@ -105,16 +105,46 @@ class AwsS3Test extends TestCase
self::URL . 'test/test.png',
self::URL . 'test/test.png'
],
[
self::URL,
self::URL . 'media/catalog/test.png',
self::URL . 'media/catalog/test.png'
],
[
'',
self::URL . 'media/catalog/test.png',
self::URL . 'media/catalog/test.png'
],
[
self::URL . 'test/',
'test.txt',
self::URL . 'test/test.txt'
],
[
self::URL . 'media/',
'media/image.jpg',
self::URL . 'media/image.jpg'
],
[
self::URL . 'media/',
'/catalog/test.png',
self::URL . 'media/catalog/test.png'
],
[
self::URL,
'var/import/images',
self::URL . 'var/import/images'
],
[
self::URL . 'export/',
null,
self::URL . 'export/'
],
[
self::URL . 'var/import/images/product_images/',
self::URL . 'var/import/images/product_images/1.png',
self::URL . 'var/import/images/product_images/1.png'
],
[
'',
self::URL . 'media/catalog/test.png',
@@ -6,8 +6,6 @@
namespace Magento\Backup\Model\Fs;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Config\DocumentRoot;
use Magento\Framework\Filesystem\Directory\TargetDirectory;
/**
* Backup data collection
@@ -52,20 +50,16 @@ class Collection extends \Magento\Framework\Data\Collection\Filesystem
* @param \Magento\Backup\Helper\Data $backupData
* @param \Magento\Framework\Filesystem $filesystem
* @param \Magento\Backup\Model\Backup $backup
* @param TargetDirectory|null $targetDirectory
* @param DocumentRoot|null $documentRoot
* @throws \Magento\Framework\Exception\FileSystemException
*/
public function __construct(
\Magento\Framework\Data\Collection\EntityFactory $entityFactory,
\Magento\Backup\Helper\Data $backupData,
\Magento\Framework\Filesystem $filesystem,
\Magento\Backup\Model\Backup $backup,
TargetDirectory $targetDirectory = null,
DocumentRoot $documentRoot = null
\Magento\Backup\Model\Backup $backup
) {
$this->_backupData = $backupData;
parent::__construct($entityFactory, $targetDirectory, $documentRoot);
parent::__construct($entityFactory, $filesystem);
$this->_filesystem = $filesystem;
$this->_backup = $backup;
@@ -197,7 +197,7 @@ class DataTest extends TestCase
*/
public function testGetImgUrl()
{
$this->assertEquals($this->helper->getImgUrl(), 'http://localhost/pub/media/captcha/base/');
$this->assertEquals($this->helper->getImgUrl(), 'http://localhost/media/captcha/base/');
}
/**
@@ -223,7 +223,7 @@ class DataTest extends TestCase
{
$store = $this->createMock(Store::class);
$store->expects($this->any())->method('getBaseUrl')->willReturn('http://localhost/pub/media/');
$store->expects($this->any())->method('getBaseUrl')->willReturn('http://localhost/media/');
return $store;
}
@@ -217,7 +217,7 @@ class DefaultTest extends TestCase
{
$this->assertEquals(
$this->_object->getImgSrc(),
'http://localhost/pub/media/captcha/base/' . $this->_object->getId() . '.png'
'http://localhost/media/captcha/base/' . $this->_object->getId() . '.png'
);
}
@@ -310,7 +310,7 @@ class DefaultTest extends TestCase
)->method(
'getImgUrl'
)->willReturn(
'http://localhost/pub/media/captcha/base/'
'http://localhost/media/captcha/base/'
);
return $helper;
@@ -365,7 +365,7 @@ class DefaultTest extends TestCase
->onlyMethods(['getBaseUrl'])
->disableOriginalConstructor()
->getMock();
$store->expects($this->any())->method('getBaseUrl')->willReturn('http://localhost/pub/media/');
$store->expects($this->any())->method('getBaseUrl')->willReturn('http://localhost/media/');
$store->expects($this->any())->method('isAdmin')->willReturn(false);
return $store;
}
+23 -4
View File
@@ -5,7 +5,10 @@
*/
namespace Magento\Catalog\Helper;
use Magento\Catalog\Model\Config\CatalogMediaConfig;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Element\Block\ArgumentInterface;
/**
@@ -133,27 +136,34 @@ class Image extends AbstractHelper implements ArgumentInterface
*/
private $viewAssetPlaceholderFactory;
/**
* @var CatalogMediaConfig
*/
private $mediaConfig;
/**
* @param \Magento\Framework\App\Helper\Context $context
* @param \Magento\Catalog\Model\Product\ImageFactory $productImageFactory
* @param \Magento\Framework\View\Asset\Repository $assetRepo
* @param \Magento\Framework\View\ConfigInterface $viewConfig
* @param \Magento\Catalog\Model\View\Asset\PlaceholderFactory $placeholderFactory
* @param CatalogMediaConfig $mediaConfig
*/
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Catalog\Model\Product\ImageFactory $productImageFactory,
\Magento\Framework\View\Asset\Repository $assetRepo,
\Magento\Framework\View\ConfigInterface $viewConfig,
\Magento\Catalog\Model\View\Asset\PlaceholderFactory $placeholderFactory = null
\Magento\Catalog\Model\View\Asset\PlaceholderFactory $placeholderFactory = null,
CatalogMediaConfig $mediaConfig = null
) {
$this->_productImageFactory = $productImageFactory;
parent::__construct($context);
$this->_assetRepo = $assetRepo;
$this->viewConfig = $viewConfig;
$this->viewAssetPlaceholderFactory = $placeholderFactory
?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Catalog\Model\View\Asset\PlaceholderFactory::class);
?: ObjectManager::getInstance()->get(\Magento\Catalog\Model\View\Asset\PlaceholderFactory::class);
$this->mediaConfig = $mediaConfig ?: ObjectManager::getInstance()->get(CatalogMediaConfig::class);
}
/**
@@ -532,7 +542,16 @@ class Image extends AbstractHelper implements ArgumentInterface
public function getUrl()
{
try {
$this->applyScheduledActions();
switch ($this->mediaConfig->getMediaUrlFormat()) {
case CatalogMediaConfig::IMAGE_OPTIMIZATION_PARAMETERS:
$this->initBaseFile();
break;
case CatalogMediaConfig::HASH:
$this->applyScheduledActions();
break;
default:
throw new LocalizedException(__("The specified Catalog media URL format is not supported."));
}
return $this->_getModel()->getUrl();
} catch (\Exception $e) {
return $this->getDefaultPlaceholderUrl();
@@ -0,0 +1,50 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Catalog\Model\Config;
use Magento\Framework\App\Config\ScopeConfigInterface;
/**
* Config for catalog media
*/
class CatalogMediaConfig
{
private const XML_PATH_CATALOG_MEDIA_URL_FORMAT = 'web/url/catalog_media_url_format';
const IMAGE_OPTIMIZATION_PARAMETERS = 'image_optimization_parameters';
const HASH = 'hash';
/**
* @var ScopeConfigInterface
*/
private $scopeConfig;
/**
* @param ScopeConfigInterface $scopeConfig
*/
public function __construct(ScopeConfigInterface $scopeConfig)
{
$this->scopeConfig = $scopeConfig;
}
/**
* Get media URL format for catalog images
*
* @param string $scopeType
* @param null|int|string $scopeCode
* @return string
*/
public function getMediaUrlFormat($scopeType = ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $scopeCode = null): string
{
return $this->scopeConfig->getValue(
CatalogMediaConfig::XML_PATH_CATALOG_MEDIA_URL_FORMAT,
$scopeType,
$scopeCode
);
}
}
@@ -0,0 +1,33 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Catalog\Model\Config\Source\Web;
use Magento\Catalog\Model\Config\CatalogMediaConfig;
/**
* Option provider for catalog media URL format system setting.
*/
class CatalogMediaUrlFormat implements \Magento\Framework\Data\OptionSourceInterface
{
/**
* Get a list of supported catalog media URL formats.
*
* @codeCoverageIgnore
* @return array
*/
public function toOptionArray(): array
{
return [
[
'value' => CatalogMediaConfig::IMAGE_OPTIMIZATION_PARAMETERS,
'label' => __('Image optimization based on query parameters')
],
['value' => CatalogMediaConfig::HASH, 'label' => __('Unique hash per image variant (Legacy mode)')]
];
}
}
@@ -10,9 +10,11 @@ use Magento\Catalog\Model\View\Asset\ImageFactory;
use Magento\Catalog\Model\View\Asset\PlaceholderFactory;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Image as MagentoImage;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Catalog\Model\Product\Image\ParamsBuilder;
use Magento\Framework\Filesystem\Driver\File as FilesystemDriver;
/**
* Image operations
@@ -101,6 +103,7 @@ class Image extends \Magento\Framework\Model\AbstractModel
/**
* @var int
* @deprecated unused
*/
protected $_angle;
@@ -199,6 +202,11 @@ class Image extends \Magento\Framework\Model\AbstractModel
*/
private $serializer;
/**
* @var FilesystemDriver
*/
private $filesystemDriver;
/**
* Constructor
*
@@ -219,6 +227,8 @@ class Image extends \Magento\Framework\Model\AbstractModel
* @param array $data
* @param SerializerInterface $serializer
* @param ParamsBuilder $paramsBuilder
* @param FilesystemDriver $filesystemDriver
* @throws \Magento\Framework\Exception\FileSystemException
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
@@ -239,7 +249,8 @@ class Image extends \Magento\Framework\Model\AbstractModel
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = [],
SerializerInterface $serializer = null,
ParamsBuilder $paramsBuilder = null
ParamsBuilder $paramsBuilder = null,
FilesystemDriver $filesystemDriver = null
) {
$this->_storeManager = $storeManager;
$this->_catalogProductMediaConfig = $catalogProductMediaConfig;
@@ -254,6 +265,7 @@ class Image extends \Magento\Framework\Model\AbstractModel
$this->viewAssetPlaceholderFactory = $viewAssetPlaceholderFactory;
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
$this->paramsBuilder = $paramsBuilder ?: ObjectManager::getInstance()->get(ParamsBuilder::class);
$this->filesystemDriver = $filesystemDriver ?: ObjectManager::getInstance()->get(FilesystemDriver::class);
}
/**
@@ -663,7 +675,12 @@ class Image extends \Magento\Framework\Model\AbstractModel
public function isCached()
{
$path = $this->imageAsset->getPath();
return is_array($this->loadImageInfoFromCache($path)) || file_exists($path);
try {
$isCached = is_array($this->loadImageInfoFromCache($path)) || $this->filesystemDriver->isExists($path);
} catch (FileSystemException $e) {
$isCached = false;
}
return $isCached;
}
/**
@@ -7,6 +7,7 @@
namespace Magento\Catalog\Model\Product\Media;
use Magento\Eav\Model\Entity\Attribute;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\StoreManagerInterface;
/**
@@ -76,7 +77,7 @@ class Config implements ConfigInterface
public function getBaseMediaUrl()
{
return $this->storeManager->getStore()
->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'catalog/product';
->getBaseUrl(UrlInterface::URL_TYPE_MEDIA) . $this->getBaseMediaUrlAddition();
}
/**
@@ -97,7 +98,7 @@ class Config implements ConfigInterface
public function getBaseTmpMediaUrl()
{
return $this->storeManager->getStore()->getBaseUrl(
\Magento\Framework\UrlInterface::URL_TYPE_MEDIA
UrlInterface::URL_TYPE_MEDIA
) . 'tmp/' . $this->getBaseMediaUrlAddition();
}
@@ -108,7 +108,7 @@ class Filter extends \Magento\Framework\Filter\Template
* The original intent of _absolute parameter was to simply append specified path to a base URL
* bypassing any kind of processing.
* For example, normally you would use {{view url="css/styles.css"}} directive which would automatically resolve
* into something like http://example.com/pub/static/area/theme/en_US/css/styles.css
* into something like http://example.com/static/area/theme/en_US/css/styles.css
* But with _absolute, the expected behavior is this: {{view url="favicon.ico" _absolute=true}} should resolve
* into something like http://example.com/favicon.ico
*
@@ -6,11 +6,16 @@
namespace Magento\Catalog\Model\View\Asset;
use Magento\Catalog\Model\Config\CatalogMediaConfig;
use Magento\Catalog\Model\Product\Media\ConfigInterface;
use Magento\Framework\Encryption\Encryptor;
use Magento\Framework\Encryption\EncryptorInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Asset\ContextInterface;
use Magento\Framework\View\Asset\LocalInterface;
use Magento\Catalog\Helper\Image as ImageHelper;
use Magento\Framework\App\ObjectManager;
use Magento\Store\Model\StoreManagerInterface;
/**
* A locally available image file asset that can be referred with a file path
@@ -58,6 +63,21 @@ class Image implements LocalInterface
*/
private $encryptor;
/**
* @var ImageHelper
*/
private $imageHelper;
/**
* @var StoreManagerInterface
*/
private $storeManager;
/**
* @var string
*/
private $mediaFormatUrl;
/**
* Image constructor.
*
@@ -66,13 +86,19 @@ class Image implements LocalInterface
* @param EncryptorInterface $encryptor
* @param string $filePath
* @param array $miscParams
* @param ImageHelper $imageHelper
* @param CatalogMediaConfig $catalogMediaConfig
* @param StoreManagerInterface $storeManager
*/
public function __construct(
ConfigInterface $mediaConfig,
ContextInterface $context,
EncryptorInterface $encryptor,
$filePath,
array $miscParams
array $miscParams,
ImageHelper $imageHelper = null,
CatalogMediaConfig $catalogMediaConfig = null,
StoreManagerInterface $storeManager = null
) {
if (isset($miscParams['image_type'])) {
$this->sourceContentType = $miscParams['image_type'];
@@ -85,14 +111,73 @@ class Image implements LocalInterface
$this->filePath = $filePath;
$this->miscParams = $miscParams;
$this->encryptor = $encryptor;
$this->imageHelper = $imageHelper ?: ObjectManager::getInstance()->get(ImageHelper::class);
$this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
$catalogMediaConfig = $catalogMediaConfig ?: ObjectManager::getInstance()->get(CatalogMediaConfig::class);
$this->mediaFormatUrl = $catalogMediaConfig->getMediaUrlFormat();
}
/**
* @inheritdoc
* Get catalog image URL.
*
* @return string
* @throws LocalizedException
*/
public function getUrl()
{
return $this->context->getBaseUrl() . DIRECTORY_SEPARATOR . $this->getImageInfo();
switch ($this->mediaFormatUrl) {
case CatalogMediaConfig::IMAGE_OPTIMIZATION_PARAMETERS:
return $this->getUrlWithTransformationParameters();
case CatalogMediaConfig::HASH:
return $this->context->getBaseUrl() . DIRECTORY_SEPARATOR . $this->getImageInfo();
default:
throw new LocalizedException(
__("The specified Catalog media URL format '$this->mediaFormatUrl' is not supported.")
);
}
}
/**
* Get image URL with transformation parameters
*
* @return string
*/
private function getUrlWithTransformationParameters()
{
return $this->getOriginalImageUrl() . '?' . http_build_query($this->getImageTransformationParameters());
}
/**
* The list of parameters to be used during image transformations (e.g. resizing or applying watermarks).
*
* This method can be used as an extension point.
*
* @return string[]
*/
public function getImageTransformationParameters()
{
return [
'width' => $this->miscParams['image_width'],
'height' => $this->miscParams['image_height'],
'store' => $this->storeManager->getStore()->getCode(),
'image-type' => $this->sourceContentType
];
}
/**
* Get URL to the original version of the product image.
*
* @return string
*/
private function getOriginalImageUrl()
{
$originalImageFile = $this->getSourceFile();
if (!$originalImageFile) {
return $this->imageHelper->getDefaultPlaceholderUrl();
} else {
return $this->context->getBaseUrl() . $this->getFilePath();
}
}
/**
@@ -10,7 +10,11 @@ namespace Magento\Catalog\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\State;
use Magento\MediaStorage\Service\ImageResize;
use Magento\Catalog\Model\Config\CatalogMediaConfig;
/**
* Resize product images after the product is saved
*/
class ImageResizeAfterProductSave implements ObserverInterface
{
/**
@@ -23,17 +27,26 @@ class ImageResizeAfterProductSave implements ObserverInterface
*/
private $state;
/**
* @var CatalogMediaConfig
*/
private $catalogMediaConfig;
/**
* Product constructor.
*
* @param ImageResize $imageResize
* @param State $state
* @param CatalogMediaConfig $catalogMediaConfig
*/
public function __construct(
ImageResize $imageResize,
State $state
State $state,
CatalogMediaConfig $catalogMediaConfig
) {
$this->imageResize = $imageResize;
$this->state = $state;
$this->catalogMediaConfig = $catalogMediaConfig;
}
/**
@@ -44,6 +57,12 @@ class ImageResizeAfterProductSave implements ObserverInterface
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
$catalogMediaUrlFormat = $this->catalogMediaConfig->getMediaUrlFormat();
if ($catalogMediaUrlFormat == CatalogMediaConfig::IMAGE_OPTIMIZATION_PARAMETERS) {
// Skip image resizing on the Magento side when it is offloaded to a web server or CDN
return;
}
/** @var $product \Magento\Catalog\Model\Product */
$product = $observer->getEvent()->getProduct();
@@ -1,454 +0,0 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Catalog\Test\Unit\Block\Adminhtml\Product\Helper\Form\Gallery;
use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery;
use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery\Content;
use Magento\Catalog\Helper\Image;
use Magento\Catalog\Model\Entity\Attribute;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Media\Config;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\Read;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Json\EncoderInterface;
use Magento\Framework\Phrase;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\MediaStorage\Helper\File\Storage\Database;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ContentTest extends TestCase
{
/**
* @var Filesystem|MockObject
*/
protected $fileSystemMock;
/**
* @var Read|MockObject
*/
protected $readMock;
/**
* @var Content|MockObject
*/
protected $content;
/**
* @var Config|MockObject
*/
protected $mediaConfigMock;
/**
* @var EncoderInterface|MockObject
*/
protected $jsonEncoderMock;
/**
* @var Gallery|MockObject
*/
protected $galleryMock;
/**
* @var Image|MockObject
*/
protected $imageHelper;
/**
* @var Database|MockObject
*/
protected $databaseMock;
/**
* @var ObjectManager
*/
protected $objectManager;
protected function setUp(): void
{
$this->fileSystemMock = $this->getMockBuilder(Filesystem::class)
->addMethods(['stat'])
->onlyMethods(['getDirectoryRead'])
->disableOriginalConstructor()
->getMock();
$this->readMock = $this->getMockForAbstractClass(ReadInterface::class);
$this->galleryMock = $this->createMock(Gallery::class);
$this->mediaConfigMock = $this->createPartialMock(
Config::class,
['getMediaUrl', 'getMediaPath']
);
$this->jsonEncoderMock = $this->getMockBuilder(EncoderInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->databaseMock = $this->getMockBuilder(Database::class)
->disableOriginalConstructor()
->getMock();
$this->objectManager = new ObjectManager($this);
$this->content = $this->objectManager->getObject(
Content::class,
[
'mediaConfig' => $this->mediaConfigMock,
'jsonEncoder' => $this->jsonEncoderMock,
'filesystem' => $this->fileSystemMock,
'fileStorageDatabase' => $this->databaseMock
]
);
}
public function testGetImagesJson()
{
$url = [
['file_1.jpg', 'url_to_the_image/image_1.jpg'],
['file_2.jpg', 'url_to_the_image/image_2.jpg']
];
$mediaPath = [
['file_1.jpg', 'catalog/product/image_1.jpg'],
['file_2.jpg', 'catalog/product/image_2.jpg']
];
$sizeMap = [
['catalog/product/image_1.jpg', ['size' => 399659]],
['catalog/product/image_2.jpg', ['size' => 879394]]
];
$imagesResult = [
[
'value_id' => '2',
'file' => 'file_2.jpg',
'media_type' => 'image',
'position' => '0',
'url' => 'url_to_the_image/image_2.jpg',
'size' => 879394
],
[
'value_id' => '1',
'file' => 'file_1.jpg',
'media_type' => 'image',
'position' => '1',
'url' => 'url_to_the_image/image_1.jpg',
'size' => 399659
]
];
$images = [
'images' => [
[
'value_id' => '1',
'file' => 'file_1.jpg',
'media_type' => 'image',
'position' => '1'
] ,
[
'value_id' => '2',
'file' => 'file_2.jpg',
'media_type' => 'image',
'position' => '0'
]
]
];
$this->content->setElement($this->galleryMock);
$this->galleryMock->expects($this->once())->method('getImages')->willReturn($images);
$this->fileSystemMock->expects($this->once())->method('getDirectoryRead')->willReturn($this->readMock);
$this->mediaConfigMock->method('getMediaUrl')->willReturnMap($url);
$this->mediaConfigMock->method('getMediaPath')->willReturnMap($mediaPath);
$this->readMock->method('stat')->willReturnMap($sizeMap);
$this->jsonEncoderMock->expects($this->once())->method('encode')->willReturnCallback('json_encode');
$this->readMock->method('isFile')->willReturn(true);
$this->databaseMock->method('checkDbUsage')->willReturn(false);
$this->assertSame(json_encode($imagesResult), $this->content->getImagesJson());
}
public function testGetImagesJsonWithoutImages()
{
$this->content->setElement($this->galleryMock);
$this->galleryMock->expects($this->once())->method('getImages')->willReturn(null);
$this->assertSame('[]', $this->content->getImagesJson());
}
public function testGetImagesJsonWithException()
{
$this->imageHelper = $this->getMockBuilder(Image::class)
->disableOriginalConstructor()
->setMethods(['getDefaultPlaceholderUrl'])
->getMock();
$this->objectManager->setBackwardCompatibleProperty(
$this->content,
'imageHelper',
$this->imageHelper
);
$placeholderUrl = 'url_to_the_placeholder/placeholder.jpg';
$imagesResult = [
[
'value_id' => '2',
'file' => 'file_2.jpg',
'media_type' => 'image',
'position' => '0',
'url' => 'url_to_the_placeholder/placeholder.jpg',
'size' => 0
],
[
'value_id' => '1',
'file' => 'file_1.jpg',
'media_type' => 'image',
'position' => '1',
'url' => 'url_to_the_placeholder/placeholder.jpg',
'size' => 0
]
];
$images = [
'images' => [
[
'value_id' => '1',
'file' => 'file_1.jpg',
'media_type' => 'image',
'position' => '1'
],
[
'value_id' => '2',
'file' => 'file_2.jpg',
'media_type' => 'image',
'position' => '0'
]
]
];
$this->content->setElement($this->galleryMock);
$this->galleryMock->expects($this->once())->method('getImages')->willReturn($images);
$this->fileSystemMock->method('getDirectoryRead')->willReturn($this->readMock);
$this->mediaConfigMock->method('getMediaUrl');
$this->mediaConfigMock->method('getMediaPath');
$this->readMock
->method('isFile')
->willReturn(true);
$this->databaseMock
->method('checkDbUsage')
->willReturn(false);
$this->readMock->method('stat')->willReturnOnConsecutiveCalls(
$this->throwException(
new FileSystemException(new Phrase('test'))
),
$this->throwException(
new FileSystemException(new Phrase('test'))
)
);
$this->imageHelper->method('getDefaultPlaceholderUrl')->willReturn($placeholderUrl);
$this->jsonEncoderMock->expects($this->once())->method('encode')->willReturnCallback('json_encode');
$this->assertSame(json_encode($imagesResult), $this->content->getImagesJson());
}
/**
* Test GetImageTypes() will return value for given attribute from data persistor.
*
* @return void
*/
public function testGetImageTypesFromDataPersistor()
{
$attributeCode = 'thumbnail';
$value = 'testImageValue';
$scopeLabel = 'testScopeLabel';
$label = 'testLabel';
$name = 'testName';
$expectedTypes = [
$attributeCode => [
'code' => $attributeCode,
'value' => $value,
'label' => $label,
'name' => $name,
],
];
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$product->expects($this->once())
->method('getData')
->with($this->identicalTo($attributeCode))
->willReturn(null);
$mediaAttribute = $this->getMediaAttribute($label, $attributeCode);
$product->expects($this->once())
->method('getMediaAttributes')
->willReturn([$mediaAttribute]);
$this->galleryMock->expects($this->exactly(2))
->method('getDataObject')
->willReturn($product);
$this->galleryMock->expects($this->once())
->method('getImageValue')
->with($this->identicalTo($attributeCode))
->willReturn($value);
$this->galleryMock->expects($this->once())
->method('getScopeLabel')
->with($this->identicalTo($mediaAttribute))
->willReturn($scopeLabel);
$this->galleryMock->expects($this->once())
->method('getAttributeFieldName')
->with($this->identicalTo($mediaAttribute))
->willReturn($name);
$this->getImageTypesAssertions($attributeCode, $scopeLabel, $expectedTypes);
}
/**
* Test GetImageTypes() will return value for given attribute from product.
*
* @return void
*/
public function testGetImageTypesFromProduct()
{
$attributeCode = 'thumbnail';
$value = 'testImageValue';
$scopeLabel = 'testScopeLabel';
$label = 'testLabel';
$name = 'testName';
$expectedTypes = [
$attributeCode => [
'code' => $attributeCode,
'value' => $value,
'label' => $label,
'name' => $name,
],
];
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$product->expects($this->once())
->method('getData')
->with($this->identicalTo($attributeCode))
->willReturn($value);
$mediaAttribute = $this->getMediaAttribute($label, $attributeCode);
$product->expects($this->once())
->method('getMediaAttributes')
->willReturn([$mediaAttribute]);
$this->galleryMock->expects($this->exactly(2))
->method('getDataObject')
->willReturn($product);
$this->galleryMock->expects($this->never())
->method('getImageValue');
$this->galleryMock->expects($this->once())
->method('getScopeLabel')
->with($this->identicalTo($mediaAttribute))
->willReturn($scopeLabel);
$this->galleryMock->expects($this->once())
->method('getAttributeFieldName')
->with($this->identicalTo($mediaAttribute))
->willReturn($name);
$this->getImageTypesAssertions($attributeCode, $scopeLabel, $expectedTypes);
}
/**
* Perform assertions.
*
* @param string $attributeCode
* @param string $scopeLabel
* @param array $expectedTypes
* @return void
*/
private function getImageTypesAssertions(string $attributeCode, string $scopeLabel, array $expectedTypes)
{
$this->content->setElement($this->galleryMock);
$result = $this->content->getImageTypes();
$scope = $result[$attributeCode]['scope'];
$this->assertSame($scopeLabel, $scope->getText());
unset($result[$attributeCode]['scope']);
$this->assertSame($expectedTypes, $result);
}
/**
* Get media attribute mock.
*
* @param string $label
* @param string $attributeCode
* @return MockObject
*/
private function getMediaAttribute(string $label, string $attributeCode)
{
$frontend = $this->getMockBuilder(Product\Attribute\Frontend\Image::class)
->disableOriginalConstructor()
->getMock();
$frontend->expects($this->once())
->method('getLabel')
->willReturn($label);
$mediaAttribute = $this->getMockBuilder(Attribute::class)
->disableOriginalConstructor()
->getMock();
$mediaAttribute
->method('getAttributeCode')
->willReturn($attributeCode);
$mediaAttribute->expects($this->once())
->method('getFrontend')
->willReturn($frontend);
return $mediaAttribute;
}
/**
* Test GetImagesJson() calls MediaStorage functions to obtain image from DB prior to stat call
*
* @return void
*/
public function testGetImagesJsonMediaStorageMode()
{
$images = [
'images' => [
[
'value_id' => '0',
'file' => 'file_1.jpg',
'media_type' => 'image',
'position' => '0'
]
]
];
$mediaPath = [
['file_1.jpg', 'catalog/product/image_1.jpg']
];
$this->content->setElement($this->galleryMock);
$this->galleryMock->expects($this->once())
->method('getImages')
->willReturn($images);
$this->fileSystemMock->expects($this->once())
->method('getDirectoryRead')
->willReturn($this->readMock);
$this->mediaConfigMock
->method('getMediaPath')
->willReturnMap($mediaPath);
$this->readMock
->method('isFile')
->willReturn(false);
$this->databaseMock
->method('checkDbUsage')
->willReturn(true);
$this->databaseMock->expects($this->once())
->method('saveFileToFilesystem')
->with('catalog/product/image_1.jpg');
$this->readMock->method('stat')->willReturn(['size' => 123]);
$this->content->getImagesJson();
}
}
@@ -8,6 +8,7 @@ declare(strict_types=1);
namespace Magento\Catalog\Test\Unit\Helper;
use Magento\Catalog\Helper\Image;
use Magento\Catalog\Model\Config\CatalogMediaConfig;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\ImageFactory as ProductImageFactory;
use Magento\Catalog\Model\View\Asset\PlaceholderFactory;
@@ -70,6 +71,11 @@ class ImageTest extends TestCase
*/
protected $placeholderFactory;
/**
* @var CatalogMediaConfig|MockObject
*/
private $catalogMediaConfigMock;
protected function setUp(): void
{
$this->mockContext();
@@ -90,12 +96,17 @@ class ImageTest extends TestCase
->disableOriginalConstructor()
->getMock();
$this->catalogMediaConfigMock = $this->createPartialMock(CatalogMediaConfig::class, ['getMediaUrlFormat']);
$this->catalogMediaConfigMock->method('getMediaUrlFormat')->willReturn(CatalogMediaConfig::HASH);
$this->helper = new Image(
$this->context,
$this->imageFactory,
$this->assetRepository,
$this->viewConfig,
$this->placeholderFactory
$this->placeholderFactory,
$this->catalogMediaConfigMock
);
}
@@ -14,7 +14,9 @@ use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
@@ -186,6 +188,7 @@ class ImageTest extends TestCase
*/
public function testBeforeSaveAttributeFileName()
{
$this->setupObjectManagerForCheckImageExist(false);
$this->attribute->expects($this->once())
->method('getName')
->willReturn('test_attribute');
@@ -253,11 +256,23 @@ class ImageTest extends TestCase
);
}
private function setupObjectManagerForCheckImageExist($return)
{
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
$mockFileSystem = $this->createMock(Filesystem::class);
$mockRead = $this->createMock(ReadInterface::class);
$objectManagerMock->method($this->logicalOr('get', 'create'))->willReturn($mockFileSystem);
$mockFileSystem->method('getDirectoryRead')->willReturn($mockRead);
$mockRead->method('isExist')->willReturn($return);
\Magento\Framework\App\ObjectManager::setInstance($objectManagerMock);
}
/**
* Test beforeSaveTemporaryAttribute.
*/
public function testBeforeSaveTemporaryAttribute()
{
$this->setupObjectManagerForCheckImageExist(false);
$this->attribute->expects($this->once())
->method('getName')
->willReturn('test_attribute');
@@ -268,7 +283,7 @@ class ImageTest extends TestCase
$this->storeMock->expects($this->once())
->method('getBaseMediaDir')
->willReturn('pub/media');
->willReturn('media');
$model = $this->setUpModelForTests();
$model->setAttribute($this->attribute);
@@ -279,7 +294,9 @@ class ImageTest extends TestCase
->with(DirectoryList::MEDIA)
->willReturn($mediaDirectoryMock);
$this->imageUploader->expects($this->any())->method('moveFileFromTmp')->willReturn('test123.jpg');
$mediaDirectoryMock->method('getAbsolutePath')->willReturn('/media/test123.jpg');
$this->imageUploader->method('moveFileFromTmp')->willReturn('test123.jpg');
$object = new DataObject(
[
@@ -287,7 +304,7 @@ class ImageTest extends TestCase
[
'name' => 'test123.jpg',
'tmp_name' => 'abc123',
'url' => 'http://www.example.com/pub/media/temp/test123.jpg'
'url' => 'http://www.example.com/media/temp/test123.jpg'
],
],
]
@@ -297,7 +314,7 @@ class ImageTest extends TestCase
$this->assertEquals(
[
['name' => '/pub/media/test123.jpg', 'tmp_name' => 'abc123', 'url' => '/pub/media/test123.jpg'],
['name' => '/media/test123.jpg', 'tmp_name' => 'abc123', 'url' => '/media/test123.jpg'],
],
$object->getData('_additional_data_test_attribute')
);
@@ -418,6 +435,7 @@ class ImageTest extends TestCase
*/
public function testBeforeSaveWithExceptions()
{
$this->setupObjectManagerForCheckImageExist(false);
$model = $this->setUpModelForTests();
$this->storeManagerInterfaceMock->expects($this->once())
@@ -84,8 +84,8 @@ class ImageTest extends TestCase
],
[
'testimage',
'http://www.example.com/pub/media/',
'http://www.example.com/pub/media/catalog/category/testimage'
'http://www.example.com/media/',
'http://www.example.com/media/catalog/category/testimage'
],
[
'testimage',
@@ -94,8 +94,8 @@ class ImageTest extends TestCase
],
[
'/pub/media/catalog/category/testimage',
'http://www.example.com/pub/media/',
'http://www.example.com/pub/media/catalog/category/testimage'
'http://www.example.com/media/',
'http://www.example.com/media/catalog/category/testimage'
],
[
'/pub/media/catalog/category/testimage',
@@ -104,8 +104,8 @@ class ImageTest extends TestCase
],
[
'/pub/media/posters/testimage',
'http://www.example.com/pub/media/',
'http://www.example.com/pub/media/posters/testimage'
'http://www.example.com/media/',
'http://www.example.com/media/posters/testimage'
],
[
'/pub/media/posters/testimage',
@@ -1,168 +0,0 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Catalog\Test\Unit\Model;
use Magento\Catalog\Model\ImageUploader;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\MediaStorage\Helper\File\Storage\Database;
use Magento\MediaStorage\Model\File\Uploader;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
class ImageUploaderTest extends TestCase
{
/**
* @var ImageUploader
*/
private $imageUploader;
/**
* Core file storage database
*
* @var Database|MockObject
*/
private $coreFileStorageDatabaseMock;
/**
* Media directory object (writable).
*
* @var Filesystem|MockObject
*/
private $mediaDirectoryMock;
/**
* Media directory object (writable).
*
* @var WriteInterface|MockObject
*/
private $mediaWriteDirectoryMock;
/**
* Uploader factory
*
* @var UploaderFactory|MockObject
*/
private $uploaderFactoryMock;
/**
* Store manager
*
* @var StoreManagerInterface|MockObject
*/
private $storeManagerMock;
/**
* @var LoggerInterface|MockObject
*/
private $loggerMock;
/**
* Base tmp path
*
* @var string
*/
private $baseTmpPath;
/**
* Base path
*
* @var string
*/
private $basePath;
/**
* Allowed extensions
*
* @var array
*/
private $allowedExtensions;
/**
* Allowed mime types
*
* @var array
*/
private $allowedMimeTypes;
protected function setUp(): void
{
$this->coreFileStorageDatabaseMock = $this->createMock(
Database::class
);
$this->mediaDirectoryMock = $this->createMock(
Filesystem::class
);
$this->mediaWriteDirectoryMock = $this->createMock(
WriteInterface::class
);
$this->mediaDirectoryMock->expects($this->any())->method('getDirectoryWrite')->willReturn(
$this->mediaWriteDirectoryMock
);
$this->uploaderFactoryMock = $this->createMock(
UploaderFactory::class
);
$this->storeManagerMock = $this->createMock(
StoreManagerInterface::class
);
$this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
$this->baseTmpPath = 'base/tmp/';
$this->basePath = 'base/real/';
$this->allowedExtensions = ['.jpg'];
$this->allowedMimeTypes = ['image/jpg', 'image/jpeg', 'image/gif', 'image/png'];
$this->imageUploader =
new ImageUploader(
$this->coreFileStorageDatabaseMock,
$this->mediaDirectoryMock,
$this->uploaderFactoryMock,
$this->storeManagerMock,
$this->loggerMock,
$this->baseTmpPath,
$this->basePath,
$this->allowedExtensions,
$this->allowedMimeTypes
);
}
public function testSaveFileToTmpDir()
{
$fileId = 'file.jpg';
$allowedMimeTypes = [
'image/jpg',
'image/jpeg',
'image/gif',
'image/png',
];
/** @var \Magento\MediaStorage\Model\File\Uploader|MockObject $uploader */
$uploader = $this->createMock(Uploader::class);
$this->uploaderFactoryMock->expects($this->once())->method('create')->willReturn($uploader);
$uploader->expects($this->once())->method('setAllowedExtensions')->with($this->allowedExtensions);
$uploader->expects($this->once())->method('setAllowRenameFiles')->with(true);
$this->mediaWriteDirectoryMock->expects($this->once())->method('getAbsolutePath')->with($this->baseTmpPath)
->willReturn($this->basePath);
$uploader->expects($this->once())->method('save')->with($this->basePath)
->willReturn(['tmp_name' => $this->baseTmpPath, 'file' => $fileId, 'path' => $this->basePath]);
$uploader->expects($this->atLeastOnce())->method('checkMimeType')->with($allowedMimeTypes)->willReturn(true);
$storeMock = $this->createPartialMock(
Store::class,
['getBaseUrl']
);
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($storeMock);
$storeMock->expects($this->once())->method('getBaseUrl');
$this->coreFileStorageDatabaseMock->expects($this->once())->method('saveFile');
$result = $this->imageUploader->saveFileToTmpDir($fileId);
$this->assertArrayNotHasKey('path', $result);
}
}
@@ -1,79 +0,0 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Catalog\Test\Unit\Model\View\Asset\Image;
use Magento\Catalog\Model\Product\Media\ConfigInterface;
use Magento\Catalog\Model\View\Asset\Image\Context;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class ContextTest extends TestCase
{
/**
* @var Context
*/
protected $model;
/**
* @var WriteInterface|MockObject
*/
protected $mediaDirectory;
/**
* @var ContextInterface|MockObject
*/
protected $mediaConfig;
/**
* @var Filesystem|MockObject
*/
protected $filesystem;
protected function setUp(): void
{
$this->mediaConfig = $this->getMockBuilder(ConfigInterface::class)
->getMockForAbstractClass();
$this->mediaConfig->expects($this->any())->method('getBaseMediaPath')->willReturn('catalog/product');
$this->mediaDirectory = $this->getMockBuilder(WriteInterface::class)
->getMockForAbstractClass();
$this->mediaDirectory->expects($this->once())->method('create')->with('catalog/product');
$this->filesystem = $this->getMockBuilder(Filesystem::class)
->disableOriginalConstructor()
->getMock();
$this->filesystem->expects($this->once())
->method('getDirectoryWrite')
->with(DirectoryList::MEDIA)
->willReturn($this->mediaDirectory);
$this->model = new Context(
$this->mediaConfig,
$this->filesystem
);
}
public function testGetPath()
{
$path = '/var/www/html/magento2ce/pub/media/catalog/product';
$this->mediaDirectory->expects($this->once())
->method('getAbsolutePath')
->with('catalog/product')
->willReturn($path);
$this->assertEquals($path, $this->model->getPath());
}
public function testGetUrl()
{
$baseUrl = 'http://localhost/pub/media/catalog/product';
$this->mediaConfig->expects($this->once())->method('getBaseMediaUrl')->willReturn($baseUrl);
$this->assertEquals($baseUrl, $this->model->getBaseUrl());
}
}
@@ -1,213 +0,0 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Catalog\Test\Unit\Model\View\Asset;
use Magento\Catalog\Model\Product\Media\ConfigInterface;
use Magento\Catalog\Model\View\Asset\Image;
use Magento\Framework\Encryption\EncryptorInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\View\Asset\ContextInterface;
use Magento\Framework\View\Asset\Repository;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class ImageTest extends TestCase
{
/**
* @var Image
*/
protected $model;
/**
* @var ContextInterface|MockObject
*/
protected $mediaConfig;
/**
* @var EncryptorInterface|MockObject
*/
protected $encryptor;
/**
* @var ContextInterface|MockObject
*/
protected $context;
/**
* @var Repository|MockObject
*/
private $assetRepo;
private $objectManager;
protected function setUp(): void
{
$this->mediaConfig = $this->getMockForAbstractClass(ConfigInterface::class);
$this->encryptor = $this->getMockForAbstractClass(EncryptorInterface::class);
$this->context = $this->getMockForAbstractClass(ContextInterface::class);
$this->assetRepo = $this->createMock(Repository::class);
$this->objectManager = new ObjectManager($this);
$this->model = $this->objectManager->getObject(
Image::class,
[
'mediaConfig' => $this->mediaConfig,
'imageContext' => $this->context,
'encryptor' => $this->encryptor,
'filePath' => '/somefile.png',
'assetRepo' => $this->assetRepo,
'miscParams' => [
'image_width' => 100,
'image_height' => 50,
'constrain_only' => false,
'keep_aspect_ratio' => false,
'keep_frame' => true,
'keep_transparency' => false,
'background' => '255,255,255',
'image_type' => 'image', //thumbnail,small_image,image,swatch_image,swatch_thumb
'quality' => 80,
'angle' => null
]
]
);
}
public function testModuleAndContentAndContentType()
{
$contentType = 'image';
$this->assertEquals($contentType, $this->model->getContentType());
$this->assertEquals($contentType, $this->model->getSourceContentType());
$this->assertNull($this->model->getContent());
$this->assertEquals('cache', $this->model->getModule());
}
public function testGetFilePath()
{
$this->assertEquals('/somefile.png', $this->model->getFilePath());
}
public function testGetSoureFile()
{
$this->mediaConfig->expects($this->once())->method('getBaseMediaPath')->willReturn('catalog/product');
$this->assertEquals('catalog/product/somefile.png', $this->model->getSourceFile());
}
public function testGetContext()
{
$this->assertInstanceOf(ContextInterface::class, $this->model->getContext());
}
/**
* @param string $filePath
* @param array $miscParams
* @param string $readableParams
* @dataProvider getPathDataProvider
*/
public function testGetPath($filePath, $miscParams, $readableParams)
{
$imageModel = $this->objectManager->getObject(
Image::class,
[
'mediaConfig' => $this->mediaConfig,
'context' => $this->context,
'encryptor' => $this->encryptor,
'filePath' => $filePath,
'assetRepo' => $this->assetRepo,
'miscParams' => $miscParams
]
);
$absolutePath = '/var/www/html/magento2ce/pub/media/catalog/product';
$hashPath = 'somehash';
$this->context->method('getPath')->willReturn($absolutePath);
$this->encryptor->expects(static::once())
->method('hash')
->with($readableParams, $this->anything())
->willReturn($hashPath);
static::assertEquals(
$absolutePath . '/cache/' . $hashPath . $filePath,
$imageModel->getPath()
);
}
/**
* @param string $filePath
* @param array $miscParams
* @param string $readableParams
* @dataProvider getPathDataProvider
*/
public function testGetUrl($filePath, $miscParams, $readableParams)
{
$imageModel = $this->objectManager->getObject(
Image::class,
[
'mediaConfig' => $this->mediaConfig,
'context' => $this->context,
'encryptor' => $this->encryptor,
'filePath' => $filePath,
'assetRepo' => $this->assetRepo,
'miscParams' => $miscParams
]
);
$absolutePath = 'http://localhost/pub/media/catalog/product';
$hashPath = 'somehash';
$this->context->expects(static::once())->method('getBaseUrl')->willReturn($absolutePath);
$this->encryptor->expects(static::once())
->method('hash')
->with($readableParams, $this->anything())
->willReturn($hashPath);
static::assertEquals(
$absolutePath . '/cache/' . $hashPath . $filePath,
$imageModel->getUrl()
);
}
/**
* @return array
*/
public function getPathDataProvider()
{
return [
[
'/some_file.png',
[], //default value for miscParams,
'h:empty_w:empty_q:empty_r:empty_nonproportional_noframe_notransparency_notconstrainonly_nobackground',
],
[
'/some_file_2.png',
[
'image_type' => 'thumbnail',
'image_height' => 75,
'image_width' => 75,
'keep_aspect_ratio' => true,
'keep_frame' => true,
'keep_transparency' => true,
'constrain_only' => true,
'background' => [233,1,0],
'angle' => null,
'quality' => 80,
],
'h:75_w:75_proportional_frame_transparency_doconstrainonly_rgb233,1,0_r:empty_q:80',
],
[
'/some_file_3.png',
[
'image_type' => 'thumbnail',
'image_height' => 75,
'image_width' => 75,
'keep_aspect_ratio' => false,
'keep_frame' => false,
'keep_transparency' => false,
'constrain_only' => false,
'background' => [233,1,0],
'angle' => 90,
'quality' => 80,
],
'h:75_w:75_nonproportional_noframe_notransparency_notconstrainonly_rgb233,1,0_r:90_q:80',
],
];
}
}
@@ -141,10 +141,10 @@ class PlaceholderTest extends TestCase
if ($placeholderPath == null) {
$this->imageContext->expects($this->never())->method('getBaseUrl');
$expectedResult = 'http://localhost/pub/media/catalog/product/to_default/placeholder/by_type';
$expectedResult = 'http://localhost/media/catalog/product/to_default/placeholder/by_type';
$this->repository->expects($this->any())->method('getUrl')->willReturn($expectedResult);
} else {
$baseUrl = 'http://localhost/pub/media/catalog/product';
$baseUrl = 'http://localhost/media/catalog/product';
$this->imageContext->expects($this->any())->method('getBaseUrl')->willReturn($baseUrl);
$expectedResult = $baseUrl
. DIRECTORY_SEPARATOR . $imageModel->getModule()
@@ -104,9 +104,6 @@ class ImageTest extends TestCase
->method('create')
->willReturn($image);
$imageHelper->expects($this->once())
->method('getResizedImageInfo')
->willReturn([11, 11]);
$this->state->expects($this->once())
->method('emulateAreaCode')
->with(
@@ -116,12 +113,14 @@ class ImageTest extends TestCase
)
->willReturn($imageHelper);
$width = 5;
$height = 10;
$imageHelper->expects($this->once())
->method('getHeight')
->willReturn(10);
->willReturn($height);
$imageHelper->expects($this->once())
->method('getWidth')
->willReturn(10);
->willReturn($width);
$imageHelper->expects($this->once())
->method('getLabel')
->willReturn('Label');
@@ -137,10 +136,10 @@ class ImageTest extends TestCase
->with();
$image->expects($this->once())
->method('setResizedHeight')
->with(11);
->with($height);
$image->expects($this->once())
->method('setResizedWidth')
->with(11);
->with($width);
$productRenderInfoDto->expects($this->once())
->method('setImages')
@@ -118,18 +118,14 @@ class Image implements ProductRenderCollectorInterface
[$product, $imageCode, (int) $productRender->getStoreId(), $image]
);
try {
$resizedInfo = $helper->getResizedImageInfo();
} catch (NotLoadInfoImageException $exception) {
$resizedInfo = [$helper->getWidth(), $helper->getHeight()];
}
$image->setCode($imageCode);
$image->setHeight($helper->getHeight());
$image->setWidth($helper->getWidth());
$height = $helper->getHeight();
$image->setHeight($height);
$width = $helper->getWidth();
$image->setWidth($width);
$image->setLabel($helper->getLabel());
$image->setResizedHeight($resizedInfo[1]);
$image->setResizedWidth($resizedInfo[0]);
$image->setResizedHeight($height);
$image->setResizedWidth($width);
$images[] = $image;
}
@@ -214,6 +214,13 @@
<source_model>Magento\Catalog\Model\Config\Source\LayoutList</source_model>
</field>
</group>
<group id="url">
<field id="catalog_media_url_format" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0" canRestore="1">
<label>Catalog media URL format</label>
<source_model>Magento\Catalog\Model\Config\Source\Web\CatalogMediaUrlFormat</source_model>
<comment><![CDATA[Images should be optimized based on query parameters by your CDN or web server. Use the legacy mode for backward compatibility. <a href="https://docs.magento.com/m2/ee/user_guide/configuration/general/web.html#url-options">Learn more</a> about catalog URL formats.<br/><br/><strong style="color:red">Warning!</strong> If you switch back to legacy mode, you must <a href="https://devdocs.magento.com/guides/v2.3/frontend-dev-guide/themes/theme-images.html#resize-catalog-images">use the CLI to regenerate images</a>.]]></comment>
</field>
</group>
</section>
<section id="system" translate="label" type="text" sortOrder="900" showInDefault="1" showInWebsite="1" showInStore="1">
<class>separator-top</class>
+7 -1
View File
@@ -67,7 +67,8 @@
<media_storage_configuration>
<allowed_resources>
<tmp_images_folder>tmp</tmp_images_folder>
<catalog_product_images>media/catalog/product/cache/</catalog_product_images>
<catalog_product_images>media/catalog/product/</catalog_product_images>
<catalog_product_images_tmp>media/tmp/catalog/product/</catalog_product_images_tmp>
<catalog_images_folder>catalog</catalog_images_folder>
<product_custom_options_fodler>custom_options</product_custom_options_fodler>
</allowed_resources>
@@ -83,6 +84,11 @@
<thumbnail_position>stretch</thumbnail_position>
</watermark>
</design>
<web>
<url>
<catalog_media_url_format>hash</catalog_media_url_format>
</url>
</web>
<general>
<validator_data>
<input_types>
@@ -30,7 +30,7 @@ class Collection extends \Magento\Framework\Data\Collection\Filesystem
\Magento\Framework\Filesystem $filesystem
) {
$this->_filesystem = $filesystem;
parent::__construct($entityFactory);
parent::__construct($entityFactory, $filesystem);
}
/**
@@ -192,12 +192,12 @@ class ConfigTest extends TestCase
->willReturn('localhost/index.php/');
$this->filesystemMock->expects($this->once())
->method('getUri')
->willReturn('pub/static');
->willReturn('static');
/** @var ContextInterface|MockObject $contextMock */
$contextMock = $this->getMockForAbstractClass(ContextInterface::class);
$contextMock->expects($this->once())
->method('getBaseUrl')
->willReturn('localhost/pub/static/');
->willReturn('localhost/static/');
$this->assetRepoMock->expects($this->once())
->method('getStaticViewFileContext')
->willReturn($contextMock);
@@ -217,8 +217,8 @@ class ConfigTest extends TestCase
$config = $this->wysiwygConfig->getConfig($data);
$this->assertInstanceOf(DataObject::class, $config);
$this->assertEquals($expectedResults[0], $config->getData('someData'));
$this->assertEquals('localhost/pub/static/', $config->getData('baseStaticUrl'));
$this->assertEquals('localhost/pub/static/', $config->getData('baseStaticDefaultUrl'));
$this->assertEquals('localhost/static/', $config->getData('baseStaticUrl'));
$this->assertEquals('localhost/static/', $config->getData('baseStaticDefaultUrl'));
}
/**
@@ -10,6 +10,7 @@
namespace Magento\Config\Model\Config\Backend\Admin;
use Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\ObjectManager;
/**
@@ -36,7 +37,6 @@ class Robots extends \Magento\Framework\App\Config\Value
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param array $data
* @param DocumentRoot $documentRoot
*/
public function __construct(
\Magento\Framework\Model\Context $context,
@@ -46,13 +46,11 @@ class Robots extends \Magento\Framework\App\Config\Value
\Magento\Framework\Filesystem $filesystem,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = [],
\Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot $documentRoot = null
array $data = []
) {
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
$documentRoot = $documentRoot ?: ObjectManager::getInstance()->get(DocumentRoot::class);
$this->_directory = $filesystem->getDirectoryWrite($documentRoot->getPath());
$this->_directory = $filesystem->getDirectoryWrite(DirectoryList::PUB);
$this->_file = 'robots.txt';
}
@@ -233,7 +233,8 @@ class FileProcessor
);
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Something went wrong while saving the file.')
__('Something went wrong while saving the file.'),
$e
);
}
@@ -11,10 +11,13 @@ use Magento\Customer\Api\AddressMetadataInterface;
use Magento\Customer\Api\CustomerMetadataInterface;
use Magento\Customer\Model\FileProcessor;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\File\Mime;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\Url\EncoderInterface;
use Magento\Framework\UrlInterface;
use Magento\MediaStorage\Model\File\Uploader;
@@ -363,17 +366,73 @@ class FileProcessorTest extends TestCase
$path = CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER . '/' . FileProcessor::TMP_DIR . $filePath;
$newPath = $destinationPath . $filePath;
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
$mockFileSystem = $this->createMock(Filesystem::class);
$mockRead = $this->createMock(ReadInterface::class);
$objectManagerMock->method('get')->willReturn($mockFileSystem);
$mockFileSystem->method('getDirectoryRead')->willReturn($mockRead);
$mockRead->method('isExist')->willReturn(false);
ObjectManager::setInstance($objectManagerMock);
$this->mediaDirectory->expects($this->once())
->method('renameFile')
->with($path, $newPath)
->willReturn(true);
$model = $this->getModel(CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER);
$this->assertEquals('/f/i' . $filePath, $model->moveTemporaryFile($filePath));
}
public function testMoveTemporaryFileNewFileName()
{
$filePath = '/filename.ext1';
$destinationPath = 'customer/f/i';
$this->mediaDirectory->expects($this->once())
->method('create')
->with($destinationPath)
->willReturn(true);
$this->mediaDirectory->expects($this->once())
->method('isWritable')
->with($destinationPath)
->willReturn(true);
$this->mediaDirectory->expects($this->once())
->method('getAbsolutePath')
->with($destinationPath)
->willReturn('/' . $destinationPath);
$path = CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER . '/' . FileProcessor::TMP_DIR . $filePath;
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
$mockFileSystem = $this->createMock(Filesystem::class);
$mockRead = $this->createMock(ReadInterface::class);
$objectManagerMock->method('get')->willReturn($mockFileSystem);
$mockFileSystem->method('getDirectoryRead')->willReturn($mockRead);
$mockRead->method('isExist')->willReturnOnConsecutiveCalls(true, true, false);
ObjectManager::setInstance($objectManagerMock);
$this->mediaDirectory->expects($this->once())
->method('renameFile')
->with($path, 'customer/f/i/filename_2.ext1')
->willReturn(true);
$model = $this->getModel(CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER);
$this->assertEquals('/f/i/filename_2.ext1', $model->moveTemporaryFile($filePath));
}
public function testMoveTemporaryFileWithException()
{
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
$mockFileSystem = $this->createMock(Filesystem::class);
$mockRead = $this->createMock(ReadInterface::class);
$objectManagerMock->method($this->logicalOr('get', 'create'))->willReturn($mockFileSystem);
$mockFileSystem->method('getDirectoryRead')->willReturn($mockRead);
$mockRead->method('isExist')->willReturn(false);
ObjectManager::setInstance($objectManagerMock);
$this->expectException(LocalizedException::class);
$this->expectExceptionMessage('Something went wrong while saving the file');
@@ -44,7 +44,7 @@ class ProcessorTest extends TestCase
public function testProcess()
{
$url = 'http://magento.local/pub/static/';
$url = 'http://magento.local/static/';
$locale = 'en_US';
$css = '@import url("{{base_url_path}}frontend/_view/{{locale}}/css/email.css");';
$expectedCss = '@import url("' . $url . 'frontend/_view/' . $locale . '/css/email.css");';
@@ -129,7 +129,7 @@ class UploadImageTest extends TestCase
[
'targetFolder' => 'media/catalog',
'type' => 'image',
'absolutePath' => 'root/pub/media/catalog/test-image.jpeg'
'absolutePath' => 'root/media/catalog/test-image.jpeg'
]
];
}
@@ -94,7 +94,7 @@ class GalleryTest extends TestCase
$data = [
[
'media_type' => 'external-video',
'video_url' => 'http://magento.ce/pub/media/catalog/product/9/b/9br6ujuthnc.jpg',
'video_url' => 'http://magento.ce/media/catalog/product/9/b/9br6ujuthnc.jpg',
'is_base' => true,
],
[
@@ -99,11 +99,20 @@ class RetrieveImageTest extends TestCase
*/
private $fileDriverMock;
/**
* Set up
*/
private function setupObjectManagerForCheckImageExist($return)
{
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
$mockFileSystem = $this->createMock(Filesystem::class);
$mockRead = $this->createMock(ReadInterface::class);
$objectManagerMock->method($this->logicalOr('get', 'create'))->willReturn($mockFileSystem);
$mockFileSystem->method('getDirectoryRead')->willReturn($mockRead);
$mockRead->method('isExist')->willReturn($return);
\Magento\Framework\App\ObjectManager::setInstance($objectManagerMock);
}
protected function setUp(): void
{
$this->setupObjectManagerForCheckImageExist(false);
$objectManager = new ObjectManager($this);
$this->contextMock = $this->createMock(Context::class);
$this->validatorMock = $this
@@ -0,0 +1,80 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\RemoteStorage\Plugin;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\RuntimeException;
use Magento\Framework\Exception\ValidatorException;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\MediaStorage\Model\File\Storage\Synchronization;
use Magento\RemoteStorage\Driver\DriverPool as RemoteDriverPool;
use Magento\Framework\Filesystem\DriverPool as LocalDriverPool;
use Magento\RemoteStorage\Model\Config;
use Magento\RemoteStorage\Filesystem;
/**
* Modifies the base URL.
*/
class MediaStorage
{
/**
* @var bool
*/
private $isEnabled;
/**
* @var WriteInterface
*/
private $remoteDir;
/**
* @var WriteInterface
*/
private $localDir;
/**
* @param Config $config
* @param Filesystem $filesystem
* @throws FileSystemException
* @throws RuntimeException
*/
public function __construct(Config $config, Filesystem $filesystem)
{
$this->isEnabled = $config->isEnabled();
$this->remoteDir = $filesystem->getDirectoryWrite(DirectoryList::PUB, RemoteDriverPool::REMOTE);
$this->localDir = $filesystem->getDirectoryWrite(DirectoryList::PUB, LocalDriverPool::FILE);
}
/**
* Download remote file
* @param Synchronization $subject
* @param string $relativeFileName
* @return null
* @throws FileSystemException
* @throws ValidatorException
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function beforeSynchronize(Synchronization $subject, string $relativeFileName)
{
if ($this->isEnabled) {
if ($this->remoteDir->isExist($relativeFileName)) {
$file = $this->localDir->openFile($relativeFileName, 'w');
try {
$file->lock();
$file->write($this->remoteDir->readFile($relativeFileName));
$file->unlock();
$file->close();
} catch (FileSystemException $e) {
$file->close();
}
}
}
return null;
}
}
+2 -1
View File
@@ -9,7 +9,8 @@
"magento/module-backend": "*",
"magento/module-sitemap": "*",
"magento/module-cms": "*",
"magento/module-downloadable": "*"
"magento/module-downloadable": "*",
"magento/module-media-storage": "*"
},
"type": "magento2-module",
"license": [
@@ -74,6 +74,9 @@
<argument name="filesystem" xsi:type="object">fullRemoteFilesystem</argument>
</arguments>
</type>
<type name="Magento\MediaStorage\Model\File\Storage\Synchronization">
<plugin name="remote_media" type="Magento\RemoteStorage\Plugin\MediaStorage" />
</type>
<type name="Magento\Framework\Data\Collection\Filesystem">
<arguments>
<argument name="filesystem" xsi:type="object">fullRemoteFilesystem</argument>
@@ -11,6 +11,7 @@
<module name="Magento_Backend"/>
<module name="Magento_Sitemap"/>
<module name="Magento_Store"/>
<module name="Magento_MediaStorage"/>
</sequence>
</module>
</config>
@@ -61,7 +61,7 @@ class ProductTest extends TestCase
*/
public function productProvider()
{
$storeBaseMediaUrl = 'http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/';
$storeBaseMediaUrl = 'http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/';
return [
[
[
@@ -533,7 +533,7 @@ class SitemapTest extends TestCase
$methods[] = 'beforeSave';
}
$storeBaseMediaUrl = 'http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/';
$storeBaseMediaUrl = 'http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/';
$this->itemProviderMock->expects($this->any())
->method('getItems')
@@ -13,18 +13,18 @@
<changefreq>monthly</changefreq>
<priority>0.5</priority>
<image:image>
<image:loc>http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image1.png</image:loc>
<image:loc>http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image1.png</image:loc>
<image:title>Product &amp; &gt; title &lt; &quot;</image:title>
<image:caption>Copyright &#xa9; caption &amp;trade; &amp; &gt; title &lt; &quot;</image:caption>
</image:image>
<image:image>
<image:loc>http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image_no_caption.png</image:loc>
<image:loc>http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image_no_caption.png</image:loc>
<image:title>Product &amp; &gt; title &lt; &quot;</image:title>
</image:image>
<PageMap xmlns="http://www.google.com/schemas/sitemap-pagemap/1.0">
<DataObject type="thumbnail">
<Attribute name="name" value="Product &amp; &gt; title &lt; &quot;"/>
<Attribute name="src" value="http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/t/h/thumbnail.jpg"/>
<Attribute name="src" value="http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/t/h/thumbnail.jpg"/>
</DataObject>
</PageMap>
</url>
@@ -31,18 +31,18 @@
<changefreq>monthly</changefreq>
<priority>0.5</priority>
<image:image>
<image:loc>http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image1.png</image:loc>
<image:loc>http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image1.png</image:loc>
<image:title>Product &amp; &gt; title &lt; &quot;</image:title>
<image:caption>Copyright &#xa9; caption &amp;trade; &amp; &gt; title &lt; &quot;</image:caption>
</image:image>
<image:image>
<image:loc>http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image_no_caption.png</image:loc>
<image:loc>http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/i/m/image_no_caption.png</image:loc>
<image:title>Product &amp; &gt; title &lt; &quot;</image:title>
</image:image>
<PageMap xmlns="http://www.google.com/schemas/sitemap-pagemap/1.0">
<DataObject type="thumbnail">
<Attribute name="name" value="Product &amp; &gt; title &lt; &quot;"/>
<Attribute name="src" value="http://store.com/pub/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/t/h/thumbnail.jpg"/>
<Attribute name="src" value="http://store.com/media/catalog/product/cache/c9e0b0ef589f3508e5ba515cde53c5ff/t/h/thumbnail.jpg"/>
</DataObject>
</PageMap>
</url>
@@ -136,10 +136,10 @@ class StoreConfigManagerTest extends TestCase
$secureBaseUrl = 'https://magento/base_url';
$baseLinkUrl = 'http://magento/base_url/links';
$secureBaseLinkUrl = 'https://magento/base_url/links';
$baseStaticUrl = 'http://magento/base_url/pub/static';
$baseStaticUrl = 'http://magento/base_url/static';
$secureBaseStaticUrl = 'https://magento/base_url/static';
$baseMediaUrl = 'http://magento/base_url/pub/media';
$secureBaseMediaUrl = 'https://magento/base_url/pub/media';
$baseMediaUrl = 'http://magento/base_url/media';
$secureBaseMediaUrl = 'https://magento/base_url/media';
$locale = 'en_US';
$timeZone = 'America/Los_Angeles';
$baseCurrencyCode = 'USD';
+1 -1
View File
@@ -310,7 +310,7 @@ class Data
* Method getting full media gallery for current Product
*
* Array structure: [
* ['image'] => 'http://url/pub/media/catalog/product/2/0/blabla.jpg',
* ['image'] => 'http://url/media/catalog/product/2/0/blabla.jpg',
* ['mediaGallery'] => [
* galleryImageId1 => simpleProductImage1.jpg,
* galleryImageId2 => simpleProductImage2.jpg,
+61 -23
View File
@@ -6,8 +6,9 @@
namespace Magento\Swatches\Helper;
use Magento\Catalog\Helper\Image;
use Magento\Framework\App\Area;
use Magento\Catalog\Model\Config\CatalogMediaConfig;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\ObjectManager;
/**
* Helper to move images from tmp to catalog directory
@@ -72,6 +73,11 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
*/
private $imageConfig;
/**
* @var string
*/
private $mediaUrlFormat;
/**
* @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig
* @param \Magento\Framework\Filesystem $filesystem
@@ -80,6 +86,8 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
* @param \Magento\Framework\Image\Factory $imageFactory
* @param \Magento\Theme\Model\ResourceModel\Theme\Collection $themeCollection
* @param \Magento\Framework\View\ConfigInterface $configInterface
* @param CatalogMediaConfig $catalogMediaConfig
* @throws \Magento\Framework\Exception\FileSystemException
*/
public function __construct(
\Magento\Catalog\Model\Product\Media\Config $mediaConfig,
@@ -88,7 +96,8 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Image\Factory $imageFactory,
\Magento\Theme\Model\ResourceModel\Theme\Collection $themeCollection,
\Magento\Framework\View\ConfigInterface $configInterface
\Magento\Framework\View\ConfigInterface $configInterface,
CatalogMediaConfig $catalogMediaConfig = null
) {
$this->mediaConfig = $mediaConfig;
$this->fileStorageDb = $fileStorageDb;
@@ -97,6 +106,9 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
$this->imageFactory = $imageFactory;
$this->themeCollection = $themeCollection;
$this->viewConfig = $configInterface;
$catalogMediaConfig = $catalogMediaConfig ?: ObjectManager::getInstance()->get(CatalogMediaConfig::class);
$this->mediaUrlFormat = $catalogMediaConfig->getMediaUrlFormat();
}
/**
@@ -106,17 +118,35 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
*/
public function getSwatchAttributeImage($swatchType, $file)
{
$generationPath = $swatchType . '/' . $this->getFolderNameSize($swatchType) . $file;
$absoluteImagePath = $this->mediaDirectory
->getAbsolutePath($this->getSwatchMediaPath() . '/' . $generationPath);
if (!file_exists($absoluteImagePath)) {
try {
$this->generateSwatchVariations($file);
} catch (\Exception $e) {
return '';
$basePath = $this->getSwatchMediaUrl();
if ($this->mediaUrlFormat === CatalogMediaConfig::HASH) {
$generationPath = $swatchType . '/' . $this->getFolderNameSize($swatchType) . $file;
$absoluteImagePath = $this->mediaDirectory
->getAbsolutePath($this->getSwatchMediaPath() . '/' . $generationPath);
if (!$this->mediaDirectory->isExist(($absoluteImagePath))) {
try {
$this->generateSwatchVariations($file);
} catch (\Exception $e) {
return '';
}
}
return $basePath . '/' . $generationPath;
}
return $this->getSwatchMediaUrl() . '/' . $generationPath;
return $basePath . '/' . $this->getRelativeTransformationParametersPath($swatchType, $file);
}
private function getRelativeTransformationParametersPath($swatchType, $file)
{
$imageConfig = $this->getImageConfig();
return $this->prepareFile($file) . '?' . http_build_query([
'width' => $imageConfig[$swatchType]['width'],
'height' => $imageConfig[$swatchType]['height'],
'store' => $this->storeManager->getStore()->getCode(),
'image-type' => $swatchType
]);
}
/**
@@ -156,7 +186,7 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
/**
* Check whether file to move exists. Getting unique name
*
* @param <type> $file
* @param string $file
* @return string
*/
protected function getUniqueFileName($file)
@@ -168,13 +198,18 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
);
} else {
$destFile = dirname($file) . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName(
$this->mediaDirectory->getAbsolutePath($this->getAttributeSwatchPath($file))
$this->getOriginalFilePath($file)
);
}
return $destFile;
}
private function getOriginalFilePath($file)
{
return $this->mediaDirectory->getAbsolutePath($this->getAttributeSwatchPath($file));
}
/**
* Generate swatch thumb and small swatch image
*
@@ -183,16 +218,19 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
*/
public function generateSwatchVariations($imageUrl)
{
$absoluteImagePath = $this->mediaDirectory->getAbsolutePath($this->getAttributeSwatchPath($imageUrl));
foreach ($this->swatchImageTypes as $swatchType) {
$imageConfig = $this->getImageConfig();
$swatchNamePath = $this->generateNamePath($imageConfig, $imageUrl, $swatchType);
$image = $this->imageFactory->create($absoluteImagePath);
$this->setupImageProperties($image);
$image->resize($imageConfig[$swatchType]['width'], $imageConfig[$swatchType]['height']);
$this->setupImageProperties($image, true);
$image->save($swatchNamePath['path_for_save'], $swatchNamePath['name']);
if ($this->mediaUrlFormat === CatalogMediaConfig::HASH) {
$absoluteImagePath = $this->getOriginalFilePath($imageUrl);
foreach ($this->swatchImageTypes as $swatchType) {
$imageConfig = $this->getImageConfig();
$swatchNamePath = $this->generateNamePath($imageConfig, $imageUrl, $swatchType);
$image = $this->imageFactory->create($absoluteImagePath);
$this->setupImageProperties($image);
$image->resize($imageConfig[$swatchType]['width'], $imageConfig[$swatchType]['height']);
$this->setupImageProperties($image, true);
$image->save($swatchNamePath['path_for_save'], $swatchNamePath['name']);
}
}
return $this;
}
@@ -281,7 +319,7 @@ class Media extends \Magento\Framework\App\Helper\AbstractHelper
}
/**
* Url type http://url/pub/media/attribute/swatch/
* Url type http://url/media/attribute/swatch/
*
* @return string
*/
@@ -7,13 +7,16 @@ declare(strict_types=1);
namespace Magento\Swatches\Test\Unit\Helper;
use Magento\Catalog\Model\Config\CatalogMediaConfig;
use Magento\Catalog\Model\Product\Media\Config;
use Magento\Framework\Config\View;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Directory\Write;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\Image;
use Magento\Framework\Image\Factory;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\MediaStorage\Helper\File\Storage\Database;
use Magento\Store\Model\Store;
@@ -59,8 +62,23 @@ class MediaTest extends TestCase
/** @var Media|ObjectManager */
protected $mediaHelperObject;
/** @var CatalogMediaConfig|MockObject */
private $catalogMediaConfigMock;
private function setupObjectManagerForCheckImageExist($return)
{
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
$mockFileSystem = $this->createMock(Filesystem::class);
$mockRead = $this->createMock(ReadInterface::class);
$objectManagerMock->method($this->logicalOr('get', 'create'))->willReturn($mockFileSystem);
$mockFileSystem->method('getDirectoryRead')->willReturn($mockRead);
$mockRead->method('isExist')->willReturn($return);
\Magento\Framework\App\ObjectManager::setInstance($objectManagerMock);
}
protected function setUp(): void
{
$this->setupObjectManagerForCheckImageExist(false);
$objectManager = new ObjectManager($this);
$this->mediaConfigMock = $this->createMock(Config::class);
@@ -78,6 +96,9 @@ class MediaTest extends TestCase
$this->storeMock = $this->createPartialMock(Store::class, ['getBaseUrl']);
$this->catalogMediaConfigMock = $this->createPartialMock(CatalogMediaConfig::class, ['getMediaUrlFormat']);
$this->catalogMediaConfigMock->method('getMediaUrlFormat')->willReturn(CatalogMediaConfig::HASH);
$this->mediaDirectoryMock = $this->createMock(Write::class);
$this->fileSystemMock = $this->createPartialMock(Filesystem::class, ['getDirectoryWrite']);
$this->fileSystemMock
@@ -94,6 +115,7 @@ class MediaTest extends TestCase
'storeManager' => $this->storeManagerMock,
'imageFactory' => $this->imageFactoryMock,
'configInterface' => $this->viewConfigMock,
'catalogMediaConfig' => $this->catalogMediaConfigMock,
]
);
}
@@ -112,7 +134,7 @@ class MediaTest extends TestCase
->expects($this->once())
->method('getBaseUrl')
->with('media')
->willReturn('http://url/pub/media/');
->willReturn('http://url/media/');
$this->generateImageConfig();
@@ -120,7 +142,7 @@ class MediaTest extends TestCase
$result = $this->mediaHelperObject->getSwatchAttributeImage($swatchType, '/f/i/file.png');
$this->assertEquals($result, $expectedResult);
$this->assertEquals($expectedResult, $result);
}
/**
@@ -131,11 +153,11 @@ class MediaTest extends TestCase
return [
[
'swatch_image',
'http://url/pub/media/attribute/swatch/swatch_image/30x20/f/i/file.png',
'http://url/media/attribute/swatch/swatch_image/30x20/f/i/file.png',
],
[
'swatch_thumb',
'http://url/pub/media/attribute/swatch/swatch_thumb/110x90/f/i/file.png',
'http://url/media/attribute/swatch/swatch_thumb/110x90/f/i/file.png',
],
];
}
@@ -153,6 +175,10 @@ class MediaTest extends TestCase
{
$this->fileStorageDbMock->method('checkDbUsage')->willReturn(false);
$this->fileStorageDbMock->method('renameFile')->willReturnSelf();
$this->mediaDirectoryMock
->expects($this->atLeastOnce())
->method('getAbsolutePath')
->willReturn('attribute/swatch/f/i/file.tmp');
$result = $this->mediaHelperObject->moveImageFromTmp('file.tmp');
$this->assertNotNull($result);
}
@@ -177,7 +203,7 @@ class MediaTest extends TestCase
$this->imageFactoryMock->expects($this->any())->method('create')->willReturn($image);
$this->generateImageConfig();
$image->expects($this->any())->method('resize')->willReturnSelf();
$image->method('resize')->willReturnSelf();
$image->expects($this->atLeastOnce())->method('backgroundColor')->with([255, 255, 255])->willReturnSelf();
$this->mediaHelperObject->generateSwatchVariations('/e/a/earth.png');
}
@@ -195,11 +221,11 @@ class MediaTest extends TestCase
->expects($this->once())
->method('getBaseUrl')
->with('media')
->willReturn('http://url/pub/media/');
->willReturn('http://url/media/');
$result = $this->mediaHelperObject->getSwatchMediaUrl();
$this->assertEquals($result, 'http://url/pub/media/attribute/swatch');
$this->assertEquals($result, 'http://url/media/attribute/swatch');
}
/**
@@ -282,7 +308,7 @@ class MediaTest extends TestCase
],
];
$configMock->expects($this->any())->method('getMediaEntities')->willReturn($imageConfig);
$configMock->method('getMediaEntities')->willReturn($imageConfig);
}
public function testGetAttributeSwatchPath()
@@ -35,7 +35,7 @@ class LogoTest extends TestCase
)->method(
'getBaseUrl'
)->willReturn(
'http://localhost/pub/media/'
'http://localhost/media/'
);
$mediaDirectory->expects($this->any())->method('isFile')->willReturn(true);
@@ -53,7 +53,7 @@ class LogoTest extends TestCase
];
$block = $objectManager->getObject(Logo::class, $arguments);
$this->assertEquals('http://localhost/pub/media/logo/default/image.gif', $block->getLogoSrc());
$this->assertEquals('http://localhost/media/logo/default/image.gif', $block->getLogoSrc());
}
/**
@@ -195,7 +195,7 @@ class FileTest extends TestCase
$this->urlBuilder->expects($this->once())
->method('getBaseUrl')
->with(['_type' => UrlInterface::URL_TYPE_MEDIA])
->willReturn('http://magento2.com/pub/media/');
->willReturn('http://magento2.com/media/');
$this->mediaDirectory->expects($this->once())
->method('getRelativePath')
->with('value')
@@ -212,7 +212,7 @@ class FileTest extends TestCase
$this->assertEquals(
[
[
'url' => 'http://magento2.com/pub/media/design/file/' . $value,
'url' => 'http://magento2.com/media/design/file/' . $value,
'file' => $value,
'size' => 234234,
'exists' => true,
@@ -241,7 +241,7 @@ class FileTest extends TestCase
'scope_id' => 1,
'value' => [
[
'url' => 'http://magento2.com/pub/media/tmp/image/' . $fileName,
'url' => 'http://magento2.com/media/tmp/image/' . $fileName,
'file' => $fileName,
'size' => 234234,
]
@@ -314,7 +314,7 @@ class FileTest extends TestCase
[
'value' => [
[
'url' => 'http://magento2.com/pub/media/tmp/image/' . $value,
'url' => 'http://magento2.com/media/tmp/image/' . $value,
'file' => $value,
'size' => 234234,
'exists' => true
@@ -358,7 +358,7 @@ class FileTest extends TestCase
{
return [
'Normal path' => ['pub/media/', 'filename.jpg'],
'Complex path' => ['some_path/pub/media/', 'filename.jpg'],
'Complex path' => ['some_path/media/', 'filename.jpg'],
];
}
}
@@ -111,7 +111,7 @@ class FileProcessorTest extends TestCase
$this->store->expects($this->once())
->method('getBaseUrl')
->with(UrlInterface::URL_TYPE_MEDIA)
->willReturn('http://magento2.com/pub/media/');
->willReturn('http://magento2.com/media/');
$this->directoryWrite->expects($this->once())
->method('getAbsolutePath')
->with('tmp/' . FileProcessor::FILE_DIR)
@@ -160,7 +160,7 @@ class FileProcessorTest extends TestCase
'name' => 'file.jpg',
'size' => '234234',
'type' => 'image/jpg',
'url' => 'http://magento2.com/pub/media/tmp/' . FileProcessor::FILE_DIR . '/file.jpg'
'url' => 'http://magento2.com/media/tmp/' . FileProcessor::FILE_DIR . '/file.jpg'
],
$this->fileProcessor->saveToTmp($fieldCode)
);
@@ -105,7 +105,7 @@ class FaviconTest extends TestCase
public function testGetFaviconFile()
{
$scopeConfigValue = 'path';
$urlToMediaDir = 'http://magento.url/pub/media/';
$urlToMediaDir = 'http://magento.url/media/';
$expectedFile = ImageFavicon::UPLOAD_DIR . '/' . $scopeConfigValue;
$expectedUrl = $urlToMediaDir . $expectedFile;
@@ -4,4 +4,4 @@
* See COPYING.txt for license details.
*/
-->
<img class = 'admin__control-thumbnail' data-bind="attr: {src: $data.value}">
<img class = 'admin__control-thumbnail' style="max-height: 75px; max-width: 75px;" data-bind="attr: {src: $data.value}">
@@ -267,7 +267,7 @@ class FilterTest extends TestCase
{
$image = 'wysiwyg/VB.png';
$construction = ['{{media url="' . $image . '"}}', 'media', ' url="' . $image . '"'];
$baseUrl = 'http://localhost/pub/media/';
$baseUrl = 'http://localhost/media/';
$this->storeMock->expects($this->once())
->method('getBaseUrl')
@@ -285,7 +285,7 @@ class FilterTest extends TestCase
{
$image = 'wysiwyg/VB.png';
$construction = ['{{media url=&quot;' . $image . '&quot;}}', 'media', ' url=&quot;' . $image . '&quot;'];
$baseUrl = 'http://localhost/pub/media/';
$baseUrl = 'http://localhost/media/';
$this->storeMock->expects($this->once())
->method('getBaseUrl')
@@ -68,7 +68,7 @@ class Wishlist implements SectionSourceInterface
}
/**
* {@inheritdoc}
* @inheritdoc
*/
public function getSectionData()
{
@@ -80,6 +80,8 @@ class Wishlist implements SectionSourceInterface
}
/**
* Get counter
*
* @return string
*/
protected function getCounter()
@@ -156,7 +158,6 @@ class Wishlist implements SectionSourceInterface
*
* @param \Magento\Catalog\Model\Product $product
* @return array
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function getImageData($product)
{
@@ -164,27 +165,11 @@ class Wishlist implements SectionSourceInterface
$helper = $this->imageHelperFactory->create()
->init($product, 'wishlist_sidebar_block');
$template = 'Magento_Catalog/product/image_with_borders';
try {
$imagesize = $helper->getResizedImageInfo();
} catch (NotLoadInfoImageException $exception) {
$imagesize = [$helper->getWidth(), $helper->getHeight()];
}
$width = $helper->getFrame()
? $helper->getWidth()
: $imagesize[0];
$height = $helper->getFrame()
? $helper->getHeight()
: $imagesize[1];
return [
'template' => $template,
'template' => 'Magento_Catalog/product/image_with_borders',
'src' => $helper->getUrl(),
'width' => $width,
'height' => $height,
'width' => $helper->getWidth(),
'height' => $helper->getHeight(),
'alt' => $helper->getLabel(),
];
}
@@ -199,9 +199,6 @@ class WishlistTest extends TestCase
$this->catalogImageHelperMock->expects($this->any())
->method('getFrame')
->willReturn(true);
$this->catalogImageHelperMock->expects($this->once())
->method('getResizedImageInfo')
->willReturn([]);
$this->wishlistHelperMock->expects($this->once())
->method('getProductUrl')
@@ -400,9 +397,6 @@ class WishlistTest extends TestCase
$this->catalogImageHelperMock->expects($this->any())
->method('getFrame')
->willReturn(true);
$this->catalogImageHelperMock->expects($this->exactly(2))
->method('getResizedImageInfo')
->willReturn([]);
$this->wishlistHelperMock->expects($this->exactly(2))
->method('getProductUrl')
@@ -649,7 +649,7 @@ QUERY;
'image_prefix' => ''
],
'with_pub_media_strategy' => [
'image_prefix' => '/pub/media/catalog/category/'
'image_prefix' => '/media/catalog/category/'
],
'catalog_category_strategy' => [
'image_prefix' => 'catalog/category/'
@@ -673,7 +673,7 @@ QUERY;
'image_prefix' => ''
],
'with_pub_media_strategy' => [
'image_prefix' => '/pub/media/catalog/category/'
'image_prefix' => '/media/catalog/category/'
],
'catalog_category_strategy' => [
'image_prefix' => 'catalog/category/'
@@ -73,11 +73,11 @@ class ContentTest extends \PHPUnit\Framework\TestCase
$imagesJson = $this->block->getImagesJson();
$images = json_decode($imagesJson);
$image = array_shift($images);
$this->assertMatchesRegularExpression('/\/m\/a\/magento_image/', $image->file);
$this->assertMatchesRegularExpression('~/m/a/magento_image~', $image->file);
$this->assertSame('image', $image->media_type);
$this->assertSame('Image Alt Text', $image->label);
$this->assertSame('Image Alt Text', $image->label_default);
$this->assertMatchesRegularExpression('/\/pub\/media\/catalog\/product\/m\/a\/magento_image/', $image->url);
$this->assertMatchesRegularExpression('~/media/catalog/product/m/a/magento_image~', $image->url);
}
/**
@@ -120,9 +120,23 @@ class GalleryTest extends \PHPUnit\Framework\TestCase
$this->assertImages(reset($result), $this->placeholderExpectation);
}
/**
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
* @magentoConfigFixture default/web/url/catalog_media_url_format image_optimization_parameters
* @magentoDbIsolation enabled
* @return void
*/
public function testGetGalleryImagesJsonWithoutImagesWithImageOptimizationParametersInUrl(): void
{
$this->block->setData('product', $this->getProduct());
$result = $this->serializer->unserialize($this->block->getGalleryImagesJson());
$this->assertImages(reset($result), $this->placeholderExpectation);
}
/**
* @dataProvider galleryDisabledImagesDataProvider
* @magentoDataFixture Magento/Catalog/_files/product_with_multiple_images.php
* @magentoConfigFixture default/web/url/catalog_media_url_format hash
* @magentoDbIsolation enabled
* @param array $images
* @param array $expectation
@@ -141,6 +155,7 @@ class GalleryTest extends \PHPUnit\Framework\TestCase
* @dataProvider galleryDisabledImagesDataProvider
* @magentoDataFixture Magento/Catalog/_files/product_with_multiple_images.php
* @magentoDataFixture Magento/Store/_files/second_store.php
* @magentoConfigFixture default/web/url/catalog_media_url_format hash
* @magentoDbIsolation disabled
* @param array $images
* @param array $expectation
@@ -173,6 +188,8 @@ class GalleryTest extends \PHPUnit\Framework\TestCase
}
/**
* Test default image generation format.
*
* @dataProvider galleryImagesDataProvider
* @magentoDataFixture Magento/Catalog/_files/product_with_multiple_images.php
* @magentoDbIsolation enabled
@@ -230,10 +247,95 @@ class GalleryTest extends \PHPUnit\Framework\TestCase
];
}
/**
* @dataProvider galleryImagesWithImageOptimizationParametersInUrlDataProvider
* @magentoDataFixture Magento/Catalog/_files/product_with_multiple_images.php
* @magentoConfigFixture default/web/url/catalog_media_url_format image_optimization_parameters
* @magentoDbIsolation enabled
* @param array $images
* @param array $expectation
* @return void
*/
public function testGetGalleryImagesJsonWithImageOptimizationParametersInUrl(
array $images,
array $expectation
): void {
$product = $this->getProduct();
$this->setGalleryImages($product, $images);
$this->block->setData('product', $this->getProduct());
[$firstImage, $secondImage] = $this->serializer->unserialize($this->block->getGalleryImagesJson());
[$firstExpectedImage, $secondExpectedImage] = $expectation;
$this->assertImages($firstImage, $firstExpectedImage);
$this->assertImages($secondImage, $secondExpectedImage);
}
/**
* @return array
*/
public function galleryImagesWithImageOptimizationParametersInUrlDataProvider(): array
{
$imageExpectation = [
'thumb' => '/m/a/magento_image.jpg?width=88&height=110&store=default&image-type=thumbnail',
'img' => '/m/a/magento_image.jpg?width=700&height=700&store=default&image-type=image',
'full' => '/m/a/magento_image.jpg?store=default&image-type=image',
'caption' => 'Image Alt Text',
'position' => '1',
'isMain' => false,
'type' => 'image',
'videoUrl' => null,
];
$thumbnailExpectation = [
'thumb' => '/m/a/magento_thumbnail.jpg?width=88&height=110&store=default&image-type=thumbnail',
'img' => '/m/a/magento_thumbnail.jpg?width=700&height=700&store=default&image-type=image',
'full' => '/m/a/magento_thumbnail.jpg?store=default&image-type=image',
'caption' => 'Thumbnail Image',
'position' => '2',
'isMain' => false,
'type' => 'image',
'videoUrl' => null,
];
return [
'with_main_image' => [
'images' => [
'/m/a/magento_image.jpg' => [],
'/m/a/magento_thumbnail.jpg' => ['main' => true],
],
'expectation' => [
$imageExpectation,
array_merge($thumbnailExpectation, ['isMain' => true]),
],
],
'without_main_image' => [
'images' => [
'/m/a/magento_image.jpg' => [],
'/m/a/magento_thumbnail.jpg' => [],
],
'expectation' => [
array_merge($imageExpectation, ['isMain' => true]),
$thumbnailExpectation,
],
],
'with_changed_position' => [
'images' => [
'/m/a/magento_image.jpg' => ['position' => '2'],
'/m/a/magento_thumbnail.jpg' => ['position' => '1'],
],
'expectation' => [
array_merge($thumbnailExpectation, ['position' => '1']),
array_merge($imageExpectation, ['position' => '2', 'isMain' => true]),
],
],
];
}
/**
* @dataProvider galleryImagesOnStoreViewDataProvider
* @magentoDataFixture Magento/Catalog/_files/product_with_multiple_images.php
* @magentoDataFixture Magento/Store/_files/second_store.php
* @magentoConfigFixture default/web/url/catalog_media_url_format hash
* @magentoDbIsolation disabled
* @param array $images
* @param array $expectation
@@ -108,7 +108,7 @@ class UploadTest extends AbstractBackendController
'name' => 'magento_image.jpg',
'type' => 'image/jpeg',
'file' => '/m/a/magento_image.jpg.tmp',
'url' => 'http://localhost/pub/media/tmp/catalog/product/m/a/magento_image.jpg',
'url' => 'http://localhost/media/tmp/catalog/product/m/a/magento_image.jpg',
'tmp_media_path' => '/m/a/magento_image.jpg',
],
],
@@ -122,7 +122,7 @@ class UploadTest extends AbstractBackendController
'name' => 'product_image.png',
'type' => 'image/png',
'file' => '/p/r/product_image.png.tmp',
'url' => 'http://localhost/pub/media/tmp/catalog/product/p/r/product_image.png',
'url' => 'http://localhost/media/tmp/catalog/product/p/r/product_image.png',
'tmp_media_path' => '/p/r/product_image.png',
],
],
@@ -136,7 +136,7 @@ class UploadTest extends AbstractBackendController
'name' => 'magento_image.gif',
'type' => 'image/gif',
'file' => '/m/a/magento_image.gif.tmp',
'url' => 'http://localhost/pub/media/tmp/catalog/product/m/a/magento_image.gif',
'url' => 'http://localhost/media/tmp/catalog/product/m/a/magento_image.gif',
'tmp_media_path' => '/m/a/magento_image.gif',
],
],
@@ -170,7 +170,7 @@ class ProductTest extends AbstractController
$this->dispatch(sprintf('catalog/product/gallery/id/%s', $product->getEntityId()));
$this->assertStringContainsString(
'http://localhost/pub/media/catalog/product/',
'http://localhost/media/catalog/product/',
$this->getResponse()->getBody()
);
$this->assertStringContainsString($this->getProductImageFile(), $this->getResponse()->getBody());
@@ -52,7 +52,7 @@ class ImageTest extends \PHPUnit\Framework\TestCase
public function testGetUrlPlaceholder($model)
{
$this->assertStringMatchesFormat(
'http://localhost/pub/static/%s/frontend/%s/Magento_Catalog/images/product/placeholder/image.jpg',
'http://localhost/static/%s/frontend/%s/Magento_Catalog/images/product/placeholder/image.jpg',
$model->getUrl()
);
}
@@ -82,7 +82,7 @@ class ImagesTest extends \PHPUnit\Framework\TestCase
public function providerGetImageHtmlDeclaration()
{
return [
[true, 'wysiwyg/hello.png', true, '<img src="http://example.com/pub/media/wysiwyg/hello.png" alt="" />'],
[true, 'wysiwyg/hello.png', true, '<img src="http://example.com/media/wysiwyg/hello.png" alt="" />'],
[
false,
'wysiwyg/hello.png',
@@ -96,7 +96,7 @@ class ImagesTest extends \PHPUnit\Framework\TestCase
$this->assertStringContainsString($expectedResult, parse_url($actualResult, PHP_URL_PATH));
}
],
[true, 'wysiwyg/hello.png', false, 'http://example.com/pub/media/wysiwyg/hello.png'],
[true, 'wysiwyg/hello.png', false, 'http://example.com/media/wysiwyg/hello.png'],
[false, 'wysiwyg/hello.png', true, '<img src="{{media url=&quot;wysiwyg/hello.png&quot;}}" alt="" />'],
];
}
@@ -46,7 +46,7 @@ class ConfigTest extends \PHPUnit\Framework\TestCase
public function testGetConfigCssUrls()
{
$config = $this->model->getConfig();
$publicPathPattern = 'http://localhost/pub/static/%s/adminhtml/Magento/backend/en_US/%s';
$publicPathPattern = 'http://localhost/static/%s/adminhtml/Magento/backend/en_US/%s';
$tinyMce4Config = $config->getData('tinymce4');
$contentCss = $tinyMce4Config['content_css'];
if (is_array($contentCss)) {
@@ -105,7 +105,7 @@ class GetInsertImageContentTest extends TestCase
true,
false,
1,
'/pub/media/catalog/category/test-image.jpg'
'/media/catalog/category/test-image.jpg'
],
[
'test-image.jpg',
@@ -109,11 +109,12 @@ class StorageTest extends \PHPUnit\Framework\TestCase
$collection = $this->storage->getFilesCollection(self::$_baseDir, 'image');
$this->assertInstanceOf(Collection::class, $collection);
foreach ($collection as $item) {
$thumbUrl = parse_url($item->getThumbUrl(), PHP_URL_PATH);
$this->assertInstanceOf(DataObject::class, $item);
$this->assertStringEndsWith('/' . $fileName, $item->getUrl());
$this->assertEquals(
'/pub/media/.thumbsMagentoCmsModelWysiwygImagesStorageTest/magento_image.jpg',
parse_url($item->getThumbUrl(), PHP_URL_PATH),
'/media/.thumbsMagentoCmsModelWysiwygImagesStorageTest/magento_image.jpg',
$thumbUrl,
"Check if Thumbnail URL is equal to the generated URL"
);
$this->assertEquals(
@@ -387,17 +388,17 @@ class StorageTest extends \PHPUnit\Framework\TestCase
[
'/',
'image1.png',
'/pub/media/.thumbs/image1.png'
'/media/.thumbs/image1.png'
],
[
'/cms',
'image2.png',
'/pub/media/.thumbscms/image2.png'
'/media/.thumbscms/image2.png'
],
[
'/cms/pages',
'image3.png',
'/pub/media/.thumbscms/pages/image3.png'
'/media/.thumbscms/pages/image3.png'
]
];
}
@@ -6,6 +6,8 @@
namespace Magento\Config\Model\Config\Backend\Admin;
use Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
/**
* @magentoAppArea adminhtml
@@ -34,10 +36,7 @@ class RobotsTest extends \PHPUnit\Framework\TestCase
$this->model->setPath('design/search_engine_robots/custom_instructions');
$this->model->afterLoad();
$documentRootPath = $objectManager->get(DocumentRoot::class)->getPath();
$this->rootDirectory = $objectManager->get(
\Magento\Framework\Filesystem::class
)->getDirectoryRead($documentRootPath);
$this->rootDirectory = $objectManager->get(Filesystem::class)->getDirectoryRead(DirectoryList::PUB);
}
/**
@@ -57,7 +56,8 @@ class RobotsTest extends \PHPUnit\Framework\TestCase
*/
public function testAfterLoadRobotsTxtExists()
{
$this->assertEquals('Sitemap: http://store.com/sitemap.xml', $this->model->getValue());
$value = $this->model->getValue();
$this->assertEquals('Sitemap: http://store.com/sitemap.xml', $value);
}
/**
@@ -92,7 +92,8 @@ class RobotsTest extends \PHPUnit\Framework\TestCase
{
$robotsTxt = "User-Agent: *\nDisallow: /checkout";
$this->model->setValue($robotsTxt)->save();
$this->assertStringEqualsFile($this->rootDirectory->getAbsolutePath('robots.txt'), $robotsTxt);
$file = $this->rootDirectory->getAbsolutePath('robots.txt');
$this->assertStringEqualsFile($file, $robotsTxt);
}
/**
@@ -9,7 +9,7 @@ use Magento\Framework\App\Filesystem\DirectoryList;
$rootDirectory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
\Magento\Framework\Filesystem::class
)->getDirectoryWrite(
DirectoryList::ROOT
DirectoryList::PUB
);
if ($rootDirectory->isExist('robots.txt')) {
$rootDirectory->delete('robots.txt');
@@ -3,12 +3,15 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
use Magento\Framework\App\Filesystem\DirectoryList;
/** @var \Magento\Framework\Filesystem\Directory\Write $rootDirectory */
$rootDirectory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
\Magento\Framework\Filesystem::class
)->getDirectoryWrite(
DirectoryList::ROOT
);
$rootDirectory->copyFile($rootDirectory->getRelativePath(__DIR__ . '/robots.txt'), 'robots.txt');
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\TestFramework\Helper\Bootstrap;
/** @var $fileSystem Filesystem */
$fileSystem = Bootstrap::getObjectManager()->get(Filesystem::class);
$pubDirectory = $fileSystem->getDirectoryWrite(DirectoryList::PUB);
$rootDirectory = $fileSystem->getDirectoryRead(DirectoryList::ROOT);
$source = $rootDirectory->getAbsolutePath(__DIR__ . '/robots.txt');
$content = $rootDirectory->readFile(__DIR__ . '/robots.txt');
$pubDirectory->writeFile('robots.txt', $content);
@@ -1,130 +0,0 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Framework\Console;
use Magento\Framework\App\DeploymentConfig;
use Magento\Framework\App\DeploymentConfig\FileReader;
use Magento\Framework\App\DeploymentConfig\Writer;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Config\File\ConfigFilePool;
use Magento\Framework\Filesystem;
use Magento\Framework\ObjectManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
class CliTest extends \PHPUnit\Framework\TestCase
{
/**
* @var ObjectManagerInterface
*/
private $objectManager;
/**
* @var Filesystem
*/
private $filesystem;
/**
* @var ConfigFilePool
*/
private $configFilePool;
/**
* @var FileReader
*/
private $reader;
/**
* @var Writer
*/
private $writer;
/**
* @var array
*/
private $envConfig;
/**
* @inheritdoc
*/
protected function setUp(): void
{
$this->objectManager = Bootstrap::getObjectManager();
$this->configFilePool = $this->objectManager->get(ConfigFilePool::class);
$this->filesystem = $this->objectManager->get(Filesystem::class);
$this->reader = $this->objectManager->get(FileReader::class);
$this->writer = $this->objectManager->get(Writer::class);
$this->envConfig = $this->reader->load(ConfigFilePool::APP_ENV);
}
/**
* @inheritdoc
*/
protected function tearDown(): void
{
$this->filesystem->getDirectoryWrite(DirectoryList::CONFIG)->writeFile(
$this->configFilePool->getPath(ConfigFilePool::APP_ENV),
"<?php\n return array();\n"
);
$this->writer->saveConfig([ConfigFilePool::APP_ENV => $this->envConfig], true);
}
/**
* Checks that settings from env.php config file are applied
* to created application instance.
*
* @magentoAppIsolation enabled
* @param bool $isPub
* @param array $params
* @dataProvider documentRootIsPubProvider
*/
public function testDocumentRootIsPublic($isPub, $params)
{
$config = include __DIR__ . '/_files/env.php';
$config['directories']['document_root_is_pub'] = $isPub;
$this->writer->saveConfig([ConfigFilePool::APP_ENV => $config], true);
$cli = new Cli();
$cliReflection = new \ReflectionClass($cli);
$serviceManagerProperty = $cliReflection->getProperty('serviceManager');
$serviceManagerProperty->setAccessible(true);
$serviceManager = $serviceManagerProperty->getValue($cli);
$deploymentConfig = $this->objectManager->get(DeploymentConfig::class);
$serviceManager->setAllowOverride(true);
$serviceManager->setService(DeploymentConfig::class, $deploymentConfig);
$serviceManagerProperty->setAccessible(false);
$documentRootResolver = $cliReflection->getMethod('documentRootResolver');
$documentRootResolver->setAccessible(true);
self::assertEquals($params, $documentRootResolver->invoke($cli));
}
/**
* Provides document root setting and expecting
* properties for object manager creation.
*
* @return array
*/
public function documentRootIsPubProvider(): array
{
return [
[true, [
'MAGE_DIRS' => [
'pub' => ['uri' => ''],
'media' => ['uri' => 'media'],
'static' => ['uri' => 'static'],
'upload' => ['uri' => 'media/upload']
]
]],
[false, []]
];
}
}
@@ -1,46 +0,0 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
return [
'backend' => [
'frontName' => 'admin',
],
'crypt' => [
'key' => 'some_key',
],
'session' => [
'save' => 'files',
],
'db' => [
'table_prefix' => '',
'connection' => [],
],
'resource' => [],
'x-frame-options' => 'SAMEORIGIN',
'MAGE_MODE' => 'default',
'cache_types' => [
'config' => 1,
'layout' => 1,
'block_html' => 1,
'collections' => 1,
'reflection' => 1,
'db_ddl' => 1,
'eav' => 1,
'customer_notification' => 1,
'config_integration' => 1,
'config_integration_api' => 1,
'full_page' => 1,
'translate' => 1,
'config_webservice' => 1,
],
'install' => [
'date' => 'Thu, 09 Feb 2017 14:28:00 +0000',
],
'directories' => [
'document_root_is_pub' => true
]
];
@@ -30,7 +30,7 @@
height="52"
src="http://magento2.vagrant236/pub/static/version1502812784/frontend/Magento/blank/en_US/Magento_Email/logo_email.png"
src="http://magento2.vagrant236/static/version1502812784/frontend/Magento/blank/en_US/Magento_Email/logo_email.png"
alt="Main Website Store"
border="0"
/>
@@ -14,12 +14,12 @@
<div data-translate="[{&quot;shown&quot;:&quot;shown_1&quot;,&quot;translated&quot;:&quot;translated_1&quot;,&quot;original&quot;:&quot;original_1&quot;,&quot;location&quot;:&quot;Tag attribute (ALT, TITLE, etc.)&quot;,&quot;scope&quot;:&quot;scope_1&quot;}]"title="some_title_shown_1_in_div">
some_text_<span data-translate="[{&quot;shown&quot;:&quot;shown_2&quot;,&quot;translated&quot;:&quot;translated_2&quot;,&quot;original&quot;:&quot;original_2&quot;,&quot;location&quot;:&quot;Text&quot;,&quot;scope&quot;:&quot;scope_2&quot;}]">shown_2</span>_in_div
</div>
<script type="text/javascript" src="http://localhost/pub/static/frontend/Magento/luma/en_US/prototype/window.js"></script>
<link rel="stylesheet" type="text/css" href="http://localhost/pub/static/frontend/Magento/luma/en_US/prototype/windows/themes/default.css"/>
<link rel="stylesheet" type="text/css" href="http://localhost/pub/media/theme/static/frontend/{{design_package}}/default/en_US/Magento_Theme/prototype/magento.css"/>
<script type="text/javascript" src="http://localhost/pub/static/frontend/Magento/luma/en_US/mage/edit-trigger.js"></script>
<script type="text/javascript" src="http://localhost/pub/static/frontend/Magento/luma/en_US/mage/translate-inline.js"></script>
<link rel="stylesheet" type="text/css" href="http://localhost/pub/static/frontend/Magento/luma/en_US/mage/translate-inline.css"/>
<script type="text/javascript" src="http://localhost/static/frontend/Magento/luma/en_US/prototype/window.js"></script>
<link rel="stylesheet" type="text/css" href="http://localhost/static/frontend/Magento/luma/en_US/prototype/windows/themes/default.css"/>
<link rel="stylesheet" type="text/css" href="http://localhost/media/theme/static/frontend/{{design_package}}/default/en_US/Magento_Theme/prototype/magento.css"/>
<script type="text/javascript" src="http://localhost/static/frontend/Magento/luma/en_US/mage/edit-trigger.js"></script>
<script type="text/javascript" src="http://localhost/static/frontend/Magento/luma/en_US/mage/translate-inline.js"></script>
<link rel="stylesheet" type="text/css" href="http://localhost/static/frontend/Magento/luma/en_US/mage/translate-inline.css"/>
<script type="text/javascript">
(function($){
@@ -27,7 +27,7 @@
$(this).translateInline({
ajaxUrl: 'http://localhost/index.php/translation/ajax/index/',
area: 'frontend',
editTrigger: {img: 'http://localhost/pub/media/theme/static/frontend/{{design_package}}/default/en_US/Magento_Theme/fam_book_open.png'}
editTrigger: {img: 'http://localhost/media/theme/static/frontend/{{design_package}}/default/en_US/Magento_Theme/fam_book_open.png'}
});
});
})(jQuery);
@@ -181,7 +181,7 @@ class UrlTest extends \PHPUnit\Framework\TestCase
* Get url with type specified in params
*/
$mediaUrl = $this->model->getBaseUrl(['_type' => \Magento\Framework\UrlInterface::URL_TYPE_MEDIA]);
$this->assertEquals('http://localhost/pub/media/', $mediaUrl, 'Incorrect media url');
$this->assertEquals('http://localhost/media/', $mediaUrl, 'Incorrect media url');
$this->assertEquals('http://localhost/index.php/', $this->model->getBaseUrl(), 'Incorrect link url');
}
@@ -490,7 +490,7 @@ class AbstractBlockTest extends \PHPUnit\Framework\TestCase
{
$actualResult = $this->_block->getViewFileUrl('css/styles.css');
$this->assertStringMatchesFormat(
'http://localhost/pub/static/%s/frontend/%s/en_US/css/styles.css',
'http://localhost/static/%s/frontend/%s/en_US/css/styles.css',
$actualResult
);
}
@@ -17,8 +17,8 @@ class ProductTest extends \PHPUnit\Framework\TestCase
/**
* Base product image path
*/
const BASE_IMAGE_PATH = '#http\:\/\/localhost\/pub\/media\/catalog\/product\/cache\/[a-z0-9]{32}:path:#';
const BASE_IMAGE_PATH = '#http://localhost/media/catalog/product/cache/[a-z0-9]{32}:path:#';
/**
* Test getCollection None images
* 1) Check that image attributes were not loaded
@@ -52,6 +52,7 @@ class ProductTest extends \PHPUnit\Framework\TestCase
* 3) Check thumbnails when no thumbnail selected
*
* @magentoConfigFixture default_store sitemap/product/image_include all
* @magentoConfigFixture default/web/url/catalog_media_url_format hash
*/
public function testGetCollectionAll()
{
@@ -120,6 +121,7 @@ class ProductTest extends \PHPUnit\Framework\TestCase
* 3) Check thumbnails when no thumbnail selected
*
* @magentoConfigFixture default_store sitemap/product/image_include base
* @magentoConfigFixture default/web/url/catalog_media_url_format hash
*/
public function testGetCollectionBase()
{
@@ -169,14 +169,14 @@ class StoreTest extends \PHPUnit\Framework\TestCase
[UrlInterface::URL_TYPE_DIRECT_LINK, false, true, 'http://localhost/index.php/'],
[UrlInterface::URL_TYPE_DIRECT_LINK, true, false, 'http://localhost/'],
[UrlInterface::URL_TYPE_DIRECT_LINK, true, true, 'http://localhost/'],
[UrlInterface::URL_TYPE_STATIC, false, false, 'http://localhost/pub/static/'],
[UrlInterface::URL_TYPE_STATIC, false, true, 'http://localhost/pub/static/'],
[UrlInterface::URL_TYPE_STATIC, true, false, 'http://localhost/pub/static/'],
[UrlInterface::URL_TYPE_STATIC, true, true, 'http://localhost/pub/static/'],
[UrlInterface::URL_TYPE_MEDIA, false, false, 'http://localhost/pub/media/'],
[UrlInterface::URL_TYPE_MEDIA, false, true, 'http://localhost/pub/media/'],
[UrlInterface::URL_TYPE_MEDIA, true, false, 'http://localhost/pub/media/'],
[UrlInterface::URL_TYPE_MEDIA, true, true, 'http://localhost/pub/media/']
[UrlInterface::URL_TYPE_STATIC, false, false, 'http://localhost/static/'],
[UrlInterface::URL_TYPE_STATIC, false, true, 'http://localhost/static/'],
[UrlInterface::URL_TYPE_STATIC, true, false, 'http://localhost/static/'],
[UrlInterface::URL_TYPE_STATIC, true, true, 'http://localhost/static/'],
[UrlInterface::URL_TYPE_MEDIA, false, false, 'http://localhost/media/'],
[UrlInterface::URL_TYPE_MEDIA, false, true, 'http://localhost/media/'],
[UrlInterface::URL_TYPE_MEDIA, true, false, 'http://localhost/media/'],
[UrlInterface::URL_TYPE_MEDIA, true, true, 'http://localhost/media/']
];
}
@@ -196,8 +196,8 @@ class StoreTest extends \PHPUnit\Framework\TestCase
$this->model = $this->_getStoreModel();
$this->model->load('default');
$this->assertEquals('http://localhost/pub/static/', $this->model->getBaseUrl(UrlInterface::URL_TYPE_STATIC));
$this->assertEquals('http://localhost/pub/media/', $this->model->getBaseUrl(UrlInterface::URL_TYPE_MEDIA));
$this->assertEquals('http://localhost/static/', $this->model->getBaseUrl(UrlInterface::URL_TYPE_STATIC));
$this->assertEquals('http://localhost/media/', $this->model->getBaseUrl(UrlInterface::URL_TYPE_MEDIA));
}
/**
@@ -11,7 +11,7 @@ class FilterTest extends \PHPUnit\Framework\TestCase
{
$image = 'wysiwyg/VB.png';
$construction = ['{{media url="' . $image . '"}}', 'media', ' url="' . $image . '"'];
$baseUrl = 'http://localhost/pub/media/';
$baseUrl = 'http://localhost/media/';
/** @var \Magento\Widget\Model\Template\Filter $filter */
$filter = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
@@ -25,7 +25,7 @@ class FilterTest extends \PHPUnit\Framework\TestCase
{
$image = 'wysiwyg/VB.png';
$construction = ['{{media url=&quot;' . $image . '&quot;}}', 'media', ' url=&quot;' . $image . '&quot;'];
$baseUrl = 'http://localhost/pub/media/';
$baseUrl = 'http://localhost/media/';
/** @var \Magento\Widget\Model\Template\Filter $filter */
$filter = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
@@ -46,7 +46,7 @@ class ConfigTest extends \PHPUnit\Framework\TestCase
$jsFilename = $plugins['src'];
$this->assertStringMatchesFormat(
'http://localhost/pub/static/%s/adminhtml/Magento/backend/en_US/%s/editor_plugin.js',
'http://localhost/static/%s/adminhtml/Magento/backend/en_US/%s/editor_plugin.js',
$jsFilename
);
@@ -125,7 +125,7 @@ class CliCommand
);
$command = $this->getCliScriptCommand() . ' setup:db-schema:split-quote ' .
implode(" ", array_keys($installParams)) .
' -vvv --magento-init-params="' .
' -vvv --no-interaction --magento-init-params="' .
$initParams['magento-init-params'] . '"';
$this->shell->execute($command, array_values($installParams));
-39
View File
@@ -1,39 +0,0 @@
<?php
/**
* Application entry point
*
* Example - run a particular store or website:
* --------------------------------------------
* require __DIR__ . '/app/bootstrap.php';
* $params = $_SERVER;
* $params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'website2';
* $params[\Magento\Store\Model\StoreManager::PARAM_RUN_TYPE] = 'website';
* $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
* \/** @var \Magento\Framework\App\Http $app *\/
* $app = $bootstrap->createApplication(\Magento\Framework\App\Http::class);
* $bootstrap->run($app);
* --------------------------------------------
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
try {
require __DIR__ . '/app/bootstrap.php';
} catch (\Exception $e) {
echo <<<HTML
<div style="font:12px/1.35em arial, helvetica, sans-serif;">
<div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;">
<h3 style="margin:0;font-size:1.7em;font-weight:normal;text-transform:none;text-align:left;color:#2f2f2f;">
Autoload error</h3>
</div>
<p>{$e->getMessage()}</p>
</div>
HTML;
exit(1);
}
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication(\Magento\Framework\App\Http::class);
$bootstrap->run($app);
@@ -157,12 +157,12 @@ class DirectoryList extends \Magento\Framework\Filesystem\DirectoryList
self::DI => [parent::PATH => 'generated/metadata'],
self::GENERATION => [parent::PATH => Io::DEFAULT_DIRECTORY],
self::SESSION => [parent::PATH => 'var/session'],
self::MEDIA => [parent::PATH => 'pub/media', parent::URL_PATH => 'pub/media'],
self::STATIC_VIEW => [parent::PATH => 'pub/static', parent::URL_PATH => 'pub/static'],
self::PUB => [parent::PATH => 'pub', parent::URL_PATH => 'pub'],
self::MEDIA => [parent::PATH => 'pub/media', parent::URL_PATH => 'media'],
self::STATIC_VIEW => [parent::PATH => 'pub/static', parent::URL_PATH => 'static'],
self::PUB => [parent::PATH => 'pub', parent::URL_PATH => ''],
self::LIB_WEB => [parent::PATH => 'lib/web'],
self::TMP => [parent::PATH => 'var/tmp'],
self::UPLOAD => [parent::PATH => 'pub/media/upload', parent::URL_PATH => 'pub/media/upload'],
self::UPLOAD => [parent::PATH => 'pub/media/upload', parent::URL_PATH => 'media/upload'],
self::TMP_MATERIALIZATION_DIR => [parent::PATH => 'var/view_preprocessed/pub/static'],
self::TEMPLATE_MINIFICATION_DIR => [parent::PATH => 'var/view_preprocessed'],
self::SETUP => [parent::PATH => 'setup/src'],
@@ -1,75 +0,0 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Framework\App\Test\Unit\Config;
use Magento\Framework\App\Config;
use Magento\Framework\App\DeploymentConfig;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Config\ConfigOptionsListConstants;
use Magento\Framework\Config\DocumentRoot;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* Test class for checking settings that defined in config file
*/
class DocumentRootTest extends TestCase
{
/**
* @var Config|MockObject
*/
private $configMock;
/**
* @var DocumentRoot
*/
private $documentRoot;
protected function setUp(): void
{
$this->configMock = $this->getMockBuilder(DeploymentConfig::class)
->disableOriginalConstructor()
->getMock();
$this->documentRoot = new DocumentRoot($this->configMock);
}
/**
* Ensures that the path returned matches the pub/ path.
*/
public function testGetPath()
{
$this->configMockSetForDocumentRootIsPub();
$this->assertSame(DirectoryList::PUB, $this->documentRoot->getPath());
}
/**
* Ensures that the deployment configuration returns the mocked value for
* the pub/ folder.
*/
public function testIsPub()
{
$this->configMockSetForDocumentRootIsPub();
$this->assertTrue($this->documentRoot->isPub());
}
private function configMockSetForDocumentRootIsPub()
{
$this->configMock->expects($this->any())
->method('get')
->willReturnMap([
[
ConfigOptionsListConstants::CONFIG_PATH_DOCUMENT_ROOT_IS_PUB,
null,
true
],
]);
}
}
@@ -10,7 +10,7 @@ use Magento\Framework\App\DeploymentConfig;
/**
* Document root detector.
*
* @deprecared Magento always uses the pub directory
* @api
*/
class DocumentRoot
@@ -35,7 +35,7 @@ class DocumentRoot
*/
public function getPath(): string
{
return $this->isPub() ? DirectoryList::PUB : DirectoryList::ROOT;
return DirectoryList::PUB;
}
/**
@@ -45,6 +45,6 @@ class DocumentRoot
*/
public function isPub(): bool
{
return (bool)$this->config->get(ConfigOptionsListConstants::CONFIG_PATH_DOCUMENT_ROOT_IS_PUB);
return true;
}
}
@@ -174,7 +174,6 @@ class Cli extends Console\Application
{
$params = (new ComplexParameter(self::INPUT_KEY_BOOTSTRAP))->mergeFromArgv($_SERVER, $_SERVER);
$params[Bootstrap::PARAM_REQUIRE_MAINTENANCE] = null;
$params = $this->documentRootResolver($params);
$requestParams = $this->serviceManager->get('magento-init-params');
$appBootstrapKey = Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS;
@@ -230,26 +229,4 @@ class Cli extends Console\Application
return array_merge([], ...$commands);
}
/**
* Provides updated configuration in accordance to document root settings.
*
* @param array $config
* @return array
*/
private function documentRootResolver(array $config = []): array
{
$params = [];
$deploymentConfig = $this->serviceManager->get(DeploymentConfig::class);
if ((bool)$deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DOCUMENT_ROOT_IS_PUB)) {
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = [
DirectoryList::PUB => [DirectoryList::URL_PATH => ''],
DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'],
DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'],
DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'],
];
}
return array_merge_recursive($config, $params);
}
}
@@ -7,10 +7,12 @@ declare(strict_types=1);
namespace Magento\Framework\Data\Collection;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Config\DocumentRoot;
use Magento\Framework\Data\Collection;
use Magento\Framework\Filesystem\Directory\TargetDirectory;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\Phrase;
/**
* Filesystem items collection
@@ -130,28 +132,26 @@ class Filesystem extends \Magento\Framework\Data\Collection
protected $_collectedFiles = [];
/**
* @var TargetDirectory|null
* @var \Magento\Framework\Filesystem
*/
private $targetDirectory;
private $filesystem;
/**
* @var DocumentRoot|null
* @var WriteInterface
*/
private $documentRoot;
private $rootDirectory;
/**
* @param EntityFactoryInterface|null $_entityFactory
* @param TargetDirectory|null $targetDirectory
* @param DocumentRoot|null $documentRoot
* @param \Magento\Framework\Filesystem $filesystem
*/
public function __construct(
EntityFactoryInterface $_entityFactory = null,
TargetDirectory $targetDirectory = null,
DocumentRoot $documentRoot = null
\Magento\Framework\Filesystem $filesystem = null
) {
$this->_entityFactory = $_entityFactory ?? ObjectManager::getInstance()->get(EntityFactoryInterface::class);
$this->targetDirectory = $targetDirectory ?? ObjectManager::getInstance()->get(TargetDirectory::class);
$this->documentRoot = $documentRoot ?? ObjectManager::getInstance()->get(DocumentRoot::class);
$this->filesystem = $filesystem ?? ObjectManager::getInstance()->get(\Magento\Framework\Filesystem::class);
$this->rootDirectory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
parent::__construct($this->_entityFactory);
}
@@ -237,11 +237,8 @@ class Filesystem extends \Magento\Framework\Data\Collection
public function addTargetDir($value)
{
$value = (string)$value;
$directory = $this->targetDirectory->getDirectoryWrite($this->documentRoot->getPath());
if (!$directory->isDirectory($value)) {
// phpcs:ignore Magento2.Exceptions.DirectThrow
throw new \Exception('Unable to set target directory.');
if (!$this->rootDirectory->isDirectory($value)) {
throw new FileSystemException(__('Unable to set target directory.'));
}
$this->_targetDirs[$value] = $value;
return $this;
@@ -266,19 +263,18 @@ class Filesystem extends \Magento\Framework\Data\Collection
* @return void
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @throws \Magento\Framework\Exception\FileSystemException
* @throws FileSystemException
*/
protected function _collectRecursive($dir)
{
$directory = $this->targetDirectory->getDirectoryRead($this->documentRoot->getPath());
$collectedResult = [];
if (!is_array($dir)) {
$dir = [$dir];
}
foreach ($dir as $folder) {
if ($nodes = $directory->search('/*', $folder)) {
if ($nodes = $this->rootDirectory->search('/*', $folder)) {
foreach ($nodes as $node) {
$collectedResult[] = $directory->getAbsolutePath($node);
$collectedResult[] = $this->rootDirectory->getAbsolutePath($node);
}
}
}
@@ -287,7 +283,7 @@ class Filesystem extends \Magento\Framework\Data\Collection
}
foreach ($collectedResult as $item) {
if ($directory->isDirectory($item)
if ($this->rootDirectory->isDirectory($item)
&& (!$this->_allowedDirsMask || preg_match($this->_allowedDirsMask, basename($item)))
) {
if ($this->_collectDirs) {
@@ -300,7 +296,7 @@ class Filesystem extends \Magento\Framework\Data\Collection
if ($this->_collectRecursively) {
$this->_collectRecursive($item);
}
} elseif ($this->_collectFiles && $directory->isFile(
} elseif ($this->_collectFiles && $this->rootDirectory->isFile(
$item
) && (!$this->_allowedFilesMask || preg_match(
$this->_allowedFilesMask,
@@ -9,6 +9,7 @@ use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Config\DocumentRoot;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\TargetDirectory;
use Magento\Framework\Filesystem\DriverInterface;
use Magento\Framework\Filesystem\DriverPool;
@@ -46,8 +47,7 @@ class Uploader
/**
* Upload type. Used to right handle $_FILES array.
*
* @var \Magento\Framework\File\Uploader::SINGLE_STYLE|\Magento\Framework\File\Uploader::MULTIPLE_STYLE
* @var Uploader::SINGLE_STYLE|\Magento\Framework\File\Uploader::MULTIPLE_STYLE
* @access protected
*/
protected $_uploadType;
@@ -212,7 +212,7 @@ class Uploader
TargetDirectory $targetDirectory = null,
DocumentRoot $documentRoot = null
) {
$this->directoryList= $directoryList ?: ObjectManager::getInstance()->get(DirectoryList::class);
$this->directoryList = $directoryList ?: ObjectManager::getInstance()->get(DirectoryList::class);
$this->_setUploadFileId($fileId);
if (!file_exists($this->_file['tmp_name'])) {
@@ -741,7 +741,7 @@ class Uploader
* Create destination folder
*
* @param string $destinationFolder
* @return \Magento\Framework\File\Uploader
* @return Uploader
* @throws FileSystemException
*/
private function createDestinationFolder(string $destinationFolder)
@@ -774,20 +774,24 @@ class Uploader
*/
public static function getNewFileName($destinationFile)
{
/** @var Filesystem $fileSystem */
$fileSystem = ObjectManager::getInstance()->get(Filesystem::class);
$local = $fileSystem->getDirectoryRead(DirectoryList::ROOT);
/** @var TargetDirectory $targetDirectory */
$targetDirectory = ObjectManager::getInstance()->get(TargetDirectory::class);
$remote = $targetDirectory->getDirectoryRead(DirectoryList::ROOT);
$fileExists = function ($path) use ($local, $remote) {
return $local->isExist($path) || $remote->isExist($path);
};
$fileInfo = pathinfo($destinationFile);
if (file_exists($destinationFile)) {
$index = 1;
$baseName = $fileInfo['filename'] . '.' . $fileInfo['extension'];
while (file_exists($fileInfo['dirname'] . '/' . $baseName)) {
$baseName = $fileInfo['filename'] . '_' . $index . '.' . $fileInfo['extension'];
$index++;
}
$destFileName = $baseName;
} else {
return $fileInfo['basename'];
$index = 1;
while ($fileExists($fileInfo['dirname'] . '/' . $fileInfo['basename'])) {
$fileInfo['basename'] = $fileInfo['filename'] . '_' . $index++ . '.' . $fileInfo['extension'];
}
return $destFileName;
return $fileInfo['basename'];
}
/**
@@ -116,7 +116,7 @@ class Write extends Read implements WriteInterface
}
$absolutePath = $this->driver->getAbsolutePath($this->path, $path);
$absoluteNewPath = $targetDirectory->getAbsolutePath($newPath);
return $this->driver->rename($absolutePath, $absoluteNewPath, $targetDirectory->driver);
return $this->driver->rename($absolutePath, $absoluteNewPath, $targetDirectory->getDriver());
}
/**
@@ -5,6 +5,7 @@
*/
namespace Magento\Framework\HTTP\PhpEnvironment;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Stdlib\Cookie\CookieReaderInterface;
use Magento\Framework\Stdlib\StringUtils;
use Laminas\Http\Header\HeaderInterface;
@@ -794,7 +795,7 @@ class Request extends \Laminas\Http\PhpEnvironment\Request
public function getBaseUrl()
{
$url = urldecode(parent::getBaseUrl());
$url = str_replace('\\', '/', $url);
$url = str_replace(['\\', '/' . DirectoryList::PUB .'/'], '/', $url);
return $url;
}
-4
View File
@@ -48,10 +48,6 @@ class Image
{
$this->_adapter->checkDependencies();
if (!file_exists($this->_fileName)) {
throw new \Exception("File '{$this->_fileName}' does not exist.");
}
$this->_adapter->open($this->_fileName);
}
@@ -13,8 +13,10 @@ namespace Magento\Framework\View\Test\Unit\Design\Theme;
use Magento\Framework\App\Area;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\ReadInterface;
use Magento\Framework\Filesystem\Directory\Write;
use Magento\Framework\Image\Factory;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\View\Design\Theme\Image;
use Magento\Framework\View\Design\Theme\Image\Uploader;
@@ -70,8 +72,20 @@ class ImageTest extends TestCase
*/
protected $imagePathMock;
private function setupObjectManagerForCheckImageExist($return)
{
$objectManagerMock = $this->getMockForAbstractClass(ObjectManagerInterface::class);
$mockFileSystem = $this->createMock(Filesystem::class);
$mockRead = $this->createMock(ReadInterface::class);
$objectManagerMock->method($this->logicalOr('get', 'create'))->willReturn($mockFileSystem);
$mockFileSystem->method('getDirectoryRead')->willReturn($mockRead);
$mockRead->method('isExist')->willReturn($return);
\Magento\Framework\App\ObjectManager::setInstance($objectManagerMock);
}
protected function setUp(): void
{
$this->setupObjectManagerForCheckImageExist(false);
$this->_mediaDirectoryMock = $this->createPartialMock(
Write::class,
['isExist', 'copyFile', 'getRelativePath', 'delete']
+25
View File
@@ -26,6 +26,9 @@
##
## In production mode, you should uncomment the 'expires' directive in the /static/ location block
# Modules can be loaded only at the very beginning of the Nginx config file, please move the line below to the main config file
# load_module /etc/nginx/modules/ngx_http_image_filter_module.so;
root $MAGE_ROOT/pub;
index index.php;
@@ -134,6 +137,28 @@ location /static/ {
}
location /media/ {
## The following section allows to offload image resizing from Magento instance to the Nginx.
## Catalog image URL format should be set accordingly.
## See https://docs.magento.com/m2/ee/user_guide/configuration/general/web.html#url-options
# location ~* ^/media/catalog/.* {
#
# # Replace placeholders and uncomment the line below to serve product images from public S3
# # See examples of S3 authentication at https://github.com/anomalizer/ngx_aws_auth
# # proxy_pass https://<bucket-name>.<region-name>.amazonaws.com;
#
# set $width "-";
# set $height "-";
# if ($arg_width != '') {
# set $width $arg_width;
# }
# if ($arg_height != '') {
# set $height $arg_height;
# }
# image_filter resize $width $height;
# image_filter_jpeg_quality 90;
# }
try_files $uri $uri/ /get.php$is_args$args;
location ~ ^/media/theme_customization/.*\.xml {
+70 -32
View File
@@ -22,6 +22,11 @@
## cgi.fix_pathinfo = 1
## If it still doesn't work, rename php.ini to php5.ini
############################################
## Enable usage of methods arguments in backtrace
#SetEnv MAGE_DEBUG_SHOW_ARGS 1
############################################
## This line is specific for 1and1 hosting
@@ -33,24 +38,6 @@
DirectoryIndex index.php
<IfModule mod_php5.c>
############################################
## Adjust memory limit
php_value memory_limit 756M
php_value max_execution_time 18000
############################################
## Disable automatic session start
## before autoload was initialized
php_flag session.auto_start off
############################################
# Disable user agent verification to not break multiple image upload
php_flag suhosin.session.cryptua off
</IfModule>
<IfModule mod_php7.c>
############################################
## Adjust memory limit
@@ -75,7 +62,6 @@
php_flag suhosin.session.cryptua off
</IfModule>
<IfModule mod_security.c>
###########################################
# Disable POST processing to not break multiple image upload
@@ -93,7 +79,7 @@
# Insert filter on all content
###SetOutputFilter DEFLATE
# Insert filter on selected content types only
#AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
#AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript application/json image/svg+xml
# Netscape 4.x has some problems...
#BrowserMatch ^Mozilla/4 gzip-only-text/html
@@ -121,6 +107,13 @@
</IfModule>
############################################
## Workaround for Apache 2.4.6 CentOS build when working via ProxyPassMatch with HHVM (or any other)
## Please, set it on virtual host configuration level
## SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
############################################
<IfModule mod_rewrite.c>
############################################
@@ -147,6 +140,13 @@
RewriteCond %{REQUEST_METHOD} ^TRAC[EK]
RewriteRule .* - [L,R=405]
############################################
## Redirect for mobile user agents
#RewriteCond %{REQUEST_URI} !^/mobiledirectoryhere/.*$
#RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC]
#RewriteRule ^(.*)$ /mobiledirectoryhere/ [L,R=302]
############################################
## Never rewrite for existing files, directories and links
@@ -168,6 +168,7 @@
AddDefaultCharset Off
#AddDefaultCharset UTF-8
AddType 'text/html; charset=UTF-8' html
<IfModule mod_expires.c>
@@ -193,18 +194,15 @@
Require all denied
</IfVersion>
</Files>
# For 404s and 403s that aren't handled by the application, show plain 404 response
ErrorDocument 404 /errors/404.php
ErrorDocument 403 /errors/404.php
############################################
## If running in cluster environment, uncomment this
## http://developer.yahoo.com/performance/rules.html#etags
#FileETag none
###########################################
<Files .htaccess>
<IfVersion < 2.4>
order allow,deny
deny from all
</IfVersion>
<IfVersion >= 2.4>
Require all denied
</IfVersion>
</Files>
## Deny access to cron.php
<Files cron.php>
<IfVersion < 2.4>
@@ -226,8 +224,48 @@ ErrorDocument 403 /errors/404.php
</IfVersion>
</Files>
# For 404s and 403s that aren't handled by the application, show plain 404 response
ErrorDocument 404 /errors/404.php
ErrorDocument 403 /errors/404.php
################################
## If running in cluster environment, uncomment this
## http://developer.yahoo.com/performance/rules.html#etags
#FileETag none
# ######################################################################
# # INTERNET EXPLORER #
# ######################################################################
# ----------------------------------------------------------------------
# | Document modes |
# ----------------------------------------------------------------------
# Force Internet Explorer 8/9/10 to render pages in the highest mode
# available in the various cases when it may not.
#
# https://hsivonen.fi/doctype/#ie8
#
# (!) Starting with Internet Explorer 11, document modes are deprecated.
# If your business still relies on older web apps and services that were
# designed for older versions of Internet Explorer, you might want to
# consider enabling `Enterprise Mode` throughout your company.
#
# https://msdn.microsoft.com/en-us/library/ie/bg182625.aspx#docmode
# http://blogs.msdn.com/b/ie/archive/2014/04/02/stay-up-to-date-with-enterprise-mode-for-internet-explorer-11.aspx
<IfModule mod_headers.c>
############################################
Header set X-UA-Compatible "IE=edge"
# `mod_headers` cannot match based on the content-type, however,
# the `X-UA-Compatible` response header should be send only for
# HTML documents and not for the other resources.
<FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ico|jpe?g|js|json(ld)?|m4[av]|manifest|map|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xml|xpi)$">
Header unset X-UA-Compatible
</FilesMatch>
## Prevent clickjacking
Header set X-Frame-Options SAMEORIGIN
</IfModule>
+1 -12
View File
@@ -7,7 +7,6 @@
*/
use Magento\Framework\App\Bootstrap;
use Magento\Framework\App\Filesystem\DirectoryList;
try {
require __DIR__ . '/../app/bootstrap.php';
@@ -24,17 +23,7 @@ HTML;
exit(1);
}
$params = $_SERVER;
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive(
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] ?? [],
[
DirectoryList::PUB => [DirectoryList::URL_PATH => ''],
DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'],
DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'],
DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'],
]
);
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
$bootstrap = Bootstrap::create(BP, $_SERVER);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication(\Magento\Framework\App\Http::class);
$bootstrap->run($app);
@@ -37,7 +37,7 @@ class ImagesGenerator
/**
* Generates image from $data and puts its to /tmp folder
*
* @param string $config
* @param array $config
* @return string $imagePath
*/
public function generate($config)
@@ -15,6 +15,7 @@ use Magento\Framework\Setup\Option\SelectConfigOption;
/**
* Deployment configuration options for the folders.
* @deprecared Magento always uses the pub directory
*/
class Directory implements ConfigOptionsListInterface
{
@@ -70,7 +71,7 @@ class Directory implements ConfigOptionsListInterface
$this->selectOptions,
self::CONFIG_PATH_DOCUMENT_ROOT_IS_PUB,
'Flag to show is Pub is on root, can be true or false only',
false
true
),
];
}