namespace Civi\Api4\Service\Spec\Provider;
+use Civi\Api4\Query\Api4SelectQuery;
use Civi\Api4\Service\Spec\FieldSpec;
use Civi\Api4\Service\Spec\RequestSpec;
* @throws \CRM_Core_Exception
*/
public function modifySpec(RequestSpec $spec): void {
+ $field = new FieldSpec('is_draft', 'Mailing', 'Boolean');
+ $field->setLabel(ts('Is Draft'))
+ ->setDescription(ts('True if mailing has not been scheduled or sent'))
+ ->setColumnName('id')
+ ->setReadonly(TRUE)
+ ->setSqlRenderer([__CLASS__, 'isDraft']);
+ $spec->addFieldSpec($field);
+
$field = new FieldSpec('stats_intended_recipients', 'Mailing', 'Integer');
$field->setLabel(ts('Stats: Intended Recipients'))
->setDescription(ts('Total emails sent'))
return $entity === 'Mailing' && $action === 'get';
}
+ /**
+ * Check if mailing has not been scheduled by anyone and has no record in MailingJob table.
+ *
+ * @param array $idField
+ * @param \Civi\Api4\Query\Api4SelectQuery $query
+ * @return string
+ */
+ public static function isDraft(array $idField, Api4SelectQuery $query): string {
+ $id = $idField['sql_name'];
+ $scheduled_id = $query->getFieldSibling($idField, 'scheduled_id')['sql_name'];
+ return "IF($scheduled_id OR EXISTS (SELECT 1 FROM civicrm_mailing_job WHERE is_test = 0 AND mailing_id = $id), 0, 1)";
+ }
+
/**
* Generate SQL for counting mailing events
*
namespace api\v4\Entity;
use api\v4\Api4TestBase;
+use Civi\Api4\Mailing;
use Civi\Test\TransactionalInterface;
/**
$eid2 = $this->createTestRecord('Email', ['contact_id' => $cid2])['id'];
$mid1 = $this->createTestRecord('Mailing')['id'];
$mid2 = $this->createTestRecord('Mailing')['id'];
- $parentJobIDs = $this->saveTestRecords('MailingJob',
- [
- 'records' => [
- ['mailing_id' => $mid1, 'is_test' => 'false'],
- ['mailing_id' => $mid2, 'is_test' => 'false'],
- ],
- ])->column('id');
+ $parentJobIDs = $this->saveTestRecords('MailingJob', [
+ 'records' => [
+ ['mailing_id' => $mid1, 'is_test' => FALSE],
+ ['mailing_id' => $mid2, 'is_test' => TRUE],
+ ],
+ ])->column('id');
+
+ // Test is_draft field
+ $mailings = Mailing::get(FALSE)
+ ->addSelect('id', 'is_draft')
+ ->addWhere('id', 'IN', [$mid1, $mid2])
+ ->execute()->indexBy('id');
+ $this->assertFalse($mailings[$mid1]['is_draft']);
+ $this->assertTrue($mailings[$mid2]['is_draft']);
+
+ Mailing::update(FALSE)
+ ->addWhere('id', '=', $mid2)
+ ->addValue('scheduled_id', $cid1)
+ ->execute();
+
+ $mailings = Mailing::get(FALSE)
+ ->addSelect('id', 'is_draft')
+ ->addWhere('id', 'IN', [$mid1, $mid2])
+ ->execute()->indexBy('id');
+ $this->assertFalse($mailings[$mid1]['is_draft']);
+ $this->assertFalse($mailings[$mid2]['is_draft']);
+
+ $parentJobIDs[] = $this->createTestRecord('MailingJob', [
+ 'mailing_id' => $mid2,
+ 'is_test' => FALSE,
+ ])['id'];
$childJobIDs = $this->saveTestRecords('MailingJob',
[
'records' => [
['mailing_id' => $mid1, 'parent_id' => $parentJobIDs[0], 'job_type' => 'child', 'is_test' => 'false'],
- ['mailing_id' => $mid2, 'parent_id' => $parentJobIDs[1], 'job_type' => 'child', 'is_test' => 'false'],
+ ['mailing_id' => $mid2, 'parent_id' => $parentJobIDs[2], 'job_type' => 'child', 'is_test' => 'false'],
],
])->column('id');
$queueIDs = $this->saveTestRecords('MailingEventQueue',
[
'records' => [
- ['job_id' => $childJobIDs[0], 'contact_id' => $cid1, 'email_id' => $eid1],
- ['job_id' => $childJobIDs[0], 'contact_id' => $cid2, 'email_id' => $eid2],
- ['job_id' => $childJobIDs[1], 'contact_id' => $cid1, 'email_id' => $eid1],
- ['job_id' => $childJobIDs[1], 'contact_id' => $cid2, 'email_id' => $eid2],
+ ['job_id' => $childJobIDs[0], 'mailing_id' => $mid1, 'contact_id' => $cid1, 'email_id' => $eid1],
+ ['job_id' => $childJobIDs[0], 'mailing_id' => $mid1, 'contact_id' => $cid2, 'email_id' => $eid2],
+ ['job_id' => $childJobIDs[1], 'mailing_id' => $mid2, 'contact_id' => $cid1, 'email_id' => $eid1],
+ ['job_id' => $childJobIDs[1], 'mailing_id' => $mid2, 'contact_id' => $cid2, 'email_id' => $eid2],
],
])->column('id');
],
]);
- $mailings = \Civi\Api4\Mailing::get(FALSE)
+ $mailings = Mailing::get(FALSE)
->addSelect('stats_intended_recipients', 'stats_successful', 'stats_opens_total', 'stats_opens_unique',
'stats_clicks_total', 'stats_clicks_unique', 'stats_bounces', 'stats_unsubscribes', 'stats_optouts',
- 'stats_optouts_and_unsubscribes', 'stats_forwards', 'stats_replies')
+ 'stats_optouts_and_unsubscribes', 'stats_forwards', 'stats_replies', 'is_draft')
->addWhere('id', 'IN', [$mid1, $mid2])
->addOrderBy('id', 'ASC')
->execute();
$this->assertEquals(0, $mailings[1]['stats_optouts']);
$this->assertEquals(2, $mailings[0]['stats_optouts_and_unsubscribes']);
$this->assertEquals(0, $mailings[1]['stats_optouts_and_unsubscribes']);
+ $this->assertFalse($mailings[0]['is_draft']);
+ $this->assertFalse($mailings[1]['is_draft']);
}
}