CRM-14798 - CRM_Case_XMLRepository - Don't double-munge the case-type name.
authortotten@civicrm.org <Tim Otten>
Fri, 27 Jun 2014 09:36:14 +0000 (02:36 -0700)
committertotten@civicrm.org <Tim Otten>
Tue, 1 Jul 2014 22:11:02 +0000 (15:11 -0700)
Prior to this commit, the naming for a case-type flowed more or less
like:

1. User makes up a display-name (title/label)
2. That title is munged via CRM_Utils_String::titleToVar to produce a machine-name
3. That machine-name is munged via CRM_Case_XMLProcessor::mungeCaseType to produce a file-name

As we begin allowing more varied dataflows for managing CaseType XML files
and CaseType DB records, it becomes more important for the naming behavior
to intuitive.

CRM/Case/BAO/CaseType.php
CRM/Case/XMLProcessor.php
CRM/Case/XMLRepository.php
tests/phpunit/api/v3/CaseTypeTest.php

index ae5daeeddc474e2a163dc28dac5ff0cfbe37b1f5..9e4ae0a80b41a5c0e4fdcbb906bb13230d1e858a 100644 (file)
@@ -70,6 +70,9 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType {
     if (!$nameParam && empty($params['id'])) {
       $params['name'] = CRM_Utils_String::titleToVar($params['title']);
     }
+    if (!empty($params['name']) && !CRM_Case_BAO_CaseType::isValidName($params['name'])) {
+      throw new CRM_Core_Exception("Cannot create caseType with malformed name [{$params['name']}]");
+    }
 
     // function to format definition column
     if (isset($params['definition']) && is_array($params['definition'])) {
@@ -309,4 +312,14 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType {
     $caseType->id = $caseTypeId;
     return $caseType->delete();
   }
+
+  /**
+   * Determine if a case-type name is well-formed
+   *
+   * @param string $caseType
+   * @return bool
+   */
+  static function isValidName($caseType) {
+    return preg_match('/^[a-zA-Z0-9_]+$/',  $caseType);
+  }
 }
index c83ed418642bea3771585cf918a950742131e032..49a63387352fa40fac07889f0be3907199acf9fa 100644 (file)
@@ -54,9 +54,23 @@ class CRM_Case_XMLProcessor {
   }
 
   /**
-   * @param $caseType
+   * This function was previously used to convert a case-type's
+   * machine-name to a file-name. However, it's mind-boggling
+   * that the file-name might be a munged version of the
+   * machine-name (which is itself a munged version of the
+   * display-name), and naming is now a more visible issue (since
+   * the overhaul of CaseType admin UI).
+   *
+   * Usage note: This is called externally by civix stubs as a
+   * sort of side-ways validation of the case-type's name
+   * (validation which was needed because of the unintuitive
+   * double-munge). We should update civix templates and then
+   * remove this function in Civi 4.6 or 5.0.
    *
-   * @return mixed|string
+   * @param string $caseType
+   * @return string
+   * @deprecated
+   * @see CRM_Case_BAO_CaseType::isValidName
    */
   public static function mungeCaseType($caseType) {
     // trim all spaces from $caseType
index 61a504b062ea0546c971a168e2fc95a4ab47bae5..e37ea6d0f5ed238504ec3e61f95e26868e681564 100644 (file)
@@ -84,7 +84,10 @@ class CRM_Case_XMLRepository {
       return simplexml_load_string($definition);
     }
 
-    $caseType = CRM_Case_XMLProcessor::mungeCaseType($caseType);
+    if (!CRM_Case_BAO_CaseType::isValidName($caseType)) {
+      // perhaps caller provider a the label instead of the name?
+      throw new CRM_Core_Exception("Cannot load caseType with malformed name [$caseType]");
+    }
 
     if (!CRM_Utils_Array::value($caseType, $this->xml)) {
       // first check custom templates directory
index 5a5a1597f0cfba9caf30a91748c071215260daab..432fa29d6bac55f478ccaa61e41f10548036ad3b 100644 (file)
@@ -102,6 +102,22 @@ class api_v3_CaseTypeTest extends CiviUnitTestCase {
     $this->assertEquals($result['values'][$id]['title'], $params['title'], 'in line ' . __LINE__);
   }
 
+  /**
+   * Create a case with an invalid name
+   */
+  function testCaseTypeCreate_invalidName() {
+    // Create Case Type
+    $params = array(
+      'title' => 'Application',
+      'name' => 'Appl ication', // spaces are not allowed
+      'is_active' => 1,
+      'weight' => 4,
+    );
+
+    $this->callAPIFailure('CaseType', 'create', $params);
+  }
+
+
   /**
    * Test update (create with id) function with valid parameters
    */