Skip to content

Commit 652a231

Browse files
ENGCOM-3683: Images in XML sitemap are always linked to base store in multistore on Schedule #19598
- Merge Pull Request #19598 from Nazar65/magento2:issue-19596 - Merged commits: 1. d5b0ffd 2. 16f11f7 3. c8afe9f 4. fda07a2 5. 5c7527e 6. d2d04b6 7. b88fa48 8. 85a2a56 9. a04cbf2
2 parents 9c36f6f + a04cbf2 commit 652a231

File tree

4 files changed

+323
-131
lines changed

4 files changed

+323
-131
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types = 1);
7+
8+
namespace Magento\Sitemap\Model;
9+
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Framework\Translate\Inline\StateInterface;
12+
use Magento\Framework\Mail\Template\TransportBuilder;
13+
use Magento\Store\Model\ScopeInterface;
14+
use Magento\Backend\App\Area\FrontNameResolver;
15+
use Magento\Sitemap\Model\Observer as Observer;
16+
use Psr\Log\LoggerInterface;
17+
18+
/**
19+
* Sends emails for the scheduled generation of the sitemap file
20+
*/
21+
class EmailNotification
22+
{
23+
/**
24+
* @var \Magento\Framework\Translate\Inline\StateInterface
25+
*/
26+
private $inlineTranslation;
27+
28+
/**
29+
* Core store config
30+
*
31+
* @var \Magento\Framework\App\Config\ScopeConfigInterface
32+
*/
33+
private $scopeConfig;
34+
35+
/**
36+
* @var \Magento\Framework\Mail\Template\TransportBuilder
37+
*/
38+
private $transportBuilder;
39+
40+
/**
41+
* @var \Psr\Log\LoggerInterface $logger
42+
*/
43+
private $logger;
44+
45+
/**
46+
* EmailNotification constructor.
47+
* @param StateInterface $inlineTranslation
48+
* @param TransportBuilder $transportBuilder
49+
* @param ScopeConfigInterface $scopeConfig
50+
* @param LoggerInterface $logger
51+
*/
52+
public function __construct(
53+
StateInterface $inlineTranslation,
54+
TransportBuilder $transportBuilder,
55+
ScopeConfigInterface $scopeConfig,
56+
LoggerInterface $logger
57+
) {
58+
$this->inlineTranslation = $inlineTranslation;
59+
$this->scopeConfig = $scopeConfig;
60+
$this->transportBuilder = $transportBuilder;
61+
$this->logger = $logger;
62+
}
63+
64+
/**
65+
* Send's error email if sitemap generated with errors.
66+
*
67+
* @param array| $errors
68+
*/
69+
public function sendErrors($errors)
70+
{
71+
$this->inlineTranslation->suspend();
72+
try {
73+
$this->transportBuilder->setTemplateIdentifier(
74+
$this->scopeConfig->getValue(
75+
Observer::XML_PATH_ERROR_TEMPLATE,
76+
ScopeInterface::SCOPE_STORE
77+
)
78+
)->setTemplateOptions(
79+
[
80+
'area' => FrontNameResolver::AREA_CODE,
81+
'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
82+
]
83+
)->setTemplateVars(
84+
['warnings' => join("\n", $errors)]
85+
)->setFrom(
86+
$this->scopeConfig->getValue(
87+
Observer::XML_PATH_ERROR_IDENTITY,
88+
ScopeInterface::SCOPE_STORE
89+
)
90+
)->addTo(
91+
$this->scopeConfig->getValue(
92+
Observer::XML_PATH_ERROR_RECIPIENT,
93+
ScopeInterface::SCOPE_STORE
94+
)
95+
);
96+
97+
$transport = $this->transportBuilder->getTransport();
98+
$transport->sendMessage();
99+
} catch (\Exception $e) {
100+
$this->logger->error('Sitemap sendErrors: '.$e->getMessage());
101+
} finally {
102+
$this->inlineTranslation->resume();
103+
}
104+
}
105+
}

app/code/Magento/Sitemap/Model/Observer.php

Lines changed: 42 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
*/
66
namespace Magento\Sitemap\Model;
77

8+
use Magento\Store\Model\App\Emulation;
9+
use Magento\Sitemap\Model\EmailNotification as SitemapEmail;
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory;
12+
use Magento\Store\Model\ScopeInterface;
13+
814
/**
915
* Sitemap module observer
1016
*
@@ -44,47 +50,40 @@ class Observer
4450
*
4551
* @var \Magento\Framework\App\Config\ScopeConfigInterface
4652
*/
47-
protected $_scopeConfig;
53+
private $scopeConfig;
4854

