-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathRegistrationAnswersController.php
More file actions
339 lines (314 loc) · 12 KB
/
RegistrationAnswersController.php
File metadata and controls
339 lines (314 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
<?php
/**
* RegistrationAnswers Controller
*
* @author Noriko Arai <arai@nii.ac.jp>
* @author Allcreator <info@allcreator.net>
* @link http://www.netcommons.org NetCommons Project
* @license http://www.netcommons.org/license.txt NetCommons License
* @copyright Copyright 2014, NetCommons Project
*/
App::uses('AppController', 'Controller');
/**
* RegistrationAnswersController
*
* @author Allcreator <info@allcreator.net>
* @package NetCommons\Registrations\Controller
*/
class RegistrationAnswersController extends RegistrationsAppController {
/**
* use model
*
* @var array
*/
public $uses = array(
'Registrations.RegistrationPage',
'Registrations.RegistrationAnswerSummary',
'Registrations.RegistrationAnswer',
);
/**
* use components
*
* @var array
*/
public $components = array(
'NetCommons.Permission',
'Registrations.Registrations',
'Registrations.RegistrationsOwnAnswer',
'AuthorizationKeys.AuthorizationKey' => array(
'operationType' => 'none',
'targetAction' => 'view',
'model' => 'Registration',
'contentId' => 0),
'VisualCaptcha.VisualCaptcha' => array(
'operationType' => 'none',
'targetAction' => 'view'),
);
/**
* use helpers
*
*/
public $helpers = [
'NetCommons.Date',
'Workflow.Workflow',
'Registrations.RegistrationAnswer'
];
/**
* target registration data
*
*/
private $__registration = null;
/**
* target isAbleToAnswer Action
*
*/
private $__ableToAnswerAction = ['view', 'confirm'];
/**
* beforeFilter
* NetCommonsお約束:できることならControllerのbeforeFilterで実行可/不可の判定して流れを変える
*
* @return void
*/
public function beforeFilter() {
// ゲストアクセスOKのアクションを設定
$this->Auth->allow('view', 'confirm', 'thanks', 'no_more_answer');
// 親クラスのbeforeFilterを済ませる
parent::beforeFilter();
// NetCommonsお約束:編集画面へのURLに編集対象のコンテンツキーが含まれている
// まずは、そのキーを取り出す
// 登録フォームキー
$registrationKey = $this->_getRegistrationKeyFromPass();
// キーで指定された登録フォームデータを取り出しておく
$conditions = $this->Registration->getBaseCondition(
array('Registration.key' => $registrationKey)
);
$this->__registration = $this->Registration->find('first', array(
'conditions' => $conditions,
));
if (! $this->__registration) {
// 単純に期間外のこともある
$this->setAction('emptyRender');
return;
$this->setAction('throwBadRequest');
return;
}
// 以下のisAbleto..の内部関数にてNetCommonsお約束である編集権限、参照権限チェックを済ませています
// 閲覧可能か
if (!$this->isAbleTo($this->__registration)) {
// 不可能な時は「登録できません」画面を出すだけ
$this->setAction('no_more_answer');
return;
}
if (in_array($this->action, $this->__ableToAnswerAction)) {
// 登録可能か
if (!$this->isAbleToAnswer($this->__registration)) {
// 登録が不可能な時は「登録できません」画面を出すだけ
$this->setAction('no_more_answer');
return;
}
}
// 登録の初めのページであることが各種認証行う条件
if (!$this->request->isPost() || !isset($this->request->data['RegistrationPage']['page_sequence'])) {
// 認証キーコンポーネントお約束:
// 取り出した登録フォームが認証キー確認を求めているなら、operationTypeをすり替える
if ($this->__registration['Registration']['is_key_pass_use'] == RegistrationsComponent::USES_USE) {
$this->AuthorizationKey->operationType = 'redirect';
$this->AuthorizationKey->contentId = $this->__registration['Registration']['id'];
}
// 画像認証コンポーネントお約束:
// 取り出した登録フォームが画像認証ありならば、operationTypeをすり替える
if ($this->__registration['Registration']['is_image_authentication'] == RegistrationsComponent::USES_USE) {
$this->VisualCaptcha->operationType = 'redirect';
}
}
}
/**
* test_mode
*
* テストモード登録のとき、一番最初に表示するページ
* 一覧表示画面で「テスト」ボタンがここへ誘導するようになっている。
* どのような登録フォームであるのかの各種属性設定をわかりやすくまとめて表示する表紙的な役割を果たす。
*
* あくまで作成者の便宜のために表示しているものであるので、最初のページだったら必ずここを表示といったような
* 強制的redirectなどは設定しない。なので強制URL-Hackしたらこの画面をスキップすることだって可能。
* 作成者への「便宜」のための親切心ページなのでスキップしたい人にはそうさせてあげるのでよいと考える。
*
* @return void
*/
public function test_mode() {
$status = $this->__registration['Registration']['status'];
// テストモード確認画面からのPOSTや、現在の登録フォームデータのステータスが公開状態の時
// 次へリダイレクト
if ($this->request->isPost() || $status == WorkflowComponent::STATUS_PUBLISHED) {
$this->redirect(NetCommonsUrl::actionUrl(array(
'controller' => 'registration_answers',
'action' => 'view',
Current::read('Block.id'),
$this->_getRegistrationKey($this->__registration),
'frame_id' => Current::read('Frame.id')
)));
return;
}
$this->request->data['Frame'] = Current::read('Frame');
$this->request->data['Block'] = Current::read('Block');
$this->set('registration', $this->__registration);
}
/**
* view method
* Display the question of the registration , to accept the answer input
*
* @return void
*/
public function view() {
$registration = $this->__registration;
$registrationKey = $this->_getRegistrationKey($this->__registration);
// 選択肢ランダム表示対応
$this->__shuffleChoice($registration);
// ページの指定のない場合はFIRST_PAGE_SEQUENCEをデフォルトとする
$nextPageSeq = RegistrationsComponent::FIRST_PAGE_SEQUENCE; // default
// POSTチェック
if ($this->request->isPost()) {
// 登録データがある場合は登録をDBに書きこむ
if (isset($this->data['RegistrationAnswer'])) {
$summary = $this->RegistrationsOwnAnswer->forceGetProgressiveAnswerSummary($this->__registration);
if (! $summary) {
// 保存エラーの場合は今のページを再表示
$nextPageSeq = $this->data['RegistrationPage']['page_sequence'];
} else {
if (! $this->RegistrationAnswer->saveAnswer($this->data, $registration, $summary)) {
// 保存エラーの場合は今のページを再表示
$nextPageSeq = $this->data['RegistrationPage']['page_sequence'];
} else {
// 登録データがあり、無事保存できたら次ページを取得する
$nextPageSeq = $this->RegistrationPage->getNextPage(
$registration,
$this->data['RegistrationPage']['page_sequence'],
$this->data['RegistrationAnswer']);
}
}
}
// 次ページはもう存在しない
if ($nextPageSeq === false) {
// 確認画面へ
$url = NetCommonsUrl::actionUrl(array(
'controller' => 'registration_answers',
'action' => 'confirm',
Current::read('Block.id'),
$registrationKey,
'frame_id' => Current::read('Frame.id'),
));
$this->redirect($url);
return;
}
}
if (! ($this->request->isPost() && $nextPageSeq == $this->data['RegistrationPage']['page_sequence'])) {
// 確認画面から戻ってきたときもDBからデータを取り出してる。
$summary = $this->RegistrationsOwnAnswer->getProgressiveSummaryOfThisUser($registrationKey);
//$summary = false;
$setAnswers = $this->RegistrationAnswer->getProgressiveAnswerOfThisSummary($summary);
$this->set('answers', $setAnswers);
$this->request->data['RegistrationAnswer'] = $setAnswers;
// 入力される登録データですがsetで設定するデータとして扱います
// 誠にCake流儀でなくて申し訳ないのですが、様々な種別のAnswerデータを
// 特殊な文字列加工して統一化した形状でDBに入れている都合上、このような仕儀になっています
} else {
$this->set('answers', $this->request->data['RegistrationAnswer']);
}
// 質問情報をView変数にセット
$this->request->data['Frame'] = Current::read('Frame');
$this->request->data['Block'] = Current::read('Block');
$this->request->data['RegistrationPage'] = $registration['RegistrationPage'][$nextPageSeq];
$this->set('registration', $registration);
$this->set('questionPage', $registration['RegistrationPage'][$nextPageSeq]);
$this->NetCommons->handleValidationError($this->RegistrationAnswer->validationErrors);
}
/**
* confirm method
*
* @return void
*/
public function confirm() {
// 解答入力画面で表示していたときのシャッフルを取り出す
$this->__shuffleChoice($this->__registration);
// 登録中サマリレコード取得
$summary = $this->RegistrationsOwnAnswer->getProgressiveSummaryOfThisUser(
$this->_getRegistrationKey($this->__registration));
if (!$summary) {
$this->setAction('throwBadRequest');
return;
}
// POSTチェック
if ($this->request->isPost()) {
// サマリの状態を完了にして確定する
$summary['RegistrationAnswerSummary']['answer_status'] = RegistrationsComponent::ACTION_ACT;
$summary['RegistrationAnswerSummary']['answer_time'] = (new NetCommonsTime())->getNowDatetime();
$this->RegistrationAnswerSummary->save($summary['RegistrationAnswerSummary']);
$this->RegistrationsOwnAnswer->saveOwnAnsweredKeys($this->_getRegistrationKey($this->__registration));
// ありがとう画面へ行く
$url = NetCommonsUrl::actionUrl(array(
'controller' => 'registration_answers',
'action' => 'thanks',
Current::read('Block.id'),
$this->_getRegistrationKey($this->__registration),
'frame_id' => Current::read('Frame.id'),
));
$this->redirect($url);
}
// 登録情報取得
// 登録情報並べ替え
$setAnswers = $this->RegistrationAnswer->getProgressiveAnswerOfThisSummary($summary);
// 質問情報をView変数にセット
$this->request->data['Frame'] = Current::read('Frame');
$this->request->data['Block'] = Current::read('Block');
$this->set('registration', $this->__registration);
$this->request->data['RegistrationAnswer'] = $setAnswers;
$this->set('answers', $setAnswers);
}
/**
* thanks method
*
* @return void
*/
public function thanks() {
// 後始末
// 登録中にたまっていたセッションキャッシュをクリア
$this->Session->delete('Registrations.' . $this->__registration['Registration']['key']);
// View変数にセット
$this->request->data['Frame'] = Current::read('Frame');
$this->request->data['Block'] = Current::read('Block');
$this->set('registration', $this->__registration);
$this->set('ownAnsweredKeys', $this->RegistrationsOwnAnswer->getOwnAnsweredKeys());
}
/**
* no_more_answer method
* 条件によって登録できない登録フォームにアクセスしたときに表示
*
* @return void
*/
public function no_more_answer() {
}
/**
* _shuffleChoice
* shuffled choices and write into session
*
* @param array &$registration 登録フォーム
* @return void
*/
private function __shuffleChoice(&$registration) {
foreach ($registration['RegistrationPage'] as &$page) {
foreach ($page['RegistrationQuestion'] as &$q) {
$choices = $q['RegistrationChoice'];
if ($q['is_choice_random'] == RegistrationsComponent::USES_USE) {
$sessionPath = 'Registrations.' . $registration['Registration']['key'] . '.RegistrationQuestion.' . $q['key'] . '.RegistrationChoice';
if ($this->Session->check($sessionPath)) {
$choices = $this->Session->read($sessionPath);
} else {
shuffle($choices);
$this->Session->write($sessionPath, $choices);
}
}
$q['RegistrationChoice'] = $choices;
}
}
}
}