CRM-16650 - Improve entityRef fields for shortcodes
authorColeman Watts <coleman@civicrm.org>
Wed, 10 Jun 2015 14:53:41 +0000 (10:53 -0400)
committerColeman Watts <coleman@civicrm.org>
Wed, 10 Jun 2015 16:47:54 +0000 (12:47 -0400)
----------------------------------------
* CRM-16650: Allow hooks to modify available shortcodes
  https://issues.civicrm.org/jira/browse/CRM-16650

CRM/Core/Form/ShortCode.php
CRM/UF/Page/Group.php
api/v3/ContributionPage.php
api/v3/Generic/Getlist.php
api/v3/Survey.php
api/v3/UFGroup.php

index 2f501072f2c6fbf28e8c4c676f08d7bcd8c0dc1c..97c5beccdbdc2268df72af7f4471fae761e975ee 100755 (executable)
  */
 class CRM_Core_Form_ShortCode extends CRM_Core_Form {
   /**
-   * List of entities supported by shortcodes, and their form properties
+   * List of entities supported by shortcodes, and their form properties.
+   *
+   * Keys should be the "component" string for the shortcode
+   * Values should be an array with label and select.
+   * Select can be NULL if there is no entity to select.
+   * Otherwise it contains the shortcode key for this entity id (usually 'id') plus an array of params for the EntityRef field
+   * @see CRM_Core_Form::addEntityRef
    *
    * @var array
+   *   [component => [
+   *     label => Option Label
+   *     select => key + EntityRef params
+   *   ]]
    */
   public $components = array();
 
   /**
-   * List of options to display on the form
+   * List of radio option groups to display on the form
+   *
+   * Control the conditional logic of showing/hiding each group via the "components" array.
+   * Or set 'components' => TRUE if it applies to all
    *
    * @var array
+   *   [key, components, options]
    */
   public $options = array();
 
 
   /**
-   * Build form data. Overridable via hook_civicrm_preProcess
+   * Build form data. Can be modified via hook_civicrm_preProcess
    *
    * @return void
    */
@@ -69,8 +83,13 @@ class CRM_Core_Form_ShortCode extends CRM_Core_Form {
       'label' => ts("Profile"),
       'select' => array(
         'key' => 'gid',
-        'entity' => 'Profile',
+        'entity' => 'UFGroup',
         'select' => array('minimumInputLength' => 0),
+        'api' => array(
+          'params' => array(
+            'id' => $this->profileAccess(),
+          ),
+        ),
       ),
     );
 
@@ -103,6 +122,11 @@ class CRM_Core_Form_ShortCode extends CRM_Core_Form {
           'key' => 'id',
           'entity' => 'Survey',
           'select' => array('minimumInputLength' => 0),
+          'api' => array(
+            'params' => array(
+              'activity_type_id' => "Petition",
+            ),
+          ),
         ),
       );
     }
