Skip to content

Commit 6f91ddf

Browse files
committed
Merge branch 'develop' into MC-13769
2 parents e64ec70 + 3d071cc commit 6f91ddf

File tree

97 files changed

+3015
-2412
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+3015
-2412
lines changed

README.md

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,44 @@ Use this access to:
99

1010
Should you find an issue in Page Builder functionality, please report it on GitHub.
1111

12+
## GitHub installation only
13+
14+
**The pre-release version of Page Builder MUST be installed by cloning the GitHub repos as described here.**
15+
16+
Before installing Page Builder, make sure you have:
17+
18+
* A local development installation of Magento Commerce 2.3+
19+
* Access to the Page Builder repository
20+
* [npm package manager](https://www.npmjs.com/get-npm)
21+
22+
1. Clone the Page Builder repos into the root directory of your Magento Commerce 2.3+ installation:
23+
24+
```bash
25+
git clone https://github.com/magento/magento2-page-builder
26+
git clone https://github.com/magento/magento2-page-builder-ee
27+
```
28+
29+
2. From the root directory of your Magento Commerce installation, use the `dev/tools/build-ee.php` script to symlink `magento2-page-builder` and `magento2-page-builder-ee` repos into your Magento Commerce installation:
30+
31+
```bash
32+
php dev/tools/build-ee.php --command=link --ee-source="magento2-page-builder" --ce-source="."
33+
php dev/tools/build-ee.php --command=link --ee-source="magento2-page-builder-ee" --ce-source="."
34+
```
35+
36+
The results should look like this:
37+
38+
![Symlinks to Page Builder](docs/images/symlinked-pagebuilder.png)
39+
40+
3. Enable the Page Builder module using the following command:
41+
42+
```bash
43+
bin/magento setup:upgrade
44+
```
45+
1246
## Developer documentation
1347

1448
We will update the developer documentation frequently during beta. Please use this link to access the latest updates: 
15-
[Page Builder developer documentation](https://devdocs.magedevteam.com/ds_pagebuilder/page-builder/getting-started/install-pagebuilder.html)
49+
[Page Builder developer documentation](https://devdocs.magedevteam.com/72/page-builder/docs/getting-started/introduction.html)
1650

1751
## Contribute to Page Builder
1852

app/code/Magento/PageBuilder/Controller/Adminhtml/Form/Element/ProductConditions/Child.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99
namespace Magento\PageBuilder\Controller\Adminhtml\Form\Element\ProductConditions;
1010

11+
use Magento\Framework\App\Action\HttpPostActionInterface;
1112
use Magento\Rule\Model\Condition\AbstractCondition;
1213

1314
/**
1415
* Responsible for rendering the child elements of the conditions rule tree using the provided params
1516
*/
16-
class Child extends \Magento\CatalogWidget\Controller\Adminhtml\Product\Widget
17+
class Child extends \Magento\CatalogWidget\Controller\Adminhtml\Product\Widget implements HttpPostActionInterface
1718
{
1819
/**
1920
* @var \Magento\CatalogWidget\Model\Rule
@@ -33,6 +34,8 @@ public function __construct(
3334
}
3435

3536
/**
37+
* Render child template
38+
*
3639
* @return void
3740
*/
3841
public function execute()
@@ -43,19 +46,25 @@ public function execute()
4346

4447
$typeData = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
4548
$className = $typeData[0];
49+
$prefix = $this->getRequest()->getParam('prefix', 'conditions');
4650

4751
$model = $this->_objectManager->create($className)
4852
->setId($id)
4953
->setType($className)
5054
->setRule($this->rule)
51-
->setPrefix($this->getRequest()->getParam('prefix', 'conditions'));
55+
->setPrefix($prefix);
5256

5357
if (!empty($typeData[1])) {
5458
$model->setAttribute($typeData[1]);
5559
}
5660

5761
$result = '';
5862
if ($model instanceof AbstractCondition) {
63+
// set value of $prefix in model's data registry to value of 'conditions',
64+
// as is required for correct use of \Magento\Rule\Model\Condition\Combine::getConditions
65+
if ($model->getData($prefix) === null) {
66+
$model->setData($prefix, $model->getData('conditions'));
67+
}
5968
$model->setJsFormObject($jsObjectName);
6069
$model->setFormName($formName);
6170
$result = $model->asHtmlRecursive();

app/code/Magento/PageBuilder/Plugin/Filter/TemplatePlugin.php

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\PageBuilder\Plugin\Filter;
99

10+
use Magento\Store\Model\Store;
11+
1012
/**
1113
* Plugin to the template filter to process any background images added by Page Builder
1214
*/
@@ -105,6 +107,32 @@ public function afterFilter(\Magento\Framework\Filter\Template $subject, string
105107
return $result;
106108
}
107109

110+
/**
111+
* Determine if custom variable directive's return value needs to be escaped and do so if true
112+
*
113+
* @param \Magento\Framework\Filter\Template $subject
114+
* @param \Closure $proceed
115+
* @param string[] $construction
116+
* @return string
117+
*/
118+
public function aroundCustomvarDirective(
119+
\Magento\Framework\Filter\Template $subject,
120+
\Closure $proceed,
121+
$construction
122+
) {
123+
// Determine the need to escape the return value of observed method.
124+
// Admin context requires store ID of 0; in that context return value should be escaped
125+
$shouldEscape = $subject->getStoreId() !== null && (int) $subject->getStoreId() === Store::DEFAULT_STORE_ID;
126+
127+
if (!$shouldEscape) {
128+
return $proceed($construction);
129+
}
130+
131+
$result = $proceed($construction);
132+
133+
return htmlspecialchars($result);
134+
}
135+
108136
/**
109137
* Create a DOM document from a given string
110138
*
@@ -180,8 +208,27 @@ private function generateDecodedHtmlPlaceholderMappingInDocument(\DOMDocument $d
180208
continue;
181209
}
182210

211+
// clone html code content type to save reference to its attributes/outerHTML, which we are not going to
212+
// decode
213+
$clonedHtmlContentTypeNode = clone $htmlContentTypeNode;
214+
215+
// clear inner contents of cloned node for replacement later with $decodedInnerHtml using sprintf;
216+
// we want to retain html content type node and avoid doing any manipulation on it
217+
$clonedHtmlContentTypeNode->nodeValue = '%s';
218+
219+
// remove potentially harmful attributes on html content type node itself
220+
while ($htmlContentTypeNode->attributes->length) {
221+
$htmlContentTypeNode->removeAttribute($htmlContentTypeNode->attributes->item(0)->name);
222+
}
223+
224+
// decode outerHTML safely
183225
$preDecodedOuterHtml = $document->saveHTML($htmlContentTypeNode);
184-
$decodedOuterHtml = html_entity_decode($preDecodedOuterHtml);
226+
227+
// clear empty <div> wrapper around outerHTML to replace with $clonedHtmlContentTypeNode
228+
$decodedInnerHtml = preg_replace('#^<[^>]*>|</[^>]*>$#', '', html_entity_decode($preDecodedOuterHtml));
229+
230+
// Use $clonedHtmlContentTypeNode's placeholder to inject decoded inner html
231+
$decodedOuterHtml = sprintf($document->saveHTML($clonedHtmlContentTypeNode), $decodedInnerHtml);
185232

186233
// generate unique node name element to replace with decoded html contents at end of processing;
187234
// goal is to create a document as few times as possible to prevent inadvertent parsing of contents as html

app/code/Magento/PageBuilder/Test/Mftf/ActionGroup/CatalogProductActionGroup.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,20 @@
2020
<waitForPageLoad stepKey="waitForPageBuilderToOpen"/>
2121
<waitForElementVisible selector="{{pageBuilderArea}}{{PageBuilderPanel.layoutMenuSection}}" stepKey="waiForPageBuilderVisible"/>
2222
</actionGroup>
23+
<actionGroup name="expandAdminCategorySection">
24+
<!-- Move to CE -->
25+
<arguments>
26+
<argument name="sectionSelector" defaultValue="{{AdminCategoryContentSection.sectionHeader}}" type="string"/>
27+
<argument name="sectionDependentSelector" defaultValue="{{AdminCategoryContentSection.uploadButton}}" type="string"/>
28+
</arguments>
29+
<scrollToTopOfPage stepKey="scrollToTopOfPage"/>
30+
<waitForElementVisible time="30" selector="{{sectionSelector}}" stepKey="waitForSection"/>
31+
<conditionalClick selector="{{sectionSelector}}" dependentSelector="{{sectionDependentSelector}}" visible="false" stepKey="expandSection"/>
32+
<waitForPageLoad time="30" stepKey="waitForSectionToExpand"/>
33+
</actionGroup>
34+
<actionGroup name="saveCatalogCategory" extends="saveCategoryForm">
35+
<!-- Move to CE: Fix CE action group -->
36+
<waitForElementVisible selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="waitForSaveCategoryButton" before="saveCategory"/>
37+
<waitForPageLoad stepKey="waitForPageLoad" after="saveCategory"/>
38+
</actionGroup>
2339
</actionGroups>

app/code/Magento/PageBuilder/Test/Mftf/ActionGroup/ContentTypeProductsActionGroup.xml

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,41 @@
6161
<grabMultiple selector="{{page.product(index)}}" stepKey="grabProducts"/>
6262
<assertCount stepKey="assertCount" expected="{{count}}" expectedType="int" actualType="variable" actual="grabProducts"/>
6363
</actionGroup>
64-
<actionGroup name="addCategoryConditionToProductsBlock">
64+
<actionGroup name="addConditionToProductConditions">
6565
<arguments>
66-
<argument name="page" defaultValue=""/>
67-
<argument name="category" defaultValue="" type="string"/>
68-
<argument name="conditionIndex" defaultValue="1" type="string"/>
66+
<argument name="conditionType" defaultValue="PageBuilderProductsConditionCategory"/>
67+
<argument name="conditionInput" defaultValue="1" type="string"/>
68+
<argument name="index" defaultValue="1" type="string"/>
69+
</arguments>
70+
<comment userInput="addConditionToProductConditions" stepKey="comment"/>
71+
<waitForElementVisible selector="{{ProductsContentTypeForm.conditionsList}}" stepKey="waitForConditionsToLoad"/>
72+
<waitForElementVisible selector="{{ProductsContentTypeForm.conditionsListAddButton(index)}}" stepKey="waitForAddConditionButton"/>
73+
<click selector="{{ProductsContentTypeForm.conditionsListAddButton(index)}}" stepKey="clickAddConditionButton"/>
74+
<selectOption selector="{{ProductsContentTypeForm.conditionsListAddTypeSelect(index)}}" userInput="{{conditionType.value}}" stepKey="selectConditionType"/>
75+
<waitForPageLoad stepKey="waitForConditionFieldsToLoad"/>
76+
<click selector="{{ProductsContentTypeForm.conditionsListConditionPlaceholder}}" stepKey="revealCategoryInput"/>
77+
<fillField selector="{{ProductsContentTypeForm.conditionsListConditionInput}}" userInput="{{conditionInput}}" stepKey="fillCategoryField"/>
78+
</actionGroup>
79+
<actionGroup name="addConditionsCombinationToProductsAndSetAggregateParameters">
80+
<arguments>
81+
<argument name="aggregatorType" defaultValue="all" type="string"/>
82+
<argument name="booleanValueForAggregator" defaultValue="1" type="string"/>
83+
<argument name="index" defaultValue="1" type="string"/>
6984
</arguments>
70-
<waitForElementVisible selector="{{page.conditionsList}}" stepKey="waitForConditionsToLoad"/>
71-
<click selector="{{page.conditionsListAddButton}}" stepKey="addCondition"/>
72-
<selectOption selector="{{page.conditionsListAddTypeSelect}}" userInput="Magento\CatalogWidget\Model\Rule\Condition\Product|category_ids" stepKey="selectCategoryOption"/>
73-
<waitForLoadingMaskToDisappear stepKey="waitForCategoriesToLoad"/>
74-
<click selector="{{page.conditionsListConditionPlaceholder}}" stepKey="revealCategoryInput"/>
75-
<fillField selector="{{page.conditionsListConditionInput}}" userInput="{{category}}" stepKey="fillCategoryField"/>
85+
<comment userInput="addConditionsCombinationToProductsAndSetAggregateParameters" stepKey="comment"/>
86+
<waitForElementVisible selector="{{ProductsContentTypeForm.conditionsList}}" stepKey="waitForConditionsToLoad"/>
87+
<waitForElementVisible selector="{{ProductsContentTypeForm.conditionsListAddButton(index)}}" stepKey="waitForAddConditionButton"/>
88+
<click selector="{{ProductsContentTypeForm.conditionsListAddButton(index)}}" stepKey="clickAddConditionButton"/>
89+
<selectOption selector="{{ProductsContentTypeForm.conditionsListAddTypeSelect(index)}}" userInput="{{PageBuilderProductsConditionCombination.value}}" stepKey="selectCombinationOption"/>
90+
<waitForPageLoad stepKey="waitForConditionsCombinationTemplateToLoad"/>
91+
<click selector="{{ProductsContentTypeForm.conditionsCombinationAggregateSelector(index)}}" stepKey="clickAggregateType"/>
92+
<selectOption selector="{{ProductsContentTypeForm.conditionsCombinationAggregateSelectorSelect(index)}}" userInput="{{aggregatorType}}" stepKey="selectAggregateType"/>
93+
<waitForPageLoad stepKey="waitForAggregateTypeToLoad"/>
94+
<click selector="{{ProductsContentTypeForm.conditionsListText}}" stepKey="clearOptions"/>
95+
<click selector="{{ProductsContentTypeForm.conditionsCombinationAggregateBooleanSelector(index)}}" stepKey="clickAggregateTypeBoolean"/>
96+
<selectOption selector="{{ProductsContentTypeForm.conditionsCombinationAggregateBooleanSelectorSelect(index)}}" userInput="{{booleanValueForAggregator}}" stepKey="selectAggregateTypeBoolean"/>
97+
<waitForPageLoad stepKey="waitForAggregateTypeBooleanToLoad"/>
98+
<click selector="{{ProductsContentTypeForm.conditionsListText}}" stepKey="clearOptions2"/>
7699
</actionGroup>
77100
<actionGroup name="clickProductImageInProductsOnStorefront">
78101
<arguments>

0 commit comments

Comments
 (0)