Merge pull request #4814 from atif-shaikh/CRM-14199Improvement
[civicrm-core.git] / CRM / Contact / BAO / Query.php
index 82b0ba67e25021eec9d300ff10f5ffead037ff34..4b766157c2bca031c2ec4cad66ed2170fe069c7d 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.5                                                |
+ | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
  | Copyright CiviCRM LLC (c) 2004-2014                                |
  +--------------------------------------------------------------------+
@@ -43,7 +43,7 @@ class CRM_Contact_BAO_Query {
    *
    * @var int
    */
-  CONST
+  const
     MODE_CONTACTS = 1,
     MODE_CONTRIBUTE = 2,
     MODE_MEMBER = 8,
@@ -58,7 +58,7 @@ class CRM_Contact_BAO_Query {
     MODE_MAILING = 16384;
 
   /**
-   * the default set of return properties
+   * The default set of return properties
    *
    * @var array
    * @static
@@ -66,7 +66,7 @@ class CRM_Contact_BAO_Query {
   static $_defaultReturnProperties = NULL;
 
   /**
-   * the default set of hier return properties
+   * The default set of hier return properties
    *
    * @var array
    * @static
@@ -74,7 +74,7 @@ class CRM_Contact_BAO_Query {
   static $_defaultHierReturnProperties;
 
   /**
-   * the set of input params
+   * The set of input params
    *
    * @var array
    */
@@ -86,21 +86,21 @@ class CRM_Contact_BAO_Query {
 
   public $_sort;
   /**
-   * the set of output params
+   * The set of output params
    *
    * @var array
    */
   public $_returnProperties;
 
   /**
-   * the select clause
+   * The select clause
    *
    * @var array
    */
   public $_select;
 
   /**
-   * the name of the elements that are in the select clause
+   * The name of the elements that are in the select clause
    * used to extract the values
    *
    * @var array
@@ -108,28 +108,28 @@ class CRM_Contact_BAO_Query {
   public $_element;
 
   /**
-   * the tables involved in the query
+   * The tables involved in the query
    *
    * @var array
    */
   public $_tables;
 
   /**
-   * the table involved in the where clause
+   * The table involved in the where clause
    *
    * @var array
    */
   public $_whereTables;
 
   /**
-   * the where clause
+   * The where clause
    *
    * @var array
    */
   public $_where;
 
   /**
-   * the where string
+   * The where string
    *
    * @var string
    *
@@ -137,7 +137,7 @@ class CRM_Contact_BAO_Query {
   public $_whereClause;
 
   /**
-   * additional permission Where Clause
+   * Additional permission Where Clause
    *
    * @var string
    *
@@ -145,7 +145,7 @@ class CRM_Contact_BAO_Query {
   public $_permissionWhereClause;
 
   /**
-   * the from string
+   * The from string
    *
    * @var string
    *
@@ -153,7 +153,7 @@ class CRM_Contact_BAO_Query {
   public $_fromClause;
 
   /**
-   * additional permission from clause
+   * Additional permission from clause
    *
    * @var string
    *
@@ -161,7 +161,7 @@ class CRM_Contact_BAO_Query {
   public $_permissionFromClause;
 
   /**
-   * the from clause for the simple select and alphabetical
+   * The from clause for the simple select and alphabetical
    * select
    *
    * @var string
@@ -169,7 +169,7 @@ class CRM_Contact_BAO_Query {
   public $_simpleFromClause;
 
   /**
-   * the having values
+   * The having values
    *
    * @var string
    *
@@ -199,28 +199,28 @@ class CRM_Contact_BAO_Query {
   public $_options;
 
   /**
-   * are we in search mode
+   * Are we in search mode
    *
    * @var boolean
    */
   public $_search = TRUE;
 
   /**
-   * should we skip permission checking
+   * Should we skip permission checking
    *
    * @var boolean
    */
   public $_skipPermission = FALSE;
 
   /**
-   * should we skip adding of delete clause
+   * Should we skip adding of delete clause
    *
    * @var boolean
    */
   public $_skipDeleteClause = FALSE;
 
   /**
-   * are we in strict mode (use equality over LIKE)
+   * Are we in strict mode (use equality over LIKE)
    *
    * @var boolean
    */
@@ -243,7 +243,7 @@ class CRM_Contact_BAO_Query {
   public $_primaryLocation = TRUE;
 
   /**
-   * are contact ids part of the query
+   * Are contact ids part of the query
    *
    * @var boolean
    */
@@ -264,14 +264,14 @@ class CRM_Contact_BAO_Query {
   public $_displayRelationshipType = NULL;
 
   /**
-   * reference to the query object for custom values
+   * Reference to the query object for custom values
    *
    * @var Object
    */
   public $_customQuery;
 
   /**
-   * should we enable the distinct clause, used if we are including
+   * Should we enable the distinct clause, used if we are including
    * more than one group
    *
    * @var boolean
@@ -284,7 +284,7 @@ class CRM_Contact_BAO_Query {
   public $_useGroupBy = FALSE;
 
   /**
-   * the relationship type direction
+   * The relationship type direction
    *
    * @var array
    * @static
@@ -292,7 +292,7 @@ class CRM_Contact_BAO_Query {
   static $_relType;
 
   /**
-   * the activity role
+   * The activity role
    *
    * @var array
    * @static
@@ -318,7 +318,7 @@ class CRM_Contact_BAO_Query {
   static $_withContactActivitiesOnly;
 
   /**
-   * use distinct component clause for component searches
+   * Use distinct component clause for component searches
    *
    * @var string
    */
@@ -327,7 +327,7 @@ class CRM_Contact_BAO_Query {
   public $_rowCountClause;
 
   /**
-   * use groupBy component clause for component searches
+   * Use groupBy component clause for component searches
    *
    * @var string
    */
@@ -405,7 +405,7 @@ class CRM_Contact_BAO_Query {
   public $_pseudoConstantsSelect = array();
 
   /**
-   * class constructor which also does all the work
+   * Class constructor which also does all the work
    *
    * @param array $params
    * @param array $returnProperties
@@ -476,12 +476,11 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * function which actually does all the work for the constructor
+   * Function which actually does all the work for the constructor
    *
    * @return void
-   * @access private
    */
-  function initialize() {
+  public function initialize() {
     $this->_select = array();
     $this->_element = array();
     $this->_tables = array();
@@ -519,7 +518,7 @@ class CRM_Contact_BAO_Query {
     $this->openedSearchPanes(TRUE);
   }
 
-  function buildParamsLookup() {
+  public function buildParamsLookup() {
     // first fix and handle contact deletion nicely
     // this code is primarily for search builder use case
     // where different clauses can specify if they want deleted
@@ -586,9 +585,8 @@ class CRM_Contact_BAO_Query {
    * hack to make them part of the query
    *
    * @return void
-   * @access public
    */
-  function addSpecialFields() {
+  public function addSpecialFields() {
     static $special = array('contact_type', 'contact_sub_type', 'sort_name', 'display_name');
     foreach ($special as $name) {
       if (!empty($this->_returnProperties[$name])) {
@@ -606,9 +604,8 @@ class CRM_Contact_BAO_Query {
    * in the params list
    *
    * @return void
-   * @access public
    */
-  function selectClause() {
+  public function selectClause() {
 
     $this->addSpecialFields();
 
@@ -913,9 +910,8 @@ class CRM_Contact_BAO_Query {
    * the return values
    *
    * @return void
-   * @access public
    */
-  function addHierarchicalElements() {
+  public function addHierarchicalElements() {
     if (empty($this->_returnProperties['location'])) {
       return;
     }
@@ -1237,9 +1233,8 @@ class CRM_Contact_BAO_Query {
    * the return values
    *
    * @return void
-   * @access public
    */
-  function addMultipleElements() {
+  public function addMultipleElements() {
     if (empty($this->_returnProperties['website'])) {
       return;
     }
@@ -1264,7 +1259,7 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * generate the query based on what type of query we need
+   * Generate the query based on what type of query we need
    *
    * @param boolean $count
    * @param boolean $sortByChar
@@ -1272,9 +1267,8 @@ class CRM_Contact_BAO_Query {
    * @param boolean $onlyDeleted
    *
    * @return array sql query parts as an array
-   * @access public
    */
-  function query($count = FALSE, $sortByChar = FALSE, $groupContacts = FALSE, $onlyDeleted = FALSE) {
+  public function query($count = FALSE, $sortByChar = FALSE, $groupContacts = FALSE, $onlyDeleted = FALSE) {
     // build permission clause
     $this->generatePermissionClause($onlyDeleted, $count);
 
@@ -1383,12 +1377,12 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * @param $name
+   * @param string $name
    * @param $grouping
    *
    * @return null
    */
-  function &getWhereValues($name, $grouping) {
+  public function &getWhereValues($name, $grouping) {
     $result = NULL;
     foreach ($this->_params as $values) {
       if ($values[0] == $name && $values[3] == $grouping) {
@@ -1404,7 +1398,7 @@ class CRM_Contact_BAO_Query {
    * @param $from
    * @param $to
    */
-  static function fixDateValues($relative, &$from, &$to) {
+  public static function fixDateValues($relative, &$from, &$to) {
     if ($relative) {
       list($from, $to) = CRM_Utils_Date::getFromTo($relative, $from, $to);
     }
@@ -1417,7 +1411,7 @@ class CRM_Contact_BAO_Query {
    *
    * @return array
    */
-  static function convertFormValues(&$formValues, $wildcard = 0, $useEquals = FALSE) {
+  public static function convertFormValues(&$formValues, $wildcard = 0, $useEquals = FALSE) {
     $params = array();
     if (empty($formValues)) {
       return $params;
@@ -1480,14 +1474,14 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * @param $id
+   * @param int $id
    * @param $values
    * @param int $wildcard
    * @param bool $useEquals
    *
    * @return array|null
    */
-  static function &fixWhereValues($id, &$values, $wildcard = 0, $useEquals = FALSE) {
+  public static function &fixWhereValues($id, &$values, $wildcard = 0, $useEquals = FALSE) {
     // skip a few search variables
     static $skipWhere = NULL;
     static $likeNames = NULL;
@@ -1573,7 +1567,7 @@ class CRM_Contact_BAO_Query {
   /**
    * @param $values
    */
-  function whereClauseSingle(&$values) {
+  public function whereClauseSingle(&$values) {
     // do not process custom fields or prefixed contact ids or component params
     if (CRM_Core_BAO_CustomField::getKeyID($values[0]) ||
       (substr($values[0], 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX) ||
@@ -1802,9 +1796,8 @@ class CRM_Contact_BAO_Query {
    * where clause
    *
    * @return string
-   * @access public
    */
-  function whereClause() {
+  public function whereClause() {
     $this->_where[0] = array();
     $this->_qill[0] = array();
 
@@ -1889,7 +1882,7 @@ class CRM_Contact_BAO_Query {
    *
    * @throws Exception
    */
-  function restWhere(&$values) {
+  public function restWhere(&$values) {
     $name = CRM_Utils_Array::value(0, $values);
     $op = CRM_Utils_Array::value(1, $values);
     $value = CRM_Utils_Array::value(2, $values);
@@ -2220,7 +2213,7 @@ class CRM_Contact_BAO_Query {
    * @return array
    * @throws Exception
    */
-  static function getLocationTableName(&$where, &$locType) {
+  public static function getLocationTableName(&$where, &$locType) {
     if (isset($locType[1]) && is_numeric($locType[1])) {
       list($tbName, $fldName) = explode(".", $where);
 
@@ -2263,11 +2256,11 @@ class CRM_Contact_BAO_Query {
   /**
    * Given a result dao, extract the values and return that array
    *
-   * @param Object $dao
+   * @param CRM_Core_DAO $dao
    *
    * @return array values for this query
    */
-  function store($dao) {
+  public function store($dao) {
     $value = array();
 
     foreach ($this->_element as $key => $dontCare) {
@@ -2308,12 +2301,11 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * getter for tables array
+   * Getter for tables array
    *
    * @return array
-   * @access public
    */
-  function tables() {
+  public function tables() {
     return $this->_tables;
   }
 
@@ -2323,12 +2315,12 @@ class CRM_Contact_BAO_Query {
    * logic may have eroded
    * @return array
    */
-  function whereTables() {
+  public function whereTables() {
     return $this->_whereTables;
   }
 
   /**
-   * generate the where clause (used in match contacts and permissions)
+   * Generate the where clause (used in match contacts and permissions)
    *
    * @param array $params
    * @param array $fields
@@ -2337,10 +2329,9 @@ class CRM_Contact_BAO_Query {
    * @param boolean $strict
    *
    * @return string
-   * @access public
    * @static
    */
-  static function getWhereClause($params, $fields, &$tables, &$whereTables, $strict = FALSE) {
+  public static function getWhereClause($params, $fields, &$tables, &$whereTables, $strict = FALSE) {
     $query = new CRM_Contact_BAO_Query($params, NULL, $fields,
       FALSE, $strict
     );
@@ -2352,7 +2343,7 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * create the from clause
+   * Create the from clause
    *
    * @param array $tables tables that need to be included in this from clause
    *                      if null, return mimimal from clause (i.e. civicrm_contact)
@@ -2363,10 +2354,9 @@ class CRM_Contact_BAO_Query {
    * @param int $mode
    *
    * @return string the from clause
-   * @access public
    * @static
    */
-  static function fromClause(&$tables, $inner = NULL, $right = NULL, $primaryLocation = TRUE, $mode = 1) {
+  public static function fromClause(&$tables, $inner = NULL, $right = NULL, $primaryLocation = TRUE, $mode = 1) {
 
     $from = ' FROM civicrm_contact contact_a';
     if (empty($tables)) {
@@ -2611,7 +2601,7 @@ class CRM_Contact_BAO_Query {
    *
    * @return void
    */
-  function deletedContacts($values) {
+  public function deletedContacts($values) {
     list($_, $_, $value, $grouping, $_) = $values;
     if ($value) {
       // *prepend* to the relevant grouping as this is quite an important factor
@@ -2620,14 +2610,13 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * where / qill clause for contact_type
+   * Where / qill clause for contact_type
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function contactType(&$values) {
+  public function contactType(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $subTypes = array();
@@ -2688,53 +2677,59 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * where / qill clause for contact_sub_type
+   * Where / qill clause for contact_sub_type
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function contactSubType(&$values) {
+  public function contactSubType(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
-    $this->includeContactSubTypes($value, $grouping);
+    $this->includeContactSubTypes($value, $grouping, $op);
   }
 
   /**
    * @param $value
    * @param $grouping
    */
-  function includeContactSubTypes($value, $grouping) {
+  public function includeContactSubTypes($value, $grouping, $op = 'LIKE') {
 
     $clause = array();
     $alias = "contact_a.contact_sub_type";
+    $qillOperators = array('NOT LIKE' => ts('Not Like')) + CRM_Core_SelectValues::getSearchBuilderOperators();
 
-    if (is_array($value)) {
+    $op = str_replace('IN', 'LIKE', $op);
+    $op = str_replace('=', 'LIKE', $op);
+    $op = str_replace('!', 'NOT ', $op);
+
+    if (strpos($op, 'NULL') !== FALSE || strpos($op, 'EMPTY') !== FALSE) {
+      $this->_where[$grouping][] = self::buildClause($alias, $op, $value, 'String');
+    }
+    else if (is_array($value)) {
       foreach ($value as $k => $v) {
         if (!empty($k)) {
-          $clause[$k] = "($alias like '%" . CRM_Core_DAO::VALUE_SEPARATOR . CRM_Utils_Type::escape($k, 'String') . CRM_Core_DAO::VALUE_SEPARATOR . "%')";
+          $clause[$k] = "($alias $op '%" . CRM_Core_DAO::VALUE_SEPARATOR . CRM_Utils_Type::escape($k, 'String') . CRM_Core_DAO::VALUE_SEPARATOR . "%')";
         }
       }
     }
     else {
-      $clause[$value] = "($alias like '%" . CRM_Core_DAO::VALUE_SEPARATOR . CRM_Utils_Type::escape($value, 'String') . CRM_Core_DAO::VALUE_SEPARATOR . "%')";
+      $clause[$value] = "($alias $op '%" . CRM_Core_DAO::VALUE_SEPARATOR . CRM_Utils_Type::escape($value, 'String') . CRM_Core_DAO::VALUE_SEPARATOR . "%')";
     }
 
     if (!empty($clause)) {
       $this->_where[$grouping][] = "( " . implode(' OR ', $clause) . " )";
-      $this->_qill[$grouping][] = ts('Contact Subtype') . ' - ' . implode(' ' . ts('or') . ' ', array_keys($clause));
     }
+    $this->_qill[$grouping][] = ts('Contact Subtype %1 ', array(1 => $qillOperators[$op])) . implode(' ' . ts('or') . ' ', array_keys($clause));
   }
 
   /**
-   * where / qill clause for groups
+   * Where / qill clause for groups
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function group(&$values) {
+  public function group(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (count($value) > 1) {
@@ -2831,7 +2826,7 @@ class CRM_Contact_BAO_Query {
    *
    * @return array
    */
-  function getGroupsFromTypeCriteria($value){
+  public function getGroupsFromTypeCriteria($value){
     $groupIds = array();
     foreach ($value as $groupTypeValue) {
       $groupList = CRM_Core_PseudoConstant::group($groupTypeValue);
@@ -2841,14 +2836,13 @@ class CRM_Contact_BAO_Query {
   }
 
   /**
-   * where / qill clause for smart groups
+   * Where / qill clause for smart groups
    *
    * @param $values
    *
    * @return string|NULL
-   * @access public
    */
-  function savedSearch(&$values) {
+  public function savedSearch(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
     return $this->addGroupContactCache(array_keys($value));
   }
@@ -2860,7 +2854,7 @@ class CRM_Contact_BAO_Query {
    *
    * @return null|string
    */
-  function addGroupContactCache($groups, $tableAlias = NULL, $joinTable = "contact_a") {
+  public function addGroupContactCache($groups, $tableAlias = NULL, $joinTable = "contact_a") {
     $config = CRM_Core_Config::singleton();
 
     // Find all the groups that are part of a saved search.
@@ -2895,26 +2889,25 @@ WHERE  id IN ( $groupIDs )
       $groupIDsFiltered = implode(',', $groupsFiltered);
 
       if ($tableAlias == NULL) {
-        $tableAlias = "civicrm_group_contact_cache_{$groupIDsFiltered}";
+        $tableAlias = "`civicrm_group_contact_cache_{$groupIDsFiltered}`";
       }
 
-      $this->_tables[$tableAlias] = $this->_whereTables[$tableAlias] = " LEFT JOIN civicrm_group_contact_cache `{$tableAlias}` ON {$joinTable}.id = `{$tableAlias}`.contact_id ";
+      $this->_tables[$tableAlias] = $this->_whereTables[$tableAlias] = " LEFT JOIN civicrm_group_contact_cache {$tableAlias} ON {$joinTable}.id = {$tableAlias}.contact_id ";
 
-      return "`{$tableAlias}`.group_id IN (" . $groupIDsFiltered . ")";
+      return "{$tableAlias}.group_id IN (" . $groupIDsFiltered . ")";
     }
 
     return NULL;
   }
 
   /**
-   * where / qill clause for cms users
+   * Where / qill clause for cms users
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function ufUser(&$values) {
+  public function ufUser(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if ($value == 1) {
@@ -2931,14 +2924,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * all tag search specific
+   * All tag search specific
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function tagSearch(&$values) {
+  public function tagSearch(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $op = "LIKE";
@@ -2999,14 +2991,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for tag
+   * Where / qill clause for tag
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function tag(&$values) {
+  public function tag(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $tagNames = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
@@ -3086,14 +3077,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where/qill clause for notes
+   * Where/qill clause for notes
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function notes(&$values) {
+  public function notes(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $noteOptionValues = $this->getWhereValues('note_option', $grouping);
@@ -3134,13 +3124,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * @param $name
+   * @param string $name
    * @param $op
    * @param $grouping
    *
    * @return bool
    */
-  function nameNullOrEmptyOp($name, $op, $grouping) {
+  public function nameNullOrEmptyOp($name, $op, $grouping) {
     switch ( $op ) {
       case 'IS NULL':
       case 'IS NOT NULL':
@@ -3164,25 +3154,23 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for sort_name
+   * Where / qill clause for sort_name
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function sortName(&$values) {
-    list($name, $op, $value, $grouping, $wildcard) = $values;
+  public function sortName(&$values) {
+    list($fieldName, $op, $value, $grouping, $wildcard) = $values;
 
     // handle IS NULL / IS NOT NULL / IS EMPTY / IS NOT EMPTY
-    if ( $this->nameNullOrEmptyOp( $name, $op, $grouping ) ) {
+    if ($this->nameNullOrEmptyOp($fieldName, $op, $grouping)) {
       return;
     }
 
-    $newName = $name;
-    $name = trim($value);
+    $input = $value = trim($value);
 
-    if (empty($name)) {
+    if (!strlen($value)) {
       return;
     }
 
@@ -3194,24 +3182,23 @@ WHERE  id IN ( $groupIDs )
     $subGlue = ' OR ';
 
     $strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower';
-    $locationType = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
 
-    if (substr($name, 0, 1) == '"' &&
-      substr($name, -1, 1) == '"'
-    ) {
-      //If name is encased in double quotes, the value should be taken to be the string in entirety and the
-      $value = substr($name, 1, -1);
-      $value = $strtolower(CRM_Core_DAO::escapeString($value));
-      $wc = ($newName == 'sort_name') ? 'LOWER(contact_a.sort_name)' : 'LOWER(contact_a.display_name)';
-      $sub[] = " ( $wc = '$value' ) ";
-      if ($config->includeEmailInName) {
-        $sub[] = " ( civicrm_email.email = '$value' ) ";
-      }
-    }
-    elseif (strpos($name, ',') !== FALSE) {
-      // if we have a comma in the string, search for the entire string
-      $value = $strtolower(CRM_Core_DAO::escapeString($name));
-      if ($wildcard) {
+    $firstChar = substr($value, 0, 1);
+    $lastChar = substr($value, -1, 1);
+    $quotes = array("'", '"');
+    // If string is quoted, strip quotes and otherwise don't alter it
+    if ((strlen($value) > 2) && in_array($firstChar, $quotes) && in_array($lastChar, $quotes)) {
+      $value = trim($value, implode('', $quotes));
+    }
+    // Replace spaces with wildcards for a LIKE operation
+    // UNLESS string contains a comma (this exception is a tiny bit questionable)
+    elseif ($op == 'LIKE' && strpos($value, ',') === FALSE) {
+      $value = str_replace(' ', '%', $value);
+    }
+    $value = $strtolower(CRM_Core_DAO::escapeString(trim($value)));
+    if (strlen($value)) {
+      $fieldsub = array();
+      if ($wildcard && $op == 'LIKE') {
         if ($config->includeWildCardInName) {
           $value = "'%$value%'";
         }
@@ -3223,91 +3210,21 @@ WHERE  id IN ( $groupIDs )
       else {
         $value = "'$value'";
       }
-      if ($newName == 'sort_name') {
+      if ($fieldName == 'sort_name') {
         $wc = self::caseImportant($op) ? "LOWER(contact_a.sort_name)" : "contact_a.sort_name";
       }
       else {
         $wc = self::caseImportant($op) ? "LOWER(contact_a.display_name)" : "contact_a.display_name";
       }
-      $sub[] = " ( $wc $op $value )";
+      $fieldsub[] = " ( $wc $op $value )";
       if ($config->includeNickNameInName) {
         $wc = self::caseImportant($op) ? "LOWER(contact_a.nick_name)" : "contact_a.nick_name";
-        $sub[] = " ( $wc $op $value )";
+        $fieldsub[] = " ( $wc $op $value )";
       }
       if ($config->includeEmailInName) {
-        $sub[] = " ( civicrm_email.email $op $value ) ";
-      }
-    }
-    else {
-      // the string should be treated as a series of keywords to be matched with match ANY OR
-      // match ALL depending on Civi config settings (see CiviAdmin)
-
-      // The Civi configuration setting can be overridden if the string *starts* with the case
-      // insenstive strings 'AND:' or 'OR:'TO THINK ABOUT: what happens when someone searches
-      // for the following "AND: 'a string in quotes'"? - probably nothing - it would make the
-      // AND OR variable reduntant because there is only one search string?
-
-      // Check to see if the $subGlue is overridden in the search text
-      if (strtolower(substr($name, 0, 4)) == 'and:') {
-        $name = substr($name, 4);
-        $subGlue = ' AND ';
-      }
-      if (strtolower(substr($name, 0, 3)) == 'or:') {
-        $name = substr($name, 3);
-        $subGlue = ' OR ';
-      }
-
-      $firstChar = substr($name, 0, 1);
-      $lastChar = substr($name, -1, 1);
-      $quotes = array("'", '"');
-      if ((strlen($name) > 2) && in_array($firstChar, $quotes) &&
-        in_array($lastChar, $quotes)
-      ) {
-        $name = substr($name, 1);
-        $name = substr($name, 0, -1);
-        $pieces = array($name);
-      }
-      else {
-        $pieces = explode(' ', $name);
-      }
-      foreach ($pieces as $piece) {
-        $value = $strtolower(CRM_Core_DAO::escapeString(trim($piece)));
-        if (strlen($value)) {
-          // Added If as a sanitization - without it, when you do an OR search, any string with
-          // double spaces (i.e. "  ") or that has a space after the keyword (e.g. "OR: ") will
-          // return all contacts because it will include a condition similar to "OR contact
-          // name LIKE '%'".  It might be better to replace this with array_filter.
-          $fieldsub = array();
-          if ($wildcard) {
-            if ($config->includeWildCardInName) {
-              $value = "'%$value%'";
-            }
-            else {
-              $value = "'$value%'";
-            }
-            $op = 'LIKE';
-          }
-          else {
-            $value = "'$value'";
-          }
-          if ($newName == 'sort_name') {
-            $wc = self::caseImportant($op) ? "LOWER(contact_a.sort_name)" : "contact_a.sort_name";
-          }
-          else {
-            $wc = self::caseImportant($op) ? "LOWER(contact_a.display_name)" : "contact_a.display_name";
-          }
-          $fieldsub[] = " ( $wc $op $value )";
-          if ($config->includeNickNameInName) {
-            $wc = self::caseImportant($op) ? "LOWER(contact_a.nick_name)" : "contact_a.nick_name";
-            $fieldsub[] = " ( $wc $op $value )";
-          }
-          if ($config->includeEmailInName) {
-            $fieldsub[] = " ( civicrm_email.email $op $value ) ";
-          }
-          $sub[] = ' ( ' . implode(' OR ', $fieldsub) . ' ) ';
-          // I seperated the glueing in two.  The first stage should always be OR because we are searching for matches in *ANY* of these fields
-        }
+        $fieldsub[] = " ( civicrm_email.email $op $value ) ";
       }
+      $sub[] = ' ( ' . implode(' OR ', $fieldsub) . ' ) ';
     }
 
     $sub = ' ( ' . implode($subGlue, $sub) . ' ) ';
@@ -3315,22 +3232,21 @@ WHERE  id IN ( $groupIDs )
     $this->_where[$grouping][] = $sub;
     if ($config->includeEmailInName) {
       $this->_tables['civicrm_email'] = $this->_whereTables['civicrm_email'] = 1;
-      $this->_qill[$grouping][] = ts('Name or Email') . " $op - '$name'";
+      $this->_qill[$grouping][] = ts('Name or Email') . " $op - '$input'";
     }
     else {
-      $this->_qill[$grouping][] = ts('Name like') . " - '$name'";
+      $this->_qill[$grouping][] = ts('Name') . " $op - '$input'";
     }
   }
 
   /**
-   * where / qill clause for email
+   * Where / qill clause for email
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function email(&$values) {
+  public function email(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $n = trim($value);
@@ -3366,14 +3282,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for phone number
+   * Where / qill clause for phone number
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function phone_numeric(&$values) {
+  public function phone_numeric(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
     // Strip non-numeric characters; allow wildcards
     $number = preg_replace('/[^\d%]/', '', $value);
@@ -3389,14 +3304,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for phone type/location
+   * Where / qill clause for phone type/location
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function phone_option_group($values) {
+  public function phone_option_group($values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
     $option = ($name == 'phone_phone_type_id' ? 'phone_type_id' : 'location_type_id');
     $options = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', $option);
@@ -3407,14 +3321,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for street_address
+   * Where / qill clause for street_address
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function street_address(&$values) {
+  public function street_address(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (!$op) {
@@ -3442,14 +3355,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for street_unit
+   * Where / qill clause for street_unit
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function street_number(&$values) {
+  public function street_number(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (!$op) {
@@ -3477,14 +3389,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for sorting by character
+   * Where / qill clause for sorting by character
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function sortByCharacter(&$values) {
+  public function sortByCharacter(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $name = trim($value);
@@ -3494,12 +3405,11 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for including contact ids
+   * Where / qill clause for including contact ids
    *
    * @return void
-   * @access public
    */
-  function includeContactIDs() {
+  public function includeContactIDs() {
     if (!$this->_includeContactIds || empty($this->_params)) {
       return;
     }
@@ -3516,14 +3426,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for postal code
+   * Where / qill clause for postal code
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function postalCode(&$values) {
+  public function postalCode(&$values) {
     // skip if the fields dont have anything to do with postal_code
     if (empty($this->_fields['postal_code'])) {
       return;
@@ -3558,15 +3467,14 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for location type
+   * Where / qill clause for location type
    *
    * @param $values
    * @param null $status
    *
    * @return void
-   * @access public
    */
-  function locationType(&$values, $status = NULL) {
+  public function locationType(&$values, $status = NULL) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (is_array($value)) {
@@ -3597,7 +3505,7 @@ WHERE  id IN ( $groupIDs )
    *
    * @return array
    */
-  function country(&$values, $fromStateProvince = TRUE) {
+  public function country(&$values, $fromStateProvince = TRUE) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (!$fromStateProvince) {
@@ -3678,15 +3586,14 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for county (if present)
+   * Where / qill clause for county (if present)
    *
    * @param $values
    * @param null $status
    *
    * @return void
-   * @access public
    */
-  function county(&$values, $status = null) {
+  public function county(&$values, $status = null) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (! is_array($value)) {
@@ -3747,15 +3654,14 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for state/province AND country (if present)
+   * Where / qill clause for state/province AND country (if present)
    *
    * @param $values
    * @param null $status
    *
    * @return void
-   * @access public
    */
-  function stateProvince(&$values, $status = NULL) {
+  public function stateProvince(&$values, $status = NULL) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     // quick escape for IS NULL
@@ -3842,14 +3748,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for change log
+   * Where / qill clause for change log
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function changeLog(&$values) {
+  public function changeLog(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $targetName = $this->getWhereValues('changed_by', $grouping);
@@ -3868,7 +3773,7 @@ WHERE  id IN ( $groupIDs )
   /**
    * @param $values
    */
-  function modifiedDates($values) {
+  public function modifiedDates($values) {
     $this->_useDistinct = TRUE;
 
     // CRM-11281, default to added date if not set
@@ -3892,7 +3797,7 @@ WHERE  id IN ( $groupIDs )
   /**
    * @param $values
    */
-  function demographics(&$values) {
+  public function demographics(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (($name == 'birth_date_low') || ($name == 'birth_date_high')) {
@@ -3914,7 +3819,7 @@ WHERE  id IN ( $groupIDs )
   /**
    * @param $values
    */
-  function privacy(&$values) {
+  public function privacy(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
     //fixed for profile search listing CRM-4633
     if (strpbrk($value, "[")) {
@@ -3933,7 +3838,7 @@ WHERE  id IN ( $groupIDs )
   /**
    * @param $values
    */
-  function privacyOptions($values) {
+  public function privacyOptions($values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     if (empty($value) || !is_array($value)) {
@@ -3973,7 +3878,7 @@ WHERE  id IN ( $groupIDs )
   /**
    * @param $values
    */
-  function preferredCommunication(&$values) {
+  public function preferredCommunication(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
 
     $pref = array();
@@ -4023,14 +3928,13 @@ WHERE  id IN ( $groupIDs )
   }
 
   /**
-   * where / qill clause for relationship
+   * Where / qill clause for relationship
    *
    * @param $values
    *
    * @return void
-   * @access public
    */
-  function relationship(&$values) {
+  public function relationship(&$values) {
     list($name, $op, $value, $grouping, $wildcard) = $values;
     if ($this->_relationshipValuesAdded){
        return;
@@ -4160,6 +4064,12 @@ civicrm_relationship.start_date > {$today}
       $this->_qill[$grouping][] = ts('Relationship - Inactive or not Current');
     }
 
+    $onlyDeleted = 0;
+    if (in_array(array('deleted_contacts', '=', '1', '0', '0'), $this->_params)) {
+      $onlyDeleted = 1;
+    }
+    $where[$grouping][] = "(contact_b.is_deleted = {$onlyDeleted})";
+
     //check for permissioned, non-permissioned and all permissioned relations
     if ($relPermission[2] == 1) {
       $where[$grouping][] = "(
@@ -4213,7 +4123,7 @@ civicrm_relationship.is_permission_a_b = 0
  * @param array $where = array to add where clauses to, in case you are generating a temp table
  * not the main query.
  */
-  function addRelationshipDateClauses($grouping, &$where){
+  public function addRelationshipDateClauses($grouping, &$where){
     $dateValues = array();
     $dateTypes = array(
         'start_date',
@@ -4237,14 +4147,13 @@ civicrm_relationship.is_permission_a_b = 0
   }
 
   /**
-   * default set of return properties
+   * Default set of return properties
    *
    * @param int $mode
    *
    * @return array derault return properties
-   * @access public
    */
-  static function &defaultReturnProperties($mode = 1) {
+  public static function &defaultReturnProperties($mode = 1) {
     if (!isset(self::$_defaultReturnProperties)) {
       self::$_defaultReturnProperties = array();
     }
@@ -4319,14 +4228,13 @@ civicrm_relationship.is_permission_a_b = 0
   }
 
   /**
-   * get primary condition for a sql clause
+   * Get primary condition for a sql clause
    *
    * @param int $value
    *
    * @return string|NULL
-   * @access public
    */
-  static function getPrimaryCondition($value) {
+  public static function getPrimaryCondition($value) {
     if (is_numeric($value)) {
       $value = (int ) $value;
       return ($value == 1) ? 'is_primary = 1' : 'is_primary = 0';
@@ -4335,16 +4243,15 @@ civicrm_relationship.is_permission_a_b = 0
   }
 
   /**
-   * wrapper for a simple search query
+   * Wrapper for a simple search query
    *
    * @param array $params
    * @param array $returnProperties
    * @param bool $count
    *
    * @return string
-   * @access public
    */
-  static function getQuery($params = NULL, $returnProperties = NULL, $count = FALSE) {
+  public static function getQuery($params = NULL, $returnProperties = NULL, $count = FALSE) {
     $query = new CRM_Contact_BAO_Query($params, $returnProperties);
     list($select, $from, $where, $having) = $query->query();
 
@@ -4366,14 +4273,12 @@ civicrm_relationship.is_permission_a_b = 0
    * @param string $sort
    * @param int $offset
    * @param int $row_count
-   * @param bool $smartGroupCache
+   * @param bool $smartGroupCache  ?? update smart group cache?
    * @param bool $count return count obnly
    * @param bool $skipPermissions Should permissions be ignored or should the logged in user's permissions be applied
    *
-   * @params bool $smartGroupCache ?? update smart group cache?
    *
    * @return array
-   * @access public
    */
   static function apiQuery(
     $params = NULL,
@@ -4453,7 +4358,7 @@ civicrm_relationship.is_permission_a_b = 0
   }
 
   /**
-   * create and query the db for an contact search
+   * Create and query the db for an contact search
    *
    * @param int $offset the offset for the query
    * @param int $rowCount the number of rows to return
@@ -4470,7 +4375,6 @@ civicrm_relationship.is_permission_a_b = 0
    * @param bool $skipOrderAndLimit
    *
    * @return CRM_Core_DAO
-   * @access public
    */
   function searchQuery(
     $offset = 0, $rowCount = 0, $sort = NULL,
@@ -4659,7 +4563,7 @@ civicrm_relationship.is_permission_a_b = 0
    * @param bool   $includeContactIds
    * @return CRM_Core_DAO
    */
-  function getCachedContacts($cacheKey, $offset, $rowCount, $includeContactIds) {
+  public function getCachedContacts($cacheKey, $offset, $rowCount, $includeContactIds) {
     $this->_includeContactIds = $includeContactIds;
     $onlyDeleted = in_array(array('deleted_contacts', '=', '1', '0', '0'), $this->_params);
     list($select, $from, $where) = $this->query(FALSE, FALSE, FALSE, $onlyDeleted);
@@ -4686,7 +4590,7 @@ civicrm_relationship.is_permission_a_b = 0
    *
    * @return null
    */
-  function generatePermissionClause($onlyDeleted = FALSE, $count = FALSE) {
+  public function generatePermissionClause($onlyDeleted = FALSE, $count = FALSE) {
     if (!$this->_skipPermission) {
       $this->_permissionWhereClause = CRM_ACL_API::whereClause(
         CRM_Core_Permission::VIEW,
@@ -4728,7 +4632,7 @@ civicrm_relationship.is_permission_a_b = 0
   /**
    * @param $val
    */
-  function setSkipPermission($val) {
+  public function setSkipPermission($val) {
     $this->_skipPermission = $val;
   }
 
@@ -4737,7 +4641,7 @@ civicrm_relationship.is_permission_a_b = 0
    *
    * @return array
    */
-  function &summaryContribution($context = NULL) {
+  public function &summaryContribution($context = NULL) {
     list($innerselect, $from, $where, $having) = $this->query(TRUE);
 
     // hack $select
@@ -4866,22 +4770,20 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
   }
 
   /**
-   * getter for the qill object
+   * Getter for the qill object
    *
    * @return string
-   * @access public
    */
-  function qill() {
+  public function qill() {
     return $this->_qill;
   }
 
   /**
-   * default set of return default hier return properties
+   * Default set of return default hier return properties
    *
    * @return array
-   * @access public
    */
-  static function &defaultHierReturnProperties() {
+  public static function &defaultHierReturnProperties() {
     if (!isset(self::$_defaultHierReturnProperties)) {
       self::$_defaultHierReturnProperties = array(
         'home_URL' => 1,
@@ -4961,9 +4863,9 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
 
   /**
    * @param $values
-   * @param $tableName
-   * @param $fieldName
-   * @param $dbFieldName
+   * @param string $tableName
+   * @param string $fieldName
+   * @param string $dbFieldName
    * @param $fieldTitle
    * @param bool $appendTimeStamp
    */
@@ -5074,9 +4976,9 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
 
   /**
    * @param $values
-   * @param $tableName
-   * @param $fieldName
-   * @param $dbFieldName
+   * @param string $tableName
+   * @param string $fieldName
+   * @param string $dbFieldName
    * @param $fieldTitle
    * @param null $options
    */
@@ -5166,9 +5068,8 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
    * @param string  $dataType    data type of the field
    *
    * @return string where clause for the query
-   * @access public
    */
-  static function buildClause($field, $op, $value = NULL, $dataType = NULL) {
+  public static function buildClause($field, $op, $value = NULL, $dataType = NULL) {
     $op = trim($op);
     $clause = "$field $op";
 
@@ -5231,7 +5132,7 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
    *
    * @return array
    */
-  function openedSearchPanes($reset = FALSE) {
+  public function openedSearchPanes($reset = FALSE) {
     if (!$reset || empty($this->_whereTables)) {
       return self::$_openedPanes;
     }
@@ -5265,7 +5166,7 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
   /**
    * @param $operator
    */
-  function setOperator($operator) {
+  public function setOperator($operator) {
     $validOperators = array('AND', 'OR');
     if (!in_array($operator, $validOperators)) {
       $operator = 'AND';
@@ -5276,7 +5177,7 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
   /**
    * @return string
    */
-  function getOperator() {
+  public function getOperator() {
     return $this->_operator;
   }
 
@@ -5285,7 +5186,7 @@ SELECT COUNT( conts.total_amount ) as cancel_count,
    * @param $where
    * @param $having
    */
-  function filterRelatedContacts(&$from, &$where, &$having) {
+  public function filterRelatedContacts(&$from, &$where, &$having) {
     static $_rTypeProcessed = NULL;
     static $_rTypeFrom = NULL;
     static $_rTypeWhere = NULL;
@@ -5361,7 +5262,7 @@ AND   displayRelType.is_active = 1
    *
    * @return bool
    */
-  static function caseImportant( $op ) {
+  public static function caseImportant( $op ) {
     return
       in_array($op, array('LIKE', 'IS NULL', 'IS NOT NULL', 'IS EMPTY', 'IS NOT EMPTY')) ? FALSE : TRUE;
   }
@@ -5372,7 +5273,7 @@ AND   displayRelType.is_active = 1
    *
    * @return bool
    */
-  static function componentPresent( &$returnProperties, $prefix ) {
+  public static function componentPresent( &$returnProperties, $prefix ) {
     foreach ($returnProperties as $name => $dontCare ) {
       if (substr($name, 0, strlen($prefix)) == $prefix) {
         return TRUE;
@@ -5388,14 +5289,12 @@ AND   displayRelType.is_active = 1
    * @param $op       string the sql operator, this function should handle ALL SQL operators
    * @param $value string|integer|array depends on the operator and who's calling the query builder
    * @param $grouping int    the index where to place the where clause
-   * @param $selectValues
+   * @param $selectValues the key value pairs for this element. This allows us to use this function for things besides option-value pairs
    * @param $field    array  an array that contains various properties of the field identified by $name
    * @param $label    string The label for this field element
    * @param $dataType string The data type for this element
-   *
    * @param bool $useIDsOnly
    *
-   * @internal param array $selectValue the key value pairs for this element. This allows us to use this function for things besides option-value pairs
    * @return void     adds the where clause and qill to the query object
    */
   function optionValueQuery(
@@ -5466,7 +5365,7 @@ AND   displayRelType.is_active = 1
   }
 
   /**
-   * function to check and explode a user defined numeric string into an array
+   * Check and explode a user defined numeric string into an array
    * this was the protocol used by search builder in the old old days before we had
    * super nice js widgets to do the hard work
    *
@@ -5477,7 +5376,7 @@ AND   displayRelType.is_active = 1
    *         array of numeric values if string does match the pattern
    * @static
    */
-  static function parseSearchBuilderString($string, $dataType = 'Integer') {
+  public static function parseSearchBuilderString($string, $dataType = 'Integer') {
     $string = trim($string);
     if (substr($string, 0, 1) != '(' || substr($string, -1, 1) != ')') {
       Return FALSE;
@@ -5508,14 +5407,14 @@ AND   displayRelType.is_active = 1
   }
 
   /**
-   * convert the pseudo constants id's to their names
+   * Convert the pseudo constants id's to their names
    *
    * @param CRM_Core_DAO dao
    * @param bool $return
    *
    * @return array
    */
-  function convertToPseudoNames(&$dao, $return = FALSE) {
+  public function convertToPseudoNames(&$dao, $return = FALSE) {
     if (empty($this->_pseudoConstantsSelect)) {
       return;
     }
@@ -5584,12 +5483,12 @@ AND   displayRelType.is_active = 1
   }
 
   /**
-   * include pseudo fields LEFT JOIN
+   * Include pseudo fields LEFT JOIN
    * @param string|array $sort  can be a object or string
    *
    * @return array
    */
-  function includePseudoFieldsJoin($sort) {
+  public function includePseudoFieldsJoin($sort) {
     if (!$sort || empty($this->_pseudoConstantsSelect)) {
       return;
     }