From eb1fa975475bc450035936cc8ff55150f0a352e3 Mon Sep 17 00:00:00 2001
From: Fabian Schmengler
Date: Thu, 23 Mar 2017 09:59:51 +0000
Subject: [PATCH 001/316] Remove unused attribute
Kept in constructor for backwards compatibility
---
app/code/Magento/SampleData/Model/Dependency.php | 6 ------
1 file changed, 6 deletions(-)
diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php
index 611f69e0babc1..d4f653d39e462 100644
--- a/app/code/Magento/SampleData/Model/Dependency.php
+++ b/app/code/Magento/SampleData/Model/Dependency.php
@@ -26,11 +26,6 @@ class Dependency
*/
protected $composerInformation;
- /**
- * @var Filesystem
- */
- private $filesystem;
-
/**
* @var PackageFactory
*/
@@ -54,7 +49,6 @@ public function __construct(
ComponentRegistrar $componentRegistrar
) {
$this->composerInformation = $composerInformation;
- $this->filesystem = $filesystem;
$this->packageFactory = $packageFactory;
$this->componentRegistrar = $componentRegistrar;
}
From 479a443df80985a5052395fd7ff477f32bef50ca Mon Sep 17 00:00:00 2001
From: Fabian Schmengler
Date: Thu, 23 Mar 2017 10:07:59 +0000
Subject: [PATCH 002/316] Change type hint to interface
---
app/code/Magento/SampleData/Model/Dependency.php | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php
index d4f653d39e462..9c5c89154ee11 100644
--- a/app/code/Magento/SampleData/Model/Dependency.php
+++ b/app/code/Magento/SampleData/Model/Dependency.php
@@ -6,10 +6,11 @@
namespace Magento\SampleData\Model;
use Magento\Framework\Component\ComponentRegistrar;
+use Magento\Framework\Component\ComponentRegistrarInterface;
use Magento\Framework\Composer\ComposerInformation;
-use Magento\Framework\Filesystem;
use Magento\Framework\Config\Composer\Package;
use Magento\Framework\Config\Composer\PackageFactory;
+use Magento\Framework\Filesystem;
/**
* Sample Data dependency
@@ -32,7 +33,7 @@ class Dependency
private $packageFactory;
/**
- * @var ComponentRegistrar
+ * @var ComponentRegistrarInterface
*/
private $componentRegistrar;
@@ -40,13 +41,13 @@ class Dependency
* @param ComposerInformation $composerInformation
* @param Filesystem $filesystem
* @param PackageFactory $packageFactory
- * @param ComponentRegistrar $componentRegistrar
+ * @param ComponentRegistrarInterface $componentRegistrar
*/
public function __construct(
ComposerInformation $composerInformation,
Filesystem $filesystem,
PackageFactory $packageFactory,
- ComponentRegistrar $componentRegistrar
+ ComponentRegistrarInterface $componentRegistrar
) {
$this->composerInformation = $composerInformation;
$this->packageFactory = $packageFactory;
From 9768fc614f070bb7a43713f67f01d13d3013d2f7 Mon Sep 17 00:00:00 2001
From: Fabian Schmengler
Date: Thu, 23 Mar 2017 11:59:24 +0000
Subject: [PATCH 003/316] Add unit test for Magento\SampleData\Model\Dependency
---
.../Magento/SampleData/Model/Dependency.php | 29 +++-
.../Test/Unit/Model/DependencyTest.php | 147 ++++++++++++++++++
2 files changed, 168 insertions(+), 8 deletions(-)
create mode 100644 app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php
index 9c5c89154ee11..dc6277acdbb93 100644
--- a/app/code/Magento/SampleData/Model/Dependency.php
+++ b/app/code/Magento/SampleData/Model/Dependency.php
@@ -5,6 +5,7 @@
*/
namespace Magento\SampleData\Model;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Component\ComponentRegistrar;
use Magento\Framework\Component\ComponentRegistrarInterface;
use Magento\Framework\Composer\ComposerInformation;
@@ -37,6 +38,11 @@ class Dependency
*/
private $componentRegistrar;
+ /**
+ * @var Filesystem\Directory\ReadInterfaceFactory
+ */
+ private $directoryReadFactory;
+
/**
* @param ComposerInformation $composerInformation
* @param Filesystem $filesystem
@@ -47,11 +53,16 @@ public function __construct(
ComposerInformation $composerInformation,
Filesystem $filesystem,
PackageFactory $packageFactory,
- ComponentRegistrarInterface $componentRegistrar
+ ComponentRegistrarInterface $componentRegistrar,
+ \Magento\Framework\Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory = null
) {
$this->composerInformation = $composerInformation;
$this->packageFactory = $packageFactory;
$this->componentRegistrar = $componentRegistrar;
+ if ($directoryReadFactory === null) {
+ $directoryReadFactory = ObjectManager::getInstance()->get(Filesystem\Directory\ReadInterfaceFactory::class);
+ }
+ $this->directoryReadFactory = $directoryReadFactory;
}
/**
@@ -81,14 +92,15 @@ protected function getSuggestsFromModules()
{
$suggests = [];
foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- $file = $moduleDir . '/composer.json';
-
- if (!file_exists($file) || !is_readable($file)) {
+ /** @var Filesystem\Directory\ReadInterface $directory */
+ $directory = $this->directoryReadFactory->create(['path' => $moduleDir]);
+ echo "path=$moduleDir\n";
+ if (!$directory->isExist('composer.json') || !$directory->isReadable('composer.json')) {
continue;
}
/** @var Package $package */
- $package = $this->getModuleComposerPackage($file);
+ $package = $this->getModuleComposerPackage($directory);
$suggest = json_decode(json_encode($package->get('suggest')), true);
if (!empty($suggest)) {
$suggests += $suggest;
@@ -100,11 +112,12 @@ protected function getSuggestsFromModules()
/**
* Load package
*
- * @param string $file
+ * @param Filesystem\Directory\ReadInterface $directory
* @return Package
+ * @throws \Magento\Framework\Exception\FileSystemException
*/
- protected function getModuleComposerPackage($file)
+ protected function getModuleComposerPackage(Filesystem\Directory\ReadInterface $directory)
{
- return $this->packageFactory->create(['json' => json_decode(file_get_contents($file))]);
+ return $this->packageFactory->create(['json' => json_decode($directory->readFile('composer.json'))]);
}
}
diff --git a/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
new file mode 100644
index 0000000000000..75c69a598580d
--- /dev/null
+++ b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
@@ -0,0 +1,147 @@
+getMockBuilder(ComposerInformation::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $composerInformation->method('getSuggestedPackages')
+ ->willReturn($suggestionsFromLockFile);
+
+ /** @var Filesystem|\PHPUnit_Framework_MockObject_MockObject $filesystem */
+ $filesystem = $this->getMockBuilder(Filesystem::class)->disableOriginalConstructor()->getMock();
+
+ /** @var PackageFactory|\PHPUnit_Framework_MockObject_MockObject $packageFactory */
+ $packageFactory = $this->getMockBuilder(PackageFactory::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['create'])
+ ->getMock();
+ $packageFactory->method('create')
+ ->willReturnCallback(function($args) {
+ return new Package($args['json']);
+ });
+
+ /** @var ComponentRegistrarInterface|\PHPUnit_Framework_MockObject_MockObject $componentRegistrar */
+ $componentRegistrar = $this->getMockBuilder(ComponentRegistrarInterface::class)
+ ->getMockForAbstractClass();
+ $componentRegistrar->method('getPaths')
+ ->with(ComponentRegistrar::MODULE)
+ ->willReturn(
+ $moduleDirectories
+ );
+
+ $directoryReadFactory = $this->getMockBuilder(Filesystem\Directory\ReadInterfaceFactory::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['create'])
+ ->getMock();
+ $directoryReadFactory->method('create')
+ ->willReturnMap($composerJsonGenerator($this));
+
+ $dependency = new Dependency(
+ $composerInformation,
+ $filesystem,
+ $packageFactory,
+ $componentRegistrar,
+ $directoryReadFactory
+ );
+ $this->assertEquals($expectedPackages, $dependency->getSampleDataPackages());
+ }
+ public static function dataPackagesFromComposerSuggest()
+ {
+ return [
+ [
+ 'moduleDirectories' => [
+ 'app/code/LocalModule',
+ 'app/code/LocalModuleWithoutComposerJson',
+ 'vendor/company/module',
+ ],
+ 'composerJsonGenerator' => function(DependencyTest $test) {
+ return [
+ [
+ ['path' => 'app/code/LocalModule'],
+ $test->stubComposerJsonReader(
+ ['name' => 'local/module', 'suggest' => ['local/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '0.1.0']]
+ )
+ ],
+ [
+ ['path' => 'app/code/LocalModuleWithoutComposerJson'],
+ $test->stubFileNotFoundReader()
+ ],
+ [
+ ['path' => 'vendor/company/module'],
+ $test->stubComposerJsonReader(
+ ['name' => 'company/module', 'suggest' => ['company/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.0.0-beta']]
+ )
+ ],
+ ];
+ },
+ 'suggestions' => [
+ 'magento/foo-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '100.0.0',
+ 'thirdparty/bar-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.2.3',
+ 'thirdparty/something-else' => 'Just a suggested package',
+ ],
+ 'expectedPackages' => [
+ 'magento/foo-sample-data' => '100.0.0',
+ 'thirdparty/bar-sample-data' => '1.2.3',
+ 'local/module-sample-data' => '0.1.0',
+ 'company/module-sample-data' => '1.0.0-beta',
+ ]
+ ]
+ ];
+ }
+
+ public function stubComposerJsonReader(array $composerJsonContent)
+ {
+ $stub = $this->getMockBuilder(Filesystem\Directory\ReadInterface::class)
+ ->getMockForAbstractClass();
+ $stub->method('isExist')
+ ->with('composer.json')
+ ->willReturn(true);
+ $stub->method('isReadable')
+ ->with('composer.json')
+ ->willReturn(true);
+ $stub->method('readFile')
+ ->with('composer.json')
+ ->willReturn(json_encode($composerJsonContent));
+ return $stub;
+ }
+
+ public function stubFileNotFoundReader()
+ {
+ $stub = $this->getMockBuilder(Filesystem\Directory\ReadInterface::class)
+ ->getMockForAbstractClass();
+ $stub->method('isExist')
+ ->with('composer.json')
+ ->willReturn(false);
+ $stub->method('readFile')
+ ->with('composer.json')
+ ->willThrowException(new FileSystemException(new Phrase('File not found')));
+ return $stub;
+ }
+}
+
From 29bc089e79ac40c822611b195b6008601eecde6a Mon Sep 17 00:00:00 2001
From: Fabian Schmengler
Date: Thu, 23 Mar 2017 12:27:12 +0000
Subject: [PATCH 004/316] Look for composer.json in parent of registered module
directory for sample data suggestions
This allows modules to follow the pds/skeleton standard and have their source code in a 'src' subdirectory of the repository
---
.../Magento/SampleData/Model/Dependency.php | 36 ++++++++++++-------
.../Test/Unit/Model/DependencyTest.php | 24 +++++++++++++
2 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php
index dc6277acdbb93..7d665ed7e5a2e 100644
--- a/app/code/Magento/SampleData/Model/Dependency.php
+++ b/app/code/Magento/SampleData/Model/Dependency.php
@@ -48,13 +48,15 @@ class Dependency
* @param Filesystem $filesystem
* @param PackageFactory $packageFactory
* @param ComponentRegistrarInterface $componentRegistrar
+ * @param Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory
+ * @throws \RuntimeException
*/
public function __construct(
ComposerInformation $composerInformation,
Filesystem $filesystem,
PackageFactory $packageFactory,
ComponentRegistrarInterface $componentRegistrar,
- \Magento\Framework\Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory = null
+ Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory = null
) {
$this->composerInformation = $composerInformation;
$this->packageFactory = $packageFactory;
@@ -69,6 +71,7 @@ public function __construct(
* Retrieve list of sample data packages from suggests
*
* @return array
+ * @throws \Magento\Framework\Exception\FileSystemException
*/
public function getSampleDataPackages()
{
@@ -87,20 +90,13 @@ public function getSampleDataPackages()
* Retrieve suggested sample data packages from modules composer.json
*
* @return array
+ * @throws \Magento\Framework\Exception\FileSystemException
*/
protected function getSuggestsFromModules()
{
$suggests = [];
foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) {
- /** @var Filesystem\Directory\ReadInterface $directory */
- $directory = $this->directoryReadFactory->create(['path' => $moduleDir]);
- echo "path=$moduleDir\n";
- if (!$directory->isExist('composer.json') || !$directory->isReadable('composer.json')) {
- continue;
- }
-
- /** @var Package $package */
- $package = $this->getModuleComposerPackage($directory);
+ $package = $this->getModuleComposerPackage($moduleDir);
$suggest = json_decode(json_encode($package->get('suggest')), true);
if (!empty($suggest)) {
$suggests += $suggest;
@@ -112,12 +108,26 @@ protected function getSuggestsFromModules()
/**
* Load package
*
- * @param Filesystem\Directory\ReadInterface $directory
+ * @param string $moduleDir
* @return Package
* @throws \Magento\Framework\Exception\FileSystemException
*/
- protected function getModuleComposerPackage(Filesystem\Directory\ReadInterface $directory)
+ private function getModuleComposerPackage($moduleDir): Package
{
- return $this->packageFactory->create(['json' => json_decode($directory->readFile('composer.json'))]);
+ /*
+ * Also look in parent directory of registered module directory to allow modules to follow the pds/skeleton
+ * standard and have their source code in a "src" subdirectory of the repository
+ *
+ * see: https://github.com/php-pds/skeleton
+ */
+ foreach ([$moduleDir, $moduleDir . DIRECTORY_SEPARATOR . '..'] as $dir) {
+ /** @var Filesystem\Directory\ReadInterface $directory */
+ $directory = $this->directoryReadFactory->create(['path' => $dir]);
+ if ($directory->isExist('composer.json') && $directory->isReadable('composer.json')) {
+ /** @var Package $package */
+ return $this->packageFactory->create(['json' => json_decode($directory->readFile('composer.json'))]);
+ }
+ }
+ return $this->packageFactory->create(['json' => new \stdClass]);
}
}
diff --git a/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
index 75c69a598580d..b32118f6b864c 100644
--- a/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
+++ b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
@@ -79,6 +79,7 @@ public static function dataPackagesFromComposerSuggest()
'app/code/LocalModule',
'app/code/LocalModuleWithoutComposerJson',
'vendor/company/module',
+ 'vendor/company2/module/src'
],
'composerJsonGenerator' => function(DependencyTest $test) {
return [
@@ -98,6 +99,28 @@ public static function dataPackagesFromComposerSuggest()
['name' => 'company/module', 'suggest' => ['company/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.0.0-beta']]
)
],
+ [
+ ['path' => 'vendor/company2/module/src/..'],
+ $test->stubComposerJsonReader(
+ ['name' => 'company2/module', 'suggest' => ['company2/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.10']]
+ )
+ ],
+ [
+ ['path' => 'vendor/company2/module/src'],
+ $test->stubFileNotFoundReader()
+ ],
+ [
+ ['path' => 'vendor/company/module/..'],
+ $test->stubFileNotFoundReader()
+ ],
+ [
+ ['path' => 'app/code/LocalModuleWithoutComposerJson/..'],
+ $test->stubFileNotFoundReader()
+ ],
+ [
+ ['path' => 'app/code/LocalModule/..'],
+ $test->stubFileNotFoundReader()
+ ],
];
},
'suggestions' => [
@@ -110,6 +133,7 @@ public static function dataPackagesFromComposerSuggest()
'thirdparty/bar-sample-data' => '1.2.3',
'local/module-sample-data' => '0.1.0',
'company/module-sample-data' => '1.0.0-beta',
+ 'company2/module-sample-data' => '1.10',
]
]
];
From e45250ab4458db0165e09a3990d492e5239cc4a4 Mon Sep 17 00:00:00 2001
From: Fabian Schmengler
Date: Thu, 23 Mar 2017 13:31:09 +0000
Subject: [PATCH 005/316] Fix code style issues
---
.../Magento/SampleData/Model/Dependency.php | 3 ++
.../Test/Unit/Model/DependencyTest.php | 34 ++++++++++++++-----
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php
index 7d665ed7e5a2e..bf9a8f501be94 100644
--- a/app/code/Magento/SampleData/Model/Dependency.php
+++ b/app/code/Magento/SampleData/Model/Dependency.php
@@ -53,9 +53,12 @@ class Dependency
*/
public function __construct(
ComposerInformation $composerInformation,
+ // $filesystem kept for BC
+ // @codingStandardsIgnoreLine
Filesystem $filesystem,
PackageFactory $packageFactory,
ComponentRegistrarInterface $componentRegistrar,
+ // $directoryReadFactory optional for BC
Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory = null
) {
$this->composerInformation = $composerInformation;
diff --git a/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
index b32118f6b864c..3be13af6ae91b 100644
--- a/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
+++ b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php
@@ -24,8 +24,12 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
* @param string[] $suggestionsFromLockFile
* @param string[] $expectedPackages
*/
- public function testPackagesFromComposerSuggest($moduleDirectories, callable $composerJsonGenerator, $suggestionsFromLockFile, $expectedPackages)
- {
+ public function testPackagesFromComposerSuggest(
+ array $moduleDirectories,
+ callable $composerJsonGenerator,
+ array $suggestionsFromLockFile,
+ array $expectedPackages
+ ) {
/** @var ComposerInformation|\PHPUnit_Framework_MockObject_MockObject $composerInformation */
$composerInformation = $this->getMockBuilder(ComposerInformation::class)
->disableOriginalConstructor()
@@ -42,7 +46,7 @@ public function testPackagesFromComposerSuggest($moduleDirectories, callable $co
->setMethods(['create'])
->getMock();
$packageFactory->method('create')
- ->willReturnCallback(function($args) {
+ ->willReturnCallback(function ($args) {
return new Package($args['json']);
});
@@ -81,12 +85,17 @@ public static function dataPackagesFromComposerSuggest()
'vendor/company/module',
'vendor/company2/module/src'
],
- 'composerJsonGenerator' => function(DependencyTest $test) {
+ 'composerJsonGenerator' => function (DependencyTest $test) {
return [
[
['path' => 'app/code/LocalModule'],
$test->stubComposerJsonReader(
- ['name' => 'local/module', 'suggest' => ['local/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '0.1.0']]
+ [
+ 'name' => 'local/module',
+ 'suggest' => [
+ 'local/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '0.1.0'
+ ]
+ ]
)
],
[
@@ -96,13 +105,23 @@ public static function dataPackagesFromComposerSuggest()
[
['path' => 'vendor/company/module'],
$test->stubComposerJsonReader(
- ['name' => 'company/module', 'suggest' => ['company/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.0.0-beta']]
+ [
+ 'name' => 'company/module',
+ 'suggest' => [
+ 'company/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.0.0-beta'
+ ]
+ ]
)
],
[
['path' => 'vendor/company2/module/src/..'],
$test->stubComposerJsonReader(
- ['name' => 'company2/module', 'suggest' => ['company2/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.10']]
+ [
+ 'name' => 'company2/module',
+ 'suggest' => [
+ 'company2/module-sample-data' => Dependency::SAMPLE_DATA_SUGGEST . '1.10'
+ ]
+ ]
)
],
[
@@ -168,4 +187,3 @@ public function stubFileNotFoundReader()
return $stub;
}
}
-
From 4355d78e7f98aa0b03067c88c1a3aedabb652edb Mon Sep 17 00:00:00 2001
From: Fabian Schmengler
Date: Thu, 23 Mar 2017 13:55:30 +0000
Subject: [PATCH 006/316] Add missing DI preference for
Filesystem\Directory\ReadInterface
---
app/code/Magento/SampleData/etc/di.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/code/Magento/SampleData/etc/di.xml b/app/code/Magento/SampleData/etc/di.xml
index cfc9a280bb80e..aedd2d31f58dc 100644
--- a/app/code/Magento/SampleData/etc/di.xml
+++ b/app/code/Magento/SampleData/etc/di.xml
@@ -15,4 +15,5 @@
+
From 3319ea0f58ef4014d4d2c89457e521a785c80c47 Mon Sep 17 00:00:00 2001
From: Fabian Schmengler
Date: Thu, 23 Mar 2017 17:24:47 +0000
Subject: [PATCH 007/316] Keep it PHP 5.6 compatible for now
---
app/code/Magento/SampleData/Model/Dependency.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php
index bf9a8f501be94..03e1999d72898 100644
--- a/app/code/Magento/SampleData/Model/Dependency.php
+++ b/app/code/Magento/SampleData/Model/Dependency.php
@@ -51,16 +51,17 @@ class Dependency
* @param Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory
* @throws \RuntimeException
*/
+ // @codingStandardsIgnoreStart
public function __construct(
ComposerInformation $composerInformation,
// $filesystem kept for BC
- // @codingStandardsIgnoreLine
Filesystem $filesystem,
PackageFactory $packageFactory,
ComponentRegistrarInterface $componentRegistrar,
// $directoryReadFactory optional for BC
Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory = null
) {
+ // @codingStandardsIgnoreEnd
$this->composerInformation = $composerInformation;
$this->packageFactory = $packageFactory;
$this->componentRegistrar = $componentRegistrar;
@@ -115,7 +116,7 @@ protected function getSuggestsFromModules()
* @return Package
* @throws \Magento\Framework\Exception\FileSystemException
*/
- private function getModuleComposerPackage($moduleDir): Package
+ private function getModuleComposerPackage($moduleDir)
{
/*
* Also look in parent directory of registered module directory to allow modules to follow the pds/skeleton
From 9efec7e00b7d041297a8650f971bdce1f90b4ae8 Mon Sep 17 00:00:00 2001
From: olysenko
Date: Wed, 19 Apr 2017 17:24:05 +0300
Subject: [PATCH 008/316] MAGETWO-57995: [GITHUB] Simple product videos display
the thumbnail image rather than the embedded video player. #6360
---
.../Block/Plugin/Product/Media/Gallery.php | 80 +++++++++++++++
.../Plugin/Product/Media/GalleryTest.php | 99 +++++++++++++++++++
.../Magento/ConfigurableProduct/etc/di.xml | 3 +
3 files changed, 182 insertions(+)
create mode 100644 app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
create mode 100644 app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php
diff --git a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
new file mode 100644
index 0000000000000..1ea04f5ef99fc
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
@@ -0,0 +1,80 @@
+json = $json;
+ parent::__construct($context, $arrayUtils, $data);
+ }
+
+ /**
+ * @param \Magento\Catalog\Block\Product\View\Gallery $subject
+ * @param string $result
+ * @return string
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function afterGetOptionsMediaGalleryDataJson(
+ \Magento\Catalog\Block\Product\View\Gallery $subject,
+ $result
+ ) {
+ $result = $this->json->unserialize($result);
+ if ($this->getProduct()->getTypeId() == 'configurable') {
+ /** @var Configurable $productType */
+ $productType = $this->getProduct()->getTypeInstance();
+ $products = $productType->getUsedProducts($this->getProduct());
+ /** @var Product $product */
+ foreach ($products as $product) {
+ $key = $product->getId();
+ $result[$key] = $this->getProductGallery($product);
+ }
+ }
+ return $this->json->serialize($result);
+ }
+
+ /**
+ * @param Product $product
+ * @return array
+ */
+ private function getProductGallery($product)
+ {
+ $result = [];
+ $images = $product->getMediaGalleryImages();
+ foreach ($images as $image) {
+ $result[] = [
+ 'mediaType' => $image->getMediaType(),
+ 'videoUrl' => $image->getVideoUrl(),
+ 'isBase' => $product->getImage() == $image->getFile(),
+ ];
+ }
+ return $result;
+ }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php
new file mode 100644
index 0000000000000..f2f497996ed6b
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php
@@ -0,0 +1,99 @@
+json = $this->getMockBuilder(Json::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $productMock = $this->getMockBuilder(Product::class)
+ ->setMethods(['getTypeId', 'getTypeInstance'])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $variationProduct = $this->getMockBuilder(Product::class)
+ ->setMethods(['setMediaGalleryEntries', 'getId', 'getMediaGalleryImages', 'getImage'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $image = new \Magento\Framework\DataObject(
+ ['media_type' => 'type', 'video_url' => 'url', 'file' => 'image.jpg']
+ );
+ $variationProduct->expects($this->any())->method('setMediaGalleryEntries')->willReturn([]);
+ $variationProduct->expects($this->any())->method('getId')->willReturn($this->variationProductId);
+ $variationProduct->expects($this->any())->method('getMediaGalleryImages')->willReturn([$image]);
+ $variationProduct->expects($this->any())->method('getImage')->willReturn('image.jpg');
+
+ $configurableType = $this->getMockBuilder(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getUsedProducts'])
+ ->getMock();
+ $configurableType->expects($this->any())->method('getUsedProducts')->with($productMock)
+ ->willReturn([$variationProduct]);
+
+ $productMock->expects($this->any())->method('getTypeId')->willReturn('configurable');
+ $productMock->expects($this->any())->method('getTypeInstance')->willReturn($configurableType);
+
+ $this->plugin = $helper->getObject(
+ Gallery::class,
+ [
+ 'json' => $this->json
+ ]
+ );
+ $this->plugin->setData('product', $productMock);
+ }
+
+ public function testAfterGetOptions()
+ {
+ $resultJson = '[]';
+ $this->json->expects($this->once())->method('unserialize')->with('[]')->willReturn([]);
+ $expected = [
+ $this->variationProductId => [
+ [
+ 'mediaType' => 'type',
+ 'videoUrl' => 'url',
+ 'isBase' => true
+ ]
+ ]
+ ];
+ $this->json->expects($this->any())->method('serialize')->with($expected)
+ ->willReturn(json_encode($expected));
+
+ $blockMock = $this->getMockBuilder(\Magento\ProductVideo\Block\Product\View\Gallery::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $result = $this->plugin->afterGetOptionsMediaGalleryDataJson($blockMock, $resultJson);
+ $this->assertEquals(json_encode($expected), $result);
+ }
+}
diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml
index 496d85310e817..cbfb7e24dfcca 100644
--- a/app/code/Magento/ConfigurableProduct/etc/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/di.xml
@@ -147,6 +147,9 @@
+
+
+ Magento\Framework\App\Cache\Type\Collection
From 1543c70ccd42c3ab097d5b826eb34752d00e3dfb Mon Sep 17 00:00:00 2001
From: olysenko
Date: Thu, 20 Apr 2017 11:54:11 +0300
Subject: [PATCH 009/316] MAGETWO-57995: [GITHUB] Simple product videos display
the thumbnail image rather than the embedded video player. #6360
---
.../Block/Plugin/Product/Media/Gallery.php | 20 +--
.../Plugin/Product/Media/GalleryTest.php | 127 +++++++++---------
2 files changed, 71 insertions(+), 76 deletions(-)
diff --git a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
index 1ea04f5ef99fc..8f712d3a1d8d9 100644
--- a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
+++ b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
@@ -12,7 +12,7 @@
/**
* Class Gallery
*/
-class Gallery extends \Magento\Catalog\Block\Product\View\AbstractView
+class Gallery
{
/**
* @var Json
@@ -20,37 +20,29 @@ class Gallery extends \Magento\Catalog\Block\Product\View\AbstractView
private $json;
/**
- * @param \Magento\Catalog\Block\Product\Context $context
- * @param \Magento\Framework\Stdlib\ArrayUtils $arrayUtils
* @param Json $json
- * @param array $data
*/
public function __construct(
- \Magento\Catalog\Block\Product\Context $context,
- \Magento\Framework\Stdlib\ArrayUtils $arrayUtils,
- Json $json,
- array $data = []
+ Json $json
) {
$this->json = $json;
- parent::__construct($context, $arrayUtils, $data);
}
/**
* @param \Magento\Catalog\Block\Product\View\Gallery $subject
* @param string $result
* @return string
- *
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterGetOptionsMediaGalleryDataJson(
\Magento\Catalog\Block\Product\View\Gallery $subject,
$result
) {
$result = $this->json->unserialize($result);
- if ($this->getProduct()->getTypeId() == 'configurable') {
+ $parentProduct = $subject->getProduct();
+ if ($parentProduct->getTypeId() == Configurable::TYPE_CODE) {
/** @var Configurable $productType */
- $productType = $this->getProduct()->getTypeInstance();
- $products = $productType->getUsedProducts($this->getProduct());
+ $productType = $parentProduct->getTypeInstance();
+ $products = $productType->getUsedProducts($parentProduct);
/** @var Product $product */
foreach ($products as $product) {
$key = $product->getId();
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php
index f2f497996ed6b..34e4925c7bc9b 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Block/Plugin/Product/Media/GalleryTest.php
@@ -14,86 +14,89 @@
*/
class GalleryTest extends \PHPUnit_Framework_TestCase
{
- /**
- * @var Gallery
- */
- private $plugin;
-
- /**
- * @var Json|\PHPUnit_Framework_MockObject_MockObject
- */
- private $json;
-
- /**
- * @var int
- */
- private $variationProductId = 1;
- protected function setUp()
+ public function testAfterGetOptions()
{
- $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-
- $this->json = $this->getMockBuilder(Json::class)
- ->disableOriginalConstructor()
- ->getMock();
-
- $productMock = $this->getMockBuilder(Product::class)
- ->setMethods(['getTypeId', 'getTypeInstance'])
- ->disableOriginalConstructor()
- ->getMock();
+ $jsonMock = $this->createJsonMock();
+ $productMock = $this->createProductMock();
+ $galleryMock = $this->createGalleryMock();
+ $variationProductMock = $this->createProductMock();
+ $configurableTypeMock = $this->createConfigurableTypeMock();
- $variationProduct = $this->getMockBuilder(Product::class)
- ->setMethods(['setMediaGalleryEntries', 'getId', 'getMediaGalleryImages', 'getImage'])
- ->disableOriginalConstructor()
- ->getMock();
+ $resultJson = '[]';
+ $variationProductId = 1;
+ $expectedGalleryJson = [
+ $variationProductId => [
+ [
+ 'mediaType' => 'type',
+ 'videoUrl' => 'url',
+ 'isBase' => true
+ ]
+ ]
+ ];
$image = new \Magento\Framework\DataObject(
['media_type' => 'type', 'video_url' => 'url', 'file' => 'image.jpg']
);
- $variationProduct->expects($this->any())->method('setMediaGalleryEntries')->willReturn([]);
- $variationProduct->expects($this->any())->method('getId')->willReturn($this->variationProductId);
- $variationProduct->expects($this->any())->method('getMediaGalleryImages')->willReturn([$image]);
- $variationProduct->expects($this->any())->method('getImage')->willReturn('image.jpg');
- $configurableType = $this->getMockBuilder(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class)
- ->disableOriginalConstructor()
- ->setMethods(['getUsedProducts'])
- ->getMock();
- $configurableType->expects($this->any())->method('getUsedProducts')->with($productMock)
- ->willReturn([$variationProduct]);
-
- $productMock->expects($this->any())->method('getTypeId')->willReturn('configurable');
- $productMock->expects($this->any())->method('getTypeInstance')->willReturn($configurableType);
+ $galleryMock->expects(($this->any()))->method('getProduct')->willReturn($productMock);
+ $productMock->expects($this->once())->method('getTypeId')->willReturn('configurable');
+ $productMock->expects($this->once())->method('getTypeInstance')->willReturn($configurableTypeMock);
+ $configurableTypeMock->expects($this->once())->method('getUsedProducts')->with($productMock)
+ ->willReturn([$variationProductMock]);
+ $variationProductMock->expects($this->once())->method('getId')->willReturn($variationProductId);
+ $variationProductMock->expects($this->once())->method('getMediaGalleryImages')->willReturn([$image]);
+ $variationProductMock->expects($this->once())->method('getImage')->willReturn('image.jpg');
+ $jsonMock->expects($this->once())->method('serialize')->with($expectedGalleryJson)
+ ->willReturn(json_encode($expectedGalleryJson));
- $this->plugin = $helper->getObject(
+ $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $plugin = $helper->getObject(
Gallery::class,
[
- 'json' => $this->json
+ 'json' => $jsonMock
]
);
- $this->plugin->setData('product', $productMock);
+ $result = $plugin->afterGetOptionsMediaGalleryDataJson($galleryMock, $resultJson);
+ $this->assertEquals(json_encode($expectedGalleryJson), $result);
}
- public function testAfterGetOptions()
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
+ private function createJsonMock()
{
- $resultJson = '[]';
- $this->json->expects($this->once())->method('unserialize')->with('[]')->willReturn([]);
- $expected = [
- $this->variationProductId => [
- [
- 'mediaType' => 'type',
- 'videoUrl' => 'url',
- 'isBase' => true
- ]
- ]
- ];
- $this->json->expects($this->any())->method('serialize')->with($expected)
- ->willReturn(json_encode($expected));
+ return $this->getMockBuilder(Json::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
+ private function createProductMock()
+ {
+ return $this->getMockBuilder(Product::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
- $blockMock = $this->getMockBuilder(\Magento\ProductVideo\Block\Product\View\Gallery::class)
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
+ private function createGalleryMock()
+ {
+ return $this->getMockBuilder(\Magento\Catalog\Block\Product\View\Gallery::class)
->disableOriginalConstructor()
->getMock();
+ }
- $result = $this->plugin->afterGetOptionsMediaGalleryDataJson($blockMock, $resultJson);
- $this->assertEquals(json_encode($expected), $result);
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject
+ */
+ private function createConfigurableTypeMock()
+ {
+ return $this->getMockBuilder(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class)
+ ->disableOriginalConstructor()
+ ->getMock();
}
}
From 8a22ae9328a9e262c61acf31c659ffc3f409bce8 Mon Sep 17 00:00:00 2001
From: olysenko
Date: Fri, 21 Apr 2017 12:20:04 +0300
Subject: [PATCH 010/316] MAGETWO-57995: [GITHUB] Simple product videos display
the thumbnail image rather than the embedded video player. #6360
---
.../ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
index 8f712d3a1d8d9..1df68482eb6b8 100644
--- a/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
+++ b/app/code/Magento/ConfigurableProduct/Block/Plugin/Product/Media/Gallery.php
@@ -10,7 +10,7 @@
use Magento\Framework\Serialize\Serializer\Json;
/**
- * Class Gallery
+ * Provides a serialized media gallery data for configurable product options.
*/
class Gallery
{
From f7449dfcec46acd9843f50152d2710b29101cc08 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Wed, 3 May 2017 11:03:59 -0500
Subject: [PATCH 011/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- returning saved url on replace method so we can output what hasn't been saved
---
.../Model/Category/Plugin/Storage.php | 7 ++--
...ProductProcessUrlRewriteSavingObserver.php | 9 ++++-
.../Magento/CatalogUrlRewrite/etc/events.xml | 3 ++
.../Model/Storage/AbstractStorage.php | 14 +++-----
.../UrlRewrite/Model/Storage/DbStorage.php | 36 +++++++++++++++----
.../UrlRewrite/Model/UrlPersistInterface.php | 2 +-
6 files changed, 50 insertions(+), 21 deletions(-)
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php
index fc31d96f85234..745977f9190a5 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php
@@ -33,15 +33,15 @@ public function __construct(
/**
* @param \Magento\UrlRewrite\Model\StorageInterface $object
- * @param null $result
+ * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $result
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
- * @return void
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterReplace(StorageInterface $object, $result, array $urls)
{
$toSave = [];
- foreach ($this->filterUrls($urls) as $record) {
+ foreach ($this->filterUrls($result) as $record) {
$metadata = $record->getMetadata();
$toSave[] = [
'url_rewrite_id' => $record->getUrlRewriteId(),
@@ -52,6 +52,7 @@ public function afterReplace(StorageInterface $object, $result, array $urls)
if ($toSave) {
$this->productResource->saveMultiple($toSave);
}
+ return $result;
}
/**
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
index ad0220ea30ef3..018e3c3e59340 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
@@ -58,7 +58,14 @@ public function execute(\Magento\Framework\Event\Observer $observer)
]);
if ($product->isVisibleInSiteVisibility()) {
- $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
+ $generatedUrls = $this->productUrlRewriteGenerator->generate($product);
+ $product->setData(
+ 'unsaved_urls',
+ array_diff_key(
+ $generatedUrls,
+ $this->urlPersist->replace($generatedUrls)
+ )
+ );
}
}
}
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/events.xml
index cc558fe81f16d..bf543173538cd 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/events.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/events.xml
@@ -33,4 +33,7 @@
+
+
+
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index 6296f0acbfe83..c9c06ec514815 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -76,24 +76,18 @@ abstract protected function doFindOneByData($data);
public function replace(array $urls)
{
if (!$urls) {
- return;
+ return [];
}
- try {
- $this->doReplace($urls);
- } catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
- throw new \Magento\Framework\Exception\AlreadyExistsException(
- __('URL key for specified store already exists.')
- );
- }
+ return $this->doReplace($urls);
}
/**
* Save new url rewrites and remove old if exist. Template method
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
- * @return int
- * @throws \Magento\Framework\Exception\AlreadyExistsException
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
+ * @throws \Magento\Framework\Exception\AlreadyExistsException|\Exception
*/
abstract protected function doReplace($urls);
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index 3093e10e63091..3e8185a7665f4 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -20,7 +20,7 @@ class DbStorage extends AbstractStorage
/**
* Code of "Integrity constraint violation: 1062 Duplicate entry" error
*/
- const ERROR_CODE_DUPLICATE_ENTRY = 23000;
+ const ERROR_CODE_DUPLICATE_ENTRY = 1062;
/**
* @var \Magento\Framework\DB\Adapter\AdapterInterface
@@ -90,11 +90,12 @@ protected function doReplace($urls)
$urlData[UrlRewrite::ENTITY_TYPE] = $type;
$this->deleteByData($urlData);
}
- $data = [];
- foreach ($urls as $url) {
- $data[] = $url->toArray();
+ foreach ($urls as $key => $url) {
+ if (!$this->insert($url->toArray())) {
+ unset($urls[$key]);
+ }
}
- $this->insertMultiple($data);
+ return $urls;
}
/**
@@ -104,13 +105,14 @@ protected function doReplace($urls)
* @return void
* @throws \Magento\Framework\Exception\AlreadyExistsException
* @throws \Exception
+ * @deprecated
*/
protected function insertMultiple($data)
{
try {
$this->connection->insertMultiple($this->resource->getTableName(self::TABLE_NAME), $data);
} catch (\Exception $e) {
- if ($e->getCode() === self::ERROR_CODE_DUPLICATE_ENTRY
+ if (($e->getCode() === self::ERROR_CODE_DUPLICATE_ENTRY)
&& preg_match('#SQLSTATE\[23000\]: [^:]+: 1062[^\d]#', $e->getMessage())
) {
throw new \Magento\Framework\Exception\AlreadyExistsException(
@@ -121,6 +123,28 @@ protected function insertMultiple($data)
}
}
+ /**
+ * Insert multiple
+ *
+ * @param array $data
+ * @return bool
+ * @throws \Exception
+ */
+ private function insert($data)
+ {
+ try {
+ return $this->connection->insert($this->resource->getTableName(self::TABLE_NAME), $data) > 0;
+ } catch (\Exception $e) {
+ if ($e->getCode() === self::ERROR_CODE_DUPLICATE_ENTRY
+ && preg_match('#SQLSTATE\[23000\]: [^:]+: 1062[^\d]#', $e->getMessage())
+ ) {
+ return false;
+ } else {
+ throw $e;
+ }
+ }
+ }
+
/**
* Get filter for url rows deletion due to provided urls
*
diff --git a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
index d1ec01b5a2d9f..44443fb8ce56d 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
@@ -15,7 +15,7 @@ interface UrlPersistInterface
* Save new url rewrites and remove old if exist
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
- * @return void
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
public function replace(array $urls);
From d3b1de3c53057080dd918d57f6a986c539c0623c Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Wed, 3 May 2017 14:15:19 -0500
Subject: [PATCH 012/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- adding observer for notice on controller
---
...uplicateUrlControllerAfterSaveObserver.php | 62 +++++++++++++++++++
1 file changed, 62 insertions(+)
create mode 100644 app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
new file mode 100644
index 0000000000000..3653cc9d2b057
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
@@ -0,0 +1,62 @@
+messageManager = $messageManager;
+ $this->escaper = $escaper;
+ }
+
+ /**
+ * Add url collisions notices
+ *
+ * @param \Magento\Framework\Event\Observer $observer
+ * @return void
+ */
+ public function execute(\Magento\Framework\Event\Observer $observer)
+ {
+ /** @var \Magento\Catalog\Model\Product $product */
+ $product = $observer->getEvent()->getProduct();
+ if ($product->getData('unsaved_urls')) {
+ $urls = '';
+ foreach ($product->getData('unsaved_urls') as $url) {
+ /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite $url */
+ $urls .= $url->getRequestPath() . ', ';
+ }
+ $urls = rtrim($urls, ', ');
+ $this->messageManager->addNoticeMessage(
+ __(
+ 'The following urls have not been saved for product %1: %2',
+ $this->escaper->escapeHtml($product->getName()),
+ $this->escaper->escapeHtml($urls)
+ )
+ );
+ }
+ }
+}
From 4d10e7cd37ecd347933b433c6b3316e31621d975 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Wed, 3 May 2017 17:31:56 -0500
Subject: [PATCH 013/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- fixing returns
---
app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php | 4 ++--
app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index c9c06ec514815..607acb16cadf5 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -86,8 +86,8 @@ public function replace(array $urls)
* Save new url rewrites and remove old if exist. Template method
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
- * @throws \Magento\Framework\Exception\AlreadyExistsException|\Exception
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+ * @throws \Exception
*/
abstract protected function doReplace($urls);
diff --git a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
index 44443fb8ce56d..590eb2debffd5 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
@@ -15,7 +15,7 @@ interface UrlPersistInterface
* Save new url rewrites and remove old if exist
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
public function replace(array $urls);
From d9a0475d8203f875e86318bb8e483689e5317551 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Wed, 3 May 2017 22:06:23 -0500
Subject: [PATCH 014/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- adding logging, removing throwing exception
---
...uplicateUrlControllerAfterSaveObserver.php | 5 ++-
.../Model/Storage/AbstractStorage.php | 1 -
.../UrlRewrite/Model/Storage/DbStorage.php | 32 ++++++++++++++++---
.../UrlRewrite/Model/UrlPersistInterface.php | 1 -
4 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
index 3653cc9d2b057..34d7c9d13a11f 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
@@ -50,10 +50,9 @@ public function execute(\Magento\Framework\Event\Observer $observer)
$urls .= $url->getRequestPath() . ', ';
}
$urls = rtrim($urls, ', ');
- $this->messageManager->addNoticeMessage(
+ $this->messageManager->addWarningMessage(
__(
- 'The following urls have not been saved for product %1: %2',
- $this->escaper->escapeHtml($product->getName()),
+ 'The following URL keys for specified store already exists %1',
$this->escaper->escapeHtml($urls)
)
);
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index 607acb16cadf5..3de311505f08d 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -87,7 +87,6 @@ public function replace(array $urls)
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
- * @throws \Exception
*/
abstract protected function doReplace($urls);
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index 3e8185a7665f4..a594739082c24 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -9,6 +9,7 @@
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
use Magento\Framework\Api\DataObjectHelper;
+use Psr\Log\LoggerInterface;
class DbStorage extends AbstractStorage
{
@@ -32,18 +33,27 @@ class DbStorage extends AbstractStorage
*/
protected $resource;
+ /**
+ * @var \Psr\Log\LoggerInterface
+ */
+ private $logger;
+
/**
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory $urlRewriteFactory
* @param DataObjectHelper $dataObjectHelper
* @param \Magento\Framework\App\ResourceConnection $resource
+ * @param \Psr\Log\LoggerInterface|null $logger
*/
public function __construct(
UrlRewriteFactory $urlRewriteFactory,
DataObjectHelper $dataObjectHelper,
- ResourceConnection $resource
+ ResourceConnection $resource,
+ LoggerInterface $logger = null
) {
$this->connection = $resource->getConnection();
$this->resource = $resource;
+ $this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()
+ ->get(\Psr\Log\LoggerInterface::class);
parent::__construct($urlRewriteFactory, $dataObjectHelper);
}
@@ -128,21 +138,33 @@ protected function insertMultiple($data)
*
* @param array $data
* @return bool
- * @throws \Exception
*/
private function insert($data)
{
try {
return $this->connection->insert($this->resource->getTableName(self::TABLE_NAME), $data) > 0;
} catch (\Exception $e) {
- if ($e->getCode() === self::ERROR_CODE_DUPLICATE_ENTRY
+ if (isset($data['request_path'])
+ && isset($data['entity_type'])
+ && isset($data['store_id'])
+ && isset($data['entity_id'])
+ && $e->getCode() === self::ERROR_CODE_DUPLICATE_ENTRY
&& preg_match('#SQLSTATE\[23000\]: [^:]+: 1062[^\d]#', $e->getMessage())
) {
- return false;
+ $this->logger->warning(
+ __(
+ 'Could not insert a duplicate URL when trying to insert %1 for %3 on store %2, entity id %4.',
+ $data['request_path'],
+ $data['entity_type'],
+ $data['store_id'],
+ $data['entity_id']
+ )
+ );
} else {
- throw $e;
+ $this->logger->warning($e->getMessage());
}
}
+ return false;
}
/**
diff --git a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
index 590eb2debffd5..371a683351eea 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
@@ -16,7 +16,6 @@ interface UrlPersistInterface
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
- * @throws \Magento\Framework\Exception\AlreadyExistsException
*/
public function replace(array $urls);
From 756101e69d5a61ea2479b3943ec82fded4301592 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Thu, 4 May 2017 10:44:53 -0500
Subject: [PATCH 015/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- adding registry instead of setting data to product
---
...uplicateUrlControllerAfterSaveObserver.php | 22 +++++++++++-----
...ProductProcessUrlRewriteSavingObserver.php | 26 ++++++++++++-------
.../UrlRewrite/Model/Storage/DbStorage.php | 4 +--
3 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
index 34d7c9d13a11f..d4cfd14c9e81e 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
@@ -8,6 +8,7 @@
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Escaper;
+use Magento\CatalogUrlRewrite\Model\UrlDuplicatesRegistry;
class DuplicateUrlControllerAfterSaveObserver implements ObserverInterface
{
@@ -21,38 +22,45 @@ class DuplicateUrlControllerAfterSaveObserver implements ObserverInterface
*/
private $escaper;
+ /**
+ * @var UrlDuplicatesRegistry
+ */
+ private $urlDuplicatesRegistry;
+
/**
* @param ManagerInterface $messageManager
* @param Escaper $escaper
+ * @param UrlDuplicatesRegistry $urlDuplicatesRegistry
*/
public function __construct(
ManagerInterface $messageManager,
- Escaper $escaper
+ Escaper $escaper,
+ UrlDuplicatesRegistry $urlDuplicatesRegistry
) {
$this->messageManager = $messageManager;
$this->escaper = $escaper;
+ $this->urlDuplicatesRegistry = $urlDuplicatesRegistry;
}
/**
- * Add url collisions notices
+ * Add url rewrite duplicates warnings
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
- /** @var \Magento\Catalog\Model\Product $product */
- $product = $observer->getEvent()->getProduct();
- if ($product->getData('unsaved_urls')) {
+ if (!empty($this->urlDuplicatesRegistry->getUrlDuplicates())) {
$urls = '';
- foreach ($product->getData('unsaved_urls') as $url) {
+ foreach ($this->urlDuplicatesRegistry->getUrlDuplicates() as $url) {
/** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite $url */
$urls .= $url->getRequestPath() . ', ';
}
$urls = rtrim($urls, ', ');
$this->messageManager->addWarningMessage(
__(
- 'The following URL keys for specified store already exists %1',
+ 'Could not save the following URL keys for specified store because they already exist: %1',
$this->escaper->escapeHtml($urls)
)
);
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
index 018e3c3e59340..005153bab030c 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
@@ -10,29 +10,38 @@
use Magento\UrlRewrite\Model\UrlPersistInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
use Magento\Framework\Event\ObserverInterface;
+use Magento\CatalogUrlRewrite\Model\UrlDuplicatesRegistry;
class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
{
/**
* @var ProductUrlRewriteGenerator
*/
- protected $productUrlRewriteGenerator;
+ private $productUrlRewriteGenerator;
/**
* @var UrlPersistInterface
*/
- protected $urlPersist;
+ private $urlPersist;
+
+ /**
+ * @var UrlDuplicatesRegistry
+ */
+ private $urlDuplicatesRegistry;
/**
* @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
* @param UrlPersistInterface $urlPersist
+ * @param UrlDuplicatesRegistry $urlDuplicatesRegistry
*/
public function __construct(
ProductUrlRewriteGenerator $productUrlRewriteGenerator,
- UrlPersistInterface $urlPersist
+ UrlPersistInterface $urlPersist,
+ UrlDuplicatesRegistry $urlDuplicatesRegistry
) {
$this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
$this->urlPersist = $urlPersist;
+ $this->urlDuplicatesRegistry = $urlDuplicatesRegistry;
}
/**
@@ -59,13 +68,12 @@ public function execute(\Magento\Framework\Event\Observer $observer)
if ($product->isVisibleInSiteVisibility()) {
$generatedUrls = $this->productUrlRewriteGenerator->generate($product);
- $product->setData(
- 'unsaved_urls',
- array_diff_key(
- $generatedUrls,
- $this->urlPersist->replace($generatedUrls)
- )
+ $unsavedUrlsDuplicates = array_diff_key(
+ $generatedUrls,
+ $this->urlPersist->replace($generatedUrls)
);
+ // Set the duplicates to registry so it can be processed by the presentation layer
+ $this->urlDuplicatesRegistry->setUrlDuplicates($unsavedUrlsDuplicates);
}
}
}
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index a594739082c24..297bd9f150bc5 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -134,12 +134,12 @@ protected function insertMultiple($data)
}
/**
- * Insert multiple
+ * Inserts a url as array to database
*
* @param array $data
* @return bool
*/
- private function insert($data)
+ private function insert(array $data)
{
try {
return $this->connection->insert($this->resource->getTableName(self::TABLE_NAME), $data) > 0;
From e98c5f66fa743e0bc5544a6df16ddb63b4ac83c2 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Thu, 4 May 2017 10:47:46 -0500
Subject: [PATCH 016/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- adding registry instead of setting data to product
---
.../Model/UrlDuplicatesRegistry.php | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 app/code/Magento/CatalogUrlRewrite/Model/UrlDuplicatesRegistry.php
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/UrlDuplicatesRegistry.php b/app/code/Magento/CatalogUrlRewrite/Model/UrlDuplicatesRegistry.php
new file mode 100644
index 0000000000000..330e0b737dec1
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/UrlDuplicatesRegistry.php
@@ -0,0 +1,46 @@
+urlDuplicates)) {
+ $this->urlDuplicates = $urlDuplicates;
+ } else {
+ throw new \Magento\Framework\Exception\RuntimeException(__('Url rewrites duplicates can only be set once'));
+ }
+ }
+
+ /**
+ * Returns the stored url rewrites duplicates
+ *
+ * @return array|\Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+ */
+ public function getUrlDuplicates()
+ {
+ return $this->urlDuplicates;
+ }
+}
From 84aa1cd705b68320769d9cd6fef50d6c48ad2f4f Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Thu, 4 May 2017 12:46:14 -0500
Subject: [PATCH 017/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- moving registry to url rewrites
---
...uplicateUrlControllerAfterSaveObserver.php | 6 +++--
...ProductProcessUrlRewriteSavingObserver.php | 11 +++------
.../Model/Storage/AbstractStorage.php | 23 +++++++++++++++++--
.../Model/UrlDuplicatesRegistry.php | 14 +++++++++--
4 files changed, 40 insertions(+), 14 deletions(-)
rename app/code/Magento/{CatalogUrlRewrite => UrlRewrite}/Model/UrlDuplicatesRegistry.php (79%)
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
index d4cfd14c9e81e..ca464d129b29d 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
@@ -8,7 +8,7 @@
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Escaper;
-use Magento\CatalogUrlRewrite\Model\UrlDuplicatesRegistry;
+use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
class DuplicateUrlControllerAfterSaveObserver implements ObserverInterface
{
@@ -60,7 +60,9 @@ public function execute(\Magento\Framework\Event\Observer $observer)
$urls = rtrim($urls, ', ');
$this->messageManager->addWarningMessage(
__(
- 'Could not save the following URL keys for specified store because they already exist: %1',
+ 'There is a conflict between the product\'s URL keys and other URLs.'
+ . 'The product can\'t be accessed in the frontend in the specified store, through this URL: %1'
+ . 'To fix the conflict, under Search Engine Optimization, edit the URL key to make it unique.',
$this->escaper->escapeHtml($urls)
)
);
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
index 005153bab030c..364559b9086b2 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
@@ -10,7 +10,7 @@
use Magento\UrlRewrite\Model\UrlPersistInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
use Magento\Framework\Event\ObserverInterface;
-use Magento\CatalogUrlRewrite\Model\UrlDuplicatesRegistry;
+use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
{
@@ -67,13 +67,8 @@ public function execute(\Magento\Framework\Event\Observer $observer)
]);
if ($product->isVisibleInSiteVisibility()) {
- $generatedUrls = $this->productUrlRewriteGenerator->generate($product);
- $unsavedUrlsDuplicates = array_diff_key(
- $generatedUrls,
- $this->urlPersist->replace($generatedUrls)
- );
- // Set the duplicates to registry so it can be processed by the presentation layer
- $this->urlDuplicatesRegistry->setUrlDuplicates($unsavedUrlsDuplicates);
+ $this->urlDuplicatesRegistry->clearUrlDuplicates();
+ $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
}
}
}
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index 3de311505f08d..0b6ad0677002e 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -8,6 +8,7 @@
use Magento\UrlRewrite\Model\StorageInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
use Magento\Framework\Api\DataObjectHelper;
+use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
/**
* Abstract db storage
@@ -20,14 +21,25 @@ abstract class AbstractStorage implements StorageInterface
/** @var DataObjectHelper */
protected $dataObjectHelper;
+ /**
+ * @var UrlDuplicatesRegistry
+ */
+ private $urlDuplicatesRegistry;
+
/**
* @param UrlRewriteFactory $urlRewriteFactory
* @param DataObjectHelper $dataObjectHelper
+ * @param UrlDuplicatesRegistry $urlDuplicatesRegistry
*/
- public function __construct(UrlRewriteFactory $urlRewriteFactory, DataObjectHelper $dataObjectHelper)
- {
+ public function __construct(
+ UrlRewriteFactory $urlRewriteFactory,
+ DataObjectHelper $dataObjectHelper,
+ UrlDuplicatesRegistry $urlDuplicatesRegistry = null
+ ) {
$this->urlRewriteFactory = $urlRewriteFactory;
$this->dataObjectHelper = $dataObjectHelper;
+ $this->urlDuplicatesRegistry = $urlDuplicatesRegistry ?: \Magento\Framework\App\ObjectManager::getInstance()
+ ->get(UrlDuplicatesRegistry::class);
}
/**
@@ -79,6 +91,13 @@ public function replace(array $urls)
return [];
}
+ $savedUrls = $this->doReplace($urls);
+ $unsavedUrlsDuplicates = array_diff_key(
+ $urls,
+ $savedUrls
+ );
+ // Set the duplicates to registry so it can be processed by the presentation layer
+ $this->urlDuplicatesRegistry->setUrlDuplicates($unsavedUrlsDuplicates);
return $this->doReplace($urls);
}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/UrlDuplicatesRegistry.php b/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
similarity index 79%
rename from app/code/Magento/CatalogUrlRewrite/Model/UrlDuplicatesRegistry.php
rename to app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
index 330e0b737dec1..939c57401bafa 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/UrlDuplicatesRegistry.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
@@ -1,10 +1,10 @@
urlDuplicates = [];
+ }
+
/**
* Set the url rewrites duplicates that resulted from a saving process
*
From 6f73f13318160726ae057bc08bb3df6f34c232c3 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Thu, 4 May 2017 13:55:43 -0500
Subject: [PATCH 018/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- adding complex warning
---
...uplicateUrlControllerAfterSaveObserver.php | 10 +++----
.../CatalogUrlRewrite/etc/adminhtml/di.xml | 12 +++++++++
.../etc/adminhtml/events.xml | 3 +++
.../Magento/CatalogUrlRewrite/etc/events.xml | 3 ---
.../addProductUrlDuplicateMessage.phtml | 27 +++++++++++++++++++
5 files changed, 45 insertions(+), 10 deletions(-)
create mode 100644 app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
index ca464d129b29d..bb90cffa7f9bc 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
@@ -58,13 +58,9 @@ public function execute(\Magento\Framework\Event\Observer $observer)
$urls .= $url->getRequestPath() . ', ';
}
$urls = rtrim($urls, ', ');
- $this->messageManager->addWarningMessage(
- __(
- 'There is a conflict between the product\'s URL keys and other URLs.'
- . 'The product can\'t be accessed in the frontend in the specified store, through this URL: %1'
- . 'To fix the conflict, under Search Engine Optimization, edit the URL key to make it unique.',
- $this->escaper->escapeHtml($urls)
- )
+ $this->messageManager->addComplexWarningMessage(
+ 'addProductUrlDuplicateMessage',
+ ['urls' => $this->escaper->escapeHtml($urls)]
);
}
}
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
index 32ecc97d0f85f..0b363956ba9d7 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
@@ -35,4 +35,16 @@
+
+
+
+
+ \Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE
+
+ Magento_CatalogUrlRewrite::messages/addProductUrlDuplicateMessage.phtml
+
+
+
+
+
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
index 9c4a8aaf41231..79c4ae1ec1073 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
@@ -9,4 +9,7 @@
+
+
+
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/events.xml
index bf543173538cd..cc558fe81f16d 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/events.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/events.xml
@@ -33,7 +33,4 @@
-
-
-
diff --git a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
new file mode 100644
index 0000000000000..816ebd29af8b0
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
@@ -0,0 +1,27 @@
+
+
+
+ escapeHtml(__('There is a conflict between the product\'s URL keys and other URLs keys.')); ?>
+
+
+
+ escapeHtml(
+ __('The product can\'t be accessed in the frontend in the specified store, through this URL key:')
+ ); ?>
+
+ getData('urls');?>
+
+
+
+ escapeHtml(
+ __('To fix the conflict, under Search Engine Optimization section, edit the URL key to make it unique.')
+ );
+ ?>
+
\ No newline at end of file
From 968a2b67ba95ef2505457fbe1790a778d1e9a2bc Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Thu, 4 May 2017 14:41:50 -0500
Subject: [PATCH 019/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- styles change
---
.../messages/addProductUrlDuplicateMessage.phtml | 11 ++++-------
.../Magento/UrlRewrite/Model/Storage/DbStorage.php | 4 ++--
.../backend/web/css/source/components/_messages.less | 3 +--
3 files changed, 7 insertions(+), 11 deletions(-)
diff --git a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
index 816ebd29af8b0..bae5d00f596a7 100644
--- a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
+++ b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
@@ -6,11 +6,9 @@
/** @var \Magento\Framework\View\Element\Template $block */
?>
-
-
+
escapeHtml(__('There is a conflict between the product\'s URL keys and other URLs keys.')); ?>
-
-
+
escapeHtml(
__('The product can\'t be accessed in the frontend in the specified store, through this URL key:')
@@ -18,10 +16,9 @@
getData('urls');?>
-
-
+
escapeHtml(
- __('To fix the conflict, under Search Engine Optimization section, edit the URL key to make it unique.')
+ __('To fix the conflict, under the Search Engine Optimization section, edit the URL key to make it unique.')
);
?>
\ No newline at end of file
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index 297bd9f150bc5..a73671ea322cf 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -153,7 +153,7 @@ private function insert(array $data)
) {
$this->logger->warning(
__(
- 'Could not insert a duplicate URL when trying to insert %1 for %3 on store %2, entity id %4.',
+ 'Could not insert a duplicate URL when trying to insert %1 for %2 on store %3, entity id %4.',
$data['request_path'],
$data['entity_type'],
$data['store_id'],
@@ -161,7 +161,7 @@ private function insert(array $data)
)
);
} else {
- $this->logger->warning($e->getMessage());
+ $this->logger->error($e->getMessage());
}
}
return false;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less
index cbf1e28661173..6564b22e4f0ea 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less
@@ -73,11 +73,10 @@
height: auto;
left: 1.9rem;
line-height: inherit;
- margin-top: -1.3rem;
position: absolute;
speak: none;
text-shadow: none;
- top: 50%;
+ top: 1.5rem;
width: auto;
}
}
From edc0c999fdb4f985a0fce7098065d8ca7333f93f Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Thu, 4 May 2017 15:00:10 -0500
Subject: [PATCH 020/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- text change
---
.../templates/messages/addProductUrlDuplicateMessage.phtml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
index bae5d00f596a7..6e96f9c894aac 100644
--- a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
+++ b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addProductUrlDuplicateMessage.phtml
@@ -7,18 +7,18 @@
/** @var \Magento\Framework\View\Element\Template $block */
?>
- escapeHtml(__('There is a conflict between the product\'s URL keys and other URLs keys.')); ?>
+ escapeHtml(__('A conflict has occurred between the product\'s URL and other URL.')); ?>
escapeHtml(
- __('The product can\'t be accessed in the frontend in the specified store, through this URL key:')
+ __('As a result, you cannot access this product through the specified URL:')
); ?>
getData('urls');?>
escapeHtml(
- __('To fix the conflict, under the Search Engine Optimization section, edit the URL key to make it unique.')
+ __('To fix the conflict, navigate to Search Engine Optimization section, then edit the URL key to make it unique.')
);
?>
- escapeHtml(__('A conflict has occurred between the product\'s URL and other URL.')); ?>
-
-
- escapeHtml(
- __('As a result, you cannot access this product through the specified URL:')
- ); ?>
-
- getData('urls');?>
-
-
- escapeHtml(
- __('To fix the conflict, navigate to Search Engine Optimization section, then edit the URL key to make it unique.')
- );
- ?>
-
\ No newline at end of file
diff --git a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml
new file mode 100644
index 0000000000000..1ca315275fccb
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml
@@ -0,0 +1,51 @@
+getData('entity_type');
+?>
+
+ escapeHtml(__('A conflict has occurred between the product\'s URL(s) and other URL(s).'));
+ } else {
+ echo $block->escapeHtml(__('A conflict has occurred between the category\'s URL(s) and other URL(s).'));
+ }
+ ?>
+
+
+ escapeHtml(
+ __('As a result, you cannot access this product through the specified URL(s): ')
+ );
+ } else {
+ echo $block->escapeHtml(
+ __('As a result, you cannot access this category through the specified URL(s): ')
+ );
+ }
+ $urls = explode(', ', $block->getData('urls'));
+ if (!empty($urls)) {
+ if (count($urls) > 1) {
+ echo " ";
+ }
+ $count = 1;
+ foreach ($urls as $url) {
+ echo "" . $block->escapeHtml($url) . "";
+ if ($count <= count($urls)) {
+ echo " ";
+ }
+ $count++;
+ }
+ }
+ echo $block->escapeHtml(
+ __(
+ 'To fix the conflict, navigate to Search Engine Optimization section, '
+ . 'then edit the URL key to make it unique.'
+ )
+ );
+ ?>
+
\ No newline at end of file
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
index 46ebd40d59b11..1f4afb89ba663 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
@@ -107,6 +107,12 @@ public function execute()
try {
$this->pageRepository->save($model);
$this->messageManager->addSuccess(__('You saved the page.'));
+
+ $this->_eventManager->dispatch(
+ 'controller_action_cms_page_save_entity_after',
+ ['controller' => $this, 'page' => $model]
+ );
+
$this->dataPersistor->clear('cms_page');
if ($this->getRequest()->getParam('back')) {
return $resultRedirect->setPath('*/*/edit', ['page_id' => $model->getId(), '_current' => true]);
diff --git a/app/code/Magento/Cms/etc/adminhtml/di.xml b/app/code/Magento/Cms/etc/adminhtml/di.xml
index 8a1a4b24258d7..c0dcd2024cfbd 100644
--- a/app/code/Magento/Cms/etc/adminhtml/di.xml
+++ b/app/code/Magento/Cms/etc/adminhtml/di.xml
@@ -12,4 +12,16 @@
Magento\Framework\Url
+
+
+
+
+ \Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE
+
+ Magento_Cms::messages/addUrlDuplicateWarningMessage.phtml
+
+
+
+
+
diff --git a/app/code/Magento/Cms/etc/adminhtml/events.xml b/app/code/Magento/Cms/etc/adminhtml/events.xml
new file mode 100644
index 0000000000000..a4eca5b2f86f0
--- /dev/null
+++ b/app/code/Magento/Cms/etc/adminhtml/events.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index 0b6ad0677002e..edaebde861503 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -97,7 +97,7 @@ public function replace(array $urls)
$savedUrls
);
// Set the duplicates to registry so it can be processed by the presentation layer
- $this->urlDuplicatesRegistry->setUrlDuplicates($unsavedUrlsDuplicates);
+ $this->urlDuplicatesRegistry->addUrlDuplicates($unsavedUrlsDuplicates);
return $this->doReplace($urls);
}
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index a73671ea322cf..80cc58c6bef65 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -153,11 +153,12 @@ private function insert(array $data)
) {
$this->logger->warning(
__(
- 'Could not insert a duplicate URL when trying to insert %1 for %2 on store %3, entity id %4.',
+ 'Could not insert a conflicting URL when trying to insert \'%1\' for %2 '
+ .'with entity id %3 on store %4',
$data['request_path'],
$data['entity_type'],
- $data['store_id'],
- $data['entity_id']
+ $data['entity_id'],
+ $data['store_id']
)
);
} else {
diff --git a/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php b/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
index 939c57401bafa..b48cfdf66cd40 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
@@ -35,12 +35,10 @@ public function clearUrlDuplicates()
* @return void
* @throws \Magento\Framework\Exception\RuntimeException
*/
- public function setUrlDuplicates(array $urlDuplicates)
+ public function addUrlDuplicates(array $urlDuplicates)
{
if (empty($this->urlDuplicates)) {
- $this->urlDuplicates = $urlDuplicates;
- } else {
- throw new \Magento\Framework\Exception\RuntimeException(__('Url rewrites duplicates can only be set once'));
+ $this->urlDuplicates = array_merge($this->urlDuplicates, $urlDuplicates);
}
}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less
index da8158e045ab6..97ed1d8cdb1ec 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/pages/_login.less
@@ -84,7 +84,7 @@
}
.messages {
- margin-top: -1rem;
+ margin-top: 0.5rem;
+ form .admin__legend {
display: none;
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less
index 6564b22e4f0ea..de24bf89620d4 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less
@@ -76,7 +76,7 @@
position: absolute;
speak: none;
text-shadow: none;
- top: 1.5rem;
+ top: 1.3rem;
width: auto;
}
}
@@ -110,7 +110,7 @@
content: @alert-icon__error__content;
font-size: @alert-icon__error__font-size;
left: 2.2rem;
- margin-top: -1rem;
+ margin-top: 0.5rem;
}
}
From d25dfb36bec92a2d0204268ccbfeb60260173bed Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Wed, 10 May 2017 17:48:42 -0500
Subject: [PATCH 022/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- throwing exception for category
---
.../Controller/Adminhtml/Category/Move.php | 4 ----
.../Controller/Adminhtml/Category/Save.php | 4 ----
...CategoryProcessUrlRewriteMovingObserver.php | 18 ++++++++++++++++--
...CategoryProcessUrlRewriteSavingObserver.php | 18 ++++++++++++++++++
...DuplicateUrlControllerAfterSaveObserver.php | 1 +
.../CatalogUrlRewrite/etc/adminhtml/events.xml | 6 ------
.../UrlRewrite/Model/UrlDuplicatesRegistry.php | 1 -
7 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
index b38e51fb9075e..704054dc22e5b 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
@@ -67,10 +67,6 @@ public function execute()
throw new \Exception(__('Category is not available for requested store.'));
}
$category->move($parentNodeId, $prevNodeId);
- $this->_eventManager->dispatch(
- 'controller_action_catalog_category_move_after',
- ['controller' => $this, 'category' => $category]
- );
} catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
$error = true;
$this->messageManager->addError(__('There was a category move error. %1', $e->getMessage()));
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
index 9bfab59273835..a296126f73df7 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
@@ -212,10 +212,6 @@ public function execute()
$category->save();
$this->messageManager->addSuccess(__('You saved the category.'));
- $this->_eventManager->dispatch(
- 'controller_action_catalog_category_save_entity_after',
- ['controller' => $this, 'category' => $category]
- );
} catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
var_dump($e->getMessage());
$this->messageManager->addError($e->getMessage());
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
index 76c2e1a85a8da..f8f10a54a4f8c 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
@@ -14,6 +14,7 @@
use Magento\UrlRewrite\Model\UrlPersistInterface;
use Magento\Framework\Event\ObserverInterface;
use Magento\CatalogUrlRewrite\Model\Map\DatabaseMapPool;
+use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
{
@@ -40,6 +41,9 @@ class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
/** @var string[] */
private $dataUrlRewriteClassNames;
+ /** @var UrlDuplicatesRegistry */
+ private $urlDuplicatesRegistry;
+
/**
* @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
* @param UrlPersistInterface $urlPersist
@@ -47,6 +51,7 @@ class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
* @param UrlRewriteHandler $urlRewriteHandler
* @param UrlRewriteBunchReplacer $urlRewriteBunchReplacer
* @param DatabaseMapPool $databaseMapPool
+ * @param UrlDuplicatesRegistry $urlDuplicatesRegistry,
* @param string[] $dataUrlRewriteClassNames
*/
public function __construct(
@@ -56,6 +61,7 @@ public function __construct(
UrlRewriteHandler $urlRewriteHandler,
UrlRewriteBunchReplacer $urlRewriteBunchReplacer,
DatabaseMapPool $databaseMapPool,
+ UrlDuplicatesRegistry $urlDuplicatesRegistry,
$dataUrlRewriteClassNames = [
DataCategoryUrlRewriteDatabaseMap::class,
DataProductUrlRewriteDatabaseMap::class
@@ -85,11 +91,19 @@ public function execute(\Magento\Framework\Event\Observer $observer)
$category->getStoreId()
);
$category->setData('save_rewrites_history', $saveRewritesHistory);
+ $this->urlDuplicatesRegistry->clearUrlDuplicates();
$categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category, true);
$this->urlRewriteHandler->deleteCategoryRewritesForChildren($category);
$this->urlRewriteBunchReplacer->doBunchReplace($categoryUrlRewriteResult);
-
-
+ if (!empty($this->urlDuplicatesRegistry->getUrlDuplicates())) {
+ throw new \Magento\Framework\Exception\AlreadyExistsException(
+ __(
+ 'URL key %1 for specified store already exists.',
+ current($this->urlDuplicatesRegistry->getUrlDuplicates())
+ )
+ );
+ }
+ $this->urlDuplicatesRegistry->clearUrlDuplicates();
$productUrlRewriteResult = $this->urlRewriteHandler->generateProductUrlRewrites($category);
$this->urlRewriteBunchReplacer->doBunchReplace($productUrlRewriteResult);
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
index eff2e529ce557..aed080a23131d 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
@@ -12,6 +12,7 @@
use Magento\CatalogUrlRewrite\Model\Map\DataProductUrlRewriteDatabaseMap;
use Magento\CatalogUrlRewrite\Model\UrlRewriteBunchReplacer;
use Magento\Framework\Event\ObserverInterface;
+use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
{
@@ -30,11 +31,15 @@ class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
/** @var string[] */
private $dataUrlRewriteClassNames;
+ /** @var UrlDuplicatesRegistry */
+ private $urlDuplicatesRegistry;
+
/**
* @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
* @param UrlRewriteHandler $urlRewriteHandler
* @param UrlRewriteBunchReplacer $urlRewriteBunchReplacer
* @param DatabaseMapPool $databaseMapPool
+ * @param UrlDuplicatesRegistry $urlDuplicatesRegistry
* @param string[] $dataUrlRewriteClassNames
*/
public function __construct(
@@ -42,6 +47,7 @@ public function __construct(
UrlRewriteHandler $urlRewriteHandler,
UrlRewriteBunchReplacer $urlRewriteBunchReplacer,
DatabaseMapPool $databaseMapPool,
+ UrlDuplicatesRegistry $urlDuplicatesRegistry,
$dataUrlRewriteClassNames = [
DataCategoryUrlRewriteDatabaseMap::class,
DataProductUrlRewriteDatabaseMap::class
@@ -52,6 +58,7 @@ public function __construct(
$this->urlRewriteBunchReplacer = $urlRewriteBunchReplacer;
$this->databaseMapPool = $databaseMapPool;
$this->dataUrlRewriteClassNames = $dataUrlRewriteClassNames;
+ $this->urlDuplicatesRegistry = $urlDuplicatesRegistry;
}
/**
@@ -59,6 +66,7 @@ public function __construct(
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
+ * @throws \Magento\Framework\Exception\AlreadyExistsException
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
@@ -71,9 +79,19 @@ public function execute(\Magento\Framework\Event\Observer $observer)
|| $category->dataHasChangedFor('is_anchor')
|| $category->getIsChangedProductList()
) {
+ $this->urlDuplicatesRegistry->clearUrlDuplicates();
$categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category);
$this->urlRewriteBunchReplacer->doBunchReplace($categoryUrlRewriteResult);
+ if (!empty($this->urlDuplicatesRegistry->getUrlDuplicates())) {
+ throw new \Magento\Framework\Exception\AlreadyExistsException(
+ __(
+ 'URL key %1 for specified store already exists.',
+ current($this->urlDuplicatesRegistry->getUrlDuplicates())
+ )
+ );
+ }
+ $this->urlDuplicatesRegistry->clearUrlDuplicates();
$productUrlRewriteResult = $this->urlRewriteHandler->generateProductUrlRewrites($category);
$this->urlRewriteBunchReplacer->doBunchReplace($productUrlRewriteResult);
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
index 5bbed4470c787..68cd881f91f2c 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
@@ -59,6 +59,7 @@ public function execute(\Magento\Framework\Event\Observer $observer)
}
$urls = rtrim($urls, ', ');
+ //replace this with admin permament notification
$this->messageManager->addComplexWarningMessage(
'addUrlDuplicateWarningMessage',
['urls' => $urls, 'entity_type' => $observer->getProduct() ? 'product' : 'category']
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
index b43a9ec4ad3c5..79c4ae1ec1073 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
@@ -12,10 +12,4 @@
-
-
-
-
-
-
diff --git a/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php b/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
index b48cfdf66cd40..2903076967895 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
@@ -33,7 +33,6 @@ public function clearUrlDuplicates()
*
* @param array $urlDuplicates
* @return void
- * @throws \Magento\Framework\Exception\RuntimeException
*/
public function addUrlDuplicates(array $urlDuplicates)
{
From 397391d1c84cba2170ae112f123e683636ed1e8f Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Fri, 12 May 2017 13:14:17 -0500
Subject: [PATCH 023/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- throwing exception for replace, and have a better exception message
---
...ategoryProcessUrlRewriteMovingObserver.php | 22 ++----
...ategoryProcessUrlRewriteSavingObserver.php | 24 ++-----
...uplicateUrlControllerAfterSaveObserver.php | 69 -------------------
...ProductProcessUrlRewriteSavingObserver.php | 11 +--
.../CatalogUrlRewrite/etc/adminhtml/di.xml | 12 ----
.../etc/adminhtml/events.xml | 3 -
.../addUrlDuplicateWarningMessage.phtml | 51 --------------
app/code/Magento/Cms/etc/adminhtml/di.xml | 12 ----
app/code/Magento/Cms/etc/adminhtml/events.xml | 12 ----
.../Model/Storage/AbstractStorage.php | 21 +-----
.../UrlRewrite/Model/Storage/DbStorage.php | 29 +++++---
.../Model/UrlDuplicatesRegistry.php | 53 --------------
.../UrlRewrite/Model/UrlPersistInterface.php | 1 +
13 files changed, 35 insertions(+), 285 deletions(-)
delete mode 100644 app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
delete mode 100644 app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml
delete mode 100644 app/code/Magento/Cms/etc/adminhtml/events.xml
delete mode 100644 app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
index f8f10a54a4f8c..78a7592450424 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
@@ -14,8 +14,12 @@
use Magento\UrlRewrite\Model\UrlPersistInterface;
use Magento\Framework\Event\ObserverInterface;
use Magento\CatalogUrlRewrite\Model\Map\DatabaseMapPool;
-use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
+/**
+ * Generates Category Url Rewrites after move/save and Products Url Rewrites assigned to the category that's being saved
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
{
/** @var CategoryUrlRewriteGenerator */
@@ -41,9 +45,6 @@ class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
/** @var string[] */
private $dataUrlRewriteClassNames;
- /** @var UrlDuplicatesRegistry */
- private $urlDuplicatesRegistry;
-
/**
* @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
* @param UrlPersistInterface $urlPersist
@@ -51,7 +52,6 @@ class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
* @param UrlRewriteHandler $urlRewriteHandler
* @param UrlRewriteBunchReplacer $urlRewriteBunchReplacer
* @param DatabaseMapPool $databaseMapPool
- * @param UrlDuplicatesRegistry $urlDuplicatesRegistry,
* @param string[] $dataUrlRewriteClassNames
*/
public function __construct(
@@ -61,7 +61,6 @@ public function __construct(
UrlRewriteHandler $urlRewriteHandler,
UrlRewriteBunchReplacer $urlRewriteBunchReplacer,
DatabaseMapPool $databaseMapPool,
- UrlDuplicatesRegistry $urlDuplicatesRegistry,
$dataUrlRewriteClassNames = [
DataCategoryUrlRewriteDatabaseMap::class,
DataProductUrlRewriteDatabaseMap::class
@@ -91,22 +90,11 @@ public function execute(\Magento\Framework\Event\Observer $observer)
$category->getStoreId()
);
$category->setData('save_rewrites_history', $saveRewritesHistory);
- $this->urlDuplicatesRegistry->clearUrlDuplicates();
$categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category, true);
$this->urlRewriteHandler->deleteCategoryRewritesForChildren($category);
$this->urlRewriteBunchReplacer->doBunchReplace($categoryUrlRewriteResult);
- if (!empty($this->urlDuplicatesRegistry->getUrlDuplicates())) {
- throw new \Magento\Framework\Exception\AlreadyExistsException(
- __(
- 'URL key %1 for specified store already exists.',
- current($this->urlDuplicatesRegistry->getUrlDuplicates())
- )
- );
- }
- $this->urlDuplicatesRegistry->clearUrlDuplicates();
$productUrlRewriteResult = $this->urlRewriteHandler->generateProductUrlRewrites($category);
$this->urlRewriteBunchReplacer->doBunchReplace($productUrlRewriteResult);
-
//frees memory for maps that are self-initialized in multiple classes that were called by the generators
$this->resetUrlRewritesDataMaps($category);
}
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
index aed080a23131d..98df1fe591b15 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
@@ -12,8 +12,12 @@
use Magento\CatalogUrlRewrite\Model\Map\DataProductUrlRewriteDatabaseMap;
use Magento\CatalogUrlRewrite\Model\UrlRewriteBunchReplacer;
use Magento\Framework\Event\ObserverInterface;
-use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
+/**
+ * Generates Category Url Rewrites after save and Products Url Rewrites assigned to the category that's being saved
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
{
/** @var CategoryUrlRewriteGenerator */
@@ -31,15 +35,11 @@ class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
/** @var string[] */
private $dataUrlRewriteClassNames;
- /** @var UrlDuplicatesRegistry */
- private $urlDuplicatesRegistry;
-
/**
* @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
* @param UrlRewriteHandler $urlRewriteHandler
* @param UrlRewriteBunchReplacer $urlRewriteBunchReplacer
* @param DatabaseMapPool $databaseMapPool
- * @param UrlDuplicatesRegistry $urlDuplicatesRegistry
* @param string[] $dataUrlRewriteClassNames
*/
public function __construct(
@@ -47,7 +47,6 @@ public function __construct(
UrlRewriteHandler $urlRewriteHandler,
UrlRewriteBunchReplacer $urlRewriteBunchReplacer,
DatabaseMapPool $databaseMapPool,
- UrlDuplicatesRegistry $urlDuplicatesRegistry,
$dataUrlRewriteClassNames = [
DataCategoryUrlRewriteDatabaseMap::class,
DataProductUrlRewriteDatabaseMap::class
@@ -58,7 +57,6 @@ public function __construct(
$this->urlRewriteBunchReplacer = $urlRewriteBunchReplacer;
$this->databaseMapPool = $databaseMapPool;
$this->dataUrlRewriteClassNames = $dataUrlRewriteClassNames;
- $this->urlDuplicatesRegistry = $urlDuplicatesRegistry;
}
/**
@@ -79,22 +77,10 @@ public function execute(\Magento\Framework\Event\Observer $observer)
|| $category->dataHasChangedFor('is_anchor')
|| $category->getIsChangedProductList()
) {
- $this->urlDuplicatesRegistry->clearUrlDuplicates();
$categoryUrlRewriteResult = $this->categoryUrlRewriteGenerator->generate($category);
$this->urlRewriteBunchReplacer->doBunchReplace($categoryUrlRewriteResult);
- if (!empty($this->urlDuplicatesRegistry->getUrlDuplicates())) {
- throw new \Magento\Framework\Exception\AlreadyExistsException(
- __(
- 'URL key %1 for specified store already exists.',
- current($this->urlDuplicatesRegistry->getUrlDuplicates())
- )
- );
- }
-
- $this->urlDuplicatesRegistry->clearUrlDuplicates();
$productUrlRewriteResult = $this->urlRewriteHandler->generateProductUrlRewrites($category);
$this->urlRewriteBunchReplacer->doBunchReplace($productUrlRewriteResult);
-
//frees memory for maps that are self-initialized in multiple classes that were called by the generators
$this->resetUrlRewritesDataMaps($category);
}
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
deleted file mode 100644
index 68cd881f91f2c..0000000000000
--- a/app/code/Magento/CatalogUrlRewrite/Observer/DuplicateUrlControllerAfterSaveObserver.php
+++ /dev/null
@@ -1,69 +0,0 @@
-messageManager = $messageManager;
- $this->escaper = $escaper;
- $this->urlDuplicatesRegistry = $urlDuplicatesRegistry;
- }
-
- /**
- * Add url rewrite duplicates warnings
- *
- * @param \Magento\Framework\Event\Observer $observer
- * @return void
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
- */
- public function execute(\Magento\Framework\Event\Observer $observer)
- {
- if (!empty($this->urlDuplicatesRegistry->getUrlDuplicates())) {
- $urls = '';
- foreach ($this->urlDuplicatesRegistry->getUrlDuplicates() as $url) {
- /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite $url */
- $urls .= $url->getRequestPath() . ', ';
- }
- $urls = rtrim($urls, ', ');
-
- //replace this with admin permament notification
- $this->messageManager->addComplexWarningMessage(
- 'addUrlDuplicateWarningMessage',
- ['urls' => $urls, 'entity_type' => $observer->getProduct() ? 'product' : 'category']
- );
- }
- }
-}
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
index d23362cd4f1da..e4ccd0b869db7 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php
@@ -10,7 +10,6 @@
use Magento\UrlRewrite\Model\UrlPersistInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
use Magento\Framework\Event\ObserverInterface;
-use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
{
@@ -24,24 +23,16 @@ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
*/
private $urlPersist;
- /**
- * @var UrlDuplicatesRegistry
- */
- private $urlDuplicatesRegistry;
-
/**
* @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
* @param UrlPersistInterface $urlPersist
- * @param UrlDuplicatesRegistry $urlDuplicatesRegistry
*/
public function __construct(
ProductUrlRewriteGenerator $productUrlRewriteGenerator,
- UrlPersistInterface $urlPersist,
- UrlDuplicatesRegistry $urlDuplicatesRegistry
+ UrlPersistInterface $urlPersist
) {
$this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
$this->urlPersist = $urlPersist;
- $this->urlDuplicatesRegistry = $urlDuplicatesRegistry;
}
/**
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
index 8d7d257ee7e82..32ecc97d0f85f 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml
@@ -35,16 +35,4 @@
-
-
-
-
- \Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE
-
- Magento_CatalogUrlRewrite::messages/addUrlDuplicateWarningMessage.phtml
-
-
-
-
-
diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
index 79c4ae1ec1073..9c4a8aaf41231 100644
--- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
+++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/events.xml
@@ -9,7 +9,4 @@
-
-
-
diff --git a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml b/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml
deleted file mode 100644
index 1ca315275fccb..0000000000000
--- a/app/code/Magento/CatalogUrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml
+++ /dev/null
@@ -1,51 +0,0 @@
-getData('entity_type');
-?>
-
- escapeHtml(__('A conflict has occurred between the product\'s URL(s) and other URL(s).'));
- } else {
- echo $block->escapeHtml(__('A conflict has occurred between the category\'s URL(s) and other URL(s).'));
- }
- ?>
-
-
- escapeHtml(
- __('As a result, you cannot access this product through the specified URL(s): ')
- );
- } else {
- echo $block->escapeHtml(
- __('As a result, you cannot access this category through the specified URL(s): ')
- );
- }
- $urls = explode(', ', $block->getData('urls'));
- if (!empty($urls)) {
- if (count($urls) > 1) {
- echo " ";
- }
- $count = 1;
- foreach ($urls as $url) {
- echo "" . $block->escapeHtml($url) . "";
- if ($count <= count($urls)) {
- echo " ";
- }
- $count++;
- }
- }
- echo $block->escapeHtml(
- __(
- 'To fix the conflict, navigate to Search Engine Optimization section, '
- . 'then edit the URL key to make it unique.'
- )
- );
- ?>
-
\ No newline at end of file
diff --git a/app/code/Magento/Cms/etc/adminhtml/di.xml b/app/code/Magento/Cms/etc/adminhtml/di.xml
index c0dcd2024cfbd..8a1a4b24258d7 100644
--- a/app/code/Magento/Cms/etc/adminhtml/di.xml
+++ b/app/code/Magento/Cms/etc/adminhtml/di.xml
@@ -12,16 +12,4 @@
Magento\Framework\Url
-
-
-
-
- \Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE
-
- Magento_Cms::messages/addUrlDuplicateWarningMessage.phtml
-
-
-
-
-
diff --git a/app/code/Magento/Cms/etc/adminhtml/events.xml b/app/code/Magento/Cms/etc/adminhtml/events.xml
deleted file mode 100644
index a4eca5b2f86f0..0000000000000
--- a/app/code/Magento/Cms/etc/adminhtml/events.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index edaebde861503..e976172bc9c42 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -8,7 +8,6 @@
use Magento\UrlRewrite\Model\StorageInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
use Magento\Framework\Api\DataObjectHelper;
-use Magento\UrlRewrite\Model\UrlDuplicatesRegistry;
/**
* Abstract db storage
@@ -21,25 +20,16 @@ abstract class AbstractStorage implements StorageInterface
/** @var DataObjectHelper */
protected $dataObjectHelper;
- /**
- * @var UrlDuplicatesRegistry
- */
- private $urlDuplicatesRegistry;
-
/**
* @param UrlRewriteFactory $urlRewriteFactory
* @param DataObjectHelper $dataObjectHelper
- * @param UrlDuplicatesRegistry $urlDuplicatesRegistry
*/
public function __construct(
UrlRewriteFactory $urlRewriteFactory,
- DataObjectHelper $dataObjectHelper,
- UrlDuplicatesRegistry $urlDuplicatesRegistry = null
+ DataObjectHelper $dataObjectHelper
) {
$this->urlRewriteFactory = $urlRewriteFactory;
$this->dataObjectHelper = $dataObjectHelper;
- $this->urlDuplicatesRegistry = $urlDuplicatesRegistry ?: \Magento\Framework\App\ObjectManager::getInstance()
- ->get(UrlDuplicatesRegistry::class);
}
/**
@@ -90,14 +80,6 @@ public function replace(array $urls)
if (!$urls) {
return [];
}
-
- $savedUrls = $this->doReplace($urls);
- $unsavedUrlsDuplicates = array_diff_key(
- $urls,
- $savedUrls
- );
- // Set the duplicates to registry so it can be processed by the presentation layer
- $this->urlDuplicatesRegistry->addUrlDuplicates($unsavedUrlsDuplicates);
return $this->doReplace($urls);
}
@@ -106,6 +88,7 @@ public function replace(array $urls)
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+ * @throws \Magento\Framework\Exception\AlreadyExistsException
*/
abstract protected function doReplace($urls);
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index 80cc58c6bef65..78871874d7022 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -100,11 +100,21 @@ protected function doReplace($urls)
$urlData[UrlRewrite::ENTITY_TYPE] = $type;
$this->deleteByData($urlData);
}
- foreach ($urls as $key => $url) {
- if (!$this->insert($url->toArray())) {
- unset($urls[$key]);
+ $urlConflicted = [];
+ foreach ($urls as $url) {
+ if (!$this->insertUrl($url->toArray())) {
+ $urlConflicted[$url->getStoreId()] = $url->getRequestPath();
}
}
+ if (!empty($urlConflicted)) {
+ throw new \Magento\Framework\Exception\AlreadyExistsException(
+ __(
+ 'A conflict has occurred between the entity\'s URL(s) and other URL(s): %1.',
+ implode(', ', $urlConflicted)
+ )
+ );
+ }
+
return $urls;
}
@@ -126,7 +136,7 @@ protected function insertMultiple($data)
&& preg_match('#SQLSTATE\[23000\]: [^:]+: 1062[^\d]#', $e->getMessage())
) {
throw new \Magento\Framework\Exception\AlreadyExistsException(
- __('URL key for specified store already exists.')
+ __('A conflict has occurred between the entity\'s URL(s) and other URL(s).')
);
}
throw $e;
@@ -134,12 +144,13 @@ protected function insertMultiple($data)
}
/**
- * Inserts a url as array to database
+ * Inserts a url as array to database and returns conflict status
*
* @param array $data
* @return bool
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
- private function insert(array $data)
+ private function insertUrl(array $data)
{
try {
return $this->connection->insert($this->resource->getTableName(self::TABLE_NAME), $data) > 0;
@@ -161,11 +172,13 @@ private function insert(array $data)
$data['store_id']
)
);
+ return false;
} else {
- $this->logger->error($e->getMessage());
+ throw new \Magento\Framework\Exception\LocalizedException(
+ __('Something went wrong while inserting a url key.')
+ );
}
}
- return false;
}
/**
diff --git a/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php b/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
deleted file mode 100644
index 2903076967895..0000000000000
--- a/app/code/Magento/UrlRewrite/Model/UrlDuplicatesRegistry.php
+++ /dev/null
@@ -1,53 +0,0 @@
-urlDuplicates = [];
- }
-
- /**
- * Set the url rewrites duplicates that resulted from a saving process
- *
- * @param array $urlDuplicates
- * @return void
- */
- public function addUrlDuplicates(array $urlDuplicates)
- {
- if (empty($this->urlDuplicates)) {
- $this->urlDuplicates = array_merge($this->urlDuplicates, $urlDuplicates);
- }
- }
-
- /**
- * Returns the stored url rewrites duplicates
- *
- * @return array|\Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
- */
- public function getUrlDuplicates()
- {
- return $this->urlDuplicates;
- }
-}
diff --git a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
index 371a683351eea..03f76fbc70268 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
@@ -16,6 +16,7 @@ interface UrlPersistInterface
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+ * @throws \Magento\Framework\Exception\AlreadyExistsException|\Magento\Framework\Exception\LocalizedException
*/
public function replace(array $urls);
From 9b3a4a5e01fdcaa1754c2b35cf97b12b02933ae0 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Fri, 12 May 2017 15:39:12 -0500
Subject: [PATCH 024/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- throwing detailed exception about each conflicting entity
---
.../Model/Storage/AbstractStorage.php | 4 +-
.../UrlRewrite/Model/Storage/DbStorage.php | 39 +++++++++++++++++--
2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index e976172bc9c42..fe61d3f08a6c1 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -50,7 +50,7 @@ public function findAllByData(array $data)
* Find all rows by specific filter. Template method
*
* @param array $data
- * @return array
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
*/
abstract protected function doFindAllByData($data);
@@ -68,7 +68,7 @@ public function findOneByData(array $data)
* Find row by specific filter. Template method
*
* @param array $data
- * @return array
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite
*/
abstract protected function doFindOneByData($data);
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index 78871874d7022..76672b202a603 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -10,6 +10,8 @@
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;
use Magento\Framework\Api\DataObjectHelper;
use Psr\Log\LoggerInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteData;
+use Magento\Framework\UrlInterface;
class DbStorage extends AbstractStorage
{
@@ -38,22 +40,31 @@ class DbStorage extends AbstractStorage
*/
private $logger;
+ /**
+ * @var \Magento\Framework\UrlInterface
+ */
+ protected $urlBuilder;
+
/**
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory $urlRewriteFactory
* @param DataObjectHelper $dataObjectHelper
* @param \Magento\Framework\App\ResourceConnection $resource
* @param \Psr\Log\LoggerInterface|null $logger
+ * @param \Magento\Framework\UrlInterface|null $urlBuilder
*/
public function __construct(
UrlRewriteFactory $urlRewriteFactory,
DataObjectHelper $dataObjectHelper,
ResourceConnection $resource,
- LoggerInterface $logger = null
+ LoggerInterface $logger = null,
+ UrlInterface $urlBuilder = null
) {
$this->connection = $resource->getConnection();
$this->resource = $resource;
$this->logger = $logger ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Psr\Log\LoggerInterface::class);
+ $this->urlBuilder = $urlBuilder ?: \Magento\Framework\App\ObjectManager::getInstance()
+ ->get(\Magento\Framework\UrlInterface::class);
parent::__construct($urlRewriteFactory, $dataObjectHelper);
}
@@ -100,17 +111,37 @@ protected function doReplace($urls)
$urlData[UrlRewrite::ENTITY_TYPE] = $type;
$this->deleteByData($urlData);
}
+ /** @var \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urlConflicted */
$urlConflicted = [];
foreach ($urls as $url) {
if (!$this->insertUrl($url->toArray())) {
- $urlConflicted[$url->getStoreId()] = $url->getRequestPath();
+ $urlConflicted[] = $url;
}
}
if (!empty($urlConflicted)) {
+ $urlsWithLinks = '';
+ foreach ($urlConflicted as $url) {
+ $urlFound = $this->doFindOneByData(
+ [
+ UrlRewriteData::REQUEST_PATH => $url->getRequestPath(),
+ UrlRewriteData::STORE_ID => $url->getStoreId()
+ ]
+ );
+ $adminEditUrl = $this->urlBuilder->getUrl(
+ 'adminhtml/url_rewrite/edit',
+ ['id' => $urlFound[UrlRewriteData::URL_REWRITE_ID]]
+ );
+ $urlsWithLinks .=''
+ . $url->getRequestPath() . ' ';
+ }
+
throw new \Magento\Framework\Exception\AlreadyExistsException(
__(
- 'A conflict has occurred between the entity\'s URL(s) and other URL(s): %1.',
- implode(', ', $urlConflicted)
+ 'A conflict has occurred between the entity\'s URL(s) and the existing URL(s): %1'
+ . 'To fix the conflict, rename the conflicting urls by clicking on the links above, '
+ . 'or navigate to Search Engine Optimization section, '
+ . 'then edit the URL key to make it unique',
+ $urlsWithLinks
)
);
}
From beae4368d4a3bc7e75234eaba3dbf6dd3ff8d4d0 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Fri, 12 May 2017 15:47:22 -0500
Subject: [PATCH 025/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- changing signatures
---
.../Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php | 2 +-
app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php | 4 ++--
app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php | 4 ++--
app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php | 4 ++--
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php
index 980b79670869b..748589924d916 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Storage/DbStorage.php
@@ -15,7 +15,7 @@ class DbStorage extends BaseDbStorage
* @param array $data
* @return \Magento\Framework\DB\Select
*/
- protected function prepareSelect($data)
+ protected function prepareSelect(array $data)
{
$select = $this->connection->select();
$select->from(['url_rewrite' => $this->resource->getTableName('url_rewrite')])
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index fe61d3f08a6c1..9ad2eaf6931d6 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -68,9 +68,9 @@ public function findOneByData(array $data)
* Find row by specific filter. Template method
*
* @param array $data
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite
+ * @return array
*/
- abstract protected function doFindOneByData($data);
+ abstract protected function doFindOneByData(array $data);
/**
* {@inheritdoc}
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index 76672b202a603..114d12a0cabe9 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -75,7 +75,7 @@ public function __construct(
* @param array $data
* @return \Magento\Framework\DB\Select
*/
- protected function prepareSelect($data)
+ protected function prepareSelect(array $data)
{
$select = $this->connection->select();
$select->from($this->resource->getTableName(self::TABLE_NAME));
@@ -97,7 +97,7 @@ protected function doFindAllByData($data)
/**
* {@inheritdoc}
*/
- protected function doFindOneByData($data)
+ protected function doFindOneByData(array $data)
{
return $this->connection->fetchRow($this->prepareSelect($data));
}
diff --git a/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php b/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
index 6c084c147e28f..c8cec9c93b184 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
@@ -15,7 +15,7 @@ interface UrlFinderInterface
* Find rewrite by specific data
*
* @param array $data
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
+ * @return array|null
*/
public function findOneByData(array $data);
@@ -23,7 +23,7 @@ public function findOneByData(array $data);
* Find rewrites by specific data
*
* @param array $data
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+ * @return array
*/
public function findAllByData(array $data);
}
From 2c5fc9f03856a6f0ca17632499ebd17508486aa2 Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Fri, 12 May 2017 15:53:54 -0500
Subject: [PATCH 026/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- changing signatures
---
.../Magento/UrlRewrite/Model/Storage/AbstractStorage.php | 6 +++---
app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php | 4 ++--
app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
index 9ad2eaf6931d6..f794c3809af42 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/AbstractStorage.php
@@ -50,9 +50,9 @@ public function findAllByData(array $data)
* Find all rows by specific filter. Template method
*
* @param array $data
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+ * @return array
*/
- abstract protected function doFindAllByData($data);
+ abstract protected function doFindAllByData(array $data);
/**
* {@inheritdoc}
@@ -90,7 +90,7 @@ public function replace(array $urls)
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
- abstract protected function doReplace($urls);
+ abstract protected function doReplace(array $urls);
/**
* Create url rewrite object
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index 114d12a0cabe9..dab330974da5d 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -89,7 +89,7 @@ protected function prepareSelect(array $data)
/**
* {@inheritdoc}
*/
- protected function doFindAllByData($data)
+ protected function doFindAllByData(array $data)
{
return $this->connection->fetchAll($this->prepareSelect($data));
}
@@ -105,7 +105,7 @@ protected function doFindOneByData(array $data)
/**
* {@inheritdoc}
*/
- protected function doReplace($urls)
+ protected function doReplace(array $urls)
{
foreach ($this->createFilterDataBasedOnUrls($urls) as $type => $urlData) {
$urlData[UrlRewrite::ENTITY_TYPE] = $type;
diff --git a/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php b/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
index c8cec9c93b184..6c084c147e28f 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlFinderInterface.php
@@ -15,7 +15,7 @@ interface UrlFinderInterface
* Find rewrite by specific data
*
* @param array $data
- * @return array|null
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
public function findOneByData(array $data);
@@ -23,7 +23,7 @@ public function findOneByData(array $data);
* Find rewrites by specific data
*
* @param array $data
- * @return array
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
*/
public function findAllByData(array $data);
}
From 916f075fa6a65507ae96501309ac6a42ebee2d6e Mon Sep 17 00:00:00 2001
From: Cristian Partica
Date: Fri, 12 May 2017 16:27:41 -0500
Subject: [PATCH 027/316] MAGETWO-66480: [GITHUB] URL key for specified store
already exists #6671
- modifying text on exception
---
.../Magento/UrlRewrite/Model/Storage/DbStorage.php | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
index dab330974da5d..df81562276621 100644
--- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
+++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php
@@ -119,7 +119,7 @@ protected function doReplace(array $urls)
}
}
if (!empty($urlConflicted)) {
- $urlsWithLinks = '';
+ $urlsWithLinks = ' ';
foreach ($urlConflicted as $url) {
$urlFound = $this->doFindOneByData(
[
@@ -131,16 +131,16 @@ protected function doReplace(array $urls)
'adminhtml/url_rewrite/edit',
['id' => $urlFound[UrlRewriteData::URL_REWRITE_ID]]
);
- $urlsWithLinks .=''
- . $url->getRequestPath() . ' ';
+ $urlsWithLinks .='- '
+ . $url->getRequestPath() . ' ';
}
throw new \Magento\Framework\Exception\AlreadyExistsException(
__(
- 'A conflict has occurred between the entity\'s URL(s) and the existing URL(s): %1'
- . 'To fix the conflict, rename the conflicting urls by clicking on the links above, '
- . 'or navigate to Search Engine Optimization section, '
- . 'then edit the URL key to make it unique',
+ '
The value specified in the URL Key field would generate a URL that already exists.
The value specified in the URL Key field would generate a URL that already exists.
'
- .'To resolve this conflict, you can either change the value of the URL Key field '
- .' (located in the Search Engine Optimization section) to a unique value, '
- . 'or change the URL Key fields in all locations listed below:%1',
- $urlsWithLinks
- )
+ }
+ if (!empty($urlConflicted)) {
+ throw new \Magento\UrlRewrite\Model\Storage\UrlAlreadyExistsException(
+ __('URL key for specified store already exists.'),
+ null,
+ $urlConflicted
);
}
-
return $urls;
}
@@ -193,7 +169,7 @@ private function insertUrl(array $data)
&& $e->getCode() === self::ERROR_CODE_DUPLICATE_ENTRY
&& preg_match('#SQLSTATE\[23000\]: [^:]+: 1062[^\d]#', $e->getMessage())
) {
- $this->logger->warning(
+ $this->logger->critical(
__(
'Could not insert a conflicting URL when trying to insert \'%1\' for %2 '
.'with entity id %3 on store %4',
diff --git a/app/code/Magento/UrlRewrite/Model/Storage/UrlAlreadyExistsException.php b/app/code/Magento/UrlRewrite/Model/Storage/UrlAlreadyExistsException.php
new file mode 100644
index 0000000000000..59fa69a6b5b57
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Model/Storage/UrlAlreadyExistsException.php
@@ -0,0 +1,41 @@
+urls = $urls;
+ if ($phrase === null) {
+ $phrase = new Phrase('Unique constraint violation found');
+ }
+ parent::__construct($phrase, $cause);
+ }
+
+ /**
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+ */
+ public function getUrls()
+ {
+ return $this->urls;
+ }
+}
diff --git a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
index 03f76fbc70268..449bd050e5858 100644
--- a/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
+++ b/app/code/Magento/UrlRewrite/Model/UrlPersistInterface.php
@@ -16,7 +16,7 @@ interface UrlPersistInterface
*
* @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
- * @throws \Magento\Framework\Exception\AlreadyExistsException|\Magento\Framework\Exception\LocalizedException
+ * @throws \Magento\UrlRewrite\Model\Storage\UrlAlreadyExistsException
*/
public function replace(array $urls);
diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml
new file mode 100644
index 0000000000000..cc304f5ebbc7a
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/messages/addUrlDuplicateWarningMessage.phtml
@@ -0,0 +1,33 @@
+
+getData('urls');
+?>
+
+ escapeHtml(__('The value specified in the URL Key field would generate a URL that already exists.'));
+ ?>
+
+
+ escapeHtml(
+ __(
+ 'To resolve this conflict, you can either change the value of the URL Key field '
+ . '(located in the Search Engine Optimization section) to a unique value, or change the Request Path fields'
+ .' in all locations listed below:'
+ )
+ );
+
+ if (!empty($urls)) {
+ foreach ($urls as $key => $url) {
+ // key is the url that has been setup by the controller with the information from the exception
+ echo '