4955
/**
5056
* @var \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory
5157
*/
52-
protected $_collectionFactory;
53-
54-
/**
55-
* @var \Magento\Framework\Mail\Template\TransportBuilder
56-
*/
57-
protected $_transportBuilder;
58+
private $collectionFactory;
5859

5960
/**
60-
* @var \Magento\Store\Model\StoreManagerInterface
61+
* @var Emulation
6162
*/
62-
protected $_storeManager;
63+
private $appEmulation;
6364

6465
/**
65-
* @var \Magento\Framework\Translate\Inline\StateInterface
66+
* @var $emailNotification
6667
*/
67-
protected $inlineTranslation;
68+
private $emailNotification;
6869

6970
/**
70-
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
71-
* @param \Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory $collectionFactory
72-
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
73-
* @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
74-
* @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
71+
* Observer constructor.
72+
* @param ScopeConfigInterface $scopeConfig
73+
* @param CollectionFactory $collectionFactory
74+
* @param EmailNotification $emailNotification
75+
* @param Emulation $appEmulation
7576
*/
7677
public function __construct(
77-
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
78-
\Magento\Sitemap\Model\ResourceModel\Sitemap\CollectionFactory $collectionFactory,
79-
\Magento\Store\Model\StoreManagerInterface $storeManager,
80-
\Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
81-
\Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
78+
ScopeConfigInterface $scopeConfig,
79+
CollectionFactory $collectionFactory,
80+
SitemapEmail $emailNotification,
81+
Emulation $appEmulation
8282
) {
83-
$this->_scopeConfig = $scopeConfig;
84-
$this->_collectionFactory = $collectionFactory;
85-
$this->_storeManager = $storeManager;
86-
$this->_transportBuilder = $transportBuilder;
87-
$this->inlineTranslation = $inlineTranslation;
83+
$this->scopeConfig = $scopeConfig;
84+
$this->collectionFactory = $collectionFactory;
85+
$this->appEmulation = $appEmulation;
86+
$this->emailNotification = $emailNotification;
8887
}
8988

