Skip to content

Commit 6a80d57

Browse files
committed
Merge remote-tracking branch '39746/issue/39743-cms-page-error-log-fix' into commpr-10131-1706
2 parents 2c6483a + aaf1c99 commit 6a80d57

File tree

3 files changed

+267
-39
lines changed

3 files changed

+267
-39
lines changed

app/code/Magento/Cms/Model/Page/DataProvider.php

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
namespace Magento\Cms\Model\Page;
77

88
use Magento\Cms\Api\Data\PageInterface;
9-
use Magento\Cms\Api\PageRepositoryInterface;
10-
use Magento\Cms\Model\PageFactory;
9+
use Magento\Cms\Model\Page\Service\PageService;
1110
use Magento\Cms\Model\ResourceModel\Page\CollectionFactory;
1211
use Magento\Framework\App\ObjectManager;
1312
use Magento\Framework\App\Request\DataPersistorInterface;
@@ -33,11 +32,6 @@ class DataProvider extends ModifierPoolDataProvider
3332
*/
3433
protected $loadedData;
3534

36-
/**
37-
* @var PageRepositoryInterface
38-
*/
39-
private $pageRepository;
40-
4135
/**
4236
* @var AuthorizationInterface
4337
*/
@@ -49,14 +43,9 @@ class DataProvider extends ModifierPoolDataProvider
4943
private $request;
5044

5145
/**
52-
* @var CustomLayoutManagerInterface
46+
* @var PageService
5347
*/
54-
private $customLayoutManager;
55-
56-
/**
57-
* @var PageFactory
58-
*/
59-
private $pageFactory;
48+
private $pageService;
6049

6150
/**
6251
* @var LoggerInterface
@@ -74,9 +63,7 @@ class DataProvider extends ModifierPoolDataProvider
7463
* @param PoolInterface|null $pool
7564
* @param AuthorizationInterface|null $auth
7665
* @param RequestInterface|null $request
77-
* @param CustomLayoutManagerInterface|null $customLayoutManager
78-
* @param PageRepositoryInterface|null $pageRepository
79-
* @param PageFactory|null $pageFactory
66+
* @param PageService|null $pageService
8067
* @param LoggerInterface|null $logger
8168
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
8269
*/
@@ -91,9 +78,7 @@ public function __construct(
9178
?PoolInterface $pool = null,
9279
?AuthorizationInterface $auth = null,
9380
?RequestInterface $request = null,
94-
?CustomLayoutManagerInterface $customLayoutManager = null,
95-
?PageRepositoryInterface $pageRepository = null,
96-
?PageFactory $pageFactory = null,
81+
?PageService $pageService = null,
9782
?LoggerInterface $logger = null
9883
) {
9984
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool);
@@ -102,10 +87,7 @@ public function __construct(
10287
$this->auth = $auth ?? ObjectManager::getInstance()->get(AuthorizationInterface::class);
10388
$this->meta = $this->prepareMeta($this->meta);
10489
$this->request = $request ?? ObjectManager::getInstance()->get(RequestInterface::class);
105-
$this->customLayoutManager = $customLayoutManager
106-
?? ObjectManager::getInstance()->get(CustomLayoutManagerInterface::class);
107-
$this->pageRepository = $pageRepository ?? ObjectManager::getInstance()->get(PageRepositoryInterface::class);
108-
$this->pageFactory = $pageFactory ?: ObjectManager::getInstance()->get(PageFactory::class);
90+
$this->pageService = $pageService ?: ObjectManager::getInstance()->get(PageService::class);
10991
$this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
11092
}
11193

@@ -150,22 +132,16 @@ private function getCurrentPage(): PageInterface
150132
{
151133
$pageId = $this->getPageId();
152134
if ($pageId) {
153-
try {
154-
$page = $this->pageRepository->getById($pageId);
155-
} catch (LocalizedException $exception) {
156-
$page = $this->pageFactory->create();
157-
}
158-
159-
return $page;
135+
return $this->pageService->getPageById($pageId);
160136
}
161137

162138
$data = $this->dataPersistor->get('cms_page');
163139
if (empty($data)) {
164-
return $this->pageFactory->create();
140+
return $this->pageService->createPageFactory();
165141
}
166142
$this->dataPersistor->clear('cms_page');
167143

168-
return $this->pageFactory->create()
144+
return $this->pageService->createPageFactory()
169145
->setData($data);
170146
}
171147

@@ -215,12 +191,15 @@ public function getMeta()
215191

