Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple website support #274

Merged
merged 71 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
f0bf3c3
Multiple website support
boehsermoe Jul 15, 2020
6f1eadb
Active theme per website
boehsermoe Jul 15, 2020
bc0efbd
Website component
boehsermoe Jul 16, 2020
33ce18c
Redirect to host
boehsermoe Jul 17, 2020
50ee463
website lang mapping and query behavior
boehsermoe Jul 18, 2020
ba37f02
translations
boehsermoe Jul 18, 2020
7b64ac0
bootstrap host info mapping
boehsermoe Jul 18, 2020
23bbb7d
hide website dropdown when only one website
boehsermoe Jul 18, 2020
9b2ae19
db schema 4.0
boehsermoe Jul 18, 2020
26d2c53
db schema 4.0
boehsermoe Jul 18, 2020
9bcec0c
syntax fix
boehsermoe Jul 18, 2020
e4e4301
Unit tests
boehsermoe Jul 18, 2020
660b6f9
Unit tests
boehsermoe Jul 18, 2020
8c93a88
website fixture
boehsermoe Jul 18, 2020
dea0ced
website fixture
boehsermoe Jul 19, 2020
c33b984
website fixture
boehsermoe Jul 19, 2020
74baa8c
Unit tests
boehsermoe Jul 19, 2020
e8d5337
Unit tests
boehsermoe Jul 19, 2020
3c460c9
Unit tests
boehsermoe Jul 19, 2020
102174e
Unit tests
boehsermoe Jul 19, 2020
0246c95
Unit tests
boehsermoe Jul 19, 2020
3189a56
Unit tests
boehsermoe Jul 23, 2020
d3d9c7c
multi website test scopes
boehsermoe Jul 23, 2020
4f0af06
Merge branch 'master' into multi-site
boehsermoe Jul 23, 2020
f769a1f
unit testing
boehsermoe Jul 23, 2020
84a1709
Merge branch 'master' of https://github.com/luyadev/luya-module-cms i…
boehsermoe Jul 23, 2020
dcd91ab
Merge branch 'multi-site' of github.com:boehsermoe/luya-module-cms in…
boehsermoe Jul 23, 2020
5a12c02
unit testing
boehsermoe Jul 23, 2020
edfbeee
unit testing
boehsermoe Jul 23, 2020
93960ea
unit testing
boehsermoe Jul 23, 2020
6cc4398
unit testing
boehsermoe Jul 23, 2020
6f4af8c
Merge branch 'master' into multi-site
boehsermoe Jul 27, 2020
ea20a5f
fix parent nav id
boehsermoe Jul 28, 2020
a843fa2
Merge branch 'multi-site' of github.com:boehsermoe/luya-module-cms in…
boehsermoe Jul 28, 2020
2562892
Website find
boehsermoe Aug 13, 2020
af0dc02
Merge branch 'master' of github.com:boehsermoe/luya-module-cms into m…
boehsermoe Aug 24, 2020
ae527c6
remove messages
boehsermoe Aug 24, 2020
b3fe14b
Merge branch 'master' into multi-site
boehsermoe Aug 24, 2020
7acdc8b
Unit tests fix
boehsermoe Aug 24, 2020
5774409
Merge branch 'master' of https://github.com/luyadev/luya-module-cms i…
boehsermoe Sep 23, 2020
9548cf6
website docs and messages
boehsermoe Sep 23, 2020
e3c7926
multi website tests
boehsermoe Sep 25, 2020
b4b0fc2
multi website tests
boehsermoe Sep 25, 2020
57d90b8
multi website tests
boehsermoe Sep 25, 2020
7197250
added theme id to validation rules
nadar Oct 24, 2020
fcd1ce5
Merge branch 'master' of https://github.com/luyadev/luya-module-cms i…
boehsermoe Apr 22, 2021
3f6abf7
website scope on create new page
boehsermoe Apr 23, 2021
d54781d
Merge branch 'master' of https://github.com/luyadev/luya-module-cms i…
boehsermoe May 13, 2021
3071437
gitignore
boehsermoe May 13, 2021
fa62361
unit tests
boehsermoe May 14, 2021
0ccfedc
schema and query fixes
boehsermoe May 18, 2021
3ae18b3
user events instead of function override
boehsermoe May 18, 2021
ad4f6ae
fix website query
boehsermoe May 18, 2021
8ba6ad3
check current theme id
boehsermoe May 18, 2021
484c6d0
MenuController Unit Tests
boehsermoe May 23, 2021
4a7f780
NavController toggleHome Test
boehsermoe May 24, 2021
f3afe44
NavController toggleHome Test
boehsermoe May 24, 2021
9599f07
NavController Unit Tests
boehsermoe May 24, 2021
a1206fb
NavController Unit Tests
boehsermoe May 24, 2021
429c96f
NavController Unit Tests
boehsermoe May 24, 2021
2545fc5
reload ServiceMenuData after website save
boehsermoe May 26, 2021
6ce0b16
Add website dropdown on cocontainer form
boehsermoe May 26, 2021
832228e
Website Prefix for container
boehsermoe May 26, 2021
4f3220d
query fix
boehsermoe May 26, 2021
37271f3
website prefix
boehsermoe May 26, 2021
02e414e
query fix for website defautl container
boehsermoe May 27, 2021
cd33056
Container sort
boehsermoe May 27, 2021
29139a0
Container sort
boehsermoe May 27, 2021
0ea9ec5
container with website filter
boehsermoe May 28, 2021
a88f931
ensure init value
nadar Jun 1, 2021
9364065
clearable option
nadar Jun 1, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- name: Setup database
run: |
sudo /etc/init.d/mysql start
mysql -h 127.0.0.1 --port 8888 -u root -proot myapp_test < tests/data/sql/3.0.0.sql
mysql -h 127.0.0.1 --port 8888 -u root -proot myapp_test < tests/data/sql/4.0.0.sql

