889a9c1a657f91baafd209977b2304b1b23a41d7
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2015
35 * This class contains the functions for Case Type management.
37 class CRM_Case_BAO_CaseType
extends CRM_Case_DAO_CaseType
{
40 * Static field for all the case information that we can potentially export.
44 static $_exportableFields = NULL;
47 * Takes an associative array and creates a Case Type object.
49 * the function extract all the params it needs to initialize the create a
50 * case type object. the params array could contain additional unused name/value
53 * @param array $params
54 * (reference ) an assoc array of name/value pairs.
56 * @throws CRM_Core_Exception
58 * @return CRM_Case_BAO_CaseType
60 public static function add(&$params) {
61 $caseTypeDAO = new CRM_Case_DAO_CaseType();
63 // form the name only if missing: CRM-627
64 $nameParam = CRM_Utils_Array
::value('name', $params, NULL);
65 if (!$nameParam && empty($params['id'])) {
66 $params['name'] = CRM_Utils_String
::titleToVar($params['title']);
69 // Old case-types (pre-4.5) may keep their ucky names, but new case-types must satisfy isValidName()
70 if (empty($params['id']) && !empty($params['name']) && !CRM_Case_BAO_CaseType
::isValidName($params['name'])) {
71 throw new CRM_Core_Exception("Cannot create new case-type with malformed name [{$params['name']}]");
74 $caseTypeName = (isset($params['name'])) ?
$params['name'] : CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_CaseType', $params['id'], 'name', 'id', TRUE);
76 // function to format definition column
77 if (isset($params['definition']) && is_array($params['definition'])) {
78 $params['definition'] = self
::convertDefinitionToXML($caseTypeName, $params['definition']);
79 CRM_Core_ManagedEntities
::scheduleReconciliation();
82 $caseTypeDAO->copyValues($params);
83 return $caseTypeDAO->save();
87 * Generate and assign an arbitrary value to a field of a test object.
89 * @param string $fieldName
90 * @param array $fieldDef
92 * The globally-unique ID of the test object.
94 protected function assignTestValue($fieldName, &$fieldDef, $counter) {
95 if ($fieldName == 'definition') {
96 $this->{$fieldName} = "<CaseType><name>TestCaseType{$counter}</name></CaseType>";
99 parent
::assignTestValue($fieldName, $fieldDef, $counter);
105 * Format / convert submitted array to xml for case type definition
107 * @param string $name
108 * @param array $definition
109 * The case-type definition expressed as an array-tree.
113 public static function convertDefinitionToXML($name, $definition) {
114 $xmlFile = '<?xml version="1.0" encoding="utf-8" ?>' . "\n\n<CaseType>\n";
115 $xmlFile .= "<name>" . self
::encodeXmlString($name) . "</name>\n";
117 if (array_key_exists('forkable', $definition)) {
118 $xmlFile .= "<forkable>" . ((int) $definition['forkable']) . "</forkable>\n";
121 if (isset($definition['activityTypes'])) {
122 $xmlFile .= "<ActivityTypes>\n";
123 foreach ($definition['activityTypes'] as $values) {
124 $xmlFile .= "<ActivityType>\n";
125 foreach ($values as $key => $value) {
126 $xmlFile .= "<{$key}>" . self
::encodeXmlString($value) . "</{$key}>\n";
128 $xmlFile .= "</ActivityType>\n";
130 $xmlFile .= "</ActivityTypes>\n";
133 if (isset($definition['activitySets'])) {
134 $xmlFile .= "<ActivitySets>\n";
135 foreach ($definition['activitySets'] as $k => $val) {
136 $xmlFile .= "<ActivitySet>\n";
137 foreach ($val as $index => $setVal) {
139 case 'activityTypes':
140 if (!empty($setVal)) {
141 $xmlFile .= "<ActivityTypes>\n";
142 foreach ($setVal as $values) {
143 $xmlFile .= "<ActivityType>\n";
144 foreach ($values as $key => $value) {
145 $xmlFile .= "<{$key}>" . self
::encodeXmlString($value) . "</{$key}>\n";
147 $xmlFile .= "</ActivityType>\n";
149 $xmlFile .= "</ActivityTypes>\n";
153 case 'sequence': // passthrough
156 $xmlFile .= "<{$index}>true</{$index}>\n";
161 $xmlFile .= "<{$index}>" . self
::encodeXmlString($setVal) . "</{$index}>\n";
165 $xmlFile .= "</ActivitySet>\n";
168 $xmlFile .= "</ActivitySets>\n";
171 if (isset($definition['caseRoles'])) {
172 $xmlFile .= "<CaseRoles>\n";
173 foreach ($definition['caseRoles'] as $values) {
174 $xmlFile .= "<RelationshipType>\n";
175 foreach ($values as $key => $value) {
176 $xmlFile .= "<{$key}>" . self
::encodeXmlString($value) . "</{$key}>\n";
178 $xmlFile .= "</RelationshipType>\n";
180 $xmlFile .= "</CaseRoles>\n";
183 $xmlFile .= '</CaseType>';
188 * Ugh. This shouldn't exist. Use a real XML-encoder.
190 * Escape a string for use in XML.
193 * A string which should outputted to XML.
197 protected static function encodeXmlString($str) {
198 // PHP 5.4: return htmlspecialchars($str, ENT_XML1, 'UTF-8')
199 return htmlspecialchars($str);
203 * Get the case definition either from db or read from xml file.
205 * @param SimpleXmlElement $xml
206 * A single case-type record.
209 * the definition of the case-type, expressed as PHP array-tree
211 public static function convertXmlToDefinition($xml) {
212 // build PHP array based on definition
213 $definition = array();
215 if (isset($xml->forkable
)) {
216 $definition['forkable'] = (int) $xml->forkable
;
219 // set activity types
220 if (isset($xml->ActivityTypes
)) {
221 $definition['activityTypes'] = array();
222 foreach ($xml->ActivityTypes
->ActivityType
as $activityTypeXML) {
223 $definition['activityTypes'][] = json_decode(json_encode($activityTypeXML), TRUE);
228 if (isset($xml->ActivitySets
)) {
229 $definition['activitySets'] = array();
230 foreach ($xml->ActivitySets
->ActivitySet
as $activitySetXML) {
231 // parse basic properties
232 $activitySet = array();
233 $activitySet['name'] = (string) $activitySetXML->name
;
234 $activitySet['label'] = (string) $activitySetXML->label
;
235 if ('true' == (string) $activitySetXML->timeline
) {
236 $activitySet['timeline'] = 1;
238 if ('true' == (string) $activitySetXML->sequence
) {
239 $activitySet['sequence'] = 1;
242 if (isset($activitySetXML->ActivityTypes
)) {
243 $activitySet['activityTypes'] = array();
244 foreach ($activitySetXML->ActivityTypes
->ActivityType
as $activityTypeXML) {
245 $activitySet['activityTypes'][] = json_decode(json_encode($activityTypeXML), TRUE);
248 $definition['activitySets'][] = $activitySet;
253 if (isset($xml->CaseRoles
)) {
254 $definition['caseRoles'] = array();
255 foreach ($xml->CaseRoles
->RelationshipType
as $caseRoleXml) {
256 $definition['caseRoles'][] = json_decode(json_encode($caseRoleXml), TRUE);
264 * Given the list of params in the params array, fetch the object
265 * and store the values in the values array
267 * @param array $params
268 * Input parameters to find object.
269 * @param array $values
270 * Output values of the object.
272 * @return CRM_Case_BAO_CaseType|null the found object or null
274 public static function &getValues(&$params, &$values) {
275 $caseType = new CRM_Case_BAO_CaseType();
277 $caseType->copyValues($params);
279 if ($caseType->find(TRUE)) {
280 CRM_Core_DAO
::storeValues($caseType, $values);
287 * Takes an associative array and creates a case type object.
289 * @param array $params
290 * (reference ) an assoc array of name/value pairs.
292 * @return CRM_Case_BAO_CaseType
294 public static function &create(&$params) {
295 $transaction = new CRM_Core_Transaction();
297 if (!empty($params['id'])) {
298 CRM_Utils_Hook
::pre('edit', 'CaseType', $params['id'], $params);
301 CRM_Utils_Hook
::pre('create', 'CaseType', NULL, $params);
304 $caseType = self
::add($params);
306 if (is_a($caseType, 'CRM_Core_Error')) {
307 $transaction->rollback();
311 if (!empty($params['id'])) {
312 CRM_Utils_Hook
::post('edit', 'CaseType', $caseType->id
, $case);
315 CRM_Utils_Hook
::post('create', 'CaseType', $caseType->id
, $case);
317 $transaction->commit();
318 CRM_Case_XMLRepository
::singleton(TRUE);
324 * Retrieve DB object based on input parameters.
326 * It also stores all the retrieved values in the default array.
328 * @param array $params
329 * (reference ) an assoc array of name/value pairs.
330 * @param array $defaults
331 * (reference ) an assoc array to hold the name / value pairs.
332 * in a hierarchical manner
334 * @return CRM_Case_BAO_CaseType
336 public static function retrieve(&$params, &$defaults) {
337 $caseType = CRM_Case_BAO_CaseType
::getValues($params, $defaults);
342 * @param int $caseTypeId
344 * @throws CRM_Core_Exception
347 public static function del($caseTypeId) {
348 $caseType = new CRM_Case_DAO_CaseType();
349 $caseType->id
= $caseTypeId;
350 $refCounts = $caseType->getReferenceCounts();
351 $total = array_sum(CRM_Utils_Array
::collect('count', $refCounts));
353 throw new CRM_Core_Exception(ts("You can not delete this case type -- it is assigned to %1 existing case record(s). If you do not want this case type to be used going forward, consider disabling it instead.", array(1 => $total)));
355 $result = $caseType->delete();
356 CRM_Case_XMLRepository
::singleton(TRUE);
361 * Determine if a case-type name is well-formed
363 * @param string $caseType
366 public static function isValidName($caseType) {
367 return preg_match('/^[a-zA-Z0-9_]+$/', $caseType);
371 * Determine if the case-type has *both* DB and file-based definitions.
373 * @param int $caseTypeId
375 * TRUE if there are *both* DB and file-based definitions
377 public static function isForked($caseTypeId) {
378 $caseTypeName = CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_CaseType', $caseTypeId, 'name', 'id', TRUE);
380 $dbDefinition = CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_CaseType', $caseTypeId, 'definition', 'id', TRUE);
381 $fileDefinition = CRM_Case_XMLRepository
::singleton()->retrieveFile($caseTypeName);
382 return $fileDefinition && $dbDefinition;
388 * Determine if modifications are allowed on the case-type
390 * @param int $caseTypeId
392 * TRUE if the definition can be modified
394 public static function isForkable($caseTypeId) {
395 $caseTypeName = CRM_Core_DAO
::getFieldValue('CRM_Case_DAO_CaseType', $caseTypeId, 'name', 'id', TRUE);
397 // if file-based definition explicitly disables "forkable" option, then don't allow changes to definition
398 $fileDefinition = CRM_Case_XMLRepository
::singleton()->retrieveFile($caseTypeName);
399 if ($fileDefinition && isset($fileDefinition->forkable
)) {
400 return CRM_Utils_String
::strtobool((string) $fileDefinition->forkable
);