From 88474c10ac32f71b8a013e52a9083bae533635c0 Mon Sep 17 00:00:00 2001 From: Marc Michalsky forumZFD Date: Mon, 1 Feb 2021 14:33:03 +0100 Subject: [PATCH] clean up improve method documentation and more --- CRM/TwingleCampaign/BAO/Campaign.php | 250 +++++++------------- CRM/TwingleCampaign/BAO/TwingleApiCall.php | 88 ++++--- CRM/TwingleCampaign/BAO/TwingleCampaign.php | 25 +- CRM/TwingleCampaign/BAO/TwingleEvent.php | 101 +++----- CRM/TwingleCampaign/BAO/TwingleProject.php | 118 +++------ api/v3/TwingleEvent/Get.php | 11 +- api/v3/TwingleEvent/Sync.php | 55 +++-- api/v3/TwingleProject/Create.php | 31 ++- api/v3/TwingleProject/Get.php | 5 +- api/v3/TwingleSync/Sync.php | 2 +- 10 files changed, 305 insertions(+), 381 deletions(-) diff --git a/CRM/TwingleCampaign/BAO/Campaign.php b/CRM/TwingleCampaign/BAO/Campaign.php index a0a62d4..70d073e 100644 --- a/CRM/TwingleCampaign/BAO/Campaign.php +++ b/CRM/TwingleCampaign/BAO/Campaign.php @@ -22,91 +22,30 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { /** - * Campaign constructor. + * ## Campaign constructor. * - * @param array $campaign - * Result array of Twingle API call - * - * Origin of the arrays. It can be one of two constants: - * Campaign::TWINGLE|CIVICRM - * - * @throws Exception + * @param array $values + * @param int|null $id */ - protected function __construct(array $campaign) { + protected function __construct(array $values, int $id = NULL) { + $this->id = $id; $tmpClassName = explode('_', get_class($this)); $this->className = array_pop($tmpClassName); // Set campaign values - $this->update($campaign); - } - - /** - * Check if a campaign already exists and if so set attributes - * to the values of the existing campaign. - * - * @return bool - * Returns TRUE id the campaign already exists - * - * @throws CiviCRM_API3_Exception - * - * @throws Exception - */ - public function exists(): bool { - - if (!$this->values['id']) { - return FALSE; - } - - $single = FALSE; - - $query = ['sequential' => 1,]; - - switch($this->className) { - case 'TwingleProject': - $query['project_id'] = $this->values['id']; - break; - case 'TwingleEvent': - $query['event_id'] = $this->values['id']; - } - - $result = civicrm_api3($this->className, 'get', $query); - - // If there is more than one campaign for this entity, handle the duplicates - if ($result['count'] > 1) { - self::handleDuplicates($result); - } - else { - $single = TRUE; - } - - // If this campaign already exists, get its attributes - if ($result['count'] == 1) { - - // Extract campaign values from result array - $values = $result['values'][0]; - - // Set id attribute - $this->id = $values['id']; - - // Set attributes to the values of the existing campaign - // to reflect the state of the actual campaign in the database - $this->update($values); - - return TRUE; - } - else { - return FALSE; - } + $this->update($values); } /** - * Update an existing campaign + * ## Update instance values + * This method updates the **$values** array of this instance with the values + * from the provided array if they are defined in + * *CRM/TwingleCampaign/resources/twingle_api_templates.json* * * @param array $values * Array with values to update - * */ public function update(array $values) { // Update campaign values @@ -129,67 +68,85 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { /** - * Deactivate all duplicates of a campaign but the newest one + * ## Set embed data fields + * This method sets all embed data fields that are defined in + * *CRM/TwingleCampaign/resources/twingle_api_templates.json* * - * @param array $result - * - * @throws CiviCRM_API3_Exception + * @param array $embedData + * Array with embed data from Twingle API */ - protected function handleDuplicates(array &$result) { + public function setEmbedData(array $embedData) { - // Sort campaigns ascending by the value of the last_modified_date - uasort($result['values'], function ($a, $b) { - return $a['last_modified_date'] <=> $b['last_modified_date']; - }); + // Get all embed_data keys from template + $embed_data_keys = Cache::getInstance() + ->getTemplates()['project_embed_data']; - // Deactivate all but the first campaign - while (sizeof($result['values']) > 1) { - self::deactivateById(array_pop($result['values'])); + // Transfer all embed_data values + foreach ($embed_data_keys as $key) { + $this->values[$key] = $embedData[$key]; } } - /** - * Translate values between CiviCRM Campaigns and Twingle format - * - * @param array $values - * array of which values shall be translated - * - * @param string $direction - * TwingleProject::IN -> translate array values from Twingle to CiviCRM
- * TwingleProject::OUT -> translate array values from CiviCRM to Twingle - * - * @throws Exception - */ - public static abstract function formatValues(array &$values, string $direction); + + public abstract function formatValues(array &$values, string $direction); /** - * Translate array keys between CiviCRM Campaigns and Twingle + * ## Translate array keys between CiviCRM Campaigns and Twingle * - * @param array $values - * array of which keys to translate - * - * @param string $direction - * Campaign::IN -> translate array keys from Twingle format into + * Constants for **$direction**:
+ * **Campaign::IN** translate array keys from Twingle format into * CiviCRM format
- * Campaign::OUT -> translate array keys from CiviCRM format into + * **Campaign::OUT** translate array keys from CiviCRM format into * Twingle format * + * @param array $values + * array of keys to translate + * + * @param string $direction + * const: Campaign::OUT or Campaign::OUT + * * @throws Exception */ - public static abstract function translateKeys(array &$values, string $direction); + public function translateKeys(array &$values, string $direction) { + + // Get translations for fields + $field_translations = Cache::getInstance() + ->getTranslations()[$this->className]; + + // Set the direction of the translation + if ($direction == self::OUT) { + $field_translations = array_flip($field_translations); + } + // Throw error if $direction constant does not match IN or OUT + elseif ($direction != self::IN) { + throw new Exception( + "Invalid Parameter $direction for translateKeys()" + ); + } + + // Translate keys + foreach ($field_translations as $origin => $translation) { + $values[$translation] = $values[$origin]; + unset($values[$origin]); + } + } /** - * Translate between field names and custom field names + * ## Translate field names and custom field names + * + * Constants for **$direction**:
+ * **Campaign::IN** translate array keys from Twingle format into + * CiviCRM format
+ * **Campaign::OUT** translate array keys from CiviCRM format into + * Twingle format * * @param array $values - * array of which keys shall be translated + * array of keys to translate * * @param string $direction - * Campaign::IN -> translate field names into custom field names
- * Campaign::OUT -> translate custom field names into field names - * + * const: Campaign::OUT or Campaign::OUT */ public function translateCustomFields(array &$values, string $direction) { @@ -245,23 +202,6 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { } } - /** - * Set embed data fields - * - * @param array $embedData - * Array with embed data from Twingle API - */ - public function setEmbedData(array $embedData) { - - // Get all embed_data keys from template - $embed_data_keys = Cache::getInstance() - ->getTemplates()['project_embed_data']; - - // Transfer all embed_data values - foreach ($embed_data_keys as $key) { - $this->values[$key] = htmlspecialchars($embedData[$key]); - } - } /** * Set counter url @@ -273,8 +213,9 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { $this->values['counter'] = $counterUrl; } + /** - * Deactivate this Campaign campaign + * ## Deactivate this campaign * * @return bool * TRUE if deactivation was successful @@ -282,13 +223,12 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { * @throws CiviCRM_API3_Exception */ public function deactivate(): bool { - return self::deactivateByid($this->id); - } + /** - * Deactivate a Campaign campaign by ID + * ## Deactivate campaign by ID * * @param $id * ID of the campaign that should get deactivated @@ -319,28 +259,21 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { else { return FALSE; } - } - /** - * Get a response that describes the status of a Campaign - * - * @param string $status - * status of the Campaign you want the response for - * - * @return array - * Returns a response array that contains title, id, project_id and status - */ public abstract function getResponse(string $status): array; + /** - * Validates $input to be either a DateTime string or an Unix timestamp + * ## Get timestamp + * Validates **$input** to be either a *DateTime string* or an *Unix timestamp* + * and in both cases returns a *Unix time stamp*. * * @param $input - * Pass a DateTime string or a Unix timestamp + * Provide a DateTime string or a Unix timestamp * - * @return int + * @return int|null * Returns a Unix timestamp or NULL if $input is invalid */ public static function getTimestamp($input): ?int { @@ -361,27 +294,24 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { else { return NULL; } - } - /** - * Return a timestamp of the last update of the Campaign - * - * @return int|string|null - */ + public abstract function lastUpdate(); /** - * Validates $input to be either a DateTime string or an Unix timestamp + * ## Get DateTime + * Validates **$input** to be either a *DateTime string* or an *Unix timestamp* + * and in both cases returns *DateTime string*. * * @param $input - * Pass a DateTime string or a Unix timestamp + * Provide a DateTime string or a Unix timestamp * * @return string * Returns a DateTime string or NULL if $input is invalid */ - public static function getDateTime($input) { + public static function getDateTime($input): ?string { // Check whether $input is a Unix timestamp if ( @@ -399,25 +329,17 @@ abstract class CRM_TwingleCampaign_BAO_Campaign { else { return NULL; } - } /** - * Returns the project_id of a Campaign + * ## Get id + * Returns the **id** of this campaign. * * @return int */ - public function getProjectId() { - return $this->values['id']; - } - - - /** - * @return mixed - */ - public function getId() { - return $this->id; + public function getId(): int { + return (int) $this->id; } } diff --git a/CRM/TwingleCampaign/BAO/TwingleApiCall.php b/CRM/TwingleCampaign/BAO/TwingleApiCall.php index 8a612fe..ac46903 100644 --- a/CRM/TwingleCampaign/BAO/TwingleApiCall.php +++ b/CRM/TwingleCampaign/BAO/TwingleApiCall.php @@ -19,7 +19,7 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { private $extensionName; /** - * TwingleApiCall constructor. + * ## TwingleApiCall constructor * * @param $apiKey * @@ -65,16 +65,17 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } /** - * If $id parameter is empty, this function returns all projects for all - * organisations this API key is assigned to. + * ## Get project from Twingle + * If the **$id** parameter is empty, this function returns all projects for + * this organisation. * - * If $id parameter is given, this function returns a single project. + * If the **$id** parameter is provided, this function returns a single + * project. * * @param int|null $projectId - * - * @return mixed + * @return array|false */ - public function getProject(int $projectId = NULL) { + public function getProject(int $projectId = NULL): ?array { $url = empty($projectId) ? $this->protocol . 'project' . $this->baseUrl . 'by-organisation/' . $this->organisationId @@ -84,18 +85,20 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } /** - * Sends an curl post call to Twingle to update an existing project and then - * updates the TwingleProject campaign. + * ## Push project to Twingle + * Sends a curl post call to Twingle to update an existing project. + * + * Returns an array with all project values. * * @param TwingleProject $project * The TwingleProject object that should get pushed to Twingle * * @return array - * Returns a response array that contains title, id, project_id and status * @throws \Exception */ - public function pushProject(TwingleProject &$project) { + public function pushProject(TwingleProject &$project): array { + // Get only those values from the TwingleProject object which Twingle expects $values = $project->export(); // Prepare url for curl @@ -112,18 +115,19 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } /** - * Returns all Events for the given $projectId or a single event if an - * $eventId is given, too. + * ## Get event from Twingle + * Returns all events for the provided **$projectId** or a single event if an + * **$eventId** is provided, too. * * @param int $projectId - * * @param null|int $eventId - * * @return array + * @throws Exception */ - public function getEvent($projectId, $eventId = NULL) { + public function getEvent(int $projectId, int $eventId = NULL): array { $result = []; + // Construct url for curl $url = empty($eventId) ? $this->protocol . 'project' . $this->baseUrl . $projectId . '/event' : $this->protocol . 'project' . $this->baseUrl . $projectId . '/event/' @@ -147,15 +151,15 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { // If no $eventId was given, expect one or more events. // Store the events, increase the offset and ask again until there // are no more events incoming. - if ($response['data'] && !$eventId) { + if (!$eventId) { $result = array_merge($result, $response['data']); $offset = $offset + $this->limit; $finished = count($response['data']) < $this->limit; } // If $eventId was given, expect only one event else { - // If result the array contains 'message', the $eventId does not exist - if (!$result['message']) { + // If the response array contains 'message', the $eventId does not exist + if (!$response['message']) { $result = $response; } $finished = TRUE; @@ -165,13 +169,15 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { } /** + * ## Get project embed data + * Get embed data for a specific project. + * * @param $projectId * - * @return array|NULL - * @throws \Exception + * @return array + * @throws Exception */ - public - function getProjectEmbedData($projectId): array { + public function getProjectEmbedData($projectId): array { $result = $this->getProject($projectId); @@ -190,19 +196,21 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { /** - * Does a cURL and gives back the result array. + * ## Send a GET cURL + * Sends a GET cURL and returns the result array. * * @param $url - * The url the curl should get sent to + * The destination url * * @param null $params * The parameters you want to send (optional) * - * @return array|bool + * @return array * Returns the result array of the curl or FALSE, if the curl failed + * @throws Exception */ private - function curlGet($url, $params = NULL) { + function curlGet($url, $params = NULL): array { if (!empty($params)) { $url = $url . '?' . http_build_query($params); } @@ -213,27 +221,30 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { 'Content-Type: application/json', ]); $response = json_decode(curl_exec($curl), TRUE); - if (empty($response)) { - $response = curl_error($curl); - } curl_close($curl); + if ($response === FALSE) { + throw new Exception('GET curl failed'); + } return $response; } + /** - * Sends a curl post and gives back the result array. + * ## Send a POST cURL + * Sends a POST cURL and returns the result array. * * @param $url - * The url the curl should get sent to + * The destination url * * @param $data - * The data that should get posted + * The data that should get send * - * @return false|mixed + * @return array * Returns the result array of the curl or FALSE, if the curl failed + * @throws Exception */ private - function curlPost($url, $data) { + function curlPost($url, $data): array { $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($curl, CURLOPT_POST, TRUE); @@ -244,11 +255,10 @@ class CRM_TwingleCampaign_BAO_TwingleApiCall { $json = json_encode($data); curl_setopt($curl, CURLOPT_POSTFIELDS, $json); $response = json_decode(curl_exec($curl), TRUE); - if (empty($response)) { - $response = FALSE; - } curl_close($curl); + if ($response === FALSE) { + throw new Exception('POST curl failed'); + } return $response; } - } diff --git a/CRM/TwingleCampaign/BAO/TwingleCampaign.php b/CRM/TwingleCampaign/BAO/TwingleCampaign.php index 8d40e46..d8373ce 100644 --- a/CRM/TwingleCampaign/BAO/TwingleCampaign.php +++ b/CRM/TwingleCampaign/BAO/TwingleCampaign.php @@ -1,7 +1,28 @@ values; - self::formatValues( + $this::formatValues( $values_prepared_for_import, self::IN ); - self::translateKeys( + $this->translateKeys( $values_prepared_for_import, self::IN ); @@ -107,19 +107,20 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { /** - * Translate values between CiviCRM Campaigns and Twingle + * ## Translate values between CiviCRM Campaigns and Twingle formats + * Constants for **$direction**:
+ * **TwingleProject::IN** translate array values from Twingle to CiviCRM format
+ * **TwingleProject::OUT** translate array values from CiviCRM to Twingle format * * @param array $values - * array of which values shall be translated + * array of values to translate * * @param string $direction - * self::IN -> translate array values from Twingle to CiviCRM
- * self::OUT -> translate array values from CiviCRM to Twingle + * const: TwingleProject::IN or TwingleProject::OUT * * @throws Exception */ - public - static function formatValues(array &$values, string $direction) { + public function formatValues(array &$values, string $direction) { if ($direction == self::IN) { @@ -189,55 +190,15 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { /** - * Translate array keys between CiviCRM Campaigns and Twingle - * - * @param array $values - * array of which keys shall be translated - * - * @param string $direction - * Campaign::IN -> translate array keys from Twingle format into - * CiviCRM format
- * Campaign::OUT -> translate array keys from CiviCRM format into - * Twingle format - * - * @throws Exception - */ - public - static function translateKeys(array &$values, string $direction) { - - // Get translations for fields - $field_translations = Cache::getInstance() - ->getTranslations()['TwingleEvent']; - - // Set the direction of the translation - if ($direction == self::OUT) { - $field_translations = array_flip($field_translations); - } - // Throw error if $direction constant does not match IN or OUT - elseif ($direction != self::IN) { - throw new Exception( - "Invalid Parameter $direction for translateKeys()" - ); - // TODO: use specific exception or create own - } - - // Translate keys - foreach ($field_translations as $origin => $translation) { - $values[$translation] = $values[$origin]; - unset($values[$origin]); - } - } - - - /** - * Get a response that describes the status of a TwingleEvent + * ## Get a response + * Get a response that describes the status of this TwingleEvent instance. + * Returns an array that contains **title**, **id**, **event_id**, + * **project_id** and **status** (if provided) * * @param string|null $status * status of the TwingleEvent you want to give back along with the response * * @return array - * Returns a response array that contains title, id, event_id, project_id and - * status */ public function getResponse(string $status = NULL): array { @@ -256,8 +217,9 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { /** - * Matches a single string that should contain first and lastname to match a - * contact or create a new one if it does not exist yet. + * ## Match a contact + * This method uses a single string that is expected to contain first and + * lastname to match a contact or create a new one if it does not exist yet. * * @param string $names * @param string $email @@ -288,13 +250,14 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { /** - * Gets the campaign id of the parent TwingleProject campaign. + * ## Get parent campaign id + * Returns the campaign id of the parent TwingleProject campaign. * * @return int|null * @throws CiviCRM_API3_Exception */ private - function getParentCampaignId() { + function getParentCampaignId(): ?int { $cf_project_id = Cache::getInstance() ->getCustomFieldMapping()['twingle_project_id']; $parentCampaign = civicrm_api3('Campaign', 'get', [ @@ -310,35 +273,37 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { } /** - * Return a timestamp of the last update of the Campaign + * ## Last update + * Returns a timestamp of the last update of the TwingleEvent campaign. * * @return int|string|null */ public function lastUpdate() { - return self::getTimestamp($this->values['updated_at']); } /** - * Returns the project_id of a TwingleEvent + * ## Get project id + * Returns the **project_id** of this TwingleEvent. * * @return int */ public - function getProjectId() { + function getProjectId(): int { return (int) $this->values['project_id']; } /** - * Returns the event_id of a TwingleEvent + * ## Get event id + * Returns the **event_id** of this TwingleEvent. * * @return int */ public - function getEventId() { + function getEventId(): int { return (int) $this->values['id']; } } diff --git a/CRM/TwingleCampaign/BAO/TwingleProject.php b/CRM/TwingleCampaign/BAO/TwingleProject.php index d7e5b14..24f6aec 100644 --- a/CRM/TwingleCampaign/BAO/TwingleProject.php +++ b/CRM/TwingleCampaign/BAO/TwingleProject.php @@ -7,16 +7,16 @@ use CRM_TwingleCampaign_BAO_Campaign as Campaign; class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { /** - * TwingleProject constructor. + * ## TwingleProject constructor + * + * @param array $values + * Project values * - * @param array $project - * Result array of Twingle API call to - * https://project.twingle.de/api/by-organisation/$organisation_id * @param int|null $id - * + * CiviCRM Campaign id */ - public function __construct(array $project, int $id = NULL) { - parent::__construct($project, $id); + public function __construct(array $values, int $id = NULL) { + parent::__construct($values, $id); $this->prefix = 'twingle_project_'; $this->values['campaign_type_id'] = 'twingle_project'; @@ -27,8 +27,10 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { /** - * Export values. Ensures that only those values will be exported which the - * Twingle API expects. + * ## Export values + * Ensures that only those values will be exported which the Twingle API + * expects. These values are defined in + * *CRM/TwingleCampaign/resources/twingle_api_templates.json* * * @return array * Array with all values to send to the Twingle API @@ -55,25 +57,25 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { /** - * Create the Campaign as a campaign in CiviCRM if it does not exist + * ## Create this TwingleProject as a campaign in CiviCRM + * + * Returns _TRUE_ if creation was successful or _FALSE_ if it creation failed. * * @param bool $no_hook * Do not trigger postSave hook to prevent recursion * * @return bool - * Returns a boolean - * * @throws \Exception */ public function create(bool $no_hook = FALSE): bool { // Prepare project values for import into database $values_prepared_for_import = $this->values; - self::formatValues( + $this->formatValues( $values_prepared_for_import, self::IN ); - self::translateKeys( + $this->translateKeys( $values_prepared_for_import, self::IN ); @@ -121,17 +123,23 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { $this->create(); // this will also trigger the postSave hook } + + /** + * ## Translate values between CiviCRM Campaigns and Twingle formats + * + * Constants for **$direction**:
+ * **TwingleProject::IN** translate array values from Twingle to CiviCRM format
+ * **TwingleProject::OUT** translate array values from CiviCRM to Twingle format * * @param array $values - * array of which values shall be translated + * array of values to translate * * @param string $direction - * TwingleProject::IN -> translate array values from Twingle to CiviCRM
- * TwingleProject::OUT -> translate array values from CiviCRM to Twingle + * const: TwingleProject::IN or TwingleProject::OUT * * @throws Exception */ - public static function formatValues(array &$values, string $direction) { + public function formatValues(array &$values, string $direction) { if ($direction == self::IN) { @@ -164,7 +172,6 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { $values['allow_more'] = empty($values['allow_more']) ? FALSE : TRUE; - } else { @@ -175,73 +182,18 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { } } - /** - * Translate array keys between CiviCRM Campaigns and Twingle - * - * @param array $values - * array of which keys shall be translated - * - * @param string $direction - * Campaign::IN -> translate array keys from Twingle format into - * CiviCRM format
- * Campaign::OUT -> translate array keys from CiviCRM format into - * Twingle format - * - * @throws Exception - */ - public static function translateKeys(array &$values, string $direction) { - - // Get translations for fields - $field_translations = Cache::getInstance() - ->getTranslations()['TwingleProject']; - - // Set the direction of the translation - if ($direction == self::OUT) { - $field_translations = array_flip($field_translations); - } - // Throw error if $direction constant does not match IN or OUT - elseif ($direction != self::IN) { - throw new Exception( - "Invalid Parameter $direction for translateKeys()" - ); - // TODO: use specific exception or create own - } - - // Translate keys - foreach ($field_translations as $origin => $translation) { - $values[$translation] = $values[$origin]; - unset($values[$origin]); - } - } - /** - * Set embed data fields - * - * @param array $embedData - * Array with embed data from Twingle API - */ - public function setEmbedData(array $embedData) { - - // Get all embed_data keys from template - $embed_data_keys = Cache::getInstance() - ->getTemplates()['project_embed_data']; - - // Transfer all embed_data values - foreach ($embed_data_keys as $key) { - $this->values[$key] = $embedData[$key]; - } - } - - - /** - * Get a response that describes the status of a TwingleProject + * ## Get a response + * Get a response that describes the status of this TwingleProject instance + * Returns an array that contains **title**, **id**, **project_id** and + * **status** (if provided) * * @param string|null $status * status of the TwingleProject you want to give back along with the response * * @return array - * Returns a response array that contains title, id, project_id and status + * */ public function getResponse(string $status = NULL): array { $project_type = empty($this->values['type']) ? 'default' : $this->values['type']; @@ -258,19 +210,21 @@ class CRM_TwingleCampaign_BAO_TwingleProject extends Campaign { return $response; } + /** - * Return a timestamp of the last update of the Campaign + * ## Last update + * Returns a timestamp of the last update of the TwingleProject campaign. * * @return int|string|null */ public function lastUpdate() { - return self::getTimestamp($this->values['last_update']); } /** - * Returns the project_id of a TwingleProject + * ## Get project id + * Returns the **project_id** of this TwingleProject. * * @return int */ diff --git a/api/v3/TwingleEvent/Get.php b/api/v3/TwingleEvent/Get.php index 2d8b9ce..a67dba3 100644 --- a/api/v3/TwingleEvent/Get.php +++ b/api/v3/TwingleEvent/Get.php @@ -143,8 +143,15 @@ function civicrm_api3_twingle_event_Get(array $params): array { } } try { - TwingleEvent::translateKeys($returnValues[$event['id']], TwingleEvent::OUT); - TwingleEvent::formatValues($returnValues[$event['id']], TwingleEvent::OUT); + $tmp_event = new TwingleEvent([]); + $tmp_event->translateKeys( + $returnValues[$event['id']], + TwingleEvent::OUT + ); + TwingleEvent::formatValues( + $returnValues[$event['id']], + TwingleEvent::OUT + ); } catch (Exception $e) { throw new CiviCRM_API3_Exception($e->getMessage()); diff --git a/api/v3/TwingleEvent/Sync.php b/api/v3/TwingleEvent/Sync.php index 0a47627..32f709b 100644 --- a/api/v3/TwingleEvent/Sync.php +++ b/api/v3/TwingleEvent/Sync.php @@ -41,6 +41,13 @@ function _civicrm_api3_twingle_event_Sync_spec(array &$spec) { 'api.required' => 0, 'description' => E::ts('The key to access the Twingle API'), ]; + $spec['limit'] = [ + 'name' => 'limit', + 'title' => E::ts('Limit'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + 'description' => E::ts('Limit for the number of events that should get requested per call to the Twingle API'), + ]; } /** @@ -65,6 +72,7 @@ function _civicrm_api3_twingle_event_Sync_spec(array &$spec) { * @return array * API result descriptor * @throws \CiviCRM_API3_Exception + * @throws \Exception * @see civicrm_api3_create_success */ function civicrm_api3_twingle_event_Sync(array $params): array { @@ -80,9 +88,14 @@ function civicrm_api3_twingle_event_Sync(array $params): array { // Try to retrieve twingleApi from cache or create a new $twingleApi = Civi::cache()->get('twinglecampaign_twingle_api'); - if (NULL === $twingleApi || $params['twingle_api_key']) { + if (NULL === $twingleApi || $params['twingle_api_key'] || $params['limit']) { try { - $twingleApi = new TwingleApiCall($apiKey); + if ($params['limit']) { + $twingleApi = new TwingleApiCall($apiKey, $params['limit']); + } + else { + $twingleApi = new TwingleApiCall($apiKey); + } } catch (Exception $e) { return civicrm_api3_create_error($e->getMessage()); } @@ -154,6 +167,18 @@ function civicrm_api3_twingle_event_Sync(array $params): array { // Get all events for given project from Twingle and CiviCRM if ($params['project_id']) { $events_from_twingle = $twingleApi->getEvent($params['project_id']); + + // If Twingle does not know any events for this project_id (yet) + if ($events_from_twingle['count'] == 0) { + return civicrm_api3_create_success( + "Apparently this project does not have any events yet or " . + "the provided project_id is unknown to Twingle.", + $params, + 'TwingleEvent', + 'Sync' + ); + } + $events_from_civicrm = civicrm_api3( 'TwingleEvent', 'get', @@ -181,17 +206,17 @@ function civicrm_api3_twingle_event_Sync(array $params): array { 'get', ['sequential' => 1] ); - } - // Get all events for the chosen project from Twingle - foreach ($projects_from_civicrm['values'] as $project_from_civicrm) { - $event_from_twingle = $twingleApi->getEvent($project_from_civicrm['project_id']); - array_push( - $events_from_twingle, - $event_from_twingle - ); + // Get all events for the chosen project from Twingle + foreach ($projects_from_civicrm['values'] as $project_from_civicrm) { + $event_from_twingle = $twingleApi->getEvent($project_from_civicrm['project_id']); + array_push( + $events_from_twingle, + $event_from_twingle + ); + } + $events_from_twingle = array_merge(... $events_from_twingle); } - $events_from_twingle = array_merge(... $events_from_twingle); // Synchronize existing events or create new ones foreach ($events_from_twingle as $event_from_twingle) { @@ -275,7 +300,7 @@ function civicrm_api3_twingle_event_Sync(array $params): array { return civicrm_api3_create_success( $result_values, $params, - 'TwingleProject', + 'TwingleEvent', 'Sync' ); } @@ -292,7 +317,7 @@ function civicrm_api3_twingle_event_Sync(array $params): array { */ function instantiateEvent($values): CRM_TwingleCampaign_BAO_TwingleEvent { try { - return new TwingleEvent($values); + return new TwingleEvent($values, $values['id']); } catch (Exception $e) { throw new CiviCRM_API3_Exception( $e->getMessage(), @@ -379,7 +404,7 @@ function sync(TwingleEvent $event, array $params): array { // If Twingle's timestamp of the event differs from the timestamp of the - // CiviCRM TwingleProject campaign, update the campaign on CiviCRM's side. + // CiviCRM TwingleEvent campaign, update the campaign on CiviCRM's side. // NOTE: Changes on TwingleEvents are not meant to get pushed to Twingle if ($event_from_twingle['updated_at'] != $event->lastUpdate()) { return updateLocally($event_from_twingle, $event, $params, $twingleApi); @@ -387,7 +412,7 @@ function sync(TwingleEvent $event, // If both versions are still synchronized else { - $response[] = $event->getResponse('TwingleEvent up to date'); + $response = $event->getResponse('TwingleEvent up to date'); return civicrm_api3_create_success( $response, $params, diff --git a/api/v3/TwingleProject/Create.php b/api/v3/TwingleProject/Create.php index 01a30e2..4d58cc1 100644 --- a/api/v3/TwingleProject/Create.php +++ b/api/v3/TwingleProject/Create.php @@ -86,14 +86,33 @@ function _civicrm_api3_twingle_project_Create_spec(array &$spec) { * @see civicrm_api3_create_success * */ -function civicrm_api3_twingle_project_Create($params) { - $returnValues = []; +function civicrm_api3_twingle_project_Create($params): array { + // For logging purpose + $extensionName = E::LONG_NAME; + + // instantiate project $project = new TwingleProject($params, 'TWINGLE'); - if (!$project->exists()) { - $returnValues = $project->create(); - } + // Try to create the TwingleProject campaign + try { + $project->create(); + return civicrm_api3_create_success( + $project->getResponse('TwingleProject created'), + $params, + 'TwingleProject', + 'Create' + ); + } catch(Exception $e){ + $errorMessage = $e->getMessage(); + Civi::log()->error( + "$extensionName could not create TwingleProject: $errorMessage", + $project->getResponse() + ); + return civicrm_api3_create_error( + "Could not create TwingleProject: $errorMessage", + $project->getResponse() + ); + } - return civicrm_api3_create_success($returnValues, $params, 'TwingleProject', 'Create'); } diff --git a/api/v3/TwingleProject/Get.php b/api/v3/TwingleProject/Get.php index 2821bbd..f0f66da 100644 --- a/api/v3/TwingleProject/Get.php +++ b/api/v3/TwingleProject/Get.php @@ -152,8 +152,9 @@ function civicrm_api3_twingle_project_Get(array $params): array { } } try { - TwingleProject::translateKeys($returnValues[$project['id']], TwingleProject::OUT); - TwingleProject::formatValues($returnValues[$project['id']], TwingleProject::OUT); + $tmp_project = new TwingleProject([]); + $tmp_project->translateKeys($returnValues[$project['id']], TwingleProject::OUT); + $tmp_project->formatValues($returnValues[$project['id']], TwingleProject::OUT); } catch (Exception $e) { throw new API_Exception($e->getMessage()); diff --git a/api/v3/TwingleSync/Sync.php b/api/v3/TwingleSync/Sync.php index a0f9060..72ccd31 100644 --- a/api/v3/TwingleSync/Sync.php +++ b/api/v3/TwingleSync/Sync.php @@ -74,7 +74,7 @@ function civicrm_api3_twingle_sync_Sync($params) { $is_test = $params['is_test']; } - // If function call provides an API key, use it instead of the API key set + // If call provides an API key, use it instead of the API key set // on the extension settings page $apiKey = empty($params['twingle_api_key']) ? trim(Civi::settings()->get('twingle_api_key'))