## run unit tests
- name: PHP Unit tests for PHP 7.0, 7.2, 7.3, 7.4, 8.0
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
/luya
node_modules/
composer.lock
.phpunit.result.cache
.phpunit.result.cache
/tests/_output/*
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ In order to read more about upgrading and BC breaks have a look at the [UPGRADE

## 4.0.0

* [#274](https://github.com/luyadev/luya-module-cms/pull/274) Multiple website support
* [#341](https://github.com/luyadev/luya-module-cms/pull/341) All deprecated methods has been removed `Url::toMenuItem`, `Block::objectId`, `NavItemPage::getBlock`.
+ [#320](https://github.com/luyadev/luya-module-cms/pull/320) Replace cms menu item `publish_from` and `publish_till` with sheduler.
+ [#329](https://github.com/luyadev/luya-module-cms/issues/329) Ensure its not possible to drag a placeholder block into itself (this can create circular references)
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"issues":"https://github.com/luyadev/luya-module-cms/issues"
},
"require-dev":{
"luyadev/luya-testsuite":"^2.0",
"luyadev/luya-testsuite":"^2.0 || dev-master",
"twbs/bootstrap":"^4.3.0",
"unglue/client":"^1.3"
},
Expand Down Expand Up @@ -57,6 +57,10 @@
{
"type":"composer",
"url":"https://asset-packagist.org"
},
{
"type":"git",
"url":"https://github.com/boehsermoe/luya-testsuite.git"
}
]
}
8 changes: 8 additions & 0 deletions log/testdox.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
31 changes: 20 additions & 11 deletions src/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace luya\cms;

use luya\cms\models\Website;
use luya\helpers\StringHelper;
use Yii;
use yii\base\Component;
use yii\web\NotFoundHttpException;
Expand Down Expand Up @@ -85,6 +87,7 @@
* @property array $currentUrlRule Get the url rules for the current menu item.
* @property \luya\cms\menu\Item $current Get the current active menu item.
* @property \luya\cms\menu\Item $home Get the home menu item.
* @property \luya\web\Composition $composition Get the composition.
*
* @author Basil Suter <basil@nadar.io>
* @since 1.0.0
Expand Down Expand Up @@ -319,7 +322,7 @@ public function setLanguageContainer($langShortCode, array $data)
public function getLanguageContainer($langShortCode)
{
if (!array_key_exists($langShortCode, $this->_languageContainer)) {
$this->_languageContainer[$langShortCode] = $this->loadLanguageContainer($langShortCode);
$this->_languageContainer[$langShortCode] = $this->loadWebsiteLanguageContainer($langShortCode);
$this->trigger(self::EVENT_AFTER_LOAD);
}

Expand Down Expand Up @@ -350,7 +353,7 @@ public function getLanguages()

return $this->_languages;
}

/**
* Get an array containing all redirect items from the database table cms_nav_item_redirect.
*
Expand Down Expand Up @@ -603,16 +606,17 @@ public function getModulesMap()
* load all navigation items for a specific language id.
*
* @param integer $langId
* @param integer $websiteId
* @return array
*/
private function getNavData($langId)
private function getNavData($langId, $websiteId)
{
return (new DbQuery())
->from(['cms_nav_item item'])
->select(['item.id', 'item.nav_id', 'item.title', 'item.description', 'item.keywords', 'item.image_id', 'item.is_url_strict_parsing_disabled', 'item.alias', 'item.title_tag', 'item.timestamp_create', 'item.timestamp_update', 'item.create_user_id', 'item.update_user_id', 'nav.is_home', 'nav.parent_nav_id', 'nav.sort_index', 'nav.is_hidden', 'item.nav_item_type', 'item.nav_item_type_id', 'nav_container.alias AS container'])
->leftJoin('cms_nav nav', 'nav.id=item.nav_id')
->leftJoin('cms_nav_container nav_container', 'nav_container.id=nav.nav_container_id')
->where(['nav.is_deleted' => false, 'item.lang_id' => $langId, 'nav.is_offline' => false, 'nav.is_draft' => false])
->where(['nav.is_deleted' => false, 'nav_container.website_id' => $websiteId, 'item.lang_id' => $langId, 'nav.is_offline' => false, 'nav.is_draft' => false])
->orderBy(['container' => 'ASC', 'parent_nav_id' => 'ASC', 'nav.sort_index' => 'ASC'])
->indexBy('id')
->all();
Expand Down Expand Up @@ -688,26 +692,30 @@ private function aliasMatch(array $urlParts, $strictParsing = false)
}

