CRM-14165 - Improve option page lookup
authorColeman Watts <coleman@civicrm.org>
Thu, 6 Feb 2014 00:44:54 +0000 (16:44 -0800)
committerColeman Watts <coleman@civicrm.org>
Thu, 6 Feb 2014 00:44:54 +0000 (16:44 -0800)
CRM/Activity/Form/Activity.php
CRM/Contact/Form/Edit/Phone.php
CRM/Core/DAO.php
CRM/Core/Form.php
CRM/Core/PseudoConstant.php
CRM/Utils/Api.php [new file with mode: 0644]
css/civicrm.css
js/Common.js

index 23af98507ed3ce415865e346a8a9a78b73ca5041..82ec0cf40b61ecdbfc78b180380a10e12e99244b 100644 (file)
@@ -695,7 +695,7 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task {
           $this->addWysiwyg($field, $values['label'], $attribute, $required);
         }
         elseif ($values['type'] == 'select' && empty($attribute)) {
-          $this->addSelect('CRM_Activity_BAO_Activity', $field, array(), $required);
+          $this->addSelect($field, array(), $required);
         }
         elseif ($field != 'source_contact_id') {
           $this->add($values['type'], $field, $values['label'], $attribute, $required);
@@ -712,7 +712,7 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task {
       CRM_Campaign_BAO_Campaign::accessCampaign()
     ) {
       $buildEngagementLevel = TRUE;
-      $this->addSelect('CRM_Activity_BAO_Activity', 'engagement_level');
+      $this->addSelect('engagement_level');
       $this->addRule('engagement_level',
         ts('Please enter the engagement index as a number (integers only).'),
         'positiveInteger'
index a268f2cb5b43e9ef2ede490af1e14da6a0e83d0c..3fb2d97cd4bc4981ff29e6b0e0ac4eddcf68239d 100644 (file)
@@ -61,16 +61,16 @@ class CRM_Contact_Form_Edit_Phone {
     $form->applyFilter('__ALL__', 'trim');
 
     //phone type select
-    $form->addElement('select', "phone[$blockId][phone_type_id]", ts('Phone'), CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id'));
+    $form->addSelect("phone[$blockId][phone_type_id]", array('data-api-entity' => 'phone', 'class' => 'six'));
 
     //main phone number with crm_phone class
-    $form->addElement('text', "phone[$blockId][phone]", ts('Phone'), array_merge(CRM_Core_DAO::getAttribute('CRM_Core_DAO_Phone', 'phone'), array('class' => 'crm_phone twelve')));
+    $form->add('text', "phone[$blockId][phone]", ts('Phone'), array_merge(CRM_Core_DAO::getAttribute('CRM_Core_DAO_Phone', 'phone'), array('class' => 'crm_phone twelve')));
     // phone extension
     $form->addElement('text', "phone[$blockId][phone_ext]", ts('Extension'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Phone', 'phone_ext'));
 
     if (isset($form->_contactType) || $blockEdit) {
       //Block type select
-      $form->addElement('select', "phone[$blockId][location_type_id]", '', CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'));
+      $form->addSelect("phone[$blockId][location_type_id]", array('data-api-entity' => 'phone', 'class' => 'six'));
 
       //is_Primary radio
       $js = array('id' => 'Phone_' . $blockId . '_IsPrimary', 'onClick' => 'singleSelect( this.id );');
index 33346c19a1778d65cad6009d071526a8e4fa4ffc..54b0b484b115c22c8a00c9caf839976ea3de658a 100644 (file)
@@ -929,8 +929,11 @@ FROM   civicrm_domain
    * execute a query and get the single result
    *
    * @param string $query query to be executed
+   * @param array $params
+   * @param bool $abort
+   * @param bool $i18nRewrite
+   * @return string|null the result of the query if any
    *
-   * @return string the result of the query
    * @static
    * @access public
    */
index b6b573f7a3c44e4aed1d8f21636749cd122ad1bd..028af24379107bb370eaec474291bcef8cd2c808 100644 (file)
@@ -912,18 +912,24 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * @throws CRM_Core_Exception
    * @return HTML_QuickForm_Element
    */
-  function addSelect($baoName, $name, $props = array(), $required = FALSE) {
-    $options = $baoName::buildOptions($name, 'create');
-    if ($options === FALSE) {
-      throw new CRM_Core_Exception('No option list for field ' . $name);
+  function addSelect($name, $props = array(), $required = FALSE) {
+    if (!isset($props['data-api-entity'])) {
+      $props['data-api-entity'] = CRM_Utils_Api::getEntityName($this);
     }
+    if (!isset($props['data-api-field'])) {
+      $props['data-api-field'] = strrpos($name, '[') ? rtrim(substr($name, 1 + strrpos($name, '[')), ']') : $name;
+    }
+    $options = civicrm_api3($props['data-api-entity'], 'getoptions', array(
+        'field' => $props['data-api-field'],
+      )
+    );
+    $options = $options['values'];
     if (!array_key_exists('placeholder', $props)) {
       $props['placeholder'] = $required ? ts('- select -') : ts('- none -');
     }
     if (!empty($props['placeholder']) && empty($props['multiple'])) {
       $options = array('' => '') + $options;
     }
-    $bao = new $baoName;
     // Handle custom field
     if (strpos($name, 'custom_') === 0 && is_numeric($name[7])) {
       list(, $id) = explode('_', $name);
@@ -933,15 +939,19 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
     }
     // Core field
     else {
-      $meta = $bao->getFieldSpec($name);
-      $label = isset($props['label']) ? $props['label'] : ts($meta['title']);
-      if (!empty($meta['pseudoconstant']['optionGroupName'])) {
-        $props['data-option-group-url'] = 'civicrm/admin/options/' . $meta['pseudoconstant']['optionGroupName'];
+      $getFields = civicrm_api3($props['data-api-entity'], 'getfields');
+      foreach($getFields['values'] as $uniqueName => $fieldSpec) {
+        if (
+          $uniqueName === $props['data-api-field'] ||
+          CRM_Utils_Array::value('name', $fieldSpec) === $props['data-api-field'] ||
+          in_array($props['data-api-field'], CRM_Utils_Array::value('api.aliases', $fieldSpec, array()))
+        ) {
+          break;
+        }
       }
+      $label = isset($props['label']) ? $props['label'] : $fieldSpec['title'];
+      $props['data-option-group-url'] = CRM_Core_PseudoConstant::getOptionEditUrl($fieldSpec);
     }
-    require_once 'api/api.php';
-    $props['data-api-entity'] = _civicrm_api_get_entity_name_from_dao($bao);
-    $bao->free();
     $props['class'] = isset($props['class']) ? $props['class'] . ' ' : '';
     $props['class'] .= "crm-select2";
     CRM_Utils_Array::remove($props, 'label');
index 066a82cc354ced12fd94e049e8f434ff4f16b019..30c01bd552927de8e29da5cfd84147ca30b414d7 100644 (file)
@@ -493,6 +493,32 @@ class CRM_Core_PseudoConstant {
     return CRM_Utils_Array::key($value, $values);
   }
 
+  /**
+   * Lookup the admin page at which a field's option list can be edited
+   * @param $fieldSpec
+   * @return string|null
+   */
+  static function getOptionEditUrl($fieldSpec) {
+    // If it's an option group, that's easy
+    if (!empty($fieldSpec['pseudoconstant']['optionGroupName'])) {
+      return 'civicrm/admin/options/' . $fieldSpec['pseudoconstant']['optionGroupName'];
+    }
+    // For everything else...
+    elseif (!empty($fieldSpec['pseudoconstant']['table'])) {
+      $daoName = CRM_Core_DAO_AllCoreTables::getClassForTable($fieldSpec['pseudoconstant']['table']);
+      if (!$daoName) {
+        return NULL;
+      }
+      // We don't have good mapping so have to do a bit of guesswork from the menu
+      list(, , , $ent) = explode('_', $daoName);
+      $sql = "SELECT path FROM civicrm_menu
+        WHERE page_callback LIKE '%CRM_Admin_Page_$ent%'
+        LIMIT 1";
+      return CRM_Core_Dao::singleValueQuery($sql);
+    }
+    return NULL;
+  }
+
   /**
    * DEPRECATED generic populate method
    * All pseudoconstant functions that use this method are also deprecated.
diff --git a/CRM/Utils/Api.php b/CRM/Utils/Api.php
new file mode 100644 (file)
index 0000000..4d700e5
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.4                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2013                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+*/
+
+class CRM_Utils_Api {
+  /**
+   * Attempt to retrieve the api entity name from any calling class
+   * @param $classNameOrObject
+   * @throws CRM_Core_Exception
+   */
+  static function getEntityName($classNameOrObject) {
+    require_once 'api/api.php';
+    $className = is_string($classNameOrObject) ? $classNameOrObject : get_class($classNameOrObject);
+
+    // First try the obvious replacements
+    $daoName = str_replace(array('_BAO_', '_Form_', '_Page_'), '_DAO_', $className);
+    $shortName = CRM_Core_DAO_AllCoreTables::getBriefName($daoName);
+
+    // If that didn't work, try a different pattern
+    if (!$shortName) {
+      list(, $entity) = explode('_', $className);
+      $daoName = "CRM_{$entity}_DAO_$entity";
+      $shortName = CRM_Core_DAO_AllCoreTables::getBriefName($daoName);
+    }
+
+    // If that didn't work, try a different pattern
+    if (!$shortName) {
+      list(, , , $entity) = explode('_', $className);
+      $daoName = "CRM_Core_DAO_$entity";
+      $shortName = CRM_Core_DAO_AllCoreTables::getBriefName($daoName);
+    }
+    if (!$shortName) {
+      throw new CRM_Core_Exception('Could not find api name for supplied class');
+    }
+    return _civicrm_api_get_entity_name_from_camel($shortName);
+  }
+}
index ae8abda34fee6d389b00a9cd029ad0cfba16da01..2c410e4cd66ed85b3206a7f1ac0e0c03adaed6d9 100644 (file)
@@ -3760,7 +3760,7 @@ div.m ul#civicrm-menu,
   width: 15em;
 }
 .crm-container .select2-container {
-  min-width: 15em !important;
+  min-width: 8em !important;
   font-size: 11px;
 }
 /* Style civi form inputs to match select2 */
@@ -3799,6 +3799,9 @@ div.m ul#civicrm-menu,
 .crm-container .select2-search-choice-close {
   top: 2px;
 }
+.crm-container .select2-container .select2-choice abbr {
+  top: 6px;
+}
 /* Add search icon to ajax single-selects */
 .crm-container .crm-ajax-select .select2-arrow b {
   background-position: -39px -22px;
index dd5498f557fe0bd584d0575d608a0b4fc8b699df..4471d763eb897444467fb2745c95283904710692 100644 (file)
@@ -961,7 +961,7 @@ CRM.validate = CRM.validate || {
         CRM.loadForm(CRM.url(url, {reset: 1}))
           .on('dialogclose', function() {
             var $elects = $('select[data-option-group-url="' + url + '"]');
-            CRM.api3($elects.data('api-entity'), 'getoptions', {sequential: 1, field: $elects.attr('name')})
+            CRM.api3($elects.data('api-entity'), 'getoptions', {sequential: 1, field: $elects.data('api-field')})
               .done(function(data) {
                 CRM.utils.setOptions($elects, data.values);
               });