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 - -[![Build Status](https://api.travis-ci.org/NetCommons3/Topics.png?branch=master)](https://travis-ci.org/NetCommons3/Topics) -[![Coverage Status](https://coveralls.io/repos/NetCommons3/Topics/badge.png?branch=master)](https://coveralls.io/r/NetCommons3/Topics?branch=master) - -| dependencies | status | -| ------------- | ------ | -| composer.json | [![Dependency Status](https://www.versioneye.com/user/projects/(versioneye_project_ID)/badge.png)](https://www.versioneye.com/user/projects/(versioneye_project_ID)) | +[![Tests Status](https://github.com/NetCommons3/Topics/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/NetCommons3/Topics/actions/workflows/tests.yml) +[![Coverage Status](https://coveralls.io/repos/NetCommons3/Topics/badge.svg?branch=master)](https://coveralls.io/r/NetCommons3/Topics?branch=master) +[![Stable Version](https://img.shields.io/packagist/v/netcommons/topics.svg?label=stable)](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, + )); + ?> +
+
NetCommonsForm->checkbox('TopicFrameSetting.display_summary', array( diff --git a/View/Elements/Topics/header.ctp b/View/Elements/Topics/header.ctp index 057fd67..6c08f3f 100644 --- a/View/Elements/Topics/header.ctp +++ b/View/Elements/Topics/header.ctp @@ -8,13 +8,22 @@ * @license http://www.netcommons.org/license.txt NetCommons License * @copyright Copyright 2014, NetCommons Project */ +$named = $this->Paginator->params['named']; +$named['page'] = '1'; +$url = NetCommonsUrl::blockUrl($named); ?>
- DisplayNumber->dropDownToggleDays(array('currentDays' => $topicFrameSetting['display_days'])); ?> + DisplayNumber->dropDownToggleDays(array( + 'currentDays' => $topicFrameSetting['display_days'], + 'url' => $url + )); ?> - DisplayNumber->dropDownToggle(array('currentLimit' => $topicFrameSetting['display_number'])); ?> + DisplayNumber->dropDownToggle(array( + 'currentLimit' => $topicFrameSetting['display_number'], + 'url' => $url + )); ?> diff --git a/View/Elements/Topics/item.ctp b/View/Elements/Topics/item.ctp index 3951d84..ff1b9ca 100644 --- a/View/Elements/Topics/item.ctp +++ b/View/Elements/Topics/item.ctp @@ -53,16 +53,26 @@
- - - + NetCommonsHtml->handleLink($item, [], []); ?>
- - -
- + +
+
+ +
+ +
+
+ +
+ + + +
+ +
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}} + +
+
+ +
+ {{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(); };