Skip to content

Commit

Permalink
ENGCOM-8576: FIX Perfomance Issue for Backend EDIT of CMS #30936 #30943
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrieldagama authored Feb 4, 2021
2 parents 0d98fdc + 6effeb4 commit e5208f0
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 88 deletions.
130 changes: 80 additions & 50 deletions app/code/Magento/Cms/Model/Page/DataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
*/
namespace Magento\Cms\Model\Page;

use Magento\Cms\Model\Page;
use Magento\Cms\Api\Data\PageInterface;
use Magento\Cms\Api\PageRepositoryInterface;
use Magento\Cms\Model\PageFactory;
use Magento\Cms\Model\ResourceModel\Page\CollectionFactory;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Ui\DataProvider\Modifier\PoolInterface;
use Magento\Framework\AuthorizationInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Ui\DataProvider\Modifier\PoolInterface;
use Magento\Ui\DataProvider\ModifierPoolDataProvider;
use Psr\Log\LoggerInterface;

/**
* Class DataProvider
* Cms Page DataProvider
*/
class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider
class DataProvider extends ModifierPoolDataProvider
{
/**
* @var \Magento\Cms\Model\ResourceModel\Page\Collection
*/
protected $collection;

/**
* @var DataPersistorInterface
*/
Expand All @@ -33,6 +33,11 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider
*/
protected $loadedData;

/**
* @var PageRepositoryInterface
*/
private $pageRepository;

/**
* @var AuthorizationInterface
*/
Expand All @@ -49,9 +54,14 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider
private $customLayoutManager;

/**
* @var CollectionFactory
* @var PageFactory
*/
private $pageFactory;

/**
* @var LoggerInterface
*/
private $collectionFactory;
private $logger;

/**
* @param string $name
Expand All @@ -65,6 +75,9 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider
* @param AuthorizationInterface|null $auth
* @param RequestInterface|null $request
* @param CustomLayoutManagerInterface|null $customLayoutManager
* @param PageRepositoryInterface|null $pageRepository
* @param PageFactory|null $pageFactory
* @param LoggerInterface|null $logger
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Expand All @@ -78,33 +91,22 @@ public function __construct(
PoolInterface $pool = null,
?AuthorizationInterface $auth = null,
?RequestInterface $request = null,
?CustomLayoutManagerInterface $customLayoutManager = null
?CustomLayoutManagerInterface $customLayoutManager = null,
?PageRepositoryInterface $pageRepository = null,
?PageFactory $pageFactory = null,
?LoggerInterface $logger = null
) {
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool);
$this->collection = $pageCollectionFactory->create();
$this->collectionFactory = $pageCollectionFactory;
$this->dataPersistor = $dataPersistor;
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool);
$this->auth = $auth ?? ObjectManager::getInstance()->get(AuthorizationInterface::class);
$this->meta = $this->prepareMeta($this->meta);
$this->request = $request ?? ObjectManager::getInstance()->get(RequestInterface::class);
$this->customLayoutManager = $customLayoutManager
?? ObjectManager::getInstance()->get(CustomLayoutManagerInterface::class);
}

/**
* Find requested page.
*
* @return Page|null
*/
private function findCurrentPage(): ?Page
{
if ($this->getRequestFieldName() && ($pageId = (int)$this->request->getParam($this->getRequestFieldName()))) {
//Loading data for the collection.
$this->getData();
return $this->collection->getItemById($pageId);
}

return null;
$this->pageRepository = $pageRepository ?? ObjectManager::getInstance()->get(PageRepositoryInterface::class);
$this->pageFactory = $pageFactory ?: ObjectManager::getInstance()->get(PageFactory::class);
$this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
}

/**
Expand All @@ -128,29 +130,53 @@ public function getData()
if (isset($this->loadedData)) {
return $this->loadedData;
}
$this->collection = $this->collectionFactory->create();
$items = $this->collection->getItems();
/** @var $page \Magento\Cms\Model\Page */
foreach ($items as $page) {
$this->loadedData[$page->getId()] = $page->getData();
if ($page->getCustomLayoutUpdateXml() || $page->getLayoutUpdateXml()) {
//Deprecated layout update exists.
$this->loadedData[$page->getId()]['layout_update_selected'] = '_existing_';

$page = $this->getCurrentPage();
$this->loadedData[$page->getId()] = $page->getData();
if ($page->getCustomLayoutUpdateXml() || $page->getLayoutUpdateXml()) {
//Deprecated layout update exists.
$this->loadedData[$page->getId()]['layout_update_selected'] = '_existing_';
}

return $this->loadedData;
}

/**
* Return current page
*
* @return PageInterface
*/
private function getCurrentPage(): PageInterface
{
$pageId = $this->getPageId();
if ($pageId) {
try {
$page = $this->pageRepository->getById($pageId);
} catch (LocalizedException $exception) {
$page = $this->pageFactory->create();
}

return $page;
}

$data = $this->dataPersistor->get('cms_page');
if (!empty($data)) {
$page = $this->collection->getNewEmptyItem();
$page->setData($data);
$this->loadedData[$page->getId()] = $page->getData();
if ($page->getCustomLayoutUpdateXml() || $page->getLayoutUpdateXml()) {
$this->loadedData[$page->getId()]['layout_update_selected'] = '_existing_';
}
$this->dataPersistor->clear('cms_page');
if (empty($data)) {
return $this->pageFactory->create();
}
$this->dataPersistor->clear('cms_page');

return $this->loadedData;
return $this->pageFactory->create()
->setData($data);
}

/**
* Returns current page id from request
*
* @return int
*/
private function getPageId(): int
{
return (int) $this->request->getParam($this->getRequestFieldName());
}

/**
Expand Down Expand Up @@ -186,16 +212,20 @@ public function getMeta()

//List of custom layout files available for current page.
$options = [['label' => 'No update', 'value' => '_no_update_']];
if ($page = $this->findCurrentPage()) {
//We must have a specific page selected.
//If custom layout XML is set then displaying this special option.

$page = null;
try {
$page = $this->pageRepository->getById($this->getPageId());
if ($page->getCustomLayoutUpdateXml() || $page->getLayoutUpdateXml()) {
$options[] = ['label' => 'Use existing layout update XML', 'value' => '_existing_'];
}
foreach ($this->customLayoutManager->fetchAvailableFiles($page) as $layoutFile) {
$options[] = ['label' => $layoutFile, 'value' => $layoutFile];
}
} catch (LocalizedException $e) {
$this->logger->error($e->getMessage());
}

$customLayoutMeta = [
'design' => [
'children' => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
namespace Magento\Cms\Model\Page;

use Magento\Cms\Api\GetPageByIdentifierInterface;
use Magento\Framework\App\Request\Http as HttpRequest;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\TestFramework\Cms\Model\CustomLayoutManager;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;
use Magento\Cms\Model\Page as PageModel;
use Magento\Framework\App\Request\Http as HttpRequest;

/**
* Test pages data provider.
Expand All @@ -22,6 +23,12 @@
*/
class DataProviderTest extends TestCase
{
private $providerData = [
'name' => 'test',
'primaryFieldName' => 'page_id',
'requestFieldName' => 'page_id',
];

/**
* @var DataProvider
*/
Expand All @@ -42,59 +49,69 @@ class DataProviderTest extends TestCase
*/
private $request;

/**
* @var ObjectManagerInterface
*/
private $objectManager;

/**
* @inheritDoc
*/
protected function setUp(): void
{
$objectManager = Bootstrap::getObjectManager();
$objectManager->configure([
'preferences' => [
\Magento\Cms\Model\Page\CustomLayoutManagerInterface::class =>
\Magento\TestFramework\Cms\Model\CustomLayoutManager::class
]
$this->objectManager = Bootstrap::getObjectManager();
$this->objectManager->configure([
'preferences' => [CustomLayoutManagerInterface::class => CustomLayoutManager::class]
]);
$this->repo = $objectManager->get(GetPageByIdentifierInterface::class);
$this->filesFaker = $objectManager->get(CustomLayoutManager::class);
$this->request = $objectManager->get(HttpRequest::class);
$this->provider = $objectManager->create(
$this->repo = $this->objectManager->get(GetPageByIdentifierInterface::class);
$this->filesFaker = $this->objectManager->get(CustomLayoutManager::class);
$this->request = $this->objectManager->get(HttpRequest::class);
$this->provider = $this->objectManager->create(
DataProvider::class,
[
'name' => 'test',
'primaryFieldName' => 'page_id',
'requestFieldName' => 'page_id',
'customLayoutManager' => $this->filesFaker
]
array_merge($this->providerData, ['customLayoutManager' => $this->filesFaker])
);
}

/**
* Check that custom layout date is handled properly.
*
* @magentoDataFixture Magento/Cms/_files/pages_with_layout_xml.php
* @throws \Throwable
* @dataProvider customLayoutDataProvider
*
* @param string $identifier
* @param string|null $layoutUpdateSelected
* @return void
*/
public function testCustomLayoutData(): void
public function testCustomLayoutData(string $identifier, ?string $layoutUpdateSelected): void
{
$data = $this->provider->getData();
$page1Data = null;
$page2Data = null;
$page3Data = null;
foreach ($data as $pageData) {
if ($pageData[PageModel::IDENTIFIER] === 'test_custom_layout_page_1') {
$page1Data = $pageData;
} elseif ($pageData[PageModel::IDENTIFIER] === 'test_custom_layout_page_2') {
$page2Data = $pageData;
} elseif ($pageData[PageModel::IDENTIFIER] === 'test_custom_layout_page_3') {
$page3Data = $pageData;
}
}
$this->assertNotEmpty($page1Data);
$this->assertNotEmpty($page2Data);
$this->assertEquals('_existing_', $page1Data['layout_update_selected']);
$this->assertNull($page2Data['layout_update_selected']);
$this->assertEquals('test_selected', $page3Data['layout_update_selected']);
$page = $this->repo->execute($identifier, 0);

$request = $this->objectManager->create(RequestInterface::class);
$request->setParam('page_id', $page->getId());

$provider = $this->objectManager->create(
DataProvider::class,
array_merge($this->providerData, ['request' => $request])
);

$data = $provider->getData();
$pageData = $data[$page->getId()];

$this->assertEquals($layoutUpdateSelected, $pageData['layout_update_selected']);
}

/**
* DataProvider for testCustomLayoutData
*
* @return array
*/
public function customLayoutDataProvider(): array
{
return [
['test_custom_layout_page_1', '_existing_'],
['test_custom_layout_page_2', null],
['test_custom_layout_page_3', 'test_selected'],
];
}

/**
Expand Down

0 comments on commit e5208f0

Please sign in to comment.