├── .codeclimate.yml
├── .github
└── workflows
│ └── tests.yml
├── .gitignore
├── .php-cs-fixer.dist.php
├── 1.0.0-cms.png
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── SECURITY.md
├── UPGRADE.md
├── actions.phpunit.xml
├── composer.json
├── docker-compose.yml
├── log
└── testdox.html
├── phpstan.neon
├── phpunit.xml.dist
├── rector.php
├── src
├── Exception.php
├── LinkConverter.php
├── Menu.php
├── Website.php
├── admin
│ ├── Module.php
│ ├── apis
│ │ ├── AdminController.php
│ │ ├── BlockController.php
│ │ ├── BlockgroupController.php
│ │ ├── LayoutController.php
│ │ ├── LogController.php
│ │ ├── MenuController.php
│ │ ├── NavContainerController.php
│ │ ├── NavController.php
│ │ ├── NavItemBlockController.php
│ │ ├── NavItemController.php
│ │ ├── NavItemPageBlockItemController.php
│ │ ├── NavItemPageController.php
│ │ ├── RedirectController.php
│ │ ├── ThemeController.php
│ │ └── WebsiteController.php
│ ├── assets
│ │ └── Main.php
│ ├── aws
│ │ └── BlockPagesActiveWindow.php
│ ├── controllers
│ │ ├── BlockController.php
│ │ ├── BlockgroupController.php
│ │ ├── ConfigController.php
│ │ ├── DefaultController.php
│ │ ├── LayoutController.php
│ │ ├── LogController.php
│ │ ├── NavcontainerController.php
│ │ ├── PageController.php
│ │ ├── PermissionController.php
│ │ ├── RedirectController.php
│ │ ├── ThemeController.php
│ │ └── WebsiteController.php
│ ├── helpers
│ │ └── MenuHelper.php
│ ├── importers
│ │ ├── BlockImporter.php
│ │ ├── CmslayoutImporter.php
│ │ ├── PropertyConsistencyImporter.php
│ │ └── ThemeImporter.php
│ ├── messages
│ │ ├── bg
│ │ │ └── cmsadmin.php
│ │ ├── cn
│ │ │ └── cmsadmin.php
│ │ ├── de
│ │ │ └── cmsadmin.php
│ │ ├── el
│ │ │ └── cmsadmin.php
│ │ ├── en
│ │ │ └── cmsadmin.php
│ │ ├── es
│ │ │ └── cmsadmin.php
│ │ ├── fa
│ │ │ └── cmsadmin.php
│ │ ├── fr
│ │ │ └── cmsadmin.php
│ │ ├── hu
│ │ │ └── cmsadmin.php
│ │ ├── id
│ │ │ └── cmsadmin.php
│ │ ├── it
│ │ │ └── cmsadmin.php
│ │ ├── kr
│ │ │ └── cmsadmin.php
│ │ ├── nl
│ │ │ └── cmsadmin.php
│ │ ├── pl
│ │ │ └── cmsadmin.php
│ │ ├── pt
│ │ │ └── cmsadmin.php
│ │ ├── ru
│ │ │ └── cmsadmin.php
│ │ ├── th
│ │ │ └── cmsadmin.php
│ │ ├── tr
│ │ │ └── cmsadmin.php
│ │ ├── ua
│ │ │ └── cmsadmin.php
│ │ └── vi
│ │ │ └── cmsadmin.php
│ ├── migrations
│ │ ├── m141203_143052_cms_cat.php
│ │ ├── m141203_143059_cms_nav.php
│ │ ├── m141203_143111_cms_nav_item.php
│ │ ├── m141208_134038_cms_nav_item_page.php
│ │ ├── m150106_095003_cms_layout.php
│ │ ├── m150108_154017_cms_block.php
│ │ ├── m150108_155009_cms_nav_item_page_block_item.php
│ │ ├── m150122_125429_cms_nav_item_module.php
│ │ ├── m150205_141350_block_group.php
│ │ ├── m150924_112309_cms_nav_prop.php
│ │ ├── m151012_072207_cms_log.php
│ │ ├── m151022_143429_cms_nav_item_redirect.php
│ │ ├── m160629_092417_cmspermissiontable.php
│ │ ├── m170116_120553_cms_block_variation_field.php
│ │ ├── m170218_215610_cms_nav_layout_file.php
│ │ ├── m170301_084325_cms_config.php
│ │ ├── m170619_103728_cms_blocksettings.php
│ │ ├── m171003_065811_add_class_column_to_block_group_table.php
│ │ ├── m171121_170909_add_publish_at_date.php
│ │ ├── m171206_113949_cms_redirection_table.php
│ │ ├── m180723_123237_indexes.php
│ │ ├── m190219_142706_og_image.php
│ │ ├── m190220_105505_cms_redirect_target_field.php
│ │ ├── m190227_123549_cms_nav_item_strict_url_parsing.php
│ │ ├── m190529_123549_cms_nav_item_module_route_and_params.php
│ │ ├── m190728_084936_cms_theme.php
│ │ ├── m200226_211908_nav_item_is_cacheable.php
│ │ ├── m200706_202002_cms_website.php
│ │ ├── m210605_172811_cms_website_permissions.php
│ │ ├── m210708_091145_v4.php
│ │ └── m230720_130000_page_link_anchor.php
│ ├── resources
│ │ ├── dist
│ │ │ ├── main.css
│ │ │ ├── main.js
│ │ │ └── main.unglue
│ │ ├── img
│ │ │ └── empty-placeholder-arrow.png
│ │ ├── js
│ │ │ ├── cmsadmin.js
│ │ │ └── services.js
│ │ └── scss
│ │ │ ├── browser-fixes
│ │ │ ├── _ie.scss
│ │ │ └── _safari.scss
│ │ │ ├── cmsadmin.scss
│ │ │ ├── components
│ │ │ ├── _block-elements.scss
│ │ │ ├── _block.scss
│ │ │ ├── _blockholder.scss
│ │ │ ├── _card.scss
│ │ │ ├── _cmsadmin.scss
│ │ │ ├── _cmsnav.scss
│ │ │ ├── _empty-placeholder.scss
│ │ │ ├── _menu-dropdown.scss
│ │ │ ├── _toolbar.scss
│ │ │ └── _treeview.scss
│ │ │ └── variables
│ │ │ └── _variables.scss
│ └── views
│ │ ├── aws
│ │ └── blockpages
│ │ │ └── index.php
│ │ ├── config
│ │ └── index.php
│ │ ├── default
│ │ ├── _angulardirectives.php
│ │ └── index.php
│ │ ├── page
│ │ ├── _navitem.php
│ │ ├── _navitem_settings.php
│ │ ├── _settings.php
│ │ ├── create.php
│ │ ├── drafts.php
│ │ └── update.php
│ │ └── permission
│ │ └── index.php
├── base
│ ├── BaseBlockInjector.php
│ ├── BlockCfg.php
│ ├── BlockConfigElement.php
│ ├── BlockGroup.php
│ ├── BlockInterface.php
│ ├── BlockVar.php
│ ├── BlockVariationRegister.php
│ ├── InternalBaseBlock.php
│ ├── NavItemType.php
│ ├── NavItemTypeInterface.php
│ ├── PhpBlock.php
│ ├── PhpBlockInterface.php
│ └── PhpBlockView.php
├── behaviours
│ └── WebsiteScopeBehavior.php
├── frontend
│ ├── Bootstrap.php
│ ├── Module.php
│ ├── base
│ │ └── Controller.php
│ ├── blockgroups
│ │ ├── DevelopmentGroup.php
│ │ ├── LayoutGroup.php
│ │ ├── MainGroup.php
│ │ ├── MediaGroup.php
│ │ ├── ProjectGroup.php
│ │ └── TextGroup.php
│ ├── blocks
│ │ ├── HtmlBlock.php
│ │ ├── MirrorLanguageBlock.php
│ │ └── ModuleBlock.php
│ ├── commands
│ │ ├── BlockController.php
│ │ ├── PageController.php
│ │ └── UpdaterController.php
│ ├── components
│ │ ├── CatchAllUrlRule.php
│ │ ├── RouteBehaviorUrlRule.php
│ │ └── WebsiteBehaviorUrlRule.php
│ ├── controllers
│ │ ├── BlockController.php
│ │ ├── DefaultController.php
│ │ ├── ErrorController.php
│ │ └── PreviewController.php
│ ├── events
│ │ ├── BeforeRenderEvent.php
│ │ └── MenuItemEvent.php
│ ├── messages
│ │ ├── bg
│ │ │ └── cms.php
│ │ ├── cn
│ │ │ └── cms.php
│ │ ├── de
│ │ │ └── cms.php
│ │ ├── el
│ │ │ └── cms.php
│ │ ├── en
│ │ │ └── cms.php
│ │ ├── es
│ │ │ └── cms.php
│ │ ├── fa
│ │ │ └── cms.php
│ │ ├── fr
│ │ │ └── cms.php
│ │ ├── hu
│ │ │ └── cms.php
│ │ ├── id
│ │ │ └── cms.php
│ │ ├── it
│ │ │ └── cms.php
│ │ ├── nl
│ │ │ └── cms.php
│ │ ├── pl
│ │ │ └── cms.php
│ │ ├── pt
│ │ │ └── cms.php
│ │ ├── ru
│ │ │ └── cms.php
│ │ ├── th
│ │ │ └── cms.php
│ │ ├── tr
│ │ │ └── cms.php
│ │ ├── ua
│ │ │ └── cms.php
│ │ └── vi
│ │ │ └── cms.php
│ └── views
│ │ ├── _toolbar.php
│ │ ├── blocks
│ │ ├── HtmlBlock.php
│ │ └── ModuleBlock.php
│ │ ├── commands
│ │ └── block
│ │ │ ├── create_block.php
│ │ │ └── create_block_view.php
│ │ ├── error
│ │ └── index.php
│ │ └── inline
│ │ ├── toolbar.css
│ │ └── toolbar.js
├── helpers
│ ├── BlockHelper.php
│ └── Url.php
├── injectors
│ ├── ActiveQueryCheckboxInjector.php
│ ├── ActiveQueryRadioInjector.php
│ ├── ActiveQuerySelectInjector.php
│ ├── BaseActiveQueryInjector.php
│ ├── LinkInjector.php
│ └── TagInjector.php
├── menu
│ ├── InjectItem.php
│ ├── InjectItemInterface.php
│ ├── Item.php
│ ├── Query.php
│ ├── QueryIterator.php
│ ├── QueryIteratorFilter.php
│ └── QueryOperatorFieldInterface.php
├── models
│ ├── Block.php
│ ├── BlockGroup.php
│ ├── Config.php
│ ├── Layout.php
│ ├── Log.php
│ ├── Nav.php
│ ├── NavContainer.php
│ ├── NavItem.php
│ ├── NavItemModule.php
│ ├── NavItemPage.php
│ ├── NavItemPageBlockItem.php
│ ├── NavItemRedirect.php
│ ├── NavPermission.php
│ ├── Property.php
│ ├── Redirect.php
│ ├── Theme.php
│ └── Website.php
├── tags
│ ├── AliasTag.php
│ ├── MenuTag.php
│ └── PageTag.php
└── widgets
│ ├── LangSwitcher.php
│ └── NavTree.php
└── tests
├── BlockTestCase.php
├── CmsConsoleTestCase.php
├── CmsFrontendTestCase.php
├── CmsNgRestTestCase.php
├── Dockerfile
├── ModelTestCase.php
├── WebModelTestCase.php
├── data
├── assets
│ └── .gitignore
├── blocks
│ ├── ConcretImplementationBlock.php
│ ├── PhpTestBlock.php
│ ├── TestBlock.php
│ ├── UnitTestBlock.php
│ └── import
│ │ └── TestBlock.php
├── cmslayouts
│ ├── layoutwithjson.json
│ ├── layoutwithjson.php
│ └── phplayout.php
├── configs
│ └── cms.php
├── env.php
├── fixtures
│ └── TagFixture.php
├── images
│ └── blocks
│ │ └── TestBlock.jpg
├── items
│ └── RootItem.php
├── modules
│ ├── CmsUnitModule.php
│ ├── CmsUrlRuleModule.php
│ ├── controllers
│ │ ├── DefaultController.php
│ │ └── FooController.php
│ ├── otherThemes
│ │ └── otherTheme
│ │ │ └── theme.json
│ └── themes
│ │ └── testTheme
│ │ ├── theme.json
│ │ └── views
│ │ └── cmslayouts
│ │ └── themeLayout.php
├── sql
│ ├── 1.0.0-RC1.sql
│ ├── 1.0.0-RC2.sql
│ ├── 1.0.0-RC3.sql
│ ├── 1.0.0-RC4.sql
│ ├── 1.0.0-beta7.sql
│ ├── 1.0.0-beta8.sql
│ ├── 1.0.0.sql
│ ├── 3.0.0.sql
│ ├── 4.0.0.sql
│ └── latest
│ │ └── 5.0.0.sql
├── themes
│ ├── appTheme
│ │ ├── theme.json
│ │ └── views
│ │ │ └── cmslayouts
│ │ │ └── appThemeLayout.php
│ └── testTheme
│ │ └── theme.json
└── views
│ ├── blocks
│ └── PhpTestBlock.php
│ ├── cmslayouts
│ └── main.php
│ └── layouts
│ └── main.php
├── runtime
└── .gitkeep
└── src
├── LinkConverterTest.php
├── MenuTest.php
├── MessageFileTest.php
├── admin
├── apis
│ ├── AdminControllerTest.php
│ ├── MenuControllerTest.php
│ ├── NavControllerTest.php
│ └── NavItemControllerTest.php
├── controllers
│ ├── DefaultControllerTest.php
│ ├── PageControllerTest.php
│ └── PermissionControllerTest.php
└── importers
│ ├── BlockImporterTest.php
│ ├── CmslayoutImporterTest.php
│ └── ThemeImporterTest.php
├── base
├── BaseBlockInjectorTest.php
├── BlockPlaceholderIterationTest.php
├── BlockTest.php
├── BlockVariationRegisterTest.php
├── InternalBaseBlockTest.php
├── PhpBlockTest.php
└── PhpBlockViewTest.php
├── controllers
├── BlockControllerTest.php.bkp
├── DefaultControllerTest.php
└── PreviewControllerTest.php.bkp
├── frontend
├── BootstrapErrorPageTest.php
├── ModuleTest.php
├── blockgroups
│ ├── DevelopmentGroupTest.php
│ ├── LayoutGroupTest.php
│ ├── MainGroupTest.php
│ ├── MediaGroupTest.php
│ ├── ProjectGroupTest.php
│ └── TextGroupTest.php
├── blocks
│ ├── HtmlBlockTest.php
│ ├── MirrorLanguageBlockTest.php
│ └── ModuleBlockTest.php
├── commands
│ ├── BlockControllerTest.php
│ └── PageControllerTest.php
├── components
│ ├── CatchAllUrlRuleTest.php
│ └── WebsiteBehaviorUrlRuleTest.php
└── controllers
│ └── BlockControllerTest.php
├── helpers
├── BlockHelperTest.php
└── UrlTest.php
├── injectors
├── ActiveQueryCheckboxInjectorTest.php
├── ActiveQuerySelectInjectorTest.php
├── LinkInjectorTest.php
└── TagInjectorTest.php
├── menu
├── InjectItemTest.php
├── ItemSqliteTest.php
├── ItemTest.php
├── QuerySqliteTest.php
├── QueryTest.php
└── _dataFrArray.php
├── models
├── BlockGroupTest.php
├── BlockTest.php
├── NavContainerTest.php
├── NavItemModuleTest.php
├── NavItemPageBlockItemTest.php
├── NavItemPageTest.php
├── NavItemTest.php
├── NavTest.php
├── RedirectTest.php
└── ThemeTest.php
├── tags
├── MenuTagTest.php
└── PageTagTest.php
└── widgets
├── LangSwitcherSqliteTest.php
├── LangSwitcherTest.php
└── NavTreeTest.php
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | exclude_patterns:
2 | - "src/frontend/messages/**/*.php"
3 | - "src/admin/messages/**/*.php"
4 | - "src/admin/migrations/*.php"
5 | - "src/admin/views/"
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /.php_cs.cache
3 | /.buildpath
4 | /.project
5 | /.settings/
6 | /phpunit.xml
7 | /luya
8 | node_modules/
9 | composer.lock
10 | .phpunit.result.cache
11 | /tests/_output/*
12 | .php-cs-fixer.cache
13 | .tmp
--------------------------------------------------------------------------------
/.php-cs-fixer.dist.php:
--------------------------------------------------------------------------------
1 | in(__DIR__)
5 | ;
6 |
7 | $config = new PhpCsFixer\Config();
8 | return $config->setRules([
9 | '@PSR12' => true,
10 | 'array_syntax' => ['syntax' => 'short'],
11 | 'ordered_imports' => ['sort_algorithm' => 'alpha'],
12 | 'no_unused_imports' => true,
13 | ])
14 | ->setFinder($finder)
15 | ;
--------------------------------------------------------------------------------
/1.0.0-cms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyadev/luya-module-cms/8a3472acfc2620374fb8de6aed1f2736926cca2b/1.0.0-cms.png
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2014-2018 Zephir Software Design AG. https://luya.io
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # LUYA Content Management System
6 |
7 |
8 | [](https://luya.io)
9 | 
10 | [](https://codeclimate.com/github/luyadev/luya-module-cms/maintainability)
11 | [](https://codeclimate.com/github/luyadev/luya-module-cms/test_coverage)
12 | [](https://packagist.org/packages/luyadev/luya-module-cms)
13 | [](https://packagist.org/packages/luyadev/luya-module-cms)
14 |
15 | The LUYA CMS module provides a full functional Content Management System for adding contents based on blocks.
16 |
17 | 
18 |
19 | To use the LUYA CMS module you have to run a LUYA Application which is provided by the LUYA core.
20 |
21 | For installation and usage please check: [LUYA.IO](https://luya.io)
22 |
23 | ## Installation
24 |
25 | For the installation of modules Composer is required.
26 |
27 | ```sh
28 | composer require luyadev/luya-module-cms
29 | ```
30 |
31 | ### Configuration
32 |
33 | Add the frontend and admin module of the cms module to your configuration modules section and bootstrap the cms frontend module:
34 |
35 | ```php
36 | 'modules' => [
37 | // ...
38 | 'cms' => 'luya\cms\frontend\Module',
39 | 'cmsadmin' => 'luya\cms\admin\Module',
40 | // ...
41 | ]
42 | ```
43 |
44 |
45 | ### Initialization
46 |
47 | After successfully installation and configuration run the migrate, import and setup command to initialize the module in your project.
48 |
49 | 1.) Migrate your database.
50 |
51 | ```sh
52 | ./vendor/bin/luya migrate
53 | ```
54 |
55 | 2.) Import the module and migrations into your LUYA project.
56 |
57 | ```sh
58 | ./vendor/bin/luya import
59 | ```
60 |
61 | > Please note that the module names *cms* and *cmsadmin* are required and should not be changed!
62 |
63 | ## Developers
64 |
65 | If you want to contribute, make sure to read the [guidelines](https://luya.io/guide/dev/guideline).
66 |
67 | ## Unit Testing
68 |
69 | 1. `cp phpunit.xml.dist phpunit.xml`
70 | 2. `docker compose up`
71 | 3. `docker compose run luyacmsphpunit tests` to run all tests or `docker compose run luyacmsphpunit tests/src/helpers/UrlTest.php` to run a specific test.
72 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | Please use the email security@luya.io to report to us any security issue you find in LUYA.
4 | DO NOT use the issue tracker or discuss it in the public forum as it will cause more damage than help.
5 |
6 | Please note that as a non-commercial OpenSource project we are not able to pay bounties at the moment.
7 |
--------------------------------------------------------------------------------
/actions.phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 | ./tests
15 |
16 |
17 |
18 |
19 | ./vendor
20 | ./tests
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "luyadev/luya-module-cms",
3 | "description": "The LUYA CMS module provides a full functional Content Management System for adding contents based on blocks.",
4 | "type": "luya-core",
5 | "keywords": [
6 | "php",
7 | "luya",
8 | "module",
9 | "cms",
10 | "yii2",
11 | "yii",
12 | "contentmanager",
13 | "content",
14 | "yii2-cms"
15 | ],
16 | "license": "MIT",
17 | "homepage": "https://luya.io",
18 | "authors": [
19 | {
20 | "name": "Basil Suter",
21 | "email": "git@nadar.io",
22 | "homepage": "https://github.com/nadar"
23 | }
24 | ],
25 | "support": {
26 | "issues": "https://github.com/luyadev/luya-module-cms/issues"
27 | },
28 | "require": {
29 | "php": ">=8.0"
30 | },
31 | "require-dev": {
32 | "luyadev/luya-module-admin": "^5.0.0",
33 | "luyadev/luya-testsuite": "^3.1.4",
34 | "twbs/bootstrap": "^4.3.0",
35 | "unglue/client": "^1.3",
36 | "friendsofphp/php-cs-fixer": "^3.2",
37 | "phpstan/phpstan": "^1.7",
38 | "rector/rector": "^0.14.2"
39 | },
40 | "autoload": {
41 | "psr-4": {
42 | "luya\\cms\\": "src/"
43 | }
44 | },
45 | "autoload-dev": {
46 | "psr-4": {
47 | "cmstests\\": "tests/"
48 | }
49 | },
50 | "config": {
51 | "fxp-asset": {
52 | "enabled": false
53 | },
54 | "platform": {
55 | "php": "8.0"
56 | },
57 | "allow-plugins": {
58 | "yiisoft/yii2-composer": true,
59 | "luyadev/luya-composer": true
60 | }
61 | },
62 | "extra": {
63 | "luya": {
64 | "bootstrap": [
65 | "\\luya\\cms\\frontend\\Bootstrap"
66 | ],
67 | "blocks": [
68 | "src{{DS}}frontend{{DS}}blocks"
69 | ]
70 | }
71 | },
72 | "repositories": [
73 | {
74 | "type": "composer",
75 | "url": "https://asset-packagist.org"
76 | }
77 | ],
78 | "scripts": {
79 | "phpstan": "vendor/bin/phpstan -v",
80 | "phpcsfixer": "vendor/bin/php-cs-fixer fix",
81 | "rector": "vendor/bin/rector"
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 | services:
3 | luyacmsdb:
4 | image: mysql:5.7
5 | container_name: luyacmsdb
6 | volumes:
7 | - ./tests/data/sql/latest:/docker-entrypoint-initdb.d
8 | command:
9 | - --character-set-server=utf8
10 | - --collation-server=utf8_general_ci
11 | environment:
12 | MYSQL_ROOT_PASSWORD: luyacms
13 | MYSQL_DATABASE: luyacms
14 | MYSQL_USER: luyacms
15 | MYSQL_PASSWORD: luyacms
16 |
17 | luyacmscomposer:
18 | image: composer:latest
19 | volumes:
20 | - ./:/app
21 | command: composer install
22 |
23 | luyacmsphpunit:
24 | build: 'tests/'
25 | entrypoint: vendor/bin/phpunit
26 | volumes:
27 | - .:/app
28 | working_dir: /app
29 |
30 | luyacmsrector:
31 | image: php:8.0-cli
32 | entrypoint: vendor/bin/rector
33 | volumes:
34 | - .:/app
35 | working_dir: /app
36 |
37 |
--------------------------------------------------------------------------------
/log/testdox.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 0
3 | paths:
4 | - src
5 | bootstrapFiles:
6 | - vendor/yiisoft/yii2/Yii.php
7 | tmpDir: .tmp
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 | ./tests
15 |
16 |
17 |
18 |
19 | ./vendor
20 | ./tests
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/rector.php:
--------------------------------------------------------------------------------
1 | paths([
11 | __DIR__ . '/src'
12 | ]);
13 |
14 | // register a single rule
15 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
16 |
17 | // define sets of rules
18 | $rectorConfig->sets([
19 | LevelSetList::UP_TO_PHP_80
20 | ]);
21 |
22 | $rectorConfig->skip([
23 | __DIR__ . '/src/base/BlockInterface.php'
24 | ]);
25 | };
26 |
--------------------------------------------------------------------------------
/src/Exception.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | class Exception extends \luya\Exception
12 | {
13 | /**
14 | * @return string the user-friendly name of this exception
15 | */
16 | public function getName()
17 | {
18 | return 'CMS-Module Exception';
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/admin/apis/BlockController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class BlockController extends \luya\admin\ngrest\base\Api
14 | {
15 | public $modelClass = 'luya\cms\models\Block';
16 |
17 | public function actionToFav()
18 | {
19 | $block = Yii::$app->request->getBodyParam('block');
20 |
21 | if (!empty($block)) {
22 | return Yii::$app->adminuser->identity->setting->set("blockfav.{$block['id']}", $block);
23 | }
24 | }
25 |
26 | public function actionRemoveFav()
27 | {
28 | $block = Yii::$app->request->getBodyParam('block');
29 |
30 | if (!empty($block)) {
31 | return Yii::$app->adminuser->identity->setting->remove("blockfav.{$block['id']}");
32 | }
33 | }
34 |
35 | public function actionToggleGroup()
36 | {
37 | $group = Yii::$app->request->getBodyParam('group');
38 |
39 | if (!empty($group)) {
40 | return Yii::$app->adminuser->identity->setting->set("togglegroup.{$group['id']}", (int) $group['toggle_open']);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/admin/apis/BlockgroupController.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | class BlockgroupController extends \luya\admin\ngrest\base\Api
12 | {
13 | public $modelClass = 'luya\cms\models\BlockGroup';
14 | }
15 |
--------------------------------------------------------------------------------
/src/admin/apis/LayoutController.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | class LayoutController extends \luya\admin\ngrest\base\Api
12 | {
13 | public $modelClass = 'luya\cms\models\Layout';
14 | }
15 |
--------------------------------------------------------------------------------
/src/admin/apis/LogController.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | class NavContainerController extends \luya\admin\ngrest\base\Api
12 | {
13 | public $modelClass = 'luya\cms\models\NavContainer';
14 | }
15 |
--------------------------------------------------------------------------------
/src/admin/apis/NavItemBlockController.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.0
13 | */
14 | class NavItemBlockController extends \luya\admin\base\RestController
15 | {
16 | /**
17 | * Copy all attached sub blocks (referencing sourceId) into new context and update prevId to sourceId
18 | *
19 | * @param $sourceId
20 | * @param $targetPrevId
21 | * @param $targetNavItemPageId
22 | */
23 | private function copySubBlocksTo($sourceId, $targetPrevId, $targetNavItemPageId)
24 | {
25 | if ($sourceId) {
26 | $subBlocks = NavItemPageBlockItem::findAll(['prev_id' => $sourceId]);
27 | foreach ($subBlocks as $block) {
28 | $newBlock = new NavItemPageBlockItem();
29 | $newBlock->attributes = $block->toArray();
30 | $newBlock->nav_item_page_id = $targetNavItemPageId;
31 | $newBlock->prev_id = $targetPrevId;
32 | $newBlock->insert();
33 |
34 | // check for attached sub blocks and start recursion
35 | $attachedBlocks = NavItemPageBlockItem::findAll(['prev_id' => $block->id]);
36 | if ($attachedBlocks) {
37 | $this->copySubBlocksTo($block->id, $newBlock->id, $targetNavItemPageId);
38 | }
39 | }
40 | }
41 | }
42 |
43 | public function actionCopyBlockFromStack()
44 | {
45 | $model = NavItemPageBlockItem::findOne((int) Yii::$app->request->getBodyParam('copyBlockId', 0));
46 |
47 | if (($model) && ((Yii::$app->request->getBodyParam('copyBlockId', 0) !== Yii::$app->request->getBodyParam('prev_id', false)))) {
48 | $newModel = new NavItemPageBlockItem();
49 | $newModel->attributes = $model->toArray();
50 | $newModel->is_dirty = true;
51 | $newModel->prev_id = Yii::$app->request->getBodyParam('prev_id', false);
52 | $newModel->placeholder_var = Yii::$app->request->getBodyParam('placeholder_var', false);
53 | $newModel->sort_index = Yii::$app->request->getBodyParam('sort_index', false);
54 | $newModel->nav_item_page_id = Yii::$app->request->getBodyParam('nav_item_page_id', false);
55 |
56 | if ($newModel->insert()) {
57 | $this->copySubBlocksTo(Yii::$app->request->getBodyParam('copyBlockId', false), $newModel->id, $newModel->nav_item_page_id);
58 | return ['response' => true];
59 | }
60 | }
61 |
62 | return ['response' => false];
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/admin/apis/NavItemPageBlockItemController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class NavItemPageBlockItemController extends RestActiveController
14 | {
15 | public $modelClass = 'luya\cms\models\NavItemPageBlockItem';
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/apis/NavItemPageController.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.1
13 | */
14 | class NavItemPageController extends RestActiveController
15 | {
16 | public $modelClass = 'luya\cms\models\NavItemPage';
17 |
18 | /**
19 | * Returns all versions/pages for a given navItemId
20 | *
21 | * @param $navItemId
22 | * @return array
23 | */
24 | public function actionVersions($navItemId)
25 | {
26 | return NavItemPage::find()->where(['nav_item_id' => $navItemId])->asArray()->all();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/admin/apis/RedirectController.php:
--------------------------------------------------------------------------------
1 | request->pathInfo
24 | *
25 | * url: https://example.com/hello/world
26 | * path: hello/world
27 | *
28 | * @param string $path The path to check inside the redirect list.
29 | * @since 1.0.9
30 | */
31 | public function actionCatch($path)
32 | {
33 | $compositePath = Yii::$app->composition->prependTo($path);
34 | foreach (Redirect::find()->all() as $redirect) {
35 | if ($redirect->matchRequestPath($path)) {
36 | return $redirect;
37 | }
38 |
39 | // if its a multi linguage website and the language has not been omited form request path compare this version too.
40 | // this is requred since the luya UrlManager can change the pathInfo
41 | if ($path !== $compositePath) {
42 | if ($redirect->matchRequestPath($compositePath)) {
43 | return $redirect;
44 | }
45 | }
46 | }
47 |
48 | return false;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/admin/apis/ThemeController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 3.0.0
12 | */
13 | class ThemeController extends \luya\admin\ngrest\base\Api
14 | {
15 | public $modelClass = 'luya\cms\models\Theme';
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/apis/WebsiteController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 4.0.0
12 | */
13 | class WebsiteController extends \luya\admin\ngrest\base\Api
14 | {
15 | public $modelClass = 'luya\cms\models\Website';
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/assets/Main.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | class Main extends \yii\web\AssetBundle
12 | {
13 | /**
14 | * @inheritdoc
15 | */
16 | public $sourcePath = '@cmsadmin/resources';
17 |
18 | /**
19 | * @inheritdoc
20 | */
21 | public $js = [
22 | 'dist/main.js'
23 | ];
24 |
25 | /**
26 | * @inheritdoc
27 | */
28 | public $css = [
29 | 'dist/main.css',
30 | ];
31 |
32 | /**
33 | * @inheritdoc
34 | */
35 | public $depends = [
36 | 'luya\admin\assets\Main',
37 | ];
38 |
39 | /**
40 | * @inheritdoc
41 | */
42 | public $publishOptions = [
43 | 'except' => [
44 | 'node_modules/',
45 | ]
46 | ];
47 | }
48 |
--------------------------------------------------------------------------------
/src/admin/aws/BlockPagesActiveWindow.php:
--------------------------------------------------------------------------------
1 | model->translationName;
43 | }
44 |
45 | /**
46 | * The default action which is going to be requested when clicking the ActiveWindow.
47 | *
48 | * @return string The response string, render and displayed trough the angular ajax request.
49 | */
50 | public function index()
51 | {
52 | return $this->render('index', [
53 | 'blocks' => $this->model->getNavItemPageBlockItems()
54 | ->select(['nav_item_page_id', 'is_hidden', 'title'])
55 | ->with(['navItemPage.forceNavItem.lang', 'navItemPage.forceNavItem.nav'])
56 | ->joinWith(['navItemPage.forceNavItem'])
57 | ->distinct()
58 | ->orderBy(['title' => SORT_ASC])
59 | ->all(),
60 | ]);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/admin/controllers/BlockController.php:
--------------------------------------------------------------------------------
1 |
13 | * @since 1.0.0
14 | */
15 | class BlockController extends Controller
16 | {
17 | public $modelClass = 'luya\cms\models\Block';
18 |
19 | /**
20 | * Generate the the block preview.
21 | *
22 | * @param int $blockId
23 | * @return string
24 | * @throws NotFoundHttpException
25 | * @since 1.0.8
26 | */
27 | public function actionPreview($blockId)
28 | {
29 | $blockItem = Block::findOne($blockId);
30 | if (!$blockItem) {
31 | throw new NotFoundHttpException();
32 | }
33 |
34 | /** @var $blockObject \luya\cms\base\InternalBaseBlock */
35 | $blockObject = $blockItem->getObject('preview', 'admin-preview');
36 |
37 | return $blockObject->renderAdminPreview();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/admin/controllers/BlockgroupController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class BlockgroupController extends Controller
14 | {
15 | public $modelClass = 'luya\cms\models\BlockGroup';
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/controllers/ConfigController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class ConfigController extends Controller
14 | {
15 | public function actionIndex()
16 | {
17 | return $this->render('index');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/admin/controllers/DefaultController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class DefaultController extends Controller
14 | {
15 | public function actionIndex()
16 | {
17 | return $this->render('index');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/admin/controllers/LayoutController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class LayoutController extends Controller
14 | {
15 | public $modelClass = 'luya\cms\models\Layout';
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/controllers/LogController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class NavcontainerController extends Controller
14 | {
15 | public $modelClass = 'luya\cms\models\NavContainer';
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/controllers/PageController.php:
--------------------------------------------------------------------------------
1 |
15 | * @since 1.0.0
16 | */
17 | class PageController extends Controller
18 | {
19 | public function actionCreate()
20 | {
21 | return $this->render('create');
22 | }
23 |
24 | public function actionUpdate()
25 | {
26 | return $this->render('update', [
27 | 'canBlockUpdate' => Yii::$app->auth->matchApi(Yii::$app->adminuser->id, 'api-cms-navitempageblockitem', Auth::CAN_UPDATE),
28 | 'canBlockDelete' => Yii::$app->auth->matchApi(Yii::$app->adminuser->id, 'api-cms-navitempageblockitem', Auth::CAN_DELETE),
29 | 'canBlockCreate' => Yii::$app->auth->matchApi(Yii::$app->adminuser->id, 'api-cms-navitempageblockitem', Auth::CAN_CREATE),
30 | ]);
31 | }
32 |
33 | public function actionDrafts()
34 | {
35 | return $this->render('drafts');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/admin/controllers/PermissionController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class PermissionController extends Controller
14 | {
15 | public function actionIndex()
16 | {
17 | return $this->render('index');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/admin/controllers/RedirectController.php:
--------------------------------------------------------------------------------
1 |
13 | * @since 3.0.0
14 | */
15 | class ThemeController extends Controller
16 | {
17 | public $modelClass = 'luya\cms\models\Theme';
18 | }
19 |
--------------------------------------------------------------------------------
/src/admin/controllers/WebsiteController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 4.0.0
12 | */
13 | class WebsiteController extends Controller
14 | {
15 | public $modelClass = 'luya\cms\models\Website';
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/importers/PropertyConsistencyImporter.php:
--------------------------------------------------------------------------------
1 |
13 | * @since 1.0.0
14 | */
15 | class PropertyConsistencyImporter extends Importer
16 | {
17 | public $queueListPosition = self::QUEUE_POSITION_LAST;
18 |
19 | public function run()
20 | {
21 | foreach (CmsProperty::find()->all() as $cmsPropertyModel) {
22 | $adminProperty = AdminProperty::findOne($cmsPropertyModel->admin_prop_id);
23 | if (!$adminProperty) {
24 | $cmsPropertyModel->delete();
25 | $this->addLog('Old property values has been removed due to not existing property object.');
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/admin/migrations/m141203_143052_cms_cat.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | class m141203_143052_cms_cat extends Migration
14 | {
15 | public function safeUp()
16 | {
17 | $this->createTable('cms_nav_container', [
18 | 'id' => $this->primaryKey(),
19 | 'name' => $this->string(180)->notNull(),
20 | 'alias' => $this->string(180)->notNull(),
21 | 'is_deleted' => $this->boolean()->defaultValue(false),
22 | ]);
23 | }
24 |
25 | public function safeDown()
26 | {
27 | $this->dropTable('cms_nav_container');
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/admin/migrations/m141203_143059_cms_nav.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav', [
10 | 'id' => $this->primaryKey(),
11 | 'nav_container_id' => $this->integer(11)->notNull(),
12 | 'parent_nav_id' => $this->integer(11)->notNull(),
13 | 'sort_index' => $this->integer(11)->notNull(),
14 | 'is_deleted' => $this->boolean()->defaultValue(false),
15 | 'is_hidden' => $this->boolean()->defaultValue(false),
16 | 'is_home' => $this->boolean()->defaultValue(false),
17 | 'is_offline' => $this->boolean()->defaultValue(false),
18 | 'is_draft' => $this->boolean()->defaultValue(false),
19 | ]);
20 | }
21 |
22 | public function safeDown()
23 | {
24 | $this->dropTable('cms_nav');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/admin/migrations/m141203_143111_cms_nav_item.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav_item', [
11 | 'id' => $this->primaryKey(),
12 | 'nav_id' => $this->integer(11)->notNull(),
13 | 'lang_id' => $this->integer(11)->notNull(),
14 | 'nav_item_type' => $this->integer(11)->notNull(),
15 | 'nav_item_type_id' => $this->integer(11)->notNull(),
16 | 'create_user_id' => $this->integer(11)->notNull(),
17 | 'update_user_id' => $this->integer(11)->notNull(),
18 | 'timestamp_create' => $this->integer(11)->defaultValue(0),
19 | 'timestamp_update' => $this->integer(11)->defaultValue(0),
20 | 'title' => $this->string(180)->notNull(),
21 | 'alias' => $this->string(80)->notNull(),
22 | 'description' => $this->text(),
23 | 'keywords' => $this->text(),
24 | 'title_tag' => $this->string(255),
25 | ]);
26 | }
27 |
28 | public function safeDown()
29 | {
30 | $this->dropTable('cms_nav_item');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/admin/migrations/m141208_134038_cms_nav_item_page.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav_item_page', [
11 | 'id' => $this->primaryKey(),
12 | 'layout_id' => $this->integer(11)->notNull(),
13 | 'nav_item_id' => $this->integer(11)->notNull(),
14 | 'timestamp_create' => $this->integer(11)->notNull(),
15 | 'create_user_id' => $this->integer(11)->notNull(),
16 | 'version_alias' => $this->string(250),
17 | ]);
18 | }
19 |
20 | public function safeDown()
21 | {
22 | $this->dropTable('cms_nav_item_page');
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/admin/migrations/m150106_095003_cms_layout.php:
--------------------------------------------------------------------------------
1 | createTable('cms_layout', [
11 | 'id' => $this->primaryKey(),
12 | 'name' => $this->string(255),
13 | 'json_config' => $this->text(),
14 | 'view_file' => $this->string(255),
15 | ]);
16 | }
17 |
18 | public function safeDown()
19 | {
20 | $this->dropTable('cms_layout');
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/admin/migrations/m150108_154017_cms_block.php:
--------------------------------------------------------------------------------
1 | createTable('cms_block', [
11 | 'id' => $this->primaryKey(),
12 | 'group_id' => $this->integer(11)->notNull(),
13 | 'class' => $this->string(255)->notNull(),
14 | ]);
15 | }
16 |
17 | public function safeDown()
18 | {
19 | $this->dropTable('cms_block');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/admin/migrations/m150108_155009_cms_nav_item_page_block_item.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav_item_page_block_item', [
11 | 'id' => $this->primaryKey(),
12 | 'block_id' => $this->integer(11)->notNull(),
13 | 'placeholder_var' => $this->string(80)->notNull(),
14 | 'nav_item_page_id' => $this->integer(11),
15 | 'prev_id' => $this->integer(11),
16 | 'json_config_values' => $this->text(),
17 | 'json_config_cfg_values' => $this->text(),
18 | 'is_dirty' => $this->boolean()->defaultValue(false),
19 | 'create_user_id' => $this->integer(11)->defaultValue(0),
20 | 'update_user_id' => $this->integer(11)->defaultValue(0),
21 | 'timestamp_create' => $this->integer(11)->defaultValue(0),
22 | 'timestamp_update' => $this->integer(11)->defaultValue(0),
23 | 'sort_index' => $this->integer(11)->defaultValue(0),
24 | 'is_hidden' => $this->boolean()->defaultValue(false),
25 | ]);
26 | }
27 |
28 | public function safeDown()
29 | {
30 | $this->dropTable('cms_nav_item_page_block_item');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/admin/migrations/m150122_125429_cms_nav_item_module.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav_item_module', [
11 | 'id' => $this->primaryKey(),
12 | 'module_name' => $this->string(255)->notNull(),
13 | ]);
14 | }
15 |
16 | public function safeDown()
17 | {
18 | $this->dropTable('cms_nav_item_module');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/admin/migrations/m150205_141350_block_group.php:
--------------------------------------------------------------------------------
1 | createTable('cms_block_group', [
11 | 'id' => $this->primaryKey(),
12 | 'name' => $this->string(255)->notNull(),
13 | 'is_deleted' => $this->boolean()->defaultValue(false),
14 | 'identifier' => $this->string(120)->notNull(),
15 | 'created_timestamp' => $this->integer(11)->defaultValue(0),
16 | ]);
17 | }
18 |
19 | public function safeDown()
20 | {
21 | $this->dropTable('cms_block_group');
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/admin/migrations/m150924_112309_cms_nav_prop.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav_property', [
10 | 'id' => $this->primaryKey(),
11 | 'nav_id' => $this->integer(11)->notNull(),
12 | 'admin_prop_id' => $this->integer(11)->notNull(),
13 | 'value' => $this->text(),
14 | ]);
15 | }
16 |
17 | public function safeDown()
18 | {
19 | $this->dropTable('cms_nav_property');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/admin/migrations/m151012_072207_cms_log.php:
--------------------------------------------------------------------------------
1 | createTable('cms_log', [
10 | 'id' => $this->primaryKey(),
11 | 'user_id' => $this->integer()->defaultValue(0),
12 | 'is_insertion' => $this->boolean()->defaultValue(false),
13 | 'is_update' => $this->boolean()->defaultValue(false),
14 | 'is_deletion' => $this->boolean()->defaultValue(false),
15 | 'timestamp' => $this->integer(11)->notNull(),
16 | 'message' => $this->string(255),
17 | 'data_json' => $this->text(),
18 | 'table_name' => $this->string(120),
19 | 'row_id' => $this->integer(11)->defaultValue(0),
20 | ]);
21 | }
22 |
23 | public function safeDown()
24 | {
25 | $this->dropTable('cms_log');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/admin/migrations/m151022_143429_cms_nav_item_redirect.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav_item_redirect', [
10 | 'id' => $this->primaryKey(),
11 | 'type' => $this->integer(11)->notNull(),
12 | 'value' => $this->string(255)->notNull(),
13 | ]);
14 | }
15 |
16 | public function safeDown()
17 | {
18 | $this->dropTable('cms_nav_item_redirect');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/admin/migrations/m160629_092417_cmspermissiontable.php:
--------------------------------------------------------------------------------
1 | createTable('cms_nav_permission', [
10 | 'group_id' => $this->integer(11)->notNull(),
11 | 'nav_id' => $this->integer(11)->notNull(),
12 | 'inheritance' => $this->boolean()->defaultValue(false),
13 | ]);
14 | }
15 |
16 | public function safeDown()
17 | {
18 | $this->dropTable('cms_nav_permission');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/admin/migrations/m170116_120553_cms_block_variation_field.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav_item_page_block_item', 'variation', $this->string(255)->defaultValue(0));
10 | }
11 |
12 | public function safeDown()
13 | {
14 | $this->dropColumn('cms_nav_item_page_block_item', 'variation');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/migrations/m170218_215610_cms_nav_layout_file.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav', 'layout_file', $this->string());
11 | }
12 |
13 | public function safeDown()
14 | {
15 | $this->dropColumn('cms_nav', 'layout_file');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/admin/migrations/m170301_084325_cms_config.php:
--------------------------------------------------------------------------------
1 | createTable('cms_config', [
11 | 'name' => $this->string(80),
12 | 'value' => $this->string(255)->notNull(),
13 | 'PRIMARY KEY(name)',
14 | ]);
15 | }
16 |
17 | public function safeDown()
18 | {
19 | $this->dropTable('cms_config');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/admin/migrations/m170619_103728_cms_blocksettings.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_block', 'is_disabled', $this->boolean()->defaultValue(false));
10 | }
11 |
12 | public function safeDown()
13 | {
14 | $this->dropColumn('cms_block', 'is_disabled');
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/admin/migrations/m171003_065811_add_class_column_to_block_group_table.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_block_group', 'class', $this->string()->notNull()->defaultValue(null)); // default value supports upgrading and sync from previous system.s
16 | }
17 |
18 | /**
19 | * @inheritdoc
20 | */
21 | public function safeDown()
22 | {
23 | $this->dropColumn('cms_block_group', 'class');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/admin/migrations/m171121_170909_add_publish_at_date.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav', 'publish_from', $this->integer()->null());
10 | $this->addColumn('cms_nav', 'publish_till', $this->integer()->null());
11 | }
12 |
13 | public function safeDown()
14 | {
15 | $this->dropColumn('cms_nav', 'publish_from');
16 | $this->dropColumn('cms_nav', 'publish_till');
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/admin/migrations/m171206_113949_cms_redirection_table.php:
--------------------------------------------------------------------------------
1 | createTable('cms_redirect', [
16 | 'id' => $this->primaryKey(),
17 | 'timestamp_create' => $this->integer(),
18 | 'catch_path' => $this->string()->notNull(),
19 | 'redirect_path' => $this->string()->notNull(),
20 | 'redirect_status_code' => $this->integer()->notNull(),
21 | ]);
22 | }
23 |
24 | /**
25 | * @inheritdoc
26 | */
27 | public function safeDown()
28 | {
29 | $this->dropTable('cms_redirect');
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/admin/migrations/m190219_142706_og_image.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav_item', 'image_id', $this->integer());
16 | }
17 |
18 | /**
19 | * {@inheritdoc}
20 | */
21 | public function safeDown()
22 | {
23 | $this->dropColumn('cms_nav_item', 'image_id');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/admin/migrations/m190220_105505_cms_redirect_target_field.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav_item_redirect', 'target', $this->string());
16 | }
17 |
18 | /**
19 | * {@inheritdoc}
20 | */
21 | public function safeDown()
22 | {
23 | $this->dropColumn('cms_nav_item_redirect', 'target');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/admin/migrations/m190227_123549_cms_nav_item_strict_url_parsing.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav_item', 'is_url_strict_parsing_disabled', $this->boolean()->defaultValue(false));
16 | }
17 |
18 | /**
19 | * {@inheritdoc}
20 | */
21 | public function safeDown()
22 | {
23 | $this->dropColumn('cms_nav_item', 'is_url_strict_parsing_disabled');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/admin/migrations/m190529_123549_cms_nav_item_module_route_and_params.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav_item_module', 'controller_name', $this->string());
16 | $this->addColumn('cms_nav_item_module', 'action_name', $this->string());
17 | $this->addColumn('cms_nav_item_module', 'action_params', $this->text());
18 | }
19 |
20 | /**
21 | * {@inheritdoc}
22 | */
23 | public function safeDown()
24 | {
25 | $this->dropColumn('cms_nav_item_module', 'controller_name');
26 | $this->dropColumn('cms_nav_item_module', 'action_name');
27 | $this->dropColumn('cms_nav_item_module', 'action_params');
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/admin/migrations/m190728_084936_cms_theme.php:
--------------------------------------------------------------------------------
1 | createTable('cms_theme', [
13 | 'id' => $this->primaryKey(),
14 | 'is_active' => $this->boolean()->defaultValue(false),
15 | 'base_path' => $this->string(191)->notNull()->unique(),
16 | 'json_config' => $this->text()->notNull(),
17 | ]);
18 | }
19 |
20 | public function safeDown()
21 | {
22 | $this->dropTable('cms_theme');
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/admin/migrations/m200226_211908_nav_item_is_cacheable.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav_item', 'is_cacheable', $this->boolean()->defaultValue(false));
16 | }
17 |
18 | /**
19 | * {@inheritdoc}
20 | */
21 | public function safeDown()
22 | {
23 | $this->dropColumn('cms_nav_item', 'is_cacheable');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/admin/migrations/m200706_202002_cms_website.php:
--------------------------------------------------------------------------------
1 | createTable('cms_website', [
16 | 'id' => $this->primaryKey(),
17 | 'name' => $this->string(120)->unique()->notNull(),
18 | 'is_default' => $this->boolean()->notNull()->defaultValue(false),
19 | 'is_active' => $this->boolean()->notNull()->defaultValue(false),
20 | 'is_deleted' => $this->boolean()->notNull()->defaultValue(false),
21 | 'host' => $this->string(191)->unique()->notNull(),
22 | 'aliases' => $this->string(255)->null()->defaultValue(null),
23 | 'redirect_to_host' => $this->boolean()->notNull()->defaultValue(false),
24 | 'theme_id' => $this->integer()->defaultValue(null),
25 | 'default_lang' => $this->string(2)->defaultValue(null),
26 | ]);
27 |
28 | $this->insert('cms_website', [
29 | 'id' => 1,
30 | 'name' => 'default',
31 | 'is_default' => true,
32 | 'is_active' => true,
33 | 'host' => '',
34 | 'theme_id' => $this->db->createCommand('SELECT id FROM cms_theme WHERE is_active = 1')->queryScalar() ?: null
35 | ]);
36 |
37 | $this->addColumn('cms_nav_container', 'website_id', $this->integer()->notNull()->defaultValue(1)->after('id'));
38 |
39 | $this->alterColumn('cms_nav', 'parent_nav_id', $this->integer(11)->notNull()->defaultValue(0));
40 |
41 | $this->alterColumn('cms_nav_item_page', 'nav_item_id', $this->integer(11)->defaultValue(null));
42 | $this->update('cms_nav_item_page', ['nav_item_id' => 0], ['nav_item_id' => null]);
43 |
44 | // $this->alterColumn('cms_nav', 'parent_nav_id', $this->integer(11)->defaultValue(null));
45 | // $this->update('cms_nav', ['parent_nav_id' => null], ['parent_nav_id' => 0]);
46 |
47 | $this->renameColumn('cms_theme', 'is_active', 'is_default');
48 | }
49 |
50 | /**
51 | * {@inheritdoc}
52 | */
53 | public function safeDown()
54 | {
55 | $this->dropColumn('cms_nav_container', 'website_id');
56 | $this->dropTable('cms_website');
57 | $this->renameColumn('cms_theme', 'is_default', 'is_active');
58 |
59 | return true;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/admin/migrations/m210605_172811_cms_website_permissions.php:
--------------------------------------------------------------------------------
1 | addColumn(Website::tableName(), 'group_ids', $this->text());
17 | $this->addColumn(Website::tableName(), 'user_ids', $this->text());
18 |
19 | $this->update(Website::tableName(), [
20 | 'group_ids' => '[{"value":0}]',
21 | 'user_ids' => '[{"value":0}]',
22 | ]);
23 | }
24 |
25 | /**
26 | * {@inheritdoc}
27 | */
28 | public function safeDown()
29 | {
30 | $this->dropColumn(Website::tableName(), 'group_ids');
31 | $this->dropColumn(Website::tableName(), 'user_ids');
32 |
33 | return true;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/admin/migrations/m210708_091145_v4.php:
--------------------------------------------------------------------------------
1 | addColumn('cms_nav_item_page', 'timestamp_update', $this->integer());
16 | $this->alterColumn('cms_nav_item', 'alias', $this->string(180)->notNull());
17 | }
18 |
19 | /**
20 | * {@inheritdoc}
21 | */
22 | public function safeDown()
23 | {
24 | $this->dropColumn('cms_nav_item_page', 'timestamp_update');
25 | $this->alterColumn('cms_nav_item', 'alias', $this->string(80)->notNull());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/admin/migrations/m230720_130000_page_link_anchor.php:
--------------------------------------------------------------------------------
1 | addColumn(NavItemRedirect::tableName(), 'anchor', $this->string());
17 | }
18 |
19 | /**
20 | * {@inheritdoc}
21 | */
22 | public function safeDown()
23 | {
24 | $this->dropColumn(NavItemRedirect::tableName(), 'anchor');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/admin/resources/dist/main.unglue:
--------------------------------------------------------------------------------
1 | {
2 | "js" : [
3 | "../js/cmsadmin.js",
4 | "../js/services.js"
5 | ],
6 | "css": [
7 | "../scss/cmsadmin.scss"
8 | ],
9 | "options": {
10 | "compress" : false,
11 | "maps" : true
12 | }
13 | }
--------------------------------------------------------------------------------
/src/admin/resources/img/empty-placeholder-arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyadev/luya-module-cms/8a3472acfc2620374fb8de6aed1f2736926cca2b/src/admin/resources/img/empty-placeholder-arrow.png
--------------------------------------------------------------------------------
/src/admin/resources/scss/browser-fixes/_ie.scss:
--------------------------------------------------------------------------------
1 | // Internet Explorer
2 |
3 | // IE 10
4 | body[class*='internet-explorer-'] {
5 |
6 | /**
7 | * ====================
8 | * Block
9 | * ====================
10 | */
11 |
12 | .block-toolbar {
13 | display: none;
14 | }
15 |
16 | .block:hover > .block-toolbar,
17 | .block-is-layout > .block-toolbar,
18 | .block-is-layout:hover > .block-toolbar {
19 | display: flex;
20 | }
21 |
22 | .cmsadmin-frame {
23 | height: calc(100vh - 25px);
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/src/admin/resources/scss/browser-fixes/_safari.scss:
--------------------------------------------------------------------------------
1 | body[class*='safari'] {
2 | }
--------------------------------------------------------------------------------
/src/admin/resources/scss/cmsadmin.scss:
--------------------------------------------------------------------------------
1 | // ==================================================
2 | // Include Bootstrap Mixins / Functions
3 | // ==================================================
4 |
5 | @import "../../../../vendor/twbs/bootstrap/scss/mixins/clearfix";
6 | @import "../../../../vendor/twbs/bootstrap/scss/functions";
7 |
8 | // ==================================================
9 | // Variables
10 | // ==================================================
11 |
12 | @import "../../../../vendor/luyadev/luya-module-admin/src/resources/scss/variables/colors";
13 | @import "../../../../vendor/luyadev/luya-module-admin/src/resources/scss/variables/bootstrap";
14 | @import "../../../../vendor/luyadev/luya-module-admin/src/resources/scss/variables/custom";
15 | @import "../../../../vendor/luyadev/luya-module-admin/src/resources/scss/variables/flags";
16 | @import "../../../../vendor/luyadev/luya-module-admin/src/resources/scss/variables/zindex";
17 |
18 | // ==================================================
19 | // Include Bootstrap variables
20 | // ==================================================
21 |
22 | @import "../../../../vendor/twbs/bootstrap/scss/variables";
23 |
24 | // ==================================================
25 | // Helpers
26 | // ==================================================
27 |
28 | @import "../../../../vendor/luyadev/luya-module-admin/src/resources/scss/helpers/google-chrome-font-offset-fix";
29 | @import "../../../../vendor/luyadev/luya-module-admin/src/resources/scss/helpers/zindex";
30 |
31 |
32 | // ==================================================
33 | // Variables
34 | // ==================================================
35 |
36 | @import "variables/variables";
37 |
38 | // ==================================================
39 | // Components
40 | // ==================================================
41 |
42 | @import "components/block";
43 | @import "components/block-elements";
44 | @import "components/blockholder";
45 | @import "components/card";
46 | @import "components/cmsadmin";
47 | @import "components/cmsnav";
48 | @import "components/empty-placeholder";
49 | @import "components/menu-dropdown";
50 | @import "components/toolbar";
51 | @import "components/treeview";
52 |
53 | // ==================================================
54 | // Browser fixes – always last cause they suck balls
55 | // ==================================================
56 |
57 | @import "browser-fixes/ie";
58 | @import "browser-fixes/safari";
59 |
--------------------------------------------------------------------------------
/src/admin/resources/scss/components/_block-elements.scss:
--------------------------------------------------------------------------------
1 | .block-front {
2 |
3 | h1, h2, h3, h4, h5 {
4 | color: $black;
5 | }
6 |
7 | > *:last-of-type {
8 | margin-bottom: 0;
9 | }
10 |
11 | table {
12 | margin: 0;
13 |
14 | td > p:first-of-type:last-of-type,
15 | th > p:first-of-type:last-of-type {
16 | margin: 0;
17 | }
18 | }
19 |
20 | hr {
21 | margin-bottom: 1rem !important;
22 | margin-top: 1rem !important;
23 | }
24 |
25 | img {
26 | max-width: 100%;
27 | width: auto;
28 | }
29 |
30 | blockquote {
31 | background-color: map-get($grays, 100);
32 | border-left: 3px solid theme-color(primary);
33 | display: block;
34 | padding: 15px;
35 | position: relative;
36 | width: 100%;
37 |
38 | p {
39 | font-family: $font-family-sans-serif;
40 | font-style: italic;
41 | margin: 0;
42 | position: relative;
43 | text-indent: 40px;
44 |
45 | &:before {
46 | color: theme-color(primary);
47 | content: '\201C';
48 | font-size: 70px;
49 | font-weight: 700;
50 | left: 0;
51 | line-height: 0;
52 | position: absolute;
53 | text-indent: 0;
54 | text-shadow: 3px 7px 5px rgba(0, 0, 0, 0.1);
55 | top: 20px;
56 | }
57 | }
58 | }
59 |
60 | iframe {
61 | max-width: 100%;
62 | }
63 |
64 | .iframe-container {
65 | height: 0;
66 | margin: 0;
67 | overflow: hidden;
68 | padding-bottom: 56.25%; /* ratio 16x9 */
69 | pointer-events: none;
70 | position: relative;
71 | width: 100%;
72 |
73 | iframe {
74 | height: 100%;
75 | left: 0;
76 | position: absolute;
77 | top: 0;
78 | width: 100%;
79 | }
80 | }
81 |
82 | }
--------------------------------------------------------------------------------
/src/admin/resources/scss/components/_card.scss:
--------------------------------------------------------------------------------
1 | // Extend default bootstrap card behaviour
2 |
3 | .card-no-container-title {
4 | .block-front .row:not(:first-of-type) & {
5 | margin-top: 5px;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/admin/resources/scss/components/_cmsnav.scss:
--------------------------------------------------------------------------------
1 | .cmsnav {
2 | display: block;
3 | margin-bottom: 10px;
4 | width: 100%;
5 | }
6 |
7 | // ==================================================
8 | // General lists
9 | // ==================================================
10 |
11 | .cmsnav-list {
12 | display: block;
13 | list-style: none;
14 | margin: 0;
15 | padding: 0;
16 |
17 | &:not(:first-of-type) {
18 | margin-top: 15px;
19 | }
20 | }
21 |
22 | // ==================================================
23 | // Buttons
24 | // ==================================================
25 |
26 | .cmsnav-button:not(:first-of-type) {
27 | margin-top: 5px;
28 | }
29 |
30 | // ==================================================
31 | // Switches
32 | // ==================================================
33 |
34 |
35 |
36 | // ==================================================
37 | // Treeview
38 | // ==================================================
39 |
40 | .cmsnav-treeview {
41 | display: block;
42 | }
--------------------------------------------------------------------------------
/src/admin/resources/scss/components/_empty-placeholder.scss:
--------------------------------------------------------------------------------
1 | .empty-placeholder {
2 | padding: 10px;
3 | text-align: center;
4 |
5 | &--drag-hover {
6 | background-color: theme-color(primary);
7 | color: $white;
8 | }
9 | }
--------------------------------------------------------------------------------
/src/admin/resources/scss/components/_menu-dropdown.scss:
--------------------------------------------------------------------------------
1 | .menu-dropdown {
2 | clear: both;
3 | display: block;
4 | padding-top: 10px;
5 |
6 | .form-side > & {
7 | padding-top: 0;
8 | }
9 | }
10 |
11 | .menu-dropdown-toggle-all {
12 | font-size: 14px;
13 | cursor: pointer;
14 |
15 | i {
16 | font-size: 24px;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/admin/resources/scss/components/_toolbar.scss:
--------------------------------------------------------------------------------
1 | .toolbar-item {
2 | flex: 0 0 auto;
3 | padding: 0 20px;
4 |
5 | &:first-of-type {
6 | padding-left: 0;
7 | }
8 | &-lang + .toolbar-item:not(.toolbar-item-lang) {
9 | border-left: 1px solid $nav-tabs-border-color;
10 | }
11 |
12 | &:last-of-type {
13 | padding-right: 0;
14 | }
15 |
16 | &-lang {
17 | padding: 5px 10px;
18 | }
19 | }
--------------------------------------------------------------------------------
/src/admin/resources/scss/variables/_variables.scss:
--------------------------------------------------------------------------------
1 | $block-border-width: 1px !default;
2 | $block-border-color: map-get($grays, 500) !default;
3 | $block-padding: 10px !default;
4 |
5 | $blockholder-width: 255px;
6 | $blockholder-width-small: 48px;
--------------------------------------------------------------------------------
/src/admin/views/aws/blockpages/index.php:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 | = Module::t('aws_block_pages_title_label'); ?> |
17 | = Module::t('aws_block_pages_language_label'); ?> |
18 | = Module::t('aws_block_pages_version_label'); ?> |
19 | = Module::t('aws_block_pages_block_visible_label'); ?> |
20 | = Module::t('aws_block_pages_last_updated_label'); ?> |
21 | = Module::t('aws_block_pages_created_label'); ?> |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | = $block->navItemPage->forceNavItem->nav->is_hidden ? 'visibility_off' : 'visibility'; ?>
30 |
31 |
32 |
33 | = $block->navItemPage->forceNavItem->nav->is_offline ? 'cloud_off' : 'cloud_queue'; ?>
34 |
35 |
36 | = $block->navItemPage->forceNavItem->title; ?>
37 | |
38 | = $block->navItemPage->forceNavItem->lang->name; ?> |
39 | = $block->navItemPage->version_alias; ?> |
40 | = Yii::$app->formatter->asBoolean(!$block->is_hidden); ?> |
41 | = Yii::$app->formatter->asDate($block->navItemPage->forceNavItem->timestamp_update); ?> |
42 | = Yii::$app->formatter->asDate($block->navItemPage->forceNavItem->timestamp_create); ?> |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/admin/views/config/index.php:
--------------------------------------------------------------------------------
1 |
5 | = Module::t('menu_group_item_env_config'); ?>
6 |
7 |
8 |
9 |
10 | = Module::t('config_index_httpexceptionnavid'); ?> |
11 | |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/admin/views/page/create.php:
--------------------------------------------------------------------------------
1 |
5 |
6 |
= Module::t('view_index_add_title'); ?>
7 |
8 |
--------------------------------------------------------------------------------
/src/admin/views/page/drafts.php:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | |
13 | |
14 |
15 |
16 |
17 | {{item.title}} |
18 |
19 | |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/base/BlockCfg.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | class BlockCfg extends BlockConfigElement
12 | {
13 | public function toArray()
14 | {
15 | return [
16 | 'id' => $this->id,
17 | 'var' => $this->item['var'],
18 | 'label' => $this->item['label'],
19 | 'type' => $this->item['type'],
20 | 'placeholder' => $this->get('placeholder'),
21 | 'options' => $this->get('options'),
22 | 'initvalue' => $this->get('initvalue'),
23 | 'required' => $this->get('required', 0),
24 | ];
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/base/BlockConfigElement.php:
--------------------------------------------------------------------------------
1 |
17 | * @since 1.0.0
18 | */
19 | abstract class BlockConfigElement
20 | {
21 | protected $id;
22 |
23 | /**
24 | *
25 | * @param array $item The element config with all fields.
26 | * @throws Exception
27 | */
28 | public function __construct(public array $item)
29 | {
30 | if (!$this->has(['var', 'label', 'type'])) {
31 | throw new Exception('Required attributes in config var element is missing. var, label and type are required.');
32 | }
33 | $this->id = md5($this->get('var').uniqid());
34 | }
35 |
36 | /**
37 | * Has the config element an element or not.
38 | *
39 | * @param string $key
40 | * @return boolean
41 | */
42 | protected function has($key)
43 | {
44 | if (!is_array($key)) {
45 | return (array_key_exists($key, $this->item));
46 | }
47 |
48 | foreach ($key as $value) {
49 | if (!array_key_exists($value, $this->item)) {
50 | return false;
51 | }
52 | }
53 |
54 | return true;
55 | }
56 |
57 | /**
58 | * Get the element value.
59 | *
60 | * @param string $key
61 | * @return string
62 | */
63 | protected function get($key, mixed $default = null)
64 | {
65 | if (!$this->has($key)) {
66 | return $default;
67 | }
68 |
69 | return $this->item[$key];
70 | }
71 |
72 | /**
73 | * Extract the data from the element.
74 | *
75 | * @return array
76 | */
77 | abstract public function toArray();
78 | }
79 |
--------------------------------------------------------------------------------
/src/base/BlockGroup.php:
--------------------------------------------------------------------------------
1 |
15 | * @since 1.0.0
16 | */
17 | abstract class BlockGroup extends BaseObject
18 | {
19 | /**
20 | * The unique identifier of the block group
21 | *
22 | * @return string
23 | */
24 | abstract public function identifier();
25 |
26 | /**
27 | * The label used in the administration are for this group
28 | *
29 | * @return string
30 | */
31 | abstract public function label();
32 |
33 | /**
34 | * The position index, lower will be a the top, higher will be at the bottom of the blocks list.
35 | *
36 | * Endless Numbers are available.
37 | *
38 | * @return number The number for sort position in the administration area. 0 = Top, 100 = Bottom.
39 | */
40 | public function getPosition()
41 | {
42 | return 50;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/base/BlockVar.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | class BlockVar extends BlockConfigElement
12 | {
13 | public function toArray()
14 | {
15 | return [
16 | 'id' => $this->id,
17 | 'var' => $this->item['var'],
18 | 'label' => $this->item['label'],
19 | 'type' => $this->item['type'],
20 | 'placeholder' => $this->get('placeholder'),
21 | 'options' => $this->get('options'),
22 | 'initvalue' => $this->get('initvalue'),
23 | 'required' => $this->get('required', 0),
24 | ];
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/base/NavItemType.php:
--------------------------------------------------------------------------------
1 |
17 | * @since 1.0.0
18 | */
19 | abstract class NavItemType extends ActiveRecord implements NavItemTypeInterface
20 | {
21 | /**
22 | * Get the response content for the item type
23 | *
24 | * @return mixed
25 | */
26 | abstract public function getContent();
27 |
28 | /**
29 | * Get the corresponding nav item type for this type object
30 | *
31 | * @return NavItem An active record type.
32 | */
33 | public function getNavItem()
34 | {
35 | return $this->hasOne(NavItem::class, ['nav_item_type_id' => 'id'])->where(['nav_item_type' => static::getNummericType()]);
36 | }
37 |
38 | /**
39 | * Context properts array.
40 | *
41 | * @return array
42 | */
43 | public function getContextPropertysArray()
44 | {
45 | return []; // override
46 | }
47 |
48 | private $_controller;
49 |
50 | /**
51 | * Setter method to store the current controller Object
52 | * @param Controller $controller The controller object.
53 | */
54 | public function setController(Controller $controller)
55 | {
56 | $this->_controller = $controller;
57 | }
58 |
59 | /**
60 | * Getter method for the controller object.
61 | *
62 | * @return Controller
63 | */
64 | public function getController()
65 | {
66 | return $this->_controller;
67 | }
68 |
69 | private array $_options = [];
70 |
71 | /**
72 | * Setter method for options.
73 | */
74 | public function setOptions(array $options)
75 | {
76 | $this->_options = $options;
77 | }
78 |
79 | /**
80 | * Getter method for options.
81 | * @return array
82 | */
83 | public function getOptions()
84 | {
85 | return $this->_options;
86 | }
87 |
88 | /**
89 | * Get a specific option value for a defined eky.
90 | *
91 | * @param string $key The array key to lookup inside the $options array.
92 | * @return boolean|mixed
93 | */
94 | public function getOption($key)
95 | {
96 | return $this->_options[$key] ?? false;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/base/NavItemTypeInterface.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | interface NavItemTypeInterface
12 | {
13 | /**
14 | * Returns the databas-nummeric identifier to make the navItem relation.
15 | *
16 | * @return integer The numeric identifier for the type (1=page, 2=module, 3=redirect, ...)
17 | */
18 | public static function getNummericType();
19 | }
20 |
--------------------------------------------------------------------------------
/src/base/PhpBlockInterface.php:
--------------------------------------------------------------------------------
1 |
9 | * @since 1.0.0
10 | */
11 | interface PhpBlockInterface
12 | {
13 | public function frontend();
14 |
15 | public function admin();
16 | }
17 |
--------------------------------------------------------------------------------
/src/behaviours/WebsiteScopeBehavior.php:
--------------------------------------------------------------------------------
1 | 'initEvent',
15 | ];
16 | }
17 |
18 | public function initEvent(Event $event)
19 | {
20 | /** @var NgRestActiveQuery $query */
21 | $query = $event->sender;
22 | $query->andWhere(['website_id' => Yii::$app->website->current['id']]);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/frontend/blockgroups/DevelopmentGroup.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.0
13 | */
14 | class DevelopmentGroup extends BlockGroup
15 | {
16 | public function identifier()
17 | {
18 | return 'development-group';
19 | }
20 |
21 | public function label()
22 | {
23 | return Module::t('block_group_dev_elements');
24 | }
25 |
26 | public function getPosition()
27 | {
28 | return 90;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/frontend/blockgroups/LayoutGroup.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.0
13 | */
14 | class LayoutGroup extends BlockGroup
15 | {
16 | public function identifier()
17 | {
18 | return 'layout-group';
19 | }
20 |
21 | public function label()
22 | {
23 | return Module::t('block_group_layout_elements');
24 | }
25 |
26 | public function getPosition()
27 | {
28 | return 67;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/frontend/blockgroups/MainGroup.php:
--------------------------------------------------------------------------------
1 |
14 | * @since 1.0.0
15 | */
16 | class MainGroup extends BlockGroup
17 | {
18 | public function identifier()
19 | {
20 | return 'main-group';
21 | }
22 |
23 | public function label()
24 | {
25 | return Module::t('block_group_basic_elements');
26 | }
27 |
28 | public function getPosition()
29 | {
30 | return 66;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/frontend/blockgroups/MediaGroup.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.0
13 | */
14 | class MediaGroup extends BlockGroup
15 | {
16 | public function identifier()
17 | {
18 | return 'media-group';
19 | }
20 |
21 | public function label()
22 | {
23 | return Module::t('block_group_media_group');
24 | }
25 |
26 | public function getPosition()
27 | {
28 | return 62;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/frontend/blockgroups/ProjectGroup.php:
--------------------------------------------------------------------------------
1 |
14 | * @since 1.0.0
15 | */
16 | class ProjectGroup extends BlockGroup
17 | {
18 | public function identifier()
19 | {
20 | return 'project-group';
21 | }
22 |
23 | public function label()
24 | {
25 | return Module::t('block_group_project_elements');
26 | }
27 |
28 | public function getPosition()
29 | {
30 | return 64;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/frontend/blockgroups/TextGroup.php:
--------------------------------------------------------------------------------
1 |
14 | * @since 1.0.0
15 | */
16 | class TextGroup extends BlockGroup
17 | {
18 | public function identifier()
19 | {
20 | return 'text-group';
21 | }
22 |
23 | public function label()
24 | {
25 | return Module::t('block_group_text_elements');
26 | }
27 |
28 | public function getPosition()
29 | {
30 | return 60;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/frontend/blocks/HtmlBlock.php:
--------------------------------------------------------------------------------
1 |
13 | * @since 1.0.0
14 | */
15 | final class HtmlBlock extends PhpBlock
16 | {
17 | /**
18 | * @inheritdoc
19 | */
20 | public $module = 'cms';
21 |
22 | /**
23 | * @inheritdoc
24 | */
25 | public $cacheEnabled = true;
26 |
27 | /**
28 | * @inheritdoc
29 | */
30 | public function blockGroup()
31 | {
32 | return DevelopmentGroup::class;
33 | }
34 |
35 | /**
36 | * @inheritdoc
37 | */
38 | public function name()
39 | {
40 | return Module::t('block_html_name');
41 | }
42 |
43 | /**
44 | * @inheritdoc
45 | */
46 | public function icon()
47 | {
48 | return 'code';
49 | }
50 |
51 | /**
52 | * @inheritdoc
53 | */
54 | public function config()
55 | {
56 | return [
57 | 'vars' => [
58 | ['var' => 'html', 'label' => Module::t('block_html_html_label'), 'type' => self::TYPE_TEXTAREA],
59 | ],
60 | 'cfgs' => [
61 | ['var' => 'raw', 'label' => Module::t('block_html_cfg_raw_label'), 'type' => self::TYPE_CHECKBOX]
62 | ],
63 | ];
64 | }
65 |
66 | /**
67 | * @inheritdoc
68 | */
69 | public function admin()
70 | {
71 | $message = Module::t('block_html_no_content');
72 | return <<{$message}{% else %}
75 | {% if cfgs.raw == 1 %}
76 | {{ vars.html | raw }}
77 | {% else %}
78 | {{ vars.html | escape }}
79 | {% endif %}
80 | {% endif %}
81 | EOT;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/frontend/components/CatchAllUrlRule.php:
--------------------------------------------------------------------------------
1 |
17 | * @since 1.0.0
18 | */
19 | class CatchAllUrlRule extends UrlRule
20 | {
21 | /**
22 | * @inheritdoc
23 | */
24 | public $pattern = '';
25 |
26 | /**
27 | * @inheritdoc
28 | */
29 | public $route = 'cms/default/index';
30 |
31 | /**
32 | * @inheritdoc
33 | */
34 | public $encodeParams = false;
35 |
36 | /**
37 | * @inheritdoc
38 | */
39 | public function parseRequest($manager, $request)
40 | {
41 | // add trace info
42 | Yii::info('LUYA-CMS CatchAllUrlRule is parsing the Request for path info \'' . $request->pathInfo .'\'', __METHOD__);
43 |
44 | $pathInfo = $request->pathInfo;
45 |
46 | // if no path is given, the route should not apply.
47 | if (empty($pathInfo)) {
48 | return false;
49 | }
50 |
51 | // if there is a trailing slash given, the request is invalid as long as the urlManager suffix
52 | // does not contain a trailing slash.
53 | if (rtrim($pathInfo, '//') !== $pathInfo && !str_ends_with($manager->suffix, '/')) {
54 | return false;
55 | }
56 |
57 | // return the custom route
58 | return [$this->route, ['path' => $request->pathInfo]];
59 | }
60 |
61 | /**
62 | * @inheritdoc
63 | */
64 | public function createUrl($manager, $route, $params)
65 | {
66 | if (ltrim($route, '/') !== $this->route) {
67 | $this->createStatus = self::CREATE_STATUS_ROUTE_MISMATCH;
68 | return false;
69 | }
70 |
71 | if (!isset($params['path']) || empty($params['path'])) {
72 | $this->createStatus = self::CREATE_STATUS_PARAMS_MISMATCH;
73 | return false;
74 | }
75 |
76 | $path = ArrayHelper::remove($params, 'path');
77 |
78 | if (empty($params)) {
79 | return $path;
80 | }
81 |
82 | return $path .'?'.http_build_query($params);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/frontend/components/RouteBehaviorUrlRule.php:
--------------------------------------------------------------------------------
1 |
14 | * @since 1.0.0
15 | */
16 | class RouteBehaviorUrlRule extends UrlRule
17 | {
18 | /**
19 | * @inheritdoc
20 | */
21 | public $pattern = '//';
22 |
23 | /**
24 | * @inheritdoc
25 | */
26 | public $route = '//';
27 |
28 | /**
29 | * @inheritdoc
30 | */
31 | public $defaults = ['controller' => 'default', 'action' => 'index'];
32 |
33 | /**
34 | * @inheritdoc
35 | */
36 | public $mode = UrlRule::PARSING_ONLY;
37 |
38 | /**
39 | * @inheritdoc
40 | */
41 | public function parseRequest($manager, $request)
42 | {
43 | // return route in parts where key 0 should be the module assuming routed strings.
44 | $parts = explode("/", $request->pathInfo);
45 |
46 | // if there is no key 0, the module does not exists in module list or the module name is cms, its an invalid request.
47 | if (!isset($parts[0]) || !Yii::$app->hasModule($parts[0]) || $parts[0] === 'cms') {
48 | return false;
49 | }
50 |
51 | // add trace info
52 | Yii::info('LUYA-CMS RouteBehaviorUrlRule is parsing the Request for path info \'' . $request->pathInfo .'\'', __METHOD__);
53 |
54 | return parent::parseRequest($manager, $request);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/frontend/components/WebsiteBehaviorUrlRule.php:
--------------------------------------------------------------------------------
1 |
16 | * @since 4.0.0
17 | */
18 | class WebsiteBehaviorUrlRule extends UrlRule
19 | {
20 | /**
21 | * @inheritdoc
22 | */
23 | public $pattern = '//';
24 |
25 | /**
26 | * @inheritdoc
27 | */
28 | public $route = '//';
29 |
30 | /**
31 | * @inheritdoc
32 | */
33 | public $defaults = ['controller' => 'default', 'action' => 'index'];
34 |
35 | /**
36 | * @inheritdoc
37 | */
38 | public $mode = UrlRule::PARSING_ONLY;
39 |
40 | /**
41 | * @inheritdoc
42 | */
43 | public function parseRequest($manager, $request)
44 | {
45 | $matchedWebsite = Yii::$app->website->findOneByHostName($request->hostName);
46 | if (boolval($matchedWebsite['redirect_to_host']) && $matchedWebsite['host'] !== $request->hostName) {
47 | $request->setHostInfo($matchedWebsite['host']);
48 | throw new UrlNormalizerRedirectException(Url::to($request->getAbsoluteUrl()), 301);
49 | }
50 |
51 | return false;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/frontend/controllers/BlockController.php:
--------------------------------------------------------------------------------
1 |
18 | * @since 1.0.0
19 | */
20 | class BlockController extends Controller
21 | {
22 | /**
23 | * @inheritdoc
24 | */
25 | public $enableCsrfValidation = false;
26 |
27 | /**
28 | * Run the callback for a given block.
29 | *
30 | * @param string $callback The name of the callback to call inside the block object.
31 | * @param integer $id The id of the block item where the callbacke is located.
32 | * @throws \luya\cms\Exception
33 | * @return mixed
34 | */
35 | public function actionIndex($callback, $id)
36 | {
37 | $model = NavItemPageBlockItem::findOne($id);
38 |
39 | if (!$model) {
40 | throw new Exception("Unable to find item id.");
41 | }
42 |
43 | $block = $model->block->getObject($model->id, 'callback');
44 |
45 | if (!$block) {
46 | throw new Exception("Unable to find block object.");
47 | }
48 |
49 | return ObjectHelper::callMethodSanitizeArguments($block, $this->callbackToMethod($callback), Yii::$app->request->get());
50 | }
51 |
52 | /**
53 | * Ensure the callback method from a given name.
54 | *
55 | * The callback method must start with 'callback'.
56 | *
57 | * @param string $callbackName The name of the callback, like `my-action`
58 | * @return string Convert the callbackname to `callbackMyAction`
59 | */
60 | protected function callbackToMethod($callbackName)
61 | {
62 | if (!StringHelper::startsWith($callbackName, 'callback')) {
63 | return 'callback' . Inflector::id2camel($callbackName);
64 | }
65 |
66 | return lcfirst(Inflector::id2camel($callbackName));
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/frontend/controllers/ErrorController.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class ErrorController extends \luya\web\Controller
14 | {
15 | public function actionIndex()
16 | {
17 | return $this->renderPartial($this->module->errorViewFile, [
18 | 'exception' => Yii::$app->errorHandler->exception
19 | ]);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/frontend/controllers/PreviewController.php:
--------------------------------------------------------------------------------
1 |
16 | * @since 1.0.0
17 | */
18 | class PreviewController extends Controller
19 | {
20 | /**
21 | * Renders the preview action.
22 | *
23 | * @param integer $itemId The nav item to render.
24 | * @param integer $version The version to display.
25 | * @param integer $date The date from the preview frame, is false when not using the preview frame from the cms.
26 | * @throws ForbiddenHttpException
27 | * @throws NotFoundHttpException
28 | */
29 | public function actionIndex($itemId, $version = false, $date = false): \yii\web\Response|string
30 | {
31 | if (Yii::$app->adminuser->isGuest) {
32 | throw new ForbiddenHttpException('Unable to see the preview page, session expired or not logged in.');
33 | }
34 |
35 | $navItem = NavItem::findOne($itemId);
36 |
37 | if (!$navItem) {
38 | throw new NotFoundHttpException("The requested nav item with id {$itemId} does not exist.");
39 | }
40 |
41 | $langShortCode = $navItem->lang->short_code;
42 |
43 | Yii::$app->composition['langShortCode'] = $langShortCode;
44 |
45 | $item = Yii::$app->menu->find()->where(['id' => $itemId])->with('hidden')->lang($langShortCode)->one();
46 |
47 | if ($item && !$date && $navItem->nav_item_type_id == $version) {
48 | return $this->redirect($item->link);
49 | }
50 |
51 | // this item is still offline so we have to inject and fake it with the inject api
52 | if (!$item) {
53 | // create new item to inject
54 | $inject = new InjectItem([
55 | 'id' => $itemId,
56 | 'navId' => $navItem->nav->id,
57 | 'childOf' => Yii::$app->menu->home->id,
58 | 'title' => $navItem->title,
59 | 'alias' => $navItem->alias,
60 | 'isHidden' => true,
61 | ]);
62 | // inject item into menu component
63 | Yii::$app->menu->injectItem($inject);
64 | // find the inject menu item
65 | $item = Yii::$app->menu->find()->where(['id' => $inject->id])->with('hidden')->lang($langShortCode)->one();
66 | // something really went wrong while finding injected item
67 | if (!$item) {
68 | throw new NotFoundHttpException("Unable to find the preview for this ID, maybe the page is still Offline?");
69 | }
70 | }
71 |
72 | // set the current item, as it would be resolved wrong from the url manager / request path
73 | Yii::$app->menu->current = $item;
74 |
75 | return $this->renderContent($this->renderItem($itemId, null, $version));
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/frontend/events/BeforeRenderEvent.php:
--------------------------------------------------------------------------------
1 |
11 | * @since 1.0.0
12 | */
13 | class BeforeRenderEvent extends \yii\base\Event
14 | {
15 | /**
16 | * @var boolean Whether current request is valid or not, if $isValid is false an {{MethodNotAllowedHttpException}} will
17 | * be thrown while rendering.
18 | */
19 | public $isValid = true;
20 |
21 | /**
22 | * @var \luya\cms\menu\Item The current menu item resolved from {{luya\cms\Menu::getCurrent()}}.
23 | */
24 | public $menu;
25 | }
26 |
--------------------------------------------------------------------------------
/src/frontend/events/MenuItemEvent.php:
--------------------------------------------------------------------------------
1 | [
15 | * 'class' => 'luya\cms\Menu',
16 | * 'on eventOnItemFind' => function(MenuItemEvent $event) {
17 | * if ($event->item->alias == 'this-is-my-alias') {
18 | * // will turn this item to invisble
19 | * $event->visible = false;
20 | * }
21 | * }
22 | * ],
23 | * ```
24 | *
25 | * @property integer $visible Menu item visibility getter/setter.
26 | *
27 | * @author Basil Suter
28 | * @since 1.0.0
29 | */
30 | class MenuItemEvent extends \yii\base\Event
31 | {
32 | /**
33 | * @var Item
34 | */
35 | public $item;
36 |
37 | /**
38 | * Whether the item is visible or not
39 | *
40 | * @return boolean
41 | */
42 | public function getVisible()
43 | {
44 | return !$this->item->isHidden;
45 | }
46 |
47 | /**
48 | * Setter method for the item visibility
49 | *
50 | * @param integer $state
51 | */
52 | public function setVisible($state)
53 | {
54 | $this->item->isHidden = !$state;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/frontend/messages/cn/cms.php:
--------------------------------------------------------------------------------
1 | '语言',
5 | 'tb_properties' => '属性',
6 | 'tb_seo' => 'SEO搜索优化',
7 | 'tb_seo_title' => '标题',
8 | 'tb_seo_description' => '描述',
9 | 'tb_seo_description_notfound' => '当前页面没有添加描述.',
10 | 'tb_seo_link' => 'URL链接',
11 | 'tb_seo_keywords' => '关键字',
12 | 'tb_seo_keywords_notfound' => '未找到关键字.您应该添加关键字来分析您的内容.',
13 | 'tb_seo_warning' => '您的某些关键字在您的内容中找不到,您应该通过更改关键字或将缺少的关键字添加到内容来解决这个问题。',
14 | 'tb_edit_alt' => '在CMS管理中编辑此页面',
15 | 'tb_visible_not_alt' => '这个网页对访客不可见',
16 | 'tb_visible_alt' => '这个页面对访问者是可见的',
17 | 'block_html_html_label' => 'HTML代码',
18 | 'block_html_no_content' => '没有添加HTML代码。',
19 | 'block_module_name' => '模块',
20 | 'block_module_modulename_label' => '模块名称',
21 | 'block_module_modulecontroller_label' => '控制器名称(不带controller后缀)',
22 | 'block_module_moduleaction_label' => '动作名称(不带action前缀)',
23 | 'block_module_moduleactionargs_label' => '动作参数(json: {"var":"value"})',
24 | 'block_module_no_module' => '尚未指定模块。',
25 | 'block_module_integration' => '模块整合',
26 | 'block_html_name' => 'HTML',
27 | 'block_module_modulename_help' => '只列出在配置文件中注册的前端模块。',
28 | 'block_group_dev_elements' => '高级',
29 | 'block_group_layout_elements' => '布局',
30 | 'block_group_basic_elements' => '基础',
31 | 'block_group_project_elements' => '开发',
32 | 'block_group_text_elements' => '文本',
33 | 'block_group_media_group' => '媒体',
34 |
35 | // 1.0.0
36 | 'block_module_strictrender' => '严格渲染',
37 | 'block_module_strictrender_help' => '当严格渲染被启用时,模块将只运行提供的路由(模块,控制器,动作,参数)而不监听动作和控制器路由。',
38 | 'block_html_cfg_raw_label' => '在Admin中渲染HTML',
39 |
40 | // 3.4.0
41 | 'tag_alias_readme' => 'The alias tag allows you to use aliases defined in your application as well as predefined aliases. As an example, you can use `alias[@web]` to link to images in the public html folder: `
`',
42 | 'tag_menu_readme' => 'Generate a link to a menu item where the key is the page id (you can see the page ids when hovering over the site navigation in the administration).',
43 | 'tag_page_readme' => 'Get the content of a full page or of a placeholder of a page. The first parameter is the page id (which you get by hovering over the site navigation in the administration): `page[1]`. If you only want to get the content of a placeholder of the cmslayout, use the second parameter: `page[1](placeholderName)`.',
44 | 'block_mirror_language_name' => 'Mirror Language',
45 | 'block_mirror_config_language_label' => 'Source Language',
46 | 'block_mirror_admin_empty_language' => 'Configure a edit source language to mirror its content for the current placeholder.',
47 | 'block_mirror_admin_configured_language' => 'Mirroring this placeholder from arrow_right_alt {name}.',
48 | ];
49 |
--------------------------------------------------------------------------------
/src/frontend/views/blocks/HtmlBlock.php:
--------------------------------------------------------------------------------
1 |
6 | = $this->varValue('html'); ?>
--------------------------------------------------------------------------------
/src/frontend/views/blocks/ModuleBlock.php:
--------------------------------------------------------------------------------
1 |
6 | = $this->extraValue('moduleContent');?>
--------------------------------------------------------------------------------
/src/frontend/views/commands/block/create_block_view.php:
--------------------------------------------------------------------------------
1 |
4 | /**
5 | * View file for block: = $blockClassName; ?>
6 | *
7 | * = $luyaText; ?>
8 | *
9 |
10 | * @param = $doc; ?>
11 |
12 |
13 | *
14 | * @var \luya\cms\base\PhpBlockView $this
15 | */
16 | ?>
17 |
--------------------------------------------------------------------------------
/src/frontend/views/error/index.php:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
getMessage()); ?>
31 |
32 |
Error statusCode; ?>
33 |
34 |
35 |
36 |
The above error occurred while the Web server was processing your request.
37 |
Please contact us if you think this is a server error. Thank you.
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/injectors/ActiveQueryCheckboxInjector.php:
--------------------------------------------------------------------------------
1 | \newsadmin\models\Article::find()->where(['cat_id' => 1]),
19 | * 'label' => 'title', // This attribute from the model is used to render the admin block dropdown selection.
20 | * ]);
21 | * ```
22 | *
23 | * In order to configure the ActiveQueryCheckboxInjector used the {{\luya\cms\base\InternalBaseBlock::injectors}} method:
24 | *
25 | * ```php
26 | * public function injectors()
27 | * {
28 | * return [
29 | * 'theData' => new ActiveQueryCheckboxInjector([
30 | * 'query' => News::find()->where(['is_deleted' => 0]),
31 | * 'label' => function($model) {
32 | * return $model->title . " - " . $model->description;
33 | * },
34 | * ]);
35 | * ];
36 | * }
37 | * ```
38 | *
39 | * @property \yii\db\ActiveQueryInterface $query The ActiveQuery object
40 | *
41 | * @author Basil Suter
42 | * @since 1.0.0
43 | */
44 | final class ActiveQueryCheckboxInjector extends BaseActiveQueryInjector
45 | {
46 | /**
47 | * @inheritdoc
48 | */
49 | public function setup()
50 | {
51 | // injecto the config
52 | $this->setContextConfig([
53 | 'var' => $this->varName,
54 | 'type' => TypesInterface::TYPE_CHECKBOX_ARRAY,
55 | 'label' => $this->varLabel,
56 | 'options' => [
57 | 'items' => $this->getQueryData(),
58 | ],
59 | ]);
60 | // provide the extra data
61 | $this->context->addExtraVar($this->varName, $this->getExtraAssignArrayData());
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/injectors/ActiveQueryRadioInjector.php:
--------------------------------------------------------------------------------
1 | \newsadmin\models\Article::find()->where(['cat_id' => 1]),
18 | * 'label' => 'title', // This attribute from the model is used to render the admin block dropdown selection.
19 | * ]);
20 | * ```
21 | *
22 | * In order to configure the ActiveQueryRadioInjector used the {{\luya\cms\base\InternalBaseBlock::injectors}} method:
23 | *
24 | * ```php
25 | * public function injectors()
26 | * {
27 | * return [
28 | * 'theData' => new ActiveQueryRadioInjector([
29 | * 'query' => News::find()->where(['is_deleted' => 0]),
30 | * 'label' => function($model) {
31 | * return $model->title . " - " . $model->description;
32 | * },
33 | * ]);
34 | * ];
35 | * }
36 | * ```
37 | *
38 | * @property \yii\db\ActiveQueryInterface $query The ActiveQuery object
39 | *
40 | * @author Basil Suter
41 | * @since 1.0.0
42 | */
43 | final class ActiveQueryRadioInjector extends BaseActiveQueryInjector
44 | {
45 | /**
46 | * @inheritdoc
47 | */
48 | public function setup()
49 | {
50 | // injecto the config
51 | $this->setContextConfig([
52 | 'var' => $this->varName,
53 | 'type' => TypesInterface::TYPE_RADIO,
54 | 'label' => $this->varLabel,
55 | 'options' => $this->getQueryData(),
56 | ]);
57 | // provide the extra data
58 | $this->context->addExtraVar($this->varName, $this->getExtraAssignSingleData());
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/injectors/ActiveQuerySelectInjector.php:
--------------------------------------------------------------------------------
1 | \newsadmin\models\Article::find()->where(['cat_id' => 1]),
18 | * 'label' => 'title', // This attribute from the model is used to render the admin block dropdown selection.
19 | * ]);
20 | * ```
21 | *
22 | * In order to configure the ActiveQuerySelectInjector used the {{\luya\cms\base\InternalBaseBlock::injectors}} method:
23 | *
24 | * ```php
25 | * public function injectors()
26 | * {
27 | * return [
28 | * 'theData' => new ActiveQuerySelectInjector([
29 | * 'query' => News::find()->where(['is_deleted' => 0]),
30 | * 'label' => function($model) {
31 | * return $model->title . " - " . $model->description;
32 | * },
33 | * ]);
34 | * ];
35 | * }
36 | * ```
37 | *
38 | * @property \yii\db\ActiveQueryInterface $query The ActiveQuery object
39 | *
40 | * @author Basil Suter
41 | * @since 2.1.0
42 | */
43 | class ActiveQuerySelectInjector extends BaseActiveQueryInjector
44 | {
45 | /**
46 | * @inheritdoc
47 | */
48 | public function setup()
49 | {
50 | // injecto the config
51 | $this->setContextConfig([
52 | 'var' => $this->varName,
53 | 'type' => TypesInterface::TYPE_SELECT,
54 | 'label' => $this->varLabel,
55 | 'options' => $this->getQueryData(),
56 | ]);
57 |
58 | // provide the extra data
59 | $this->context->addExtraVar($this->varName, $this->getExtraAssignSingleData());
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/injectors/LinkInjector.php:
--------------------------------------------------------------------------------
1 | new \luya\cms\injectors\LinkInjector()
24 | * ];
25 | * }
26 | * ```
27 | *
28 | * The value of the `$this->extraValue('theLink')` is a {{luya\web\LinkInterface}} therefor you can access the `getHref` and `getTarget` methods in order to generate the link:
29 | *
30 | * ```php
31 | * Go There
32 | * ```
33 | *
34 | * @author Basil Suter
35 | * @since 1.0.0
36 | */
37 | final class LinkInjector extends BaseBlockInjector
38 | {
39 | private function getLinkUrl()
40 | {
41 | $content = $this->getContextConfigValue($this->varName);
42 |
43 | return BlockHelper::linkObject($content);
44 | }
45 |
46 | /**
47 | * @inheritdoc
48 | */
49 | public function setup()
50 | {
51 | $this->setContextConfig([
52 | 'var' => $this->varName,
53 | 'type' => 'zaa-link',
54 | 'label' => $this->varLabel,
55 | ]);
56 |
57 | $this->context->addExtraVar($this->varName, $this->getLinkUrl());
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/injectors/TagInjector.php:
--------------------------------------------------------------------------------
1 |
20 | * @since 1.0.0
21 | */
22 | class TagInjector extends BaseBlockInjector
23 | {
24 | /**
25 | * Returns all avialable Tags.
26 | *
27 | * @return \luya\admin\models\Tag Tag Model ActiveQuery.
28 | */
29 | public function getCheckboxArray()
30 | {
31 | return Tag::find()->select(['name'])->indexBy('id')->column();
32 | }
33 |
34 | private $_assignedTags;
35 |
36 | /**
37 | * Get assigned models for the current Block.
38 | *
39 | * @return \luya\admin\models\Tag All selected tags within the tag model.
40 | */
41 | public function getAssignedTags()
42 | {
43 | if ($this->_assignedTags === null) {
44 | $ids = ArrayHelper::getColumn($this->getContextConfigValue($this->varName, []), 'value');
45 | $this->_assignedTags = Tag::find()->where(['in','id', $ids])->indexBy('name')->all();
46 | }
47 |
48 | return $this->_assignedTags;
49 | }
50 |
51 | /**
52 | * @inheritdoc
53 | */
54 | public function setup()
55 | {
56 | $this->setContextConfig([
57 | 'var' => $this->varName,
58 | 'type' => TypesInterface::TYPE_CHECKBOX_ARRAY,
59 | 'label' => $this->varLabel,
60 | 'options' => BlockHelper::checkboxArrayOption($this->getCheckboxArray()),
61 | ]);
62 |
63 | $this->context->addExtraVar($this->varName, $this->getAssignedTags());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/menu/InjectItemInterface.php:
--------------------------------------------------------------------------------
1 |
14 | * @since 1.0.0
15 | */
16 | interface InjectItemInterface
17 | {
18 | /**
19 | * Getter method for the language on which the item is injected. The language is the short code
20 | * based from the composition component.
21 | *
22 | * @return string A language short code string (like de, en)
23 | */
24 | public function getLang();
25 |
26 | /**
27 | * Getter method for the unqiue id of a language item which can be auto generated or directly from
28 | * the injection item. Ensure the unique identifier when setting this property.
29 | *
30 | * @return integer|string The unique identifier can be either a string or a number, or a concat of both.
31 | */
32 | public function getId();
33 |
34 | /**
35 | * This method provides all setter variables for the item.
36 | *
37 | * @return array An array where the key is the name of the setter property like `title`, `alias` etc.
38 | */
39 | public function toArray();
40 | }
41 |
--------------------------------------------------------------------------------
/src/models/Config.php:
--------------------------------------------------------------------------------
1 |
14 | * @since 1.0.0
15 | */
16 | class Config extends \yii\db\ActiveRecord
17 | {
18 | use RegistryTrait;
19 |
20 | public const HTTP_EXCEPTION_NAV_ID = 'httpExceptionNavId';
21 |
22 | /**
23 | * @inheritdoc
24 | */
25 | public static function tableName()
26 | {
27 | return 'cms_config';
28 | }
29 |
30 | /**
31 | * @inheritdoc
32 | */
33 | public function rules()
34 | {
35 | return [
36 | [['name', 'value'], 'required'],
37 | [['name'], 'unique'],
38 | ];
39 | }
40 |
41 | /**
42 | * @inheritdoc
43 | */
44 | public function attributeLabels()
45 | {
46 | return [
47 | 'name' => 'Name',
48 | 'value' => 'Value',
49 | ];
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/models/Layout.php:
--------------------------------------------------------------------------------
1 |
18 | * @since 1.0.0
19 | */
20 | class Layout extends NgRestModel
21 | {
22 | /**
23 | * @inheritdoc
24 | */
25 | public static function tableName()
26 | {
27 | return 'cms_layout';
28 | }
29 |
30 | /**
31 | * @inheritdoc
32 | */
33 | public static function ngRestApiEndpoint()
34 | {
35 | return 'api-cms-layout';
36 | }
37 |
38 | /**
39 | * @inheritdoc
40 | */
41 | public function rules()
42 | {
43 | return [
44 | [['name', 'json_config', 'view_file'], 'required'],
45 | [['json_config'], 'string'],
46 | [['name', 'view_file'], 'string', 'max' => 255],
47 | ];
48 | }
49 |
50 | /**
51 | * @inheritdoc
52 | */
53 | public function attributeLabels()
54 | {
55 | return [
56 | 'name' => Module::t('model_layout_name_label'),
57 | 'json_config' => Module::t('model_layout_json_config_label'),
58 | 'view_file' => Module::t('model_layout_view_file_label'),
59 | ];
60 | }
61 |
62 | /**
63 | * @inheritdoc
64 | */
65 | public function ngRestAttributeTypes()
66 | {
67 | return [
68 | 'name' => 'text',
69 | 'json_config' => ['textarea', 'encoding' => false],
70 | 'view_file' => 'text',
71 | ];
72 | }
73 |
74 | /**
75 | * @inheritdoc
76 | */
77 | public function ngRestScopes()
78 | {
79 | return [
80 | ['list', ['name', 'json_config', 'view_file']],
81 | [['update'], ['name']],
82 | ];
83 | }
84 |
85 | /**
86 | * Get the json config as array.
87 | *
88 | * @param string $node Get a given key from the config array.
89 | * @return array If the given node is not found an empty array will be returned.
90 | */
91 | public function getJsonConfig($node = null)
92 | {
93 | $json = Json::decode($this->json_config);
94 |
95 | if (!$node) {
96 | return $json;
97 | }
98 |
99 | if (isset($json[$node])) {
100 | return $json[$node];
101 | }
102 |
103 | return [];
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/models/NavItemRedirect.php:
--------------------------------------------------------------------------------
1 |
22 | * @since 1.0.0
23 | */
24 | class NavItemRedirect extends NavItemType implements NavItemTypeInterface
25 | {
26 | /**
27 | * @inheritdoc
28 | */
29 | public static function tableName()
30 | {
31 | return 'cms_nav_item_redirect';
32 | }
33 |
34 | /**
35 | * @inheritdoc
36 | */
37 | public static function getNummericType()
38 | {
39 | return NavItem::TYPE_REDIRECT;
40 | }
41 |
42 | /**
43 | * @inheritdoc
44 | */
45 | public function rules()
46 | {
47 | return [
48 | [['type', 'value'], 'required'],
49 | [['type'], 'integer'],
50 | [['target', 'anchor'], 'string', 'max' => 255],
51 | [['value'], 'string', 'max' => 255, 'strict' => false],
52 | ];
53 | }
54 |
55 | /**
56 | * @inheritdoc
57 | */
58 | public function attributeLabels()
59 | {
60 | return [
61 | 'value' => Module::t('model_navitemredirect_value_label'),
62 | 'type' => Module::t('model_navitemredirect_type_label'),
63 | 'target' => 'Target',
64 | ];
65 | }
66 |
67 | /**
68 | * Resolve the values with {{luya\cms\LinkConverter}}.
69 | */
70 | public function resolveValue(): \luya\web\LinkInterface|bool
71 | {
72 | $converter = new LinkConverter();
73 | $converter->value = $this->value;
74 | $converter->type = $this->type;
75 | $converter->target = $this->target;
76 | $converter->anchor = $this->anchor;
77 | return $converter->getLink();
78 | }
79 |
80 | /**
81 | * @inheritdoc
82 | */
83 | public function getContent()
84 | {
85 | $link = $this->resolveValue();
86 |
87 | if (!$link) {
88 | throw new InvalidConfigException(sprintf("Unable to redirect to the given page, invalid link object. Make sure the target page with id '%s' is online!", $this->value));
89 | }
90 |
91 | Yii::$app->getResponse()->redirect($link->getHref());
92 | Yii::$app->end();
93 |
94 | return;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/models/NavPermission.php:
--------------------------------------------------------------------------------
1 |
13 | * @since 1.0.4
14 | */
15 | class NavPermission extends \yii\db\ActiveRecord
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | public static function tableName()
21 | {
22 | return 'cms_nav_permission';
23 | }
24 |
25 | /**
26 | * {@inheritdoc}
27 | */
28 | public function rules()
29 | {
30 | return [
31 | [['group_id', 'nav_id'], 'required'],
32 | [['group_id', 'nav_id', 'inheritance'], 'integer'],
33 | ];
34 | }
35 |
36 | /**
37 | * {@inheritdoc}
38 | */
39 | public function attributeLabels()
40 | {
41 | return [
42 | 'group_id' => 'Group ID',
43 | 'nav_id' => 'Nav ID',
44 | 'inheritance' => 'Inheritance',
45 | ];
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/models/Property.php:
--------------------------------------------------------------------------------
1 |
15 | * @since 1.0.0
16 | */
17 | final class Property extends \yii\db\ActiveRecord
18 | {
19 | /**
20 | * @inheritdoc
21 | */
22 | public static function tableName()
23 | {
24 | return 'cms_nav_property';
25 | }
26 |
27 | /**
28 | * @inheritdoc
29 | */
30 | public function rules()
31 | {
32 | return [
33 | [['nav_id', 'admin_prop_id', 'value'], 'required'],
34 | ];
35 | }
36 |
37 | /**
38 | * Property Active Query.
39 | *
40 | * @return \luya\admin\models\Property
41 | */
42 | public function getAdminProperty()
43 | {
44 | return $this->hasOne(AdminProperty::class, ['id' => 'admin_prop_id']);
45 | }
46 |
47 | private $_object;
48 |
49 | /**
50 | * Create the Property object with the given value.
51 | *
52 | * @return \luya\admin\base\Property
53 | */
54 | public function getObject()
55 | {
56 | if ($this->_object === null) {
57 | $this->_object = $this->adminProperty->createObject($this->value);
58 | }
59 |
60 | return $this->_object;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/tags/AliasTag.php:
--------------------------------------------------------------------------------
1 |
14 | * @since 1.0.0
15 | */
16 | class MenuTag extends BaseTag
17 | {
18 | public function example()
19 | {
20 | return 'menu[123](Go to Page 123)';
21 | }
22 |
23 | public function readme()
24 | {
25 | return Module::t('tag_menu_readme');
26 | }
27 |
28 | public function parse($value, $sub)
29 | {
30 | $menuItem = Yii::$app->menu->find()->where(['nav_id' => $value])->with('hidden')->one();
31 |
32 | if ($menuItem) {
33 | $alias = (empty($sub)) ? $menuItem->title : $sub;
34 |
35 | return Html::a($alias, $menuItem->link);
36 | }
37 |
38 | return false;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/tags/PageTag.php:
--------------------------------------------------------------------------------
1 | parse(1, 'placeholderName'); // where 1 is the Nav ID if no placeholder name is given us null to render the whole page.
21 | * ```
22 | *
23 | * @author Basil Suter
24 | * @since 1.0.0
25 | */
26 | class PageTag extends BaseTag
27 | {
28 | /**
29 | * @inheritdoc
30 | */
31 | public function example()
32 | {
33 | return 'page[1](placeholder)';
34 | }
35 |
36 | /**
37 | * @inheritdoc
38 | */
39 | public function readme()
40 | {
41 | return Module::t('tag_page_readme');
42 | }
43 |
44 | /**
45 | * Get the content of Nav for the current active language with cmslayout or placeholder.
46 | *
47 | * If the page does not have a corresponding activeLanguageItem, null is returned.
48 | *
49 | * @param string $value The value of the Nav ID e.g 1 (hover the cms menu to see the ID).
50 | * @param string|null $sub If null this parameter will be ignored otherwise its the name of the placeholder inside this cmslayout.
51 | * @return string The content rendered with the cmslayout, or if $sub is provided and not null with its placeholder name.
52 | * @see \luya\tag\TagInterface::parse()
53 | */
54 | public function parse($value, $sub)
55 | {
56 | $page = Nav::findOne(['id' => $value]);
57 |
58 | // verify if the page is of type content
59 |
60 | if ($page && $page->activeLanguageItem) {
61 | if ($page->activeLanguageItem->nav_item_type !== NavItem::TYPE_PAGE) {
62 | return null;
63 | }
64 |
65 | if (empty($sub)) {
66 | return $page->activeLanguageItem->getContent();
67 | } else {
68 | return $page->activeLanguageItem->type->renderPlaceholder($sub);
69 | }
70 | }
71 |
72 | return null;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/BlockTestCase.php:
--------------------------------------------------------------------------------
1 | 'basetestcase',
13 | 'basePath' => dirname(__DIR__),
14 | 'aliases' => [
15 | '@cmstests' => '.',
16 | ],
17 | 'components' => [
18 | 'db' => [
19 | 'class' => 'yii\db\Connection',
20 | 'dsn' => 'sqlite::memory:',
21 | ],
22 | 'urlManager' => [
23 | 'cache' => null,
24 | ]
25 | ],
26 | 'modules' => [
27 | 'admin' => [
28 | 'class' => 'luya\admin\Module',
29 | 'queueMutexClass' => 'yii\mutex\FileMutex',
30 | ],
31 | 'cms' => [
32 | 'class' => '\luya\cms\frontend\Module'
33 | ],
34 | 'cmsadmin' => [
35 | 'class' => 'luya\cms\admin\Module',
36 | 'blocks' => ['@cmstests/tests/data/blocks/import'],
37 | 'cmsLayouts' => ['@cmstests/tests/data/cmslayouts'],
38 | ],
39 | 'CmsUnitModule' => '\cmstests\data\modules\CmsUnitModule',
40 | ],
41 | ];
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/CmsFrontendTestCase.php:
--------------------------------------------------------------------------------
1 | 1]);
26 | $data[] = self::generateMenuItem(2, 'Page 1', []);
27 | $data[] = self::generateMenuItem(3, 'Page 1.1', ['parent_nav_id' => 2, 'depth' => 2]);
28 | $data[] = self::generateMenuItem(4, 'Page 1.2', ['parent_nav_id' => 2, 'depth' => 2]);
29 | $data[] = self::generateMenuItem(5, 'Page 1.3', ['parent_nav_id' => 2, 'depth' => 2]);
30 | $data[] = self::generateMenuItem(6, 'Page 1.2.1', ['parent_nav_id' => 4, 'depth' => 3]);
31 | $data[] = self::generateMenuItem(7, 'Page 1.2.2', ['parent_nav_id' => 4, 'depth' => 3]);
32 | $data[] = self::generateMenuItem(8, 'Page 1.2.3', ['parent_nav_id' => 4, 'depth' => 3]);
33 | return $data;
34 | }
35 |
36 | public static function mockMenuContainerArray()
37 | {
38 | $data[] = self::generateMenuItem(1, 'homepage', ['is_home' => 1]);
39 | $data[] = self::generateMenuItem(2, 'Page 1', []);
40 | $data[] = self::generateMenuItem(3, '(c1) Page 1', ['container' => 'c1']);
41 | $data[] = self::generateMenuItem(5, '(c2) Page 1', ['container' => 'c2']);
42 | $data[] = self::generateMenuItem(6, '(c2) Page 2', ['container' => 'c2']);
43 |
44 | return $data;
45 | }
46 |
47 | public static function generateMenuItem($id, $title, array $args)
48 | {
49 | return array_merge([
50 | 'id' => $id,
51 | 'nav_id' => $id,
52 | 'lang' => 'en',
53 | 'link' => Inflector::slug($title),
54 | 'title' => $title,
55 | 'alias' => Inflector::slug($title),
56 | 'type' => 1,
57 | 'container' => 'default',
58 | 'description' => 0,
59 | 'keyowrds' => null,
60 | 'create_user_id' => 0,
61 | 'update_user_id' => 0,
62 | 'image_id' => 0,
63 | 'timestamp_create' => time(),
64 | 'timestamp_update' => time(),
65 | 'parent_nav_id' => 0,
66 | 'is_home' => 0,
67 | 'sort_index' => 1000,
68 | 'depth' => 1,
69 | ], $args);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/tests/CmsNgRestTestCase.php:
--------------------------------------------------------------------------------
1 | 'ngresttest',
13 | 'basePath' => dirname(__DIR__),
14 | 'components' => [
15 | 'db' => [
16 | 'class' => 'yii\db\Connection',
17 | 'dsn' => 'sqlite::memory:',
18 | ],
19 | 'urlManager' => [
20 | 'cache' => null,
21 | ]
22 | ]
23 | ];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:8.1-cli
2 | RUN apt-get update -yqq \
3 | && apt-get install -y libicu-dev sqlite3 \
4 | && docker-php-ext-install intl mysqli pdo pdo_mysql
--------------------------------------------------------------------------------
/tests/ModelTestCase.php:
--------------------------------------------------------------------------------
1 | 'basetestcase',
14 | 'basePath' => dirname(__DIR__),
15 | 'components' => [
16 | 'db' => [
17 | 'class' => 'yii\db\Connection',
18 | 'dsn' => 'sqlite::memory:',
19 | ],
20 | 'urlManager' => [
21 | 'cache' => null,
22 | ],
23 | 'adminLanguage' => [
24 | 'class' => AdminLanguage::class,
25 | ]
26 | ]
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/WebModelTestCase.php:
--------------------------------------------------------------------------------
1 | 'webmodel',
13 | 'basePath' => dirname(__DIR__),
14 | 'components' => [
15 | 'db' => [
16 | 'class' => 'yii\db\Connection',
17 | 'dsn' => 'sqlite::memory:',
18 | ],
19 | 'urlManager' => [
20 | 'cache' => null,
21 | ]
22 | ],
23 | 'modules' => [
24 | 'admin' => [
25 | 'class' => 'luya\admin\Module',
26 | 'queueMutexClass' => 'yii\mutex\FileMutex',
27 | ],
28 | 'cms' => 'luya\cms\frontend\Module',
29 | 'cmsadmin' => 'luya\cms\admin\Module',
30 | ]
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/data/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/tests/data/blocks/PhpTestBlock.php:
--------------------------------------------------------------------------------
1 | 'bar'];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/data/blocks/TestBlock.php:
--------------------------------------------------------------------------------
1 | [
25 | ['var' => 'var1', 'label' => 'VAR 1', 'type' => 'zaa-text', 'placeholder' => 'VAR 1 PLACEHOLDER'],
26 | ['var' => 'var2', 'label' => 'VAR 2', 'type' => 'zaa-text'],
27 | ],
28 | 'cfgs' => [
29 | ['var' => 'cfg1', 'label' => 'CFG 1', 'type' => 'zaa-text'],
30 | ],
31 | ];
32 | }
33 |
34 | public function admin()
35 | {
36 | return [
37 | $this->getVarValue('var1'),
38 | $this->getVarValue('var2'),
39 | $this->getCfgValue('cfg1'),
40 | $this->getEnvOptions(),
41 | ];
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/data/blocks/UnitTestBlock.php:
--------------------------------------------------------------------------------
1 | [
25 | ['var' => 'var1', 'label' => 'VAR 1', 'type' => 'zaa-text', 'placeholder' => 'VAR 1 PLACEHOLDER'],
26 | ['var' => 'var2', 'label' => 'VAR 2', 'type' => 'zaa-text'],
27 | ],
28 | 'cfgs' => [
29 | ['var' => 'cfg1', 'label' => 'CFG 1', 'type' => 'zaa-text'],
30 | ],
31 | ];
32 | }
33 |
34 | public function admin()
35 | {
36 | return [
37 | $this->getVarValue('var1'),
38 | $this->getVarValue('var2'),
39 | $this->getCfgValue('cfg1'),
40 | $this->getEnvOptions(),
41 | ];
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/data/cmslayouts/layoutwithjson.json:
--------------------------------------------------------------------------------
1 | {
2 | "rows" : [
3 | [
4 | {"cols": 8, "var": "left", "label": "Main content Left"},
5 | {"cols": 4, "var": "right", "label": "Sidebar Right"}
6 | ]
7 | ]
8 | }
--------------------------------------------------------------------------------
/tests/data/cmslayouts/layoutwithjson.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | = $placeholders['left']; ?>
4 |
5 |
6 | = $placeholders['right']; ?>
7 |
8 |
--------------------------------------------------------------------------------
/tests/data/cmslayouts/phplayout.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | = $placeholders['left']; ?>
4 |
5 |
6 | = $placeholders['right']; ?>
7 |
8 |
--------------------------------------------------------------------------------
/tests/data/configs/cms.php:
--------------------------------------------------------------------------------
1 | 'testenv',
5 | 'siteTitle' => 'Luya Tests',
6 | 'remoteToken' => 'testtoken',
7 | 'basePath' => dirname(__DIR__),
8 | 'defaultRoute' => 'cms',
9 | 'aliases' => [
10 | 'cmstests' => dirname(__DIR__) . '/../',
11 | ],
12 | 'language' => 'en',
13 | 'modules' => [
14 | 'admin' => [
15 | 'class' => 'luya\admin\Module',
16 | 'queueMutexClass' => 'yii\mutex\FileMutex',
17 | ],
18 | 'cms' => [
19 | 'class' => '\luya\cms\frontend\Module'
20 | ],
21 | 'cmsadmin' => 'luya\cms\admin\Module',
22 | 'CmsUnitModule' => '\cmstests\data\modules\CmsUnitModule',
23 | ],
24 | 'components' => [
25 | 'request' => [
26 | 'forceWebRequest' => true,
27 | ],
28 | 'composition' => [
29 | 'hidden' => false,
30 | ],
31 | 'db' => [
32 | 'class' => 'yii\db\Connection',
33 | 'dsn' => DB_DSN,
34 | 'username' => DB_USER,
35 | 'password' => DB_PASS,
36 | 'charset' => 'utf8',
37 | ],
38 | 'cache' => \yii\caching\ArrayCache::class,
39 | 'assetManager' => [
40 | 'basePath' => dirname(__DIR__) . '/assets',
41 | ],
42 | 'website' => [
43 | 'class' => \luya\cms\Website::class,
44 | ]
45 | ],
46 | ];
47 |
--------------------------------------------------------------------------------
/tests/data/env.php:
--------------------------------------------------------------------------------
1 | [
15 | 'id' => '1',
16 | 'name' => 'John',
17 | ],
18 | 'tag2' => [
19 | 'id' => '2',
20 | 'name' => 'Jane',
21 | ],
22 | ];
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/data/images/blocks/TestBlock.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyadev/luya-module-cms/8a3472acfc2620374fb8de6aed1f2736926cca2b/tests/data/images/blocks/TestBlock.jpg
--------------------------------------------------------------------------------
/tests/data/items/RootItem.php:
--------------------------------------------------------------------------------
1 | $this->getId(),
23 | 'nav_id' => 1,
24 | 'lang' => $this->getLang(),
25 | 'link' => '/',
26 | 'title' => 'Root',
27 | 'title_tag' => 'Root',
28 | 'alias' => 'root',
29 | 'description' => null,
30 | 'keywords' => null,
31 | 'create_user_id' => 0,
32 | 'update_user_id' => 0,
33 | 'timestamp_create' => time(),
34 | 'timestamp_update' => time(),
35 | 'is_home' => 1,
36 | 'parent_nav_id' => 0,
37 | 'sort_index' => 0,
38 | 'is_hidden' => false,
39 | 'type' => 1,
40 | 'redirect' => false,
41 | 'container' => 'default',
42 | 'depth' => 0,
43 | ];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/data/modules/CmsUnitModule.php:
--------------------------------------------------------------------------------
1 | /' => 'cmsurlrulemodule/default/index',
11 | ];
12 | }
13 |
--------------------------------------------------------------------------------
/tests/data/modules/controllers/DefaultController.php:
--------------------------------------------------------------------------------
1 | = $placeholders['content']; ?>
--------------------------------------------------------------------------------
/tests/data/themes/testTheme/theme.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/tests/data/views/blocks/PhpTestBlock.php:
--------------------------------------------------------------------------------
1 | frontend
--------------------------------------------------------------------------------
/tests/data/views/cmslayouts/main.php:
--------------------------------------------------------------------------------
1 | = $placeholders['content']; ?>
--------------------------------------------------------------------------------
/tests/data/views/layouts/main.php:
--------------------------------------------------------------------------------
1 | beginPage();
10 | ?>
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | = $this->title; ?>
19 | head() ?>
20 |
21 |
22 | beginBody() ?>
23 | = $content; ?>
24 | endBody() ?>
25 |
26 |
27 | endPage() ?>
--------------------------------------------------------------------------------
/tests/runtime/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luyadev/luya-module-cms/8a3472acfc2620374fb8de6aed1f2736926cca2b/tests/runtime/.gitkeep
--------------------------------------------------------------------------------
/tests/src/LinkConverterTest.php:
--------------------------------------------------------------------------------
1 | LinkConverter::TYPE_INTERNAL_PAGE, 'value' => 1, 'target' => null]);
16 |
17 | $this->assertInstanceOf(\luya\cms\menu\Item::class, $converter->getLink());
18 | }
19 |
20 | public function testExternalLink()
21 | {
22 | $converter = LinkConverter::fromArray(['type' => LinkConverter::TYPE_EXTERNAL_URL, 'value' => "luya.io", 'target' => null]);
23 |
24 | $this->assertInstanceOf(WebsiteLink::class, $converter->getLink());
25 | }
26 |
27 | public function testFileLink()
28 | {
29 | $this->markTestSkipped('Require a file entry in the test database.');
30 |
31 | $converter = LinkConverter::fromArray(['type' => LinkConverter::TYPE_LINK_TO_FILE, 'value' => 1, 'target' => null]);
32 |
33 | $this->assertInstanceOf(\luya\admin\file\Item::class, $converter->getLink());
34 | }
35 |
36 | public function testEmailLink()
37 | {
38 | $converter = LinkConverter::fromArray(['type' => LinkConverter::TYPE_LINK_TO_EMAIL, 'value' => 'mail@luya.io', 'target' => null]);
39 |
40 | $this->assertInstanceOf(EmailLink::class, $converter->getLink());
41 | }
42 |
43 | public function testTelephoneLink()
44 | {
45 | $converter = LinkConverter::fromArray(['type' => LinkConverter::TYPE_LINK_TO_TELEPHONE, 'value' => '0123456', 'target' => null]);
46 |
47 | $this->assertInstanceOf(TelephoneLink::class, $converter->getLink());
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/src/MenuTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(is_object(Yii::$app->menu));
18 | }
19 |
20 | public function testSelfClass()
21 | {
22 | $objectData = new Menu((new \luya\web\Request()));
23 | $current = $objectData->current;
24 | $this->assertEquals("Homepage", $current->title);
25 | $this->assertEquals(Yii::$app->urlManager->prependBaseUrl(''), $current->link);
26 | }
27 |
28 | public function testGetCurrent()
29 | {
30 | $current = Yii::$app->menu->current;
31 | $this->assertEquals("Homepage", $current->title);
32 | $this->assertEquals(Yii::$app->urlManager->prependBaseUrl(''), $current->link);
33 | }
34 |
35 | public function testGetHome()
36 | {
37 | $home = Yii::$app->menu->home;
38 | $this->assertEquals("Homepage", $home->title);
39 | $this->assertEquals(Yii::$app->urlManager->prependBaseUrl(''), $home->link);
40 | }
41 |
42 | public function testOffsetArrayAccess()
43 | {
44 | $menu = Yii::$app->menu;
45 | $this->assertEquals(17, count($menu['en']));
46 | }
47 |
48 | public function testCurrentAppendix()
49 | {
50 | $this->assertEmpty(Yii::$app->menu->currentAppendix);
51 | }
52 |
53 | public function testFind()
54 | {
55 | $obj = Yii::$app->menu->find();
56 | $this->assertTrue($obj instanceof Query);
57 | }
58 |
59 | public function testFindOne()
60 | {
61 | $obj = Yii::$app->menu->findOne(['id' => 1]);
62 | $this->assertTrue($obj instanceof Item);
63 | }
64 |
65 | public function testFindOneFalse()
66 | {
67 | $obj = Yii::$app->menu->findOne(['id' => 2000]);
68 | $this->assertFalse($obj);
69 | }
70 |
71 | public function testFindAll()
72 | {
73 | $iterator = Yii::$app->menu->findAll(['parent_nav_id' => 0]);
74 | $this->assertTrue($iterator instanceof QueryIteratorFilter);
75 | }
76 |
77 | public function testOffsetLangaugeDoesNotExists()
78 | {
79 | $this->expectException(NotFoundHttpException::class);
80 | Yii::$app->menu['ru'];
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/tests/src/MessageFileTest.php:
--------------------------------------------------------------------------------
1 | compareMessages(Yii::getAlias('@cmsadmin/messages'), 'en');
16 | }
17 |
18 | public function testFrontendMessages()
19 | {
20 | $this->compareMessages(Yii::getAlias('@cms/messages'), 'en');
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/src/admin/apis/AdminControllerTest.php:
--------------------------------------------------------------------------------
1 | createAdminLangFixture([]);
16 | $this->createCmsLog([
17 | 1 => [
18 | 'id' => 1,
19 | 'user_id' => 1,
20 | 'is_insertion' => 1,
21 | 'is_update' => 0,
22 | 'is_deletion' => 0,
23 | 'timestamp' => time(),
24 | 'table_name' => 'xyz',
25 | 'row_id' => 1,
26 | ]
27 | ]);
28 | $this->createAdminUserFixture();
29 | $ctrl = new AdminController('id', $this->app);
30 |
31 | $log = $ctrl->actionDashboardLog();
32 |
33 | $this->assertNotEmpty($log);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/src/admin/apis/NavItemControllerTest.php:
--------------------------------------------------------------------------------
1 | createAdminLangFixture();
20 | $this->createCmsNavItemPageFixture([
21 | 2 => [
22 | 'id' => 2,
23 | 'layout_id' => 1,
24 | 'nav_item_id' => 1,
25 | 'version_alias' => 'test',
26 | ]
27 | ]);
28 |
29 | $this->createCmsNavItemFixture([
30 | 1 => [
31 | 'id' => 1,
32 | ]
33 | ]);
34 | }
35 |
36 | public function testChangePageVersionLayoutNotFound()
37 | {
38 | $ctrl = new NavItemController('nav-item', $this->app->getModule('cmsadmin'));
39 |
40 | Yii::$app->request->setBodyParams(['pageItemId' => 1, 'layoutId' => 1, 'alias' => 1]);
41 | $this->expectException(NotFoundHttpException::class);
42 | $ctrl->actionChangePageVersionLayout();
43 | }
44 |
45 | public function testChangePageVersionLayout()
46 | {
47 | $ctrl = new NavItemController('nav-item', $this->app->getModule('cmsadmin'));
48 |
49 | Yii::$app->request->setBodyParams(['pageItemId' => 2, 'layoutId' => 1, 'alias' => 'foobar']);
50 | $r = $ctrl->actionChangePageVersionLayout();
51 |
52 | $this->assertInstanceOf(NavItemType::class, $r);
53 |
54 | $this->assertSame(1, $r->layout_id);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/src/admin/controllers/DefaultControllerTest.php:
--------------------------------------------------------------------------------
1 | app, function (PermissionScope $scope) {
17 | $ctrl = new DefaultController('default', $this->app->getModule('cmsadmin'));
18 | $this->assertNotEmpty($ctrl->actionIndex());
19 | });
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/src/admin/controllers/PageControllerTest.php:
--------------------------------------------------------------------------------
1 | app, function (PermissionScope $scope) {
17 | $ctrl = new PageController('page', $this->app->getModule('cmsadmin'));
18 | $this->assertNotEmpty($ctrl->actionUpdate());
19 | $this->assertNotEmpty($ctrl->actionDrafts());
20 | $this->assertNotEmpty($ctrl->actionCreate());
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/src/admin/controllers/PermissionControllerTest.php:
--------------------------------------------------------------------------------
1 | app->getModule('cmsadmin'));
16 | $this->assertNotEmpty($ctrl->actionIndex());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/src/base/BaseBlockInjectorTest.php:
--------------------------------------------------------------------------------
1 | [
20 | ['var' => 'text-input', 'type' => 'zaa-text', 'label' => 'text'],
21 | ],
22 | ];
23 | }
24 | }
25 |
26 | class StubInjector extends BaseBlockInjector
27 | {
28 | /**
29 | * @inheritdoc
30 | */
31 | public function setup()
32 | {
33 | $this->setContextConfig([
34 | 'var' => $this->varName,
35 | 'label' => $this->varLabel,
36 | 'type' => 'injector-test',
37 | ]);
38 |
39 | $this->context->addExtraVar($this->varName, 'injector-output');
40 | }
41 | }
42 |
43 | class BaseBlockInjectorTest extends CmsFrontendTestCase
44 | {
45 | public function testLinkInjector()
46 | {
47 | $block = new StubBlock();
48 | $injector = new StubInjector(['context' => $block]);
49 | $injector->setup();
50 |
51 | $cfgs = $block->getConfigVarsExport();
52 |
53 | $this->assertSame('injector-test', $cfgs[0]['type']);
54 | $this->assertSame('zaa-text', $cfgs[1]['type']);
55 | }
56 |
57 | public function testAppendOfVar()
58 | {
59 | $block = new StubBlock();
60 | $injector = new StubInjector(['context' => $block, 'append' => true]);
61 | $injector->setup();
62 |
63 | $cfgs = $block->getConfigVarsExport();
64 |
65 | $this->assertSame('injector-test', $cfgs[1]['type']);
66 | $this->assertSame('zaa-text', $cfgs[0]['type']);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/tests/src/base/PhpBlockTest.php:
--------------------------------------------------------------------------------
1 | assertSame('admin', $block->renderAdmin());
15 | }
16 |
17 | public function testFrontendResponse()
18 | {
19 | $block = new PhpTestBlock();
20 | return $this->assertSame('frontend', $block->renderFrontend());
21 | }
22 |
23 | public function testExtraVarsGetter()
24 | {
25 | $block = new PhpTestBlock();
26 | $this->assertArrayHasKey('foo', $block->extraVars());
27 | }
28 |
29 | public function testExtraVarsValueGetter()
30 | {
31 | $block = new PhpTestBlock();
32 | $this->assertSame('bar', $block->getExtraValue('foo'));
33 | }
34 |
35 | public function textExtraVarValuesGetter()
36 | {
37 | $block = new PhpTestBlock();
38 | $this->assertArrayHasKey('foo', $block->getExtraVarValues());
39 | }
40 |
41 | /**
42 | * @todo Test register multiple asset bundles
43 | */
44 | public function testOnRegister()
45 | {
46 | $block = new PhpTestBlock();
47 | $block->cacheEnabled = true;
48 |
49 | $block->getView()->registerAssetBundle(AssetBundle::class);
50 | // $block->getView()->registerAssetBundle(JqueryAsset::class);
51 |
52 | $block->onRegister();
53 |
54 | $this->assertSame([AssetBundle::class], \Yii::$app->cache->get(['blockassetbundles', $block->getEnvOption('id')]));
55 | // $this->assertSame([AssetBundle::class, JqueryAsset::class], \Yii::$app->cache->get(['blockassetbundles', $block->getEnvOption('id')]));
56 | }
57 |
58 | public function testRelativeViewPath()
59 | {
60 | $block = new PhpTestBlock();
61 | $block->module = null;
62 |
63 | $this->assertStringContainsString('tests'.DIRECTORY_SEPARATOR.'data'.DIRECTORY_SEPARATOR.'blocks'.DIRECTORY_SEPARATOR.'views', $block->getViewPath());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/src/controllers/BlockControllerTest.php.bkp:
--------------------------------------------------------------------------------
1 | runAction('block/index');
18 | }
19 |
20 | /**
21 | * @expectedException yii\base\Exception
22 | */
23 | public function testUnableToFindItemId()
24 | {
25 | $response = (new Module('cms'))->runAction('block/index', ['callback' => 'test', 'id' => 0]);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/src/controllers/PreviewControllerTest.php.bkp:
--------------------------------------------------------------------------------
1 | getModule('cms')->runAction('preview/index');
18 | }
19 |
20 | /**
21 | * itemId param is missing
22 | * @expectedException yii\web\ForbiddenHttpException
23 | */
24 | public function testNoAuthToView()
25 | {
26 | $response = Yii::$app->getModule('cms')->runAction('preview/index', ['itemId' => 1]);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/src/frontend/BootstrapErrorPageTest.php:
--------------------------------------------------------------------------------
1 | bootstrap($this->app);
19 |
20 | $event = new ErrorHandlerExceptionRenderEvent();
21 | $event->exception = new NotFoundHttpException("not found");
22 |
23 |
24 | new ActiveRecordFixture([
25 | 'modelClass' => Config::class,
26 | ]);
27 |
28 | Config::set(Config::HTTP_EXCEPTION_NAV_ID, 1);
29 |
30 | $this->expectException('yii\web\HeadersAlreadySentException');
31 | $this->app->errorHandler->trigger(ErrorHandler::EVENT_BEFORE_EXCEPTION_RENDER, $event);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/src/frontend/ModuleTest.php:
--------------------------------------------------------------------------------
1 | fixture = new NgRestModelFixture([
23 | 'modelClass' => Theme::class,
24 | ]);
25 | }
26 |
27 | public function testBootstrap()
28 | {
29 | /** @var Theme $themeModel */
30 | $themeModel = $this->fixture->newModel;
31 | $themeModel->is_default = 1;
32 | $themeModel->base_path = '@app/themes/appTheme';
33 | $themeModel->json_config = '{}';
34 | $this->assertTrue($themeModel->save());
35 |
36 | Yii::$app->request->forceWebRequest = true;
37 | Yii::$app->request->setIsConsoleRequest(false);
38 |
39 | /** @var Module $module */
40 | $module = Yii::$app->getModule('cms');
41 | $module->luyaBootstrap(Yii::$app);
42 |
43 | Yii::$app->themeManager->activeThemeName = '@app/themes/moduleTest';
44 | Yii::$app->themeManager->setup();
45 |
46 | $this->assertTrue(Yii::$app->themeManager->hasActiveTheme);
47 | $this->assertEquals(Yii::getAlias('@app/themes/appTheme'), Yii::$app->themeManager->activeTheme->basePath);
48 |
49 | $this->fixture->cleanup();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/tests/src/frontend/blockgroups/DevelopmentGroupTest.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.6
13 | */
14 | class DevelopmentGroupTest extends CmsBlockGroupTestCase
15 | {
16 | public $blockGroupClass = 'luya\cms\frontend\blockgroups\DevelopmentGroup';
17 |
18 | public $blockGroupIdentifier = 'development-group';
19 | }
20 |
--------------------------------------------------------------------------------
/tests/src/frontend/blockgroups/LayoutGroupTest.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.6
13 | */
14 | class LayoutGroupTest extends CmsBlockGroupTestCase
15 | {
16 | public $blockGroupClass = 'luya\cms\frontend\blockgroups\LayoutGroup';
17 |
18 | public $blockGroupIdentifier = 'layout-group';
19 | }
20 |
--------------------------------------------------------------------------------
/tests/src/frontend/blockgroups/MainGroupTest.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.6
13 | */
14 | class MainGroupTest extends CmsBlockGroupTestCase
15 | {
16 | public $blockGroupClass = 'luya\cms\frontend\blockgroups\MainGroup';
17 |
18 | public $blockGroupIdentifier = 'main-group';
19 | }
20 |
--------------------------------------------------------------------------------
/tests/src/frontend/blockgroups/MediaGroupTest.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.6
13 | */
14 | class MediaGroupTest extends CmsBlockGroupTestCase
15 | {
16 | public $blockGroupClass = 'luya\cms\frontend\blockgroups\MediaGroup';
17 |
18 | public $blockGroupIdentifier = 'media-group';
19 | }
20 |
--------------------------------------------------------------------------------
/tests/src/frontend/blockgroups/ProjectGroupTest.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.6
13 | */
14 | class ProjectGroupTest extends CmsBlockGroupTestCase
15 | {
16 | public $blockGroupClass = 'luya\cms\frontend\blockgroups\ProjectGroup';
17 |
18 | public $blockGroupIdentifier = 'project-group';
19 | }
20 |
--------------------------------------------------------------------------------
/tests/src/frontend/blockgroups/TextGroupTest.php:
--------------------------------------------------------------------------------
1 |
12 | * @since 1.0.6
13 | */
14 | class TextGroupTest extends CmsBlockGroupTestCase
15 | {
16 | public $blockGroupClass = 'luya\cms\frontend\blockgroups\TextGroup';
17 |
18 | public $blockGroupIdentifier = 'text-group';
19 | }
20 |
--------------------------------------------------------------------------------
/tests/src/frontend/blocks/HtmlBlockTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('', $this->renderFrontend());
14 | }
15 |
16 | public function testInputHtml()
17 | {
18 | $this->block->setVarValues([
19 | 'html' => 'Hello World
',
20 | ]);
21 |
22 | $this->assertSame('Hello World
', $this->renderFrontendNoSpace());
23 | }
24 |
25 | public function testAdminRawOutput()
26 | {
27 | $this->block->setVarValues([
28 | 'html' => 'hello
',
29 | ]);
30 |
31 | $this->assertSame('<p>hello</p>
', $this->renderAdminNoSpace());
32 |
33 | $this->block->setCfgValues(['raw' => 1]);
34 |
35 | $this->assertSame('hello
', $this->renderAdminNoSpace());
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/src/frontend/blocks/MirrorLanguageBlockTest.php:
--------------------------------------------------------------------------------
1 | createAdminLangFixture([
16 | 1 => [
17 | 'id' => 1,
18 | 'name' => 'en',
19 | 'short_code' => 'en',
20 | 'is_default' => 1,
21 | 'is_deleted' => 0,
22 | ],
23 | 2 => [
24 | 'id' => 2,
25 | 'name' => 'de',
26 | 'short_code' => 'de',
27 | 'is_default' => 0,
28 | 'is_deleted' => 0,
29 | ]
30 | ]);
31 | $this->createCmsNavItemPageBlockItemFixture([
32 | 1 => [
33 | 'id' => 1,
34 | 'placeholder_var' => 'xyz',
35 | 'nav_item_page_id' => 1,
36 | ]
37 | ]);
38 | $this->createCmsNavItemPageFixture([
39 | 1 => [
40 | 'id' => 1,
41 | 'nav_item_id' => 1
42 | ]
43 | ]);
44 |
45 | $this->createCmsNavItemFixture([
46 | 1 => [
47 | 'id' => 1,
48 | 'lang_id' => 1,
49 | 'nav_item_type' => 1,
50 | ],
51 | 2 => [
52 | 'id' => 2,
53 | 'lang_id' => 2,
54 | 'nav_item_type' => 1,
55 | ]
56 | ]);
57 |
58 | $block = new MirrorLanguageBlock();
59 |
60 | $this->assertEmpty($block->frontend());
61 | $this->assertNotEmpty($block->name());
62 | $this->assertNotEmpty($block->icon());
63 | $this->assertNotEmpty($block->config());
64 | $this->assertNotEmpty($block->admin());
65 |
66 | $block->setVarValues(['language' => 2]);
67 |
68 | $r = $block->frontend();
69 |
70 | $block->setVarValues(['language' => 1]);
71 |
72 | $r = $block->frontend();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/src/frontend/commands/PageControllerTest.php:
--------------------------------------------------------------------------------
1 | app, function (PageScope $scope) {
15 | $scope->createCmsNavFixture([]);
16 | $scope->createCmsNavItemFixture([]);
17 | $scope->createCmsNavItemPageFixture([]);
18 | $scope->createCmsNavItemPageBlockItemFixture([
19 | 'item1' => [
20 | 'id' => 1,
21 | 'json_config_values' => '',
22 | 'json_config_cfg_values' => '',
23 | 'block_id' => 0,
24 | 'placeholder_var' => 'default',
25 | 'nav_item_page_id' => 1,
26 | ]
27 | ]);
28 | $scope->createCmsPropertyFixture([]);
29 | $scope->createCmsNavPermissionFixture([]);
30 | $ctrl = new PageControllerStub('page', $this->app);
31 | $ctrl->sendInput('yes');
32 | $r = $ctrl->actionCleanup();
33 |
34 | $this->assertSame(0, $r);
35 | });
36 |
37 |
38 | PageScope::run($this->app, function (PageScope $scope) {
39 | $scope->createCmsNavFixture([]);
40 | $scope->createCmsNavItemFixture([]);
41 | $scope->createCmsNavItemPageFixture([]);
42 | $scope->createCmsNavItemPageBlockItemFixture([
43 | 'item1' => [
44 | 'id' => 1,
45 | 'json_config_values' => '',
46 | 'json_config_cfg_values' => '',
47 | 'block_id' => 0,
48 | 'placeholder_var' => 'default',
49 | 'nav_item_page_id' => 1,
50 | ]
51 | ]);
52 | $scope->createCmsPropertyFixture([]);
53 | $scope->createCmsNavPermissionFixture([]);
54 | $ctrl = new PageControllerStub('page', $this->app);
55 | $ctrl->truncateStreams();
56 | $r = $ctrl->actionCleanup();
57 |
58 | $this->assertSame(1, $r);
59 | });
60 | }
61 | }
62 |
63 | class PageControllerStub extends PageController
64 | {
65 | use CommandStdStreamTrait;
66 | }
67 |
--------------------------------------------------------------------------------
/tests/src/frontend/components/CatchAllUrlRuleTest.php:
--------------------------------------------------------------------------------
1 | assertFalse($rule->createUrl($this->app->urlManager, '/cms/default/index/', ['path' => 'foo/bar']));
15 | $this->assertFalse($rule->createUrl($this->app->urlManager, '/wrong/route', ['path' => 'foo/bar']));
16 | $this->assertFalse($rule->createUrl($this->app->urlManager, 'cms/default/index', []));
17 |
18 | $this->assertSame('foo/bar', $rule->createUrl($this->app->urlManager, 'cms/default/index', ['path' => 'foo/bar']));
19 | $this->assertSame('foo/bar', $rule->createUrl($this->app->urlManager, '/cms/default/index', ['path' => 'foo/bar']));
20 | $this->assertSame('foo/bar?page=1', $rule->createUrl($this->app->urlManager, 'cms/default/index', ['path' => 'foo/bar', 'page' => 1]));
21 | }
22 |
23 | public function testParseRequest()
24 | {
25 | $rule = new CatchAllUrlRule();
26 |
27 | $this->assertFalse($rule->parseRequest($this->app->urlManager, $this->app->request));
28 |
29 | $this->app->request->pathInfo = 'foo/bar';
30 | $this->assertSame([
31 | 'cms/default/index',
32 | ['path' => 'foo/bar'],
33 | ], $rule->parseRequest($this->app->urlManager, $this->app->request));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/src/frontend/controllers/BlockControllerTest.php:
--------------------------------------------------------------------------------
1 | app);
13 |
14 | $this->assertSame('callbackMyAction', $this->invokeMethod($ctrl, 'callbackToMethod', ['my-action']));
15 | $this->assertSame('callbackMyAction', $this->invokeMethod($ctrl, 'callbackToMethod', ['myAction']));
16 | $this->assertSame('callbackMyAction', $this->invokeMethod($ctrl, 'callbackToMethod', ['callback-my-action']));
17 | $this->assertSame('callbackMyAction', $this->invokeMethod($ctrl, 'callbackToMethod', ['callbackMyAction']));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/src/helpers/BlockHelperTest.php:
--------------------------------------------------------------------------------
1 | assertSame([['label' => 'World', 'value' => 'Hello']], BlockHelper::selectArrayOption(['Hello' => 'World']));
13 |
14 | $this->assertSame([
15 | ['label' => 'bar', 'value' => 'foo']
16 | ], BlockHelper::selectArrayOption(['foo' => 'bar']));
17 |
18 | $this->assertSame([
19 | ['label' => 'Prompt!', 'value' => 0],
20 | ['label' => 'bar', 'value' => 'foo']
21 | ], BlockHelper::selectArrayOption(['foo' => 'bar'], 'Prompt!'));
22 | }
23 |
24 | public function testCheckboxArrayOption()
25 | {
26 | $this->assertSame(['items' => [['label' => 'World', 'value' => 'Hello']]], BlockHelper::checkboxArrayOption(['Hello' => 'World']));
27 | }
28 |
29 | public function testImageUpload()
30 | {
31 | $this->assertFalse(BlockHelper::imageUpload(1));
32 | }
33 | public function testImageArrayUpload()
34 | {
35 | $this->assertSame([], BlockHelper::imageArrayUpload([
36 | ['imageId' => 1],
37 | ['imageId' => 2]
38 | ]));
39 | }
40 |
41 | public function testFileUpload()
42 | {
43 | $this->assertFalse(BlockHelper::fileUpload(1));
44 | }
45 | public function testFileArrayUpload()
46 | {
47 | $this->assertSame([], BlockHelper::fileArrayUpload(
48 | [
49 | ['fileId' => 1],
50 | ['fileId' => 2]
51 | ]
52 | ));
53 | }
54 |
55 | public function testInternalGenerateLinkObject()
56 | {
57 | $url = BlockHelper::linkObject(['type' => 1, 'value' => 2]);
58 | $this->assertInstanceOf('luya\web\LinkInterface', $url);
59 |
60 | $this->assertSame('_self', $url->getTarget());
61 | }
62 |
63 | public function testExternalGenerateLinkObject()
64 | {
65 | $url = BlockHelper::linkObject(['type' => 2, 'value' => 'https://luya.io']);
66 | $this->assertInstanceOf('luya\web\LinkInterface', $url);
67 |
68 | $this->assertSame('_blank', $url->getTarget());
69 | }
70 |
71 | public function testMarkdown()
72 | {
73 | $this->assertSameTrimmed('barfoo
', BlockHelper::markdown('**barfoo**'));
74 | }
75 |
76 | public function testRadioArrayOption()
77 | {
78 | $this->assertSame([
79 | ['label' => 'bar', 'value' => 'foo']
80 | ], BlockHelper::radioArrayOption(['foo' => 'bar']));
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/tests/src/helpers/UrlTest.php:
--------------------------------------------------------------------------------
1 | assertSame('foobar', Url::toModule('foobar'));
13 | $this->assertSame('foobar', Url::toModule('foobar', true));
14 | }
15 |
16 | public function testToModuleRoute()
17 | {
18 | $this->expectException('luya\cms\Exception');
19 | Url::toModuleRoute('foobar', ['/module/controller/action']);
20 | }
21 |
22 | public function testToMenuItem()
23 | {
24 | $this->assertStringContainsString('en/module/controller/action', Url::toMenuNavItem(1, ['/module/controller/action']));
25 | $https = Url::toMenuNavItem(1, ['/module/controller/action'], 'https');
26 | $this->assertStringContainsString('en/module/controller/action', $https);
27 | $this->assertStringContainsString('https://', $https);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/src/injectors/ActiveQueryCheckboxInjectorTest.php:
--------------------------------------------------------------------------------
1 | NavItem::find(), 'varName' => 'test', 'varLabel' => 'test label', 'context' => $block]);
29 | $injector->setup();
30 |
31 | $vars = $block->getConfigVarsExport();
32 |
33 | $v = $vars[0];
34 |
35 | $this->assertSame('test', $v['var']);
36 | $this->assertSame('test label', $v['label']);
37 |
38 | $items = $v['options']['items'];
39 |
40 | $this->assertNotEmpty(count($items));
41 |
42 | $item1 = $v['options']['items'][0];
43 |
44 | $this->assertStringContainsString('Homepage, homepage,', $item1['label']);
45 | }
46 |
47 | public function testFieldSelectionBasicInjector()
48 | {
49 | $block = new Block();
50 | $injector = new ActiveQueryCheckboxInjector(['query' => NavItem::find()->select(['title']), 'label' => 'title', 'varName' => 'test', 'varLabel' => 'test label', 'context' => $block]);
51 | $injector->setup();
52 |
53 | $vars = $block->getConfigVarsExport();
54 |
55 | $v = $vars[0];
56 |
57 | $this->assertSame('test', $v['var']);
58 | $this->assertSame('test label', $v['label']);
59 |
60 | $items = $v['options']['items'];
61 |
62 | $this->assertNotEmpty(count($items));
63 |
64 | $item1 = $v['options']['items'][0];
65 |
66 | $this->assertSame('Homepage', $item1['label']);
67 | }
68 |
69 | /**
70 | * https://github.com/luyadev/luya/issues/1187
71 | */
72 | public function testLabelLambda()
73 | {
74 | $block = new Block();
75 | $injector = new ActiveQueryCheckboxInjector(['query' => NavItem::find(), 'label' => function ($model) {
76 | return $model->id . '@' . $model->title;
77 | }, 'varName' => 'test', 'varLabel' => 'test label', 'context' => $block]);
78 | $injector->setup();
79 | $vars = $block->getConfigVarsExport();
80 | $this->assertSame('1@Homepage', $vars[0]['options']['items'][0]['label']);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/tests/src/injectors/ActiveQuerySelectInjectorTest.php:
--------------------------------------------------------------------------------
1 | Layout::class,
19 | 'fixtureData' => [
20 | 1 => [
21 | 'id' => 1,
22 | 'name' => 'foo',
23 | 'json_config' => '{"node":"value"}',
24 | 'view_file' => 'none.php',
25 | ]
26 | ]
27 | ]);
28 | }
29 |
30 | public function testVariableResponse()
31 | {
32 | $block = new TestBlock();
33 | $block->setVarValues([
34 | 'foobar' => 1,
35 | ]);
36 |
37 | $injector = new ActiveQuerySelectInjector([
38 | 'query' => Layout::find(),
39 | 'varName' => 'foobar',
40 | 'varLabel' => 'test',
41 | 'label' => 'name',
42 | 'context' => $block,
43 | ]);
44 | $injector->setup();
45 |
46 |
47 | $f = $block->getExtraValue('foobar');
48 | $x = $block->getVarValue('foobar');
49 | $y = $block->getConfigVarsExport();
50 |
51 | $this->assertSame('foo', $y[0]['options'][0]['label']);
52 | $this->assertSame(1, $x);
53 | $this->assertSame(['node' => 'value'], $f->getJsonConfig());
54 | $this->assertSame('value', $f->getJsonConfig('node'));
55 | }
56 |
57 | public function testVariableNotFoundId()
58 | {
59 | $block = new TestBlock();
60 | $block->setVarValues([
61 | 'foobar' => 0,
62 | ]);
63 |
64 | $injector = new ActiveQuerySelectInjector([
65 | 'query' => Layout::find(),
66 | 'varName' => 'foobar',
67 | 'varLabel' => 'test',
68 | 'label' => 'name',
69 | 'context' => $block,
70 | ]);
71 | $injector->setup();
72 |
73 | $this->assertFalse($block->getExtraValue('foobar'));
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/tests/src/injectors/LinkInjectorTest.php:
--------------------------------------------------------------------------------
1 | $block]);
28 | $injector->setup();
29 |
30 | $vars = $block->getConfigVarsExport();
31 |
32 | $this->assertArrayHasKey('type', $vars[0]);
33 | $this->assertSame('zaa-link', $vars[0]['type']);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/src/injectors/TagInjectorTest.php:
--------------------------------------------------------------------------------
1 | createAdminLangFixture([
34 | 1 => [
35 | 'id' => 1,
36 | 'name' => 'en',
37 | 'short_code' => 'en',
38 | 'is_default' => 1,
39 | 'is_deleted' => 0,
40 | ]
41 | ]);
42 | }
43 |
44 | public function testTagInjector()
45 | {
46 | new ActiveRecordFixture([
47 | 'modelClass' => Tag::class,
48 | 'fixtureData' => [
49 | 'tag1' => [
50 | 'id' => '1',
51 | 'name' => 'John',
52 | ],
53 | 'tag2' => [
54 | 'id' => '2',
55 | 'name' => 'Jane',
56 | ],
57 | ]
58 | ]);
59 |
60 | $block = new StubTagBlock();
61 | $injector = new TagInjector(['context' => $block]);
62 | $injector->setup();
63 |
64 | $vars = $block->getConfigVarsExport();
65 |
66 | $this->assertSame(['items' => [
67 | ['label' => 'John', 'value' => 1],
68 | ['label' => 'Jane', 'value' => 2],
69 | ]], $vars[0]['options']);
70 | }
71 |
72 | public function testEvalTagInjector()
73 | {
74 | new ActiveRecordFixture([
75 | 'modelClass' => Tag::class,
76 | 'fixtureData' => [
77 | 'tag1' => [
78 | 'name' => 'John',
79 | 'id' => '1',
80 | ],
81 | 'tag2' => [
82 |
83 | 'name' => 'Jane',
84 | 'id' => '2',
85 | ],
86 | ]
87 | ]);
88 |
89 | $block = new StubTagBlock();
90 | $block->setVarValues(['tags' => [['value' => 2]]]);
91 | $injector = new TagInjector(['context' => $block, 'varName' => 'tags']);
92 | $injector->setup();
93 | $this->assertArrayHasKey('Jane', $injector->getAssignedTags());
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/tests/src/menu/InjectItemTest.php:
--------------------------------------------------------------------------------
1 | expectException('luya\cms\Exception');
14 | $item = new InjectItem(['alias' => 'foo bar', 'childOf' => 0, 'title' => 'Hello Word']);
15 | $item->toArray();
16 | }
17 |
18 | public function testToArray()
19 | {
20 | $item = new InjectItem(['alias' => 'foo bar', 'childOf' => 1, 'title' => 'Hello Word']);
21 | $a = $item->toArray();
22 |
23 | $this->assertSame('homepage/foo-bar', $a['alias']);
24 | $this->assertSame('homepage/foo-bar', $item->alias);
25 | }
26 |
27 | public function testChainMethodToArray()
28 | {
29 | $array = (new InjectItem())->setAlias('bar-foo')->setItem(Yii::$app->menu->home)->setTitle('World Hello')->toArray();
30 |
31 | $this->assertSame('homepage/bar-foo', $array['alias']);
32 | }
33 |
34 | public function testSetAliasFromTitle()
35 | {
36 | $object = (new InjectItem())->setTitle('Hello ! World!')->setChildOf(1);
37 |
38 | $this->assertSame('homepage/hello-world', $object->alias);
39 |
40 | $alis = (new InjectItem())->setTitle('Foo Bar')->setAlias('luya-alias')->setChildOf(1);
41 |
42 | $this->assertSame('homepage/luya-alias', $alis->alias);
43 |
44 | $notoverride = (new InjectItem())->setAlias('luya-io')->setTitle('Hello')->setChildOf(1);
45 |
46 | $this->assertSame('homepage/luya-io', $notoverride->alias);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/src/models/BlockGroupTest.php:
--------------------------------------------------------------------------------
1 | [
13 | 'id' => 1,
14 | 'group_id' => 1,
15 | 'class' => 'path\to\Block',
16 | 'is_disabled' => 0,
17 | ]
18 | ];
19 |
20 | public $modelClass = 'luya\cms\models\Block';
21 | public $apiClass = 'luya\cms\admin\apis\BlockController';
22 | public $controllerClass = 'luya\cms\admin\controllers\BlockController';
23 |
24 | /*
25 | public function testFindOne()
26 | {
27 | $fixture = $this->modelFixture;
28 |
29 | $relationFixture = new ActiveRecordFixture([
30 | 'modelClass' => 'luya\cms\models\NavItemPageBlockItem',
31 | 'fixtureData' => [
32 | 'model1' => [
33 | 'id' => '1',
34 | 'block_id' => '1',
35 | 'placeholder_var' => 'content',
36 | 'nav_item_page_id' => 0,
37 | 'prev_id' => '',
38 | 'json_config_values' => '{}',
39 | 'json_config_cfg_values' => '{}',
40 | 'is_dirty' => 0,
41 | 'create_user_id' => 1,
42 | 'update_user_id' => 1,
43 | 'timestamp_create' => time(),
44 | 'timestamp_update' => time(),
45 | ]
46 | ]
47 | ]);
48 |
49 | $pageFixture = new ActiveRecordFixture([
50 | 'modelClass' => 'luya\cms\models\NavItemPage',
51 | ]);
52 |
53 | $pageFixture = new ActiveRecordFixture([
54 | 'modelClass' => 'luya\cms\models\Log',
55 | ]);
56 |
57 | // get existing
58 | $block = $fixture->getModel('model1');
59 | $this->assertSame(1, $block->id);
60 | $this->assertEquals(1, $block->usageCount);
61 | $this->assertSame(1, $block->delete());
62 |
63 |
64 |
65 | // add new model
66 | $model = $fixture->getNewModel();
67 | $model->attributes = ['group_id' => 2, 'class' => 'FooBar', 'is_disabled' => 0];
68 | $this->assertTrue($model->save());
69 | //$this->assertSame(0, $model->fileExists);
70 |
71 | }
72 | */
73 |
74 | public function testControllerMethods()
75 | {
76 | $this->assertNull($this->api->actionToFav());
77 | $this->assertNull($this->api->actionRemoveFav());
78 | $this->assertNull($this->api->actionToggleGroup());
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/tests/src/models/NavContainerTest.php:
--------------------------------------------------------------------------------
1 | app, function (PageScope $scope) {
18 | $this->createAdminGroupFixture(1);
19 | $this->createAdminUserFixture();
20 |
21 | $this->createCmsWebsiteFixture([
22 | [
23 | 'id' => 2,
24 | 'name' => 'test',
25 | 'host' => 'test',
26 | 'aliases' => '',
27 | 'is_default' => 0,
28 | 'is_active' => 1,
29 | 'is_deleted' => 0,
30 | ]
31 | ]);
32 | $this->createCmsNavContainerFixture([
33 | [
34 | 'id' => 2,
35 | 'name' => 'test container',
36 | 'alias' => 'test container',
37 | 'website_id' => 2,
38 | 'is_deleted' => 0,
39 | ]
40 | ]);
41 | Yii::$app->request->setHostInfo("http://test");
42 |
43 | $this->assertFalse(NavContainer::find()->andWhere(['id' => 1])->exists());
44 |
45 | $navContainer = NavContainer::findOne(2);
46 |
47 | $this->assertEquals(2, $navContainer->website_id);
48 | $this->assertSame('test container', $navContainer->name);
49 |
50 | $website = $navContainer->website;
51 |
52 | $this->assertEquals(2, $website->id);
53 | $this->assertSame('test', $website->name);
54 | });
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/src/models/NavItemModuleTest.php:
--------------------------------------------------------------------------------
1 | NavItemModule::class,
15 | ]);
16 |
17 | $model = $fixture->newModel;
18 | $model->action_params = ['foo' => 'bar'];
19 | $model->validate();
20 |
21 | // test encoding
22 | $this->assertSame('{"foo":"bar"}', $model->action_params);
23 | $this->assertSame(['foo' => 'bar'], $model->getDecodedActionParams());
24 | $model->action_params = $model->getDecodedActionParams();
25 | $this->assertSame(['foo' => 'bar'], $model->getDecodedActionParams()); // if already is array
26 |
27 |
28 | // empty model test
29 | $emptyModel = $fixture->newModel;
30 |
31 | $this->assertSame([], $emptyModel->getDecodedActionParams());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/src/models/NavItemPageBlockItemTest.php:
--------------------------------------------------------------------------------
1 | NavItemPageBlockItem::class,
18 | ]);
19 |
20 | new NgRestModelFixture([
21 | 'modelClass' => NavItemPage::class,
22 | ]);
23 |
24 | new NgRestModelFixture([
25 | 'modelClass' => Block::class,
26 | 'fixtureData' => [
27 | 1 => [
28 | 'id' => 1,
29 | ]
30 | ]
31 | ]);
32 |
33 | new NgRestModelFixture([
34 | 'modelClass' => Log::class,
35 | ]);
36 |
37 | $model = $fixtures->newModel;
38 | $model->block_id = 1;
39 | $model->placeholder_var = 'container';
40 |
41 | $this->assertTrue($model->save());
42 |
43 | $model->prev_id = 1;
44 | $this->assertFalse($model->update());
45 |
46 | $this->assertArrayHasKey('prev_id', $model->getErrors());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/src/models/NavItemTest.php:
--------------------------------------------------------------------------------
1 | createCmsNavItemFixture();
18 | $model = new NavItem();
19 |
20 | $model->alias = "äÄöÖüÜß<>";
21 | $model->slugifyAlias();
22 | $this->assertSame("ääööüüß", $model->alias);
23 |
24 | $model->alias = "這是 LUYA";
25 | $model->slugifyAlias();
26 | $this->assertSame("這是-luya", $model->alias);
27 |
28 | $model->alias = "a1Zあ新~!@#$^&*()_[];',:?";
29 | $model->slugifyAlias();
30 | $this->assertSame("a1zあ新~!@#$^&*()[];',:?", $model->alias);
31 | }
32 |
33 | public function testGetDefaultLanguageRelationGetter()
34 | {
35 | $this->createCmsNavFixture([
36 | 1 => [
37 | 'id' => 1,
38 | ]
39 | ]);
40 |
41 | $this->createCmsNavItemFixture([
42 | 1 => [
43 | 'id' => 1,
44 | 'nav_id' => 1,
45 | 'lang_id' => 1,
46 | ]
47 | ]);
48 |
49 | $this->createAdminLangFixture([
50 | 1 => [
51 | 'id' => 1,
52 | 'name' => 'English',
53 | 'short_code' => 'en',
54 | 'is_default' => 1,
55 | 'is_deleted' => 0,
56 | ]
57 | ]);
58 |
59 | $nav = Nav::findOne(1);
60 |
61 | $this->assertSame(1, $nav->id);
62 | $this->assertSame(1, $nav->defaultLanguageItem->id);
63 | $this->assertSame(1, $nav->activeLanguageItem->id);
64 | }
65 |
66 | public function testEmptyValidatorForNavItemTypeId()
67 | {
68 | $fixture = new NgRestModelFixture([
69 | 'modelClass' => NavItem::class,
70 | ]);
71 |
72 | $model = $fixture->newModel;
73 |
74 | $model->isNewRecord = false;
75 | $model->nav_item_type_id = 0;
76 | $this->assertFalse($model->validate(['nav_item_type_id']));
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tests/src/models/NavTest.php:
--------------------------------------------------------------------------------
1 | activeLanguageItem;
16 |
17 | $this->assertSame('Homepage', $item->title);
18 | $this->assertSame('homepage', $item->alias);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/src/models/ThemeTest.php:
--------------------------------------------------------------------------------
1 | Theme::class
15 | ]);
16 |
17 | $theme = new Theme();
18 | $values = [
19 | 'name' => 'lorem',
20 | 'parentTheme' => 'ipsum',
21 | 'author' => 'me',
22 | ];
23 | $theme->json_config = json_encode($values, JSON_FORCE_OBJECT);
24 |
25 | $theme->afterFind();
26 |
27 | $this->assertSame('lorem', $theme->getName());
28 | $this->assertSame('ipsum', $theme->getParentTheme());
29 | $this->assertSame('me', $theme->getAuthor());
30 |
31 | $this->assertSame($values, $theme->getJsonConfig());
32 | $this->assertNull($theme->getJsonConfig('foo'));
33 | }
34 |
35 | public function testInvalidJsonConfig()
36 | {
37 | $fixture = new NgRestModelFixture([
38 | 'modelClass' => Theme::class
39 | ]);
40 |
41 | $theme = new Theme();
42 | $theme->json_config = '}[';
43 |
44 | $theme->afterFind();
45 |
46 | $this->assertEmpty($theme->getJsonConfig());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/src/tags/MenuTagTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('Homepage', $tag->parse(1, null));
15 | $this->assertEquals('foobar', $tag->parse(1, 'foobar'));
16 |
17 | $this->assertEquals('Page 1', $tag->parse(2, null));
18 | $this->assertEquals('foobar', $tag->parse(2, 'foobar'));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/src/tags/PageTagTest.php:
--------------------------------------------------------------------------------
1 | assertSame('', $tag->parse('1', null));
14 | }
15 |
16 | public function testContentPlaceholderResponse()
17 | {
18 | $tag = new PageTag();
19 | $this->assertSame('', $tag->parse(1, 'content'));
20 | }
21 |
22 |
23 | public function testRedirectWrongItemTypeResponse()
24 | {
25 | $tag = new PageTag();
26 | $this->assertNull($tag->parse(14, 'content'));
27 | }
28 |
29 | public function testRedirectWrongItemTypeResponseWithoutPlaceholder()
30 | {
31 | $tag = new PageTag();
32 | $this->assertNull($tag->parse(14, null));
33 | }
34 |
35 | public function testContentNotFoundException()
36 | {
37 | $tag = new PageTag();
38 | $this->assertNull($tag->parse(9999, 'content'));
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/src/widgets/LangSwitcherTest.php:
--------------------------------------------------------------------------------
1 | assertSame(str_replace(["\r\n", "\r"], "\n", ''), str_replace(["\r\n", "\r"], "\n", $out));
18 | }
19 |
20 | public function testCallable()
21 | {
22 | $out = LangSwitcher::widget(['linkLabel' => function ($lang) {
23 | return strtoupper($lang['short_code']);
24 | }]);
25 |
26 | $this->assertSame(str_replace(["\r\n", "\r"], "\n", ''), str_replace(["\r\n", "\r"], "\n", $out));
30 | }
31 |
32 | public function testSortCallable()
33 | {
34 | $out = LangSwitcher::widget(['itemsCallback' => function ($items) {
35 | ksort($items);
36 |
37 | return $items;
38 | }]);
39 |
40 |
41 | $this->assertSame(str_replace(["\r\n", "\r"], "\n", ''), str_replace(["\r\n", "\r"], "\n", $out));
45 | }
46 |
47 | public function testOutputWithoutUl()
48 | {
49 | $out = LangSwitcher::widget(['noListTag' => true]);
50 |
51 | $this->assertSame(str_replace(["\r\n", "\r"], "\n", 'English
52 | Deutsch'), str_replace(["\r\n", "\r"], "\n", $out));
53 | }
54 | }
55 |
--------------------------------------------------------------------------------