@@ -136,7 +160,7 @@ class CRM_Core_Form_ShortCode extends CRM_Core_Form {
       ),
       array(
         'key' => 'hijack',
-        'components' => '*',
+        'components' => TRUE,
         'label' => ts('If you only insert one shortcode, you can choose to override all page content with the content of the shortcode.'),
         'options' => array(
           '0' => ts("Don't override"),
@@ -164,7 +188,7 @@ class CRM_Core_Form_ShortCode extends CRM_Core_Form {
     $options = $defaults = array();
     foreach ($this->options as $num => $field) {
       $this->addRadio("option_$num", CRM_Utils_Array::value('label', $field), $field['options'], array('allowClear' => FALSE, 'data-key' => $field['key']));
-      if ($field['components'] === '*') {
+      if ($field['components'] === TRUE) {
         $field['components'] = array_keys($this->components);
       }
       $options["option_$num"] = $field;
@@ -179,6 +203,32 @@ class CRM_Core_Form_ShortCode extends CRM_Core_Form {
     $this->setDefaults($defaults);
   }
 
+  /**
+   * The CiviCRM api (and therefore EntityRef) does not support OR logic, ACLs or joins.
+   *
+   * I'm not proud of this, but here's a workaround to pre-filter the api params
+   *
+   * @return array
+   */
+  private function profileAccess() {
+    $sql = "
+      SELECT g.id
+      FROM   civicrm_uf_group g, civicrm_uf_join j
+      WHERE  g.is_active = 1
+      AND    j.is_active = 1
+      AND    ( group_type LIKE '%Individual%'
+         OR    group_type LIKE '%Contact%' )
+      AND    g.id = j.uf_group_id
+      AND    j.module = 'Profile'
+      ";
+    $dao = CRM_Core_DAO::executeQuery($sql);
+    $ids = array();
+    while ($dao->fetch()) {
+      $ids[] = $dao->id;
+    }
+    return array('IN' => $ids);
+  }
+
   // No postProccess fn; this form never gets submitted
 
 }
index 4d0fdf7179266fd98baba4823755cc81b7595394..b489ff7b2de326d7f6863b59ff6503f290561cf2 100644 (file)
@@ -303,7 +303,6 @@ class CRM_UF_Page_Group extends CRM_Core_Page {
    */
   public function browse($action = NULL) {
     $ufGroup = array();
-    $allUFGroups = array();
     $allUFGroups = CRM_Core_BAO_UFGroup::getModuleUFGroup();
     if (empty($allUFGroups)) {
       return;
@@ -342,35 +341,15 @@ class CRM_UF_Page_Group extends CRM_Core_Page {
       }
 
       $groupTypes = self::extractGroupTypes($value['group_type']);
-      $groupComponents = array('Contribution', 'Membership', 'Activity', 'Participant', 'Case');
 
-      // drop Create, Edit and View mode links if profile group_type is Contribution, Membership, Activities or Participant
+      // drop Create, Edit and View mode links if profile group_type is one of the following:
+      $groupComponents = array('Contribution', 'Membership', 'Activity', 'Participant', 'Case');
       $componentFound = array_intersect($groupComponents, array_keys($groupTypes));
       if (!empty($componentFound)) {
         $action -= CRM_Core_Action::ADD;
       }
 
-      $groupTypesString = '';
-      if (!empty($groupTypes)) {
-        $groupTypesStrings = array();
-        foreach ($groupTypes as $groupType => $typeValues) {
-          if (is_array($typeValues)) {
-            if ($groupType == 'Participant') {
-              foreach ($typeValues as $subType => $subTypeValues) {
-                $groupTypesStrings[] = $subType . '::' . implode(': ', $subTypeValues);
-              }
-            }
-            else {
-              $groupTypesStrings[] = $groupType . '::' . implode(': ', current($typeValues));
-            }
-          }
-          else {
-            $groupTypesStrings[] = $groupType;
-          }
-        }
-        $groupTypesString = implode(', ', $groupTypesStrings);
-      }
-      $ufGroup[$id]['group_type'] = $groupTypesString;
+      $ufGroup[$id]['group_type'] = self::formatGroupTypes($groupTypes);
 
       $ufGroup[$id]['action'] = CRM_Core_Action::formLink(self::actionLinks(), $action,
         array('id' => $id),
@@ -501,4 +480,35 @@ class CRM_UF_Page_Group extends CRM_Core_Page {
     return $returnGroupTypes;
   }
 
+  /**
+   * Format 'group_type' field for display
+   *
+   * @param array $groupTypes
+   *   output from self::extractGroupTypes
+   * @return string
+   */
+  public static function formatGroupTypes($groupTypes) {
+    $groupTypesString = '';
+    if (!empty($groupTypes)) {
+      $groupTypesStrings = array();
+      foreach ($groupTypes as $groupType => $typeValues) {
+        if (is_array($typeValues)) {
+          if ($groupType == 'Participant') {
+            foreach ($typeValues as $subType => $subTypeValues) {
+              $groupTypesStrings[] = $subType . '::' . implode(': ', $subTypeValues);
+            }
+          }
+          else {
+            $groupTypesStrings[] = $groupType . '::' . implode(': ', current($typeValues));
+          }
+        }
+        else {
+          $groupTypesStrings[] = $groupType;
+        }
+      }
+      $groupTypesString = implode(', ', $groupTypesStrings);
+    }
+    return $groupTypesString;
+  }
+
 }
index 8c9af557f6f771c849eb4b9de4a9c8918e43eb83..bd7812b26e2948540d5a2ed1c1b23c9a5e37b477 100644 (file)
@@ -103,3 +103,24 @@ function civicrm_api3_contribution_page_submit($params) {
   $result = CRM_Contribute_Form_Contribution_Confirm::submit($params);
   return civicrm_api3_create_success($result, $params, 'ContributionPage', 'submit');
 }
+
+
+/**
+ * Set default getlist parameters.
+ *
+ * @see _civicrm_api3_generic_getlist_defaults
+ *
+ * @param array $request
+ *
+ * @return array
+ */
+function _civicrm_api3_contribution_page_getlist_defaults(&$request) {
+  return array(
+    'description_field' => array(
+      'intro_text',
+    ),
+    'params' => array(
+      'is_active' => 1,
+    ),
+  );
+}
index 2404608fc67167933b0f70c823824b886d380847..8c06d73f196f04315285619cbe1f34569ec9c973 100644 (file)
@@ -159,6 +159,7 @@ function _civicrm_api3_generic_getlist_params(&$request) {
  *
  * @param array $result
  * @param array $request
+ * @param string $entity
  * @param array $fields
  *
  * @return array
index 2487134834492ac020da629929c4dfd86aa3d31f..922a634f4962776003c5a391e0fd1f98db0a1b7d 100644 (file)
@@ -88,3 +88,23 @@ function civicrm_api3_survey_get($params) {
 function civicrm_api3_survey_delete($params) {
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
+
+/**
+ * Set default getlist parameters.
+ *
+ * @see _civicrm_api3_generic_getlist_defaults
+ *
+ * @param array $request
+ *
+ * @return array
+ */
+function _civicrm_api3_survey_getlist_defaults(&$request) {
+  return array(
+    'description_field' => array(
+      'campaign_id',
+    ),
+    'params' => array(
+      'is_active' => 1,
+    ),
+  );
+}
index 438883e7f9bc600cf4ab0a15e72f024d178b3de6..6f7cc671bce019dbd125a03c687bda7699aee73f 100644 (file)
@@ -85,3 +85,76 @@ function civicrm_api3_uf_group_get($params) {
 function civicrm_api3_uf_group_delete($params) {
   return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
 }
+
+/**
+ * Set default getlist parameters.
+ *
+ * @see _civicrm_api3_generic_getlist_defaults
+ *
+ * @param array $request
+ *
+ * @return array
+ */
+function _civicrm_api3_uf_group_getlist_defaults(&$request) {
+  return array(
+    'description_field' => array(
+      'description',
+      'group_type',
+    ),
+    'params' => array(
+      'is_active' => 1,
+    ),
+  );
+}
+
+/**
+ * Format getlist output
+ *
+ * @see _civicrm_api3_generic_getlist_output
+ *
+ * @param array $result
+ * @param array $request
+ * @param string $entity
+ * @param array $fields
+ *
+ * @return array
+ */
+function _civicrm_api3_uf_group_getlist_output($result, $request, $entity, $fields) {
+  $output = array();
+  if (!empty($result['values'])) {
+    foreach ($result['values'] as $row) {
+      $data = array(
+        'id' => $row[$request['id_field']],
+        'label' => $row[$request['label_field']],
+      );
+      if (!empty($request['description_field'])) {
+        $data['description'] = array();
+        foreach ((array) $request['description_field'] as $field) {
+          if (!empty($row[$field])) {
+            // Special formatting for group_type field
+            if ($field == 'group_type') {
+              $groupTypes = CRM_UF_Page_Group::extractGroupTypes($row[$field]);
+              $data['description'][] = CRM_UF_Page_Group::formatGroupTypes($groupTypes);
+              continue;
+            }
+            if (!isset($fields[$field]['pseudoconstant'])) {
+              $data['description'][] = $row[$field];
+            }
+            else {
+              $data['description'][] = CRM_Core_PseudoConstant::getLabel(
+                _civicrm_api3_get_BAO($entity),
+                $field,
+                $row[$field]
+              );
+            }
+          }
+        }
+      };
+      if (!empty($request['image_field'])) {
+        $data['image'] = isset($row[$request['image_field']]) ? $row[$request['image_field']] : '';
+      }
+      $output[] = $data;
+    }
+  }
+  return $output;
+}