CRM-12940, extending core search via hook_civicrm_queryObjects
authorDeepak Srivastava <deepak.srivastava@webaccess.co.in>
Fri, 12 Jul 2013 09:40:30 +0000 (15:10 +0530)
committerDeepak Srivastava <deepak.srivastava@webaccess.co.in>
Fri, 12 Jul 2013 09:40:30 +0000 (15:10 +0530)
----------------------------------------
* CRM-12940: Allow extensions to participate in CRM_*_BAO_Query
  http://issues.civicrm.org/jira/browse/CRM-12940

CRM/Contact/BAO/Query.php
CRM/Contact/BAO/Query/Hook.php [new file with mode: 0644]
CRM/Contact/BAO/Query/Interface.php [new file with mode: 0644]
CRM/Extension/Manager.php
CRM/Utils/Hook.php

index cffcf2d71e3c0b7f946b507fbcefaf817f0bd93e..573c6b8c67b11626c3f3f208464c51a74f11c122 100644 (file)
@@ -442,8 +442,8 @@ class CRM_Contact_BAO_Query {
       $fields = CRM_Activity_BAO_Activity::exportableFields();
       $this->_fields = array_merge($this->_fields, $fields);
 
-      // add any fields supported by extensions
-      $extFields = CRM_Extension_System::singleton()->getManager()->getSearchQueryFields();
+      // add any fields provided by hook implementers
+      $extFields = CRM_Contact_BAO_Query_Hook::singleton()->getFields();
       $this->_fields = array_merge($this->_fields, $extFields);
     }
 
