예제 #1
0
파일: Custom.php 프로젝트: hguru/224Civi
 public function preProcess()
 {
     $this->set('searchFormName', 'Custom');
     $this->set('context', 'custom');
     $csID = CRM_Utils_Request::retrieve('csid', 'Integer', $this);
     $ssID = CRM_Utils_Request::retrieve('ssID', 'Integer', $this);
     $gID = CRM_Utils_Request::retrieve('gid', 'Integer', $this);
     list($this->_customSearchID, $this->_customSearchClass, $formValues) = CRM_Contact_BAO_SearchCustom::details($csID, $ssID, $gID);
     if (!$this->_customSearchID) {
         CRM_Core_Error::fatal('Could not get details for custom search.');
     }
     // stash this as a hidden element so we can potentially go there if the session
     // is reset but this is available in the POST
     $this->addElement('hidden', 'csid', $csID);
     if (!empty($formValues)) {
         $this->_formValues = $formValues;
     }
     // set breadcrumb to return to Custom Search listings page
     $breadCrumb = array(array('title' => ts('Custom Searches'), 'url' => CRM_Utils_System::url('civicrm/contact/search/custom/list', 'reset=1')));
     CRM_Utils_System::appendBreadCrumb($breadCrumb);
     // use the custom selector
     self::$_selectorName = 'CRM_Contact_Selector_Custom';
     $this->set('customSearchID', $this->_customSearchID);
     $this->set('customSearchClass', $this->_customSearchClass);
     parent::preProcess();
     // instantiate the new class
     $this->_customClass = new $this->_customSearchClass($this->_formValues);
     // CRM-12747
     if (isset($this->_customClass->_permissionedComponent) && !self::isPermissioned($this->_customClass->_permissionedComponent)) {
         CRM_Utils_System::permissionDenied();
     }
 }
예제 #2
0
파일: Custom.php 프로젝트: bhirsch/voipdev
 public function preProcess()
 {
     require_once 'CRM/Contact/BAO/SearchCustom.php';
     $csID = CRM_Utils_Request::retrieve('csid', 'Integer', $this);
     $ssID = CRM_Utils_Request::retrieve('ssID', 'Integer', $this);
     $gID = CRM_Utils_Request::retrieve('gid', 'Integer', $this);
     list($this->_customSearchID, $this->_customSearchClass, $formValues) = CRM_Contact_BAO_SearchCustom::details($csID, $ssID, $gID);
     if (!$this->_customSearchID) {
         CRM_Core_Error::fatal('Could not get details for custom search.');
     }
     if (!empty($formValues)) {
         $this->_formValues = $formValues;
     }
     // set breadcrumb to return to Custom Search listings page
     $breadCrumb = array(array('title' => ts('Custom Searches'), 'url' => CRM_Utils_System::url('civicrm/contact/search/custom/list', 'reset=1')));
     CRM_Utils_System::appendBreadCrumb($breadCrumb);
     // use the custom selector
     require_once 'CRM/Contact/Selector/Custom.php';
     $this->_selectorName = 'CRM_Contact_Selector_Custom';
     $this->set('customSearchID', $this->_customSearchID);
     $this->set('customSearchClass', $this->_customSearchClass);
     parent::preProcess();
     // instantiate the new class
     eval('$this->_customClass = new ' . $this->_customSearchClass . '( $this->_formValues );');
 }
예제 #3
0
 /**
  * Get from where email (whatever that means!).
  *
  * @param int $id
  *
  * @return array
  */
 public static function fromWhereEmail($id)
 {
     $params = self::getSearchParams($id);
     if ($params) {
         if (!empty($params['customSearchID'])) {
             return CRM_Contact_BAO_SearchCustom::fromWhereEmail(NULL, $id);
         } else {
             $tables = $whereTables = array('civicrm_contact' => 1, 'civicrm_email' => 1);
             $where = CRM_Contact_BAO_SavedSearch::whereClause($id, $tables, $whereTables);
             $from = CRM_Contact_BAO_Query::fromClause($whereTables);
             return array($from, $where);
         }
     } else {
         // fix for CRM-7240
         $from = "\nFROM      civicrm_contact contact_a\nLEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1)\n";
         $where = " ( 1 ) ";
         $tables['civicrm_contact'] = $whereTables['civicrm_contact'] = 1;
         $tables['civicrm_email'] = $whereTables['civicrm_email'] = 1;
         return array($from, $where);
     }
 }