216192
$page = null;
217193
try {
218-
$page = $this->pageRepository->getById($this->getPageId());
219-
if ($page->getCustomLayoutUpdateXml() || $page->getLayoutUpdateXml()) {
220-
$options[] = ['label' => 'Use existing layout update XML', 'value' => '_existing_'];
221-
}
222-
foreach ($this->customLayoutManager->fetchAvailableFiles($page) as $layoutFile) {
223-
$options[] = ['label' => $layoutFile, 'value' => $layoutFile];
194+
$pageId = $this->getPageId();
195+
if ($pageId) {
196+
$page = $this->pageService->getPageById($pageId);
197+
if ($page->getCustomLayoutUpdateXml() || $page->getLayoutUpdateXml()) {
198+
$options[] = ['label' => 'Use existing layout update XML', 'value' => '_existing_'];
199+
}
200+
foreach ($this->pageService->fetchAvailableCustomLayouts($page) as $layoutFile) {
201+
$options[] = ['label' => $layoutFile, 'value' => $layoutFile];
202+
}
224203
}
225204
} catch (LocalizedException $e) {
226205
$this->logger->error($e->getMessage());
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
declare(strict_types=1);
3+
/**
4+
* Copyright 2015 Adobe
5+
* All Rights Reserved.
6+
*/
7+
namespace Magento\Cms\Model\Page\Service;
8+
9+
use Magento\Cms\Api\Data\PageInterface;
10+
use Magento\Cms\Api\PageRepositoryInterface;
11+
use Magento\Cms\Model\Page\CustomLayoutManagerInterface;
12+
use Magento\Cms\Model\PageFactory;
13+
use Magento\Framework\Exception\LocalizedException;
14+
15+
/**
16+
* Cms Page Service Class
17+
*/
18+
class PageService
19+
{
20+
/**
21+
* @param PageRepositoryInterface $pageRepository
22+
* @param PageFactory $pageFactory
23+
* @param CustomLayoutManagerInterface $customLayoutManager
24+
*/
25+
public function __construct(
26+
private readonly PageRepositoryInterface $pageRepository,
27+
private readonly PageFactory $pageFactory,
28+
private readonly CustomLayoutManagerInterface $customLayoutManager,
29+
) {
30+
}
31+
32+
/**
33+
* To get the page by its ID. If the page not exists, a new page instance is returned
34+
*
35+
* @param int $id
36+
* @return PageInterface
37+
*/
38+
public function getPageById(int $id): PageInterface
39+
{
40+
try {
41+
return $this->pageRepository->getById($id);
42+
} catch (LocalizedException) {
43+
return $this->pageFactory->create();
44+
}
45+
}
46+
47+
/**
48+
* To create pagefactory class
49+
*
50+
* @return PageInterface
51+
*/
52+
public function createPageFactory(): PageInterface
53+
{
54+
return $this->pageFactory->create();
55+
}
56+
57+
/**
58+
* Fetches the available custom layouts for a given page.
59+
*
60+
* @param PageInterface $page
61+
* @return array
62+
*/
63+
public function fetchAvailableCustomLayouts(PageInterface $page): array
64+
{
65+
return $this->customLayoutManager->fetchAvailableFiles($page);
66+
}
67+
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Cms\Test\Unit\Model\Page\Service;
9+
10+
use Magento\Cms\Api\Data\PageInterface;
11+
use Magento\Cms\Api\PageRepositoryInterface;
12+
use Magento\Cms\Model\Page\CustomLayoutManagerInterface;
13+
use Magento\Cms\Model\Page\Service\PageService;
14+
use Magento\Cms\Model\PageFactory;
15+
use Magento\Framework\Exception\LocalizedException;
16+
use Magento\Framework\Exception\NoSuchEntityException;
17+
use PHPUnit\Framework\MockObject\MockObject;
18+
use PHPUnit\Framework\TestCase;
19+
20+
/**
21+
* Unit tests for PageService
22+
*/
23+
class PageServiceTest extends TestCase
24+
{
25+
/**
26+
* @var PageRepositoryInterface|MockObject
27+
*/
28+
private $pageRepositoryMock;
29+
30+
/**
31+
* @var PageFactory|MockObject
32+
*/
33+
private $pageFactoryMock;
34+
35+
/**
36+
* @var CustomLayoutManagerInterface|MockObject
37+
*/
38+
private $customLayoutManagerMock;
39+
40+
/**
41+
* @var PageService
42+
*/
43+
private $pageService;
44+
45+
/**
46+
* @var PageInterface|MockObject
47+
*/
48+
private $pageMock;
49+
50+
/**
51+
* Set up test environment
52+
*/
53+
protected function setUp(): void
54+
{
55+
$this->pageRepositoryMock = $this->createMock(PageRepositoryInterface::class);
56+
$this->pageFactoryMock = $this->createMock(PageFactory::class);
57+
$this->customLayoutManagerMock = $this->createMock(CustomLayoutManagerInterface::class);
58+
$this->pageMock = $this->createMock(PageInterface::class);
59+
60+
$this->pageService = new PageService(
61+
$this->pageRepositoryMock,
62+
$this->pageFactoryMock,
63+
$this->customLayoutManagerMock
64+
);
65+
}
66+
67+
/**
68+
* Test getPageById returns existing page when page exists
69+
*/
70+
public function testGetPageByIdReturnsExistingPage(): void
71+
{
72+
$pageId = 1;
73+
74+
$this->pageRepositoryMock->expects($this->once())
75+
->method('getById')
76+
->with($pageId)
77+
->willReturn($this->pageMock);
78+
79+
$this->pageFactoryMock->expects($this->never())
80+
->method('create');
81+
82+
$result = $this->pageService->getPageById($pageId);
83+
84+
$this->assertSame($this->pageMock, $result);
85+
}
86+
87+
/**
88+
* Test getPageById returns new page instance when page doesn't exist
89+
*/
90+
public function testGetPageByIdReturnsNewPageWhenNotExists(): void
91+
{
92+
$pageId = 999;
93+
$newPageMock = $this->createMock(PageInterface::class);
94+
95+
$this->pageRepositoryMock->expects($this->once())
96+
->method('getById')
97+
->with($pageId)
98+
->willThrowException(new NoSuchEntityException(__('Page not found')));
99+
100+
$this->pageFactoryMock->expects($this->once())
101+
->method('create')
102+
->willReturn($newPageMock);
103+
104+
$result = $this->pageService->getPageById($pageId);
105+
106+
$this->assertSame($newPageMock, $result);
107+
}
108+
109+
/**
110+
* Test getPageById handles LocalizedException and returns new page
111+
*/
112+
public function testGetPageByIdHandlesLocalizedException(): void
113+
{
114+
$pageId = 1;
115+
$newPageMock = $this->createMock(PageInterface::class);
116+
117+
$this->pageRepositoryMock->expects($this->once())
118+
->method('getById')
119+
->with($pageId)
120+
->willThrowException(new LocalizedException(__('Some localized error')));
121+
122+
$this->pageFactoryMock->expects($this->once())
123+
->method('create')
124+
->willReturn($newPageMock);
125+
126+
$result = $this->pageService->getPageById($pageId);
127+
128+
$this->assertSame($newPageMock, $result);
129+
}
130+
131+
/**
132+
* Test createPageFactory returns new page instance
133+
*/
134+
public function testCreatePageFactory(): void
135+
{
136+
$newPageMock = $this->createMock(PageInterface::class);
137+
138+
$this->pageFactoryMock->expects($this->once())
139+
->method('create')
140+
->willReturn($newPageMock);
141+
142+
$result = $this->pageService->createPageFactory();
143+
144+
$this->assertSame($newPageMock, $result);
145+
}
146+
147+
/**
148+
* Test fetchAvailableCustomLayouts returns available layouts
149+
*/
150+
public function testFetchAvailableCustomLayouts(): void
151+
{
152+
$expectedLayouts = [
153+
'layout1.xml',
154+
'layout2.xml',
155+
'custom_layout.xml'
156+
];
157+
158+
$this->customLayoutManagerMock->expects($this->once())
159+
->method('fetchAvailableFiles')
160+
->with($this->pageMock)
161+
->willReturn($expectedLayouts);
162+
163+
$result = $this->pageService->fetchAvailableCustomLayouts($this->pageMock);
164+
165+
$this->assertSame($expectedLayouts, $result);
166+
}
167+
168+
/**
169+
* Test fetchAvailableCustomLayouts returns empty array when no layouts available
170+
*/
171+
public function testFetchAvailableCustomLayoutsReturnsEmptyArray(): void
172+
{
173+
$this->customLayoutManagerMock->expects($this->once())
174+
->method('fetchAvailableFiles')
175+
->with($this->pageMock)
176+
->willReturn([]);
177+
178+
$result = $this->pageService->fetchAvailableCustomLayouts($this->pageMock);
179+
180+
$this->assertSame([], $result);
181+
}
182+
}

0 commit comments

Comments
 (0)