@@ -772,7 +772,7 @@ class CRM_Contact_BAO_Query {
     //fix for CRM-951
     CRM_Core_Component::alterQuery($this, 'select');
 
-    CRM_Extension_System::singleton()->getManager()->alterSearchQuery($this, 'select');
+    CRM_Contact_BAO_Query_Hook::singleton()->alterSearchQuery($this, 'select');
 
     if (!empty($this->_cfIDs)) {
       $this->_customQuery = new CRM_Core_BAO_CustomQuery($this->_cfIDs, TRUE);
@@ -1633,7 +1633,7 @@ class CRM_Contact_BAO_Query {
 
       CRM_Core_Component::alterQuery($this, 'where');
 
-      CRM_Extension_System::singleton()->getManager()->alterSearchQuery($this, 'where');
+      CRM_Contact_BAO_Query_Hook::singleton()->alterSearchQuery($this, 'where');
     }
 
     if ($this->_customQuery) {
@@ -2358,7 +2358,8 @@ class CRM_Contact_BAO_Query {
 
         default:
           $from .= CRM_Core_Component::from($name, $mode, $side);
-          $from .= CRM_Extension_System::singleton()->getManager()->buildSearchfrom($name, $mode, $side);
+          $from .= CRM_Contact_BAO_Query_Hook::singleton()->buildSearchfrom($name, $mode, $side);
+
           continue;
       }
     }
diff --git a/CRM/Contact/BAO/Query/Hook.php b/CRM/Contact/BAO/Query/Hook.php
new file mode 100644 (file)
index 0000000..f9b9ee0
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.3                                                |
+ +--------------------------------------------------------------------+
+ | 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        |
+ +--------------------------------------------------------------------+
+*/
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2013
+ * $Id$
+ *
+ */
+
+/**
+ * Delegate query functions based on hook system
+ */
+class CRM_Contact_BAO_Query_Hook {
+  /**
+   * @var array of CRM_Contact_BAO_Query_Interface objects
+   */
+  protected $_queryObjects = NULL;
+
+  /**
+   * singleton function used to manage this object
+   *
+   * @return object
+   * @static
+   *
+   */
+  public static function singleton() {
+    static $singleton = NULL;
+    if (!$singleton) {
+      $singleton = new CRM_Contact_BAO_Query_Hook();
+    }
+    return $singleton;
+  }
+
+ /**
+  * Get or build the list of search objects (via hook)
+  *
+  * @return array of CRM_Contact_BAO_Query_Interface objects
+  */
+  public function getSearchQueryObjects() {
+    if ($this->_queryObjects === NULL) {
+      $this->_queryObjects = array();
+      CRM_Utils_Hook::queryObjects($this->_queryObjects);
+      CRM_Core_Error::debug_var( '$this->_queryObjects', $this->_queryObjects );
+    }
+    return $this->_queryObjects;
+  }
+  
+  public function &getFields() {
+    $extFields = array();
+    foreach (self::getSearchQueryObjects() as $obj) {
+      $flds = $obj->getFields();
+      $extFields = array_merge($extFields, $flds);
+    }
+    return $extFields;
+  }
+  
+  public function alterSearchQuery(&$query, $fnName) {
+    foreach (self::getSearchQueryObjects() as $obj) {
+      $obj->$fnName($query);
+    }
+  }
+  
+  public function buildSearchfrom($fieldName, $mode, $side) {
+    $from = '';
+    foreach (self::getSearchQueryObjects() as $obj) {
+      $from .= $obj->from($fieldName, $mode, $side);
+    }
+    return $from;
+  }
+}
\ No newline at end of file
diff --git a/CRM/Contact/BAO/Query/Interface.php b/CRM/Contact/BAO/Query/Interface.php
new file mode 100644 (file)
index 0000000..18f0077
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.3                                                |
+ +--------------------------------------------------------------------+
+ | 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        |
+ +--------------------------------------------------------------------+
+*/
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2013
+ * $Id$
+ *
+ */
+
+/**
+ * Interface for search BAO query objects
+ */
+interface CRM_Contact_BAO_Query_Interface {
+
+  public function &getFields();
+
+  public function select(&$query);
+
+  public function where(&$query);
+
+  public function from($fieldName, $mode, $side);
+}
\ No newline at end of file
index f49b1dff33036a3372bfc51457fb80ca42d760b5..57844795281cd79e0ec11deb4b48f9a008619523 100644 (file)
@@ -387,47 +387,6 @@ class CRM_Extension_Manager {
     $this->mapper->refresh();
   }
 
-  public function &getSearchQueryFields() {
-    $extFields = array();
-    foreach (self::getActiveSearchQueryObjects() as $obj) {
-      $flds = $obj->getFields();
-      $extFields = array_merge($extFields, $flds);
-    }
-    return $extFields;
-  }
-
-  public function alterSearchQuery(&$query, $fnName) {
-    foreach (self::getActiveSearchQueryObjects() as $obj) {
-      $obj->$fnName($query);
-    }
-  }
-
-  public function buildSearchfrom($fieldName, $mode, $side) {
-    foreach (self::getActiveSearchQueryObjects() as $obj) {
-      $obj->from($fieldName, $mode, $side);
-    }
-  }
-
-  public function getActiveSearchQueryObjects() {
-    $queryObjects = array();
-    $extStatus = $this->getStatuses();
-    foreach ($extStatus as $key => $status) {
-      if ($status == CRM_Extension_Manager::STATUS_INSTALLED) {
-        $path = $this->mapper->keyToBasePath($key);
-        $info = $this->mapper->keyToInfo($key);
-        $classFile = $info->civix['namespace'] . DIRECTORY_SEPARATOR . 'BAO' . DIRECTORY_SEPARATOR . 'Query';
-        $queryFile = $path . DIRECTORY_SEPARATOR . "{$classFile}.php";
-        if (file_exists($queryFile)) {
-          require_once $queryFile;
-          $className = str_replace(DIRECTORY_SEPARATOR, '_', $classFile);
-          $obj  = new $className();
-          $queryObjects[] = $obj;
-        }
-      }
-    }
-    return $queryObjects;
-  }
-
   // ----------------------
 
   /**
index 12d92b1f930409682ee8a21a3c2529ccfcdd05e9..97888baa91744a1decae377a64d8446e5701ad98 100644 (file)
@@ -1285,4 +1285,15 @@ abstract class CRM_Utils_Hook {
   static function searchProfile($name) {
     return self::singleton()->invoke(1, $name, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_searchProfile');
   }
+
+  /**
+   * This hook is called while building the core search query, 
+   * so hook implementers can provide their own query objects which alters/extends core search.
+   *
+   * @param Array $queryObjects
+   * @return void
+   */
+  static function queryObjects(&$queryObjects) {
+    return self::singleton()->invoke(1, $queryObjects, self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_queryObjects');
+  }
 }