예제 #4
0
 /**
  * Load the smart group cache for a saved search.
  *
  * @param object $group
  *   The smart group that needs to be loaded.
  * @param bool $force
  *   Should we force a search through.
  */
 public static function load(&$group, $force = FALSE)
 {
     $groupID = $group->id;
     $savedSearchID = $group->saved_search_id;
     if (array_key_exists($groupID, self::$_alreadyLoaded) && !$force) {
         return;
     }
     // grab a lock so other processes don't compete and do the same query
     $lock = Civi::lockManager()->acquire("data.core.group.{$groupID}");
     if (!$lock->isAcquired()) {
         // this can cause inconsistent results since we don't know if the other process
         // will fill up the cache before our calling routine needs it.
         // however this routine does not return the status either, so basically
         // its a "lets return and hope for the best"
         return;
     }
     self::$_alreadyLoaded[$groupID] = 1;
     // we now have the lock, but some other process could have actually done the work
     // before we got here, so before we do any work, lets ensure that work needs to be
     // done
     // we allow hidden groups here since we dont know if the caller wants to evaluate an
     // hidden group
     if (!$force && !self::shouldGroupBeRefreshed($groupID, TRUE)) {
         $lock->release();
         return;
     }
     $sql = NULL;
     $idName = 'id';
     $customClass = NULL;
     if ($savedSearchID) {
         $ssParams = CRM_Contact_BAO_SavedSearch::getSearchParams($savedSearchID);
         // rectify params to what proximity search expects if there is a value for prox_distance
         // CRM-7021
         if (!empty($ssParams)) {
             CRM_Contact_BAO_ProximityQuery::fixInputParams($ssParams);
         }
         $returnProperties = array();
         if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) {
             $fv = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
             $returnProperties = CRM_Core_BAO_Mapping::returnProperties($fv);
         }
         if (isset($ssParams['customSearchID'])) {
             // if custom search
             // we split it up and store custom class
             // so temp tables are not destroyed if they are used
             // hence customClass is defined above at top of function
             $customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID);
             $searchSQL = $customClass->contactIDs();
             $searchSQL = str_replace('ORDER BY contact_a.id ASC', '', $searchSQL);
             if (!strstr($searchSQL, 'WHERE')) {
                 $searchSQL .= " WHERE ( 1 ) ";
             }
             $idName = 'contact_id';
         } else {
             $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
             // CRM-17075 using the formValues in this way imposes extra logic and complexity.
             // we have the where_clause and where tables stored in the saved_search table
             // and should use these rather than re-processing the form criteria (which over-works
             // the link between the form layer & the query layer too).
             // It's hard to think of when you would want to use anything other than return
             // properties = array('contact_id' => 1) here as the point would appear to be to
             // generate the list of contact ids in the group.
             // @todo review this to use values in saved_search table (preferably for 4.8).
             $query = new CRM_Contact_BAO_Query($ssParams, $returnProperties, NULL, FALSE, FALSE, 1, TRUE, TRUE, FALSE, CRM_Utils_Array::value('display_relationship_type', $formValues), CRM_Utils_Array::value('operator', $formValues, 'AND'));
             $query->_useDistinct = FALSE;
             $query->_useGroupBy = FALSE;
             $searchSQL = $query->searchQuery(0, 0, NULL, FALSE, FALSE, FALSE, TRUE, TRUE, NULL, NULL, NULL, TRUE);
         }
         $groupID = CRM_Utils_Type::escape($groupID, 'Integer');
         $sql = $searchSQL . " AND contact_a.id NOT IN (\n                              SELECT contact_id FROM civicrm_group_contact\n                              WHERE civicrm_group_contact.status = 'Removed'\n                              AND   civicrm_group_contact.group_id = {$groupID} ) ";
     }
     if ($sql) {
         $sql = preg_replace("/^\\s*SELECT/", "SELECT {$groupID} as group_id, ", $sql);
     }
     // lets also store the records that are explicitly added to the group
     // this allows us to skip the group contact LEFT JOIN
     $sqlB = "\nSELECT {$groupID} as group_id, contact_id as {$idName}\nFROM   civicrm_group_contact\nWHERE  civicrm_group_contact.status = 'Added'\n  AND  civicrm_group_contact.group_id = {$groupID} ";
     $groupIDs = array($groupID);
     self::remove($groupIDs);
     $processed = FALSE;
     $tempTable = 'civicrm_temp_group_contact_cache' . rand(0, 2000);
     foreach (array($sql, $sqlB) as $selectSql) {
         if (!$selectSql) {
             continue;
         }
         $insertSql = "CREATE TEMPORARY TABLE {$tempTable} ({$selectSql});";
         $processed = TRUE;
         CRM_Core_DAO::executeQuery($insertSql);
         CRM_Core_DAO::executeQuery("INSERT IGNORE INTO civicrm_group_contact_cache (contact_id, group_id)\n        SELECT DISTINCT {$idName}, group_id FROM {$tempTable}\n      ");
         CRM_Core_DAO::executeQuery(" DROP TEMPORARY TABLE {$tempTable}");
     }
     self::updateCacheTime($groupIDs, $processed);
     if ($group->children) {
         //Store a list of contacts who are removed from the parent group
         $sql = "\nSELECT contact_id\nFROM civicrm_group_contact\nWHERE  civicrm_group_contact.status = 'Removed'\nAND  civicrm_group_contact.group_id = {$groupID} ";
         $dao = CRM_Core_DAO::executeQuery($sql);
         $removed_contacts = array();
         while ($dao->fetch()) {
             $removed_contacts[] = $dao->contact_id;
         }
         $childrenIDs = explode(',', $group->children);
         foreach ($childrenIDs as $childID) {
             $contactIDs = CRM_Contact_BAO_Group::getMember($childID, FALSE);
             //Unset each contact that is removed from the parent group
             foreach ($removed_contacts as $removed_contact) {
                 unset($contactIDs[$removed_contact]);
             }
             $values = array();
             foreach ($contactIDs as $contactID => $dontCare) {
                 $values[] = "({$groupID},{$contactID})";
             }
             self::store($groupIDs, $values);
         }
     }
     $lock->release();
 }
 /**
  * note that $job_id is used only as a variable in the temp table construction
  * and does not play a role in the queries generated
  * @param int $job_id
  *   (misnomer) a nonce value used to name temporary tables.
  * @param int $mailing_id
  * @param bool $storeRecipients
  * @param bool $dedupeEmail
  * @param null $mode
  *
  * @return CRM_Mailing_Event_BAO_Queue|string
  */
 public static function getRecipients($job_id, $mailing_id = NULL, $storeRecipients = FALSE, $dedupeEmail = FALSE, $mode = NULL)
 {
     $mailingGroup = new CRM_Mailing_DAO_MailingGroup();
     $mailing = CRM_Mailing_BAO_Mailing::getTableName();
     $job = CRM_Mailing_BAO_MailingJob::getTableName();
     $mg = CRM_Mailing_DAO_MailingGroup::getTableName();
     $eq = CRM_Mailing_Event_DAO_Queue::getTableName();
     $email = CRM_Core_DAO_Email::getTableName();
     if ($mode == 'sms') {
         $phone = CRM_Core_DAO_Phone::getTableName();
     }
     $contact = CRM_Contact_DAO_Contact::getTableName();
     $group = CRM_Contact_DAO_Group::getTableName();
     $g2contact = CRM_Contact_DAO_GroupContact::getTableName();
     $m = new CRM_Mailing_DAO_Mailing();
     $m->id = $mailing_id;
     $m->find(TRUE);
     $email_selection_method = $m->email_selection_method;
     $location_type_id = $m->location_type_id;
     // Note: When determining the ORDER that results are returned, it's
     // the record that comes last that counts. That's because we are
     // INSERT'ing INTO a table with a primary id so that last record
     // over writes any previous record.
     switch ($email_selection_method) {
         case 'location-exclude':
             $location_filter = "({$email}.location_type_id != {$location_type_id})";
             // If there is more than one email that doesn't match the location,
             // prefer the one marked is_bulkmail, followed by is_primary.
             $order_by = "ORDER BY {$email}.is_bulkmail, {$email}.is_primary";
             break;
         case 'location-only':
             $location_filter = "({$email}.location_type_id = {$location_type_id})";
             // If there is more than one email of the desired location, prefer
             // the one marked is_bulkmail, followed by is_primary.
             $order_by = "ORDER BY {$email}.is_bulkmail, {$email}.is_primary";
             break;
         case 'location-prefer':
             $location_filter = "({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1 OR {$email}.location_type_id = {$location_type_id})";
             // ORDER BY is more complicated because we have to set an arbitrary
             // order that prefers the location that we want. We do that using
             // the FIELD function. For more info, see:
             // https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_field
             // We assign the location type we want the value "1" by putting it
             // in the first position after we name the field. All other location
             // types are left out, so they will be assigned the value 0. That
             // means, they will all be equally tied for first place, with our
             // location being last.
             $order_by = "ORDER BY FIELD({$email}.location_type_id, {$location_type_id}), {$email}.is_bulkmail, {$email}.is_primary";
             break;
         case 'automatic':
             // fall through to default
         // fall through to default
         default:
             $location_filter = "({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)";
             $order_by = "ORDER BY {$email}.is_bulkmail";
     }
     /* Create a temp table for contact exclusion */
     $mailingGroup->query("CREATE TEMPORARY TABLE X_{$job_id}\n            (contact_id int primary key)\n            ENGINE=HEAP");
     /* Add all the members of groups excluded from this mailing to the temp
      * table */
     $excludeSubGroup = "INSERT INTO        X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$g2contact}.contact_id\n                    FROM                {$g2contact}\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id AND {$mg}.entity_table = '{$group}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$mg}.group_type = 'Exclude'";
     $mailingGroup->query($excludeSubGroup);
     /* Add all unsubscribe members of base group from this mailing to the temp
      * table */
     $unSubscribeBaseGroup = "INSERT INTO        X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$g2contact}.contact_id\n                    FROM                {$g2contact}\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id AND {$mg}.entity_table = '{$group}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$g2contact}.status = 'Removed'\n                        AND             {$mg}.group_type = 'Base'";
     $mailingGroup->query($unSubscribeBaseGroup);
     /* Add all the (intended) recipients of an excluded prior mailing to
      * the temp table */
     $excludeSubMailing = "INSERT IGNORE INTO X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$eq}.contact_id\n                    FROM                {$eq}\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$mg}.group_type = 'Exclude'";
     $mailingGroup->query($excludeSubMailing);
     // get all the saved searches AND hierarchical groups
     // and load them in the cache
     $sql = "\nSELECT     {$group}.id, {$group}.cache_date, {$group}.saved_search_id, {$group}.children\nFROM       {$group}\nINNER JOIN {$mg} ON {$mg}.entity_id = {$group}.id\nWHERE      {$mg}.entity_table = '{$group}'\n  AND      {$mg}.group_type = 'Exclude'\n  AND      {$mg}.mailing_id = {$mailing_id}\n  AND      ( saved_search_id != 0\n   OR        saved_search_id IS NOT NULL\n   OR        children IS NOT NULL )\n";
     $groupDAO = CRM_Core_DAO::executeQuery($sql);
     while ($groupDAO->fetch()) {
         if ($groupDAO->cache_date == NULL) {
             CRM_Contact_BAO_GroupContactCache::load($groupDAO);
         }
         $smartGroupExclude = "\nINSERT IGNORE INTO X_{$job_id} (contact_id)\nSELECT c.contact_id\nFROM   civicrm_group_contact_cache c\nWHERE  c.group_id = {$groupDAO->id}\n";
         $mailingGroup->query($smartGroupExclude);
     }
     $tempColumn = 'email_id';
     if ($mode == 'sms') {
         $tempColumn = 'phone_id';
     }
     /* Get all the group contacts we want to include */
     $mailingGroup->query("CREATE TEMPORARY TABLE I_{$job_id}\n            ({$tempColumn} int, contact_id int primary key)\n            ENGINE=HEAP");
     /* Get the group contacts, but only those which are not in the
      * exclusion temp table */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                                AND     {$mg}.entity_table = '{$group}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$mg}.search_id IS NULL\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased <> 1\n                        AND             {$location_filter}\n                        AND             {$email}.email IS NOT NULL\n                        AND             {$email}.email != ''\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    {$order_by}";
     if ($mode == 'sms') {
         $phoneTypes = CRM_Core_OptionGroup::values('phone_type', TRUE, FALSE, FALSE, NULL, 'name');
         $query = "REPLACE INTO       I_{$job_id} (phone_id, contact_id)\n\n                    SELECT DISTINCT     {$phone}.id as phone_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$phone}\n                    INNER JOIN          {$contact}\n                            ON          {$phone}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                                AND     {$mg}.entity_table = '{$group}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$mg}.search_id IS NULL\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_sms = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased <> 1\n                        AND             {$phone}.phone_type_id = {$phoneTypes['Mobile']}\n                        AND             {$phone}.phone IS NOT NULL\n                        AND             {$phone}.phone != ''\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null";
     }
     $mailingGroup->query($query);
     /* Query prior mailings */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$eq}\n                            ON          {$eq}.contact_id = {$contact}.id\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased <> 1\n                        AND             {$location_filter}\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    {$order_by}";
     if ($mode == 'sms') {
         $query = "REPLACE INTO       I_{$job_id} (phone_id, contact_id)\n                    SELECT DISTINCT     {$phone}.id as phone_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$phone}\n                    INNER JOIN          {$contact}\n                            ON          {$phone}.contact_id = {$contact}.id\n                    INNER JOIN          {$eq}\n                            ON          {$eq}.contact_id = {$contact}.id\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$contact}.do_not_sms = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased <> 1\n                        AND             {$phone}.phone_type_id = {$phoneTypes['Mobile']}\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null";
     }
     $mailingGroup->query($query);
     $sql = "\nSELECT     {$group}.id, {$group}.cache_date, {$group}.saved_search_id, {$group}.children\nFROM       {$group}\nINNER JOIN {$mg} ON {$mg}.entity_id = {$group}.id\nWHERE      {$mg}.entity_table = '{$group}'\n  AND      {$mg}.group_type = 'Include'\n  AND      {$mg}.search_id IS NULL\n  AND      {$mg}.mailing_id = {$mailing_id}\n  AND      ( saved_search_id != 0\n   OR        saved_search_id IS NOT NULL\n   OR        children IS NOT NULL )\n";
     $groupDAO = CRM_Core_DAO::executeQuery($sql);
     while ($groupDAO->fetch()) {
         if ($groupDAO->cache_date == NULL) {
             CRM_Contact_BAO_GroupContactCache::load($groupDAO);
         }
         $smartGroupInclude = "\nREPLACE INTO I_{$job_id} (email_id, contact_id)\nSELECT     civicrm_email.id as email_id, c.id as contact_id\nFROM       civicrm_contact c\nINNER JOIN civicrm_email                ON civicrm_email.contact_id         = c.id\nINNER JOIN civicrm_group_contact_cache gc ON gc.contact_id        = c.id\nLEFT  JOIN X_{$job_id}                      ON X_{$job_id}.contact_id = c.id\nWHERE      gc.group_id = {$groupDAO->id}\n  AND      c.do_not_email = 0\n  AND      c.is_opt_out = 0\n  AND      c.is_deceased <> 1\n  AND      {$location_filter}\n  AND      civicrm_email.on_hold = 0\n  AND      X_{$job_id}.contact_id IS null\n{$order_by}\n";
         if ($mode == 'sms') {
             $smartGroupInclude = "\nREPLACE INTO I_{$job_id} (phone_id, contact_id)\nSELECT     p.id as phone_id, c.id as contact_id\nFROM       civicrm_contact c\nINNER JOIN civicrm_phone p                ON p.contact_id         = c.id\nINNER JOIN civicrm_group_contact_cache gc ON gc.contact_id        = c.id\nLEFT  JOIN X_{$job_id}                      ON X_{$job_id}.contact_id = c.id\nWHERE      gc.group_id = {$groupDAO->id}\n  AND      c.do_not_sms = 0\n  AND      c.is_opt_out = 0\n  AND      c.is_deceased <> 1\n  AND      p.phone_type_id = {$phoneTypes['Mobile']}\n  AND      X_{$job_id}.contact_id IS null";
         }
         $mailingGroup->query($smartGroupInclude);
     }
     /**
      * Construct the filtered search queries
      */
     $query = "\nSELECT search_id, search_args, entity_id\nFROM   {$mg}\nWHERE  {$mg}.search_id IS NOT NULL\nAND    {$mg}.mailing_id = {$mailing_id}\n";
     $dao = CRM_Core_DAO::executeQuery($query);
     while ($dao->fetch()) {
         $customSQL = CRM_Contact_BAO_SearchCustom::civiMailSQL($dao->search_id, $dao->search_args, $dao->entity_id);
         $query = "REPLACE INTO       I_{$job_id} ({$tempColumn}, contact_id)\n                         {$customSQL}";
         $mailingGroup->query($query);
     }
     /* Get the emails with only location override */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as local_email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                        {$mg}.entity_table = '{$group}'\n                        AND             {$mg}.group_type = 'Include'\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased <> 1\n                        AND             {$location_filter}\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    {$order_by}";
     if ($mode == "sms") {
         $query = "REPLACE INTO       I_{$job_id} (phone_id, contact_id)\n                    SELECT DISTINCT     {$phone}.id as phone_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$phone}\n                    INNER JOIN          {$contact}\n                            ON          {$phone}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                        {$mg}.entity_table = '{$group}'\n                        AND             {$mg}.group_type = 'Include'\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_sms = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased <> 1\n                        AND             {$phone}.phone_type_id = {$phoneTypes['Mobile']}\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null";
     }
     $mailingGroup->query($query);
     $eq = new CRM_Mailing_Event_BAO_Queue();
     list($aclFrom, $aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause();
     $aclWhere = $aclWhere ? "WHERE {$aclWhere}" : '';
     if ($storeRecipients && $mailing_id) {
         $sql = "\nDELETE\nFROM   civicrm_mailing_recipients\nWHERE  mailing_id = %1\n";
         $params = array(1 => array($mailing_id, 'Integer'));
         CRM_Core_DAO::executeQuery($sql, $params);
         // CRM-3975
         $groupBy = $groupJoin = '';
         if ($dedupeEmail) {
             $groupJoin = " INNER JOIN civicrm_email e ON e.id = i.email_id";
             $groupBy = " GROUP BY e.email ";
         }
         $sql = "\nINSERT INTO civicrm_mailing_recipients ( mailing_id, contact_id, {$tempColumn} )\nSELECT %1, i.contact_id, i.{$tempColumn}\nFROM       civicrm_contact contact_a\nINNER JOIN I_{$job_id} i ON contact_a.id = i.contact_id\n           {$groupJoin}\n           {$aclFrom}\n           {$aclWhere}\n           {$groupBy}\nORDER BY   i.contact_id, i.{$tempColumn}\n";
         CRM_Core_DAO::executeQuery($sql, $params);
         // if we need to add all emails marked bulk, do it as a post filter
         // on the mailing recipients table
         if (CRM_Core_BAO_Email::isMultipleBulkMail()) {
             self::addMultipleEmails($mailing_id);
         }
     }
     /* Delete the temp table */
     $mailingGroup->reset();
     $mailingGroup->query("DROP TEMPORARY TABLE X_{$job_id}");
     $mailingGroup->query("DROP TEMPORARY TABLE I_{$job_id}");
     return $eq;
 }