/**
* Helper method to load all contaienr data for a specific langauge.
* Helper method to load all container data for a specific website and language.
*
* @param string $langShortCode e.g. de
* @return array
* @throws NotFoundHttpException
*
* @since 4.0.0
*/
private function loadLanguageContainer($langShortCode)
private function loadWebsiteLanguageContainer($langShortCode)
boehsermoe marked this conversation as resolved.
Show resolved Hide resolved
boehsermoe marked this conversation as resolved.
Show resolved Hide resolved
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function loadWebsiteLanguageContainer has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method loadWebsiteLanguageContainer has 48 lines of code (exceeds 25 allowed). Consider refactoring.

{
$cacheKey = $this->_cachePrefix.$langShortCode;
$hostName = $this->request->hostName;
$cacheKey = $this->_cachePrefix.$hostName.$langShortCode;

$languageContainer = $this->getHasCache($cacheKey);

if ($languageContainer === false) {
$lang = $this->getLanguage($langShortCode);

if (!$lang) {
throw new NotFoundHttpException(sprintf("The requested language '%s' does not exist in language table", $langShortCode));
}

$data = $this->getNavData($lang['id']);

$website = Yii::$app->website->findOneByHostName($hostName);

$data = $this->getNavData($lang['id'], $website['id']);

$index = $this->buildIndexForContainer($data);

Expand All @@ -724,6 +732,7 @@ private function loadLanguageContainer($langShortCode)
$languageContainer[$key] = [
'id' => $item['id'],
'nav_id' => $item['nav_id'],
'website_id' => $website['id'],
'lang' => $lang['short_code'],
'link' => $this->buildItemLink($alias, $langShortCode),
'title' => $this->encodeValue($item['title']),
Expand Down Expand Up @@ -751,7 +760,7 @@ private function loadLanguageContainer($langShortCode)

$this->setHasCache($cacheKey, $languageContainer);
}

return $languageContainer;
}

Expand Down
120 changes: 120 additions & 0 deletions src/Website.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace luya\cms;

use Yii;
use luya\helpers\StringHelper;
use luya\traits\CacheableTrait;
use luya\web\Composition;
use yii\base\Component;
use \luya\cms\models\Website as WebsiteModel;
use yii\web\NotFoundHttpException;

/**
* Class Website
*
* @property array $current = ['name']
*
* @author Bennet Klarhoelter <boehsermoe@me.com>
* @since 4.0.0
*/
class Website extends Component
{
use CacheableTrait;

private $_current = null;

/**
* @return array|bool
* @throws NotFoundHttpException
*/
public function getCurrent()
{
if ($this->_current === null) {
$this->_current = $this->findOneByHostName(Yii::$app->request->hostName);
}

return $this->_current;
}

/**
* Get website information by hostname.
*
* @param string $hostName
* @return array|boolean If the website exists an array with informations as returned, otherwise false.
*/
public function findOneByHostName($hostName)
boehsermoe marked this conversation as resolved.
Show resolved Hide resolved
nadar marked this conversation as resolved.
Show resolved Hide resolved
nadar marked this conversation as resolved.
Show resolved Hide resolved
{
$cache = $this->getHasCache($hostName);
if ($cache) {
return $cache;
}
$defaultWebsite = false;

$websites = $this->loadAllWebsiteData();
if (isset($websites[$hostName])) {
$this->setHasCache($hostName, $websites[$hostName]);
return $websites[$hostName];
}

foreach ($websites as $website) {
foreach ($website['aliases'] as $alias) {
if (StringHelper::matchWildcard($alias, $hostName)) {
$this->setHasCache($hostName, $website);
return $website;
}
}

if ($website['is_default']) {
$defaultWebsite = $website;
}
}

if (!$defaultWebsite) {
// should never happen because there is always a default website
throw new NotFoundHttpException(sprintf("The requested host '%s' does not exist in website table", $hostName));
}

$this->setHasCache($hostName, $defaultWebsite);
return $defaultWebsite;
}

private $_allWebsiteData = null;

/**
* @return array
*/
private function loadAllWebsiteData()
{
if ($this->_allWebsiteData === null) {
$this->_allWebsiteData = WebsiteModel::find()->andWhere(['is_active' => true])->cache()->indexBy('host')->asArray()->all();
foreach ($this->_allWebsiteData as &$website) {
$aliases = array_map('trim', explode(',', $website['aliases']));
$website['aliases'] = array_filter($aliases);
}
}
return $this->_allWebsiteData;
}

/**
* Create a host mapping with default languages for {\luya\web\Composition::$hostInfoMapping}
* @return array
*/
public function createHostInfoMapping()
boehsermoe marked this conversation as resolved.
Show resolved Hide resolved
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function createHostInfoMapping has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring.

{
$hostInfoMapping = [];

foreach ($this->loadAllWebsiteData() as $website) {
if ($website['default_lang']) {
$hostInfoMapping[$website['host']] = [Composition::VAR_LANG_SHORT_CODE => $website['default_lang']];
foreach ($website['aliases'] as $alias) {
if (!isset($hostInfoMapping[$alias])) {
$hostInfoMapping[$alias] = [Composition::VAR_LANG_SHORT_CODE => $website['default_lang']];
}
}
}
}

return $hostInfoMapping;
}
}
2 changes: 2 additions & 0 deletions src/admin/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ final class Module extends \luya\admin\base\Module implements CoreModuleInterfac
'api-cms-redirect' => 'luya\cms\admin\apis\RedirectController',
'api-cms-theme' => 'luya\cms\admin\apis\ThemeController',
'api-cms-log' => 'luya\cms\admin\apis\LogController',
'api-cms-website' => 'luya\cms\admin\apis\WebsiteController',
];

