From 2b245139661eaa4e83c78d9ebaab1a403faaea02 Mon Sep 17 00:00:00 2001 From: Hendrik Bugdoll Date: Fri, 5 Apr 2024 15:06:23 +0200 Subject: [PATCH 1/6] Added new page property to blocks --- src/base/BlockInterface.php | 14 ++++++++++++++ src/base/InternalBaseBlock.php | 24 +++++++++++++++++++++--- src/base/PhpBlockView.php | 17 ++++++++++++++++- src/models/Block.php | 4 +++- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/base/BlockInterface.php b/src/base/BlockInterface.php index da475d9c..e214754f 100644 --- a/src/base/BlockInterface.php +++ b/src/base/BlockInterface.php @@ -97,6 +97,20 @@ public function blockGroup(); */ public function getFieldHelp(); + /** + * Set the block's {{luya\cms\models\NavItemPage}} object. + * + * @param NavItemPage $page The page object. + */ + public function setPage($page); + + /** + * Returns the block's {{luya\cms\models\NavItemPage}} object. + * + * @return NavItemPage + */ + public function getPage(); + /** * Set an environment option informations to the block with key value pairing. * diff --git a/src/base/InternalBaseBlock.php b/src/base/InternalBaseBlock.php index a0da1580..7464699d 100644 --- a/src/base/InternalBaseBlock.php +++ b/src/base/InternalBaseBlock.php @@ -12,10 +12,10 @@ use yii\helpers\Inflector; /** - * Concret Block implementation based on BlockInterface. + * Concrete Block implementation based on BlockInterface. * - * This is an use case for the block implemenation as InternBaseBlock fro - * two froms of implementations. + * This is an use case for the block implementation as InternBaseBlock for + * two forms of implementations. * * + {{\luya\cms\base\PhpBlock}} * @@ -290,6 +290,24 @@ public function isFrontendContext() return ($this->getEnvOption('context', false) === 'frontend') ? true : false; } + private $_page; + + /** + * @inheritdoc + */ + public function setPage($page) + { + $this->_page = $page; + } + + /** + * @inheritdoc + */ + public function getPage() + { + return $this->_page; + } + private array $_envOptions = []; /** diff --git a/src/base/PhpBlockView.php b/src/base/PhpBlockView.php index 1235897c..784640db 100644 --- a/src/base/PhpBlockView.php +++ b/src/base/PhpBlockView.php @@ -162,19 +162,34 @@ public function getBlockId() * * @return \luya\cms\models\NavItemPage * @since 1.0.2 + * @deprecated 5.2.0 + * @see getPage() */ public function getPageObject() { return $this->context->getEnvOption('pageObject'); } + /** + * Returns the context {{luya\cms\models\NavItemPage}} object. + * + * Returns the context page object where the block is implemented. + * + * @return \luya\cms\models\NavItemPage + * @since 5.2.0 + */ + public function getPage() + { + return $this->context->getPage(); + } + /** * Get a block environment value. * * + **id**: Returns the unique identifier for this block, each blocks has its id from the database, this is absolute unique. {{luya\cms\models\NavItemPageBlockItem}} -> id * + **blockId**: Returns the id of the block in the database. Two blocks of the same type would have the same blockId. {{luya\cms\models\Block}} -> id * + **context**: Returns `frontend` or `admin` to find out in which context you are. - * + **pageObject**: Returns the {{luya\cms\models\NavItemPage}} object where the block is located. Thereof you can also retrieve the related {{luya\cms\models\NavItem}} and {{luya\cms\models\Nav}} objects via `getNavItem()` and `getNav()`. + * + **pageObject**: Returns the {{luya\cms\models\NavItemPage}} object where the block is located. Thereof you can also retrieve the related {{luya\cms\models\NavItem}} and {{luya\cms\models\Nav}} objects via `getNavItem()` and `getNav()` (deprecated since 5.2.0). * + **isFirst**: Returns whether this block is the first in its placeholder or not. * + **isLast**: Returns whether this block is the last in its placeholder or not. * + **index**: Returns the index number/position within this placeholder. diff --git a/src/models/Block.php b/src/models/Block.php index cc3eef7c..356952d6 100644 --- a/src/models/Block.php +++ b/src/models/Block.php @@ -281,7 +281,9 @@ public static function createObject($class, $blockId, $id, $context, NavItemPage $object->setEnvOption('id', $id); $object->setEnvOption('blockId', $blockId); $object->setEnvOption('context', $context); - $object->setEnvOption('pageObject', $pageObject); + $object->setEnvOption('pageObject', $pageObject); // deprecated since 5.2.0 + + $object->setPage($pageObject); $object->setup(); From 626ae123bc3935e9f8cb8e4ecda8923249837cfb Mon Sep 17 00:00:00 2001 From: Hendrik Bugdoll Date: Fri, 5 Apr 2024 15:20:54 +0200 Subject: [PATCH 2/6] Apply php-cs-fixer changes --- src/base/BlockInterface.php | 4 ++-- src/models/Block.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/base/BlockInterface.php b/src/base/BlockInterface.php index e214754f..7bde25d2 100644 --- a/src/base/BlockInterface.php +++ b/src/base/BlockInterface.php @@ -99,14 +99,14 @@ public function getFieldHelp(); /** * Set the block's {{luya\cms\models\NavItemPage}} object. - * + * * @param NavItemPage $page The page object. */ public function setPage($page); /** * Returns the block's {{luya\cms\models\NavItemPage}} object. - * + * * @return NavItemPage */ public function getPage(); diff --git a/src/models/Block.php b/src/models/Block.php index 356952d6..96a01d6b 100644 --- a/src/models/Block.php +++ b/src/models/Block.php @@ -282,7 +282,7 @@ public static function createObject($class, $blockId, $id, $context, NavItemPage $object->setEnvOption('blockId', $blockId); $object->setEnvOption('context', $context); $object->setEnvOption('pageObject', $pageObject); // deprecated since 5.2.0 - + $object->setPage($pageObject); $object->setup(); From 2ce4d3e1d89609039488aa73ae0bcc211c4d365c Mon Sep 17 00:00:00 2001 From: Hendrik Bugdoll Date: Fri, 5 Apr 2024 15:35:54 +0200 Subject: [PATCH 3/6] Fixed typo in test name --- ...ck.php => ConcreteImplementationBlock.php} | 24 ++++++++++++++++++- tests/src/base/InternalBaseBlockTest.php | 4 ++-- tests/src/base/PhpBlockViewTest.php | 6 ++--- 3 files changed, 28 insertions(+), 6 deletions(-) rename tests/data/blocks/{ConcretImplementationBlock.php => ConcreteImplementationBlock.php} (90%) diff --git a/tests/data/blocks/ConcretImplementationBlock.php b/tests/data/blocks/ConcreteImplementationBlock.php similarity index 90% rename from tests/data/blocks/ConcretImplementationBlock.php rename to tests/data/blocks/ConcreteImplementationBlock.php index f3e6eba2..a83c26e5 100644 --- a/tests/data/blocks/ConcretImplementationBlock.php +++ b/tests/data/blocks/ConcreteImplementationBlock.php @@ -5,7 +5,7 @@ use luya\cms\base\BlockInterface; use luya\cms\frontend\blockgroups\DevelopmentGroup; -class ConcretImplementationBlock implements BlockInterface +class ConcreteImplementationBlock implements BlockInterface { public function onRegister() { @@ -94,6 +94,28 @@ public function getFieldHelp() return []; } + private $_page; + + /** + * Set the block's {{luya\cms\models\NavItemPage}} object. + * + * @param NavItemPage $page The page object. + */ + public function setPage($page) + { + $this->_page = $page; + } + + /** + * Returns the block's {{luya\cms\models\NavItemPage}} object. + * + * @return NavItemPage + */ + public function getPage() + { + return $this->_page; + } + private $_envs = []; /** diff --git a/tests/src/base/InternalBaseBlockTest.php b/tests/src/base/InternalBaseBlockTest.php index 6ae90804..dceab08b 100644 --- a/tests/src/base/InternalBaseBlockTest.php +++ b/tests/src/base/InternalBaseBlockTest.php @@ -8,9 +8,9 @@ class InternalBaseBlockTest extends CmsFrontendTestCase { - public function testConcretImplementation() + public function testConcreteImplementation() { - $object = new ConcretImplementationBlock(); + $object = new ConcreteImplementationBlock(); $this->assertInstanceOf('luya\cms\base\BlockInterface', $object); } diff --git a/tests/src/base/PhpBlockViewTest.php b/tests/src/base/PhpBlockViewTest.php index 4bd79a76..2f83c67e 100644 --- a/tests/src/base/PhpBlockViewTest.php +++ b/tests/src/base/PhpBlockViewTest.php @@ -3,7 +3,7 @@ namespace cmstests\src\base; use cmstests\CmsFrontendTestCase; -use cmstests\data\blocks\ConcretImplementationBlock; +use cmstests\data\blocks\ConcreteImplementationBlock; use cmstests\data\blocks\PhpTestBlock; use luya\cms\base\PhpBlockView; use luya\web\View; @@ -127,11 +127,11 @@ public function testRegisterAssetBundles() public function testGetBlock() { - $block = new ConcretImplementationBlock(); + $block = new ConcreteImplementationBlock(); $view = new PhpBlockView(); $view->context = $block; - $this->assertInstanceOf(ConcretImplementationBlock::class, $view->getBlock()); + $this->assertInstanceOf(ConcreteImplementationBlock::class, $view->getBlock()); } public function testGetters() From e8b4563ac7269c6ebf38b2ccb8d1165fc8c9af7e Mon Sep 17 00:00:00 2001 From: Hendrik Bugdoll Date: Fri, 5 Apr 2024 19:15:20 +0200 Subject: [PATCH 4/6] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8f3dd12..0aebadba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). In order to read more about upgrading and BC breaks have a look at the [UPGRADE Document](UPGRADE.md). +## 5.2.0 + ++ [#418](https://github.com/luyadev/luya-module-cms/pull/418) Added new block's `page` property in both admin and frontend context as a replacement for `getEnvOption('pageObject')`, which is now deprecated. + ## 5.1.1 (28. March 2024) + [#415](https://github.com/luyadev/luya-module-cms/pull/415) Fixed navItem relation for inactive page versions. From 7c0014ee7d0dda5f989c2ef9a1efeebab54ca8ad Mon Sep 17 00:00:00 2001 From: Hendrik Bugdoll Date: Fri, 5 Apr 2024 22:17:21 +0200 Subject: [PATCH 5/6] Added unit test for new block's page property --- .../base/BlockPlaceholderIterationTest.php | 130 ++++++++++++++++-- 1 file changed, 115 insertions(+), 15 deletions(-) diff --git a/tests/src/base/BlockPlaceholderIterationTest.php b/tests/src/base/BlockPlaceholderIterationTest.php index adfc7530..0ab8cd07 100644 --- a/tests/src/base/BlockPlaceholderIterationTest.php +++ b/tests/src/base/BlockPlaceholderIterationTest.php @@ -101,6 +101,86 @@ public function testRenderPlaceholderIteration() $this->assertSame('
foo
bar
', $page->renderPlaceholder('content')); } + public function testPageObjectPlaceholderIteration() + { + $this->app->setComponents([ + 'db' => [ + 'class' => 'yii\db\Connection', + 'dsn' => 'sqlite::memory:', + ] + ]); + + $blockFixture = new NgRestModelFixture([ + 'modelClass' => Block::class, + 'fixtureData' => [ + 'block1' => [ + 'id' => 1, + 'group_id' => 1, + 'class' => TestingPageObjectBlock::class, + 'is_disabled' => 0, + ], + ] + ]); + + $pageFixture = new ActiveRecordFixture([ + 'modelClass' => NavItemPage::class, + 'fixtureData' => [ + 'page1' => [ + 'id' => 1, + 'layout_id' => 1, + 'nav_item_id' => 1, + 'timestamp_create' => time(), + 'version_alias' => 'barfoo', + ], + ] + ]); + + $blockItemFixture = new NgRestModelFixture([ + 'modelClass' => NavItemPageBlockItem::class, + 'fixtureData' => [ + 'item1' => [ + 'id' => 1, + 'block_id' => 1, + 'placeholder_var' => 'content', + 'nav_item_page_id' => 1, + 'prev_id' => 0, + 'json_config_values' => '{}', + 'json_config_cfg_values' => '{}', + 'variation' => '', + 'is_hidden' => 0, + ], + ] + ]); + + $block1 = $blockFixture->getModel('block1'); + $page1 = $pageFixture->getModel('page1'); + $blockItem1 = $blockItemFixture->getModel('item1'); + + // admin: + + $adminBlockItems = NavItemPage::getPlaceholder('content', 0, $page1); + + $pageObject = $adminBlockItems[0]['twig_admin']; + + $this->assertInstanceOf(NavItemPage::class, $pageObject); + $this->assertSame(1, $pageObject->id); + $this->assertSame(1, $pageObject->layout_id); + $this->assertSame(1, $pageObject->nav_item_id); + $this->assertSame('barfoo', $pageObject->version_alias); + + // frontend: + + $frontendPageObjects = json_decode($page1->renderPlaceholder('content'), true); + + $pageObject = $frontendPageObjects[0]; + + $this->assertSame('luya\cms\models\NavItemPage', $pageObject['className']); + $this->assertSame(1, $pageObject['id']); + $this->assertSame(1, $pageObject['layoutId']); + $this->assertSame(1, $pageObject['navItemId']); + $this->assertSame('barfoo', $pageObject['versionAlias']); + } + public function testEnvOptionsPlaceholderIteration() { $this->app->setComponents([ @@ -175,14 +255,14 @@ public function testEnvOptionsPlaceholderIteration() ]); $block1 = $blockFixture->getModel('block1'); - $page = $pageFixture->getModel('page1'); + $page1 = $pageFixture->getModel('page1'); $blockItem1 = $blockItemFixture->getModel('item1'); $blockItem2 = $blockItemFixture->getModel('item2'); $blockItem3 = $blockItemFixture->getModel('item3'); // admin: - $adminBlockItems = NavItemPage::getPlaceholder('content', 0, $page); + $adminBlockItems = NavItemPage::getPlaceholder('content', 0, $page1); $envOptions1 = $adminBlockItems[0]['twig_admin']; $envOptions2 = $adminBlockItems[1]['twig_admin']; @@ -191,8 +271,6 @@ public function testEnvOptionsPlaceholderIteration() $this->assertSame(1, $envOptions1['id']); $this->assertSame(1, $envOptions1['blockId']); $this->assertSame('admin', $envOptions1['context']); - //@TODO assertInstanceOf() for pageObject - $this->assertNotEquals(false, $envOptions1['pageObject']); $this->assertSame(1, $envOptions1['index']); $this->assertSame(3, $envOptions1['itemsCount']); $this->assertTrue($envOptions1['isFirst']); @@ -204,8 +282,6 @@ public function testEnvOptionsPlaceholderIteration() $this->assertSame(2, $envOptions2['id']); $this->assertSame(1, $envOptions2['blockId']); $this->assertSame('admin', $envOptions2['context']); - //@TODO assertInstanceOf() for pageObject - $this->assertNotEquals(false, $envOptions2['pageObject']); $this->assertSame(2, $envOptions2['index']); $this->assertSame(3, $envOptions2['itemsCount']); $this->assertFalse($envOptions2['isFirst']); @@ -217,8 +293,6 @@ public function testEnvOptionsPlaceholderIteration() $this->assertSame(3, $envOptions3['id']); $this->assertSame(1, $envOptions3['blockId']); $this->assertSame('admin', $envOptions3['context']); - //@TODO assertInstanceOf() for pageObject - $this->assertNotEquals(false, $envOptions2['pageObject']); $this->assertSame(3, $envOptions3['index']); $this->assertSame(3, $envOptions3['itemsCount']); $this->assertFalse($envOptions3['isFirst']); @@ -229,7 +303,7 @@ public function testEnvOptionsPlaceholderIteration() // frontend: - $frontendEnvOptions = json_decode($page->renderPlaceholder('content'), true); + $frontendEnvOptions = json_decode($page1->renderPlaceholder('content'), true); $envOptions1 = $frontendEnvOptions[0]; $envOptions2 = $frontendEnvOptions[1]; @@ -238,8 +312,6 @@ public function testEnvOptionsPlaceholderIteration() $this->assertSame(1, $envOptions1['id']); $this->assertSame(1, $envOptions1['blockId']); $this->assertSame('frontend', $envOptions1['context']); - //@TODO assertInstanceOf() for pageObject - $this->assertNotEquals(false, $envOptions1['pageObject']); $this->assertSame(1, $envOptions1['index']); $this->assertSame(3, $envOptions1['itemsCount']); $this->assertTrue($envOptions1['isFirst']); @@ -251,8 +323,6 @@ public function testEnvOptionsPlaceholderIteration() $this->assertSame(2, $envOptions2['id']); $this->assertSame(1, $envOptions2['blockId']); $this->assertSame('frontend', $envOptions2['context']); - //@TODO assertInstanceOf() for pageObject - $this->assertNotEquals(false, $envOptions2['pageObject']); $this->assertSame(2, $envOptions2['index']); $this->assertSame(3, $envOptions2['itemsCount']); $this->assertFalse($envOptions2['isFirst']); @@ -264,8 +334,6 @@ public function testEnvOptionsPlaceholderIteration() $this->assertSame(3, $envOptions3['id']); $this->assertSame(1, $envOptions3['blockId']); $this->assertSame('frontend', $envOptions3['context']); - //@TODO assertInstanceOf() for pageObject - $this->assertNotEquals(false, $envOptions3['pageObject']); $this->assertSame(3, $envOptions3['index']); $this->assertSame(3, $envOptions3['itemsCount']); $this->assertFalse($envOptions3['isFirst']); @@ -333,6 +401,38 @@ public function placeholderRenderIteration(\luya\cms\base\BlockInterface $block) } } +class TestingPageObjectBlock extends InternalBaseBlock +{ + public function name() + { + return 'PageObject'; + } + + public function config() + { + return []; + } + + public function renderFrontend() + { + // simplify data of page object before stringify + $page = [ + 'className' => get_class($this->page), + 'id' => $this->page->id, + 'layoutId' => $this->page->layout_id, + 'navItemId' => $this->page->nav_item_id, + 'versionAlias' => $this->page->version_alias, + ]; + + return (($this->getEnvOption('isFirst')) ? '[' : '') . json_encode($page, JSON_NUMERIC_CHECK) . (($this->getEnvOption('isLast')) ? ']' : ','); + } + + public function renderAdmin() + { + return $this->page; + } +} + class TestingEnvOptionsBlock extends InternalBaseBlock { public function name() From 4a5ab1392541c4cfdc1c68dafc2a12b62f0f9589 Mon Sep 17 00:00:00 2001 From: Hendrik Bugdoll Date: Sat, 6 Apr 2024 22:24:26 +0200 Subject: [PATCH 6/6] Added PHP type declarations in page getter/setter --- src/base/BlockInterface.php | 6 ++++-- src/base/InternalBaseBlock.php | 5 +++-- tests/data/blocks/ConcreteImplementationBlock.php | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/base/BlockInterface.php b/src/base/BlockInterface.php index 7bde25d2..ba6ff2d7 100644 --- a/src/base/BlockInterface.php +++ b/src/base/BlockInterface.php @@ -2,6 +2,8 @@ namespace luya\cms\base; +use luya\cms\models\NavItemPage; + /** * Interface for all Blocks. * @@ -102,14 +104,14 @@ public function getFieldHelp(); * * @param NavItemPage $page The page object. */ - public function setPage($page); + public function setPage(NavItemPage $page); /** * Returns the block's {{luya\cms\models\NavItemPage}} object. * * @return NavItemPage */ - public function getPage(); + public function getPage(): NavItemPage; /** * Set an environment option informations to the block with key value pairing. diff --git a/src/base/InternalBaseBlock.php b/src/base/InternalBaseBlock.php index 7464699d..52baafed 100644 --- a/src/base/InternalBaseBlock.php +++ b/src/base/InternalBaseBlock.php @@ -4,6 +4,7 @@ use luya\admin\base\TypesInterface; use luya\cms\frontend\blockgroups\MainGroup; +use luya\cms\models\NavItemPage; use luya\helpers\ArrayHelper; use luya\helpers\FileHelper; use luya\helpers\Html; @@ -295,7 +296,7 @@ public function isFrontendContext() /** * @inheritdoc */ - public function setPage($page) + public function setPage(NavItemPage $page) { $this->_page = $page; } @@ -303,7 +304,7 @@ public function setPage($page) /** * @inheritdoc */ - public function getPage() + public function getPage(): NavItemPage { return $this->_page; } diff --git a/tests/data/blocks/ConcreteImplementationBlock.php b/tests/data/blocks/ConcreteImplementationBlock.php index a83c26e5..45481c3a 100644 --- a/tests/data/blocks/ConcreteImplementationBlock.php +++ b/tests/data/blocks/ConcreteImplementationBlock.php @@ -4,6 +4,7 @@ use luya\cms\base\BlockInterface; use luya\cms\frontend\blockgroups\DevelopmentGroup; +use luya\cms\models\NavItemPage; class ConcreteImplementationBlock implements BlockInterface { @@ -101,7 +102,7 @@ public function getFieldHelp() * * @param NavItemPage $page The page object. */ - public function setPage($page) + public function setPage(NavItemPage $page) { $this->_page = $page; } @@ -111,7 +112,7 @@ public function setPage($page) * * @return NavItemPage */ - public function getPage() + public function getPage(): NavItemPage { return $this->_page; }