Merge pull request #8895 from totten/master-bin-adm
[civicrm-core.git] / CRM / Mailing / BAO / Mailing.php
index fdf003228bb70f9fcdc5a7d74586843c720b3fd5..0265444b1b80417275e9032ac2a150b24d50908c 100644 (file)
@@ -287,7 +287,7 @@ WHERE  c.group_id = {$groupDAO->id}
 
     $query = "REPLACE INTO       I_$job_id (email_id, contact_id)
 
-                    SELECT DISTINCT     $email.id as email_id,
+                    SELECT      $email.id as email_id,
                                         $contact.id as contact_id
                     FROM                $email
                     INNER JOIN          $contact
@@ -312,6 +312,7 @@ WHERE  c.group_id = {$groupDAO->id}
                         AND             $email.on_hold = 0
                         AND             $mg.mailing_id = {$mailing_id}
                         AND             X_$job_id.contact_id IS null
+                        GROUP BY $email.id, $contact.id
                     $order_by";
 
     if ($mode == 'sms') {
@@ -348,7 +349,7 @@ WHERE  c.group_id = {$groupDAO->id}
     // Query prior mailings.
 
     $query = "REPLACE INTO       I_$job_id (email_id, contact_id)
-                    SELECT DISTINCT     $email.id as email_id,
+                    SELECT      $email.id as email_id,
                                         $contact.id as contact_id
                     FROM                $email
                     INNER JOIN          $contact
@@ -370,6 +371,7 @@ WHERE  c.group_id = {$groupDAO->id}
                         AND             $email.on_hold = 0
                         AND             $mg.mailing_id = {$mailing_id}
                         AND             X_$job_id.contact_id IS null
+                        GROUP BY $email.id, $contact.id
                     $order_by";
 
     if ($mode == 'sms') {
@@ -472,7 +474,7 @@ AND    $mg.mailing_id = {$mailing_id}
     // Get the emails with only location override.
 
     $query = "REPLACE INTO       I_$job_id (email_id, contact_id)
-                    SELECT DISTINCT     $email.id as local_email_id,
+                    SELECT              $email.id as local_email_id,
                                         $contact.id as contact_id
                     FROM                $email
                     INNER JOIN          $contact
@@ -494,6 +496,7 @@ AND    $mg.mailing_id = {$mailing_id}
                         AND             $email.on_hold = 0
                         AND             $mg.mailing_id = {$mailing_id}
                         AND             X_$job_id.contact_id IS null
+                        GROUP BY $email.id, $contact.id
                     $order_by";
     if ($mode == "sms") {
       $query = "REPLACE INTO       I_$job_id (phone_id, contact_id)
@@ -539,7 +542,7 @@ WHERE  mailing_id = %1
       $groupBy = $groupJoin = '';
       if ($dedupeEmail) {
         $groupJoin = " INNER JOIN civicrm_email e ON e.id = i.email_id";
-        $groupBy = " GROUP BY e.email ";
+        $groupBy = " GROUP BY e.email, i.contact_id ";
       }
 
       $sql = "
@@ -908,40 +911,6 @@ ORDER BY   i.contact_id, i.{$tempColumn}
     }
   }
 
-  /**
-   * Build a join and where part for a query
-   *
-   * @param $contact_id
-   * @return array - the first key is join part of the query and the second key is the where part of the query
-   */
-  public function buildAcl($contact_id) {
-    $tables = array();
-    $whereTables = array();
-    $whereClause = CRM_ACL_BAO_ACL::whereClause(CRM_Core_Permission::VIEW, $tables, $whereTables, $contact_id);
-    if (strlen($whereClause)) {
-      $whereClause = " AND (".$whereClause.")";
-    }
-
-    $join = "";
-    foreach ($whereTables as $name => $value) {
-      if (!$value) {
-        continue;
-      }
-      if ($value != 1) {
-        // if there is already a join statement in value, use value itself
-        if (strpos($value, 'JOIN')) {
-          $join .= " $value ";
-        }
-        continue;
-      }
-    }
-
-    return array (
-      $join,
-      $whereClause
-    );
-  }
-
   /**
    * Generate an event queue for a test job.
    *
@@ -952,8 +921,8 @@ ORDER BY   i.contact_id, i.{$tempColumn}
    */
   public function getTestRecipients($testParams) {
     $session = CRM_Core_Session::singleton();
-    $sender_id = $session->get('userID');
-    list($acl_join, $acl_where) = $this->buildAcl($sender_id);
+    $senderId = $session->get('userID');
+    list($aclJoin, $aclWhere) = CRM_ACL_BAO_ACL::buildAcl($senderId);
 
     if (array_key_exists($testParams['test_group'], CRM_Core_PseudoConstant::group())) {
       $contacts = civicrm_api('contact', 'get', array(
@@ -973,14 +942,14 @@ SELECT     civicrm_email.id AS email_id,
            civicrm_email.is_bulkmail as is_bulkmail
 FROM       civicrm_email
 INNER JOIN civicrm_contact contact_a ON civicrm_email.contact_id = contact_a.id
-{$acl_join}
+{$aclJoin}
 WHERE      (civicrm_email.is_bulkmail = 1 OR civicrm_email.is_primary = 1)
 AND        contact_a.id = {$groupContact}
 AND        contact_a.do_not_email = 0
 AND        contact_a.is_deceased <> 1
 AND        civicrm_email.on_hold = 0
 AND        contact_a.is_opt_out = 0
-{$acl_where}
+{$aclWhere}
 GROUP BY   civicrm_email.id
 ORDER BY   civicrm_email.is_bulkmail DESC
 ";
@@ -1794,7 +1763,8 @@ ORDER BY   civicrm_email.is_bulkmail DESC
       $job->is_test = 0;
 
       if (!$job->find(TRUE)) {
-        $job->scheduled_date = $params['scheduled_date'];
+        // Don't schedule job until we populate the recipients.
+        $job->scheduled_date = NULL;
         $job->save();
       }
 
@@ -1804,6 +1774,9 @@ ORDER BY   civicrm_email.is_bulkmail DESC
         $mode = $mailing->sms_provider_id ? 'sms' : NULL;
         self::getRecipients($job->id, $mailing->id, TRUE, $mailing->dedupe_email, $mode);
       }
+      // Schedule the job now that it has recipients.
+      $job->scheduled_date = $params['scheduled_date'];
+      $job->save();
     }
 
     return $mailing;
@@ -2500,7 +2473,7 @@ LEFT JOIN civicrm_mailing_group g ON g.mailing_id   = m.id
         $mailings = implode(',', $mailingIDs);
         $mailingQuery = "
            SELECT DISTINCT ( m.id ) as id
-           FROM civicrm_mailing m 
+           FROM civicrm_mailing m
            LEFT JOIN civicrm_mailing_group g ON g.mailing_id = m.id
            WHERE g.entity_table like 'civicrm_mailing%' AND g.entity_id IN ($mailings)";
         $mailingDao = CRM_Core_DAO::executeQuery($mailingQuery);
@@ -2539,31 +2512,31 @@ LEFT JOIN civicrm_mailing_group g ON g.mailing_id   = m.id
 
     //get all campaigns.
     $allCampaigns = CRM_Campaign_BAO_Campaign::getCampaigns(NULL, NULL, FALSE, FALSE, FALSE, TRUE);
+    $select = array(
+      "$mailing.id", "$mailing.name", "$job.status",
+      "$mailing.approval_status_id", "createdContact.sort_name as created_by", "scheduledContact.sort_name as scheduled_by",
+      "$mailing.created_id as created_id", "$mailing.scheduled_id as scheduled_id", "$mailing.is_archived as archived",
+      "$mailing.created_date as created_date", "campaign_id", "$mailing.sms_provider_id as sms_provider_id",
+    );
 
     // we only care about parent jobs, since that holds all the info on
     // the mailing
+    $selectClause = implode(', ', $select);
+    $groupFromSelect = CRM_Contact_BAO_Query::getGroupByFromSelectColumns($select, "$mailing.id");
     $query = "
-            SELECT      $mailing.id,
-                        $mailing.name,
-                        $job.status,
-                        $mailing.approval_status_id,
+            SELECT      {$selectClause},
                         MIN($job.scheduled_date) as scheduled_date,
                         MIN($job.start_date) as start_date,
-                        MAX($job.end_date) as end_date,
-                        createdContact.sort_name as created_by,
-                        scheduledContact.sort_name as scheduled_by,
-                        $mailing.created_id as created_id,
-                        $mailing.scheduled_id as scheduled_id,
-                        $mailing.is_archived as archived,
-                        $mailing.created_date as created_date,
-                        campaign_id,
-                        $mailing.sms_provider_id as sms_provider_id
+                        MAX($job.end_date) as end_date
             FROM        $mailing
             LEFT JOIN   $job ON ( $job.mailing_id = $mailing.id AND $job.is_test = 0 AND $job.parent_id IS NULL )
             LEFT JOIN   civicrm_contact createdContact ON ( civicrm_mailing.created_id = createdContact.id )
             LEFT JOIN   civicrm_contact scheduledContact ON ( civicrm_mailing.scheduled_id = scheduledContact.id )
-            WHERE       $mailingACL $additionalClause
-            GROUP BY    $mailing.id ";
+            WHERE       $mailingACL $additionalClause";
+
+    if (!empty($groupFromSelect)) {
+      $query .= $groupFromSelect;
+    }
 
     if ($sort) {
       $orderBy = trim($sort->orderBy());
@@ -2733,7 +2706,7 @@ LEFT JOIN civicrm_mailing_group g ON g.mailing_id   = m.id
       $className != 'CRM_Contact_Form_Task_SMS'
     ) {
       $form->add('wysiwyg', 'html_message',
-        ts('HTML Format'),
+        strstr($className, 'PDF') ? ts('Document Body') : ts('HTML Format'),
         array(
           'cols' => '80',
           'rows' => '8',
@@ -3210,4 +3183,18 @@ AND        m.id = %1
     return array_combine($tables, $tables);
   }
 
+  /**
+   * Get the public view url.
+   *
+   * @param int $id
+   * @param bool $absolute
+   *
+   * @return string
+   */
+  public static function getPublicViewUrl($id, $absolute = TRUE) {
+    if ((civicrm_api3('Mailing', 'getvalue', array('id' => $id, 'return' => 'visibility'))) === 'Public Pages') {
+      return CRM_Utils_System::url('civicrm/mailing/view', array('id' => $id), $absolute, NULL, TRUE, TRUE);
+    }
+  }
+
 }