Skip to content

Commit

Permalink
サブサイトを利用している場合、内部リンクが正常に取得できない問題を改善
Browse files Browse the repository at this point in the history
  • Loading branch information
ryuring committed Feb 24, 2024
1 parent 489c6e4 commit f171ceb
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 83 deletions.
125 changes: 58 additions & 67 deletions plugins/baser-core/src/View/Helper/BcBaserHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ public function link($title, $url = null, $htmlAttributes = [], $confirmMessage
* - `prefix` : URLにプレフィックスをつけるかどうか(初期値 : false)
* - `forceTitle` : 許可されていないURLの際にタイトルを強制的に出力するかどうか(初期値 : false)
* - `ssl` : SSL用のURLをして出力するかどうか(初期値 : false)
* - `enabled` : リンクが有効かどうか(初期値 : true)
* ※ その他のパラメータについては、HtmlHelper::image() を参照。
* @param bool $confirmMessage 確認メッセージ(初期値 : false)
* リンクをクリックした際に確認メッセージが表示され、はいをクリックした場合のみ遷移する
Expand All @@ -433,19 +434,14 @@ public function link($title, $url = null, $htmlAttributes = [], $confirmMessage
*/
public function getLink($title, $url = null, $options = [], $confirmMessage = false)
{
if ($confirmMessage) {
$options['confirm'] = $confirmMessage;
}

if (!is_array($options)) {
$options = [$options];
}

if ($confirmMessage) $options['confirm'] = $confirmMessage;
if (!is_array($options)) $options = [$options];
$options = array_merge([
'escape' => true,
'prefix' => false,
'forceTitle' => false,
'ssl' => $this->isSSL()
'ssl' => $this->isSSL(),
'enabled' => true
], $options);

// EVENT Html.beforeGetLink
Expand All @@ -459,82 +455,52 @@ public function getLink($title, $url = null, $options = [], $confirmMessage = fa
$options = ($event->getResult() === null || $event->getResult() === true)? $event->getData('options') : $event->getResult();
}

if ($options['prefix']) {
if (!empty($this->_View->getRequest()->getParam('prefix')) && is_array($url)) {
$url[$this->_View->getRequest()->getParam('prefix')] = true;
}
}
$request = $this->getView()->getRequest();
$prefix = $options['prefix'];
$forceTitle = $options['forceTitle'];
$ssl = $options['ssl'];
$enabled = $options['enabled'];
unset($options['prefix'], $options['forceTitle'], $options['ssl'], $options['enabled']);

unset($options['prefix']);
unset($options['forceTitle']);
unset($options['ssl']);

$_url = $this->getUrl($url);
$_url = preg_replace('/^' . preg_quote($this->_View->getRequest()->getAttribute('base'), '/') . '\//', '/', $_url);
$enabled = true;

if ($options == false) {
$enabled = false;
if ($prefix && is_array($url) && !empty($request->getParam('prefix'))) {
$url[$request->getParam('prefix')] = true;
}

// 認証チェック
$user = Bcutil::loginUser();
if (BcUtil::isInstalled()) {
$userGroups = [];
if($user && $user->user_groups) $userGroups = array_column($user->user_groups, 'id');
if (!$this->PermissionsService->check($_url, $userGroups)) {
$enabled = false;
}
}
$srcUrl = $this->getUrl($url, false, ['escape' => false]);
$srcUrl = preg_replace('/^' . preg_quote($request->getAttribute('base'), '/') . '\//', '/', $srcUrl);

if (!$enabled) {
if (!$enabled || !$this->isLinkEnabled($srcUrl)) {
if ($forceTitle) {
return "<span>$title</span>";
} else {
return '';
}
}

// 現在SSLのURLの場合、プロトコル指定(フルパス)で取得以外
// //(スラッシュスラッシュ)から始まるSSL、非SSL共有URLも除外する
// 現在SSLの場合、特定の条件でフルパスとする
// - //(スラッシュスラッシュ)から始まるURL
// - http / https 以外のプロトコル
// - ハッシュタグから始まるURL
$full = false;
if (BcUtil::isInstalled()
&& ($this->isSSL() || $ssl)
&& !(preg_match('/^(javascript|https?|ftp|tel):/', $_url))
&& !(strpos($_url, '//') === 0)
&& !preg_match('/^#/', $_url)) {

$_url = preg_replace("/^\//", "", $_url);
if (preg_match('{^' . BcUtil::getPrefix(true) . '\/}', $_url)) {
$admin = true;
} else {
$admin = false;
}
if (Configure::read('App.baseUrl')) {
$_url = 'index.php/' . $_url;
}
if(!preg_match('/^(mailto:|tel:)/', $_url)) {
if (!$ssl && !$admin) {
$url = Configure::read('BcEnv.siteUrl') . $_url;
} else {
$sslUrl = Configure::read('BcEnv.sslUrl');
if ($sslUrl) {
$url = $sslUrl . $_url;
} else {
$url = '/' . $_url;
}
}
}
&& !(preg_match('/^(javascript|https?|ftp|tel|mailto):/', $srcUrl))
&& !(strpos($srcUrl, '//') === 0)
&& !preg_match('/^#/', $srcUrl)) {
$full = true;
}

if (!$options) {
$options = [];
if (preg_match('{^' . BcUtil::getPrefix(true) . '\/}', $srcUrl)) {
$url = $this->getUrl($srcUrl, $full, ['escape' => false]);
} else {
$site = $this->getCurrentSite();
$url = $this->BcContents->getUrl($srcUrl, $full, $site->use_subdomain, (bool) $request->getAttribute('base'));
}

if (!is_array($url)) {
$url = preg_replace('/^' . preg_quote($this->_View->getRequest()->getAttribute('base'), '/') . '\//', '/', $url);
if (!$full) {
$url = preg_replace('/^' . preg_quote($request->getAttribute('base'), '/') . '\//', '/', $url);
}

$out = $this->BcHtml->link($title, $url, $options);

// EVENT Html.afterGetLink
Expand All @@ -549,6 +515,28 @@ public function getLink($title, $url = null, $options = [], $confirmMessage = fa
return $out;
}

/**
* リンクが有効化どうか
*
* ログインしているユーザーの権限によって判定する
* @param string $link
* @return true
* @noTodo
* @checked
*/
public function isLinkEnabled(string $link): bool
{
if (!BcUtil::isInstalled()) return true;
$user = Bcutil::loginUser();
if(!$user) return true;
if($user->user_groups) {
$userGroups = array_column($user->user_groups, 'id');
} else {
$userGroups = [];
}
return $this->PermissionsService->check($link, $userGroups);
}

/**
* 管理者グループかどうかチェックする
*
Expand Down Expand Up @@ -808,9 +796,12 @@ public function getContentsName($detail = false, $options = [])
* @unitTest
* @noTodo
*/
public function getUrl($url = null, $full = false)
public function getUrl($url = null, $full = false, $options = [])
{
return $this->Url->build($url, ['fullBase' => $full]);
$options = array_merge([
'fullBase' => $full
], $options);
return $this->Url->build($url, $options);
}

/**
Expand Down
19 changes: 9 additions & 10 deletions plugins/baser-core/src/View/Helper/BcContentsHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@
use BaserCore\Model\Entity\Content;
use BaserCore\Model\Entity\Site;
use BaserCore\Model\Table\SitesTable;
use BaserCore\Service\ContentsService;
use Cake\Datasource\EntityInterface;
use Cake\Utility\Hash;
use Exception;
use Cake\View\Helper;
use Cake\Core\Configure;
use Cake\Routing\Router;
use Cake\ORM\TableRegistry;
use Cake\Utility\Inflector;
use BaserCore\Utility\BcUtil;
use BaserCore\Utility\BcContainerTrait;
use BaserCore\Model\Table\ContentsTable;
Expand All @@ -41,6 +39,7 @@
* @var BcContentsHelper $this
* @property ContentsTable $_Contents
* @property PermissionsService $PermissionsService
* @property ContentsServiceInterface|ContentsService $ContentsService
*/
class BcContentsHelper extends Helper
{
Expand Down Expand Up @@ -361,18 +360,18 @@ public function getParent($id = null, $direct = true)
/**
* サイト連携データかどうか確認する
*
* @param array $data コンテンツデータ
* @param EntityInterface $content コンテンツデータ
* @return bool
* @unitTest
*/
public function isSiteRelated($data)
public function isSiteRelated(EntityInterface $content)
{
if ((@$data['Site']['relate_main_site'] && @$data['Content']['main_site_content_id'] && @$data['Content']['alias_id']) ||
@$data['Site']['relate_main_site'] && @$data['Content']['main_site_content_id'] && @$data['Content']['type'] == 'ContentFolder') {
return true;
} else {
return false;
if(!$content || !$content->site) return false;
if($content->site->relate_main_site && $content->main_site_content_id) {
if($content->alias_id) return true;
if($content->type === 'ContentFolder') return true;
}
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ public function getLinkDataProvider()
['<b>title</b>', 'https://example.com/<b>link</b>', [], '<a href="https://example.com/&lt;b&gt;link&lt;/b&gt;">&lt;b&gt;title&lt;/b&gt;</a>'], // エスケープ
['<b>title</b>', 'https://example.com/<b>link</b>', ['escape' => false], '<a href="https://example.com/<b>link</b>"><b>title</b></a>'], // エスケープ
['<b>title</b>', 'https://example.com/<b>link</b>', ['escapeTitle' => false], '<a href="https://example.com/&lt;b&gt;link&lt;/b&gt;"><b>title</b></a>'], // エスケープ
['固定ページ管理', ['prefix' => 'Admin', 'controller' => 'pages', 'action' => 'index'], [], '<a href="/baser/admin/baser-core/pages/index">固定ページ管理</a>'], // プレフィックス
['固定ページ管理', ['prefix' => 'Admin', 'controller' => 'pages', 'action' => 'index'], [], '<a href="/baser/admin/baser-core/pages/">固定ページ管理</a>'], // プレフィックス
['システム設定', ['Admin' => true, 'controller' => 'site_configs', 'action' => 'index'], ['forceTitle' => true], '<span>システム設定</span>'], // 強制タイトル
['会社案内', '/about', ['ssl' => true], '<a href="https://localhost/about">会社案内</a>'], // SSL
['テーマファイル管理', ['controller' => 'themes', 'action' => 'manage', 'jsa'], ['ssl' => true], '<a href="https://localhost/baser-core/themes/manage/jsa">テーマファイル管理</a>'], // SSL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace BaserCore\Test\TestCase\View\Helper;

use BaserCore\Model\Entity\Content;
use BaserCore\Model\Entity\Site;
use BaserCore\Test\Factory\ContentFactory;
use Cake\Routing\Router;
use BaserCore\View\BcAdminAppView;
Expand Down Expand Up @@ -177,11 +179,11 @@ public function testIsSiteRelated($expect, $data)
public function isSiteRelatedDataProvider()
{
return [
[true, ['Site' => ['relate_main_site' => true], 'Content' => ['main_site_content_id' => 1, 'alias_id' => 1, 'type' => 'BlogContent']]],
[false, ['Site' => ['relate_main_site' => false], 'Content' => ['main_site_content_id' => 1, 'alias_id' => 1, 'type' => 'BlogContent']]],
[false, ['Site' => ['relate_main_site' => true], 'Content' => ['main_site_content_id' => null, 'alias_id' => 1, 'type' => 'BlogContent']]],
[false, ['Site' => ['relate_main_site' => true], 'Content' => ['main_site_content_id' => 1, 'alias_id' => null, 'type' => 'BlogContent']]],
[true, ['Site' => ['relate_main_site' => true], 'Content' => ['main_site_content_id' => 1, 'alias_id' => null, 'type' => 'ContentFolder']]]
[true, new Content(['main_site_content_id' => 1, 'alias_id' => 1, 'type' => 'BlogContent', 'site' => new Site(['relate_main_site' => true])])],
[false, new Content(['main_site_content_id' => 1, 'alias_id' => 1, 'type' => 'BlogContent', 'site' => new Site(['relate_main_site' => false])])],
[false, new Content(['main_site_content_id' => null, 'alias_id' => 1, 'type' => 'BlogContent', 'site' => new Site(['relate_main_site' => true])])],
[false, new Content(['main_site_content_id' => 1, 'alias_id' => null, 'type' => 'BlogContent', 'site' => new Site(['relate_main_site' => true])])],
[true,new Content(['main_site_content_id' => 1, 'alias_id' => null, 'type' => 'ContentFolder', 'site' => new Site(['relate_main_site' => true])])]
];
}

Expand Down

0 comments on commit f171ceb

Please sign in to comment.