3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
35 class CRM_Contact_Form_Search_Custom_RandomSegment
extends CRM_Contact_Form_Search_Custom_Base
implements CRM_Contact_Form_Search_Interface
{
37 protected $_debug = 0;
42 public function __construct(&$formValues) {
43 parent
::__construct($formValues);
45 $this->_columns
= array(
46 ts('Contact ID') => 'contact_id',
47 ts('Contact Type') => 'contact_type',
48 ts('Name') => 'sort_name',
49 ts('Email') => 'email',
55 public function initialize() {
56 $this->_segmentSize
= CRM_Utils_Array
::value('segmentSize', $this->_formValues
);
58 $this->_includeGroups
= CRM_Utils_Array
::value('includeGroups', $this->_formValues
);
60 $this->_excludeGroups
= CRM_Utils_Array
::value('excludeGroups', $this->_formValues
);
62 $this->_allSearch
= FALSE;
63 $this->_groups
= FALSE;
65 if (empty($this->_includeGroups
) && empty($this->_excludeGroups
)) {
67 $this->_allSearch
= TRUE;
70 if (!empty($this->_includeGroups
) ||
!empty($this->_excludeGroups
)) {
72 $this->_groups
= TRUE;
77 * @param CRM_Core_Form $form
79 public function buildForm(&$form) {
86 $groups = CRM_Core_PseudoConstant
::nestedGroup();
88 $select2style = array(
90 'style' => 'width: 100%; max-width: 60em;',
91 'class' => 'crm-select2',
92 'placeholder' => ts('- select -'),
95 $form->add('select', 'includeGroups',
96 ts('Include Group(s)'),
102 $form->add('select', 'excludeGroups',
103 ts('Exclude Group(s)'),
109 $this->setTitle('Create a random segment of contacts');
112 * if you are using the standard template, this array tells the template what elements
113 * are part of the search criteria
115 $form->assign('elements', array('segmentSize', 'includeGroups', 'excludeGroups'));
121 public function summary() {
127 * @param int $rowcount
129 * @param bool $includeContactIDs
130 * @param bool $justIDs
135 $offset = 0, $rowcount = 0, $sort = NULL,
136 $includeContactIDs = FALSE, $justIDs = FALSE
139 $selectClause = "contact_a.id as contact_id";
142 $selectClause = "contact_a.id as contact_id,
143 contact_a.contact_type as contact_type,
144 contact_a.sort_name as sort_name,
145 civicrm_email.email as email";
148 return $this->sql($selectClause,
149 $offset, $rowcount, $sort,
150 $includeContactIDs, NULL
157 public function from() {
159 $randomNum = md5(uniqid());
160 $this->_tableName
= "civicrm_temp_custom_{$randomNum}";
162 //block for Group search
163 $smartGroup = array();
164 $group = new CRM_Contact_DAO_Group();
165 $group->is_active
= 1;
167 while ($group->fetch()) {
168 $allGroups[] = $group->id
;
169 if ($group->saved_search_id
) {
170 $smartGroup[$group->saved_search_id
] = $group->id
;
173 $includedGroups = implode(',', $allGroups);
175 if (!empty($this->_includeGroups
)) {
176 $iGroups = implode(',', $this->_includeGroups
);
179 //if no group selected search for all groups
180 $iGroups = $includedGroups;
182 if (is_array($this->_excludeGroups
)) {
183 $xGroups = implode(',', $this->_excludeGroups
);
189 $sql = "DROP TEMPORARY TABLE IF EXISTS Xg_{$this->_tableName}";
190 CRM_Core_DAO
::executeQuery($sql);
191 $sql = "CREATE TEMPORARY TABLE Xg_{$this->_tableName} ( contact_id int primary key) ENGINE=HEAP";
192 CRM_Core_DAO
::executeQuery($sql);
194 //used only when exclude group is selected
196 $excludeGroup = "INSERT INTO Xg_{$this->_tableName} ( contact_id )
197 SELECT DISTINCT civicrm_group_contact.contact_id
198 FROM civicrm_group_contact
200 civicrm_group_contact.status = 'Added' AND
201 civicrm_group_contact.group_id IN ( {$xGroups} )";
203 CRM_Core_DAO
::executeQuery($excludeGroup);
205 //search for smart group contacts
206 foreach ($this->_excludeGroups
as $keys => $values) {
207 if (in_array($values, $smartGroup)) {
208 $ssId = CRM_Utils_Array
::key($values, $smartGroup);
210 $smartSql = CRM_Contact_BAO_SavedSearch
::contactIDsSQL($ssId);
212 $smartSql = $smartSql . " AND contact_a.id NOT IN (
213 SELECT contact_id FROM civicrm_group_contact
214 WHERE civicrm_group_contact.group_id = {$values} AND civicrm_group_contact.status = 'Removed')";
216 $smartGroupQuery = " INSERT IGNORE INTO Xg_{$this->_tableName}(contact_id) $smartSql";
218 CRM_Core_DAO
::executeQuery($smartGroupQuery);
223 $sql = "DROP TEMPORARY TABLE IF EXISTS Ig_{$this->_tableName}";
224 CRM_Core_DAO
::executeQuery($sql);
225 $sql = "CREATE TEMPORARY TABLE Ig_{$this->_tableName}
226 ( id int PRIMARY KEY AUTO_INCREMENT,
228 group_names varchar(64)) ENGINE=HEAP";
230 if ($this->_debug
> 0) {
231 print "-- Include groups query: <pre>";
236 CRM_Core_DAO
::executeQuery($sql);
238 $includeGroup = "INSERT INTO Ig_{$this->_tableName} (contact_id, group_names)
239 SELECT civicrm_group_contact.contact_id, civicrm_group.name as group_name
240 FROM civicrm_group_contact
241 LEFT JOIN civicrm_group
242 ON civicrm_group_contact.group_id = civicrm_group.id";
244 //used only when exclude group is selected
246 $includeGroup .= " LEFT JOIN Xg_{$this->_tableName}
247 ON civicrm_group_contact.contact_id = Xg_{$this->_tableName}.contact_id";
249 $includeGroup .= " WHERE
250 civicrm_group_contact.status = 'Added' AND
251 civicrm_group_contact.group_id IN($iGroups)";
253 //used only when exclude group is selected
255 $includeGroup .= " AND Xg_{$this->_tableName}.contact_id IS null";
258 if ($this->_debug
> 0) {
259 print "-- Include groups query: <pre>";
260 print "$includeGroup;";
264 CRM_Core_DAO
::executeQuery($includeGroup);
266 //search for smart group contacts
267 foreach ($this->_includeGroups
as $keys => $values) {
268 if (in_array($values, $smartGroup)) {
270 $ssId = CRM_Utils_Array
::key($values, $smartGroup);
272 $smartSql = CRM_Contact_BAO_SavedSearch
::contactIDsSQL($ssId);
274 $smartSql .= " AND contact_a.id NOT IN (
275 SELECT contact_id FROM civicrm_group_contact
276 WHERE civicrm_group_contact.group_id = {$values} AND civicrm_group_contact.status = 'Removed')";
278 //used only when exclude group is selected
280 $smartSql .= " AND contact_a.id NOT IN (SELECT contact_id FROM Xg_{$this->_tableName})";
283 $smartGroupQuery = " INSERT IGNORE INTO Ig_{$this->_tableName}(contact_id)
286 CRM_Core_DAO
::executeQuery($smartGroupQuery);
287 $insertGroupNameQuery = "UPDATE IGNORE Ig_{$this->_tableName}
288 SET group_names = (SELECT title FROM civicrm_group
289 WHERE civicrm_group.id = $values)
290 WHERE Ig_{$this->_tableName}.contact_id IS NOT NULL
291 AND Ig_{$this->_tableName}.group_names IS NULL";
292 CRM_Core_DAO
::executeQuery($insertGroupNameQuery);
296 $from = "FROM civicrm_contact contact_a";
298 $fromTail = "LEFT JOIN civicrm_email ON ( contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1 )";
300 $fromTail .= " INNER JOIN Ig_{$this->_tableName} temptable1 ON (contact_a.id = temptable1.contact_id)";
302 // now create a temp table to store the randomized contacts
303 $sql = "DROP TEMPORARY TABLE IF EXISTS random_{$this->_tableName}";
304 CRM_Core_DAO
::executeQuery($sql);
305 $sql = "CREATE TEMPORARY TABLE random_{$this->_tableName} ( id int primary key ) ENGINE=HEAP";
306 CRM_Core_DAO
::executeQuery($sql);
308 if (substr($this->_segmentSize
, -1) == '%') {
309 $countSql = "SELECT DISTINCT contact_a.id $from $fromTail
310 WHERE " . $this->where();
311 $dao = CRM_Core_DAO
::executeQuery($countSql);
312 $totalSize = $dao->N
;
313 $multiplier = substr($this->_segmentSize
, 0, strlen($this->_segmentSize
) - 1);
315 $this->_segmentSize
= round($totalSize * $multiplier);
318 $sql = "INSERT INTO random_{$this->_tableName} ( id )
319 SELECT DISTINCT contact_a.id $from $fromTail
320 WHERE " . $this->where() . "
322 LIMIT {$this->_segmentSize}";
323 CRM_Core_DAO
::executeQuery($sql);
325 $from = "FROM random_{$this->_tableName} random";
327 $from .= " INNER JOIN civicrm_contact contact_a ON random.id = contact_a.id";
329 $from .= " $fromTail";
335 * @param bool $includeContactIDs
339 public function where($includeContactIDs = FALSE) {
346 public function templateFile() {
347 return 'CRM/Contact/Form/Search/Custom.tpl';
353 public function setTitle($title) {
355 CRM_Utils_System
::setTitle($title);
358 CRM_Utils_System
::setTitle(ts('Search'));
368 public function count() {
371 $dao = CRM_Core_DAO
::executeQuery($sql);
376 * Destructor function.
378 public function __destruct() {
379 // the temporary tables are dropped automatically
380 // so we don't do it here
381 // but let mysql clean up