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..6da4321 --- /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.1', '7.2', '7.3', '7.4' ] + mysql: [ '5.7', '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 dcad8f5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -language: php - -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - -sudo: required - -env: - matrix: - - NETCOMMONS_VERSION=master DB=mysql - global: - - secure: "eOJhJHrLG6nQUX222m/g/g1LR+k/W/mtdvJsxyHRx++Robu6EIDuXmE6Y4SuIi0vlvJbdhrOx9Gu0oKIkX5RYXbY0iwFnoQ1iXYnPBH9DoBp7ucr2ddd/UDsIkR40k6v8m2Dunzzk1xfiZvXw0UUxL/ulMQLBqvjEZu+pgLM9sc=" - - GIT_COMMITTER_NAME=s-nakajima - - GIT_COMMITTER_EMAIL=nakajimashouhei@gmail.com - - GIT_AUTHOR_NAME=s-nakajima - - GIT_AUTHOR_EMAIL=nakajimashouhei@gmail.com - -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/Controller/LikesController.php b/Controller/LikesController.php index 4fc087f..57bfe2d 100644 --- a/Controller/LikesController.php +++ b/Controller/LikesController.php @@ -47,8 +47,8 @@ public function like() { if (! $this->request->is('post')) { return $this->throwBadRequest(); } - - if ($this->Like->existsLike($this->data['Like']['content_key'])) { + $md5SessionKey = $this->__getKey(); + if ($this->Like->existsLike($this->data['Like']['content_key'], $md5SessionKey)) { return; } @@ -58,9 +58,27 @@ public function like() { 'conditions' => array('content_key' => $data['Like']['content_key']) )); $data = Hash::merge($like, $data); + if (!Current::read('User.id')) { + $data['LikesUser']['session_key'] = $md5SessionKey; + } if ($this->Like->saveLike($data)) { return; } $this->NetCommons->handleValidationError($this->Like->validationErrors); } + +/** + * session_keyを返す + * + * @return string + */ + private function __getKey() { + $md5SessionKey = $this->Session->read('Likes.md5_session_key'); + if ($md5SessionKey) { + return $md5SessionKey; + } + $md5SessionKey = md5(CakeSession::id()); + $this->Session->write('Likes.md5_session_key', $md5SessionKey); + return $md5SessionKey; + } } diff --git a/Model/Behavior/LikeBehavior.php b/Model/Behavior/LikeBehavior.php index 094b608..d1946a2 100644 --- a/Model/Behavior/LikeBehavior.php +++ b/Model/Behavior/LikeBehavior.php @@ -86,50 +86,40 @@ public function setup(Model $model, $config = array()) { * @return array タグ検索条件を加えたfind条件 */ public function beforeFind(Model $model, $query) { - if (Hash::get($query, 'recursive') > -1) { - $joinTable = false; - - $conditions = $query['conditions']; - if (is_array($conditions) === false) { - return $query; - } - $columns = array_keys($conditions); - // 条件あったらLikeテーブルとリンクテーブルをJOIN - if (preg_grep('/^Like\./', $columns) || preg_grep('/^LikesUser\./', $columns)) { - $joinTable = true; + if (Hash::get($query, 'recursive', $model->recursive) > -1) { + $likesUserConditions = array( + 'Like.id = LikesUser.like_id', + ); + if (Current::read('User.id')) { + $likesUserConditions['LikesUser.user_id'] = Current::read('User.id'); + } else { + $likesUserConditions['LikesUser.session_key'] = CakeSession::id(); } - if ($joinTable) { - $likesUserConditions = array( - 'Like.id = LikesUser.like_id', - ); - if (Current::read('User.id')) { - $likesUserConditions['LikesUser.user_id'] = Current::read('User.id'); - } else { - $likesUserConditions['LikesUser.session_key'] = CakeSession::id(); - } + $fieldName = $this->settings[$model->alias]['model'] . '.' . + $this->settings[$model->alias]['field']; - $LikesUser = ClassRegistry::init('Likes.LikesUser'); - $Like = ClassRegistry::init('Likes.Like'); - - $fieldName = $this->settings[$model->alias]['model'] . '.' . - $this->settings[$model->alias]['field']; - $query['joins'][] = [ - 'type' => 'LEFT', - 'table' => $Like->table, - 'alias' => $Like->alias, - 'conditions' => [ - 'Like.plugin_key' => Inflector::underscore($model->plugin), - $fieldName . ' = ' . 'Like.content_key', - ] - ]; - $query['joins'][] = [ - 'type' => 'LEFT', - 'table' => $LikesUser->table, - 'alias' => $LikesUser->alias, - 'conditions' => $likesUserConditions, - ]; - } + // joinではfieldsを指定しないと値を取得できない。 + // fieldsはほぼNULLのため、fieldsを追加対応ができない。そのためbindModelで対応する + // bindModelの場合、うまいことfieldsを設定してくれる。 + $model->bindModel(array( + 'belongsTo' => array( + 'Like' => array( + 'className' => 'Likes.Like', + 'foreignKey' => false, + 'conditions' => array( + 'Like.plugin_key' => Inflector::underscore($model->plugin), + //$this->__model . '.' . $this->__field . ' = ' . 'Like.content_key', + $fieldName . ' = ' . 'Like.content_key', + ), + ), + 'LikesUser' => array( + 'className' => 'Likes.LikesUser', + 'foreignKey' => false, + 'conditions' => $likesUserConditions, + ), + ) + ), true); } return $query; } diff --git a/Model/Like.php b/Model/Like.php index 13fb63b..fe99f0c 100644 --- a/Model/Like.php +++ b/Model/Like.php @@ -72,7 +72,7 @@ class Like extends LikesAppModel { * @see Model::save() */ public function beforeValidate($options = array()) { - $this->validate = Hash::merge($this->validate, array( + $this->validate = ValidateMerge::merge($this->validate, array( 'plugin_key' => array( 'notBlank' => array( 'rule' => array('notBlank'), @@ -176,9 +176,11 @@ public function afterSave($created, $options = array()) { * Exists like data * * @param string $contentKey Content key of each plugin. + * @param string $md5SessionKey md5(SessionKey) + * @see https://github.com/researchmap/RmNetCommons3/issues/1750#issuecomment-596823362 * @return bool */ - public function existsLike($contentKey) { + public function existsLike($contentKey, $md5SessionKey = null) { $this->LikesUser = ClassRegistry::init('Likes.LikesUser'); $joinConditions = array( @@ -186,8 +188,11 @@ public function existsLike($contentKey) { ); if (Current::read('User.id')) { $joinConditions[$this->LikesUser->alias . '.user_id'] = Current::read('User.id'); + } elseif (!is_null($md5SessionKey)) { + $joinConditions[$this->LikesUser->alias . '.session_key'] = (string)$md5SessionKey; } else { - $joinConditions[$this->LikesUser->alias . '.session_key'] = (string)CakeSession::id(); + // 常にインクリメント + return false; } $count = $this->find('count', array( @@ -224,7 +229,6 @@ public function saveLike($data) { $this->begin(); //バリデーション - $data['LikesUser']['session_key'] = CakeSession::id(); $this->set($data); if (! $this->validates()) { $this->rollback(); diff --git a/Model/LikesUser.php b/Model/LikesUser.php index 6a82647..5a402e9 100644 --- a/Model/LikesUser.php +++ b/Model/LikesUser.php @@ -55,7 +55,7 @@ class LikesUser extends LikesAppModel { * @see Model::save() */ public function beforeValidate($options = array()) { - $this->validate = Hash::merge($this->validate, array( + $this->validate = ValidateMerge::merge($this->validate, array( 'is_liked' => array( 'boolean' => array( 'rule' => array('boolean'), diff --git a/README.md b/README.md index 8c586ea..e5128bf 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,9 @@ Likes ============== -Likes for NetComomns3 - -[![Build Status](https://api.travis-ci.org/NetCommons3/Likes.png?branch=master)](https://travis-ci.org/NetCommons3/Likes) -[![Coverage Status](https://coveralls.io/repos/NetCommons3/Likes/badge.png?branch=master)](https://coveralls.io/r/NetCommons3/Likes?branch=master) - -| dependencies | status | -| ------------- | ------ | -| composer.json | [![Dependency Status](https://www.versioneye.com/user/projects/55208049529844d45300001f/badge.png)](https://www.versioneye.com/user/projects/55208049529844d45300001f) | +[![Tests Status](https://github.com/NetCommons3/Likes/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/NetCommons3/Likes/actions/workflows/tests.yml) +[![Coverage Status](https://coveralls.io/repos/NetCommons3/Likes/badge.svg?branch=master)](https://coveralls.io/r/NetCommons3/Likes?branch=master) +[![Stable Version](https://img.shields.io/packagist/v/netcommons/likes.svg?label=stable)](https://packagist.org/packages/netcommons/likes) ### 概要 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/phpunit.xml.dist b/phpunit.xml.dist index 22c1fb3..ec59634 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,8 @@ + + + app/Plugin/Likes @@ -14,6 +17,6 @@ - +