Skip to content

Commit a29e974

Browse files
committed
Merge remote-tracking branch 'folks/MAGETWO-67444' into PRS
2 parents 47361f8 + 053d49a commit a29e974

File tree

27 files changed

+466
-156
lines changed

27 files changed

+466
-156
lines changed

app/code/Magento/Cms/Model/ResourceModel/Block/Grid/Collection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Collection extends BlockCollection implements SearchResultInterface
3131
* @param string $eventObject
3232
* @param string $resourceModel
3333
* @param string $model
34-
* @param string|null $connection
34+
* @param \Magento\Framework\DB\Adapter\AdapterInterface|string|null $connection
3535
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
3636
*
3737
* @SuppressWarnings(PHPMD.ExcessiveParameterList)

app/code/Magento/Cms/Model/ResourceModel/Page/Grid/Collection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Collection extends PageCollection implements SearchResultInterface
2828
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
2929
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
3030
* @param mixed|null $mainTable
31-
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $eventPrefix
31+
* @param string $eventPrefix
3232
* @param mixed $eventObject
3333
* @param mixed $resourceModel
3434
* @param string $model

app/code/Magento/Config/Controller/Adminhtml/System/AbstractConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ abstract class AbstractConfig extends \Magento\Backend\App\AbstractAction
3434
/**
3535
* @param \Magento\Backend\App\Action\Context $context
3636
* @param \Magento\Config\Model\Config\Structure $configStructure
37-
* @param $sectionChecker - deprecated
37+
* @param mixed $sectionChecker - deprecated
3838
*/
3939
public function __construct(
4040
\Magento\Backend\App\Action\Context $context,

app/code/Magento/Customer/Block/CustomerData.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,23 @@
1010
*/
1111
class CustomerData extends \Magento\Framework\View\Element\Template
1212
{
13+
/**
14+
* @var array
15+
*/
16+
private $expirableSectionNames;
17+
1318
/**
1419
* @param \Magento\Framework\View\Element\Template\Context $context
1520
* @param array $data
21+
* @param array $expirableSectionNames
1622
*/
1723
public function __construct(
1824
\Magento\Framework\View\Element\Template\Context $context,
19-
array $data = []
25+
array $data = [],
26+
array $expirableSectionNames = []
2027
) {
2128
parent::__construct($context, $data);
29+
$this->expirableSectionNames = $expirableSectionNames;
2230
}
2331

2432
/**
@@ -43,4 +51,26 @@ public function getCustomerDataUrl($route)
4351
{
4452
return $this->getUrl($route, ['_secure' => $this->getRequest()->isSecure()]);
4553
}
54+
55+
/**
56+
* Retrieve lifetime period (in minutes) of the frontend section configuration.
57+
*
58+
* Once this period has expired the corresponding section must be invalidated and reloaded.
59+
*
60+
* @return int section lifetime in minutes
61+
*/
62+
public function getExpirableSectionLifetime()
63+
{
64+
return (int)$this->_scopeConfig->getValue('customer/online_customers/section_data_lifetime');
65+
}
66+
67+
/**
68+
* Retrieve the list of sections that can expire.
69+
*
70+
* @return array
71+
*/
72+
public function getExpirableSectionNames()
73+
{
74+
return array_values($this->expirableSectionNames);
75+
}
4676
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Customer\Test\Unit\Block;
7+
8+
use Magento\Customer\Block\CustomerData;
9+
use Magento\Framework\App\Config\ScopeConfigInterface;
10+
use Magento\Framework\View\Element\Template\Context;
11+
12+
class CustomerDataTest extends \PHPUnit_Framework_TestCase
13+
{
14+
/**
15+
* @var Context|\PHPUnit_Framework_MockObject_MockObject
16+
*/
17+
private $contextMock;
18+
19+
/**
20+
* @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
21+
*/
22+
private $scopeConfigMock;
23+
24+
protected function setUp()
25+
{
26+
$this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)->getMock();
27+
$this->contextMock = $this->getMockBuilder(Context::class)->disableOriginalConstructor()->getMock();
28+
$this->contextMock->expects($this->once())->method('getScopeConfig')->willReturn($this->scopeConfigMock);
29+
}
30+
31+
public function testGetExpirableSectionLifetimeReturnsConfigurationValue()
32+
{
33+
$block = new CustomerData(
34+
$this->contextMock,
35+
[],
36+
[]
37+
);
38+
39+
$this->scopeConfigMock->expects($this->once())
40+
->method('getValue')
41+
->with('customer/online_customers/section_data_lifetime', ScopeConfigInterface::SCOPE_TYPE_DEFAULT, null)
42+
->willReturn('10');
43+
44+
$actualResult = $block->getExpirableSectionLifetime();
45+
$this->assertSame(10, $actualResult);
46+
}
47+
48+
public function testGetExpirableSectionNames()
49+
{
50+
$expectedResult = ['cart'];
51+
$block = new CustomerData(
52+
$this->contextMock,
53+
[],
54+
$expectedResult
55+
);
56+
57+
$this->assertEquals($expectedResult, $block->getExpirableSectionNames());
58+
}
59+
}

app/code/Magento/Customer/etc/adminhtml/system.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@
290290
<label>Online Minutes Interval</label>
291291
<comment>Leave empty for default (15 minutes).</comment>
292292
</field>
293+
<field id="section_data_lifetime" translate="label comment" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
294+
<label>Customer Data Lifetime</label>
295+
<comment>Please specify value in minutes.</comment>
296+
</field>
293297
</group>
294298
</section>
295299
<section id="general">

app/code/Magento/Customer/etc/config.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@
9595
{{depend fax}}F: {{var fax}}|{{/depend}}|
9696
{{depend vat_id}}VAT: {{var vat_id}}{{/depend}}|]]></pdf>
9797
</address_templates>
98+
<online_customers>
99+
<section_data_lifetime>60</section_data_lifetime>
100+
</online_customers>
98101
</customer>
99102
</default>
100103
</config>

