dev/core#1098 Add unit test & code comments relating to the slow activity search
authoreileen <emcnaughton@wikimedia.org>
Tue, 2 Jul 2019 20:56:46 +0000 (08:56 +1200)
committereileen <emcnaughton@wikimedia.org>
Mon, 12 Aug 2019 00:53:55 +0000 (12:53 +1200)
The issue is the joining in of component filtering - we should fix this but do it correctly....
We probably need to extend the test to reflect contact ACLs first

CRM/Activity/BAO/Activity.php
CRM/Activity/Selector/Search.php
tests/phpunit/CRM/Activity/Selector/SearchTest.php [new file with mode: 0644]

index 313fa5c1282749902ca579c43e32a15fd5fde457..a5e1c898accb4091d4a69c5b61342b287d2f5073 100644 (file)
@@ -902,6 +902,7 @@ class CRM_Activity_BAO_Activity extends CRM_Activity_DAO_Activity {
    */
   public function addSelectWhereClause() {
     $clauses = [];
+    // @todo - check if $permissedActivityTYpes === all activity types and do not add critieria if so.
     $permittedActivityTypeIDs = self::getPermittedActivityTypes();
     if (empty($permittedActivityTypeIDs)) {
       // This just prevents a mysql fail if they have no access - should be extremely edge case.
index abd0bdfb249f80ca24bb5bbd8e0fdfae048ef2b3..77bb0fa9a83275bb9f7141266fb540ffded74dab 100644 (file)
@@ -129,7 +129,7 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM
   /**
    * The query object.
    *
-   * @var string
+   * @var \CRM_Contact_BAO_Query
    */
   protected $_query;
 
@@ -179,6 +179,13 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM
       // required here rather than "access my cases and activities" to
       // prevent those with only the later permission from seeing a list
       // of all cases which might present a privacy issue.
+      // @todo this is the cause of the current devastatingly bad performance on
+      // activity search - it involves a bad join.
+      // The correct fix is to use the permission infrastrucutre - ie. add in the
+      // clause generated by CRM_Activity_BAO_Query::addSelectWhere
+      // but some testing needs to check that before making the change
+      // see https://github.com/civicrm/civicrm-core/blob/be2fb01f90f5f299dd07402a41fed7c7c7567f00/CRM/Utils/SQL.php#L48
+      // for how it's done in the api kernel.
       if (!CRM_Core_Permission::access($componentName, TRUE, TRUE)) {
         $componentClause[] = " (activity_type.component_id IS NULL OR activity_type.component_id <> {$componentID}) ";
       }
@@ -435,7 +442,7 @@ class CRM_Activity_Selector_Search extends CRM_Core_Selector_Base implements CRM
   }
 
   /**
-   * @return string
+   * @return \CRM_Contact_BAO_Query
    */
   public function &getQuery() {
     return $this->_query;
diff --git a/tests/phpunit/CRM/Activity/Selector/SearchTest.php b/tests/phpunit/CRM/Activity/Selector/SearchTest.php
new file mode 100644 (file)
index 0000000..9370cd5
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 5                                                  |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2019                                |
+ +--------------------------------------------------------------------+
+ | 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_Activity_Selector_SearchTest
+ *
+ * @package CiviCRM
+ */
+class CRM_Activity_Selector_SearchTest extends CiviUnitTestCase {
+
+  /**
+   * Test activity search applies a permission based component filter.
+   */
+  public function testActivitySearchComponentPermission() {
+    $this->activityCreate(['activity_type_id' => 'Contribution']);
+    $this->activityCreate(['activity_type_id' => 'Pledge Reminder']);
+    $this->activityCreate(['activity_type_id' => 'Meeting']);
+    $this->setPermissions(['access CiviCRM', 'edit all contacts', 'access CiviContribute']);
+    $queryParams = [['activity_location', '=', 'Baker Street', '', '']];
+    $searchSelector = new CRM_Activity_Selector_Search($queryParams, CRM_Core_Action::VIEW);
+    $this->assertEquals(2, $searchSelector->getTotalCount(NULL));
+    $queryObject = $searchSelector->getQuery();
+    $this->assertEquals("civicrm_activity.location = 'Baker Street'", $queryObject->_where[''][0]);
+  }
+
+}