diff --git a/Model/BbsArticle.php b/Model/BbsArticle.php index a623896..86a6a54 100644 --- a/Model/BbsArticle.php +++ b/Model/BbsArticle.php @@ -54,7 +54,7 @@ class BbsArticle extends BbsesAppModel { 'Likes.Like', 'NetCommons.OriginalKey', 'Workflow.WorkflowComment', - 'Workflow.Workflow', + 'Bbses.BbsesWorkflow', 'Mails.MailQueue' => array( 'embedTags' => array( 'X-SUBJECT' => 'BbsArticle.title', diff --git a/Model/Behavior/BbsesWorkflowBehavior.php b/Model/Behavior/BbsesWorkflowBehavior.php new file mode 100644 index 0000000..fc45d2d --- /dev/null +++ b/Model/Behavior/BbsesWorkflowBehavior.php @@ -0,0 +1,62 @@ + + * @author Shohei Nakajima + * @link http://www.netcommons.org NetCommons Project + * @license http://www.netcommons.org/license.txt NetCommons License + * @copyright Copyright 2014, NetCommons Project + */ + +App::uses('WorkflowBehavior', 'Workflow.Model/Behavior'); + +/** + * Workflow Behavior + * + * @author Shohei Nakajima + * @package Bbses\Workflow\Model\Befavior + */ +class BbsesWorkflowBehavior extends WorkflowBehavior { + +/** + * beforeValidate is called before a model is validated, you can use this callback to + * add behavior validation rules into a models validate array. Returning false + * will allow you to make the validation fail. + * + * @param Model $model Model using this behavior + * @param array $options Options passed from Model::save(). + * @return mixed False or null will abort the operation. Any other result will continue. + * @see Model::save() + */ + public function beforeValidate(Model $model, $options = array()) { + if (empty($model->data['BbsArticleTree']['root_id'])) { + return parent::beforeValidate($model, $options); + } + + if (Current::permission('content_comment_publishable')) { + $statuses = WorkflowBehavior::$statuses; + } else { + $statuses = WorkflowBehavior::$statusesForEditor; + } + + $model->validate = ValidateMerge::merge($model->validate, array( + 'status' => array( + 'numeric' => array( + 'rule' => array('numeric'), + 'message' => __d('net_commons', 'Invalid request.'), + 'allowEmpty' => false, + 'required' => true, + 'on' => 'create', // Limit validation to 'create' or 'update' operations + ), + 'inList' => array( + 'rule' => array('inList', $statuses), + 'message' => __d('net_commons', 'Invalid request.'), + ) + ), + )); + + return true; + } + +} diff --git a/Test/Case/Controller/BbsArticlesController/ViewTest.php b/Test/Case/Controller/BbsArticlesController/ViewTest.php index f9a3843..bcaada4 100644 --- a/Test/Case/Controller/BbsArticlesController/ViewTest.php +++ b/Test/Case/Controller/BbsArticlesController/ViewTest.php @@ -288,11 +288,11 @@ public function dataProviderViewByEditable() { */ public function testViewError($urlOptions, $assert, $exception = null, $return = 'view') { //Exception - ClassRegistry::removeObject('WorkflowBehavior'); - $workflowBehaviorMock = $this->getMock('WorkflowBehavior', ['canReadWorkflowContent']); - ClassRegistry::addObject('WorkflowBehavior', $workflowBehaviorMock); - $this->BbsArticle->Behaviors->unload('Workflow'); - $this->BbsArticle->Behaviors->load('Workflow', $this->BbsArticle->actsAs['Workflow.Workflow']); + ClassRegistry::removeObject('BbsesWorkflowBehavior'); + $workflowBehaviorMock = $this->getMock('BbsesWorkflowBehavior', ['canReadWorkflowContent']); + ClassRegistry::addObject('BbsesWorkflowBehavior', $workflowBehaviorMock); + $this->BbsArticle->Behaviors->unload('BbsesWorkflow'); + $this->BbsArticle->Behaviors->load('BbsesWorkflow', $this->BbsArticle->actsAs['Bbses.BbsesWorkflow']); $workflowBehaviorMock ->expects($this->once()) diff --git a/Test/Case/Model/BbsArticle/SaveBbsArticleTest.php b/Test/Case/Model/BbsArticle/SaveBbsArticleTest.php index e2b1116..b789078 100644 --- a/Test/Case/Model/BbsArticle/SaveBbsArticleTest.php +++ b/Test/Case/Model/BbsArticle/SaveBbsArticleTest.php @@ -129,6 +129,8 @@ public function setUp() { Current::write('Language.id', '2'); parent::setUp(); + Current::writePermission('2', 'content_comment_publishable', true); + $model = $this->_modelName; $this->$model->Behaviors->unload('Like'); $this->$model->Behaviors->unload('Topics'); @@ -136,6 +138,42 @@ public function setUp() { $this->$model->BbsArticleTree->Behaviors->unload('Like'); } +/** + * Test to call BbsesWorkflowBehavior::beforeSave + * + * BbsesWorkflowBehaviorをモックに置き換えて登録処理を呼び出します。
+ * BbsesWorkflowBehavior::beforeSaveが1回呼び出されることをテストします。
+ * ##### 参考URL + * http://stackoverflow.com/questions/19833495/how-to-mock-a-cakephp-behavior-for-unit-testing] + * + * @param array $data 登録データ + * @dataProvider dataProviderSave + * @return void + * @throws CakeException Workflow.Workflowがロードされていないとエラー + */ + public function testCallWorkflowBehavior($data) { + $model = $this->_modelName; + $method = $this->_methodName; + + if (! $this->$model->Behaviors->loaded('Bbses.BbsesWorkflow')) { + $error = '"Workflow.Workflow" not loaded in ' . $this->$model->alias . '.'; + throw new CakeException($error); + } + + ClassRegistry::removeObject('BbsesWorkflowBehavior'); + $workflowBehaviorMock = $this->getMock('BbsesWorkflowBehavior', ['beforeSave']); + ClassRegistry::addObject('BbsesWorkflowBehavior', $workflowBehaviorMock); + $this->$model->Behaviors->unload('BbsesWorkflow'); + $this->$model->Behaviors->load('BbsesWorkflow', $this->$model->actsAs['Bbses.BbsesWorkflow']); + + $workflowBehaviorMock + ->expects($this->once()) + ->method('beforeSave') + ->will($this->returnValue(true)); + + $this->$model->$method($data); + } + /** * SaveのDataProvider * diff --git a/View/Elements/BbsArticles/edit_form.ctp b/View/Elements/BbsArticles/edit_form.ctp index a16b613..44905a4 100644 --- a/View/Elements/BbsArticles/edit_form.ctp +++ b/View/Elements/BbsArticles/edit_form.ctp @@ -51,17 +51,19 @@ params['action'] === 'edit' && $this->data['BbsArticleTree']['root_id']) { - echo $this->BbsesForm->replyEditButtons('BbsArticle.status'); - } else { + if ($this->params['action'] === 'edit' && $this->data['BbsArticleTree']['root_id'] || + $this->params['action'] === 'reply') { if ($this->params['action'] === 'reply') { - $key = isset($currentBbsArticle['BbsArticle']['key']) - ? $currentBbsArticle['BbsArticle']['key'] - : null; - $cancelUrl = NetCommonsUrl::blockUrl( - array('action' => 'view', 'key' => $key) - ); - } elseif ($this->params['action'] === 'edit') { + $key = $currentBbsArticle['BbsArticle']['key'] ?? null; + } else { + $key = $this->request->data['BbsArticle']['key'] ?? null; + } + $cancelUrl = NetCommonsUrl::blockUrl( + array('action' => 'view', 'key' => $key) + ); + echo $this->BbsesForm->replyButtons('BbsArticle.status', $cancelUrl); + } else { + if ($this->params['action'] === 'edit') { $key = isset($this->request->data['BbsArticle']['key']) ? $this->request->data['BbsArticle']['key'] : null; diff --git a/View/Helper/BbsesFormHelper.php b/View/Helper/BbsesFormHelper.php index 547d833..1a53439 100644 --- a/View/Helper/BbsesFormHelper.php +++ b/View/Helper/BbsesFormHelper.php @@ -38,9 +38,10 @@ class BbsesFormHelper extends AppHelper { * 返信フォームのボタン表示 * * @param string $statusFieldName ステータスのフィールド名("Modelname.fieldname") + * @param string $cancelUrl キャンセルボタン * @return string ボタンHTML */ - public function replyEditButtons($statusFieldName) { + public function replyButtons($statusFieldName, $cancelUrl) { $output = ''; $output .= '