prefix = 'twingle_campaign_'; $this->id = $id ?? NULL; $this->values['campaign_type_id'] = 'twingle_campaign'; if ($this->id) { $this->update($values); $this->getParentProject(); $this->createCid(); $this->createUrl(); } else { $this->update($values); } } /** * ## Create TwingleCampaign * Create this TwingleCampaign as a campaign in CiviCRM * * @param bool $no_hook * * @throws \CiviCRM_API3_Exception */ public function create(bool $no_hook = FALSE) { // Set a flag to not trigger the hook if ($no_hook) { $_SESSION['CiviCRM']['de.forumzfd.twinglecampaign']['no_hook'] = TRUE; } $values = $this->values; $this->translateCustomFields($values, self::IN); $result = civicrm_api3('Campaign', 'create', $values); if (!array_key_exists('is_error', $result) || $result['is_error'] != 0) { throw new CiviCRM_API3_Exception('TwingleCampaign creation failed'); } } /** * ## Fetch TwingleCampaign * Populate this instance with values from an existing TwingleCampaign. * * @throws CiviCRM_API3_Exception */ public function fetch() { $this->values = civicrm_api3('TwingleCampaign', 'getsingle', ['id' => $this->id]); } /** * ## Get Parent Project * Determines the id of the parent TwingleProject. If there is no parent * TwingleProject, an error message is shown on UI and the campaign gets * deleted. * * @throws \CiviCRM_API3_Exception */ private function getParentProject(): void { // Get campaign type id for TwingleProject $twingle_project_campaign_type_id = ExtensionCache::getInstance() ->getCampaignIds()['campaign_types']['twingle_project']['id']; // Determine the parent project id by looping through the campaign tree // until the parent campaign type is a TwingleProject $parent_id = $this->values['parent_id']; $parent_id = $parent_id ?? civicrm_api3( 'TwingleCampaign', 'getsingle', ['id' => $this->id] )['parent_id']; $parent_campaign_type_id = NULL; while ($parent_id && $parent_campaign_type_id != $twingle_project_campaign_type_id) { // Get parent campaign $parent_campaign = civicrm_api3('Campaign', 'getsingle', ['id' => $parent_id]); if (isset($parent_campaign['is_error'])) { if ($parent_campaign['is_error'] != 1) { throw new CiviCRM_API3_Exception($parent_campaign['error_message']); } } $parent_campaign_type_id = $parent_campaign['campaign_type_id']; if (isset($parent_campaign['parent_id'])) { $parent_id = $parent_campaign['parent_id']; } else { break; } } // Set parent_project_id and retrieve parent_project_url if ($parent_campaign_type_id == $twingle_project_campaign_type_id) { $this->values['parent_project_id'] = $parent_id; // Get custom field names for twingle_project_page and // twingle_project_url fields $cf_page = ExtensionCache::getInstance() ->getCustomFieldMapping('twingle_project_page'); $cf_url = ExtensionCache::getInstance() ->getCustomFieldMapping('twingle_project_url'); // Try to extract twingle_project_url from parent_campaign if (!empty($parent_campaign[$cf_url])) { $this->values['parent_project_url'] = $parent_campaign[$cf_url]; } // If there is no twingle_project_url use the parent_project_page instead elseif (!empty($parent_campaign[$cf_page])) { $this->values['parent_project_url'] = $parent_campaign[$cf_page]; } // If both values are missing, try a synchronization else { $parent_campaign = civicrm_api3('TwingleProject', 'sync', ['id' => $parent_id]); // Now try again to extract the twingle_project_page url if ($parent_campaign[$cf_url]) { $this->values['parent_project_url'] = $parent_campaign[$cf_page]; } // If twingle_project_widget value is still missing, show an alert on // UI, log an error and delete this TwingleCampaign else { CRM_Core_Session::setStatus( ts("Could not determine parent TwingleProject URL. This URL is needed to create the TwingleEvent URL. Please check the logs."), ts('Parent project URL missing'), 'error' ); Civi::log()->error( E::LONG_NAME . ' could not determine parent TwingleProject URL.', $this->getResponse() ); $this->delete(); } } // If this TwingleCampaign has no parent TwingleProject above it in the // campaign tree } else { CRM_Core_Session::setStatus( ts("TwingleCampaigns can only get created as a child of a TwingleProject in the campaign tree."), ts('No parent TwingleProject found'), 'alert' ); $this->delete(); } } /** * ## Create URL * Create a URL by adding a tw_cid */ private function createUrl() { // Trim parent_project_url $this->values['parent_project_url'] = trim($this->values['parent_project_url']); // If url ends with a '/', remove it if (substr($this->values['parent_project_url'], -1) == '/') { $this->values['parent_project_url'] = substr_replace($this->values['parent_project_url'], '', -1); } $this->values['url'] = $this->values['parent_project_url'] . '?tw_cid=' . $this->values['cid']; } /** * */ private function createCid() { $this->values['cid'] = md5($this->id . '_' . $this->values['name']); } /** * ## Translate field names and custom field names * * Constants for **$direction**:
* **Campaign::IN** Translate field name to custom field name
* **Campaign::OUT** Translate from custom field name to field name * * @param array $values * array of keys to translate * * @param string $direction * const: Campaign::OUT or Campaign::OUT */ public function translateCustomFields(array &$values, string $direction) { // Translate field name to custom field name if ($direction == self::IN) { foreach (ExtensionCache::getInstance() ->getCustomFieldMapping() as $field => $custom) { if (array_key_exists( str_replace( $this->prefix, '', $field ), $values) ) { $values[$custom] = $values[str_replace( $this->prefix, '', $field )]; unset($values[str_replace( $this->prefix, '', $field )] ); } } } // Translate from custom field name to field name elseif ($direction == self::OUT) { foreach (ExtensionCache::getInstance() ->getCustomFieldMapping() as $field => $custom) { if (array_key_exists( $custom, $values ) ) { $values[str_replace( $this->prefix, '', $field )] = $values[$custom]; unset($values[$custom]); } } } } /** * ## Delete TwingleCampaign * Deletes this TwingleCampaign from CiviCRM */ public function delete() { if ($this->id) { try { civicrm_api3('Campaign', 'delete', ['id' => $this->id]); } catch (CiviCRM_API3_Exception $e) { Civi::log()->error( E::LONG_NAME . ' could delete TwingleCampaign: ' . $e->getMessage(), $this->getResponse() ); } } } /** * ## Get a response * Get a response that describes the status of this TwingleCampaign instance. * Returns an array that contains **title**, **id**, **parent_project_id** * (if available) and **status** (if provided) * * @param string|null $status * status of the TwingleCampaign you want to give back along with the response * * @return array */ public function getResponse(string $status = NULL): array { $keys = ['id', 'name', 'title', 'parent_project_id', 'parent_id', 'cid', 'url']; $response = []; foreach ($keys as $key) { if (isset($this->values[$key])) { $response[$key] = $this->values[$key]; } } if ($status) { $response['status'] = $status; } return $response; } /** * ## Update values * Updates all values in **$this->values** array. * * @param array $values * values that should get updated */ private function update(array $values) { $filter = ExtensionCache::getInstance()->getTemplates()['TwingleCampaign']; foreach ($values as $key => $value) { if (in_array($key, $filter)) { $this->values[$key] = $values[$key]; } } } /** * ## Clone this TwingleProject * * This method removes the id from this instance and in the next step it * creates the clone as a new TwingleCampaign with the same values to * Twingle. * * @throws \CiviCRM_API3_Exception */ public function clone() { // TODO: implement cloning } /** * ## Get ID * @return mixed|null */ public function getId(): int { return (int) $this->id; } }