From 0d08f606e2d409f2468128b3f0aefde0fb9375dc Mon Sep 17 00:00:00 2001 From: Robert He Date: Thu, 30 Jun 2016 00:19:09 +0300 Subject: [PATCH 01/19] MAGETWO-55662: Portdown MAGETWO-51428 down to M2.1.x branch (cherry picked from commit 5dcc618) --- .htaccess | 30 ------------------------------ .htaccess.sample | 30 ------------------------------ nginx.conf.sample | 2 +- pub/.htaccess | 32 +------------------------------- 4 files changed, 2 insertions(+), 92 deletions(-) diff --git a/.htaccess b/.htaccess index 61a6e70d03e7f..f3dbe217081ac 100644 --- a/.htaccess +++ b/.htaccess @@ -32,34 +32,6 @@ DirectoryIndex index.php - - -############################################ -## adjust memory limit - - php_value memory_limit 768M - 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 - - - - - ############################################ ## adjust memory limit @@ -82,8 +54,6 @@ php_flag suhosin.session.cryptua off - - ########################################### ## disable POST processing to not break multiple image upload diff --git a/.htaccess.sample b/.htaccess.sample index 61a6e70d03e7f..f3dbe217081ac 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -32,34 +32,6 @@ DirectoryIndex index.php - - -############################################ -## adjust memory limit - - php_value memory_limit 768M - 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 - - - - - ############################################ ## adjust memory limit @@ -82,8 +54,6 @@ php_flag suhosin.session.cryptua off - - ########################################### ## disable POST processing to not break multiple image upload diff --git a/nginx.conf.sample b/nginx.conf.sample index 95f03f4dd2145..de37b23d759fe 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -161,7 +161,7 @@ location ~ (index|get|static|report|404|503)\.php$ { fastcgi_buffers 1024 4k; fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; - fastcgi_param PHP_VALUE "memory_limit=768M \n max_execution_time=600"; + fastcgi_param PHP_VALUE "memory_limit=768M \n max_execution_time=18000"; fastcgi_read_timeout 600s; fastcgi_connect_timeout 600s; diff --git a/pub/.htaccess b/pub/.htaccess index 926c012eef6a5..a8fc2ccf222db 100644 --- a/pub/.htaccess +++ b/pub/.htaccess @@ -32,12 +32,10 @@ DirectoryIndex index.php - - ############################################ ## Adjust memory limit - php_value memory_limit 256M + php_value memory_limit 768M php_value max_execution_time 18000 ############################################ @@ -56,34 +54,6 @@ php_flag suhosin.session.cryptua off - - - - -############################################ -## Adjust memory limit - - php_value memory_limit 256M - 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 - - - ########################################### # Disable POST processing to not break multiple image upload From 7c31c1daf22a7a30cfb6a93b69b96e5a6d19361d Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Thu, 25 Aug 2016 14:54:41 +0300 Subject: [PATCH 02/19] MAGETWO-55662: Portdown MAGETWO-51428 down to M2.1.x branch (cherry picked from commit ddb1eea) --- .htaccess | 24 ++++++++++++++++++++++++ pub/.htaccess | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/.htaccess b/.htaccess index f3dbe217081ac..af9470488c632 100644 --- a/.htaccess +++ b/.htaccess @@ -32,6 +32,7 @@ DirectoryIndex index.php + ############################################ ## adjust memory limit @@ -53,7 +54,30 @@ ## disable user agent verification to not break multiple image upload php_flag suhosin.session.cryptua off + + +############################################ +## adjust memory limit + + php_value memory_limit 768M + 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 + ########################################### ## disable POST processing to not break multiple image upload diff --git a/pub/.htaccess b/pub/.htaccess index a8fc2ccf222db..ecdaf1758a92a 100644 --- a/pub/.htaccess +++ b/pub/.htaccess @@ -32,6 +32,7 @@ DirectoryIndex index.php + ############################################ ## Adjust memory limit @@ -53,6 +54,31 @@ # Disable user agent verification to not break multiple image upload php_flag suhosin.session.cryptua off + + +############################################ +## Adjust memory limit + + php_value memory_limit 768M + 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 + + ########################################### From 49378d049922682cf8cdde278f505d12873d71c0 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov Date: Tue, 30 Aug 2016 12:58:44 +0300 Subject: [PATCH 03/19] MAGETWO-55662: Portdown MAGETWO-51428 down to M2.1.x branch (cherry picked from commit be08f1a) --- .user.ini | 4 ++++ pub/.user.ini | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 .user.ini create mode 100644 pub/.user.ini diff --git a/.user.ini b/.user.ini new file mode 100644 index 0000000000000..8c0b765e0551c --- /dev/null +++ b/.user.ini @@ -0,0 +1,4 @@ +memory_limit = 768M +max_execution_time = 18000 +session.auto_start = off +suhosin.session.cryptua = off \ No newline at end of file diff --git a/pub/.user.ini b/pub/.user.ini new file mode 100644 index 0000000000000..8c0b765e0551c --- /dev/null +++ b/pub/.user.ini @@ -0,0 +1,4 @@ +memory_limit = 768M +max_execution_time = 18000 +session.auto_start = off +suhosin.session.cryptua = off \ No newline at end of file From e100fd028a92bb37602c55f9da01c90ee24b3259 Mon Sep 17 00:00:00 2001 From: vzabaznov Date: Wed, 14 Sep 2016 08:51:42 +0300 Subject: [PATCH 04/19] MAGETWO-55662: Portdown MAGETWO-51428 down to M2.1.x branch --- nginx.conf.sample | 2 -- 1 file changed, 2 deletions(-) diff --git a/nginx.conf.sample b/nginx.conf.sample index de37b23d759fe..078466bb9dd04 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -160,8 +160,6 @@ location ~ (index|get|static|report|404|503)\.php$ { fastcgi_pass fastcgi_backend; fastcgi_buffers 1024 4k; - fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; - fastcgi_param PHP_VALUE "memory_limit=768M \n max_execution_time=18000"; fastcgi_read_timeout 600s; fastcgi_connect_timeout 600s; From 88112d84ce128a1c25864e64bea5aee83281f619 Mon Sep 17 00:00:00 2001 From: vzabaznov Date: Wed, 14 Sep 2016 11:11:38 +0300 Subject: [PATCH 05/19] MAGETWO-55662: Portdown MAGETWO-51428 down to M2.1.x branch --- .htaccess | 205 +---------------------------------------------- .htaccess.sample | 26 +++++- 2 files changed, 27 insertions(+), 204 deletions(-) diff --git a/.htaccess b/.htaccess index af9470488c632..89e39655e9289 100644 --- a/.htaccess +++ b/.htaccess @@ -1,207 +1,43 @@ -############################################ -## 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 - -############################################ -## default index file - - DirectoryIndex index.php - +# All explanations you could find in .htaccess.sample file +DirectoryIndex index.php -############################################ -## adjust memory limit - php_value memory_limit 768M 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 -############################################ -## adjust memory limit - php_value memory_limit 768M 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 -########################################### -## disable POST processing to not break multiple image upload - SecFilterEngine Off SecFilterScanPOST Off - - - -############################################ -## 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 - - - - -############################################ -## make HTTPS env vars available for CGI mode - SSLOptions StdEnvVars - - -############################################ -## 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 -############################################ - - -############################################ -## 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] - - - -############################################ -## 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 - - -############################################ -## 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 - - -########################################### -## Deny access to root files to hide sensitive application information RedirectMatch 403 /\.git - order allow,deny deny from all @@ -274,48 +110,11 @@ order allow,deny deny from all - -# 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 - - 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. - Header unset X-UA-Compatible - diff --git a/.htaccess.sample b/.htaccess.sample index f3dbe217081ac..85eac7913c73b 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -30,8 +30,9 @@ ############################################ ## default index file - DirectoryIndex index.php +DirectoryIndex index.php + ############################################ ## adjust memory limit @@ -53,7 +54,30 @@ ## disable user agent verification to not break multiple image upload php_flag suhosin.session.cryptua off + + +############################################ +## adjust memory limit + + php_value memory_limit 768M + 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 + ########################################### ## disable POST processing to not break multiple image upload From 16c54a004b2fe21eb69bf1cf95d3be58e8df0faf Mon Sep 17 00:00:00 2001 From: oserediuk Date: Fri, 1 Jul 2016 15:20:06 +0300 Subject: [PATCH 06/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 (cherry picked from commit 21dd4cc) --- .../Product/Helper/Form/Gallery/Content.php | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index f61f9071155aa..4c6ced39a7bd8 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -34,6 +34,16 @@ class Content extends \Magento\Backend\Block\Widget */ protected $_jsonEncoder; + /** + * @var \Magento\Catalog\Helper\Image + */ + private $imageHelper; + + /** + * @var \Magento\Framework\View\Asset\Repository + */ + private $assetRepo; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder @@ -128,12 +138,22 @@ public function getImagesJson() is_array($value['images']) && count($value['images']) ) { - $directory = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); + $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); + $staticDir = $this->_filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW); $images = $this->sortImagesByPosition($value['images']); foreach ($images as &$image) { $image['url'] = $this->_mediaConfig->getMediaUrl($image['file']); - $fileHandler = $directory->stat($this->_mediaConfig->getMediaPath($image['file'])); - $image['size'] = $fileHandler['size']; + try { + $fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file'])); + $image['size'] = $fileHandler['size']; + } catch (\Exception $e) { + $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('image'); + $fileHandler = $staticDir->stat( + $this->getAssetRepo()->createAsset($this->getImageHelper()->getPlaceholder('image'))->getPath() + ); + $image['size'] = $fileHandler['size']; + $this->_logger->warning($e); + } } return $this->_jsonEncoder->encode($images); } @@ -227,4 +247,33 @@ public function getImageTypesJson() { return $this->_jsonEncoder->encode($this->getImageTypes()); } + + /** + * @return \Magento\Catalog\Helper\Image + * + * @deprecated + */ + private function getImageHelper() + { + if ($this->imageHelper === null) { + $this->imageHelper = \Magento\Framework\App\ObjectManager::getInstance() + ->get('Magento\Catalog\Helper\Image'); + } + return $this->imageHelper; + } + + /** + * @return \Magento\Framework\View\Asset\Repository + * + * @deprecated + */ + private function getAssetRepo() + { + if ($this->assetRepo === null) { + $this->assetRepo = \Magento\Framework\App\ObjectManager::getInstance() + ->get('\Magento\Framework\View\Asset\Repository'); + } + + return $this->assetRepo; + } } From 74ab960fda20e627aeaf270eafe9343ad9d5fa82 Mon Sep 17 00:00:00 2001 From: oserediuk Date: Mon, 4 Jul 2016 16:24:53 +0300 Subject: [PATCH 07/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 - (cherry picked from commit 16895be) --- .../Block/Adminhtml/Product/Helper/Form/Gallery/Content.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 4c6ced39a7bd8..7dd45ac2e8d40 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -146,7 +146,7 @@ public function getImagesJson() try { $fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file'])); $image['size'] = $fileHandler['size']; - } catch (\Exception $e) { + } catch (\Exception $e) { $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('image'); $fileHandler = $staticDir->stat( $this->getAssetRepo()->createAsset($this->getImageHelper()->getPlaceholder('image'))->getPath() @@ -250,7 +250,6 @@ public function getImageTypesJson() /** * @return \Magento\Catalog\Helper\Image - * * @deprecated */ private function getImageHelper() @@ -264,7 +263,6 @@ private function getImageHelper() /** * @return \Magento\Framework\View\Asset\Repository - * * @deprecated */ private function getAssetRepo() From 7e9f6533a7f9ac0f6e74a177e6511636be80444e Mon Sep 17 00:00:00 2001 From: oserediuk Date: Mon, 4 Jul 2016 17:13:43 +0300 Subject: [PATCH 08/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 - (cherry picked from commit 39d7f39) --- .../Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php index 72a25933efa0b..e07bfc8164ea3 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php @@ -126,7 +126,7 @@ public function testGetImagesJson() $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->fileSystemMock->expects($this->exactly(2))->method('getDirectoryRead')->willReturn($this->readMock); $this->mediaConfigMock->expects($this->any())->method('getMediaUrl')->willReturnMap($url); $this->mediaConfigMock->expects($this->any())->method('getMediaPath')->willReturnMap($mediaPath); From 7a900b8eb966ca2a4770bf01352bbbb56dc2a531 Mon Sep 17 00:00:00 2001 From: oserediuk Date: Thu, 7 Jul 2016 13:06:48 +0300 Subject: [PATCH 09/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 - (cherry picked from commit 3459ef1) --- .../Product/Helper/Form/Gallery/Content.php | 10 +- .../Helper/Form/Gallery/ContentTest.php | 118 +++++++++++++++++- 2 files changed, 119 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 7dd45ac2e8d40..105d3c107ee3f 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -138,18 +138,18 @@ public function getImagesJson() is_array($value['images']) && count($value['images']) ) { - $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); - $staticDir = $this->_filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW); + $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); $images = $this->sortImagesByPosition($value['images']); foreach ($images as &$image) { $image['url'] = $this->_mediaConfig->getMediaUrl($image['file']); try { $fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file'])); $image['size'] = $fileHandler['size']; - } catch (\Exception $e) { - $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('image'); + } catch (\Magento\Framework\Exception\FileSystemException $e) { + $staticDir = $this->_filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW); + $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('thumbnail'); $fileHandler = $staticDir->stat( - $this->getAssetRepo()->createAsset($this->getImageHelper()->getPlaceholder('image'))->getPath() + $this->getAssetRepo()->createAsset($this->getImageHelper()->getPlaceholder('thumbnail'))->getPath() ); $image['size'] = $fileHandler['size']; $this->_logger->warning($e); diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php index e07bfc8164ea3..33faf5963c910 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php @@ -7,6 +7,7 @@ use Magento\Framework\Filesystem; use Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery\Content; +use Magento\Framework\Phrase; class ContentTest extends \PHPUnit_Framework_TestCase { @@ -40,6 +41,16 @@ class ContentTest extends \PHPUnit_Framework_TestCase */ protected $galleryMock; + /** + * @var \Magento\Catalog\Helper\Image|\PHPUnit_Framework_MockObject_MockObject + */ + protected $imageHelper; + + /** + * @var \Magento\Framework\View\Asset\Repository|\PHPUnit_Framework_MockObject_MockObject + */ + protected $assetRepo; + /** * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ @@ -47,7 +58,13 @@ class ContentTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->fileSystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false); + $this->fileSystemMock = $this->getMock( + 'Magento\Framework\Filesystem', + ['stat', 'getDirectoryRead'], + [], + '', + false + ); $this->readMock = $this->getMock('Magento\Framework\Filesystem\Directory\ReadInterface'); $this->galleryMock = $this->getMock( 'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery', @@ -56,7 +73,13 @@ public function setUp() '', false ); - $this->mediaConfigMock = $this->getMock('Magento\Catalog\Model\Product\Media\Config', [], [], '', false); + $this->mediaConfigMock = $this->getMock( + 'Magento\Catalog\Model\Product\Media\Config', + ['getMediaUrl', 'getMediaPath'], + [], + '', + false + ); $this->jsonEncoderMock = $this->getMockBuilder('Magento\Framework\Json\EncoderInterface') ->disableOriginalConstructor() ->getMock(); @@ -126,11 +149,10 @@ public function testGetImagesJson() $this->content->setElement($this->galleryMock); $this->galleryMock->expects($this->once())->method('getImages')->willReturn($images); - $this->fileSystemMock->expects($this->exactly(2))->method('getDirectoryRead')->willReturn($this->readMock); + $this->fileSystemMock->expects($this->once())->method('getDirectoryRead')->willReturn($this->readMock); $this->mediaConfigMock->expects($this->any())->method('getMediaUrl')->willReturnMap($url); $this->mediaConfigMock->expects($this->any())->method('getMediaPath')->willReturnMap($mediaPath); - $this->readMock->expects($this->any())->method('stat')->willReturnMap($sizeMap); $this->jsonEncoderMock->expects($this->once())->method('encode')->willReturnCallback('json_encode'); @@ -144,4 +166,92 @@ public function testGetImagesJsonWithoutImages() $this->assertSame('[]', $this->content->getImagesJson()); } + + public function testGetImagesJsonWithException() + { + $this->imageHelper = $this->getMockBuilder('Magento\Catalog\Helper\Image') + ->disableOriginalConstructor() + ->setMethods(['getDefaultPlaceholderUrl', 'getPlaceholder']) + ->getMock(); + + $this->assetRepo = $this->getMockBuilder('Magento\Framework\View\Asset\Repository') + ->disableOriginalConstructor() + ->setMethods(['createAsset', 'getPath']) + ->getMock(); + + $this->objectManager->setBackwardCompatibleProperty( + $this->content, + 'imageHelper', + $this->imageHelper + ); + + $this->objectManager->setBackwardCompatibleProperty( + $this->content, + 'assetRepo', + $this->assetRepo + ); + + $placeholderUrl = 'url_to_the_placeholder/placeholder.jpg'; + + $sizePlaceholder = ['size' => 399659]; + + $imagesResult = [ + [ + 'value_id' => '2', + 'file' => 'file_2.jpg', + 'media_type' => 'image', + 'position' => '0', + 'url' => 'url_to_the_placeholder/placeholder.jpg', + 'size' => 399659 + ], + [ + 'value_id' => '1', + 'file' => 'file_1.jpg', + 'media_type' => 'image', + 'position' => '1', + 'url' => 'url_to_the_placeholder/placeholder.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->any())->method('getDirectoryRead')->willReturn($this->readMock); + $this->mediaConfigMock->expects($this->any())->method('getMediaUrl'); + $this->mediaConfigMock->expects($this->any())->method('getMediaPath'); + $this->readMock->expects($this->any())->method('stat')->willReturnOnConsecutiveCalls( + $this->throwException( + new \Magento\Framework\Exception\FileSystemException(new \Magento\Framework\Phrase('test')) + ), + $sizePlaceholder, + $this->throwException( + new \Magento\Framework\Exception\FileSystemException(new \Magento\Framework\Phrase('test')) + ), + $sizePlaceholder + ); + $this->imageHelper->expects($this->any())->method('getDefaultPlaceholderUrl')->willReturn($placeholderUrl); + $this->imageHelper->expects($this->any())->method('getPlaceholder'); + $this->assetRepo->expects($this->any())->method('createAsset')->willReturnSelf(); + $this->assetRepo->expects($this->any())->method('getPath'); + $this->jsonEncoderMock->expects($this->once())->method('encode')->willReturnCallback('json_encode'); + + $this->assertSame(json_encode($imagesResult), $this->content->getImagesJson()); + } } From 10b20c03d3c01eae26a76fdfacdd18defec3a98f Mon Sep 17 00:00:00 2001 From: oserediuk Date: Fri, 8 Jul 2016 17:51:55 +0300 Subject: [PATCH 10/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 - (cherry picked from commit 2e03028) --- .../Block/Adminhtml/Product/Helper/Form/Gallery/Content.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 105d3c107ee3f..262ba8cccc27e 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -16,6 +16,7 @@ use Magento\Backend\Block\Media\Uploader; use Magento\Framework\View\Element\AbstractBlock; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\FileSystemException; class Content extends \Magento\Backend\Block\Widget { @@ -145,7 +146,7 @@ public function getImagesJson() try { $fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file'])); $image['size'] = $fileHandler['size']; - } catch (\Magento\Framework\Exception\FileSystemException $e) { + } catch (FileSystemException $e) { $staticDir = $this->_filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW); $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('thumbnail'); $fileHandler = $staticDir->stat( From b179dfd2eb09d605275b52fe8814a4e6adc0ab06 Mon Sep 17 00:00:00 2001 From: Andrii Dimov Date: Thu, 25 Aug 2016 14:51:08 +0300 Subject: [PATCH 11/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 #5497 #5871 - (cherry picked from commit 1ef843d) --- .../Adminhtml/Product/Helper/Form/Gallery/Content.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 262ba8cccc27e..d271c8a59381b 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -147,12 +147,8 @@ public function getImagesJson() $fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file'])); $image['size'] = $fileHandler['size']; } catch (FileSystemException $e) { - $staticDir = $this->_filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW); - $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('thumbnail'); - $fileHandler = $staticDir->stat( - $this->getAssetRepo()->createAsset($this->getImageHelper()->getPlaceholder('thumbnail'))->getPath() - ); - $image['size'] = $fileHandler['size']; + $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('small_image'); + $image['size'] = 0; $this->_logger->warning($e); } } From 9c6c6281e3a9088d4e60fdb2c5bdd818e2fcaaeb Mon Sep 17 00:00:00 2001 From: Andrii Dimov Date: Thu, 25 Aug 2016 18:36:28 +0300 Subject: [PATCH 12/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 #5497 #5871 - (cherry picked from commit 2240a1e) --- .../Product/Helper/Form/Gallery/Content.php | 19 --------- .../Helper/Form/Gallery/ContentTest.php | 41 ++----------------- 2 files changed, 4 insertions(+), 56 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index d271c8a59381b..04cc211018c21 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -40,11 +40,6 @@ class Content extends \Magento\Backend\Block\Widget */ private $imageHelper; - /** - * @var \Magento\Framework\View\Asset\Repository - */ - private $assetRepo; - /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder @@ -257,18 +252,4 @@ private function getImageHelper() } return $this->imageHelper; } - - /** - * @return \Magento\Framework\View\Asset\Repository - * @deprecated - */ - private function getAssetRepo() - { - if ($this->assetRepo === null) { - $this->assetRepo = \Magento\Framework\App\ObjectManager::getInstance() - ->get('\Magento\Framework\View\Asset\Repository'); - } - - return $this->assetRepo; - } } diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php index 33faf5963c910..b5ed35ced5a4b 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php @@ -46,11 +46,6 @@ class ContentTest extends \PHPUnit_Framework_TestCase */ protected $imageHelper; - /** - * @var \Magento\Framework\View\Asset\Repository|\PHPUnit_Framework_MockObject_MockObject - */ - protected $assetRepo; - /** * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ @@ -171,12 +166,7 @@ public function testGetImagesJsonWithException() { $this->imageHelper = $this->getMockBuilder('Magento\Catalog\Helper\Image') ->disableOriginalConstructor() - ->setMethods(['getDefaultPlaceholderUrl', 'getPlaceholder']) - ->getMock(); - - $this->assetRepo = $this->getMockBuilder('Magento\Framework\View\Asset\Repository') - ->disableOriginalConstructor() - ->setMethods(['createAsset', 'getPath']) + ->setMethods(['getDefaultPlaceholderUrl']) ->getMock(); $this->objectManager->setBackwardCompatibleProperty( @@ -185,32 +175,18 @@ public function testGetImagesJsonWithException() $this->imageHelper ); - $this->objectManager->setBackwardCompatibleProperty( - $this->content, - 'assetRepo', - $this->assetRepo - ); - $placeholderUrl = 'url_to_the_placeholder/placeholder.jpg'; $sizePlaceholder = ['size' => 399659]; $imagesResult = [ - [ - 'value_id' => '2', - 'file' => 'file_2.jpg', - 'media_type' => 'image', - 'position' => '0', - 'url' => 'url_to_the_placeholder/placeholder.jpg', - 'size' => 399659 - ], [ 'value_id' => '1', 'file' => 'file_1.jpg', 'media_type' => 'image', 'position' => '1', 'url' => 'url_to_the_placeholder/placeholder.jpg', - 'size' => 399659 + 'size' => 0 ] ]; @@ -221,12 +197,6 @@ public function testGetImagesJsonWithException() 'file' => 'file_1.jpg', 'media_type' => 'image', 'position' => '1' - ], - [ - 'value_id' => '2', - 'file' => 'file_2.jpg', - 'media_type' => 'image', - 'position' => '0' ] ] ]; @@ -238,18 +208,15 @@ public function testGetImagesJsonWithException() $this->mediaConfigMock->expects($this->any())->method('getMediaPath'); $this->readMock->expects($this->any())->method('stat')->willReturnOnConsecutiveCalls( $this->throwException( - new \Magento\Framework\Exception\FileSystemException(new \Magento\Framework\Phrase('test')) + new \Magento\Framework\Exception\FileSystemException(new Phrase('test')) ), $sizePlaceholder, $this->throwException( - new \Magento\Framework\Exception\FileSystemException(new \Magento\Framework\Phrase('test')) + new \Magento\Framework\Exception\FileSystemException(new Phrase('test')) ), $sizePlaceholder ); $this->imageHelper->expects($this->any())->method('getDefaultPlaceholderUrl')->willReturn($placeholderUrl); - $this->imageHelper->expects($this->any())->method('getPlaceholder'); - $this->assetRepo->expects($this->any())->method('createAsset')->willReturnSelf(); - $this->assetRepo->expects($this->any())->method('getPath'); $this->jsonEncoderMock->expects($this->once())->method('encode')->willReturnCallback('json_encode'); $this->assertSame(json_encode($imagesResult), $this->content->getImagesJson()); From 8a0ea4a28f178cc57b728b3641acff4e136f1942 Mon Sep 17 00:00:00 2001 From: Andrii Dimov Date: Fri, 26 Aug 2016 18:52:29 +0300 Subject: [PATCH 13/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 #5497 #5871 - (cherry picked from commit da52cad) --- .../Helper/Form/Gallery/ContentTest.php | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php index b5ed35ced5a4b..357bc2ec6b65a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php @@ -177,9 +177,15 @@ public function testGetImagesJsonWithException() $placeholderUrl = 'url_to_the_placeholder/placeholder.jpg'; - $sizePlaceholder = ['size' => 399659]; - $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', @@ -197,6 +203,12 @@ public function testGetImagesJsonWithException() 'file' => 'file_1.jpg', 'media_type' => 'image', 'position' => '1' + ], + [ + 'value_id' => '2', + 'file' => 'file_2.jpg', + 'media_type' => 'image', + 'position' => '0' ] ] ]; @@ -210,11 +222,9 @@ public function testGetImagesJsonWithException() $this->throwException( new \Magento\Framework\Exception\FileSystemException(new Phrase('test')) ), - $sizePlaceholder, $this->throwException( new \Magento\Framework\Exception\FileSystemException(new Phrase('test')) - ), - $sizePlaceholder + ) ); $this->imageHelper->expects($this->any())->method('getDefaultPlaceholderUrl')->willReturn($placeholderUrl); $this->jsonEncoderMock->expects($this->once())->method('encode')->willReturnCallback('json_encode'); From 7dabb19d5af171bbefd6241a7cb790aaab5d61b4 Mon Sep 17 00:00:00 2001 From: Andrii Dimov Date: Thu, 25 Aug 2016 14:51:08 +0300 Subject: [PATCH 14/19] MAGETWO-55447: Portdown MAGETWO-54718 down to M2.1.x branch - MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 #5497 #5871 - (cherry picked from commit 0bad8ab) --- .../Block/Adminhtml/Product/Helper/Form/Gallery/Content.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php index 04cc211018c21..fa863176952b1 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php @@ -134,7 +134,7 @@ public function getImagesJson() is_array($value['images']) && count($value['images']) ) { - $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); + $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); $images = $this->sortImagesByPosition($value['images']); foreach ($images as &$image) { $image['url'] = $this->_mediaConfig->getMediaUrl($image['file']); From 156c2d84399e824897431cb1ccd7cc4d7cb23054 Mon Sep 17 00:00:00 2001 From: Sergey Shvets Date: Tue, 27 Sep 2016 17:22:42 +0300 Subject: [PATCH 15/19] MAGETWO-56964: [Backport] [GitHub] Validate attribute values #4881 --- .../Adminhtml/Product/Attribute/Validate.php | 54 +++++++- .../Product/Attribute/ValidateTest.php | 128 ++++++++++++++++-- app/code/Magento/Catalog/etc/adminhtml/di.xml | 7 + app/code/Magento/Catalog/i18n/en_US.csv | 1 + .../catalog/product/attribute/options.phtml | 75 +++++++--- .../product/attribute/unique-validate.js | 46 +++++++ .../Magento/Swatches/etc/adminhtml/di.xml | 8 ++ app/code/Magento/Swatches/i18n/en_US.csv | 1 + .../catalog/product/attribute/text.phtml | 71 +++++++--- .../catalog/product/attribute/visual.phtml | 81 +++++++---- 10 files changed, 399 insertions(+), 73 deletions(-) create mode 100644 app/code/Magento/Catalog/view/adminhtml/web/catalog/product/attribute/unique-validate.js diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 991f448b4e497..74a4d73c1495d 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -22,6 +22,11 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute */ protected $layoutFactory; + /** + * @var array + */ + private $multipleAttributeList; + /** * Constructor * @@ -31,6 +36,7 @@ class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Framework\View\LayoutFactory $layoutFactory + * @param array $multipleAttributeList */ public function __construct( \Magento\Backend\App\Action\Context $context, @@ -38,15 +44,19 @@ public function __construct( \Magento\Framework\Registry $coreRegistry, \Magento\Framework\View\Result\PageFactory $resultPageFactory, \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory, - \Magento\Framework\View\LayoutFactory $layoutFactory + \Magento\Framework\View\LayoutFactory $layoutFactory, + array $multipleAttributeList = [] ) { parent::__construct($context, $attributeLabelCache, $coreRegistry, $resultPageFactory); $this->resultJsonFactory = $resultJsonFactory; $this->layoutFactory = $layoutFactory; + $this->multipleAttributeList = $multipleAttributeList; } /** * @return \Magento\Framework\Controller\ResultInterface + * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function execute() { @@ -89,9 +99,37 @@ public function execute() $response->setHtmlMessage($layout->getMessagesBlock()->getGroupedHtml()); } } + + $multipleOption = $this->getRequest()->getParam('frontend_input'); + $multipleOption = null === $multipleOption ? 'select' : $multipleOption; + if (isset($this->multipleAttributeList[$multipleOption]) && null !== $multipleOption) { + $this->checkUniqueOption( + $response, + $this->getRequest()->getParam($this->multipleAttributeList[$multipleOption]) + ); + } + return $this->resultJsonFactory->create()->setJsonData($response->toJson()); } + /** + * Throws Exception if not unique values into options + * @param array $optionsValues + * @param array $deletedOptions + * @return bool + */ + private function isUniqueAdminValues(array $optionsValues, array $deletedOptions) + { + $adminValues = []; + foreach ($optionsValues as $optionKey => $values) { + if (!(isset($deletedOptions[$optionKey]) and $deletedOptions[$optionKey] === '1')) { + $adminValues[] = reset($values); + } + } + $uniqueValues = array_unique($adminValues); + return ($uniqueValues === $adminValues); + } + /** * Set message to response object * @@ -107,4 +145,18 @@ private function setMessageToResponse($response, $messages) } return $response->setData($messageKey, $messages); } + + /** + * @param DataObject $response + * @param array|null $options + * @return $this + */ + private function checkUniqueOption(DataObject $response, array $options = null) + { + if (is_array($options) and !$this->isUniqueAdminValues($options['value'], $options['delete'])) { + $this->setMessageToResponse($response, [__('The value of Admin must be unique.')]); + $response->setError(true); + } + return $this; + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php index 94ba7ee6e487f..3283d641de6b5 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Attribute/ValidateTest.php @@ -6,14 +6,14 @@ namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Attribute; use Magento\Catalog\Controller\Adminhtml\Product\Attribute\Validate; -use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest; -use Magento\Framework\Controller\Result\JsonFactory as ResultJsonFactory; -use Magento\Framework\Controller\Result\Json as ResultJson; -use Magento\Framework\View\LayoutFactory; -use Magento\Framework\ObjectManagerInterface; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; +use Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\AttributeTest; use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet; +use Magento\Framework\Controller\Result\Json as ResultJson; +use Magento\Framework\Controller\Result\JsonFactory as ResultJsonFactory; use Magento\Framework\Escaper; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutFactory; use Magento\Framework\View\LayoutInterface; /** @@ -97,14 +97,18 @@ protected function setUp() */ protected function getModel() { - return $this->objectManager->getObject(Validate::class, [ - 'context' => $this->contextMock, - 'attributeLabelCache' => $this->attributeLabelCacheMock, - 'coreRegistry' => $this->coreRegistryMock, - 'resultPageFactory' => $this->resultPageFactoryMock, - 'resultJsonFactory' => $this->resultJsonFactoryMock, - 'layoutFactory' => $this->layoutFactoryMock, - ]); + return $this->objectManager->getObject( + Validate::class, + [ + 'context' => $this->contextMock, + 'attributeLabelCache' => $this->attributeLabelCacheMock, + 'coreRegistry' => $this->coreRegistryMock, + 'resultPageFactory' => $this->resultPageFactoryMock, + 'resultJsonFactory' => $this->resultJsonFactoryMock, + 'layoutFactory' => $this->layoutFactoryMock, + 'multipleAttributeList' => ['select' => 'option'] + ] + ); } public function testExecute() @@ -119,8 +123,8 @@ public function testExecute() $this->objectManagerMock->expects($this->exactly(2)) ->method('create') ->willReturnMap([ - ['Magento\Catalog\Model\ResourceModel\Eav\Attribute', [], $this->attributeMock], - ['Magento\Eav\Model\Entity\Attribute\Set', [], $this->attributeSetMock] + [\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class, [], $this->attributeMock], + [\Magento\Eav\Model\Entity\Attribute\Set::class, [], $this->attributeSetMock] ]); $this->attributeMock->expects($this->once()) ->method('loadByCode') @@ -147,4 +151,98 @@ public function testExecute() $this->assertInstanceOf(ResultJson::class, $this->getModel()->execute()); } + + /** + * @dataProvider provideUniqueData + * @param array $options + * @param boolean $isError + * @throws \Magento\Framework\Exception\NotFoundException + */ + public function testUniqueValidation(array $options, $isError) + { + $countFunctionCalls = ($isError) ? 6 : 5; + $this->requestMock->expects($this->exactly($countFunctionCalls)) + ->method('getParam') + ->willReturnMap([ + ['frontend_label', null, null], + ['attribute_code', null, 'test_attribute_code'], + ['new_attribute_set_name', null, 'test_attribute_set_name'], + ['option', null, $options], + ['message_key', null, Validate::DEFAULT_MESSAGE_KEY] + ]); + + $this->objectManagerMock->expects($this->once()) + ->method('create') + ->willReturn($this->attributeMock); + + $this->attributeMock->expects($this->once()) + ->method('loadByCode') + ->willReturnSelf(); + + $this->requestMock->expects($this->once()) + ->method('has') + ->with('new_attribute_set_name') + ->willReturn(false); + + $this->resultJsonFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->resultJson); + + $this->resultJson->expects($this->once()) + ->method('setJsonData') + ->willReturnSelf(); + + $this->assertInstanceOf(ResultJson::class, $this->getModel()->execute()); + } + + public function provideUniqueData() + { + return [ + // valid options + [ + [ + 'value' => [ + "option_0" => [1, 0], + "option_1" => [2, 0], + "option_2" => [3, 0], + ], + 'delete' => [ + "option_0" => "", + "option_1" => "", + "option_2" => "", + ] + ], false + ], + //with duplicate + [ + [ + 'value' => [ + "option_0" => [1, 0], + "option_1" => [1, 0], + "option_2" => [3, 0], + ], + 'delete' => [ + "option_0" => "", + "option_1" => "", + "option_2" => "", + ] + ], true + ], + //with duplicate but deleted + [ + [ + 'value' => [ + "option_0" => [1, 0], + "option_1" => [1, 0], + "option_2" => [3, 0], + ], + 'delete' => [ + "option_0" => "", + "option_1" => "1", + "option_2" => "", + ] + ], false + ], + ]; + } } diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml index 0bc836252fb95..584a2e51514db 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/di.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml @@ -47,6 +47,13 @@ + + + + option + + + Magento\Catalog\Model\Product\CopyConstructor\Composite diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index 07b408477e1c5..4ff82a93b2914 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -715,3 +715,4 @@ Disable,Disable none,none Overview,Overview Details,Details +"The value of Admin must be unique.", "The value of Admin must be unique." diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml index 3552d78f8665a..97385c0a68569 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml @@ -11,17 +11,23 @@ $stores = $block->getStoresSortedBySortOrder(); ?>
- + + escapeHtml(__('Manage Options (Values of Your Attribute)'))?> +
- + - getId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> class="_required"> - getName()) ?> + getStoresSortedBySortOrder(); - - @@ -54,23 +64,48 @@ $stores = $block->getStoresSortedBySortOrder(); - + @@ -90,6 +125,10 @@ $stores = $block->getStoresSortedBySortOrder(); "attributesData": , "isSortable": getReadOnly() && !$block->canManageOptionDefaultOnly()) ?>, "isReadOnly": getReadOnly(); ?> + }, + "Magento_Catalog/catalog/product/attribute/unique-validate": { + "element": "required-dropdown-attribute-unique", + "message": "escapeHtml(__('The value of Admin must be unique.')) ?>" } } } diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/attribute/unique-validate.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/attribute/unique-validate.js new file mode 100644 index 0000000000000..c2aa604d11e7a --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product/attribute/unique-validate.js @@ -0,0 +1,46 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery', + 'mage/backend/validation' +], function (jQuery) { + 'use strict'; + + return function (config) { + var _config = jQuery.extend({ + element: null, + message: '', + uniqueClass: 'required-unique' + }, config); + + if (typeof _config.element === 'string') { + jQuery.validator.addMethod( + _config.element, + + function (value, element) { + var inputs = jQuery(element) + .closest('table') + .find('.' + _config.uniqueClass + ':visible'), + valuesHash = {}, + isValid = true; + + inputs.each(function (el) { + var inputValue = inputs[el].value; + + if (typeof valuesHash[inputValue] !== 'undefined') { + isValid = false; + } + valuesHash[inputValue] = el; + }); + + return isValid; + }, + + _config.message + ); + } + }; +}); diff --git a/app/code/Magento/Swatches/etc/adminhtml/di.xml b/app/code/Magento/Swatches/etc/adminhtml/di.xml index fdb12b66e7e6f..e24b4aa534d54 100644 --- a/app/code/Magento/Swatches/etc/adminhtml/di.xml +++ b/app/code/Magento/Swatches/etc/adminhtml/di.xml @@ -27,4 +27,12 @@ + + + + optiontext + optionvisual + + + diff --git a/app/code/Magento/Swatches/i18n/en_US.csv b/app/code/Magento/Swatches/i18n/en_US.csv index d000032ee429a..4ea18ba81355b 100644 --- a/app/code/Magento/Swatches/i18n/en_US.csv +++ b/app/code/Magento/Swatches/i18n/en_US.csv @@ -33,3 +33,4 @@ Image,Image "Image Size","Image Size" "Example format: 200x300.","Example format: 200x300." "Image Position","Image Position" +"The value of Admin must be unique.","The value of Admin must be unique." diff --git a/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/text.phtml b/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/text.phtml index a4a3deee001f6..b00049e26f3d0 100644 --- a/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/text.phtml +++ b/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/text.phtml @@ -11,19 +11,26 @@ $stores = $block->getStoresSortedBySortOrder(); ?>
- + + escapeHtml(__('Manage Swatch (Values of Your Attribute)')) ?> +
+ escapeHtml(__('Is Default')) ?> getId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> + class="_required" + > + escapeHtml(__($_store->getName())) ?>
- + + +
+ getReadOnly() && !$block->canManageOptionDefaultOnly()):?> -
getReadOnly() && !$block->canManageOptionDefaultOnly()): ?> -
+
- getReadOnly() || $block->canManageOptionDefaultOnly()): ?> disabled="disabled"/> + getReadOnly() || $block->canManageOptionDefaultOnly()): ?> + disabled="disabled" + />
- getReadOnly()):?>disabled="disabled"/> + getReadOnly()):?>disabled="disabled"/> getReadOnly() || $block->canManageOptionDefaultOnly()):?> disabled="disabled"/> + getReadOnly() || $block->canManageOptionDefaultOnly()):?> + disabled="disabled" + /> + getReadOnly() && !$block->canManageOptionDefaultOnly()):?> -
- + getId() != \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> - + - getId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> class="_required"> - getName() ?> + @@ -35,14 +42,16 @@ $stores = $block->getStoresSortedBySortOrder(); - @@ -55,30 +64,56 @@ $stores = $block->getStoresSortedBySortOrder(); getId() != \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> @@ -87,7 +122,11 @@ $stores = $block->getStoresSortedBySortOrder(); diff --git a/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/visual.phtml b/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/visual.phtml index dd6f4b26ecf12..1bc09039cc730 100644 --- a/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/visual.phtml +++ b/app/code/Magento/Swatches/view/adminhtml/templates/catalog/product/attribute/visual.phtml @@ -11,17 +11,21 @@ $stores = $block->getStoresSortedBySortOrder(); ?>
- + + escapeHtml(__('Manage Swatch (Values of Your Attribute)')) ?>
escapeHtml(__('Is Default')) ?> + escapeHtml(__('Swatch')); ?> + getId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> + class="_required" + > + escapeHtml($_store->getName()) ?>
+
+ getReadOnly() && !$block->canManageOptionDefaultOnly()):?> -
getReadOnly() && !$block->canManageOptionDefaultOnly()): ?> -
+
- getReadOnly() || $block->canManageOptionDefaultOnly()): ?> disabled="disabled"/> + getReadOnly() || $block->canManageOptionDefaultOnly()): ?> + disabled="disabled" + />
- getReadOnly()):?>disabled="disabled"/> + getReadOnly()):?>disabled="disabled"/> - + - getReadOnly() || $block->canManageOptionDefaultOnly()):?> disabled="disabled"/> + getReadOnly() || $block->canManageOptionDefaultOnly()):?> + disabled="disabled" + /> getReadOnly() && !$block->canManageOptionDefaultOnly()):?> -
- - + + - getId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> class="_required"> - getName() ?> + getStoresSortedBySortOrder(); - @@ -54,47 +61,71 @@ $stores = $block->getStoresSortedBySortOrder(); @@ -103,7 +134,11 @@ $stores = $block->getStoresSortedBySortOrder(); From b91b2a9f81bf61059d34e7ccd59f8ab1a20fdc8f Mon Sep 17 00:00:00 2001 From: Sergey Shvets Date: Wed, 28 Sep 2016 14:01:38 +0300 Subject: [PATCH 16/19] MAGETWO-56964: [Backport] [GitHub] Validate attribute values #4881 fixed CR comments --- .../Controller/Adminhtml/Product/Attribute/Validate.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php index 74a4d73c1495d..bc34bdf9fa9a1 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php @@ -149,14 +149,12 @@ private function setMessageToResponse($response, $messages) /** * @param DataObject $response * @param array|null $options - * @return $this */ private function checkUniqueOption(DataObject $response, array $options = null) { - if (is_array($options) and !$this->isUniqueAdminValues($options['value'], $options['delete'])) { + if (is_array($options) && !$this->isUniqueAdminValues($options['value'], $options['delete'])) { $this->setMessageToResponse($response, [__('The value of Admin must be unique.')]); $response->setError(true); } - return $this; } } From 45a53c10807a5bfdd43ac91a7725f7148cd834db Mon Sep 17 00:00:00 2001 From: Olga Kopylova Date: Wed, 14 Sep 2016 15:05:29 -0500 Subject: [PATCH 17/19] MAGETWO-58090: [Backport] - [Magento Cloud] - Intermittent HTTP ERROR 500 during checkout - for 2.1 --- app/code/Magento/CatalogInventory/Helper/Stock.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Helper/Stock.php b/app/code/Magento/CatalogInventory/Helper/Stock.php index 08995925815a5..ab7314d25c1f1 100644 --- a/app/code/Magento/CatalogInventory/Helper/Stock.php +++ b/app/code/Magento/CatalogInventory/Helper/Stock.php @@ -154,7 +154,10 @@ public function addIsInStockFilterToCollection($collection) \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); $resource = $this->getStockStatusResource(); - $resource->addStockDataToCollection($collection, !$isShowOutOfStock); + $resource->addStockDataToCollection( + $collection, + !$isShowOutOfStock && $collection->getFlag('require_stock_items') + ); $collection->setFlag($stockFlag, true); } } From 9d1495ba5b700371c87e7d4dcf97716e9aa26e25 Mon Sep 17 00:00:00 2001 From: Sergey Shvets Date: Thu, 6 Oct 2016 14:39:19 +0300 Subject: [PATCH 18/19] MAGETWO-59209: [Backport] - [Github] Minicart item count is not updated if switch from https to http #6487 - for 2.1 --- app/code/Magento/Theme/view/frontend/web/js/view/messages.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Theme/view/frontend/web/js/view/messages.js b/app/code/Magento/Theme/view/frontend/web/js/view/messages.js index ef4fe41a3b908..2944cd08406eb 100644 --- a/app/code/Magento/Theme/view/frontend/web/js/view/messages.js +++ b/app/code/Magento/Theme/view/frontend/web/js/view/messages.js @@ -30,10 +30,7 @@ define([ customerData.set('messages', {}); } - $.cookieStorage.setConf({ - path: '/', - expires: -1 - }).set('mage-messages', null); + $.cookieStorage.set('mage-messages', ''); } }); }); From 9f5f72f9047179ad8642993d88d8c1ecc9fba5d8 Mon Sep 17 00:00:00 2001 From: Sergey Shvets Date: Fri, 7 Oct 2016 09:32:54 +0300 Subject: [PATCH 19/19] MAGETWO-59024: [Backport] - Ship To section on Checkout's Review & Payments step, clears out the Ship To address on page reload - for 2.1 --- .../view/frontend/web/js/model/new-customer-address.js | 2 +- .../frontend/web/js/model/shipping-rates-validator.js | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js index ab46c78c6f6e7..3d65fdc6ddfaf 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js @@ -14,7 +14,7 @@ define([], function () { return { email: addressData.email, - countryId: (addressData.country_id) ? addressData.country_id : window.checkoutConfig.defaultCountryId, + countryId: addressData['country_id'] || addressData.countryId || window.checkoutConfig.defaultCountryId, regionId: (addressData.region && addressData.region.region_id) ? addressData.region.region_id : window.checkoutConfig.defaultRegionId, diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js index e002823fef17e..4a4b71f976b99 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js @@ -12,7 +12,8 @@ define( '../action/select-shipping-address', './postcode-validator', 'mage/translate', - 'uiRegistry' + 'uiRegistry', + 'Magento_Checkout/js/model/quote' ], function ( $, @@ -22,7 +23,8 @@ define( selectShippingAddress, postcodeValidator, $t, - uiRegistry + uiRegistry, + quote ) { 'use strict'; @@ -41,7 +43,7 @@ define( * @param {Object} validator */ registerValidator: function (carrier, validator) { - if (checkoutConfig.activeCarriers.indexOf(carrier) != -1) { + if (checkoutConfig.activeCarriers.indexOf(carrier) !== -1) { validators.push(validator); } }, @@ -175,6 +177,7 @@ define( address; if (this.validateAddressData(addressFlat)) { + addressFlat = $.extend(true, {}, quote.shippingAddress(), addressFlat); address = addressConverter.formAddressDataToQuoteAddress(addressFlat); selectShippingAddress(address); }
escapeHtml(__('Is Default')) ?>escapeHtml(__('Swatch')) ?> getId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> + class="_required" + > + escapeHtml($_store->getName()) ?>
+
+ getReadOnly() && !$block->canManageOptionDefaultOnly()):?> -
getReadOnly() && !$block->canManageOptionDefaultOnly()): ?> -
+
+
- getReadOnly() || $block->canManageOptionDefaultOnly()): ?> disabled="disabled"/> + getReadOnly() || $block->canManageOptionDefaultOnly()): ?> + disabled="disabled" + />
- getReadOnly()):?>disabled="disabled"/> + getReadOnly()):?>disabled="disabled"/> - +
-

+

escapeHtml(__('Choose a color')); ?>

-
-

+
+

escapeHtml(__('Upload a file')); ?>

-

+

escapeHtml(__('Clear')); ?>

- getReadOnly() || $block->canManageOptionDefaultOnly()):?> disabled="disabled"/> + getReadOnly() || $block->canManageOptionDefaultOnly()):?> + disabled="disabled" + /> getReadOnly() && !$block->canManageOptionDefaultOnly()):?> -