1: <?php
2: /*****************************************************************************************
3: * X2Engine Open Source Edition is a customer relationship management program developed by
4: * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
5: *
6: * This program is free software; you can redistribute it and/or modify it under
7: * the terms of the GNU Affero General Public License version 3 as published by the
8: * Free Software Foundation with the addition of the following permission added
9: * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10: * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
11: * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12: *
13: * This program is distributed in the hope that it will be useful, but WITHOUT
14: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15: * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16: * details.
17: *
18: * You should have received a copy of the GNU Affero General Public License along with
19: * this program; if not, see http://www.gnu.org/licenses or write to the Free
20: * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21: * 02110-1301 USA.
22: *
23: * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
24: * California 95067, USA. or at email address contact@x2engine.com.
25: *
26: * The interactive user interfaces in modified source and object code versions
27: * of this program must display Appropriate Legal Notices, as required under
28: * Section 5 of the GNU Affero General Public License version 3.
29: *
30: * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31: * these Appropriate Legal Notices must retain the display of the "Powered by
32: * X2Engine" logo. If the display of the logo is not reasonably feasible for
33: * technical reasons, the Appropriate Legal Notices must display the words
34: * "Powered by X2Engine".
35: *****************************************************************************************/
36:
37: /**
38: *
39: * @package application.components.x2flow
40: */
41: abstract class X2FlowAction extends X2FlowItem {
42:
43: public $trigger = null;
44:
45: /**
46: * Runs the automation action with provided params.
47: * @return boolean the result of the execution
48: */
49: abstract public function execute(&$params);
50:
51: public function paramRules () {
52: return array (
53: 'id' => null
54: );
55: }
56:
57: /**
58: * Checks if all the config variables and runtime params are ship-shape
59: * Ignores param requirements if $params isn't provided
60: * Returns an array with two elements. The first element indicates whether an error occured,
61: * the second contains a log message.
62: */
63: public function validate(&$params=array(), $flowId=null) {
64: $paramRules = $this->paramRules();
65: if(!isset($paramRules['options'],$this->config['options']))
66: return array (false, Yii::t('admin', "Flow item validation error"));
67:
68: if(isset($paramRules['modelRequired'])) {
69: if(!isset($params['model'])) // model not provided when required
70: return array (false, Yii::t('admin', "Flow item validation error"));
71: if($paramRules['modelRequired'] != 1 &&
72: $paramRules['modelRequired'] !== get_class($params['model'])) {
73:
74: // model is not the correct type
75: return array (false, Yii::t('admin', "Flow item validation error"));
76: }
77: }
78: return $this->validateOptions($paramRules);
79: }
80:
81: /**
82: * @return mixed either a string containing the notification type for this flow's trigger, or null
83: */
84: public function getNotifType() {
85: if($this->trigger !== null && !empty($this->trigger->notifType))
86: return $this->trigger->notifType;
87: return null;
88: }
89: /**
90: * @return mixed either a string containing the notification type for this flow's trigger, or null
91: */
92: public function getEventType() {
93: if($this->trigger !== null && !empty($this->trigger->eventType))
94: return $this->trigger->eventType;
95: return null;
96: }
97:
98: /**
99: * Sets model fields using the provided attributes and values.
100: *
101: * @param CActiveRecord $model the model to set fields on
102: * @param array $attributes an associative array of attributes
103: * @param array $params the params array passed to X2Flow::trigger()
104: * @return boolean whether or not the attributes were valid and set successfully
105: *
106: */
107: public function setModelAttributes(&$model,&$attributeList,&$params) {
108: $data = array ();
109: foreach($attributeList as &$attr) {
110: if(!isset($attr['name'],$attr['value']))
111: continue;
112:
113: if(null !== $field = $model->getField($attr['name'])) {
114: // first do variable/expression evaluation, // then process with X2Fields::parseValue()
115: $type = $field->type;
116: $value = $attr['value'];
117: if(is_string($value)){
118: if(strpos($value, '=') === 0){
119: $evald = X2FlowFormatter::parseFormula($value, $params);
120: if(!$evald[0])
121: return false;
122: $value = $evald[1];
123: } elseif($params !== null){
124:
125: if(is_string($value) && isset($params['model'])){
126: $value = X2FlowFormatter::replaceVariables(
127: $value, $params, $type);
128: }
129: }
130: }
131:
132: $data[$attr['name']] = $value;
133: }
134: }
135: if (!isset ($model->scenario))
136: $model->setScenario ('X2Flow');
137: $model->setX2Fields ($data);
138:
139: if ($model instanceof Actions && isset($data['complete'])) {
140: switch($data['complete']) {
141: case 'Yes':
142: $model->complete();
143: break;
144: case 'No':
145: $model->uncomplete();
146: break;
147: }
148: }
149:
150: return true;
151: }
152:
153: /**
154: * Gets all action types.
155: *
156: * Optionally limits actions to a list with a property matching a value.
157: * @param string $queryProperty The property of each action to test
158: * @param mixed $queryValue The value to match actions against
159: */
160: public static function getActionTypes($queryProperty=False,$queryValue=False) {
161: $types = array();
162: foreach(self::getActionInstances() as $class) {
163: $include = true;
164: if($queryProperty)
165: $include = $class->$queryProperty == $queryValue;
166: if($include)
167: $types[get_class($class)] = $class->title;
168: }
169: ksort($types);
170: return $types;
171: }
172:
173: public static function getActionInstances() {
174: return self::getInstances('actions',array(__CLASS__, 'BaseX2FlowWorkflowStageAction', 'BaseX2FlowEmail'));
175: }
176: }
177: