private function json2criteria(&$json) { if (is_string($json)) { $search_structure = json_decode($json, true); } else { $search_structure = $json; } if (empty($search_structure) or !is_array($search_structure)) { throw new vB_Exception_Api('invalid_search_syntax', array($json)); } $criteria = new vB_Search_Criteria(); $def_sort_field = 'created'; $def_sort_dir = 'DESC'; $currentUserId = vB::getCurrentSession()->get('userid'); $criteria->setUser($currentUserId); $normalized_criteria = array(); if (!empty($search_structure['keywords'])) { $words = $criteria->add_keyword_filter($search_structure['keywords'], !empty($search_structure['title_only'])); $def_sort_field = 'lastcontent'; if (!empty($words)) { $normalized_criteria['keywords'] = ''; $separator = ''; foreach ($words as $word) { if (!empty($word['joiner'])) { $normalized_criteria['keywords'] .= $separator . strtoupper($word['joiner']); $separator = ' '; } $normalized_criteria['keywords'] .= $separator . $word['word']; $separator = ' '; } if (!empty($search_structure['title_only'])) { $normalized_criteria['title_only'] = 1; } } else { $normalized_criteria['error'] = 'ignored_search_keywords'; } $ignored_words = $criteria->get_ignored_keywords(); if (!empty($ignored_words)) { $normalized_criteria['ignored_words'] = $ignored_words; $normalized_criteria['original_keywords'] = $search_structure['keywords']; } } if (!empty($search_structure['contenttypeid'])) { $search_structure['type'] = vB_Types::instance()->getContentTypeClasses($search_structure['contenttypeid']); if (count($search_structure['type']) == 1) { $search_structure['type'] = array_pop($search_structure['type']); } unset($search_structure['contenttypeid']); } if (!empty($search_structure['type'])) { $contentypeids = $criteria->add_contenttype_filter($search_structure['type']); $normalized_criteria['type'] = $search_structure['type']; $pmcontentypeid = vB_Types::instance()->getContentTypeID('vBForum_PrivateMessage'); if (in_array($pmcontentypeid, $contentypeids)) { if (count($contentypeids) == 1) { $search_structure['private_messages_only'] = 1; } else { $search_structure['include_private_messages'] = 1; } } $vmcontentypeid = vB_Types::instance()->getContentTypeID('vBForum_VisitorMessage'); if (in_array($vmcontentypeid, $contentypeids)) { if (count($contentypeids) == 1) { $search_structure['visitor_messages_only'] = 1; } else { $search_structure['include_visitor_messages'] = 1; } } $photocontentypeid = vB_Api::instanceInternal('contenttype')->fetchContentTypeIdFromClass('Photo'); if (in_array($photocontentypeid, $contentypeids)) { $search_structure['include_attach'] = 1; } } elseif (empty($search_structure['exclude_type']) or is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] != 'vBForum_PrivateMessage' or is_array($search_structure['exclude_type']) and !in_array('vBForum_PrivateMessage', $search_structure['exclude_type'])) { $search_structure['include_private_messages'] = 1; } elseif (!empty($search_structure['exclude_type']) and (is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] == 'vBForum_VisitorMessage' or is_array($search_structure['exclude_type']) and in_array('vBForum_VisitorMessage', $search_structure['exclude_type']))) { $search_structure['exclude_visitor_messages'] = 1; } if (empty($search_structure['type']) and empty($search_structure['exclude_visitor_messages']) and (empty($search_structure['exclude_type']) or is_string($search_structure['exclude_type']) and $search_structure['exclude_type'] != 'vBForum_VisitorMessage' or is_array($search_structure['exclude_type']) and !in_array('vBForum_VisitorMessage', $search_structure['exclude_type']))) { $search_structure['include_visitor_messages'] = 1; } // author by username if (!empty($search_structure['author'])) { //reducing users from array to single if (is_array($search_structure['author']) and count($search_structure['author']) == 1) { $search_structure['author'] = array_pop($search_structure['author']); $search_structure['exactname'] = 1; } // only one username if (is_string($search_structure['author'])) { // it's an exact username - no partial match if (!empty($search_structure['exactname'])) { $search_structure['author'] = trim($search_structure['author']); switch ($search_structure['author']) { case 'myFriends': $userid = array(); if (!empty($currentUserId)) { $userid = vB::getDbAssertor()->getColumn('userlist', 'relationid', array('userid' => $currentUserId, 'friend' => 'yes'), false, 'relationid'); } $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $userid, true); break; case 'iFollow': if (empty($search_structure[self::FILTER_FOLLOW])) { $search_structure[self::FILTER_FOLLOW] = self::FILTER_FOLLOWING_USERS; } elseif ($search_structure[self::FILTER_FOLLOW] == self::FILTER_FOLLOWING_CHANNEL) { $search_structure[self::FILTER_FOLLOW] = self::FILTER_FOLLOWING_BOTH; } break; default: $criteria->add_user_filter($search_structure['author'], !empty($search_structure['exactname'])); break; } $normalized_criteria['author'] = strtolower($search_structure['author']); $normalized_criteria['exactname'] = 1; } elseif (vb_String::vbStrlen($search_structure['author']) >= 3) { $criteria->add_user_filter($search_structure['author'], !empty($search_structure['exactname'])); $normalized_criteria['author'] = strtolower($search_structure['author']); } } elseif (is_array($search_structure['author'])) { $user_names = array(); foreach ($search_structure['author'] as $author) { $author = vB_String::htmlSpecialCharsUni($author); $user = vB_Api::instanceInternal("User")->fetchByUsername($author); $userid = false; if (!empty($user['userid'])) { $user_ids[] = $user['userid']; $user_names[] = $user['username']; } } if (!empty($user_ids)) { $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $user_ids, true); } else { $criteria->add_null_filter('no record matches usernames'); } sort($user_names); $normalized_criteria['author'] = $user_names; } } // author by userid if (!empty($search_structure['authorid'])) { //reducing users from array to single if (is_array($search_structure['authorid']) and count($search_structure['authorid']) == 1) { $search_structure['authorid'] = array_pop($search_structure['authorid']); } if (is_numeric($search_structure['authorid'])) { if (!empty($search_structure['visitor_messages_only'])) { $criteria->add_filter('visitor_messages_only', vB_Search_Core::OP_EQ, $search_structure['authorid']); $normalized_criteria['visitor_messages_only'] = 1; } elseif (!empty($search_structure['include_visitor_messages'])) { $criteria->add_filter('include_visitor_messages', vB_Search_Core::OP_EQ, $search_structure['authorid']); $normalized_criteria['include_visitor_messages'] = 1; } else { $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $search_structure['authorid'], true); } if (!empty($search_structure['exclude_visitor_messages'])) { $criteria->add_filter('exclude_visitor_messages', vB_Search_Core::OP_EQ, $search_structure['authorid']); $normalized_criteria['exclude_visitor_messages'] = 1; } $normalized_criteria['authorid'] = $search_structure['authorid']; } elseif (is_array($search_structure['authorid'])) { $user_ids = array(); foreach ($search_structure['authorid'] as $author) { if (is_numeric($author)) { $user_ids[] = intval($author); } } $criteria->add_filter('userid', vB_Search_Core::OP_EQ, $user_ids, true); $normalized_criteria['authorid'] = sort($user_ids); } } else { if (!empty($search_structure['exclude_visitor_messages'])) { $criteria->add_filter('exclude_visitor_messages', vB_Search_Core::OP_EQ, 0); $normalized_criteria['exclude_visitor_messages'] = 1; } } // channel owner filter if (!empty($search_structure['my_channels'])) { $temp = array(); // restrict 'type' to string 'blog' or 'group', else default to 'blog' if (isset($search_structure['my_channels']['type']) and ($search_structure['my_channels']['type'] == 'blog' or $search_structure['my_channels']['type'] == 'group')) { $temp['type'] = $search_structure['my_channels']['type']; } else { $temp['type'] = 'blog'; } $normalized_criteria['my_channels'] = $temp; $criteria->add_filter('my_channels', vB_Search_Core::OP_EQ, $temp); unset($temp); } if (!empty($search_structure['private_messages_only'])) { $criteria->add_filter('private_messages_only', vB_Search_Core::OP_EQ, $currentUserId); $normalized_criteria['private_messages_only'] = 1; } // visitor message recipient if (!empty($search_structure['sentto'])) { //reducing users from array to single if (is_array($search_structure['sentto']) and count($search_structure['sentto']) == 1) { $search_structure['sentto'] = array_pop($search_structure['sentto']); } if (is_numeric($search_structure['sentto'])) { $criteria->add_filter('sentto', vB_Search_Core::OP_EQ, intval($search_structure['sentto'])); $normalized_criteria['visitor_messages_only'] = 1; $normalized_criteria['sentto'] = intval($search_structure['sentto']); } elseif (is_array($search_structure['sentto'])) { $user_ids = array_map('intval', $search_structure['sentto']); sort($user_ids); $criteria->add_filter('sentto', vB_Search_Core::OP_EQ, $user_ids); $normalized_criteria['visitor_messages_only'] = 1; $normalized_criteria['sentto'] = $user_ids; } } if (!empty($search_structure['tag'])) { if (is_array($search_structure['tag'])) { foreach ($search_structure['tag'] as $index => $tag) { $search_structure['tag'][$index] = vB_String::htmlSpecialCharsUni(trim($tag)); } } else { $search_structure['tag'] = vB_String::htmlSpecialCharsUni(trim($search_structure['tag'])); } $existing_tags = $criteria->add_tag_filter($search_structure['tag']); $normalized_criteria['tag'] = array_keys($existing_tags); vB_Api::instanceInternal('Tags')->logSearchTags($existing_tags); } if (!empty($search_structure['date'])) { if ($search_structure['date'] == self::FILTER_LASTVISIT) { $current_user = new vB_Legacy_CurrentUser(); $dateline = $current_user->get_field('lastvisit'); if (empty($dateline)) { $dateline = vB::getRequest()->getTimeNow() - 86400 * 14; } $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline); $normalized_criteria['date'] = self::FILTER_LASTVISIT; } if ($search_structure['date'] == self::FILTER_TOPICAGE) { $age = vB::getDatastore()->getOption('max_age_topic'); if (intval($age) == 0) { $age = 60; } $criteria->add_date_filter(vB_Search_Core::OP_GT, vB::getRequest()->getTimeNow() - 86400 * $age); $normalized_criteria['date'] = self::FILTER_TOPICAGE; } if ($search_structure['date'] == self::FILTER_CHANNELAGE) { $age = vB::getDatastore()->getOption('max_age_channel'); if (intval($age) == 0) { $age = 60; } $criteria->add_date_filter(vB_Search_Core::OP_GT, vB::getRequest()->getTimeNow() - 86400 * $age); $normalized_criteria['date'] = self::FILTER_CHANNELAGE; } // forcing to get the whole date spectrum; activity stream view enforces a date range so this is the workaround if (!empty($search_structure['date']) and is_string($search_structure['date']) and $search_structure['date'] == self::FILTER_DATEALL) { $criteria->add_date_filter(vB_Search_Core::OP_EQ, self::FILTER_DATEALL); $normalized_criteria['date'] = self::FILTER_DATEALL; } if (is_array($search_structure['date']) and !empty($search_structure['date']['from'])) { $dateline = $this->computeDateLine($search_structure['date']['from']); if (!empty($dateline)) { $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline); $normalized_criteria['date']['from'] = $search_structure['date']['from']; } } if (is_array($search_structure['date']) and !empty($search_structure['date']['to'])) { $dateline = $this->computeDateLine($search_structure['date']['to'], true); if (!empty($dateline)) { $criteria->add_date_filter(vB_Search_Core::OP_LT, $dateline); $normalized_criteria['date']['to'] = $search_structure['date']['to']; } } } if (!empty($search_structure['last'])) { if (is_array($search_structure['last']) and !empty($search_structure['last']['from'])) { $dateline = $this->computeDateLine($search_structure['last']['from']); if (!empty($dateline)) { $criteria->add_last_filter(vB_Search_Core::OP_GT, $dateline); $normalized_criteria['last']['from'] = $search_structure['last']['from']; } } if (is_array($search_structure['last']) and !empty($search_structure['last']['to'])) { $dateline = $this->computeDateLine($search_structure['last']['to'], true); if (!empty($dateline)) { $criteria->add_last_filter(vB_Search_Core::OP_LT, $dateline); $normalized_criteria['last']['to'] = $search_structure['last']['to']; } } } if (!empty($search_structure['exclude'])) { $criteria->add_exclude_filter($search_structure['exclude']); $normalized_criteria['exclude'] = $search_structure['exclude']; } if (empty($search_structure['sort'])) { $search_structure['sort'] = array($def_sort_field => $def_sort_dir); } if (!is_array($search_structure['sort'])) { $sort_dir = $def_sort_dir; if (strtolower($search_structure['sort']) == 'title') { $sort_dir = 'ASC'; } $search_structure['sort'] = array($search_structure['sort'] => $sort_dir); } foreach ($search_structure['sort'] as $sort_field => $sort_dir) { $criteria->set_sort($sort_field, strtoupper($sort_dir)); } if ($sort_field != $def_sort_field or $sort_dir != $def_sort_dir) { $normalized_criteria['sort'] = array($sort_field => strtoupper($sort_dir)); } if (!empty($search_structure['view'])) { if ($search_structure['view'] == vB_Api_Search::FILTER_VIEW_CONVERSATION_STREAM and !empty($search_structure['channel'])) { $search_structure['depth'] = 2; $search_structure['include_starter'] = true; } elseif ($search_structure['view'] == vB_Api_Search::FILTER_VIEW_CONVERSATION_THREAD and !empty($search_structure['channel'])) { $search_structure['depth'] = 1; $search_structure['include_starter'] = true; } else { $criteria->add_view_filter($search_structure['view']); $normalized_criteria['view'] = $search_structure['view']; } } if (!empty($search_structure['starter_only'])) { $criteria->add_filter('starter_only', vB_Search_Core::OP_EQ, true); $search_structure['include_starter'] = true; $normalized_criteria['starter_only'] = 1; } if (!empty($search_structure['reply_only'])) { $criteria->add_filter('reply_only', vB_Search_Core::OP_EQ, true); $search_structure['include_starter'] = false; $normalized_criteria['reply_only'] = 1; } if (!empty($search_structure['comment_only'])) { $criteria->add_filter('comment_only', vB_Search_Core::OP_EQ, true); $search_structure['include_starter'] = false; $normalized_criteria['comment_only'] = 1; } if (!empty($search_structure['channel'])) { $criteria->add_channel_filter($search_structure['channel'], empty($search_structure['depth']) ? false : $search_structure['depth'], empty($search_structure['include_starter']) ? false : true, empty($search_structure['depth_exact']) ? false : true); $normalized_criteria['channel'] = $search_structure['channel']; if (!empty($search_structure['depth'])) { $normalized_criteria['depth'] = $search_structure['depth']; } if (!empty($search_structure['depth_exact'])) { $normalized_criteria['depth_exact'] = true; } if (!empty($search_structure['include_starter'])) { $normalized_criteria['include_starter'] = 1; } } if (!empty($search_structure['featured'])) { $criteria->add_filter('featured', vB_Search_Core::OP_EQ, $search_structure['featured']); $normalized_criteria['featured'] = 1; } if (!empty($search_structure[self::FILTER_FOLLOW])) { if (is_string($search_structure[self::FILTER_FOLLOW]) and !empty($currentUserId)) { $criteria->add_follow_filter($search_structure[self::FILTER_FOLLOW], $currentUserId); $normalized_criteria[self::FILTER_FOLLOW] = $search_structure[self::FILTER_FOLLOW]; } elseif (is_array($search_structure[self::FILTER_FOLLOW])) { list($type, $userid) = each($search_structure[self::FILTER_FOLLOW]); //if ($userid == $currentUserId) //{ $criteria->add_follow_filter($type, $userid); $normalized_criteria[self::FILTER_FOLLOW] = $search_structure[self::FILTER_FOLLOW]; //} } } if (!empty($search_structure['my_following']) and !empty($currentUserId)) { $criteria->add_follow_filter(self::FILTER_FOLLOWING_CHANNEL, $currentUserId); $normalized_criteria['my_following'] = $search_structure['my_following']; } if (!empty($search_structure['exclude_type'])) { $criteria->add_contenttype_filter($search_structure['exclude_type'], vB_Search_Core::OP_NEQ); $normalized_criteria['exclude_type'] = $search_structure['exclude_type']; } if (!empty($search_structure['sticky_only'])) { $criteria->add_filter('sticky', vB_Search_Core::OP_EQ, '1'); $normalized_criteria['sticky_only'] = 1; } if (!empty($search_structure['exclude_sticky'])) { $criteria->add_filter('sticky', vB_Search_Core::OP_NEQ, '1'); $normalized_criteria['exclude_sticky'] = 1; } if (!empty($search_structure['include_sticky'])) { $criteria->set_include_sticky(); $normalized_criteria['include_sticky'] = 1; } if (empty($search_structure['include_blocked']) or empty($currentUserId) or !vB::getUserContext()->hasPermission('moderatorpermissions', 'canbanusers')) { //block people on the global ignore list. $globalignore = trim(vB::getDatastore()->getOption('globalignore')); if (!empty($globalignore)) { $blocked = preg_split('#\\s+#s', $globalignore, -1, PREG_SPLIT_NO_EMPTY); //the user can always see their own posts, so if they are in the blocked list we remove them if (!empty($currentUserId)) { $bbuserkey = array_search($currentUserId, $blocked); if ($bbuserkey !== FALSE and $bbuserkey !== NULL) { unset($blocked["{$bbuserkey}"]); } } //Make sure we didn't just empty the list if (!empty($blocked)) { $criteria->add_filter('userid', vB_Search_Core::OP_NEQ, $blocked, false, true); } } } elseif (!empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canbanusers')) { $normalized_criteria['include_blocked'] = 1; } if (empty($search_structure['include_blocked']) and !empty($currentUserId)) { $currentUserInfo = vB_User::fetchUserinfo($currentUserId); if (!empty($currentUserInfo['ignorelist'])) { $criteria->add_filter('userid', vB_Search_Core::OP_NEQ, explode(' ', $currentUserInfo['ignorelist']), false, true); } } if (!empty($search_structure['ignore_protected'])) { $criteria->add_filter('protected', vB_Search_Core::OP_NEQ, '1'); $normalized_criteria['ignore_protected'] = 1; } if (!empty($search_structure['deleted_only']) and !empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canremoveposts')) { $criteria->add_filter('showpublished', vB_Search_Core::OP_EQ, '0'); $criteria->add_filter('deleteuserid', vB_Search_Core::OP_NEQ, '0'); $normalized_criteria['deleted_only'] = 1; } if (!empty($search_structure['exclude_deleted'])) { $criteria->add_filter('showpublished', vB_Search_Core::OP_EQ, '1'); $normalized_criteria['exclude_deleted'] = 1; } if (empty($search_structure['include_attach'])) { $criteria->add_filter('inlist', vB_Search_Core::OP_EQ, 1); } else { $normalized_criteria['include_attach'] = 1; } if (!empty($search_structure['unapproved_only']) and !empty($currentUserId) and vB::getUserContext()->hasPermission('moderatorpermissions', 'canmanagethreads')) { $criteria->add_filter('approved', vB_Search_Core::OP_NEQ, '1'); $normalized_criteria['unapproved_only'] = 1; } if (!empty($search_structure['unread_only']) and !empty($currentUserId) and vB::getDatastore()->getOption('threadmarking') > 0) { $criteria->add_filter('marked', vB_Search_Core::OP_EQ, self::FILTER_MARKED_UNREAD); $normalized_criteria['unread_only'] = 1; } if (!empty($search_structure['specific'])) { $criteria->add_filter('nodeid', vB_Search_Core::OP_EQ, $search_structure['specific']); $normalized_criteria['specific'] = $search_structure['specific']; } if (!empty($search_structure['prefix'])) { $normalized_criteria['prefix'] = $search_structure['prefix']; $criteria->add_filter('prefixid', vB_Search_Core::OP_EQ, $search_structure['prefix']); } if (!empty($search_structure['has_prefix'])) { $normalized_criteria['has_prefix'] = 1; $criteria->add_filter('prefixid', vB_Search_Core::OP_NEQ, ''); } if (!empty($search_structure['no_prefix'])) { $normalized_criteria['no_prefix'] = 0; $criteria->add_filter('prefixid', vB_Search_Core::OP_EQ, ''); } // private messages are included by default. Use the exclude_type filter to exlude them // they are not included if a specific channel is requested OR looking for visitor messages if (!empty($search_structure['include_private_messages']) and empty($normalized_criteria['private_messages_only']) and empty($normalized_criteria['sentto']) and (empty($normalized_criteria['channel']) or is_numeric($normalized_criteria['channel']) and !in_array($normalized_criteria['channel'], array(vB_Channel::MAIN_CHANNEL, vB_Channel::DEFAULT_CHANNEL_PARENT, vB_Channel::PRIVATEMESSAGE_CHANNEL)) or is_array($normalized_criteria['channel']) and count(array_intersect($normalized_criteria['channel'], array(vB_Channel::MAIN_CHANNEL, vB_Channel::DEFAULT_CHANNEL_PARENT, vB_Channel::PRIVATEMESSAGE_CHANNEL))) == 0) and empty($normalized_criteria['my_channels'])) { $criteria->add_filter('include_private_messages', vB_Search_Core::OP_EQ, $currentUserId); } if (!empty($search_structure['nolimit']) and !empty($normalized_criteria['channel']) and (empty($normalized_criteria['view']) or $normalized_criteria['view'] != self::FILTER_VIEW_ACTIVITY) and empty($search_structure['author']) and empty($search_structure['authorid']) and empty($search_structure['keywords']) and empty($search_structure['sentto']) and empty($search_structure['private_messages_only']) and empty($search_structure['tag']) and empty($search_structure['featured']) and empty($search_structure['my_following']) and empty($search_structure['unapproved_only']) and empty($search_structure['unread_only'])) { $normalized_criteria['nolimit'] = 1; $criteria->setNoLimit(); } // Two pass caching can be disabled by either ignore_cache which // also disabled the searchlog table or by specifying 'disable_two_pass' // Two pass caching can be forced on when 'ignore_cache' has been called // by specifying 'force_two_pass' (for unit testing the two pass cache functionality itself) if (!empty($search_structure['ignore_cache']) or self::IGNORE_CACHE) { $normalized_criteria['disable_two_pass'] = 1; $criteria->setIgnoreCache(true); } if (!empty($search_structure['disable_two_pass'])) { $normalized_criteria['disable_two_pass'] = 1; } if (!empty($search_structure['force_two_pass']) and !empty($normalized_criteria['disable_two_pass'])) { unset($normalized_criteria['disable_two_pass']); } //checking for a restrictive filter if (empty($normalized_criteria['keywords']) and empty($normalized_criteria['authorid']) and empty($normalized_criteria['author']) and empty($normalized_criteria['private_messages_only']) and empty($normalized_criteria['visitor_messages_only']) and empty($normalized_criteria['sentto']) and empty($normalized_criteria['tag']) and (empty($normalized_criteria['date']) or is_string($normalized_criteria['date']) and $normalized_criteria['date'] == self::FILTER_DATEALL) and (empty($normalized_criteria['last']) or is_string($normalized_criteria['last']) and $normalized_criteria['last'] == self::FILTER_DATEALL) and empty($normalized_criteria['channel']) and empty($normalized_criteria['featured']) and empty($normalized_criteria[self::FILTER_FOLLOW]) and empty($normalized_criteria['my_following']) and empty($normalized_criteria['sticky_only']) and empty($normalized_criteria['deleted_only']) and empty($normalized_criteria['unapproved_only']) and empty($normalized_criteria['unread_only']) and empty($normalized_criteria['specific']) and empty($normalized_criteria['prefix']) and empty($normalized_criteria['has_prefix']) and empty($normalized_criteria['no_prefix']) and empty($normalized_criteria['my_channels'])) { //temporary solution for VBV-10061 if ($normalized_criteria['view'] == self::FILTER_VIEW_ACTIVITY) { $dateline = $this->computeDateLine(self::FILTER_LASTMONTH); if (!empty($dateline)) { $criteria->add_date_filter(vB_Search_Core::OP_GT, $dateline); } } else { throw new vB_Exception_Api('criteria_not_restrictive', array($normalized_criteria)); } } $criteria->setJSON($normalized_criteria); $json = $normalized_criteria; // allow the clients to send custom fields that will be preserved if (!empty($search_structure['custom'])) { $json['custom'] = $search_structure['custom']; } return $criteria; }