app/code/Magento/Customer/etc/frontend/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,11 @@
7070
</argument>
7171
</arguments>
7272
</type>
73+
<type name="Magento\Customer\Block\CustomerData">
74+
<arguments>
75+
<argument name="expirableSectionNames" xsi:type="array">
76+
<item name="cart" xsi:type="string">cart</item>
77+
</argument>
78+
</arguments>
79+
</type>
7380
</config>

app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
<?= /* @noEscape */ $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode([
1111
'*' => ['Magento_Customer/js/customer-data' => [
1212
'sectionLoadUrl' => $block->getCustomerDataUrl('customer/section/load'),
13+
'expirableSectionLifetime' => $block->getExpirableSectionLifetime(),
14+
'expirableSectionNames' => $block->getExpirableSectionNames(),
1315
'cookieLifeTime' => $block->getCookieLifeTime(),
1416
'updateSessionUrl' => $block->getCustomerDataUrl('customer/account/updateSession'),
1517
]],

app/code/Magento/Customer/view/frontend/web/js/customer-data.js

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ define([
197197
privateContentVersion = 'private_content_version',
198198
privateContent = $.cookieStorage.get(privateContentVersion),
199199
localPrivateContent = $.localStorage.get(privateContentVersion),
200-
needVersion = 'need_version';
200+
needVersion = 'need_version',
201+
expiredSectionNames = this.getExpiredSectionNames();
201202

202203
if (privateContent &&
203204
!$.cookieStorage.isSet(privateContentVersion) &&
@@ -213,11 +214,11 @@ define([
213214
}
214215
$.localStorage.set(privateContentVersion, privateContent);
215216
this.reload([], false);
216-
} else if (this.needReload()) {
217+
} else if (expiredSectionNames.length > 0) {
217218
_.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {
218219
buffer.notify(sectionName, sectionData);
219220
});
220-
this.reload(this.getExpiredKeys(), false);
221+
this.reload(expiredSectionNames, false);
221222
} else {
222223
_.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {
223224
buffer.notify(sectionName, sectionData);
@@ -238,57 +239,66 @@ define([
238239
},
239240

240241
/**
241-
* @return {Boolean}
242+
* Retrieve the list of sections that has expired since last page reload.
243+
*
244+
* Sections can expire due to lifetime constraints or due to inconsistent storage information
245+
* (validated by cookie data).
246+
*
247+
* @return {Array}
242248
*/
243-
needReload: function () {
244-
var cookieSections = $.cookieStorage.get('section_data_ids'),
245-
storageVal,
246-
name;
247-
248-
if (typeof cookieSections != 'object') {
249-
return true;
250-
}
249+
getExpiredSectionNames: function () {
250+
var expiredSectionNames = [],
251+
cookieSectionTimestamps = $.cookieStorage.get('section_data_ids') || {},
252+
sectionLifetime = options.expirableSectionLifetime * 60,
253+
currentTimestamp = Math.floor(Date.now() / 1000),
254+
sectionData;
255+
256+
// process sections that can expire due to lifetime constraints
257+
_.each(options.expirableSectionNames, function (sectionName) {
258+
sectionData = storage.get(sectionName);
259+
260+
if (typeof sectionData === 'object' && sectionData['data_id'] + sectionLifetime <= currentTimestamp) {
261+
expiredSectionNames.push(sectionName);
262+
}
263+
});
251264

252-
for (name in cookieSections) {
253-
if (name !== undefined) {
254-
storageVal = storage.get(name);
265+
// process sections that can expire due to storage information inconsistency
266+
_.each(cookieSectionTimestamps, function (cookieSectionTimestamp, sectionName) {
267+
sectionData = storage.get(sectionName);
255268

256-
if (typeof storageVal === 'undefined' || //eslint-disable-line max-depth
257-
typeof storageVal == 'object' && cookieSections[name] > storageVal['data_id']
258-
) {
259-
return true;
260-
}
269+
if (typeof sectionData === 'undefined' ||
270+
typeof sectionData === 'object' &&
271+
cookieSectionTimestamp != sectionData['data_id'] //eslint-disable-line
272+
) {
273+
expiredSectionNames.push(sectionName);
261274
}
262-
}
275+
});
263276

264-
return false;
277+
return _.uniq(expiredSectionNames);
265278
},
266279

267280
/**
281+
* Check if some sections have to be reloaded.
268282
*
269-
* @return {Array}
283+
* @deprecated Use getExpiredSectionNames instead.
284+
*
285+
* @return {Boolean}
270286
*/
271-
getExpiredKeys: function () {
272-
var cookieSections = $.cookieStorage.get('section_data_ids'),
273-
storageVal,
274-
name,
275-
expiredKeys = [];
276-
277-
if (typeof cookieSections != 'object') {
278-
return [];
279-
}
280-
281-
for (name in cookieSections) { //eslint-disable-line guard-for-in
282-
storageVal = storage.get(name);
287+
needReload: function () {
288+
var expiredSectionNames = this.getExpiredSectionNames();
283289

284-
if (typeof storageVal === 'undefined' ||
285-
typeof storageVal == 'object' && cookieSections[name] != storage.get(name)['data_id'] //eslint-disable-line
286-
) {
287-
expiredKeys.push(name);
288-
}
289-
}
290+
return expiredSectionNames.length > 0;
291+
},
290292

291-
return expiredKeys;
293+
/**
294+
* Retrieve the list of expired keys.
295+
*
296+
* @deprecated Use getExpiredSectionNames instead.
297+
*
298+
* @return {Array}
299+
*/
300+
getExpiredKeys: function () {
301+
return this.getExpiredSectionNames();
292302
},
293303

294304
/**

0 commit comments

Comments
 (0)