diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a3225bc..592d72f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,16 +4,25 @@ on:
tags:
- '3*'
-name: Create Release
+name: create_release
jobs:
build:
- name: Create Release
+ 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
@@ -26,3 +35,25 @@ jobs:
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/.phpcpdignore b/.phpcpdignore
new file mode 100644
index 0000000..ad49132
--- /dev/null
+++ b/.phpcpdignore
@@ -0,0 +1,2 @@
+ReservationImportController.php
+ReservationPlansController.php
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index cf8d3b1..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-language: php
-
-php:
- - 7.0
- - 7.1
- - 7.2
- - 7.3.24
- - 7.4
-
-sudo: false
-dist: trusty
-
-env:
- matrix:
- - NETCOMMONS_VERSION=master DB=mysql
- global:
- - secure: "OfqRkPfSzBeU288mu0hEktEoWMZxxcYJN9BzrDrrXgTPCev5C7URonk+71pCB3L5+pI8fD/mBanhqFgClpe1tJdmt0m6BJ6woLMSNJT/1jdxX6C55gIaKPfutO0Of1GQ8K6ibHnlgrgsk/mGwRDH01u3k0qkL3saPNrVlBgmC5E="
- - GIT_COMMITTER_NAME=to-hashimoto-3
- - GIT_COMMITTER_EMAIL=toshihide@allcreaotr.net
- - GIT_AUTHOR_NAME=AllCreator
- - GIT_AUTHOR_EMAIL=info@allcreator.net
-
-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
- - . tools/build/plugins/cakephp/travis/pre.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/ReservationFrameSettingsController.php b/Controller/ReservationFrameSettingsController.php
index 1bcac62..f9441ac 100644
--- a/Controller/ReservationFrameSettingsController.php
+++ b/Controller/ReservationFrameSettingsController.php
@@ -120,6 +120,11 @@ public function edit() {
$this->view = 'nolocation';
return;
}
+
+ // openTextの追加
+ $openText = new ReservationLocationOpenText();
+ $locations = $openText->openTextAdd($locations);
+
$this->set('locations', $locations);
// 設定情報取り出し
diff --git a/Controller/ReservationImportController.php b/Controller/ReservationImportController.php
index b1fd4f8..07b6078 100644
--- a/Controller/ReservationImportController.php
+++ b/Controller/ReservationImportController.php
@@ -131,6 +131,11 @@ public function beforeFilter() {
public function edit() {
// 施設情報
$locations = $this->ReservationLocation->getReservableLocations();
+
+ // openTextの追加
+ $openText = new ReservationLocationOpenText();
+ $locations = $openText->openTextAdd($locations);
+
$this->set('locations', $locations);
$frameId = Current::read('Frame.id');
diff --git a/Controller/ReservationLocationsController.php b/Controller/ReservationLocationsController.php
index dddb01a..029081d 100644
--- a/Controller/ReservationLocationsController.php
+++ b/Controller/ReservationLocationsController.php
@@ -94,6 +94,11 @@ public function index() {
'ReservationLocation' => $query
];
$reservationLocations = $this->Paginator->paginate('ReservationLocation');
+
+ // openTextの追加
+ $openText = new ReservationLocationOpenText();
+ $reservationLocations = $openText->openTextAdd($reservationLocations);
+
$this->set('reservationLocations', $reservationLocations);
}
@@ -377,6 +382,11 @@ public function sort() {
'ReservationLocation' => $query
];
$reservationLocations = $this->Paginator->paginate('ReservationLocation');
+
+ // openTextの追加
+ $openText = new ReservationLocationOpenText();
+ $reservationLocations = $openText->openTextAdd($reservationLocations);
+
$this->set('reservationLocations', $reservationLocations);
$this->request->data['ReservationLocations'] = $reservationLocations;
diff --git a/Controller/ReservationPlansController.php b/Controller/ReservationPlansController.php
index 971f3fb..3922f10 100644
--- a/Controller/ReservationPlansController.php
+++ b/Controller/ReservationPlansController.php
@@ -153,7 +153,7 @@ public function beforeFilter() {
ReservationPermissiveRooms::setRoomPermRoles($this->roomPermRoles);
// 表示のための各種共通パラメータ設定
- $this->_vars = $this->getVarsForShow();
+ $this->_vars = $this->__getVarsForShow();
}
/**
@@ -288,6 +288,11 @@ public function delete() {
public function add() {
// 施設情報
$locations = $this->ReservationLocation->getReservableLocations();
+
+ // openTextの追加
+ $openText = new ReservationLocationOpenText();
+ $locations = $openText->openTextAdd($locations);
+
$locations = $this->__mergeApprovalUserName($locations);
$this->set('locations', $locations);
@@ -305,7 +310,7 @@ public function add() {
$selectedRoomId = $this->request->data['ReservationActionPlan']['plan_room_id'] ?? 0;
$selectedRoom = $this->ReservationSelectRoom->getSelectedRoom(
$defaultRooms,
- $selectedRoomId
+ (int)$selectedRoomId
);
$this->set('selectedRoom', json_encode($selectedRoom));
@@ -330,6 +335,10 @@ public function add() {
*/
public function edit() {
if ($this->request->is('post')) {
+ $editRrule = $this->ReservationActionPlan->getEditRruleForUpdate($this->request->data);
+ if ($editRrule == ReservationAppBehavior::CALENDAR_PLAN_EDIT_THIS) {
+ $this->request->data['ReservationActionPlan']['is_repeat'] = '0';
+ }
$this->_reservationPost();
}
// 表示のための処理
@@ -343,6 +352,11 @@ public function edit() {
// 施設情報
$locations = $this->ReservationLocation->getReservableLocations();
+
+ // openTextの追加
+ $openText = new ReservationLocationOpenText();
+ $locations = $openText->openTextAdd($locations);
+
$locations = $this->__mergeApprovalUserName($locations);
$this->set('locations', $locations);
@@ -360,7 +374,7 @@ public function edit() {
$selectedRoomId = $this->request->data['ReservationActionPlan']['plan_room_id'];
$selectedRoom = $this->ReservationSelectRoom->getSelectedRoom(
$defaultRooms,
- $selectedRoomId
+ (int)$selectedRoomId
);
$this->set('selectedRoom', json_encode($selectedRoom));
}
@@ -617,7 +631,7 @@ public function view() {
* @return void
* @throws InternalErrorException
*/
- public function getVarsForShow() {
+ private function __getVarsForShow() {
$vars = array();
$this->setReservationCommonVars($vars);
diff --git a/Controller/ReservationsController.php b/Controller/ReservationsController.php
index bce74ec..b06c2e5 100644
--- a/Controller/ReservationsController.php
+++ b/Controller/ReservationsController.php
@@ -119,6 +119,11 @@ public function index() {
}
$categoryId = Hash::get($this->request->params['named'], 'category_id');
+ if ($categoryId === '') {
+ // タブ切り替えや前後ページングで'カテゴリ選択'だとcategory_idが空文字になるので
+ // そのときはnull(カテゴリの指定無し)にする
+ $categoryId = null;
+ }
$locations = $this->ReservationLocation->getLocations($categoryId);
@@ -163,6 +168,7 @@ public function index() {
$frameId = Current::read('Frame.id');
$languageId = Current::read('Language.id');
$this->set(compact('frameId', 'languageId', 'vars'));
+ $this->set('unselectedCategory', $this->ReservationLocation->getCountUnselectedCategory());
$this->render($ctpName);
//$roomId = Current::read('Room.id');
@@ -232,7 +238,7 @@ protected function _getWeeklyVars($vars) {
* @param array $vars カレンンダー情報
* @return array $vars 日単位(一覧)データ
*/
- public function getDailyListVars($vars) {
+ protected function _getDailyListVars($vars) {
$this->setReservationCommonVars($vars);
$vars['tab'] = 'list';
return $vars;
@@ -261,7 +267,7 @@ protected function _getDailyVars($vars) {
//if ($tab === 'timeline') {
$vars = $this->_getDailyTimelineVars($vars);
//} else {
- // $vars = $this->getDailyListVars($vars);
+ // $vars = $this->_getDailyListVars($vars);
//}
$vars['selectRooms'] = array(); //マージ前の暫定
diff --git a/Lib/ReservationLocationOpenText.php b/Lib/ReservationLocationOpenText.php
index 63b0535..845e531 100644
--- a/Lib/ReservationLocationOpenText.php
+++ b/Lib/ReservationLocationOpenText.php
@@ -78,4 +78,22 @@ public function openText($reservationLocation) {
}
return $ret;
}
+
+/**
+ * openTextをセットした施設データを返す
+ *
+ * @param array $reservationLocations 施設データ
+ * @return array
+ */
+ public function openTextAdd($reservationLocations) {
+ foreach ($reservationLocations as $key => $value) {
+ if (array_key_exists('time_table', $value['ReservationLocation']) &&
+ array_key_exists('start_time', $value['ReservationLocation']) &&
+ array_key_exists('end_time', $value['ReservationLocation']) &&
+ array_key_exists('timezone', $value['ReservationLocation'])) {
+ $reservationLocations[$key]['ReservationLocation']['openText'] = $this->openText($value);
+ }
+ }
+ return $reservationLocations;
+ }
}
\ No newline at end of file
diff --git a/Locale/jpn/LC_MESSAGES/reservations.po b/Locale/jpn/LC_MESSAGES/reservations.po
index d7a3c9d..72387a5 100644
--- a/Locale/jpn/LC_MESSAGES/reservations.po
+++ b/Locale/jpn/LC_MESSAGES/reservations.po
@@ -1413,7 +1413,7 @@ msgid "To see details of import file item settings, please see below.
"
msgstr "インポートファイルへの設定項目の詳細は、下記を参照ください。
"
"なお、各項目を無指定とする場合、空白の代わりに文字列「null」を設定してください。
"
"また、無指定(「null」指定)または指定外の設定をした場合、未設定 とします。"
-
+
msgid "-- not specified --"
msgstr "-- 指定しない --"
@@ -1421,4 +1421,8 @@ msgid "Location not found in select category."
msgstr "選択したカテゴリに登録されている施設はありません。"
msgid "No locations are available."
-msgstr "予約可能な施設がありません。"
\ No newline at end of file
+msgstr "予約可能な施設がありません。"
+
+msgid "Invalid input location"
+msgstr "施設を選択してください。"
+
diff --git a/Model/Behavior/ReservationAppBehavior.php b/Model/Behavior/ReservationAppBehavior.php
index 169cd01..1e180ef 100644
--- a/Model/Behavior/ReservationAppBehavior.php
+++ b/Model/Behavior/ReservationAppBehavior.php
@@ -175,7 +175,7 @@ public function insert(Model $model, $planParams, $rruleData, $eventData, $start
if ($model->ReservationEvent->id > 0 && $createdUserWhenUpd !== null) {
//saveが成功し、かつ、createdUserWhenUpd がnull以外なら、created_userを更新しておく。
//modifiedも更新されるが、saveの直後なので誤差の範囲として了とする。
- $model->ReservationEvent->saveField('created_user', $createdUserWhenUpd);
+ $model->ReservationEvent->saveField('created_user', $createdUserWhenUpd, ['callbacks' => false]);
//UPDATEでセットしたcreatedUserWhenUpdの値をeventDataに記録しておく
$rEventData['ReservationEvent']['created_user'] = $createdUserWhenUpd;
}
diff --git a/Model/Behavior/ReservationInsertPlanBehavior.php b/Model/Behavior/ReservationInsertPlanBehavior.php
index e6122a8..dd4faf2 100644
--- a/Model/Behavior/ReservationInsertPlanBehavior.php
+++ b/Model/Behavior/ReservationInsertPlanBehavior.php
@@ -165,7 +165,7 @@ public function insertEventData(Model $model, $planParams, $rruleData,
if ($model->ReservationEvent->id > 0 && $createdUserWhenUpd !== null) {
//saveが成功し、かつ、createdUserWhenUpd がnull以外なら、created_userを更新しておく。
//modifiedも更新されるが、saveの直後なので誤差の範囲として了とする。
- $model->ReservationEvent->saveField('created_user', $createdUserWhenUpd);
+ $model->ReservationEvent->saveField('created_user', $createdUserWhenUpd, ['callbacks' => false]);
//UPDATEでセットしたcreatedUserWhenUpdの値をeventDataに記録しておく
$eventData['ReservationEvent']['created_user'] = $createdUserWhenUpd;
}
diff --git a/Model/Behavior/ReservationMailQueueBehavior.php b/Model/Behavior/ReservationMailQueueBehavior.php
index 7c35021..60f4177 100644
--- a/Model/Behavior/ReservationMailQueueBehavior.php
+++ b/Model/Behavior/ReservationMailQueueBehavior.php
@@ -23,10 +23,11 @@ class ReservationMailQueueBehavior extends MailQueueBehavior {
* @param Model $model モデル
* @param array $sendTimes メール送信日時 配列
* @param string $typeKey メールの種類
+ * @param string $sendRoomPermission 送信するルームの役割。ルームでないときは無視される
* @return void
*/
public function saveQueue(Model $model, $sendTimes = null,
- $typeKey = MailSettingFixedPhrase::DEFAULT_TYPE) {
+ $typeKey = MailSettingFixedPhrase::DEFAULT_TYPE, $sendRoomPermission = null) {
$model->Behaviors->load('Mails.IsMailSend', $this->settings[$model->alias]);
$languageId = Current::read('Language.id');
@@ -48,8 +49,11 @@ public function saveQueue(Model $model, $sendTimes = null,
// --- ワークフローのstatusによって送信内容を変える
// 各プラグインが承認機能=ONかどうかは、気にしなくてOK。承認機能=OFFなら status=公開が飛んでくるため。
- // 承認依頼通知, 差戻し通知, 承認完了通知メール(即時)
- $this->_saveQueueNoticeMail($model, $languageId, $typeKey);
+ //承認ワークフローを使うときのみ承認関連のメールは送らない
+ if ($model->data['ReservationLocation']['use_workflow']) {
+ // 承認依頼通知, 差戻し通知, 承認完了通知メール(即時)
+ $this->_saveQueueNoticeMail($model, $languageId, $typeKey);
+ }
$mailSettingPlugin = $this->__getMailSettingPlugin($model, $languageId, $typeKey);
$isMailSend = Hash::get($mailSettingPlugin, 'MailSetting.is_mail_send');
diff --git a/Model/Behavior/ReservationPlanGenerationBehavior.php b/Model/Behavior/ReservationPlanGenerationBehavior.php
index 730a9eb..2b08ed8 100644
--- a/Model/Behavior/ReservationPlanGenerationBehavior.php
+++ b/Model/Behavior/ReservationPlanGenerationBehavior.php
@@ -69,18 +69,22 @@ public function makeCurGenPlan(Model $model, $data,
* @param string $status status 変更時の施設予約独自の新status
* @param int $createdUserWhenUpd createdUserWhenUpd
* @param bool $isMyPrivateRoom isMyPrivateRoom
+ * @param string|int $editRrule 編集ルール(この予約のみ、これ以降に指定した全ての予約、設定した全ての予約)
* @return int 生成成功時 新しく生成した次世代予定($plan)を返す。失敗時 InternalErrorExceptionを投げる。
* @throws InternalErrorException
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function makeNewGenPlan(Model $model, $data, $status,
- $createdUserWhenUpd, $isMyPrivateRoom) {
+ $createdUserWhenUpd, $isMyPrivateRoom, $editRrule) {
$action = 'update';
$plan = $this->__makeCommonGenPlan($model, $action, $data,
$data['ReservationActionPlan']['origin_rrule_id']);
//keyが同じrrule -> key同一のevents -> eventsの各子供をcopy保存する
- $plan = $this->__copyRruleData($model, $plan, $createdUserWhenUpd);
+ $plan = $this->__copyRruleData($model, $plan, $createdUserWhenUpd, $editRrule);
+
+ $baseDate = str_replace('-', '', $data['ReservationActionPlanForDisp']['detail_start_datetime']);
unset($plan['new_event_id']); //念のため変数クリア
$effectiveEvents = array(); //有効なeventだけを格納する配列を用意
@@ -90,6 +94,17 @@ public function makeNewGenPlan(Model $model, $data, $status,
if ($event['exception_event_id'] >= 1) {
continue;
}
+ if ($editRrule == self::CALENDAR_PLAN_EDIT_THIS &&
+ $data['ReservationActionPlan']['origin_event_id'] != $event['id']) {
+ //この予約のみの場合、自分自身の予約以外は無視する。
+ continue;
+ }
+ if ($editRrule == self::CALENDAR_PLAN_EDIT_AFTER &&
+ $data['ReservationActionPlan']['origin_event_id'] != $event['id'] &&
+ $baseDate > $event['start_date']) {
+ //これ以降に指定した全ての予約の場合、基準日より過去のものは無視する。
+ continue;
+ }
$newEventId = $newEventKey = null;
list($event, $newEventId, $newEventKey) = $this->__copyEventData($model,
@@ -123,10 +138,11 @@ public function makeNewGenPlan(Model $model, $data, $status,
* @param Model $model 実際のモデル名
* @param array $plan plan
* @param int $createdUserWhenUpd createdUserWhenUpd
+ * @param string|int $editRrule 編集ルール(この予約のみ、これ以降に指定した全ての予約、設定した全ての予約)
* @return int 生成成功時 新しい$planを返す。失敗時 InternalErrorExceptionを投げる。
* @throws InternalErrorException
*/
- private function __copyRruleData(Model $model, $plan, $createdUserWhenUpd) {
+ private function __copyRruleData(Model $model, $plan, $createdUserWhenUpd, $editRrule) {
//ReservationRruleには、status, is_latest, is_activeはない。
$rruleData = array();
@@ -135,6 +151,9 @@ private function __copyRruleData(Model $model, $plan, $createdUserWhenUpd) {
//次世代データの新規登録
$originRruleId = $rruleData['ReservationRrule']['id'];
$rruleData['ReservationRrule']['id'] = null;
+ if ($editRrule == self::CALENDAR_PLAN_EDIT_THIS) {
+ $rruleData['ReservationRrule']['rrule'] = '';
+ }
//作成者・作成日は原則、元予定のデータを引き継ぐ、、、が!例外がある。
//例外追加1)
@@ -249,6 +268,8 @@ private function __copyEventData(Model $model, $event, $reservationRruleId, $sta
//セットするようにした。
$model->ReservationEvent->prepareLatestCreatedForIns($eventData, $createdUserWhenUpd);
+ // $eventDataがprepareLatestCreatedForIns()で変更されるので、再度setする
+ $model->ReservationEvent->set($eventData);
//子もsave()で返ってくる。
$eventData = $model->ReservationEvent->save(null, false); //aaaaaaaaaaaaa
if (!$eventData) { //保存のみ
diff --git a/Model/Behavior/ReservationUpdatePlanBehavior.php b/Model/Behavior/ReservationUpdatePlanBehavior.php
index 1abe057..d9e9b53 100644
--- a/Model/Behavior/ReservationUpdatePlanBehavior.php
+++ b/Model/Behavior/ReservationUpdatePlanBehavior.php
@@ -398,6 +398,8 @@ public function updateDtstartData(Model $model, $planParams, $rruleData, $eventD
//is_active調整処理を行う。(eventDataの値が一部変更されます)
$model->ReservationEvent->prepareActiveForUpd($eventData);
+ // $eventDataがprepareActiveForUpd()で変更されるので、再度setする
+ $model->ReservationEvent->set($eventData);
if (!$model->ReservationEvent->save(null,
array(
'validate' => false,
diff --git a/Model/Behavior/ReservationWorkflowBehavior.php b/Model/Behavior/ReservationWorkflowBehavior.php
index e67df2d..9a15ea1 100644
--- a/Model/Behavior/ReservationWorkflowBehavior.php
+++ b/Model/Behavior/ReservationWorkflowBehavior.php
@@ -33,9 +33,16 @@ public function beforeValidate(Model $model, $options = array()) {
*
* @param Model $model Model using this behavior
* @param array $conditions Model::find conditions default value
+ * @param bool $useCommentCreatable コメントの作成権限でもチェックするかどうか
* @return array Conditions data
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
- public function getWorkflowConditions(Model $model, $conditions = array()) {
+ public function getWorkflowConditions(
+ Model $model,
+ $conditions = array(),
+ $useCommentCreatable = false
+ ) {
// is_active = 1は常に表示
$activeConditions = [
$model->alias . '.is_active' => true,
@@ -88,14 +95,21 @@ public function getWorkflowConditions(Model $model, $conditions = array()) {
* @param Model $model Model using this behavior
* @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
* @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)
+ * @param bool $useCommentCreatable コメントの作成権限でもチェックするかどうか
* @return array Conditions data
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
- public function getWorkflowContents(Model $model, $type, $query = array()) {
+ public function getWorkflowContents(
+ Model $model,
+ $type,
+ $query = array(),
+ $useCommentCreatable = false
+ ) {
//$this->log(var_export(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5), true), 'debug');
$query = Hash::merge(array(
'recursive' => -1,
- 'conditions' => $this->getWorkflowConditions($model)
+ 'conditions' => $this->getWorkflowConditions($model, [], $useCommentCreatable)
), $query);
return $model->find($type, $query);
diff --git a/Model/ReservationActionPlan.php b/Model/ReservationActionPlan.php
index a7d0210..72e05cc 100644
--- a/Model/ReservationActionPlan.php
+++ b/Model/ReservationActionPlan.php
@@ -466,6 +466,9 @@ public function validteUseLocationTimeRange($check) {
$locationKey,
Current::read('Language.id')
);
+ if (! $location) {
+ return false;
+ }
$reservableTimeTable = explode('|', $location['ReservationLocation']['time_table']);
$locationTimeZone = new DateTimeZone($location['ReservationLocation']['timezone']);
@@ -571,7 +574,7 @@ public function validteNotExistReservation($check) {
// 全ての予約を更新
$ignoreConditions = [
'NOT' => [
- 'ReservationEvent.rrule_id' =>
+ 'ReservationEvent.reservation_rrule_id' =>
Hash::get($this->data, 'ReservationActionPlan.origin_rrule_id'),
'ReservationEvent.recurrence_event_id !=' => 0,
'ReservationEvent.exception_event_id !=' => 0,
@@ -756,6 +759,9 @@ public function validateStatus($check) {
/** @var ReservationLocation $locationModel */
$locationModel = ClassRegistry::init('Reservations.ReservationLocation');
$location = $locationModel->getByKey($locationKey);
+ if (! $location) {
+ return false;
+ }
if ($location['ReservationLocation']['use_workflow']) {
// 承認必要
// 承認者か
@@ -904,9 +910,14 @@ public function saveReservationPlan($data, $procMode,
//3. isMyPrivateRoomは、変更後の公開ルームidが「編集者・承認者(=ログイン者)のプライベート」以外の場合、
//仲間の予定はプライベートの時のみ許される子情報なので、これらはcopy対象から外す(stripする)例外処理用。
//
- $newPlan = $this->makeNewGenPlan($data, $status, $createdUserWhenUpd, $isMyPrivateRoom);
-
$editRrule = $this->getEditRruleForUpdate($data);
+ $newPlan = $this->makeNewGenPlan(
+ $data,
+ $status,
+ $createdUserWhenUpd,
+ $isMyPrivateRoom,
+ $editRrule
+ );
$isInfoArray = array($isOriginRepeat, $isTimeMod, $isRepeatMod, $isMyPrivateRoom);
$eventId = $this->updatePlan($planParam, $newPlan, $status, $isInfoArray, $editRrule,
@@ -1082,7 +1093,6 @@ public function convertToPlanParamFormat($data) {
CakeLog::error($ex->getMessage());
throw($ex); //再throw
}
- CakeLog::debug(var_export($planParam, true));
return $planParam;
}
diff --git a/Model/ReservationLocation.php b/Model/ReservationLocation.php
index 180b309..9866a4e 100644
--- a/Model/ReservationLocation.php
+++ b/Model/ReservationLocation.php
@@ -188,32 +188,6 @@ public function beforeFind($query) {
return true;
}
-/**
- * Called after each find operation. Can be used to modify any results returned by find().
- * Return value should be the (modified) results.
- *
- * @param mixed $results The results of the find operation
- * @param bool $primary Whether this model is being queried directly (vs. being queried as an association)
- * @return mixed Result of the find operation
- * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
- * @link http://book.cakephp.org/2.0/en/models/callback-methods.html#afterfind
- */
- public function afterFind($results, $primary = false) {
- if (!isset($results[0][$this->alias])) {
- return $results;
- }
- foreach ($results as $key => $value) {
- if (array_key_exists('time_table', $results[$key][$this->alias]) &&
- array_key_exists('start_time', $results[$key][$this->alias]) &&
- array_key_exists('end_time', $results[$key][$this->alias]) &&
- array_key_exists('timezone', $results[$key][$this->alias])) {
- $openText = new ReservationLocationOpenText();
- $results[$key][$this->alias]['openText'] = $openText->openText($value);
- }
- }
- return $results;
- }
-
/**
* Called before each save operation, after validation. Return a non-true result
* to halt the save.
@@ -662,6 +636,19 @@ protected function _prepareData($data) {
return $data;
}
+/**
+ * カテゴリーをセットしていない施設件数を取得する
+ *
+ * @return int
+ */
+ public function getCountUnselectedCategory() {
+ $count = $this->find('count', [
+ 'conditions' => ['category_id' => null],
+ ]);
+
+ return $count;
+ }
+
/**
* getAliveCondition
* 現在使用中状態であるか判断する。CleanUpプラグインで使用
diff --git a/Policy/ReservationEventPermissionPolicy.php b/Policy/ReservationEventPermissionPolicy.php
index a428ae9..a325b23 100644
--- a/Policy/ReservationEventPermissionPolicy.php
+++ b/Policy/ReservationEventPermissionPolicy.php
@@ -31,6 +31,11 @@ class ReservationEventPermissionPolicy {
*/
protected $_readableRoomIds = [];
+/**
+ * @var ReservationLocationReservable ReadableLocationReservable model
+ */
+ private $__reservationLocationReservable;
+
/**
* ReservationEventPermissionPolicy constructor.
*
@@ -38,6 +43,9 @@ class ReservationEventPermissionPolicy {
*/
public function __construct($event) {
$this->_event = $event;
+ $this->__reservationLocationReservable = ClassRegistry::init(
+ 'Reservations.ReservationLocationReservable'
+ );
}
/**
@@ -48,19 +56,24 @@ public function __construct($event) {
*/
public function canEdit($userId) {
$data = $this->_event;
+ $location = $this->_getLocationByKey($data['ReservationEvent']['location_key']);
if ($userId == $data['ReservationEvent']['created_user']) {
- // 自分の予約は無条件に編集可能
- return true;
+ // 予約権限があれば編集可
+ return $this->__reservationLocationReservable->isReservableByLocation($location);
} else {
// 他の人の予約
- // block_permission_editable なら見られる
- if (Current::read('Room.space_id') != Space::PRIVATE_SPACE_ID) {
- if (Current::read('Permission.block_permission_editable.value')) {
- return true;
- }
+ // ルーム管理者なら編集可能にしていたが、システム管理者、サイト管理者のみ編集可能にする。
+ // サイト管理を使えるユーザなら編集可能。
+ if (Current::allowSystemPlugin('site_manager')) {
+ return true;
}
+ //// block_permission_editable なら見られる
+ //if (Current::read('Room.space_id') != Space::PRIVATE_SPACE_ID) {
+ // if (Current::read('Permission.block_permission_editable.value')) {
+ // return true;
+ // }
+ //}
- $location = $this->_getLocationByKey($data['ReservationEvent']['location_key']);
$approvalUserIds = $location['approvalUserIds'];
if (in_array($userId, $approvalUserIds)) {
diff --git a/README.md b/README.md
index 50972fa..0723cb7 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,6 @@
Reservations
=========
-Reservations for NetCommons3
-[](https://travis-ci.org/NetCommons3/Reservations)
-[](https://coveralls.io/r/NetCommons3/Reservations?branch=master)
-
-| dependencies | status |
-| ------------ | ------ |
-| composer.json | [](https://www.versioneye.com/user/projects/58c97427e054530016372010) |
+[](https://github.com/NetCommons3/Reservations/actions/workflows/tests.yml)
+[](https://coveralls.io/r/NetCommons3/Reservations?branch=master)
+[](https://packagist.org/packages/netcommons/reservations)
diff --git a/VERSION.txt b/VERSION.txt
index 619b537..86fb650 100644
--- a/VERSION.txt
+++ b/VERSION.txt
@@ -1 +1 @@
-3.3.3
+3.3.7
diff --git a/View/Elements/ReservationPlans/detail_edit_datetime.ctp b/View/Elements/ReservationPlans/detail_edit_datetime.ctp
index 83681d2..0cba784 100644
--- a/View/Elements/ReservationPlans/detail_edit_datetime.ctp
+++ b/View/Elements/ReservationPlans/detail_edit_datetime.ctp
@@ -20,7 +20,7 @@
なんとなれば、ng-initの操作によるパラメータ設定が日時を先にしないとデフォルトの設定にならないから
*/ ?>
-
'; diff --git a/View/Helper/ReservationWeeklyTimelineHelper.php b/View/Helper/ReservationWeeklyTimelineHelper.php index 1b877ab..7319de0 100644 --- a/View/Helper/ReservationWeeklyTimelineHelper.php +++ b/View/Helper/ReservationWeeklyTimelineHelper.php @@ -47,6 +47,15 @@ public function getTimelineData() { return $this->_timelineData; } +/** + * TimelineDataをクリア + * + * @return array + */ + public function clearTimelineData() { + $this->_timelineData = []; + } + /** * getPlanSummariesHtml * diff --git a/View/ReservationImport/edit.ctp b/View/ReservationImport/edit.ctp index d3b6050..896b861 100644 --- a/View/ReservationImport/edit.ctp +++ b/View/ReservationImport/edit.ctp @@ -150,7 +150,6 @@ echo $this->element('Reservations.scripts'); ] ); ?> - NetCommonsForm->input( @@ -202,7 +201,7 @@ echo $this->element('Reservations.scripts');
ReservationCategory->getCategoryName($vars, $event); ?>
-DisplayUser->handleLink($event, array('avatar' => true)); ?>
-toUserDatetime($event['ReservationEvent']['modified'])); ?>
-