diff --git a/CHANGELOG.md b/CHANGELOG.md
index 78a5fc09..8aaa7c17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,11 @@
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
In order to read more about upgrading and BC breaks have a look at the [UPGRADE Document](UPGRADE.md).
-## 2.0.1
+## 2.1.0
+
+### Added
+
++ [#210](https://github.com/luyadev/luya-module-cms/pull/210) Added new Active Query Select Injector class.
### Fixed
diff --git a/composer.json b/composer.json
index b0379927..1a3c2414 100644
--- a/composer.json
+++ b/composer.json
@@ -16,7 +16,7 @@
"issues" : "https://github.com/luyadev/luya-module-cms/issues"
},
"require-dev" : {
- "luyadev/luya-testsuite" : "^1.0@dev",
+ "luyadev/luya-testsuite" : "^1.0",
"twbs/bootstrap": "~4.3.0",
"unglue/client": "^1.3"
},
diff --git a/composer.lock b/composer.lock
index 465f47e6..b167eaaa 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "8732765d38b3e8f73427cd66371eb57f",
+ "content-hash": "8b1755a4ec83a020a40f25556f6a0779",
"packages": [],
"packages-dev": [
{
@@ -595,16 +595,16 @@
},
{
"name": "luyadev/luya-testsuite",
- "version": "dev-master",
+ "version": "1.0.17.2",
"source": {
"type": "git",
"url": "https://github.com/luyadev/luya-testsuite.git",
- "reference": "08a5c0cfc5480d8765720f1fa9005c08502a44b5"
+ "reference": "828c9b6de876fd60ec81ad105b1dc5b45eb24ee2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/luyadev/luya-testsuite/zipball/08a5c0cfc5480d8765720f1fa9005c08502a44b5",
- "reference": "08a5c0cfc5480d8765720f1fa9005c08502a44b5",
+ "url": "https://api.github.com/repos/luyadev/luya-testsuite/zipball/828c9b6de876fd60ec81ad105b1dc5b45eb24ee2",
+ "reference": "828c9b6de876fd60ec81ad105b1dc5b45eb24ee2",
"shasum": ""
},
"require": {
@@ -644,7 +644,7 @@
"module",
"php"
],
- "time": "2019-06-19T15:58:38+00:00"
+ "time": "2019-06-26T13:55:17+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -2071,7 +2071,7 @@
},
{
"name": "Gert de Pagter",
- "email": "backendtea@gmail.com"
+ "email": "BackEndTea@gmail.com"
}
],
"description": "Symfony polyfill for ctype functions",
@@ -2390,16 +2390,16 @@
},
{
"name": "yiisoft/yii2",
- "version": "2.0.21",
+ "version": "2.0.22",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-framework.git",
- "reference": "7e4622252c5f272373e1339a47d331e4a55e9591"
+ "reference": "417299927ed14adcd51c69a9d75311c5fc33d227"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/7e4622252c5f272373e1339a47d331e4a55e9591",
- "reference": "7e4622252c5f272373e1339a47d331e4a55e9591",
+ "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/417299927ed14adcd51c69a9d75311c5fc33d227",
+ "reference": "417299927ed14adcd51c69a9d75311c5fc33d227",
"shasum": ""
},
"require": {
@@ -2486,7 +2486,7 @@
"framework",
"yii2"
],
- "time": "2019-06-18T14:25:08+00:00"
+ "time": "2019-07-02T20:28:40+00:00"
},
{
"name": "yiisoft/yii2-composer",
@@ -2673,9 +2673,7 @@
],
"aliases": [],
"minimum-stability": "stable",
- "stability-flags": {
- "luyadev/luya-testsuite": 20
- },
+ "stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
diff --git a/src/admin/apis/AdminController.php b/src/admin/apis/AdminController.php
index 1713e3f9..6f5204c9 100644
--- a/src/admin/apis/AdminController.php
+++ b/src/admin/apis/AdminController.php
@@ -203,7 +203,7 @@ public function actionControllerActions($module, $controller)
/**
* Get actions for a given controller.
- *
+ *
* @param object $controller
* @since 2.0.0
* @see Replace with luya core object helper
diff --git a/src/admin/apis/NavController.php b/src/admin/apis/NavController.php
index e71ffb68..362f0764 100644
--- a/src/admin/apis/NavController.php
+++ b/src/admin/apis/NavController.php
@@ -343,16 +343,16 @@ public function actionCreateModule()
}
$create = $model->createModule(
- $parentNavId,
- $navContainerId,
- $this->postArg('lang_id'),
- $this->postArg('title'),
- $this->postArg('alias'),
- $this->postArg('module_name'),
+ $parentNavId,
+ $navContainerId,
+ $this->postArg('lang_id'),
+ $this->postArg('title'),
+ $this->postArg('alias'),
+ $this->postArg('module_name'),
$this->postArg('description'),
- $this->postArg('controller_name'),
- $this->postArg('action_name'),
- $this->postArg('action_params', [])
+ $this->postArg('controller_name'),
+ $this->postArg('action_name'),
+ $this->postArg('action_params', [])
);
if (is_array($create)) {
Yii::$app->response->statusCode = 422;
@@ -368,12 +368,12 @@ public function actionCreateModuleItem()
$create = $model->createModuleItem(
$this->postArg('nav_id'),
$this->postArg('lang_id'),
- $this->postArg('title'),
- $this->postArg('alias'),
+ $this->postArg('title'),
+ $this->postArg('alias'),
$this->postArg('module_name'),
$this->postArg('description'),
- $this->postArg('controller_name'),
- $this->postArg('action_name'),
+ $this->postArg('controller_name'),
+ $this->postArg('action_name'),
$this->postArg('action_params', [])
);
if (is_array($create)) {
diff --git a/src/admin/apis/RedirectController.php b/src/admin/apis/RedirectController.php
index 1a8999ed..3fe707ad 100644
--- a/src/admin/apis/RedirectController.php
+++ b/src/admin/apis/RedirectController.php
@@ -19,9 +19,9 @@ class RedirectController extends \luya\admin\ngrest\base\Api
/**
* Find a redirect object for a given path info.
- *
+ *
* An example using path would be: Yii::$app->request->pathInfo
- *
+ *
* url: https://example.com/hello/world
* path: hello/world
*
diff --git a/src/admin/importers/BlockImporter.php b/src/admin/importers/BlockImporter.php
index 5595dfd1..cd7d8b52 100644
--- a/src/admin/importers/BlockImporter.php
+++ b/src/admin/importers/BlockImporter.php
@@ -119,7 +119,6 @@ protected function handleBlockDefintionInDirectories(array $directories, $blockD
{
$results = [];
foreach ($directories as $directoryPath) {
-
$path = rtrim($directoryPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ltrim($blockDefinition, DIRECTORY_SEPARATOR);
$path = $this->replaceDsSeparator($path);
diff --git a/src/admin/importers/CmslayoutImporter.php b/src/admin/importers/CmslayoutImporter.php
index b5ce940b..51d9fa69 100644
--- a/src/admin/importers/CmslayoutImporter.php
+++ b/src/admin/importers/CmslayoutImporter.php
@@ -169,7 +169,7 @@ protected function importLayoutFile($file, $aliased)
}
return $layoutItem->id;
- }
+ }
// add item into the database table
$data = new Layout();
diff --git a/src/admin/messages/ru/cmsadmin.php b/src/admin/messages/ru/cmsadmin.php
index d0b016dc..800f5e37 100644
--- a/src/admin/messages/ru/cmsadmin.php
+++ b/src/admin/messages/ru/cmsadmin.php
@@ -50,7 +50,7 @@
'menu_group_item_env_container' => 'Контейнеры',
'menu_group_item_env_layouts' => 'Макеты',
'menu_group_elements' => 'Элементы контента',
- 'menu_group_item_elements_blocks' => 'Блоки',
+ 'menu_group_item_elements_blocks' => 'Блоки',
'menu_group_item_elements_group' => 'Группы блоков',
'btn_abort' => 'Отмена',
'btn_refresh' => 'Обновить',
diff --git a/src/base/BlockInterface.php b/src/base/BlockInterface.php
index f0d3ed91..fb990c5a 100644
--- a/src/base/BlockInterface.php
+++ b/src/base/BlockInterface.php
@@ -212,17 +212,17 @@ public function getIsDirtyDialogEnabled();
/**
* This method is called whenever a block inside a placeholder is rendered.
- *
+ *
* This allows you to change the render behavior of every block inside a placeholder. An example of
* adding a wrapper div to the iteration:
- *
+ *
* ```php
* public function placeholderRenderIteration(BlockInterface $block)
* {
* return '
'.$block->renderFrontend().'
';
* }
* ```
- *
+ *
* This also allows you to determined whether the block should be rendered or not as the response is the content
* of the block inside the placholder.
*
diff --git a/src/base/InternalBaseBlock.php b/src/base/InternalBaseBlock.php
index 3aff7917..c0bedf35 100644
--- a/src/base/InternalBaseBlock.php
+++ b/src/base/InternalBaseBlock.php
@@ -433,7 +433,8 @@ public function getExtraValue($key, $default = false)
$this->getExtraVarValues();
$this->_assignExtraVars = true;
}
- return (isset($this->_extraVars[$key])) ? $this->_extraVars[$key] : $default;
+
+ return isset($this->_extraVars[$key]) ? $this->_extraVars[$key] : $default;
}
/**
@@ -483,7 +484,7 @@ public function addVar(array $varConfig, $append = false)
*/
public function getConfigPlaceholdersExport()
{
- $array = (array_key_exists('placeholders', $this->config())) ? $this->config()['placeholders'] : [];
+ $array = array_key_exists('placeholders', $this->config()) ? $this->config()['placeholders'] : [];
$holders = [];
@@ -505,7 +506,7 @@ public function getConfigPlaceholdersExport()
*/
public function getConfigPlaceholdersByRowsExport()
{
- $array = (array_key_exists('placeholders', $this->config())) ? $this->config()['placeholders'] : [];
+ $array = array_key_exists('placeholders', $this->config()) ? $this->config()['placeholders'] : [];
$rows = [];
diff --git a/src/frontend/Bootstrap.php b/src/frontend/Bootstrap.php
index 0c655bd9..f1b697e0 100644
--- a/src/frontend/Bootstrap.php
+++ b/src/frontend/Bootstrap.php
@@ -46,7 +46,6 @@ public function bootstrap($app)
// handle not found exceptions
$app->errorHandler->on(ErrorHandler::EVENT_BEFORE_EXCEPTION_RENDER, function (ErrorHandlerExceptionRenderEvent $event) use ($app) {
if ($event->exception instanceof NotFoundHttpException) {
-
$errorPageNavId = Config::get(Config::HTTP_EXCEPTION_NAV_ID, 0);
/** @var $item Item */
$item = $app->menu->find()->with(['hidden'])->where(['nav_id' => $errorPageNavId])->one();
diff --git a/src/frontend/controllers/DefaultController.php b/src/frontend/controllers/DefaultController.php
index 59460100..36bdac3a 100644
--- a/src/frontend/controllers/DefaultController.php
+++ b/src/frontend/controllers/DefaultController.php
@@ -112,6 +112,4 @@ protected function findInternalRedirect()
return false;
}
-
-
}
diff --git a/src/injectors/ActiveQueryRadioInjector.php b/src/injectors/ActiveQueryRadioInjector.php
index bcd19e6a..2af39aab 100644
--- a/src/injectors/ActiveQueryRadioInjector.php
+++ b/src/injectors/ActiveQueryRadioInjector.php
@@ -2,32 +2,30 @@
namespace luya\cms\injectors;
-use yii\db\ActiveQueryInterface;
-use yii\data\ActiveDataProvider;
use luya\admin\base\TypesInterface;
/**
- * Checkboxes from an ActiveQuery.
+ * Radio List from an ActiveQuery.
*
- * Generates a checkbox selection from an active query interface and returns the
+ * Generates a radio selection from an active query interface and returns the
* models via the ActiveDataProvider.
*
* An example for the injector config:
*
* ```php
- * new ActiveQueryCheckboxInjector([
+ * new ActiveQueryRadioInjector([
* 'query' => \newsadmin\models\Article::find()->where(['cat_id' => 1]),
* 'label' => 'title', // This attribute from the model is used to render the admin block dropdown selection.
* ]);
* ```
*
- * In order to configure the ActiveQueryCheckboxInjector used the {{\luya\cms\base\InternalBaseBlock::injectors}} method:
+ * In order to configure the ActiveQueryRadioInjector used the {{\luya\cms\base\InternalBaseBlock::injectors}} method:
*
* ```php
* public function injectors()
* {
* return [
- * 'theData' => new ActiveQueryCheckboxInjector([
+ * 'theData' => new ActiveQueryRadioInjector([
* 'query' => News::find()->where(['is_deleted' => 0]),
* 'label' => function($model) {
* return $model->title . " - " . $model->description;
diff --git a/src/injectors/ActiveQuerySelectInjector.php b/src/injectors/ActiveQuerySelectInjector.php
new file mode 100644
index 00000000..a031e185
--- /dev/null
+++ b/src/injectors/ActiveQuerySelectInjector.php
@@ -0,0 +1,61 @@
+ \newsadmin\models\Article::find()->where(['cat_id' => 1]),
+ * 'label' => 'title', // This attribute from the model is used to render the admin block dropdown selection.
+ * ]);
+ * ```
+ *
+ * In order to configure the ActiveQuerySelectInjector used the {{\luya\cms\base\InternalBaseBlock::injectors}} method:
+ *
+ * ```php
+ * public function injectors()
+ * {
+ * return [
+ * 'theData' => new ActiveQuerySelectInjector([
+ * 'query' => News::find()->where(['is_deleted' => 0]),
+ * 'label' => function($model) {
+ * return $model->title . " - " . $model->description;
+ * },
+ * ]);
+ * ];
+ * }
+ * ```
+ *
+ * @property \yii\db\ActiveQueryInterface $query The ActiveQuery object
+ *
+ * @author Basil Suter
+ * @since 2.1.0
+ */
+class ActiveQuerySelectInjector extends BaseActiveQueryInjector
+{
+ /**
+ * @inheritdoc
+ */
+ public function setup()
+ {
+ // injecto the config
+ $this->setContextConfig([
+ 'var' => $this->varName,
+ 'type' => TypesInterface::TYPE_SELECT,
+ 'label' => $this->varLabel,
+ 'options' => $this->getQueryData(),
+ ]);
+
+ // provide the extra data
+ $this->context->addExtraVar($this->varName, $this->getExtraAssignSingleData());
+ }
+}
diff --git a/src/injectors/BaseActiveQueryInjector.php b/src/injectors/BaseActiveQueryInjector.php
index d3c911db..b8a9d8fb 100644
--- a/src/injectors/BaseActiveQueryInjector.php
+++ b/src/injectors/BaseActiveQueryInjector.php
@@ -41,13 +41,29 @@ abstract class BaseActiveQueryInjector extends BaseBlockInjector
*
* Define the active query which will be used to retrieve data must be an instance of {{\yii\db\ActiveQueryInterface}}.
*
- * @param \yii\db\ActiveQueryInterface $query The query provider for the {{yii\data\ActiveDataProvider}}.
+ * @param ActiveQueryInterface $query The query provider for the {{yii\data\ActiveDataProvider}}.
*/
public function setQuery(ActiveQueryInterface $query)
{
$this->_query = $query;
}
+
+ /**
+ * Get the Active Query Object.
+ *
+ * @return ActiveQueryInterface
+ * @since 2.1.0
+ */
+ protected function getQuery()
+ {
+ return $this->_query;
+ }
+ /**
+ * Get an array with options
+ *
+ * @return array
+ */
protected function getQueryData()
{
$provider = new ActiveDataProvider([
@@ -65,9 +81,15 @@ protected function getQueryData()
}
$data[] = ['value' => $model->primaryKey, 'label' => $label];
}
+
return $data;
}
+ /**
+ * Get the Active Record models from the stored block values
+ *
+ * @return \yii\db\ActiveRecord[]
+ */
protected function getExtraAssignArrayData()
{
$ids = ArrayHelper::getColumn($this->getContextConfigValue($this->varName, []), 'value');
@@ -80,12 +102,19 @@ protected function getExtraAssignArrayData()
return $provider->getModels();
}
+ /**
+ * Get a single active record based on the stored block value.
+ *
+ * @return \yii\db\ActiveRecord
+ */
protected function getExtraAssignSingleData()
{
$value = $this->getContextConfigValue($this->varName);
- if ($value) {
- return $this->_query->where(['id' => $value])->one();
+ if (!$value) {
+ return false;
}
+
+ return $this->getQuery()->where(['id' => $value])->one();
}
}
diff --git a/src/menu/Item.php b/src/menu/Item.php
index 8ec5d642..3b606199 100644
--- a/src/menu/Item.php
+++ b/src/menu/Item.php
@@ -532,9 +532,9 @@ public function getParents()
/**
* Go down to a given element which is evalutaed trough a callable.
- *
+ *
* Iterate trough parent elements until the last.
- *
+ *
* ```php
* $item = Yii::$app->menu->current->down(function(Item $item) {
* if ($item->depth == 1) {
diff --git a/src/models/Nav.php b/src/models/Nav.php
index 08bad26e..6da39cf5 100644
--- a/src/models/Nav.php
+++ b/src/models/Nav.php
@@ -257,7 +257,7 @@ public function reindex($e)
*
* This method is mainly to find all recursive children of a nav item when moving a page into a container
* all childrens requires to update its container id as well, so this method contains the data of its children
- *
+ *
* @return array An array where each entry is a Nav object
*/
public function getRecursiveChildren()
diff --git a/src/models/NavItem.php b/src/models/NavItem.php
index 2cc29c8c..01e78d3a 100644
--- a/src/models/NavItem.php
+++ b/src/models/NavItem.php
@@ -410,7 +410,7 @@ public function copyPageItem(NavItem $targetNavItem)
if ($blockItem->save()) {
// store the old block id with the new block id
$idLink[$block['id']] = $blockItem->id;
- }
+ }
unset($blockItem);
}
diff --git a/src/models/NavItemModule.php b/src/models/NavItemModule.php
index 6b213af3..93d8503d 100644
--- a/src/models/NavItemModule.php
+++ b/src/models/NavItemModule.php
@@ -18,7 +18,7 @@
* @property string $controller_name
* @property string $action_name
* @property string $action_params
- *
+ *
* @author Basil Suter
* @since 1.0.0
*/
@@ -59,11 +59,11 @@ public function init()
{
parent::init();
- $this->on(self::EVENT_AFTER_FIND, function() {
+ $this->on(self::EVENT_AFTER_FIND, function () {
$this->action_params = $this->getDecodedActionParams();
});
- $this->on(self::EVENT_BEFORE_VALIDATE, function() {
+ $this->on(self::EVENT_BEFORE_VALIDATE, function () {
$this->action_params = $this->getEncodedActionParams();
});
}
diff --git a/src/widgets/LangSwitcher.php b/src/widgets/LangSwitcher.php
index 8e328268..f75cef86 100644
--- a/src/widgets/LangSwitcher.php
+++ b/src/widgets/LangSwitcher.php
@@ -187,7 +187,7 @@ private static function getDataArray()
/**
* Prefix the current link with the dedicated host info.
- *
+ *
* Assuming hostInfoMapping is defined in composition component, the correct domain will be taken from the
* language information.
*
diff --git a/tests/src/frontend/BootstrapErrorPageTest.php b/tests/src/frontend/BootstrapErrorPageTest.php
index d8fb3453..8bb0641c 100644
--- a/tests/src/frontend/BootstrapErrorPageTest.php
+++ b/tests/src/frontend/BootstrapErrorPageTest.php
@@ -29,4 +29,4 @@ public function testBootstrap()
$this->expectException('yii\web\HeadersAlreadySentException');
$this->app->errorHandler->trigger(ErrorHandler::EVENT_BEFORE_EXCEPTION_RENDER, $event);
}
-}
\ No newline at end of file
+}
diff --git a/tests/src/injectors/ActiveQuerySelectInjectorTest.php b/tests/src/injectors/ActiveQuerySelectInjectorTest.php
new file mode 100644
index 00000000..4a798514
--- /dev/null
+++ b/tests/src/injectors/ActiveQuerySelectInjectorTest.php
@@ -0,0 +1,75 @@
+ Layout::class,
+ 'fixtureData' => [
+ 1 => [
+ 'id' => 1,
+ 'name' => 'foo',
+ 'json_config' => '{"node":"value"}',
+ 'view_file' => 'none.php',
+ ]
+ ]
+ ]);
+ }
+
+ public function testVariableResponse()
+ {
+ $block = new TestBlock();
+ $block->setVarValues([
+ 'foobar' => 1,
+ ]);
+
+ $injector = new ActiveQuerySelectInjector([
+ 'query' => Layout::find(),
+ 'varName' => 'foobar',
+ 'varLabel' => 'test',
+ 'label' => 'name',
+ 'context' => $block,
+ ]);
+ $injector->setup();
+
+
+ $f = $block->getExtraValue('foobar');
+ $x = $block->getVarValue('foobar');
+ $y = $block->getConfigVarsExport();
+
+ $this->assertSame('foo', $y[0]['options'][0]['label']);
+ $this->assertSame(1, $x);
+ $this->assertSame(['node' => 'value'], $f->getJsonConfig());
+ $this->assertSame('value', $f->getJsonConfig('node'));
+ }
+
+ public function testVariableNotFoundId()
+ {
+ $block = new TestBlock();
+ $block->setVarValues([
+ 'foobar' => 0,
+ ]);
+
+ $injector = new ActiveQuerySelectInjector([
+ 'query' => Layout::find(),
+ 'varName' => 'foobar',
+ 'varLabel' => 'test',
+ 'label' => 'name',
+ 'context' => $block,
+ ]);
+ $injector->setup();
+
+ $this->assertFalse($block->getExtraValue('foobar'));
+ }
+}
diff --git a/tests/src/menu/ItemTest.php b/tests/src/menu/ItemTest.php
index bd760779..28ae16c3 100644
--- a/tests/src/menu/ItemTest.php
+++ b/tests/src/menu/ItemTest.php
@@ -140,7 +140,7 @@ public function testGoDown()
$itemWithParent = (new Query)->where(['nav_id' => 10])->one();
$this->assertSame(2, $itemWithParent->depth);
- $f = $itemWithParent->down(function(Item $item) {
+ $f = $itemWithParent->down(function (Item $item) {
if ($item->depth == 1) {
return $item;
}
@@ -148,7 +148,7 @@ public function testGoDown()
$this->assertSame(1, $f->depth);
- $this->assertFalse($itemWithParent->down(function(Item $item) {
+ $this->assertFalse($itemWithParent->down(function (Item $item) {
// just do nothing means pass all elements.
}));
}