9089
/**
@@ -97,61 +96,39 @@ public function __construct(
9796
public function scheduledGenerateSitemaps()
9897
{
9998
$errors = [];
100-
99+
$recipient = $this->scopeConfig->getValue(
100+
Observer::XML_PATH_ERROR_RECIPIENT,
101+
ScopeInterface::SCOPE_STORE
102+
);
101103
// check if scheduled generation enabled
102-
if (!$this->_scopeConfig->isSetFlag(
104+
if (!$this->scopeConfig->isSetFlag(
103105
self::XML_PATH_GENERATION_ENABLED,
104-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
106+
ScopeInterface::SCOPE_STORE
105107
)
106108
) {
107109
return;
108110
}
109111

110-
$collection = $this->_collectionFactory->create();
112+
$collection = $this->collectionFactory->create();
111113
/* @var $collection \Magento\Sitemap\Model\ResourceModel\Sitemap\Collection */
112114
foreach ($collection as $sitemap) {
113115
/* @var $sitemap \Magento\Sitemap\Model\Sitemap */
114116
try {
117+
$this->appEmulation->startEnvironmentEmulation(
118+
$sitemap->getStoreId(),
119+
\Magento\Framework\App\Area::AREA_FRONTEND,
120+
true
121+
);
122+
115123
$sitemap->generateXml();
116124
} catch (\Exception $e) {
117125
$errors[] = $e->getMessage();
126+
} finally {
127+
$this->appEmulation->stopEnvironmentEmulation();
118128
}
119129
}
120-
121-
if ($errors && $this->_scopeConfig->getValue(
122-
self::XML_PATH_ERROR_RECIPIENT,
123-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
124-
)
125-
) {
126-
$this->inlineTranslation->suspend();
127-
128-
$this->_transportBuilder->setTemplateIdentifier(
129-
$this->_scopeConfig->getValue(
130-
self::XML_PATH_ERROR_TEMPLATE,
131-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
132-
)
133-
)->setTemplateOptions(
134-
[
135-
'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
136-
'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
137-
]
138-
)->setTemplateVars(
139-
['warnings' => join("\n", $errors)]
140-
)->setFrom(
141-
$this->_scopeConfig->getValue(
142-
self::XML_PATH_ERROR_IDENTITY,
143-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
144-
)
145-
)->addTo(
146-
$this->_scopeConfig->getValue(
147-
self::XML_PATH_ERROR_RECIPIENT,
148-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
149-
)
150-
);
151-
$transport = $this->_transportBuilder->getTransport();
152-
$transport->sendMessage();
153-
154-
$this->inlineTranslation->resume();
130+
if ($errors && $recipient) {
131+
$this->emailNotification->sendErrors($errors);
155132
}
156133
}
157134
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types = 1);
7+
8+
namespace Magento\Sitemap\Test\Unit\Model;
9+
10+
use Magento\Backend\App\Area\FrontNameResolver;
11+
use Magento\Framework\App\Config\ScopeConfigInterface;
12+
use Magento\Framework\Mail\Template\TransportBuilder;
13+
use Magento\Framework\Mail\TransportInterface;
14+
use Magento\Framework\ObjectManagerInterface;
15+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
16+
use Magento\Framework\Translate\Inline\StateInterface;
17+
use Magento\Sitemap\Model\EmailNotification;
18+
use Magento\Sitemap\Model\Observer;
19+
use Magento\Store\Model\ScopeInterface;
20+
use Magento\Store\Model\Store;
21+
use PHPUnit\Framework\TestCase;
22+
23+
/**
24+
* Test for Magento\Sitemap\Model\EmailNotification
25+
*/
26+
class EmailNotificationTest extends TestCase
27+
{
28+
/**
29+
* @var ObjectManager
30+
*/
31+
private $objectManager;
32+
33+
/**
34+
* @var EmailNotification
35+
*/
36+
private $model;
37+
38+
/**
39+
* @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
40+
*/
41+
private $scopeConfigMock;
42+
43+
/**
44+
* @var TransportBuilder|\PHPUnit_Framework_MockObject_MockObject
45+
*/
46+
private $transportBuilderMock;
47+
48+
/**
49+
* @var StateInterface|\PHPUnit_Framework_MockObject_MockObject
50+
*/
51+
private $inlineTranslationMock;
52+
53+
/**
54+
* @var ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
55+
*/
56+
private $objectManagerMock;
57+
58+
protected function setUp()
59+
{
60+
$this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class)
61+
->getMock();
62+
$this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
63+
->getMock();
64+
$this->transportBuilderMock = $this->getMockBuilder(TransportBuilder::class)
65+
->disableOriginalConstructor()
66+
->getMock();
67+
$this->inlineTranslationMock = $this->getMockBuilder(StateInterface::class)
68+
->getMock();
69+
70+
$this->objectManager = new ObjectManager($this);
71+
$this->model = $this->objectManager->getObject(
72+
EmailNotification::class,
73+
[
74+
'inlineTranslation' => $this->inlineTranslationMock,
75+
'scopeConfig' => $this->scopeConfigMock,
76+
'transportBuilder' => $this->transportBuilderMock,
77+
]
78+
);
79+
}
80+
81+
public function testSendErrors()
82+
{
83+
$exception = 'Sitemap Exception';
84+
$transport = $this->createMock(TransportInterface::class);
85+
86+
$this->scopeConfigMock->expects($this->at(0))
87+
->method('getValue')
88+
->with(
89+
Observer::XML_PATH_ERROR_TEMPLATE,
90+
ScopeInterface::SCOPE_STORE
91+
)
92+
->willReturn('error-recipient@example.com');
93+
94+
$this->inlineTranslationMock->expects($this->once())
95+
->method('suspend');
96+
97+
$this->transportBuilderMock->expects($this->once())
98+
->method('setTemplateIdentifier')
99+
->will($this->returnSelf());
100+
101+
$this->transportBuilderMock->expects($this->once())
102+
->method('setTemplateOptions')
103+
->with([
104+
'area' => FrontNameResolver::AREA_CODE,
105+
'store' => Store::DEFAULT_STORE_ID,
106+
])
107+
->will($this->returnSelf());
108+
109+
$this->transportBuilderMock->expects($this->once())
110+
->method('setTemplateVars')
111+
->with(['warnings' => $exception])
112+
->will($this->returnSelf());
113+
114+
$this->transportBuilderMock->expects($this->once())
115+
->method('setFrom')
116+
->will($this->returnSelf());
117+
118+
$this->transportBuilderMock->expects($this->once())
119+
->method('addTo')
120+
->will($this->returnSelf());
121+
122+
$this->transportBuilderMock->expects($this->once())
123+
->method('getTransport')
124+
->willReturn($transport);
125+
126+
$transport->expects($this->once())
127+
->method('sendMessage');
128+
129+
$this->inlineTranslationMock->expects($this->once())
130+
->method('resume');
131+
132+
$this->model->sendErrors(['Sitemap Exception']);
133+
}
134+
}

0 commit comments

Comments
 (0)