Skip to content

Commit d1d4a49

Browse files
authored
Merge pull request #272 from magento-obsessive-owls/1.0-develop-sync-1.0.2
Create 1.0.2-release
2 parents 3325c36 + f15c1d4 commit d1d4a49

File tree

185 files changed

+3804
-2302
lines changed

Some content is hidden

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

185 files changed

+3804
-2302
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# CODEOWNERS file for /docs/ folder.
2+
# Forces a review from other writers for anything within /docs/.
3+
/docs/ @magento/devdocs-admins

README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Use this access to:
99

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

12+
## Documentation
13+
14+
Please use this link to access the latest Page Builder documentation: https://devdocs.magento.com/page-builder/docs/index.html
15+
1216
## GitHub installation only
1317

1418
**The pre-release version of Page Builder MUST be installed by cloning the GitHub repos as described here.**
@@ -43,11 +47,6 @@ Before installing Page Builder, make sure you have:
4347
bin/magento setup:upgrade
4448
```
4549

46-
## Developer documentation
47-
48-
We will update the developer documentation frequently during beta. Please use this link to access the latest updates: 
49-
[Page Builder developer documentation](https://devdocs.magedevteam.com/72/page-builder/docs/getting-started/introduction.html)
50-
5150
## Contribute to Page Builder
5251

5352
We appreciate any and all contributions to Page Builder. If you are interested in contributing to this repository, please see our [Contribution Guide].
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\PageBuilder\Block\Adminhtml\Stage;
10+
11+
use Magento\Framework\View\Element\Template;
12+
use Magento\RequireJs\Model\FileManager;
13+
use Magento\PageBuilder\Model\Stage\Config;
14+
use Magento\Framework\Serialize\Serializer\Json;
15+
16+
/**
17+
* Class Render
18+
*/
19+
class Render extends Template
20+
{
21+
/**
22+
* @var FileManager
23+
*/
24+
private $fileManager;
25+
26+
/**
27+
* @var Config
28+
*/
29+
private $pageBuilderConfig;
30+
31+
/**
32+
* @var Json
33+
*/
34+
private $json;
35+
36+
/**
37+
* @param Template\Context $context
38+
* @param FileManager $fileManager
39+
* @param Config $config
40+
* @param Json $json
41+
* @param array $data
42+
*/
43+
public function __construct(
44+
Template\Context $context,
45+
FileManager $fileManager,
46+
Config $config,
47+
Json $json,
48+
array $data = []
49+
) {
50+
parent::__construct($context, $data);
51+
$this->fileManager = $fileManager;
52+
$this->pageBuilderConfig = $config;
53+
$this->json = $json;
54+
}
55+
56+
/**
57+
* Generate the URL to RequireJS
58+
*
59+
* @return string
60+
* @throws \Magento\Framework\Exception\LocalizedException
61+
*/
62+
public function getRequireJsUrl() : string
63+
{
64+
$asset = $this->_assetRepo->createAsset('requirejs/require.js');
65+
return $asset->getUrl();
66+
}
67+
68+
/**
69+
* Retrieve the URL to the RequireJS Config file
70+
*
71+
* @return string
72+
*/
73+
public function getRequireJsConfigUrl() : string
74+
{
75+
$requireJsConfig = $this->fileManager->createRequireJsConfigAsset();
76+
return $requireJsConfig->getUrl();
77+
}
78+
79+
/**
80+
* Retrieve the Page Builder's config
81+
*
82+
* @return array
83+
*/
84+
public function getPageBuilderConfig() : string
85+
{
86+
return $this->json->serialize($this->pageBuilderConfig->getConfig());
87+
}
88+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
*
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
8+
namespace Magento\PageBuilder\Controller\Adminhtml\Stage;
9+
10+
use Magento\Framework\App\Action\HttpGetActionInterface;
11+
use Magento\RequireJs\Block\Html\Head\Config;
12+
13+
/**
14+
* Class Render
15+
*
16+
* Iframe to render Page Builder stage in isolation
17+
*/
18+
class Render extends \Magento\Backend\App\Action implements HttpGetActionInterface
19+
{
20+
const ADMIN_RESOURCE = 'Magento_Backend::content';
21+
22+
/**
23+
* Render the RequireJS and Page Builder render blocks without any additional layout
24+
*
25+
* @return void
26+
*/
27+
public function execute()
28+
{
29+
$layout = $this->_view->getLayout();
30+
$requireJs = $layout->createBlock(
31+
\Magento\Backend\Block\Page\RequireJs::class,
32+
'require.js'
33+
);
34+
$requireJs->setTemplate('Magento_Backend::page/js/require_js.phtml');
35+
/* @var \Magento\PageBuilder\Block\Adminhtml\Stage\Render $renderBlock */
36+
$renderBlock = $layout->createBlock(
37+
\Magento\PageBuilder\Block\Adminhtml\Stage\Render::class,
38+
'stage_render'
39+
);
40+
$renderBlock->setTemplate('Magento_PageBuilder::stage/render.phtml');
41+
$babelPolyfill = $layout->createBlock(
42+
\Magento\PageBuilder\Block\Adminhtml\Html\Head\BabelPolyfill::class,
43+
'pagebuilder.babel.polyfill'
44+
);
45+
$babelPolyfill->setTemplate('Magento_PageBuilder::html/head/babel_polyfill.phtml');
46+
$this->getResponse()->setBody($requireJs->toHtml() . $babelPolyfill->toHtml() . $renderBlock->toHtml());
47+
$this->getResponse()->sendResponse();
48+
}
49+
}

app/code/Magento/PageBuilder/Controller/ContentType/Preview.php

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,28 @@ class Preview extends \Magento\Framework\App\Action\Action implements HttpPostAc
2626
*/
2727
private $rendererPool;
2828

29+
/**
30+
* @var \Magento\Backend\Model\Auth
31+
*/
32+
private $auth;
33+
2934
/**
3035
* Constructor
3136
*
3237
* @param \Magento\Backend\App\Action\Context $context
3338
* @param \Magento\PageBuilder\Model\Stage\RendererPool $rendererPool
39+
* @param \Magento\Backend\Model\Auth $auth
3440
*/
3541
public function __construct(
3642
\Magento\Backend\App\Action\Context $context,
37-
\Magento\PageBuilder\Model\Stage\RendererPool $rendererPool
43+
\Magento\PageBuilder\Model\Stage\RendererPool $rendererPool,
44+
\Magento\Backend\Model\Auth $auth = null
3845
) {
3946
parent::__construct($context);
4047

4148
$this->rendererPool = $rendererPool;
49+
$this->auth = $auth ?? \Magento\Framework\App\ObjectManager::getInstance()
50+
->get(\Magento\Backend\Model\Auth::class);
4251
}
4352

4453
/**
@@ -48,14 +57,18 @@ public function __construct(
4857
*/
4958
public function execute()
5059
{
51-
$pageResult = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
52-
// Some template filters and directive processors expect this to be called in order to function.
53-
$pageResult->initLayout();
60+
if ($this->auth->isLoggedIn()) {
61+
$pageResult = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
62+
// Some template filters and directive processors expect this to be called in order to function.
63+
$pageResult->initLayout();
64+
65+
$params = $this->getRequest()->getParams();
66+
$renderer = $this->rendererPool->getRenderer($params['role']);
67+
$result = ['data' => $renderer->render($params)];
5468

55-
$params = $this->getRequest()->getParams();
56-
$renderer = $this->rendererPool->getRenderer($params['role']);
57-
$result = ['data' => $renderer->render($params)];
69+
return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
70+
}
5871

59-
return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
72+
$this->_forward('noroute');
6073
}
6174
}

app/code/Magento/PageBuilder/Model/Stage/Config.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ public function getConfig()
135135
'content_types' => $this->getContentTypes(),
136136
'stage_config' => $this->data,
137137
'media_url' => $this->urlBuilder->getBaseUrl(['_type' => UrlInterface::URL_TYPE_MEDIA]),
138-
'preview_url' => $this->frontendUrlBuilder->getUrl('pagebuilder/contenttype/preview'),
138+
'preview_url' => $this->frontendUrlBuilder
139+
->addSessionParam()
140+
->getUrl('pagebuilder/contenttype/preview'),
141+
'render_url' => $this->urlBuilder->getUrl('pagebuilder/stage/render'),
139142
'column_grid_default' => $this->scopeConfig->getValue(self::XML_PATH_COLUMN_GRID_DEFAULT),
140143
'column_grid_max' => $this->scopeConfig->getValue(self::XML_PATH_COLUMN_GRID_MAX),
141144
'can_use_inline_editing_on_stage' => $this->isWysiwygProvisionedForEditingOnStage(),

app/code/Magento/PageBuilder/Model/Stage/HtmlFilter.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,28 @@ public function filterHtml(string $content): string
4949
$this->loggerInterface->critical($e->getMessage());
5050
}
5151
libxml_use_internal_errors($previous);
52-
// Remove all <script /> tags from output
53-
foreach (iterator_to_array($dom->getElementsByTagName('script')) as $item) {
54-
$item->parentNode->removeChild($item);
52+
// Remove all <script /> tags, on* attributes from output
53+
/** @var \DOMElement $item */
54+
foreach (iterator_to_array($dom->getElementsByTagName('*')) as $item) {
55+
if (in_array($item->tagName, ['script', 'meta', 'embed', 'object'])) {
56+
$item->parentNode->removeChild($item);
57+
} else {
58+
foreach (iterator_to_array($item->attributes) as $attribute) {
59+
if (stripos($attribute->name, 'on') === 0 ||
60+
stripos(ltrim($attribute->value), 'javascript') === 0
61+
) {
62+
$item->removeAttribute($attribute->name);
63+
}
64+
}
65+
}
5566
}
5667
$xpath = new \DOMXPath($dom);
5768
$htmlContentTypes = $xpath->query(
5869
'//*[@data-content-type="html" and not(contains(@class, "placeholder-html-code"))]'
5970
);
6071
foreach ($htmlContentTypes as $htmlContentType) {
6172
/* @var \DOMElement $htmlContentType */
62-
$innerHTML= '';
73+
$innerHTML = '';
6374
$children = $htmlContentType->childNodes;
6475
foreach ($children as $child) {
6576
$innerHTML .= $child->ownerDocument->saveXML($child);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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\PageBuilder\Plugin\Filter;
9+
10+
use Magento\Store\Model\Store;
11+
use Magento\Framework\Escaper;
12+
13+
/**
14+
* Plugin to the template filter to escape custom variable directives
15+
*/
16+
class CustomVarTemplate
17+
{
18+
/**
19+
* @var Escaper
20+
*/
21+
private $escaper;
22+
23+
/**
24+
* @param Escaper $escaper
25+
*/
26+
public function __construct(
27+
Escaper $escaper
28+
) {
29+
$this->escaper = $escaper;
30+
}
31+
32+
/**
33+
* Determine if custom variable within a Page Builder CMS Block directive's return value needs to be escaped
34+
*
35+
* @param \Magento\Email\Model\Template\Filter $subject
36+
* @param string $result
37+
* @return string
38+
*/
39+
public function afterCustomvarDirective(
40+
\Magento\Email\Model\Template\Filter $subject,
41+
$result
42+
) {
43+
// Determine the need to escape the return value of observed method.
44+
// Admin context requires store ID of 0; in that context return value should be escaped
45+
$shouldEscape = $subject->getStoreId() !== null && (int) $subject->getStoreId() === Store::DEFAULT_STORE_ID;
46+
47+
if ($shouldEscape) {
48+
return $this->escaper->escapeHtml($result);
49+
} else {
50+
return $result;
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)