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. diff --git a/src/base/BlockInterface.php b/src/base/BlockInterface.php index da475d9c..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. * @@ -97,6 +99,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(NavItemPage $page); + + /** + * Returns the block's {{luya\cms\models\NavItemPage}} object. + * + * @return NavItemPage + */ + 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 a0da1580..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; @@ -12,10 +13,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 +291,24 @@ public function isFrontendContext() return ($this->getEnvOption('context', false) === 'frontend') ? true : false; } + private $_page; + + /** + * @inheritdoc + */ + public function setPage(NavItemPage $page) + { + $this->_page = $page; + } + + /** + * @inheritdoc + */ + public function getPage(): NavItemPage + { + 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..96a01d6b 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(); diff --git a/tests/data/blocks/ConcretImplementationBlock.php b/tests/data/blocks/ConcreteImplementationBlock.php similarity index 89% rename from tests/data/blocks/ConcretImplementationBlock.php rename to tests/data/blocks/ConcreteImplementationBlock.php index f3e6eba2..45481c3a 100644 --- a/tests/data/blocks/ConcretImplementationBlock.php +++ b/tests/data/blocks/ConcreteImplementationBlock.php @@ -4,8 +4,9 @@ use luya\cms\base\BlockInterface; use luya\cms\frontend\blockgroups\DevelopmentGroup; +use luya\cms\models\NavItemPage; -class ConcretImplementationBlock implements BlockInterface +class ConcreteImplementationBlock implements BlockInterface { public function onRegister() { @@ -94,6 +95,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(NavItemPage $page) + { + $this->_page = $page; + } + + /** + * Returns the block's {{luya\cms\models\NavItemPage}} object. + * + * @return NavItemPage + */ + public function getPage(): NavItemPage + { + return $this->_page; + } + private $_envs = []; /** 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() 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()