Skip to content

Commit a450e03

Browse files
committed
Merge branch 'develop' of https://github.com/adobe-commerce-tier-4/magento2-page-builder into ACP2E-3408
2 parents 6d1bcc7 + 0a7cc2f commit a450e03

File tree

6 files changed

+218
-27
lines changed

6 files changed

+218
-27
lines changed

app/code/Magento/PageBuilder/Model/TemplateRepository.php

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2019 Adobe
4+
* All Rights Reserved.
55
*/
6-
76
declare(strict_types=1);
87

98
namespace Magento\PageBuilder\Model;
109

1110
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
1211
use Magento\Framework\Api\SearchCriteriaInterface;
12+
use Magento\Framework\App\Filesystem\DirectoryList;
1313
use Magento\Framework\Exception\CouldNotDeleteException;
1414
use Magento\Framework\Exception\CouldNotSaveException;
15+
use Magento\Framework\Exception\FileSystemException;
1516
use Magento\Framework\Exception\NoSuchEntityException;
1617
use Magento\Framework\Filesystem;
18+
use Magento\Framework\Image\Factory;
1719
use Magento\PageBuilder\Api\Data\TemplateInterface;
1820
use Magento\PageBuilder\Api\Data\TemplateSearchResultsInterfaceFactory;
1921
use Magento\PageBuilder\Api\TemplateRepositoryInterface;
@@ -71,6 +73,7 @@ class TemplateRepository implements TemplateRepositoryInterface
7173
* @param CollectionProcessorInterface $collectionProcessor
7274
* @param Filesystem $filesystem
7375
* @param Database $mediaStorage
76+
* @param Factory $imageFactory
7477
*/
7578
public function __construct(
7679
ResourceTemplate $resource,
@@ -79,7 +82,8 @@ public function __construct(
7982
TemplateSearchResultsInterfaceFactory $searchResultsFactory,
8083
CollectionProcessorInterface $collectionProcessor,
8184
Filesystem $filesystem,
82-
Database $mediaStorage
85+
Database $mediaStorage,
86+
private readonly Factory $imageFactory
8387
) {
8488
$this->resource = $resource;
8589
$this->templateFactory = $templateFactory;
@@ -142,25 +146,14 @@ public function getList(SearchCriteriaInterface $criteria)
142146
*/
143147
public function delete(TemplateInterface $template) : bool
144148
{
145-
$mediaDir = $this->filesystem
146-
->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
147-
148149
try {
149150
$templateModel = $this->templateFactory->create();
150151
$this->resource->load($templateModel, $template->getTemplateId());
151152
$this->resource->delete($templateModel);
152153
$previewImage = $template->getPreviewImage();
153154
$previewThumbImage = $templateModel->getPreviewThumbnailImage();
154-
155-
// Remove the preview image from the media directory
156-
if ($mediaDir->isExist($previewImage)) {
157-
$mediaDir->delete($previewImage);
158-
}
159-
if ($mediaDir->isExist($previewThumbImage)) {
160-
$mediaDir->delete($previewThumbImage);
161-
}
162-
$this->mediaStorage->deleteFile($previewImage);
163-
$this->mediaStorage->deleteFile($previewThumbImage);
155+
$this->deletePreviewImage($previewImage);
156+
$this->deletePreviewImage($previewThumbImage);
164157
} catch (\Exception $exception) {
165158
throw new CouldNotDeleteException(
166159
__('Could not delete the Template: %1', $exception->getMessage())
@@ -170,6 +163,32 @@ public function delete(TemplateInterface $template) : bool
170163
return true;
171164
}
172165

166+
/**
167+
* Checks if preview image is valid and tries to delete it
168+
*
169+
* @param string $imageName
170+
* @return void
171+
* @throws FileSystemException
172+
*/
173+
private function deletePreviewImage(string $imageName): void
174+
{
175+
$isValid = true;
176+
$mediaDir = $this->filesystem
177+
->getDirectoryWrite(DirectoryList::MEDIA);
178+
179+
try {
180+
$this->imageFactory->create($mediaDir->getAbsolutePath().$imageName);
181+
} catch (\Exception) {
182+
$isValid = false;
183+
}
184+
185+
if ($mediaDir->isExist($imageName) && $isValid) {
186+
$mediaDir->delete($imageName);
187+
}
188+
189+
$this->mediaStorage->deleteFile($imageName);
190+
}
191+
173192
/**
174193
* @inheritdoc
175194
*/
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2020 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -12,11 +12,11 @@
1212
<element name="title" type="input" selector="//div[@aria-label='Insert link']//div[contains(@id,'-title') and .='Insert link']"/>
1313
<element name="xButton" type="button" selector="[aria-label='Insert link'] button.mce-close"/>
1414
<element name="urlInput" type="input" selector="//div[@class='tox-dialog']//label[text()='URL']/..//input"/>
15-
<element name="browseMediaGalleryButton" type="button" selector="//div[@class='tox-dialog']//label[text()='URL']//..//button[@aria-label='Browse links']"/>
15+
<element name="browseMediaGalleryButton" type="button" selector="//div[@class='tox-dialog']//label[text()='URL']//..//button[@title='Browse links']"/>
1616
<element name="textToDisplayInput" type="input" selector="//div[@class='tox-dialog']//label[text()='Text to display']/..//input"/>
1717
<element name="titleInput" type="input" selector="//div[@class='tox-dialog']//label[text()='Title']/..//input"/>
1818
<element name="targetInput" type="input" selector="button[title='Open link in...']"/>
19-
<element name="okButton" type="button" selector="//div[@class='tox-dialog']//button[@aria-label='Save']"/>
19+
<element name="okButton" type="button" selector="//div[@class='tox-dialog']//button[@title='Save']"/>
2020
<element name="cancelButton" type="button" selector="//div[@aria-label='Insert link']//button//span[.='Cancel']"/>
2121
</section>
2222
</sections>

app/code/Magento/PageBuilder/Test/Mftf/Section/PageBuilderWYSIWYGSection/WYSIWYGOnPageBuilderInlineSection.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2020 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -43,7 +43,7 @@
4343
<element name="specialCharacter" type="button" selector=".tox-tinymce-inline button[aria-label='Special character']"/>
4444
<element name="insertWidget" type="button" selector=".tox-tinymce-inline button[aria-label='Insert Widget']"/>
4545
<element name="insertVariable" type="button" selector=".tox-tinymce-inline button[aria-label='Insert Variable']"/>
46-
<element name="imageSelectorBrowse" type="button" selector="button[aria-label='Browse files']"/>
46+
<element name="imageSelectorBrowse" type="button" selector="button[title='Browse files']"/>
4747
<element name="imageSelectorOk" type="button" selector="//div[contains(@aria-label, 'Insert/edit image')]//span[contains(@class, 'mce-txt')][text()='Ok']"/>
4848
<element name="formatOption" type="text" parameterized="true" selector="div[title='{{label}}']"/>
4949
<element name="HeadSelector" type="text" selector="div[title='Headings']"/>
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
/**
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
4+
* Copyright 2021 Adobe
5+
* All Rights Reserved.
66
*/
77
-->
88
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
99
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1010
<section name="TinyMCESection">
11-
<element name="Style" type="button" selector="button[aria-label='Format Paragraph']"/>
11+
<element name="Style" type="button" selector="button[title='Format Paragraph']"/>
1212
</section>
1313
</sections>
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\PageBuilder\Test\Unit\Model;
9+
10+
use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
11+
use Magento\Framework\Exception\CouldNotDeleteException;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Filesystem;
14+
use Magento\Framework\Filesystem\Directory\WriteInterface;
15+
use Magento\Framework\Image\Adapter\AdapterInterface;
16+
use Magento\Framework\Image\Factory;
17+
use Magento\PageBuilder\Api\Data\TemplateSearchResultsInterfaceFactory;
18+
use Magento\PageBuilder\Model\ResourceModel\Template as ResourceTemplate;
19+
use Magento\PageBuilder\Model\ResourceModel\Template\CollectionFactory;
20+
use Magento\PageBuilder\Model\Template;
21+
use Magento\PageBuilder\Model\TemplateFactory;
22+
use Magento\PageBuilder\Model\TemplateRepository;
23+
use Magento\MediaStorage\Helper\File\Storage\Database;
24+
use PHPUnit\Framework\MockObject\Exception;
25+
use PHPUnit\Framework\MockObject\MockObject;
26+
use PHPUnit\Framework\TestCase;
27+
28+
/**
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
31+
class TemplateRepositoryTest extends TestCase
32+
{
33+
/**
34+
* @var ResourceTemplate|MockObject
35+
*/
36+
private $resourceMock;
37+
38+
/**
39+
* @var TemplateFactory|MockObject
40+
*/
41+
private $templateFactoryMock;
42+
43+
/**
44+
* @var CollectionFactory|MockObject
45+
*/
46+
private $templateCollectionFactoryMock;
47+
48+
/**
49+
* @var TemplateSearchResultsInterfaceFactory|MockObject
50+
*/
51+
private $searchResultsFactoryMock;
52+
53+
/**
54+
* @var CollectionProcessorInterface|MockObject
55+
*/
56+
private $collectionProcessorMock;
57+
58+
/**
59+
* @var Filesystem|MockObject
60+
*/
61+
private $filesystemMock;
62+
63+
/**
64+
* @var Database|MockObject
65+
*/
66+
private $mediaStorageMock;
67+
68+
/**
69+
* @var Factory|MockObject
70+
*/
71+
private $imageFactoryMock;
72+
73+
/**
74+
* @var TemplateRepository
75+
*/
76+
private $templateRepository;
77+
78+
protected function setUp(): void
79+
{
80+
$this->resourceMock = $this->createMock(ResourceTemplate::class);
81+
$this->templateFactoryMock = $this->createMock(TemplateFactory::class);
82+
$this->templateCollectionFactoryMock = $this->createMock(CollectionFactory::class);
83+
$this->searchResultsFactoryMock = $this->createMock(TemplateSearchResultsInterfaceFactory::class);
84+
$this->collectionProcessorMock = $this->createMock(CollectionProcessorInterface::class);
85+
$this->filesystemMock = $this->createMock(Filesystem::class);
86+
$this->mediaStorageMock = $this->createMock(Database::class);
87+
$this->imageFactoryMock = $this->createMock(Factory::class);
88+
89+
$this->templateRepository = new TemplateRepository(
90+
$this->resourceMock,
91+
$this->templateFactoryMock,
92+
$this->templateCollectionFactoryMock,
93+
$this->searchResultsFactoryMock,
94+
$this->collectionProcessorMock,
95+
$this->filesystemMock,
96+
$this->mediaStorageMock,
97+
$this->imageFactoryMock
98+
);
99+
}
100+
101+
/**
102+
* Test for delete method
103+
*
104+
* @return void
105+
* @throws LocalizedException
106+
* @throws Exception
107+
*/
108+
public function testDelete()
109+
{
110+
$templateId = 1;
111+
$templateMock =$this->getMockBuilder(Template::class)
112+
->disableOriginalConstructor()
113+
->addMethods(['getTemplateId'])
114+
->onlyMethods(['getPreviewImage', 'getPreviewThumbnailImage'])
115+
->getMock();
116+
;
117+
$templateMock->expects($this->once())
118+
->method('getTemplateId')
119+
->willReturn($templateId);
120+
$templateMock->expects($this->once())
121+
->method('getPreviewImage')
122+
->willReturn('preview_image.jpg');
123+
$templateMock->expects($this->once())
124+
->method('getPreviewThumbnailImage')
125+
->willReturn('preview_thumb_image.jpg');
126+
127+
$this->templateFactoryMock->method('create')->willReturn($templateMock);
128+
$this->resourceMock->expects($this->once())->method('load')->with($templateMock, $templateId);
129+
$this->resourceMock->expects($this->once())->method('delete')->with($templateMock);
130+
131+
$mediaDirMock = $this->createMock(WriteInterface::class);
132+
$this->filesystemMock->method('getDirectoryWrite')->willReturn($mediaDirMock);
133+
$mediaDirMock->method('isExist')->willReturn(true);
134+
$mediaDirMock->method('delete')->willReturn(true);
135+
$this->imageFactoryMock->expects($this->exactly(2))
136+
->method('create')
137+
->willReturnCallback(
138+
function ($path) {
139+
$this->assertEquals('preview_image.jpg', $path);
140+
return $this->createMock(AdapterInterface::class);
141+
}
142+
);
143+
$this->mediaStorageMock->expects($this->exactly(2))->method('deleteFile');
144+
145+
$this->assertTrue($this->templateRepository->delete($templateMock));
146+
}
147+
148+
/**
149+
* Test for delete method when throws exception
150+
*
151+
* @return void
152+
* @throws LocalizedException
153+
*/
154+
public function testDeleteThrowsException()
155+
{
156+
$this->expectException(CouldNotDeleteException::class);
157+
158+
$templateMock =$this->getMockBuilder(Template::class)
159+
->disableOriginalConstructor()
160+
->addMethods(['getTemplateId'])
161+
->getMock();
162+
$templateMock->expects($this->once())
163+
->method('getTemplateId')
164+
->willReturn(1);
165+
166+
$this->templateFactoryMock->method('create')->willReturn($templateMock);
167+
$this->resourceMock->method('load')->willThrowException(new \Exception('Error'));
168+
169+
$this->templateRepository->delete($templateMock);
170+
}
171+
}

app/code/Magento/PageBuilder/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,4 @@ OK,OK
322322
"There is no content able to be saved within Page Builder.","There is no content able to be saved within Page Builder."
323323
"Save Content as Template","Save Content as Template"
324324
"Template Name","Template Name"
325+
"Could not delete the Template: %1","Could not delete the Template: %1"

0 commit comments

Comments
 (0)