Created
April 13, 2015 20:38
-
-
Save raoul2000/b93e478124e45fd4a58d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// the model ///////////////////////////////////////////////////////////////////// | |
class Post extends \yii\db\ActiveRecord | |
{ | |
/** | |
* @inheritdoc | |
*/ | |
public static function tableName() | |
{ | |
return 'item'; | |
} | |
/** | |
* @inheritdoc | |
*/ | |
public function rules() | |
{ | |
return [ | |
// The RelatedWorkflowValidator is in charge of validating status_ex transition | |
// depending on transition occuring on the primary workflow (status attribute) | |
['status_ex',RelatedWorkflowValidator::className()], | |
]; | |
} | |
/** | |
* (non-PHPdoc) | |
* @see \yii\base\Component::behaviors() | |
*/ | |
public function behaviors() | |
{ | |
return [ | |
// Primary workflow | |
'w1' =>[ | |
'class' => \raoul2000\workflow\base\SimpleWorkflowBehavior::className(), | |
'statusAttribute' => 'status', | |
'defaultWorkflowId' => 'PostWorkflow1' | |
], | |
// Secondary workflow | |
'w2' => [ | |
'class' => \raoul2000\workflow\base\SimpleWorkflowBehavior::className(), | |
'statusAttribute' => 'status_ex', | |
'defaultWorkflowId' => 'PostWorkflow2' | |
] | |
]; | |
} | |
} | |
// PostWorkflow1 definition ///////////////////////////////////////////////////////////////////// | |
class PostWorkflow1 implements IWorkflowDefinitionProvider | |
{ | |
public function getDefinition() { | |
return [ | |
'initialStatusId' => 'draft', | |
'status' => [ | |
'draft' => [ | |
'transition' => ['correction'] | |
], | |
'correction' => [ | |
'transition' => ['draft','ready'] | |
], | |
'ready' => [ | |
'transition' => ['draft', 'correction', 'published'] | |
], | |
'published' => [ | |
'transition' => ['ready', 'archived'] | |
], | |
'archived' => [ | |
'transition' => ['ready'] | |
] | |
] | |
]; | |
} | |
} | |
// PostWorkflow2 definition ///////////////////////////////////////////////////////////////////// | |
class PostWorkflow2 implements IWorkflowDefinitionProvider | |
{ | |
public function getDefinition() { | |
return [ | |
'initialStatusId' => 'success', | |
'status' => [ | |
'success' => [ | |
'transition' => ['onHold'] | |
], | |
'onHold' => [ | |
'transition' => ['success'] | |
], | |
] | |
]; | |
} | |
} | |
// The Standalone Validator class ///////////////////////////////////////////////////////////////////// | |
use yii\validators\Validator; | |
use raoul2000\workflow\validation\WorkflowScenario; | |
class RelatedWorkflowValidator extends Validator | |
{ | |
private $constraint; | |
/** | |
* Set constraint array where keys are scenario for the secondary workflow, and | |
* values are array of scenario for the primary workflow that allow secondary transition. | |
* If value is TRUE, the secondary transition is allowed. | |
* | |
* @see \yii\validators\Validator::init() | |
*/ | |
public function init() | |
{ | |
parent::init(); | |
$this->constraint = [ | |
// model can enter into secondary workflow no matter what is the primary workflow transition | |
WorkflowScenario::enterWorkflow('Post4Workflow2') => true, | |
WorkflowScenario::changeStatus('Post4Workflow2/success', 'Post4Workflow2/onHold') => [ | |
WorkflowScenario::changeStatus('Post4Workflow1/draft', 'Post4Workflow1/correction'), | |
WorkflowScenario::changeStatus('Post4Workflow1/ready', 'Post4Workflow1/draft') | |
], | |
WorkflowScenario::changeStatus('Post4Workflow2/onHold', 'Post4Workflow2/success') => [ | |
WorkflowScenario::changeStatus('Post4Workflow1/correction', 'Post4Workflow1/ready') | |
] | |
]; | |
} | |
/** | |
* Perform validation. | |
* WARNING : primary and secondary status attribute names are hard coded (to change if needed) | |
* | |
* @see \yii\validators\Validator::validateAttribute() | |
*/ | |
public function validateAttribute($model, $attribute) | |
{ | |
$w2scenarios=null; | |
$w1scenarios=null; | |
try { | |
list(,$w2scenarios) = $model->getBehavior('w2')->_createTransitionItems($model->status_ex, true, false); | |
if( $w2scenarios == null) { | |
return; // no pending transition for w2 : validation succeeds | |
} | |
} catch (Exception $e) { | |
$this->addError($attribute, 'invalid transition on secondary workflow'); | |
return; | |
} | |
try { | |
list(,$w1scenarios) = $model->getBehavior('w1')->_createTransitionItems($model->status, true, false); | |
} catch (Exception $e) { | |
$this->addError($attribute, 'invalid transition on primary workflow'); | |
return; | |
} | |
foreach ($w2scenarios as $w2sc) { | |
if (isset( $this->constraint[$w2sc])) { | |
if( $this->constraint[$w2sc] === true) { | |
return; | |
}elseif($w1scenarios === null && in_array($w1scenarios, $this->constraint[$w2sc])) { | |
return; | |
}else { | |
foreach ($w1scenarios as $w1sc) { | |
if( in_array($w1sc,$this->constraint[$w2sc])) { | |
return; | |
} | |
} | |
} | |
} | |
} | |
// the constraint array does not contain secondary AND related primary transition | |
// for the current model. | |
$msgInfo= implode(', ',$w2scenarios); | |
$this->addError($attribute, 'constraint failed : '. $msgInfo); | |
} | |
} | |
Do you know how to get defaultWorkflowId from controller ?
'w1' =>[
'class' => \raoul2000\workflow\base\SimpleWorkflowBehavior::className(),
'statusAttribute' => 'status',
'defaultWorkflowId' => 'PostWorkflow1'
],
I already got it , thank you , i'll update you soon
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you so much for your help , I'll test it now and see what I can do. I will update you soon