public $apiRules = [
Expand Down Expand Up @@ -265,6 +266,7 @@ public function getMenu()
->node('menu_node_cmssettings', 'settings')

->group('menu_group_page_display')
->itemApi('menu_group_item_env_websites', 'cmsadmin/website/index', 'http', 'api-cms-website')
->itemApi('menu_group_item_env_layouts', 'cmsadmin/layout/index', 'view_quilt', 'api-cms-layout')
->itemApi('menu_group_item_env_themes', 'cmsadmin/theme/index', 'color_lens', 'api-cms-theme')
->itemApi('menu_group_item_env_container', 'cmsadmin/navcontainer/index', 'label_outline', 'api-cms-navcontainer')
Expand Down
1 change: 1 addition & 0 deletions src/admin/apis/MenuController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function actionDataMenu()
'items' => ArrayHelper::typeCast(MenuHelper::getItems()),
'drafts' => ArrayHelper::typeCast(MenuHelper::getDrafts()),
'containers' => ArrayHelper::typeCast(MenuHelper::getContainers()),
'websites' => ArrayHelper::typeCast(MenuHelper::getWebsites()),
'hiddenCats' => ArrayHelper::typeCast(Yii::$app->adminuser->identity->setting->get("togglecat", [])),
];
}
Expand Down
16 changes: 13 additions & 3 deletions src/admin/apis/NavController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
namespace luya\cms\admin\apis;

