3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 class CRM_Campaign_BAO_Campaign
extends CRM_Campaign_DAO_Campaign
{
20 * Takes an associative array and creates a campaign object.
22 * the function extract all the params it needs to initialize the create a
23 * contact object. the params array could contain additional unused name/value
26 * @param array $params
27 * (reference ) an assoc array of name/value pairs.
29 * @return CRM_Campaign_DAO_Campaign
31 public static function create(&$params) {
36 if (empty($params['id'])) {
38 if (empty($params['created_id'])) {
39 $session = CRM_Core_Session
::singleton();
40 $params['created_id'] = $session->get('userID');
43 if (empty($params['created_date'])) {
44 $params['created_date'] = date('YmdHis');
47 if (empty($params['name'])) {
48 $params['name'] = CRM_Utils_String
::titleToVar($params['title'], 64);
51 CRM_Utils_Hook
::pre('create', 'Campaign', NULL, $params);
54 CRM_Utils_Hook
::pre('edit', 'Campaign', $params['id'], $params);
57 $campaign = new CRM_Campaign_DAO_Campaign();
58 $campaign->copyValues($params);
61 if (!empty($params['id'])) {
62 CRM_Utils_Hook
::post('edit', 'Campaign', $campaign->id
, $campaign);
65 CRM_Utils_Hook
::post('create', 'Campaign', $campaign->id
, $campaign);
68 /* Create the campaign group record */
70 $groupTableName = CRM_Contact_BAO_Group
::getTableName();
72 if (isset($params['groups']) && !empty($params['groups']['include']) && is_array($params['groups']['include'])) {
73 foreach ($params['groups']['include'] as $entityId) {
74 $dao = new CRM_Campaign_DAO_CampaignGroup();
75 $dao->campaign_id
= $campaign->id
;
76 $dao->entity_table
= $groupTableName;
77 $dao->entity_id
= $entityId;
78 $dao->group_type
= 'Include';
84 if (!empty($params['custom']) &&
85 is_array($params['custom'])
87 CRM_Core_BAO_CustomValueTable
::store($params['custom'], 'civicrm_campaign', $campaign->id
);
94 * Delete the campaign.
101 public static function del($id) {
106 CRM_Utils_Hook
::pre('delete', 'Campaign', $id, CRM_Core_DAO
::$_nullArray);
108 $dao = new CRM_Campaign_DAO_Campaign();
110 $result = $dao->delete();
112 CRM_Utils_Hook
::post('delete', 'Campaign', $id, $dao);
118 * Retrieve DB object based on input parameters.
120 * It also stores all the retrieved values in the default array.
122 * @param array $params
123 * (reference ) an assoc array of name/value pairs.
124 * @param array $defaults
125 * (reference ) an assoc array to hold the flattened values.
127 * @return \CRM_Campaign_DAO_Campaign|null
129 public static function retrieve(&$params, &$defaults) {
130 $campaign = new CRM_Campaign_DAO_Campaign();
132 $campaign->copyValues($params);
134 if ($campaign->find(TRUE)) {
135 CRM_Core_DAO
::storeValues($campaign, $defaults);
142 * Return the all eligible campaigns w/ cache.
144 * @param int $includeId
145 * Lets inlcude this campaign by force.
146 * @param int $excludeId
147 * Do not include this campaign.
148 * @param bool $onlyActive
149 * Consider only active campaigns.
151 * @param bool $onlyCurrent
152 * @param bool $appendDatesToTitle
153 * @param bool $forceAll
156 * $campaigns a set of campaigns.
158 public static function getCampaigns(
163 $appendDatesToTitle = FALSE,
173 'appendDatesToTitle',
176 foreach ($cacheKeyParams as $param) {
177 $cacheParam = $
$param;
181 $cacheKey .= '_' . $cacheParam;
184 if (!isset($campaigns[$cacheKey])) {
185 $where = ['( camp.title IS NOT NULL )'];
187 $where[] = "( camp.id != $excludeId )";
190 $where[] = '( camp.is_active = 1 )';
193 $where[] = '( camp.end_date IS NULL OR camp.end_date >= NOW() )';
195 $whereClause = implode(' AND ', $where);
197 $whereClause .= " OR ( camp.id = $includeId )";
202 $whereClause = '( 1 )';
210 FROM civicrm_campaign camp
212 Order By camp.title";
214 $campaign = CRM_Core_DAO
::executeQuery($query);
215 $campaigns[$cacheKey] = [];
216 $config = CRM_Core_Config
::singleton();
218 while ($campaign->fetch()) {
219 $title = $campaign->title
;
220 if ($appendDatesToTitle) {
222 foreach (['start_date', 'end_date'] as $date) {
223 if ($campaign->$date) {
224 $dates[] = CRM_Utils_Date
::customFormat($campaign->$date, $config->dateformatFull
);
227 if (!empty($dates)) {
228 $title .= ' (' . implode('-', $dates) . ')';
231 $campaigns[$cacheKey][$campaign->id
] = $title;
235 return $campaigns[$cacheKey];
239 * Wrapper to self::getCampaigns( )
240 * w/ permissions and component check.
242 * @param int $includeId
243 * @param int $excludeId
244 * @param bool $onlyActive
245 * @param bool $onlyCurrent
246 * @param bool $appendDatesToTitle
247 * @param bool $forceAll
248 * @param bool $doCheckForComponent
249 * @param bool $doCheckForPermissions
253 public static function getPermissionedCampaigns(
258 $appendDatesToTitle = FALSE,
260 $doCheckForComponent = TRUE,
261 $doCheckForPermissions = TRUE
269 'appendDatesToTitle',
270 'doCheckForComponent',
271 'doCheckForPermissions',
274 foreach ($cachekeyParams as $param) {
275 $cacheKeyParam = $
$param;
276 if (!$cacheKeyParam) {
279 $cacheKey .= '_' . $cacheKeyParam;
282 static $validCampaigns;
283 if (!isset($validCampaigns[$cacheKey])) {
287 'hasAccessCampaign' => FALSE,
288 'isCampaignEnabled' => FALSE,
291 //do check for component.
292 if ($doCheckForComponent) {
293 $campaigns['isCampaignEnabled'] = $isValid = self
::isCampaignEnable();
296 //do check for permissions.
297 if ($doCheckForPermissions) {
298 $campaigns['hasAccessCampaign'] = $isValid = self
::accessCampaign();
301 //finally retrieve campaigns from db.
303 $campaigns['campaigns'] = self
::getCampaigns($includeId,
313 $validCampaigns[$cacheKey] = $campaigns;
316 return $validCampaigns[$cacheKey];
320 * Is CiviCampaign enabled.
323 public static function isCampaignEnable() {
324 static $isEnable = NULL;
326 if (!isset($isEnable)) {
328 $config = CRM_Core_Config
::singleton();
329 if (in_array('CiviCampaign', $config->enableComponents
)) {
338 * Retrieve campaigns for dashboard.
340 * @param array $params
341 * @param bool $onlyCount
345 public static function getCampaignSummary($params = [], $onlyCount = FALSE) {
348 //build the limit and order clause.
349 $limitClause = $orderByClause = $lookupTableJoins = NULL;
352 'sort' => 'start_date',
355 'sortOrder' => 'desc',
357 foreach ($sortParams as $name => $default) {
358 if (!empty($params[$name])) {
359 $sortParams[$name] = $params[$name];
363 //need to lookup tables.
364 $orderOnCampaignTable = TRUE;
365 if ($sortParams['sort'] == 'status') {
366 $orderOnCampaignTable = FALSE;
367 $lookupTableJoins = "
368 LEFT JOIN civicrm_option_value status ON ( status.value = campaign.status_id OR campaign.status_id IS NULL )
369 INNER JOIN civicrm_option_group grp ON ( status.option_group_id = grp.id AND grp.name = 'campaign_status' )";
370 $orderByClause = "ORDER BY status.label {$sortParams['sortOrder']}";
372 elseif ($sortParams['sort'] == 'campaign_type') {
373 $orderOnCampaignTable = FALSE;
374 $lookupTableJoins = "
375 LEFT JOIN civicrm_option_value campaign_type ON ( campaign_type.value = campaign.campaign_type_id
376 OR campaign.campaign_type_id IS NULL )
377 INNER JOIN civicrm_option_group grp ON ( campaign_type.option_group_id = grp.id AND grp.name = 'campaign_type' )";
378 $orderByClause = "ORDER BY campaign_type.label {$sortParams['sortOrder']}";
380 elseif ($sortParams['sort'] == 'isActive') {
381 $sortParams['sort'] = 'is_active';
383 if ($orderOnCampaignTable) {
384 $orderByClause = "ORDER BY campaign.{$sortParams['sort']} {$sortParams['sortOrder']}";
386 $orderByClause = ($orderByClause) ?
$orderByClause . ", campaign.id {$sortParams['sortOrder']}" : $orderByClause;
387 $limitClause = "LIMIT {$sortParams['offset']}, {$sortParams['rowCount']}";
390 //build the where clause.
391 $queryParams = $where = [];
392 if (!empty($params['id'])) {
393 $where[] = "( campaign.id = %1 )";
394 $queryParams[1] = [$params['id'], 'Positive'];
396 if (!empty($params['name'])) {
397 $where[] = "( campaign.name LIKE %2 )";
398 $queryParams[2] = ['%' . trim($params['name']) . '%', 'String'];
400 if (!empty($params['title'])) {
401 $where[] = "( campaign.title LIKE %3 )";
402 $queryParams[3] = ['%' . trim($params['title']) . '%', 'String'];
404 if (!empty($params['start_date'])) {
405 $startDate = CRM_Utils_Date
::processDate($params['start_date']);
406 $where[] = "( campaign.start_date >= %4 OR campaign.start_date IS NULL )";
407 $queryParams[4] = [$startDate, 'String'];
409 if (!empty($params['end_date'])) {
410 $endDate = CRM_Utils_Date
::processDate($params['end_date'], '235959');
411 $where[] = "( campaign.end_date <= %5 OR campaign.end_date IS NULL )";
412 $queryParams[5] = [$endDate, 'String'];
414 if (!empty($params['description'])) {
415 $where[] = "( campaign.description LIKE %6 )";
416 $queryParams[6] = ['%' . trim($params['description']) . '%', 'String'];
418 if (!empty($params['campaign_type_id'])) {
419 $typeId = $params['campaign_type_id'];
420 if (is_array($params['campaign_type_id'])) {
421 $typeId = implode(' , ', $params['campaign_type_id']);
423 $where[] = "( campaign.campaign_type_id IN ( {$typeId} ) )";
425 if (!empty($params['status_id'])) {
426 $statusId = $params['status_id'];
427 if (is_array($params['status_id'])) {
428 $statusId = implode(' , ', $params['status_id']);
430 $where[] = "( campaign.status_id IN ( {$statusId} ) )";
432 if (array_key_exists('is_active', $params)) {
433 $active = "( campaign.is_active = 1 )";
434 if (!empty($params['is_active'])) {
435 $active = "( campaign.is_active = 0 OR campaign.is_active IS NULL )";
440 if (!empty($where)) {
441 $whereClause = ' WHERE ' . implode(" \nAND ", $where);
457 SELECT campaign.id as id,
458 campaign.name as name,
459 campaign.title as title,
460 campaign.is_active as is_active,
461 campaign.status_id as status_id,
462 campaign.end_date as end_date,
463 campaign.start_date as start_date,
464 campaign.description as description,
465 campaign.campaign_type_id as campaign_type_id';
467 $selectClause = 'SELECT COUNT(*)';
469 $fromClause = 'FROM civicrm_campaign campaign';
471 $query = "{$selectClause} {$fromClause} {$lookupTableJoins} {$whereClause} {$orderByClause} {$limitClause}";
473 //in case of only count.
475 return (int) CRM_Core_DAO
::singleValueQuery($query, $queryParams);
478 $campaign = CRM_Core_DAO
::executeQuery($query, $queryParams);
479 while ($campaign->fetch()) {
480 foreach ($properties as $property) {
481 $campaigns[$campaign->id
][$property] = $campaign->$property;
489 * Get the campaign count.
492 public static function getCampaignCount() {
493 return (int) CRM_Core_DAO
::singleValueQuery('SELECT COUNT(*) FROM civicrm_campaign');
497 * Get Campaigns groups.
499 * @param int $campaignId
504 public static function getCampaignGroups($campaignId) {
505 static $campaignGroups;
510 if (!isset($campaignGroups[$campaignId])) {
511 $campaignGroups[$campaignId] = [];
514 SELECT grp.title, grp.id
515 FROM civicrm_campaign_group campgrp
516 INNER JOIN civicrm_group grp ON ( grp.id = campgrp.entity_id )
517 WHERE campgrp.group_type = 'Include'
518 AND campgrp.entity_table = 'civicrm_group'
519 AND campgrp.campaign_id = %1";
521 $groups = CRM_Core_DAO
::executeQuery($query, [1 => [$campaignId, 'Positive']]);
522 while ($groups->fetch()) {
523 $campaignGroups[$campaignId][$groups->id
] = $groups->title
;
527 return $campaignGroups[$campaignId];
531 * Update the is_active flag in the db.
534 * Id of the database record.
535 * @param bool $is_active
536 * Value we want to set the is_active field.
539 * true if we found and updated the object, else false
541 public static function setIsActive($id, $is_active) {
542 return CRM_Core_DAO
::setFieldValue('CRM_Campaign_DAO_Campaign', $id, 'is_active', $is_active);
548 public static function accessCampaign() {
549 static $allow = NULL;
551 if (!isset($allow)) {
553 if (CRM_Core_Permission
::check('manage campaign') ||
554 CRM_Core_Permission
::check('administer CiviCampaign')
564 * Add select element for campaign
565 * and assign needful info to templates.
567 * @param CRM_Core_Form $form
568 * @param int $connectedCampaignId
570 public static function addCampaign(&$form, $connectedCampaignId = NULL) {
571 //some forms do set default and freeze.
573 if ($form->get('action') & CRM_Core_Action
::VIEW
) {
574 $appendDates = FALSE;
577 $campaignDetails = self
::getPermissionedCampaigns($connectedCampaignId, NULL, TRUE, TRUE, $appendDates);
578 $fields = ['campaigns', 'hasAccessCampaign', 'isCampaignEnabled'];
579 foreach ($fields as $fld) {
580 $
$fld = CRM_Utils_Array
::value($fld, $campaignDetails);
583 $showAddCampaign = FALSE;
584 if ($connectedCampaignId ||
($isCampaignEnabled && $hasAccessCampaign)) {
585 $showAddCampaign = TRUE;
586 $campaign = $form->addEntityRef('campaign_id', ts('Campaign'), [
587 'entity' => 'Campaign',
589 'select' => ['minimumInputLength' => 0],
591 //lets freeze when user does not has access or campaign is disabled.
592 if (!$isCampaignEnabled ||
!$hasAccessCampaign) {
597 //carry this info to templates.
603 foreach ($infoFields as $fld) {
604 $campaignInfo[$fld] = $
$fld;
606 $form->assign('campaignInfo', $campaignInfo);
610 * Add campaign in component search.
611 * and assign needful info to templates.
613 * @param CRM_Core_Form $form
614 * @param string $elementName
616 public static function addCampaignInComponentSearch(&$form, $elementName = 'campaign_id') {
618 $campaignDetails = self
::getPermissionedCampaigns(NULL, NULL, FALSE, FALSE, FALSE, TRUE);
619 $fields = ['campaigns', 'hasAccessCampaign', 'isCampaignEnabled'];
620 foreach ($fields as $fld) {
621 $
$fld = CRM_Utils_Array
::value($fld, $campaignDetails);
623 $showCampaignInSearch = FALSE;
624 if ($isCampaignEnabled && $hasAccessCampaign && !empty($campaigns)) {
625 //get the current campaign only.
626 $currentCampaigns = self
::getCampaigns(NULL, NULL, FALSE);
627 $pastCampaigns = array_diff($campaigns, $currentCampaigns);
629 if (!empty($currentCampaigns)) {
630 $allCampaigns = ['crm_optgroup_current_campaign' => ts('Current Campaigns')] +
$currentCampaigns;
632 if (!empty($pastCampaigns)) {
633 $allCampaigns +
= ['crm_optgroup_past_campaign' => ts('Past Campaigns')] +
$pastCampaigns;
636 $showCampaignInSearch = TRUE;
637 $form->add('select', $elementName, ts('Campaigns'), $allCampaigns, FALSE,
638 ['id' => 'campaigns', 'multiple' => 'multiple', 'class' => 'crm-select2']
645 'showCampaignInSearch',
647 foreach ($infoFields as $fld) {
648 $campaignInfo[$fld] = $
$fld;
650 $form->assign('campaignInfo', $campaignInfo);
656 public static function getEntityRefFilters() {
658 ['key' => 'campaign_type_id', 'value' => ts('Campaign Type')],
659 ['key' => 'status_id', 'value' => ts('Status')],
661 'key' => 'start_date',
662 'value' => ts('Start Date'),
664 ['key' => '{">":"now"}', 'value' => ts('Upcoming')],
666 'key' => '{"BETWEEN":["now - 3 month","now"]}',
667 'value' => ts('Past 3 Months'),
670 'key' => '{"BETWEEN":["now - 6 month","now"]}',
671 'value' => ts('Past 6 Months'),
674 'key' => '{"BETWEEN":["now - 1 year","now"]}',
675 'value' => ts('Past Year'),
681 'value' => ts('End Date'),
683 ['key' => '{">":"now"}', 'value' => ts('In the future')],
684 ['key' => '{"<":"now"}', 'value' => ts('In the past')],
685 ['key' => '{"IS NULL":"1"}', 'value' => ts('Not set')],
692 * Links to create new campaigns from entityRef widget
696 public static function getEntityRefCreateLinks() {
697 if (CRM_Core_Permission
::check([['administer CiviCampaign', 'manage campaign']])) {
700 'label' => ts('New Campaign'),
701 'url' => CRM_Utils_System
::url('civicrm/campaign/add', "reset=1",
702 NULL, NULL, FALSE, FALSE, TRUE),
703 'type' => 'Campaign',