예제 #6
0
 static function fromWhereEmail($id)
 {
     $params =& self::getSearchParams($id);
     if ($params) {
         if (CRM_Utils_Array::value('customSearchID', $params)) {
             require_once 'CRM/Contact/BAO/SearchCustom.php';
             return CRM_Contact_BAO_SearchCustom::fromWhereEmail(null, $id);
         } else {
             $tables = $whereTables = array('civicrm_contact' => 1, 'civicrm_email' => 1);
             $where = CRM_Contact_BAO_SavedSearch::whereClause($id, $tables, $whereTables);
             $from = CRM_Contact_BAO_Query::fromClause($whereTables);
             return array($from, $where);
         }
     } else {
         // fix for CRM-7240
         $from = "\nFROM      civicrm_contact contact_a \nLEFT JOIN civicrm_email ON (contact_a.id = civicrm_email.contact_id AND civicrm_email.is_primary = 1)\n";
         $where = " ( 1 ) ";
         $tables['civicrm_contact'] = $whereTables['civicrm_contact'] = 1;
         $tables['civicrm_email'] = $whereTables['civicrm_email'] = 1;
         return array($from, $where);
     }
 }
예제 #7
0
 static function &getRecipients($job_id, $mailing_id = NULL, $offset = NULL, $limit = NULL, $storeRecipients = FALSE, $dedupeEmail = FALSE, $mode = NULL)
 {
     $mailingGroup = new CRM_Mailing_DAO_MailingGroup();
     $mailing = CRM_Mailing_BAO_Mailing::getTableName();
     $job = CRM_Mailing_BAO_MailingJob::getTableName();
     $mg = CRM_Mailing_DAO_MailingGroup::getTableName();
     $eq = CRM_Mailing_Event_DAO_Queue::getTableName();
     $ed = CRM_Mailing_Event_DAO_Delivered::getTableName();
     $eb = CRM_Mailing_Event_DAO_Bounce::getTableName();
     $email = CRM_Core_DAO_Email::getTableName();
     if ($mode == 'sms') {
         $phone = CRM_Core_DAO_Phone::getTableName();
     }
     $contact = CRM_Contact_DAO_Contact::getTableName();
     $group = CRM_Contact_DAO_Group::getTableName();
     $g2contact = CRM_Contact_DAO_GroupContact::getTableName();
     /* Create a temp table for contact exclusion */
     $mailingGroup->query("CREATE TEMPORARY TABLE X_{$job_id}\n            (contact_id int primary key)\n            ENGINE=HEAP");
     /* Add all the members of groups excluded from this mailing to the temp
      * table */
     $excludeSubGroup = "INSERT INTO        X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$g2contact}.contact_id\n                    FROM                {$g2contact}\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id AND {$mg}.entity_table = '{$group}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$mg}.group_type = 'Exclude'";
     $mailingGroup->query($excludeSubGroup);
     /* Add all unsubscribe members of base group from this mailing to the temp
      * table */
     $unSubscribeBaseGroup = "INSERT INTO        X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$g2contact}.contact_id\n                    FROM                {$g2contact}\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id AND {$mg}.entity_table = '{$group}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$g2contact}.status = 'Removed'\n                        AND             {$mg}.group_type = 'Base'";
     $mailingGroup->query($unSubscribeBaseGroup);
     /* Add all the (intended) recipients of an excluded prior mailing to
      * the temp table */
     $excludeSubMailing = "INSERT IGNORE INTO X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$eq}.contact_id\n                    FROM                {$eq}\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$mg}.group_type = 'Exclude'";
     $mailingGroup->query($excludeSubMailing);
     // get all the saved searches AND hierarchical groups
     // and load them in the cache
     $sql = "\nSELECT     {$group}.id, {$group}.cache_date, {$group}.saved_search_id, {$group}.children\nFROM       {$group}\nINNER JOIN {$mg} ON {$mg}.entity_id = {$group}.id\nWHERE      {$mg}.entity_table = '{$group}'\n  AND      {$mg}.group_type = 'Exclude'\n  AND      {$mg}.mailing_id = {$mailing_id}\n  AND      ( saved_search_id != 0\n   OR        saved_search_id IS NOT NULL\n   OR        children IS NOT NULL )\n";
     $groupDAO = CRM_Core_DAO::executeQuery($sql);
     while ($groupDAO->fetch()) {
         if ($groupDAO->cache_date == NULL) {
             CRM_Contact_BAO_GroupContactCache::load($groupDAO);
         }
         $smartGroupExclude = "\nINSERT IGNORE INTO X_{$job_id} (contact_id)\nSELECT c.contact_id\nFROM   civicrm_group_contact_cache c\nWHERE  c.group_id = {$groupDAO->id}\n";
         $mailingGroup->query($smartGroupExclude);
     }
     $tempColumn = 'email_id';
     if ($mode == 'sms') {
         $tempColumn = 'phone_id';
     }
     /* Get all the group contacts we want to include */
     $mailingGroup->query("CREATE TEMPORARY TABLE I_{$job_id}\n            ({$tempColumn} int, contact_id int primary key)\n            ENGINE=HEAP");
     /* Get the group contacts, but only those which are not in the
      * exclusion temp table */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                                AND     {$mg}.entity_table = '{$group}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$mg}.search_id IS NULL\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND            ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.email IS NOT NULL\n                        AND             {$email}.email != ''\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail";
     if ($mode == 'sms') {
         $phoneTypes = CRM_Core_OptionGroup::values('phone_type', TRUE, FALSE, FALSE, NULL, 'name');
         $query = "REPLACE INTO       I_{$job_id} (phone_id, contact_id)\n\n                    SELECT DISTINCT     {$phone}.id as phone_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$phone}\n                    INNER JOIN          {$contact}\n                            ON          {$phone}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                                AND     {$mg}.entity_table = '{$group}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$mg}.search_id IS NULL\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_sms = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND             {$phone}.phone_type_id = {$phoneTypes['Mobile']}\n                        AND             {$phone}.phone IS NOT NULL\n                        AND             {$phone}.phone != ''\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null";
     }
     $mailingGroup->query($query);
     /* Query prior mailings */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$eq}\n                            ON          {$eq}.contact_id = {$contact}.id\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND            ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail";
     if ($mode == 'sms') {
         $query = "REPLACE INTO       I_{$job_id} (phone_id, contact_id)\n                    SELECT DISTINCT     {$phone}.id as phone_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$phone}\n                    INNER JOIN          {$contact}\n                            ON          {$phone}.contact_id = {$contact}.id\n                    INNER JOIN          {$eq}\n                            ON          {$eq}.contact_id = {$contact}.id\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include')\n                        AND             {$contact}.do_not_sms = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND             {$phone}.phone_type_id = {$phoneTypes['Mobile']}\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null";
     }
     $mailingGroup->query($query);
     $sql = "\nSELECT     {$group}.id, {$group}.cache_date, {$group}.saved_search_id, {$group}.children\nFROM       {$group}\nINNER JOIN {$mg} ON {$mg}.entity_id = {$group}.id\nWHERE      {$mg}.entity_table = '{$group}'\n  AND      {$mg}.group_type = 'Include'\n  AND      {$mg}.search_id IS NULL\n  AND      {$mg}.mailing_id = {$mailing_id}\n  AND      ( saved_search_id != 0\n   OR        saved_search_id IS NOT NULL\n   OR        children IS NOT NULL )\n";
     $groupDAO = CRM_Core_DAO::executeQuery($sql);
     while ($groupDAO->fetch()) {
         if ($groupDAO->cache_date == NULL) {
             CRM_Contact_BAO_GroupContactCache::load($groupDAO);
         }
         $smartGroupInclude = "\nINSERT IGNORE INTO I_{$job_id} (email_id, contact_id)\nSELECT     e.id as email_id, c.id as contact_id\nFROM       civicrm_contact c\nINNER JOIN civicrm_email e                ON e.contact_id         = c.id\nINNER JOIN civicrm_group_contact_cache gc ON gc.contact_id        = c.id\nLEFT  JOIN X_{$job_id}                      ON X_{$job_id}.contact_id = c.id\nWHERE      gc.group_id = {$groupDAO->id}\n  AND      c.do_not_email = 0\n  AND      c.is_opt_out = 0\n  AND      c.is_deceased = 0\n  AND      (e.is_bulkmail = 1 OR e.is_primary = 1)\n  AND      e.on_hold = 0\n  AND      X_{$job_id}.contact_id IS null\nORDER BY   e.is_bulkmail\n";
         if ($mode == 'sms') {
             $smartGroupInclude = "\nINSERT IGNORE INTO I_{$job_id} (phone_id, contact_id)\nSELECT     p.id as phone_id, c.id as contact_id\nFROM       civicrm_contact c\nINNER JOIN civicrm_phone p                ON p.contact_id         = c.id\nINNER JOIN civicrm_group_contact_cache gc ON gc.contact_id        = c.id\nLEFT  JOIN X_{$job_id}                      ON X_{$job_id}.contact_id = c.id\nWHERE      gc.group_id = {$groupDAO->id}\n  AND      c.do_not_sms = 0\n  AND      c.is_opt_out = 0\n  AND      c.is_deceased = 0\n  AND      p.phone_type_id = {$phoneTypes['Mobile']}\n  AND      X_{$job_id}.contact_id IS null";
         }
         $mailingGroup->query($smartGroupInclude);
     }
     /**
      * Construct the filtered search queries
      */
     $query = "\nSELECT search_id, search_args, entity_id\nFROM   {$mg}\nWHERE  {$mg}.search_id IS NOT NULL\nAND    {$mg}.mailing_id = {$mailing_id}\n";
     $dao = CRM_Core_DAO::executeQuery($query);
     while ($dao->fetch()) {
         $customSQL = CRM_Contact_BAO_SearchCustom::civiMailSQL($dao->search_id, $dao->search_args, $dao->entity_id);
         $query = "REPLACE INTO       I_{$job_id} ({$tempColumn}, contact_id)\n                         {$customSQL}";
         $mailingGroup->query($query);
     }
     /* Get the emails with only location override */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as local_email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                        {$mg}.entity_table = '{$group}'\n                        AND             {$mg}.group_type = 'Include'\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND             ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail";
     if ($mode == "sms") {
         $query = "REPLACE INTO       I_{$job_id} (phone_id, contact_id)\n                    SELECT DISTINCT     {$phone}.id as phone_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$phone}\n                    INNER JOIN          {$contact}\n                            ON          {$phone}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                        {$mg}.entity_table = '{$group}'\n                        AND             {$mg}.group_type = 'Include'\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$contact}.do_not_sms = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND             {$phone}.phone_type_id = {$phoneTypes['Mobile']}\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null";
     }
     $mailingGroup->query($query);
     $results = array();
     $eq = new CRM_Mailing_Event_BAO_Queue();
     list($aclFrom, $aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause();
     $aclWhere = $aclWhere ? "WHERE {$aclWhere}" : '';
     $limitString = NULL;
     if ($limit && $offset !== NULL) {
         $offset = CRM_Utils_Type::escape($offset, 'Int');
         $limit = CRM_Utils_Type::escape($limit, 'Int');
         $limitString = "LIMIT {$offset}, {$limit}";
     }
     if ($storeRecipients && $mailing_id) {
         $sql = "\nDELETE\nFROM   civicrm_mailing_recipients\nWHERE  mailing_id = %1\n";
         $params = array(1 => array($mailing_id, 'Integer'));
         CRM_Core_DAO::executeQuery($sql, $params);
         // CRM-3975
         $groupBy = $groupJoin = '';
         if ($dedupeEmail) {
             $groupJoin = " INNER JOIN civicrm_email e ON e.id = i.email_id";
             $groupBy = " GROUP BY e.email ";
         }
         $sql = "\nINSERT INTO civicrm_mailing_recipients ( mailing_id, contact_id, {$tempColumn} )\nSELECT %1, i.contact_id, i.{$tempColumn}\nFROM       civicrm_contact contact_a\nINNER JOIN I_{$job_id} i ON contact_a.id = i.contact_id\n           {$groupJoin}\n           {$aclFrom}\n           {$aclWhere}\n           {$groupBy}\nORDER BY   i.contact_id, i.{$tempColumn}\n";
         CRM_Core_DAO::executeQuery($sql, $params);
         // if we need to add all emails marked bulk, do it as a post filter
         // on the mailing recipients table
         if (CRM_Core_BAO_Email::isMultipleBulkMail()) {
             self::addMultipleEmails($mailing_id);
         }
     }
     /* Delete the temp table */
     $mailingGroup->reset();
     $mailingGroup->query("DROP TEMPORARY TABLE X_{$job_id}");
     $mailingGroup->query("DROP TEMPORARY TABLE I_{$job_id}");
     return $eq;
 }
 /**
  * load the smart group cache for a saved search
  */
 static function load(&$group)
 {
     $groupID = $group->id;
     $savedSearchID = $group->saved_search_id;
     $sql = null;
     $idName = 'id';
     $customClass = null;
     if ($savedSearchID) {
         require_once 'CRM/Contact/BAO/SavedSearch.php';
         $ssParams =& CRM_Contact_BAO_SavedSearch::getSearchParams($savedSearchID);
         $returnProperties = array();
         if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) {
             require_once "CRM/Core/BAO/Mapping.php";
             $fv =& CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
             $returnProperties = CRM_Core_BAO_Mapping::returnProperties($fv);
         }
         if (isset($ssParams['customSearchID'])) {
             // if custom search
             require_once 'CRM/Contact/BAO/SearchCustom.php';
             // we split it up and store custom class
             // so temp tables are not destroyed if they are used
             // hence customClass is defined above at top of function
             $customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID);
             $searchSQL = $customClass->contactIDs();
             $idName = 'contact_id';
         } else {
             require_once 'CRM/Contact/BAO/Query.php';
             $query = new CRM_Contact_BAO_Query($ssParams, $returnProperties, null, false, false, 1, true, true, false);
             $query->_useGroupBy = false;
             $searchSQL =& $query->searchQuery(0, 0, null, false, false, false, true, true, null);
         }
         $groupID = CRM_Utils_Type::escape($groupID, 'Integer');
         $sql = $searchSQL . " AND contact_a.id NOT IN ( \n                              SELECT contact_id FROM civicrm_group_contact \n                              WHERE civicrm_group_contact.status = 'Removed' \n                              AND   civicrm_group_contact.group_id = {$groupID} ) ";
     }
     if ($sql) {
         $sql .= " UNION ";
     }
     // lets also store the records that are explicitly added to the group
     // this allows us to skip the group contact LEFT JOIN
     $sql .= "\nSELECT contact_id as {$idName}\nFROM   civicrm_group_contact\nWHERE  civicrm_group_contact.status = 'Added'\n  AND  civicrm_group_contact.group_id = {$groupID} ";
     $dao = CRM_Core_DAO::executeQuery($sql);
     $values = array();
     while ($dao->fetch()) {
         $values[] = "({$groupID},{$dao->{$idName}})";
     }
     $groupIDs = array($groupID);
     self::remove($groupIDs);
     self::store($groupIDs, $values);
     if ($group->children) {
         require_once 'CRM/Contact/BAO/Group.php';
         $childrenIDs = explode(',', $group->children);
         foreach ($childrenIDs as $childID) {
             $contactIDs =& CRM_Contact_BAO_Group::getMember($childID, false);
             $values = array();
             foreach ($contactIDs as $contactID => $dontCare) {
                 $values[] = "({$groupID},{$contactID})";
             }
             self::store($groupIDs, $values);
         }
     }
 }