use luya\admin\models\TagRelation;
use luya\cms\models\NavContainer;
use luya\cms\models\NavItemRedirect;
use Yii;
use luya\cms\models\Property;
use luya\cms\models\Nav;
use luya\cms\models\NavItem;
use yii\db\Query;
use yii\helpers\Json;
use yii\base\InvalidCallException;
use luya\admin\models\UserOnline;
Expand Down Expand Up @@ -229,10 +231,18 @@ public function actionToggleHidden($navId, $hiddenStatus)

public function actionToggleHome($navId, $homeState)
{
$item = Nav::find()->where(['id' => $navId])->one();
/** @var Nav $item */
$item = Nav::find()->with('navContainer')->where(['id' => $navId])->one();
$this->menuFlush();
if ($homeState == 1) {
Nav::updateAll(['is_home' => false]);
$navIds = (new Query())
->from(Nav::tableName())
->leftJoin(NavContainer::tableName(), 'cms_nav_container.id = nav_container_id')
->where(['website_id' => $item->navContainer->website_id])
->select('cms_nav.id')
->column();
Nav::updateAll(['is_home' => false], ['id' => $navIds]);

$item->setAttributes([
'is_home' => true,
]);
Expand Down Expand Up @@ -361,7 +371,7 @@ public function actionCreatePage()
$this->menuFlush();
$model = new Nav();
$fromDraft = $this->postArg('use_draft');
$parentNavId = $this->postArg('parent_nav_id');
$parentNavId = $this->postArg('parent_nav_id') ?: null;
$navContainerId = $this->postArg('nav_container_id');

if (!empty($parentNavId)) {
Expand Down
16 changes: 16 additions & 0 deletions src/admin/apis/WebsiteController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace luya\cms\admin\apis;

/**
* Theme for LUYA CMS.
*
* This module / component allow user to manage websites.
*
* @author Bennet Klarhoelter <boehsermoe@me.com>
* @since 4.0.0
*/
class WebsiteController extends \luya\admin\ngrest\base\Api
{
public $modelClass = 'luya\cms\models\Website';
}
16 changes: 16 additions & 0 deletions src/admin/controllers/WebsiteController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace luya\cms\admin\controllers;

use luya\admin\ngrest\base\Controller;

/**
* Website Container Controller.
*
* @author Bennet Klarhölter <boehsermoe@me.com>
* @since 4.0.0
*/
class WebsiteController extends Controller
{
public $modelClass = 'luya\cms\models\Website';
}
Loading