diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..592d72f
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,59 @@
+on:
+ push:
+ # Sequence of patterns matched against refs/tags
+ tags:
+ - '3*'
+
+name: create_release
+
+jobs:
+ build:
+ name: create_release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Slack Notification on Start
+ uses: rtCamp/action-slack-notify@v2.2.0
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_RELEASE }}
+ SLACK_CHANNEL: notify-nc3-release
+ SLACK_TITLE: "${{ github.repository }}"
+ SLACK_COLOR: "#f0ad4e"
+ SLACK_MESSAGE: "Start Job"
+
+ - name: Create Release
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
+ with:
+ tag_name: ${{ github.ref }}
+ release_name: ${{ github.ref }}
+ body: |
+ NetCommons ${{ github.ref }} released.
+ draft: false
+ prerelease: false
+
+ # テスト成功時はこちらのステップが実行される
+ - name: Slack Notification on Finish
+ uses: rtCamp/action-slack-notify@v2.2.0
+ if: success()
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_RELEASE }}
+ SLACK_CHANNEL: notify-nc3-release
+ SLACK_TITLE: "${{ github.repository }}"
+ SLACK_COLOR: good
+ SLACK_MESSAGE: "Job Success"
+
+ # テスト失敗時はこちらのステップが実行される
+ - name: Slack Notification on Failure
+ uses: rtCamp/action-slack-notify@v2.2.0
+ if: failure()
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_RELEASE }}
+ SLACK_CHANNEL: notify-nc3-tests
+ SLACK_TITLE: "${{ github.repository }}"
+ SLACK_COLOR: danger
+ SLACK_MESSAGE: "Job Failure"
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..f46fc05
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,168 @@
+on:
+ push:
+ branches:
+ - main
+ - master
+ pull_request:
+ branches:
+ - main
+ - master
+
+name: tests
+
+jobs:
+ setup:
+ name: setup
+ runs-on: ubuntu-latest
+ steps:
+ - name: Slack Notification on Start
+ uses: rtCamp/action-slack-notify@v2.2.0
+ if: env.SLACK_WEBHOOK != ''
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_TESTS }}
+ SLACK_CHANNEL: notify-nc3-tests
+ SLACK_TITLE: "${{ github.repository }}"
+ SLACK_COLOR: "#f0ad4e"
+
+ tests:
+ name: tests
+ needs: setup
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ php: [ '7.4' ]
+ mysql: [ '8.0' ]
+
+ env:
+ NC3_BUILD_DIR: "/opt/nc3"
+ NC3_DOCKER_DIR: "/opt/docker"
+ NC3_GIT_URL: "git://github.com/NetCommons3/NetCommons3.git"
+ NC3_GIT_BRANCH: "master"
+ PLUGIN_BUILD_DIR: ${{ github.workspace }}
+ PHP_VERSION: ${{ matrix.php }}
+ MYSQL_VERSION: ${{ matrix.mysql }}
+ MYSQL_ROOT_PASSWORD: root
+ MYSQL_DATABASE: cakephp_test
+ COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Fix up git URLs
+ run: echo -e '[url "https://github.com/"]\n insteadOf = "git://github.com/"' >> ~/.gitconfig
+
+ - name: environment
+ run: |
+ echo "GITHUB_WORKSPACE=${GITHUB_WORKSPACE}"
+ echo "PLUGIN_BUILD_DIR=${PLUGIN_BUILD_DIR}"
+ echo "PHP_VERSION=${PHP_VERSION}"
+ echo "MYSQL_VERSION=${MYSQL_VERSION}"
+ ls -al ${PLUGIN_BUILD_DIR}
+
+ - name: docker-compose install
+ run: |
+ curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > ~/docker-compose
+ chmod +x ~/docker-compose
+ sudo mv ~/docker-compose /usr/local/bin/docker-compose
+ docker-compose --version
+
+ - name: git clone nc3
+ run: git clone -b ${NC3_GIT_BRANCH} ${NC3_GIT_URL} ${NC3_BUILD_DIR}
+
+ - name: git clone nc3_docker
+ run: git clone https://github.com/NetCommons3/nc3app-docker.git ${NC3_DOCKER_DIR}
+
+ - name: docker-compose start
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose up -d
+ docker-compose start
+
+ - run: docker ps
+
+ - name: check libraries
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/start-on-docker.sh
+
+ - name: nc3 build
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/app-build.sh
+
+ - name: phpcs (PHP CodeSniffer)
+ if: always()
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/phpcs.sh
+
+ - name: phpmd (PHP Mess Detector)
+ if: always()
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/phpmd.sh
+
+ - name: phpcpd (PHP Copy/Paste Detector)
+ if: always()
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/phpcpd.sh
+
+ - name: gjslint (JavaScript Style Check)
+ if: always()
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/gjslint.sh
+
+ - name: phpdoc (PHP Documentor)
+ if: always()
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/phpdoc.sh
+
+ - name: phpunit (PHP UnitTest)
+ if: always()
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose exec -T nc3app bash /opt/scripts/phpunit.sh
+ sudo -s chmod a+w -R ${NC3_BUILD_DIR}/build
+
+# - name: push coveralls
+# env:
+# COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+# COVERALLS_FLAG_NAME: ${{ matrix.php }}
+# run: |
+# cd ${NC3_BUILD_DIR}
+# ls -la ${NC3_BUILD_DIR}
+# vendors/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v
+
+ - name: docker-compose remove
+ if: always()
+ run: |
+ cd ${NC3_DOCKER_DIR}
+ docker-compose rm -f
+
+ # テスト失敗時はこちらのステップが実行される
+ - name: Slack Notification on Failure
+ uses: rtCamp/action-slack-notify@v2.2.0
+ if: env.SLACK_WEBHOOK != '' && failure()
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_TESTS }}
+ SLACK_CHANNEL: notify-nc3-tests
+ SLACK_TITLE: "${{ github.repository }}(php${{ matrix.php }}, mysql${{ matrix.mysql }})"
+ SLACK_COLOR: danger
+
+ teardown:
+ name: teardown
+ runs-on: ubuntu-latest
+ needs: tests
+ steps:
+ # テスト成功時はこちらのステップが実行される
+ - name: Slack Notification on Success
+ uses: rtCamp/action-slack-notify@v2.2.0
+ if: env.SLACK_WEBHOOK != '' && success()
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_TESTS }}
+ SLACK_CHANNEL: notify-nc3-tests
+ SLACK_TITLE: "${{ github.repository }}"
+ SLACK_COLOR: good
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 110ff79..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-language: php
-
-php:
- - 5.4
- - 5.5
- - 5.6
- - 7.0
- - 7.1
-
-sudo: false
-
-env:
- - NETCOMMONS_VERSION=master DB=mysql
-
-before_script:
- - export NETCOMMONS_BUILD_DIR=`dirname $TRAVIS_BUILD_DIR`/NetCommons3
- - git clone git://github.com/NetCommons3/NetCommons3 $NETCOMMONS_BUILD_DIR
- - cd $NETCOMMONS_BUILD_DIR
- - git checkout $NETCOMMONS_VERSION
- - travis_wait . tools/build/plugins/cakephp/travis/pre.sh
- - . tools/build/plugins/cakephp/travis/environment.sh
-
-script:
- - . tools/build/plugins/cakephp/travis/main.sh
-
-after_script:
- - . tools/build/plugins/cakephp/travis/post.sh
-
-notifications:
- email:
- recipients:
- - netcommons3@googlegroups.com
- on_success: never # default: change
- on_failure: always # default: always
diff --git a/Config/Migration/1609659295_add_image_url.php b/Config/Migration/1609659295_add_image_url.php
new file mode 100644
index 0000000..d862f2d
--- /dev/null
+++ b/Config/Migration/1609659295_add_image_url.php
@@ -0,0 +1,68 @@
+
+ * @link http://www.netcommons.org NetCommons Project
+ * @license http://www.netcommons.org/license.txt NetCommons License
+ * @copyright Copyright 2014, NetCommons Project
+ */
+
+App::uses('NetCommonsMigration', 'NetCommons.Config/Migration');
+
+/**
+ * 新着情報にサムネイルを表示する
+ *
+ * @author Shohei Nakajima
+ * @package NetCommons\Topics\Config\Migration
+ * @see https://github.com/NetCommons3/NetCommons3/issues/1620
+ */
+class AddImageUrl extends NetCommonsMigration {
+
+/**
+ * Migration description
+ *
+ * @var string
+ */
+ public $description = 'add_image_url';
+
+/**
+ * Actions to be performed
+ *
+ * @var array $migration
+ */
+ public $migration = array(
+ 'up' => array(
+ 'create_field' => array(
+ 'topics' => array(
+ 'thumbnail_path' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'after' => 'title_icon'),
+ ),
+ ),
+ ),
+ 'down' => array(
+ 'drop_field' => array(
+ 'topics' => array('thumbnail_path'),
+ ),
+ ),
+ );
+
+/**
+ * Before migration callback
+ *
+ * @param string $direction Direction of migration process (up or down)
+ * @return bool Should process continue
+ */
+ public function before($direction) {
+ return true;
+ }
+
+/**
+ * After migration callback
+ *
+ * @param string $direction Direction of migration process (up or down)
+ * @return bool Should process continue
+ */
+ public function after($direction) {
+ return true;
+ }
+}
diff --git a/Config/Migration/1610073630_add_column_display_thumbnail.php b/Config/Migration/1610073630_add_column_display_thumbnail.php
new file mode 100644
index 0000000..97e3e71
--- /dev/null
+++ b/Config/Migration/1610073630_add_column_display_thumbnail.php
@@ -0,0 +1,68 @@
+
+ * @link http://www.netcommons.org NetCommons Project
+ * @license http://www.netcommons.org/license.txt NetCommons License
+ * @copyright Copyright 2014, NetCommons Project
+ */
+
+App::uses('NetCommonsMigration', 'NetCommons.Config/Migration');
+
+/**
+ * 新着情報にサムネイルを表示する
+ *
+ * @author Shohei Nakajima
+ * @package NetCommons\Topics\Config\Migration
+ * @see https://github.com/NetCommons3/NetCommons3/issues/1620
+ */
+class AddColumnDisplayThumbnail extends NetCommonsMigration {
+
+/**
+ * Migration description
+ *
+ * @var string
+ */
+ public $description = 'add_column_display_thumbnail';
+
+/**
+ * Actions to be performed
+ *
+ * @var array $migration
+ */
+ public $migration = array(
+ 'up' => array(
+ 'create_field' => array(
+ 'topic_frame_settings' => array(
+ 'display_thumbnail' => array('type' => 'boolean', 'null' => false, 'default' => '1', 'after' => 'display_title'),
+ ),
+ ),
+ ),
+ 'down' => array(
+ 'drop_field' => array(
+ 'topic_frame_settings' => array('display_thumbnail'),
+ ),
+ ),
+ );
+
+/**
+ * Before migration callback
+ *
+ * @param string $direction Direction of migration process (up or down)
+ * @return bool Should process continue
+ */
+ public function before($direction) {
+ return true;
+ }
+
+/**
+ * After migration callback
+ *
+ * @param string $direction Direction of migration process (up or down)
+ * @return bool Should process continue
+ */
+ public function after($direction) {
+ return true;
+ }
+}
diff --git a/Config/Migration/1769652195_add_index.php b/Config/Migration/1769652195_add_index.php
new file mode 100644
index 0000000..96398c9
--- /dev/null
+++ b/Config/Migration/1769652195_add_index.php
@@ -0,0 +1,64 @@
+ array(
+ 'create_field' => array(
+ 'topics' => array(
+ 'indexes' => array(
+ 'idx1_p_topics' => array('column' => array('category_id'), 'unique' => 0),
+ 'idx2_p_topics' => array('column' => array('frame_id'), 'unique' => 0),
+ 'idx3_p_topics' => array('column' => array('language_id', 'room_id', 'is_latest', 'is_active', 'is_in_room', 'created_user', 'public_type', 'publish_start', 'publish_end'), 'unique' => 0),
+ 'idx4_p_topics' => array('column' => array('is_active', 'room_id', 'public_type', 'publish_start', 'publish_end', 'created_user', 'id', '`plugin_key`(191)'), 'unique' => 0),
+ ),
+ ),
+ ),
+ ),
+ 'down' => array(
+ 'drop_field' => array(
+ 'topics' => array('indexes' => array('idx1_p_topics', 'idx2_p_topics', 'idx3_p_topics', 'idx4_p_topics')),
+ ),
+ ),
+ );
+
+/**
+ * Before migration callback
+ *
+ * @param string $direction Direction of migration process (up or down)
+ * @return bool Should process continue
+ */
+ public function before($direction) {
+ return true;
+ }
+
+/**
+ * After migration callback
+ *
+ * @param string $direction Direction of migration process (up or down)
+ * @return bool Should process continue
+ */
+ public function after($direction) {
+ return true;
+ }
+}
diff --git a/Config/Schema/schema.php b/Config/Schema/schema.php
index cea5652..2a2b4b2 100644
--- a/Config/Schema/schema.php
+++ b/Config/Schema/schema.php
@@ -58,6 +58,7 @@ public function after($event = array()) {
'display_days' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 3, 'unsigned' => false),
'display_number' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 3, 'unsigned' => false),
'display_title' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
+ 'display_thumbnail' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
'display_summary' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
'display_room_name' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
'display_category_name' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
@@ -205,6 +206,7 @@ public function after($event = array()) {
'plugin_key' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'index', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'title' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'title_icon' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'thumbnail_path' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'summary' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'search_contents' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8', 'comment' => '検索対象のシリアライズデータ'),
'counts' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false),
@@ -235,6 +237,10 @@ public function after($event = array()) {
'plugin_key2' => array('column' => array('plugin_key', 'language_id', 'block_id', 'content_id'), 'unique' => 0),
'room_id' => array('column' => 'room_id', 'unique' => 0),
'search' => array('column' => array('search_contents'), 'type' => 'fulltext'),
+ 'idx1_p_topics' => array('column' => array('category_id'), 'unique' => 0),
+ 'idx2_p_topics' => array('column' => array('frame_id'), 'unique' => 0),
+ 'idx3_p_topics' => array('column' => array('language_id', 'room_id', 'is_latest', 'is_active', 'is_in_room', 'created_user', 'public_type', 'publish_start', 'publish_end'), 'unique' => 0),
+ 'idx4_p_topics' => array('column' => array('is_active', 'room_id', 'public_type', 'publish_start', 'publish_end', 'created_user', 'id', '`plugin_key`(191)'), 'unique' => 0),
),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'Mroonga', 'comment' => 'engine "InnoDB"')
);
diff --git a/Controller/TopicFrameSettingsController.php b/Controller/TopicFrameSettingsController.php
index 22a3e6d..7ebcaea 100644
--- a/Controller/TopicFrameSettingsController.php
+++ b/Controller/TopicFrameSettingsController.php
@@ -82,7 +82,7 @@ class TopicFrameSettingsController extends TopicsAppController {
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function edit() {
- $this->RoomsForm->setRoomsForCheckbox();
+ $this->RoomsForm->setRoomsForCheckbox(array(), array('limit' => 100));
$this->PluginsForm->setPluginsRoomForCheckbox($this, $this->PluginsForm->findOptions);
$pluginKeys = [];
diff --git a/Locale/eng/LC_MESSAGES/topics.pot b/Locale/eng/LC_MESSAGES/topics.pot
index cbeff1a..9c6e070 100644
--- a/Locale/eng/LC_MESSAGES/topics.pot
+++ b/Locale/eng/LC_MESSAGES/topics.pot
@@ -83,6 +83,9 @@ msgstr ""
msgid "Title"
msgstr ""
+msgid "Thumbnail"
+msgstr ""
+
#: Topics/View/Elements/TopicFrameSettings/edit_form.ctp:103
msgid "Detail"
msgstr ""
diff --git a/Locale/jpn/LC_MESSAGES/topics.po b/Locale/jpn/LC_MESSAGES/topics.po
index fb7c12c..b5c4583 100644
--- a/Locale/jpn/LC_MESSAGES/topics.po
+++ b/Locale/jpn/LC_MESSAGES/topics.po
@@ -93,6 +93,9 @@ msgstr "プライベート"
msgid "Title"
msgstr "件名"
+msgid "Thumbnail"
+msgstr "サムネイル画像"
+
msgid "Detail"
msgstr "詳細"
diff --git a/Model/Behavior/TopicsBaseBehavior.php b/Model/Behavior/TopicsBaseBehavior.php
index 8e4d376..25ca99d 100644
--- a/Model/Behavior/TopicsBaseBehavior.php
+++ b/Model/Behavior/TopicsBaseBehavior.php
@@ -10,6 +10,7 @@
*/
App::uses('ModelBehavior', 'Model');
+App::uses('WysiwygBehavior', 'Wysiwyg.Model/Behavior');
/**
* Topics Behavior
@@ -116,6 +117,7 @@ protected function _saveTopic(Model $model) {
'content_key' => Hash::get($model->data, $setting['content_key']),
'content_id' => Hash::get($model->data, $setting['content_id']),
'title' => $this->_parseTitle($model),
+ 'thumbnail_path' => $this->_parseThumbnailImage($model),
'summary' => $this->_parseContents($model),
'search_contents' => $this->_parseSearchContents($model),
'is_answer' => $setting['is_answer'],
@@ -184,6 +186,47 @@ protected function _parseTitle(Model $model) {
return $result;
}
+/**
+ * 新着のコンテンツからサムネイルにパースする
+ *
+ * 自サイトの画像のみ対象とする
+ *
+ * self::_saveTopic()から実行される
+ *
+ * @param Model $model 呼び出し元のモデル
+ * @return string
+ */
+ protected function _parseThumbnailImage(Model $model) {
+ $setting = $this->settings[$model->alias]['fields'];
+ $result = '';
+
+ $pattern = '//i';
+ $baseUrl = substr(Router::url('/', true), 0, -1);
+
+ foreach ($setting['summary'] as $field) {
+ $value = (string)Hash::get($model->data, $field);
+ $matches = [];
+ if (! preg_match_all($pattern, $value, $matches)) {
+ continue;
+ }
+
+ foreach ($matches[1] as $imgUrl) {
+ $imgUrl = str_replace(WysiwygBehavior::REPLACE_BASE_URL, '', $imgUrl);
+ $imgUrl = str_replace($baseUrl, '', $imgUrl);
+ if (substr($imgUrl, 0, 1) !== '/' ||
+ strpos($imgUrl, 'img/title_icon') !== false) {
+ continue;
+ }
+ $imgUrl = parse_url($imgUrl, PHP_URL_PATH);
+ $imgUrl = preg_replace('/\/(thumb|big|small|biggest|medium)$/i', '', $imgUrl);
+ $result = $imgUrl;
+ break 2;
+ }
+ }
+
+ return $result;
+ }
+
/**
* 新着のコンテンツにパースする
*
@@ -263,7 +306,12 @@ protected function _hasSaveData(Model $model, $field) {
$pathKey = $setting[$field];
}
- if (array_key_exists($field, $data) || Hash::get($model->data, $pathKey) !== null) {
+ list($modleByData, $fieldByData) = pluginSplit($pathKey);
+
+ if (array_key_exists($field, $data) ||
+ isset($model->data[$modleByData]) &&
+ array_key_exists($fieldByData, $model->data[$modleByData]) ||
+ Hash::get($model->data, $pathKey) !== null) {
return true;
} else {
return false;
@@ -289,8 +337,13 @@ protected function _getSaveData(Model $model, $field) {
$pathKey = $setting[$field];
}
+ list($modleByData, $fieldByData) = pluginSplit($pathKey);
+
if (array_key_exists($field, $data)) {
return Hash::get($data, $field);
+ } elseif (isset($model->data[$modleByData]) &&
+ array_key_exists($fieldByData, $model->data[$modleByData])) {
+ return $model->data[$modleByData][$fieldByData];
} elseif (Hash::get($model->data, $pathKey, false) !== false) {
return Hash::get($model->data, $pathKey);
} else {
diff --git a/Model/Behavior/TopicsBehavior.php b/Model/Behavior/TopicsBehavior.php
index aa6806d..d336d9c 100644
--- a/Model/Behavior/TopicsBehavior.php
+++ b/Model/Behavior/TopicsBehavior.php
@@ -117,7 +117,9 @@ public function saveTopics(Model $model) {
//新着に表示させる会員のリスト登録
foreach ($model->data[$model->Topic->alias] as $topic) {
- $this->_saveTopicReadable($model, $topic['id']);
+ if (isset($topic['id'])) {
+ $this->_saveTopicReadable($model, $topic['id']);
+ }
}
return true;
diff --git a/Model/Topic.php b/Model/Topic.php
index 2efd879..7bf3272 100644
--- a/Model/Topic.php
+++ b/Model/Topic.php
@@ -445,6 +445,11 @@ public function afterFind($results, $primary = false) {
}
$results[$key][$this->alias]['url'] = $url;
}
+ if (!empty($results[$key][$this->alias]['thumbnail_path'])) {
+ $results[$key][$this->alias]['thumbnail_url'] = Router::url(
+ $value[$this->alias]['thumbnail_path'] . '/thumb', true
+ );
+ }
}
return $results;
}
@@ -721,7 +726,7 @@ private function __bindModel() {
'className' => 'Blocks.BlocksLanguage',
'fields' => array('name'),
'foreignKey' => false,
- 'type' => 'INNER',
+ 'type' => 'LEFT',
'conditions' => array(
'BlocksLanguage.block_id' . ' = ' . $this->alias . '.block_id',
'BlocksLanguage.language_id' => Current::read('Language.id', '0'),
diff --git a/Model/TopicFramesPlugin.php b/Model/TopicFramesPlugin.php
index 0ee9179..3c6e928 100644
--- a/Model/TopicFramesPlugin.php
+++ b/Model/TopicFramesPlugin.php
@@ -66,8 +66,8 @@ public function validateRequestData($data) {
}
}
- $check = isset($data['TopicFramesPlugin']['plugin_key'])
- ? $data['TopicFramesPlugin']['plugin_key']
+ $check = isset($data['TopicFrameSetting']['plugin_key'])
+ ? $data['TopicFrameSetting']['plugin_key']
: [];
foreach ($check as $pluginKey) {
if (! in_array($pluginKey, $pluginKeys, true)) {
@@ -126,12 +126,14 @@ public function getPlugins($topicFrameSetting, $conditions = []) {
)
), true);
+ $conditions = Hash::merge(
+ array($this->alias . '.frame_key' => Current::read('Frame.key')),
+ $conditions
+ );
$plugin = $this->find('list', array(
'recursive' => 0,
'fields' => array('Plugin.key', 'Plugin.name'),
- 'conditions' => array(
- $this->alias . '.frame_key' => Current::read('Frame.key'),
- ),
+ 'conditions' => $conditions,
'order' => 'weight'
));
} else {
@@ -143,7 +145,7 @@ public function getPlugins($topicFrameSetting, $conditions = []) {
array('display_topics' => true, 'language_id' => Current::read('Language.id', '0')),
$conditions
);
- $plugin = $this->Plugin->find('list', array(
+ $plugin = $this->Plugin->cacheFindQuery('list', array(
'recursive' => -1,
'fields' => array('key', 'name'),
'conditions' => $conditions,
@@ -165,9 +167,9 @@ public function getPlugins($topicFrameSetting, $conditions = []) {
*/
public function saveTopicFramesPlugin($data) {
$pluginKeys = [];
- foreach ($data[$this->alias] as $frame) {
- if (isset($frame['plugin_key'])) {
- $pluginKeys[] = $frame['plugin_key'];
+ if (isset($data[$this->alias]['plugin_key'])) {
+ foreach ($data[$this->alias]['plugin_key'] as $pluginKey) {
+ $pluginKeys[] = $pluginKey;
}
}
diff --git a/README.md b/README.md
index b9c88cb..25e4e9a 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,6 @@
Topics
==============
-Topics for NetComomns3
-
-[](https://travis-ci.org/NetCommons3/Topics)
-[](https://coveralls.io/r/NetCommons3/Topics?branch=master)
-
-| dependencies | status |
-| ------------- | ------ |
-| composer.json | [/badge.png)](https://www.versioneye.com/user/projects/(versioneye_project_ID)) |
+[](https://github.com/NetCommons3/Topics/actions/workflows/tests.yml)
+[](https://coveralls.io/r/NetCommons3/Topics?branch=master)
+[](https://packagist.org/packages/netcommons/topics)
diff --git a/Test/Case/Model/Topic/PrivateGetRoomsConditionsTest.php b/Test/Case/Model/Topic/PrivateGetRoomsConditionsTest.php
index 8361bfc..e4d2d59 100644
--- a/Test/Case/Model/Topic/PrivateGetRoomsConditionsTest.php
+++ b/Test/Case/Model/Topic/PrivateGetRoomsConditionsTest.php
@@ -16,6 +16,7 @@
*
* @author Shohei Nakajima
* @package NetCommons\Topics\Test\Case\Model\Topic
+ * @see Topic::__getRoomsConditions()
*/
class PrivateTopicGetRoomsConditionsTest extends NetCommonsModelTestCase {
@@ -181,10 +182,10 @@ public function dataProvider() {
'Block.public_type' => '2',
0 => array(
'OR' =>
- array(
- 'Block.publish_start <=' => $now,
- 'Block.publish_start' => null,
- ),
+ array(
+ 'Block.publish_start <=' => $now,
+ 'Block.publish_start' => null,
+ ),
),
1 => array(
'OR' => array(
diff --git a/Test/Fixture/Room4topicsFixture.php b/Test/Fixture/Room4topicsFixture.php
index df10b6f..386b0f6 100644
--- a/Test/Fixture/Room4topicsFixture.php
+++ b/Test/Fixture/Room4topicsFixture.php
@@ -53,6 +53,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '1',
'page_layout_permitted' => '1',
'theme' => 'Default',
+ 'sort_key' => '~00000001-00000001',
),
//パブリックスペース、パブリックルーム(room_id=5)
array(
@@ -68,6 +69,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => true,
'page_layout_permitted' => true,
'theme' => null,
+ 'sort_key' => '~00000001-00000001-00000001',
),
//プライベート
@@ -84,6 +86,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => '0',
'theme' => 'Default',
+ 'sort_key' => '~00000001-00000002',
),
//プライベートルーム、管理者(room_id=6)
array(
@@ -99,6 +102,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => '0',
'theme' => null,
+ 'sort_key' => '~00000001-00000002-00000001',
),
//プライベートルーム、編集長(room_id=7)
array(
@@ -114,6 +118,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => '0',
'theme' => null,
+ 'sort_key' => '~00000001-00000002-00000002',
),
//プライベートルーム、編集者(room_id=8)
array(
@@ -129,6 +134,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => '0',
'theme' => null,
+ 'sort_key' => '~00000001-00000002-00000003',
),
//プライベートルーム、一般1(room_id=9)
array(
@@ -144,6 +150,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => '0',
'theme' => null,
+ 'sort_key' => '~00000001-00000002-00000004',
),
//プライベートルーム、ゲスト(room_id=10)
array(
@@ -159,6 +166,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => '0',
'theme' => null,
+ 'sort_key' => '~00000001-00000002-00000005',
),
//プライベートルーム、一般2(room_id=13)
array(
@@ -174,6 +182,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => '0',
'theme' => null,
+ 'sort_key' => '~00000001-00000002-00000006',
),
//コミュニティスペース
@@ -190,6 +199,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '1',
'page_layout_permitted' => '1',
'theme' => 'Default',
+ 'sort_key' => '~00000001-00000003',
),
//コミュニティスペース、ルーム1(room_id=11)
array(
@@ -205,6 +215,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => null,
'theme' => null,
+ 'sort_key' => '~00000001-00000003-00000001',
),
//コミュニティスペース、ルーム2(room_id=12)
array(
@@ -220,6 +231,7 @@ class Room4topicsFixture extends RoomFixture {
'default_participation' => '0',
'page_layout_permitted' => null,
'theme' => null,
+ 'sort_key' => '~00000001-00000003-00000002',
),
);
}
diff --git a/VERSION.txt b/VERSION.txt
new file mode 100644
index 0000000..86fb650
--- /dev/null
+++ b/VERSION.txt
@@ -0,0 +1 @@
+3.3.7
diff --git a/View/Elements/TopicFrameSettings/edit_form.ctp b/View/Elements/TopicFrameSettings/edit_form.ctp
index 1027a70..3aab877 100644
--- a/View/Elements/TopicFrameSettings/edit_form.ctp
+++ b/View/Elements/TopicFrameSettings/edit_form.ctp
@@ -99,6 +99,16 @@
?>
+
+ NetCommonsForm->checkbox('TopicFrameSetting.display_thumbnail', array(
+ 'type' => 'checkbox',
+ 'label' => __d('topics', 'Thumbnail'),
+ 'inline' => false,
+ ));
+ ?>
+
+
-
-
-
-
+
+
diff --git a/View/Elements/Topics/item_angularjs.ctp b/View/Elements/Topics/item_angularjs.ctp
index 5ce4622..d2a621d 100644
--- a/View/Elements/Topics/item_angularjs.ctp
+++ b/View/Elements/Topics/item_angularjs.ctp
@@ -51,16 +51,35 @@
-
-
- {{item.Topic.display_summary}}
+
+
diff --git a/View/Elements/Topics/select_status.ctp b/View/Elements/Topics/select_status.ctp
index f155f9b..36428e3 100644
--- a/View/Elements/Topics/select_status.ctp
+++ b/View/Elements/Topics/select_status.ctp
@@ -18,7 +18,7 @@
diff --git a/View/Helper/TopicsHelper.php b/View/Helper/TopicsHelper.php
index 1ff6a97..48dfe53 100644
--- a/View/Helper/TopicsHelper.php
+++ b/View/Helper/TopicsHelper.php
@@ -328,7 +328,7 @@ public function rssSettingHelp($content = '', $placement = 'bottom') {
$html .= __d('topics', 'Can use an embedded keyword in the channel title line and summary') . ' ';
$html .= '
';
- $html .= '';
+ $html .= '';
$html .= '';
$html .= '';
diff --git a/View/Topics/json/index_plugins.ctp b/View/Topics/json/index_plugins.ctp
index 5d73e46..8d2f899 100644
--- a/View/Topics/json/index_plugins.ctp
+++ b/View/Topics/json/index_plugins.ctp
@@ -14,4 +14,4 @@ $pluginKey = $this->request->query['plugin_key'];
echo $this->NetCommonsHtml->json(array(
'paging' => $topics[$pluginKey]['paging'],
'topics' => $this->Topics->camelizeKeyRecursive($topics[$pluginKey]['topics'])
-));
+), 'OK', 200, false);
diff --git a/View/Topics/json/index_rooms.ctp b/View/Topics/json/index_rooms.ctp
index aee86e9..0fd667a 100644
--- a/View/Topics/json/index_rooms.ctp
+++ b/View/Topics/json/index_rooms.ctp
@@ -14,4 +14,4 @@ $roomId = $this->request->query['room_id'];
echo $this->NetCommonsHtml->json(array(
'paging' => $topics[$roomId]['paging'],
'topics' => $this->Topics->camelizeKeyRecursive($topics[$roomId]['topics'])
-));
+), 'OK', 200, false);
diff --git a/composer.json b/composer.json
index 0748f32..88adc3b 100644
--- a/composer.json
+++ b/composer.json
@@ -20,12 +20,11 @@
"netcommons/plugin-manager": "@dev",
"netcommons/roles": "@dev",
"netcommons/rooms": "@dev",
- "netcommons/topics": "@dev",
"netcommons/users": "@dev",
"netcommons/workflow": "@dev"
},
- "license": "LicenseRef-NetCommons",
"license-ref-net-commons": "https://raw.githubusercontent.com/NetCommons3/NetCommons3/master/license.txt",
+ "license": "LicenseRef-NetCommons",
"authors": [
{
"name": "NetCommons Community",
@@ -44,4 +43,4 @@
"config": {
"vendor-dir": "vendors"
}
-}
\ No newline at end of file
+}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index c607911..f2c6cae 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,5 +1,8 @@
+
+
+
app/Plugin/Topics
@@ -14,6 +17,6 @@
-
+
diff --git a/webroot/css/style.css b/webroot/css/style.css
index 2b579b9..f5682b3 100644
--- a/webroot/css/style.css
+++ b/webroot/css/style.css
@@ -53,6 +53,11 @@ article .topic-status.small > .label {
-webkit-line-clamp: 3;
}
+.topic-thumbnail {
+ max-width: 80px;
+ max-height: 80px;
+}
+
.frame.nc-content-list article h2.topic-plugin-name,
.frame.nc-content-list article h2.topic-room-name {
margin-top: 16px;
diff --git a/webroot/js/topics.js b/webroot/js/topics.js
index 8c2f971..c47a92b 100644
--- a/webroot/js/topics.js
+++ b/webroot/js/topics.js
@@ -29,6 +29,7 @@ NetCommonsApp.controller('TopicSettingsController', ['$scope', function($scope)
$scope.initBlocks = function(blocks, topicFramesBlock) {
$scope.blocks = blocks;
$scope.topicFramesBlock = topicFramesBlock['topicFramesBlock'];
+ $scope.blockKey = $scope.topicFramesBlock.blockKey;
};
/**
@@ -41,7 +42,7 @@ NetCommonsApp.controller('TopicSettingsController', ['$scope', function($scope)
if (angular.isDefined($scope.blocks[pluginKey])) {
if (angular.isDefined($scope.blocks[pluginKey][$scope.blockKey])) {
- var blockKey = $scope.topicFramesBlock.blockKey;
+ var blockKey = $scope.blockKey;
} else {
var blockKey = null;
angular.forEach($scope.blocks[pluginKey], function(value, key) {
@@ -117,7 +118,7 @@ NetCommonsApp.controller('TopicsController',
$location.hash(
'page:' + ($scope.paging['page']) + '&' + 'frame_id:' + $scope.params['frame_id']
);
- $window.location.href = $event.target.href;
+ $window.location.href = $event.currentTarget.href;
$event.preventDefault();
};