예제 #9
0
 function &getRecipients($job_id, $includeDelivered = false, $mailing_id = null, $offset = NULL, $limit = NULL)
 {
     $mailingGroup = new CRM_Mailing_DAO_Group();
     $mailing = CRM_Mailing_BAO_Mailing::getTableName();
     $job = CRM_Mailing_BAO_Job::getTableName();
     $mg = CRM_Mailing_DAO_Group::getTableName();
     $eq = CRM_Mailing_Event_DAO_Queue::getTableName();
     $ed = CRM_Mailing_Event_DAO_Delivered::getTableName();
     $eb = CRM_Mailing_Event_DAO_Bounce::getTableName();
     $email = CRM_Core_DAO_Email::getTableName();
     $contact = CRM_Contact_DAO_Contact::getTableName();
     require_once 'CRM/Contact/DAO/Group.php';
     $group = CRM_Contact_DAO_Group::getTableName();
     $g2contact = CRM_Contact_DAO_GroupContact::getTableName();
     /* Create a temp table for contact exclusion */
     $mailingGroup->query("CREATE TEMPORARY TABLE X_{$job_id} \n            (contact_id int primary key) \n            ENGINE=HEAP");
     /* Add all the members of groups excluded from this mailing to the temp
      * table */
     $excludeSubGroup = "INSERT INTO        X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$g2contact}.contact_id\n                    FROM                {$g2contact}\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id AND {$mg}.entity_table = '{$group}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$mg}.group_type = 'Exclude'";
     $mailingGroup->query($excludeSubGroup);
     /* Add all unsubscribe members of base group from this mailing to the temp
      * table */
     $unSubscribeBaseGroup = "INSERT INTO        X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$g2contact}.contact_id\n                    FROM                {$g2contact}\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id AND {$mg}.entity_table = '{$group}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$g2contact}.status = 'Removed'\n                        AND             {$mg}.group_type = 'Base'";
     $mailingGroup->query($unSubscribeBaseGroup);
     /* Add all the (intended) recipients of an excluded prior mailing to
      * the temp table */
     $excludeSubMailing = "INSERT IGNORE INTO X_{$job_id} (contact_id)\n                    SELECT  DISTINCT    {$eq}.contact_id\n                    FROM                {$eq}\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    WHERE\n                                        {$mg}.mailing_id = {$mailing_id}\n                        AND             {$mg}.group_type = 'Exclude'";
     $mailingGroup->query($excludeSubMailing);
     $ss = new CRM_Core_DAO();
     $ss->query("SELECT             {$group}.saved_search_id as saved_search_id,\n                                    {$group}.id as id\n                FROM                {$group}\n                INNER JOIN          {$mg}\n                        ON          {$mg}.entity_id = {$group}.id\n                WHERE               {$mg}.entity_table = '{$group}'\n                    AND             {$mg}.group_type = 'Exclude'\n                    AND             {$mg}.mailing_id = {$mailing_id}\n                    AND             {$group}.saved_search_id IS NOT null");
     $whereTables = array();
     while ($ss->fetch()) {
         /* run the saved search query and dump result contacts into the temp
          * table */
         $tables = array($contact => 1);
         $sql = CRM_Contact_BAO_SavedSearch::contactIDsSQL($ss->saved_search_id);
         $sql = $sql . " AND contact_a.id NOT IN ( \n                              SELECT contact_id FROM {$g2contact} \n                              WHERE {$g2contact}.group_id = {$ss->id} AND {$g2contact}.status = 'Removed')";
         $mailingGroup->query("INSERT IGNORE INTO X_{$job_id} (contact_id) {$sql}");
     }
     /* Get all the group contacts we want to include */
     $mailingGroup->query("CREATE TEMPORARY TABLE I_{$job_id} \n            (email_id int, contact_id int primary key)\n            ENGINE=HEAP");
     /* Get the group contacts, but only those which are not in the
      * exclusion temp table */
     /* Get the emails with no override */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                                AND     {$mg}.entity_table = '{$group}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE           \n                                       ({$mg}.group_type = 'Include' OR {$mg}.group_type = 'Base')\n                        AND             {$mg}.search_id IS NULL\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$g2contact}.email_id IS null\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND            ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail";
     $mailingGroup->query($query);
     /* Query prior mailings */
     $mailingGroup->query("REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$eq}\n                            ON          {$eq}.contact_id = {$contact}.id\n                    INNER JOIN          {$job}\n                            ON          {$eq}.job_id = {$job}.id\n                    INNER JOIN          {$mg}\n                            ON          {$job}.mailing_id = {$mg}.entity_id AND {$mg}.entity_table = '{$mailing}'\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE\n                                       ({$mg}.group_type = 'Include' OR {$mg}.group_type = 'Base')\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND            ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail");
     /* Construct the saved-search queries */
     $ss->query("SELECT          {$group}.saved_search_id as saved_search_id,\n                                    {$group}.id as id\n                    FROM            {$group}\n                    INNER JOIN      {$mg}\n                            ON      {$mg}.entity_id = {$group}.id\n                                AND {$mg}.entity_table = '{$group}'\n                    WHERE               \n                                    {$mg}.group_type = 'Include'\n                        AND         {$mg}.search_id IS NULL\n                        AND         {$mg}.mailing_id = {$mailing_id}\n                        AND         {$group}.saved_search_id IS NOT null");
     $whereTables = array();
     while ($ss->fetch()) {
         $tables = array($contact => 1, $location => 1, $email => 1);
         list($from, $where) = CRM_Contact_BAO_SavedSearch::fromWhereEmail($ss->saved_search_id);
         $where = trim($where);
         if ($where) {
             $where = " AND {$where} ";
         }
         $ssq = "INSERT IGNORE INTO  I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        contact_a.id as contact_id \n                    {$from}\n                    LEFT JOIN           X_{$job_id}\n                            ON          contact_a.id = X_{$job_id}.contact_id\n                    WHERE           \n                                        contact_a.do_not_email = 0\n                        AND             contact_a.is_opt_out = 0\n                        AND             contact_a.is_deceased = 0\n                        AND             ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.on_hold = 0\n                                        {$where}\n                        AND             contact_a.id NOT IN ( \n                                          SELECT contact_id FROM {$g2contact} \n                                          WHERE {$g2contact}.group_id = {$ss->id} AND {$g2contact}.status = 'Removed') \n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail";
         $mailingGroup->query($ssq);
     }
     /**
      * Construct the filtered search queries
      */
     $query = "\nSELECT search_id, search_args, entity_id\nFROM   {$mg}\nWHERE  {$mg}.search_id IS NOT NULL\nAND    {$mg}.mailing_id = {$mailing_id}\n";
     $dao = CRM_Core_DAO::executeQuery($query);
     require_once 'CRM/Contact/BAO/SearchCustom.php';
     while ($dao->fetch()) {
         $customSQL = CRM_Contact_BAO_SearchCustom::civiMailSQL($dao->search_id, $dao->search_args, $dao->entity_id);
         $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                         {$customSQL}";
         $mailingGroup->query($query);
     }
     /* Get the emails with only location override */
     $query = "REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as local_email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$contact}\n                            ON          {$email}.contact_id = {$contact}.id\n                    INNER JOIN          {$g2contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE           \n                                        {$mg}.entity_table = '{$group}'\n                        AND             {$mg}.group_type = 'Include'\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$g2contact}.email_id is null\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND             ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail";
     $mailingGroup->query($query);
     /* Get the emails with full override */
     $mailingGroup->query("REPLACE INTO       I_{$job_id} (email_id, contact_id)\n                    SELECT DISTINCT     {$email}.id as email_id,\n                                        {$contact}.id as contact_id\n                    FROM                {$email}\n                    INNER JOIN          {$g2contact}\n                            ON          {$email}.id = {$g2contact}.email_id\n                    INNER JOIN          {$contact}\n                            ON          {$contact}.id = {$g2contact}.contact_id\n                    INNER JOIN          {$mg}\n                            ON          {$g2contact}.group_id = {$mg}.entity_id\n                    LEFT JOIN           X_{$job_id}\n                            ON          {$contact}.id = X_{$job_id}.contact_id\n                    WHERE           \n                                        {$mg}.entity_table = '{$group}'\n                        AND             {$mg}.group_type = 'Include'\n                        AND             {$g2contact}.status = 'Added'\n                        AND             {$g2contact}.email_id IS NOT null\n                        AND             {$contact}.do_not_email = 0\n                        AND             {$contact}.is_opt_out = 0\n                        AND             {$contact}.is_deceased = 0\n                        AND             ({$email}.is_bulkmail = 1 OR {$email}.is_primary = 1)\n                        AND             {$email}.on_hold = 0\n                        AND             {$mg}.mailing_id = {$mailing_id}\n                        AND             X_{$job_id}.contact_id IS null\n                    ORDER BY {$email}.is_bulkmail");
     $results = array();
     $eq = new CRM_Mailing_Event_BAO_Queue();
     require_once 'CRM/Contact/BAO/Contact/Permission.php';
     list($aclFrom, $aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause();
     $aclWhere = $aclWhere ? "WHERE {$aclWhere}" : '';
     $limitString = null;
     if ($limit && $offset !== null) {
         $limitString = "LIMIT {$offset}, {$limit}";
     }
     $eq->query("SELECT i.contact_id, i.email_id \n                    FROM  civicrm_contact contact_a\n                    INNER JOIN I_{$job_id} i ON contact_a.id = i.contact_id\n                    {$aclFrom}\n                    {$aclWhere}\n                    ORDER BY i.contact_id, i.email_id\n                    {$limitString}");
     /* Delete the temp table */
     $mailingGroup->reset();
     $mailingGroup->query("DROP TEMPORARY TABLE X_{$job_id}");
     $mailingGroup->query("DROP TEMPORARY TABLE I_{$job_id}");
     return $eq;
 }
 /**
  * load the smart group cache for a saved search
  */
 static function load(&$group, $fresh = FALSE)
 {
     $groupID = $group->id;
     $savedSearchID = $group->saved_search_id;
     if (array_key_exists($groupID, self::$_alreadyLoaded) && !$fresh) {
         return;
     }
     self::$_alreadyLoaded[$groupID] = 1;
     $sql = NULL;
     $idName = 'id';
     $customClass = NULL;
     if ($savedSearchID) {
         $ssParams = CRM_Contact_BAO_SavedSearch::getSearchParams($savedSearchID);
         // rectify params to what proximity search expects if there is a value for prox_distance
         // CRM-7021
         if (!empty($ssParams)) {
             CRM_Contact_BAO_ProximityQuery::fixInputParams($ssParams);
         }
         $returnProperties = array();
         if (CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_SavedSearch', $savedSearchID, 'mapping_id')) {
             $fv = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
             $returnProperties = CRM_Core_BAO_Mapping::returnProperties($fv);
         }
         if (isset($ssParams['customSearchID'])) {
             // if custom search
             // we split it up and store custom class
             // so temp tables are not destroyed if they are used
             // hence customClass is defined above at top of function
             $customClass = CRM_Contact_BAO_SearchCustom::customClass($ssParams['customSearchID'], $savedSearchID);
             $searchSQL = $customClass->contactIDs();
             $idName = 'contact_id';
         } else {
             $formValues = CRM_Contact_BAO_SavedSearch::getFormValues($savedSearchID);
             $query = new CRM_Contact_BAO_Query($ssParams, $returnProperties, NULL, FALSE, FALSE, 1, TRUE, TRUE, FALSE, CRM_Utils_Array::value('display_relationship_type', $formValues), CRM_Utils_Array::value('operator', $formValues, 'AND'));
             $query->_useDistinct = FALSE;
             $query->_useGroupBy = FALSE;
             $searchSQL = $query->searchQuery(0, 0, NULL, FALSE, FALSE, FALSE, TRUE, TRUE, NULL, NULL, NULL, TRUE);
         }
         $groupID = CRM_Utils_Type::escape($groupID, 'Integer');
         $sql = $searchSQL . " AND contact_a.id NOT IN (\n                              SELECT contact_id FROM civicrm_group_contact\n                              WHERE civicrm_group_contact.status = 'Removed'\n                              AND   civicrm_group_contact.group_id = {$groupID} ) ";
     }
     if ($sql) {
         $sql = preg_replace("/^\\s*SELECT/", "SELECT {$groupID} as group_id, ", $sql);
     }
     // lets also store the records that are explicitly added to the group
     // this allows us to skip the group contact LEFT JOIN
     $sqlB = "\nSELECT {$groupID} as group_id, contact_id as {$idName}\nFROM   civicrm_group_contact\nWHERE  civicrm_group_contact.status = 'Added'\n  AND  civicrm_group_contact.group_id = {$groupID} ";
     $groupIDs = array($groupID);
     self::remove($groupIDs);
     foreach (array($sql, $sqlB) as $selectSql) {
         if (!$selectSql) {
             continue;
         }
         $insertSql = "INSERT IGNORE INTO civicrm_group_contact_cache (group_id,contact_id) ({$selectSql});";
         $processed = TRUE;
         // FIXME
         $result = CRM_Core_DAO::executeQuery($insertSql);
     }
     self::updateCacheTime($groupIDs, $processed);
     if ($group->children) {
         //Store a list of contacts who are removed from the parent group
         $sql = "\nSELECT contact_id\nFROM civicrm_group_contact\nWHERE  civicrm_group_contact.status = 'Removed'\nAND  civicrm_group_contact.group_id = {$groupID} ";
         $dao = CRM_Core_DAO::executeQuery($sql);
         $removed_contacts = array();
         while ($dao->fetch()) {
             $removed_contacts[] = $dao->contact_id;
         }
         $childrenIDs = explode(',', $group->children);
         foreach ($childrenIDs as $childID) {
             $contactIDs = CRM_Contact_BAO_Group::getMember($childID, FALSE);
             //Unset each contact that is removed from the parent group
             foreach ($removed_contacts as $removed_contact) {
                 unset($contactIDs[$removed_contact]);
             }
             $values = array();
             foreach ($contactIDs as $contactID => $dontCare) {
                 $values[] = "({$groupID},{$contactID})";
             }
             self::store($groupIDs, $values);
         }
     }
 }
예제 #11
0
 static function fromWhereEmail($id)
 {
     $params =& self::getSearchParams($id);
     if ($params) {
         if (CRM_Utils_Array::value('customSearchID', $params)) {
             require_once 'CRM/Contact/BAO/SearchCustom.php';
             return CRM_Contact_BAO_SearchCustom::fromWhereEmail(null, $id);
         } else {
             $tables = $whereTables = array('civicrm_contact' => 1, 'civicrm_email' => 1);
             $where = CRM_Contact_BAO_SavedSearch::whereClause($id, $tables, $whereTables);
             $from = CRM_Contact_BAO_Query::fromClause($whereTables);
             return array($from, $where);
         }
     } else {
         CRM_Core_Error::fatal('No contactID clause');
     }
 }