From d39c1c2331d5c38aeffc1d4fc779f2fe69472c70 Mon Sep 17 00:00:00 2001 From: Bohdan Dmytryshyn Date: Mon, 25 Jan 2021 14:34:23 +0200 Subject: [PATCH] Release 5.5.0 --- .../CiviMobileSurvey/GetContactSurveys.php | 99 ++++++++ .../Api/CiviMobileSurvey/GetSignedValues.php | 126 ++++++++++ .../Api/CiviMobileSurvey/GetStructure.php | 192 ++++++++++++++++ .../Api/CiviMobileSurvey/Sign.php | 185 +++++++++++++++ .../Api/CiviMobileSurveyInterviewer/Get.php | 66 ++++++ .../Api/CiviMobileSurveyRespondent/Get.php | 197 ++++++++++++++++ .../GetToReserve.php | 81 +++++++ .../Api/CiviMobileSurveyRespondent/Gotv.php | 78 +++++++ .../CiviMobileSurveyRespondent/Release.php | 80 +++++++ .../CiviMobileSurveyRespondent/Reserve.php | 104 +++++++++ CRM/CiviMobileAPI/ApiWrapper/Contribution.php | 4 +- CRM/CiviMobileAPI/ApiWrapper/Event.php | 6 + .../ApiWrapper/Membership/Get.php | 29 ++- .../ApiWrapper/Survey/Getsingle.php | 31 +++ CRM/CiviMobileAPI/Calendar/Handler.php | 4 +- CRM/CiviMobileAPI/Form/Session.php | 100 ++++---- CRM/CiviMobileAPI/Form/Settings.php | 3 + .../Hook/BuildForm/ContributionPayment.php | 7 +- .../Install/Entity/CustomField.php | 10 + .../Install/Entity/CustomGroup.php | 8 + CRM/CiviMobileAPI/Page/Checklist.php | 3 +- CRM/CiviMobileAPI/Page/PublicApi/Api.php | 81 +++++-- CRM/CiviMobileAPI/Page/PublicApi/ApiBase.php | 3 + CRM/CiviMobileAPI/Page/PublicSettings.php | 1 + CRM/CiviMobileAPI/Upgrader.php | 11 + CRM/CiviMobileAPI/Utils/Checklist.php | 97 +++++++- CRM/CiviMobileAPI/Utils/CiviCRM.php | 23 ++ CRM/CiviMobileAPI/Utils/Cms.php | 35 ++- CRM/CiviMobileAPI/Utils/Cms/Wordpress.php | 15 ++ CRM/CiviMobileAPI/Utils/Permission.php | 203 +++++++++++++++- CRM/CiviMobileAPI/Utils/RestPath.php | 9 +- CRM/CiviMobileAPI/Utils/Survey.php | 24 ++ README.md | 2 + api/v3/CiviMobilePermission.php | 16 ++ api/v3/CiviMobileSurvey.php | 149 ++++++++++++ api/v3/CiviMobileSurveyInterviewer.php | 23 ++ api/v3/CiviMobileSurveyRespondent.php | 217 ++++++++++++++++++ api/v3/CiviMobileSystem.php | 3 +- api/v3/CiviMobileVenue.php | 3 +- civimobileapi.php | 37 ++- css/civimobileapiChecklist.css | 15 +- css/civimobileapiSettings.css | 5 + info.xml | 4 +- sql/create_event_session_speaker.sql | 2 +- templates/CRM/CiviMobileAPI/Form/Settings.tpl | 4 + .../CRM/CiviMobileAPI/Page/Checklist.tpl | 29 ++- 46 files changed, 2306 insertions(+), 118 deletions(-) create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetContactSurveys.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetSignedValues.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetStructure.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurvey/Sign.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurveyInterviewer/Get.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Get.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/GetToReserve.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Gotv.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Release.php create mode 100644 CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Reserve.php create mode 100644 CRM/CiviMobileAPI/ApiWrapper/Survey/Getsingle.php create mode 100644 CRM/CiviMobileAPI/Utils/Cms/Wordpress.php create mode 100644 CRM/CiviMobileAPI/Utils/Survey.php create mode 100644 api/v3/CiviMobileSurvey.php create mode 100644 api/v3/CiviMobileSurveyInterviewer.php create mode 100644 api/v3/CiviMobileSurveyRespondent.php diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetContactSurveys.php b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetContactSurveys.php new file mode 100644 index 0000000..01ba636 --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetContactSurveys.php @@ -0,0 +1,99 @@ + ['limit' => 0], + 'activity_type_id' => $this->validParams['activity_type_id'] + ]; + + if (!empty($this->validParams['survey_id'])) { + $paramsToApi['id'] = $this->validParams['survey_id']; + } + + $surveys = civicrm_api3('Survey', 'get', $paramsToApi)['values']; + + foreach ($surveys as $key => &$surveyInfo) { + if (!empty($this->validParams['title']['LIKE']) + && stripos($surveyInfo['title'], $this->validParams['title']['LIKE']) === false) { + continue; + } + + $survey = [ + 'id' => $surveyInfo['id'], + 'title' => $surveyInfo['title'], + 'is_active' => $surveyInfo['is_active'], + 'activity_type_id' => $surveyInfo['activity_type_id'] + ]; + + if (!empty($this->validParams['contact_id'])) { + $activities = civicrm_api3('Activity', 'get', [ + 'target_contact_id' => $this->validParams['contact_id'], + 'source_record_id' => $surveyInfo['id'], + 'activity_type_id' => $this->validParams['activity_type_id'], + 'status_id' => "Completed", + 'is_deleted' => 0, + ]); + + $survey['is_signed'] = (int)(boolean)$activities['count']; + + if (!is_null($this->validParams['is_signed']) + && ((!$survey['is_signed'] && $this->validParams['is_signed']) || ($survey['is_signed'] && !$this->validParams['is_signed'])) + ) { + continue; + } + } + + $preparedSurveys[] = $survey; + } + + return $preparedSurveys; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception + */ + protected function getValidParams($params) { + if (CRM_Core_Session::getLoggedInContactID()) { + if (empty($params['activity_type_id'])) { + $params['activity_type_id'] = [ + 'IN' => [] + ]; + + $activityTypes = civicrm_api3('OptionValue', 'get', [ + 'sequential' => 1, + 'option_group_id' => "activity_type", + 'component_id' => "CiviCampaign", + ])['values']; + + foreach ($activityTypes as $type) { + $params['activity_type_id']['IN'][] = $type['name']; + } + } + } else { + $params['activity_type_id'] = "Petition"; + } + + return [ + 'is_signed' => isset($params['is_signed']) ? $params['is_signed'] : NULL, + 'survey_id' => isset($params['survey_id']) ? $params['survey_id'] : NULL, + 'contact_id' => isset($params['contact_id']) ? $params['contact_id'] : NULL, + 'activity_type_id' => $params['activity_type_id'], + 'title' => isset($params['title']) ? $params['title'] : NULL, + ]; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetSignedValues.php b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetSignedValues.php new file mode 100644 index 0000000..fb38d52 --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetSignedValues.php @@ -0,0 +1,126 @@ + $this->validParams['survey_id'], + ])['values'][0]; + + if (!$surveyStructure['is_petition']) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToViewRespondentDetails()) { + throw new API_Exception(ts('Permission is required.')); + } + } else { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToViewPetitionAnswers()) { + throw new API_Exception(ts('Permission is required.')); + } + } + + try { + $activity = civicrm_api3('Activity', 'getsingle', [ + 'target_contact_id' => $this->validParams['contact_id'], + 'source_record_id' => $this->validParams['survey_id'], + 'activity_type_id' => $surveyStructure['activity_type_id'], + 'status_id' => "Completed" + ]); + } catch (Exception $e) { + throw new api_Exception('Survey is not signed. ' . $e->getMessage(), 'survey_is_not_signed'); + } + + $preparedValues['note'] = $activity['details']; + $preparedValues['result'] = !empty($activity['result']) ? $activity['result'] : ''; + + $preparedValues['activity_profile'] = $this->getProfileValuesByActivity( + $surveyStructure['profiles']['activity_profile'], + $activity + ); + $preparedValues['contact_profile'] = $this->getProfileValues( + $surveyStructure['profiles']['contact_profile'], + $this->validParams['contact_id'], + $activity['id'] + ); + + return [$preparedValues]; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception + */ + protected function getValidParams($params) { + return [ + 'contact_id' => $params['contact_id'], + 'survey_id' => $params['survey_id'], + ]; + } + + /** + * Returns values of submitted profile + * + * @param $profile + * @param $contactId + * @param $activityId + * @return array + */ + protected function getProfileValues($profile, $contactId, $activityId) { + $values = []; + $profileValues = civicrm_api3('Profile', 'get', [ + 'profile_id' => $profile['id'], + 'contact_id' => $contactId, + 'activity_id' => $activityId + ])['values']; + + foreach ($profile['fields'] as $field) { + $values[$field['name']] = $field; + if (isset($profileValues[$field['name']])) { + if (is_array($profileValues[$field['name']])) { + $selectedOptions = []; + + foreach ($profileValues[$field['name']] as $key => $value) { + if (!preg_match('/^\[[\s\S]+\]$/', $key)) { + $selectedOptions[] = strval($key); + } + } + + $values[$field['name']]['value'] = $selectedOptions; + } else { + $values[$field['name']]['value'] = $profileValues[$field['name']]; + } + } else { + $values[$field['name']]['value'] = NULL; + } + } + + return $values; + } + + /** + * Returns values of submitted profile by activity + * + * @param $profile + * @param $activityId + * @return mixed + */ + protected function getProfileValuesByActivity($profile, $activity) { + + foreach ($profile['fields'] as &$field) { + $field['value'] = isset($activity[$field['name']]) ? $activity[$field['name']] : NULL; + } + + return $profile['fields']; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetStructure.php b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetStructure.php new file mode 100644 index 0000000..979a24e --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/GetStructure.php @@ -0,0 +1,192 @@ + $this->validParams['id'], + ]); + } catch (Exception $e) { + throw new api_Exception('Survey does not exists','survey_does_not_exists'); + } + + $isPetition = true; + + try { + $petitionOptionValue = civicrm_api3('OptionValue', 'getsingle', [ + 'sequential' => 1, + 'option_group_id' => "activity_type", + 'component_id' => "CiviCampaign", + 'name' => "Petition", + ]); + + if ($surveyInfo['activity_type_id'] != $petitionOptionValue['value']) { + $isPetition = false; + } + } catch (Exception $e) { + $isPetition = false; + } + + if ($isPetition) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToViewPetition()) { + throw new API_Exception(ts('Permission is required.')); + } + } else { + if (!CRM_Core_Session::getLoggedInContactID()) { + throw new API_Exception(ts('Not authorized.')); + } + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToGetSurveysList()) { + throw new API_Exception(ts('Permission is required.')); + } + } + + $survey = [ + 'id' => $surveyInfo['id'], + 'title' => $surveyInfo['title'], + 'is_active' => $surveyInfo['is_active'], + 'is_petition' => $isPetition ? 1 : 0, + 'activity_type_id' => $surveyInfo['activity_type_id'], + 'instructions' => $surveyInfo['instructions'], + 'default_number_of_contacts' => $surveyInfo['default_number_of_contacts'], + 'max_number_of_contacts' => $surveyInfo['max_number_of_contacts'], + 'short_instructions' => $surveyInfo['instructions'] ? html_entity_decode(mb_substr(strip_tags(preg_replace('/\s\s+/', ' ', $surveyInfo['instructions'])), 0, 200), ENT_QUOTES | ENT_HTML401) : '' + ]; + + if (!empty($surveyInfo['result_id'])) { + $resultOptions = civicrm_api3('OptionValue', 'get', [ + 'sequential' => 1, + 'option_group_id' => $surveyInfo['result_id'], + 'options' => ['limit' => 0], + ])['values']; + + $preparedResultOptions = []; + + foreach ($resultOptions as $option) { + if ($option['is_active']) { + $preparedResultOptions[] = [ + 'id' => $option['id'], + 'label' => $option['label'], + 'name' => $option['name'], + 'is_default' => $option['is_default'], + 'value' => $option['value'], + ]; + } + } + + $survey['result_id'] = $surveyInfo['result_id']; + $survey['result_set'] = $preparedResultOptions; + } else { + $survey['result_id'] = ''; + $survey['result_set'] = []; + } + + $joinedProfiles = civicrm_api3('UFJoin', 'get', [ + 'entity_table' => "civicrm_survey", + 'entity_id' => $this->validParams['id'], + ])['values']; + + $survey['profiles']['activity_profile'] = []; + $survey['profiles']['contact_profile'] = []; + + foreach ($joinedProfiles as $profile) { + $fields = CRM_Core_BAO_UFGroup::getFields($profile['uf_group_id']); + $this->prepareFields($fields); + $profile_name = 'activity_profile'; + + if (($profile['weight'] == 2 && $isPetition) || ($profile['weight'] == 1 && !$isPetition)) { + $profile_name = 'contact_profile'; + } + + $survey['profiles'][$profile_name] = [ + 'id' => $profile['uf_group_id'], + 'fields' => $fields + ]; + } + + return [$survey]; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception + */ + protected function getValidParams($params) { + return [ + 'id' => $params['id'], + 'activity_type_id' => $params['activity_type_id'] + ]; + } + + /** + * Prepare fields + * + * @param $fields + */ + private function prepareFields(&$fields) { + $customFieldsIds = []; + + foreach ($fields as $key => $field) { + if (preg_match('/^custom_\d+$/', $field['name'])) { + array_push($customFieldsIds, (int) trim($field['name'], 'custom_')); + } + } + + $customFields = []; + + if (!empty($customFieldsIds)) { + $customFields = civicrm_api3('CustomField', 'get', [ + 'id' => ['IN' => $customFieldsIds], + ])['values']; + } + + foreach ($fields as &$field) { + $customField = []; + + if (preg_match('/^custom_\d+$/', $field['name'])) { + $customField = $customFields[(int) trim($field['name'], 'custom_')]; + } + + $fieldParams = [ + 'name' => $field['name'], + 'title' => $field['title'], + 'html_type' => empty($customField) ? $field['html_type'] : $customField['html_type'], + 'data_type' => empty($customField) ? $field['data_type'] : $customField['data_type'], + 'attributes' => $field['attributes'], + 'group_id' => $field['group_id'], + 'field_id' => $field['field_id'], + "is_required" => (!empty($field['is_required'])) ? $field['is_required'] : 0, + "is_view" => (!empty($field['is_view'])) ? $field['is_view'] : 0, + "date_format" => (!empty($field['date_format'])) ? $field['date_format'] : "", + "time_format" => (!empty($field['time_format'])) ? $field['time_format'] : "", + "start_date_years" => (!empty($field['start_date_years'])) ? $field['start_date_years'] : "", + "end_date_years" => (!empty($field['end_date_years'])) ? $field['end_date_years'] : "", + "default_currency" => CRM_Core_Config::singleton()->defaultCurrency, + "default_currency_symbol" => CRM_Core_Config::singleton()->defaultCurrencySymbol, + 'default_value' => (!empty($customField['default_value'])) ? $customField['default_value'] : "" + ]; + + if (!empty($customField["option_group_id"])) { + $fieldParams['options'] = CRM_CiviMobileAPI_Utils_OptionValue::getGroupValues($customField["option_group_id"], ['is_active' => 1]); + } else if (!empty($field['pseudoconstant']['optionGroupName'])) { + $fieldParams['options'] = CRM_CiviMobileAPI_Utils_OptionValue::getGroupValues($field['pseudoconstant']['optionGroupName'], ['is_active' => 1]); + } + if ($customField['html_type'] == 'Radio' && $customField['data_type'] == "Boolean") { + $fieldParams['options'] = ['1','0']; + } + + $field = $fieldParams; + } + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurvey/Sign.php b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/Sign.php new file mode 100644 index 0000000..240112d --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurvey/Sign.php @@ -0,0 +1,185 @@ +validParams['values']['contact_profile']['email-Primary']) + && $this->validParams['survey_structure']['is_petition'] + && empty($this->validParams['contact_id']) + ) { + $contacts = civicrm_api3('Contact', 'get', [ + 'sequential' => 1, + 'email' => $this->validParams['values']['contact_profile']['email-Primary'] + ]); + + if (!empty($contacts['values'])) { + $this->validParams['contact_id'] = $contacts['values'][0]['id']; + } + } + + $userSurvey = civicrm_api3('CiviMobileSurvey', 'get_contact_surveys', [ + 'contact_id' => $this->validParams['contact_id'], + 'survey_id' => $this->validParams['survey_id'], + ])['values'][0]; + if ($userSurvey['is_signed']) { + $transaction->rollback(); + throw new api_Exception('Survey already signed.', 'survey_already_signed'); + } + + if (!$this->validParams['survey_structure']['is_petition']) { + try { + $activity = civicrm_api3('Activity', 'getsingle', [ + 'sequential' => 1, + 'status_id' => "Scheduled", + 'source_record_id' => $this->validParams['survey_id'], + 'target_contact_id' => $this->validParams['contact_id'], + 'is_deleted' => 0, + 'return' => ["assignee_contact_id", "id"] + ]); + } catch (Exception $e) { + $transaction->rollback(); + throw new api_Exception('The respondent is not reserved.', 'unknown_exception'); + } + + if (!in_array(CRM_Core_Session::getLoggedInContactID(), $activity['assignee_contact_id']) && !CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToChangeInterviewer()) { + throw new API_Exception(ts('Permission is required.')); + } + + $params = [ + 'voter_id' => $this->validParams['contact_id'], + 'survey_id' => $this->validParams['survey_id'], + 'activity_id' => $activity['id'], + 'surveyTitle' => $this->validParams['survey_structure']['title'], + 'activity_type_id' => $this->validParams['survey_structure']['activity_type_id'], + 'details' => $this->validParams['note'], + 'result' => $this->validParams['result'] + ] + $this->validParams['values']['contact_profile'] + $this->validParams['values']['activity_profile']; + + CRM_Campaign_Form_Task_Interview::registerInterview($params); + } else { + $contactParams = [ + 'contactId' => $this->validParams['contact_id'] + ] + $this->validParams['values']['contact_profile']; + + $contactId = CRM_Contact_BAO_Contact::createProfileContact($contactParams, $this->validParams['survey_structure']['profiles']['contact_profile']['fields'], + $this->validParams['contact_id'], NULL, $this->validParams['survey_structure']['contact_profile']['id'], 'Individual', TRUE); + + $activityParams = [ + 'contactId' => $contactId, + 'sid' => $this->validParams['survey_id'], + 'status_id' => "Completed" + ] + $this->validParams['values']['activity_profile']; + + $activityParams['custom'] = CRM_Core_BAO_CustomField::postProcess($activityParams, NULL, 'Activity', FALSE, FALSE); + + $petitionBAO = new CRM_Campaign_BAO_Petition(); + $petitionBAO->createSignature($activityParams); + } + + $transaction->commit(); + + return [['message' => "Survey successfully signed."]]; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception` + */ + protected function getValidParams($params) { + $loggedInContactId = CRM_Core_Session::getLoggedInContactID(); + $validatedParams = []; + if (!is_array($params['values'])) { + throw new api_Exception('Values must be object.', 'values_must_be_object'); + } + + $surveyStructure = civicrm_api3('CiviMobileSurvey', 'get_structure', [ + 'id' => $params['survey_id'], + ])['values'][0]; + + if ($surveyStructure['is_petition']) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToSignPetition()) { + throw new API_Exception(ts('Permission is required.')); + } + if ($loggedInContactId) { + $params['contact_id'] = $loggedInContactId; + } + } else { + if (!$loggedInContactId) { + throw new API_Exception(ts('Not authorized.')); + } + if (empty($params['contact_id'])) { + throw new API_Exception(ts('contact_id is required.')); + } + if (!CRM_Core_Permission::check('interview campaign contacts')) { + throw new API_Exception(ts('Permission is required.')); + } + } + + $validatedParams['survey_id'] = $params['survey_id']; + $validatedParams['survey_structure'] = $surveyStructure; + $validatedParams['contact_id'] = !empty($params['contact_id']) ? $params['contact_id'] : NULL; + $validatedParams['contact_profile_id'] = $surveyStructure['profiles']['contact_profile']['id']; + $validatedParams['activity_profile_id'] = $surveyStructure['profiles']['activity_profile']['id']; + $validatedParams['note'] = !empty($params['note']) ? $params['note'] : NULL; + + if (!empty($params['result'])) { + $resultOptionLabel = NULL; + + foreach ($surveyStructure['result_set'] as $option) { + if ($option['name'] == $params['result']) { + $resultOptionLabel = $option['label']; + } + } + + if (empty($resultOptionLabel)) { + throw new api_Exception("Result option doesn`t exist.", 'no_result_option'); + } + + $validatedParams['result'] = $resultOptionLabel; + } else { + $validatedParams['result'] = NULL; + } + + $validatedParams['values'] = [ + 'activity_profile' => [], + 'contact_profile' => [] + ]; + + foreach ($surveyStructure['profiles'] as $key => $profile) { + foreach ($profile['fields'] as $field) { + if ((!isset($params['values'][$field['name']]) || (isset($params['values'][$field['name']]) && $params['values'][$field['name']] == "")) && $field['is_required']) { + throw new api_Exception("'{$field['name']}' is required.", 'required_value'); + } + if ($field['html_type'] == 'CheckBox' && is_array($params['values'][$field['name']])) { + $options = []; + + foreach ($params['values'][$field['name']] as $value) { + $options[$value] = 1; + } + + $validatedParams['values'][$key][$field['name']] = $options; + } elseif(isset($params['values'][$field['name']])) { + $validatedParams['values'][$key][$field['name']] = $params['values'][$field['name']]; + } + + } + + $validatedParams[$key . "_id"] = $profile['id']; + } + + return $validatedParams; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurveyInterviewer/Get.php b/CRM/CiviMobileAPI/Api/CiviMobileSurveyInterviewer/Get.php new file mode 100644 index 0000000..253e123 --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurveyInterviewer/Get.php @@ -0,0 +1,66 @@ + $this->validParams['survey_id'], + ]); + } catch (Exception $e) { + throw new api_Exception('Survey does not exists','survey_does_not_exists'); + } + + $activities = civicrm_api3('Activity', 'get', [ + 'sequential' => 1, + 'return' => ["assignee_contact_name"], + 'source_record_id' => $survey['id'], + 'activity_type_id' => $survey['activity_type_id'], + 'status_id' => ['IN' => ["Completed", "Scheduled"]], + 'is_deleted' => 0, + 'options' => ['limit' => 0], + ]); + + $interviewers = []; + + foreach ($activities['values'] as $activity) { + foreach ($activity['assignee_contact_name'] as $key => $value) { + $interviewers[$key] = [ + 'id' => $key, + 'display_name' => $value + ]; + } + } + + $interviewers = array_values($interviewers); + + usort($interviewers, function($a, $b) { + return strcasecmp($a['display_name'], $b['display_name']); + }); + + return $interviewers; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception` + */ + protected function getValidParams($params) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToChangeInterviewer()) { + throw new API_Exception(ts('Permission is required.')); + } + + return $params; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Get.php b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Get.php new file mode 100644 index 0000000..4a80054 --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Get.php @@ -0,0 +1,197 @@ + "civicrm_survey", + 'entity_id' => $this->validParams['survey_id'], + 'weight' => 1, + ]); + + $fields = CRM_Core_BAO_UFGroup::getFields($contactProfile['uf_group_id']); + } catch (Exception $e) { + return []; + } + + $contactParams = [ + 'options' => ['limit' => 0], + 'return' => ["id", "contact_type", "display_name", "image_URL"], + 'group' => !empty($this->validParams['group']) ? $this->validParams['group'] : NULL, + 'display_name' => !empty($this->validParams['display_name']) ? $this->validParams['display_name'] : NULL, + 'contact_type' => !empty($this->validParams['contact_type']) ? $this->validParams['contact_type'] : NULL, + 'city' => !empty($this->validParams['city']) ? $this->validParams['city'] : NULL, + 'street_address' => !empty($this->validParams['group']) ? $this->validParams['street_address'] : NULL, + 'check_permissions' => true + ]; + + $gotvCustomFieldName = 'custom_' . CRM_CiviMobileAPI_Utils_CustomField::getId(CRM_CiviMobileAPI_Install_Entity_CustomGroup::SURVEY,CRM_CiviMobileAPI_Install_Entity_CustomField::SURVEY_GOTV_STATUS); + + $activitiesParams = [ + 'sequential' => 1, + 'source_record_id' => $this->validParams['survey_id'], + 'activity_type_id' => ['IN' => $surveyActivityTypesIds], + 'is_deleted' => 0, + 'return' => ["target_contact_id", "status_id", "result", $gotvCustomFieldName], + 'options' => ['limit' => 0], + ]; + + if (!empty($this->validParams['interviewer_id'])) { + $activitiesParams['assignee_contact_id'] = $this->validParams['interviewer_id']; + } + + $filterStatuses = []; + $filterGOTV = false; + $filterInterviewed = false; + + if (!empty($this->validParams['survey_status'])) { + if (in_array('Reserved', $this->validParams['survey_status'])) { + $filterStatuses[] = "Scheduled"; + } + if (in_array('Interviewed', $this->validParams['survey_status'])) { + $filterStatuses[] = "Completed"; + $filterInterviewed = true; + } + if (in_array('GOTV', $this->validParams['survey_status'])) { + $filterStatuses[] = "Completed"; + $filterGOTV = true; + } + + if (!empty($filterStatuses)) { + $activitiesParams['status_id'] = ['IN' => $filterStatuses]; + } + } + + $activities = civicrm_api3('Activity', 'get', $activitiesParams); + + $contactIds = []; + + foreach ($activities['values'] as $activity) { + $contactIds[] = reset($activity['target_contact_id']); + } + + if (empty($contactIds)) { + return []; + } + + $contactParams['id'] = ['IN' => $contactIds]; + + $contacts = civicrm_api3('Contact', 'get', $contactParams)['values']; + + $activityStatuses = civicrm_api3('OptionValue', 'get', [ + 'sequential' => 1, + 'option_group_id' => "activity_status", + 'name' => ['IN' => ["Scheduled", "Completed"]], + ])['values']; + + $preparedStatuses = []; + + foreach ($activityStatuses as $status) { + $preparedStatuses[$status['value']] = $status['name']; + } + + $preparedContacts = []; + + foreach ($activities['values'] as $activity) { + if ($filterGOTV != $filterInterviewed + && $activity[$gotvCustomFieldName] != $filterGOTV + && $preparedStatuses[$activity['status_id']] != 'Scheduled') { + continue; + } + + $contactId = reset($activity['target_contact_id']); + if (!isset($contacts[$contactId])) { + continue; + } + $contact = $contacts[$contactId]; + + $status = NULL; + + switch ($preparedStatuses[$activity['status_id']]) { + case 'Scheduled': + $status = 'Reserved'; + break; + case 'Completed': + if (!empty($activity[$gotvCustomFieldName])) { + $status = 'GOTV'; + } else { + $status = 'Interviewed'; + } + break; + } + + if (!empty($status)) { + $preparedContact = [ + 'contact_id' => $contact['id'], + 'contact_type' => $contact['contact_type'], + 'display_name' => $contact['display_name'], + 'image_URL' => $contact['image_URL'], + 'survey_status' => $status, + 'result' => !empty($activity['result']) ? $activity['result'] : '', + ]; + + $profileResults = civicrm_api3('Profile', 'get', [ + 'sequential' => 1, + 'profile_id' => $contactProfile['uf_group_id'], + 'contact_id' => $contact['id'], + ])['values']; + + foreach (array_keys($fields) as $field) { + $preparedContact[$field] = $profileResults[$field]; + } + + $preparedContacts[] = $preparedContact; + } + } + + usort($preparedContacts, function($a, $b) { + return strcasecmp($a['display_name'], $b['display_name']); + }); + + return $preparedContacts; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception` + */ + protected function getValidParams($params) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToGetRespondents()) { + throw new API_Exception(ts('Permission is required.')); + } + + $loggedInContactId = CRM_Core_Session::getLoggedInContactID(); + + if ($loggedInContactId !== $params['interviewer_id'] && !CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToChangeInterviewer()) { + if (empty($loggedInContactId)) { + $params['interviewer_id'] = $loggedInContactId; + } else { + throw new API_Exception(ts('Permission is required.')); + } + } + + if (!empty($params['survey_status']) && !is_array($params['survey_status'])) { + $params['survey_status'] = [$params['survey_status']]; + } + + return $params; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/GetToReserve.php b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/GetToReserve.php new file mode 100644 index 0000000..ca718cc --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/GetToReserve.php @@ -0,0 +1,81 @@ + ['limit' => 0, 'sort' => 'display_name'], + 'return' => ["id", "contact_type", "display_name", "image_URL", "street_address", "city", "country", "address_id", "contact_type"], + 'group' => !empty($this->validParams['group']) ? $this->validParams['group'] : NULL, + 'display_name' => !empty($this->validParams['display_name']) ? $this->validParams['display_name'] : NULL, + 'contact_type' => !empty($this->validParams['contact_type']) ? $this->validParams['contact_type'] : NULL, + 'city' => !empty($this->validParams['city']) ? $this->validParams['city'] : NULL, + 'street_address' => !empty($this->validParams['group']) ? $this->validParams['street_address'] : NULL, + 'check_permissions' => true + ]; + + $contacts = civicrm_api3('Contact', 'get', $contactParams)['values']; + + $surveyActivityTypesIds = CRM_CiviMobileAPI_Utils_Survey::getSurveyActivityTypesIds(); + + if (empty($surveyActivityTypesIds)) { + return []; + } + + $activities = civicrm_api3('Activity', 'get', [ + 'sequential' => 1, + 'source_record_id' => $this->validParams['survey_id'], + 'activity_type_id' => ['IN' => $surveyActivityTypesIds], + 'is_deleted' => 0, + 'return' => ["target_contact_id", "status_id"], + 'options' => ['limit' => 0], + ])['values']; + + foreach ($activities as $activity) { + $contactId = reset($activity['target_contact_id']); + + if (isset($contacts[$contactId])) { + unset($contacts[$contactId]); + } + } + + $preparedContacts = []; + + foreach ($contacts as $key => $contact) { + $preparedContacts[$key] = [ + 'contact_id' => $contact['id'], + 'display_name' => $contact['display_name'], + 'image_URL' => $contact['image_URL'], + 'street_address' => $contact['street_address'], + 'city' => $contact['city'], + 'country' => $contact['country'], + 'contact_type' => $contact['contact_type'], + ]; + } + + if (!empty($this->validParams['sequential'])) { + return array_values($preparedContacts); + } + + return $preparedContacts; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception` + */ + protected function getValidParams($params) { + return $params; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Gotv.php b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Gotv.php new file mode 100644 index 0000000..6254da2 --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Gotv.php @@ -0,0 +1,78 @@ + $this->validParams['survey_id'], + ]); + } catch (Exception $e) { + throw new api_Exception('The survey doesn`t exists.', 'survey_does_not_exists'); + } + + $surveyActivityTypesIds = CRM_CiviMobileAPI_Utils_Survey::getSurveyActivityTypesIds(); + $gotvCustomFieldName = 'custom_' . CRM_CiviMobileAPI_Utils_CustomField::getId(CRM_CiviMobileAPI_Install_Entity_CustomGroup::SURVEY,CRM_CiviMobileAPI_Install_Entity_CustomField::SURVEY_GOTV_STATUS); + + $activities = civicrm_api3('Activity', 'get', [ + 'sequential' => 1, + 'source_record_id' => $survey['id'], + 'activity_type_id' => ['IN' => $surveyActivityTypesIds], + 'target_contact_id' => ['IN' => $this->validParams['contact_ids']], + 'assignee_id' => $this->validParams['interviewer_id'], + 'is_deleted' => 0, + 'status_id' => "Scheduled", + 'options' => ['limit' => 0] + ]); + + if ($activities['count'] != count($this->validParams['contact_ids'])) { + throw new api_Exception('Some contacts aren`t reserved respondents.', 'some_contacts_are_not_reserved_respondents'); + } + + foreach ($activities['values'] as $activity) { + civicrm_api3('Activity', 'create', [ + 'id' => $activity['id'], + 'status_id' => "Completed", + $gotvCustomFieldName => 1 + ]); + } + + return ['message' => 'GoTV success.']; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception` + */ + protected function getValidParams($params) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToGotvRespondents()) { + throw new API_Exception(ts('Permission is required.')); + } + + $loggedInContactId = CRM_Core_Session::getLoggedInContactID(); + + if (!empty($this->validParams['interviewer_id']) && + $this->validParams['interviewer_id'] != $loggedInContactId && + !CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToChangeInterviewer() + ) { + throw new API_Exception(ts('Permission is required.')); + } + + $params['interviewer_id'] = !empty($params['interviewer_id']) ? $params['interviewer_id'] : $loggedInContactId; + + $params['contact_ids'] = explode(',', $params['contact_ids']); + + return $params; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Release.php b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Release.php new file mode 100644 index 0000000..537c643 --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Release.php @@ -0,0 +1,80 @@ + $this->validParams['survey_id'], + ]); + } catch (Exception $e) { + throw new api_Exception('The survey doesn`t exists.', 'survey_does_not_exists'); + } + + $surveyActivityTypesIds = CRM_CiviMobileAPI_Utils_Survey::getSurveyActivityTypesIds(); + + if (empty($surveyActivityTypesIds)) { + return ['message' => 'Respondents weren`t released.']; + } + + $activities = civicrm_api3('Activity', 'get', [ + 'sequential' => 1, + 'source_record_id' => $survey['id'], + 'activity_type_id' => ['IN' => $surveyActivityTypesIds], + 'target_contact_id' => ['IN' => $this->validParams['contact_ids']], + 'assignee_id' => $this->validParams['interviewer_id'], + 'is_deleted' => 0, + 'status_id' => "Scheduled", + 'options' => ['limit' => 0] + ]); + + if ($activities['count'] != count($this->validParams['contact_ids'])) { + throw new api_Exception('Some contacts aren`t reserved respondents.', 'some_contacts_are_not_reserved_respondents'); + } + + foreach ($activities['values'] as $activity) { + civicrm_api3('Activity', 'create', [ + 'id' => $activity['id'], + 'is_deleted' => 1, + ]); + } + + return ['message' => 'Respondents is successfully released.']; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception` + */ + protected function getValidParams($params) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToReleaseRespondents()) { + throw new API_Exception(ts('Permission is required.')); + } + + $loggedInContactId = CRM_Core_Session::getLoggedInContactID(); + + if (!empty($this->validParams['interviewer_id']) && + $this->validParams['interviewer_id'] != $loggedInContactId && + !CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToChangeInterviewer() + ) { + throw new API_Exception(ts('Permission is required.')); + } + + $params['interviewer_id'] = !empty($params['interviewer_id']) ? $params['interviewer_id'] : $loggedInContactId; + + $params['contact_ids'] = explode(',', $params['contact_ids']); + + return $params; + } + +} diff --git a/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Reserve.php b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Reserve.php new file mode 100644 index 0000000..1ca899f --- /dev/null +++ b/CRM/CiviMobileAPI/Api/CiviMobileSurveyRespondent/Reserve.php @@ -0,0 +1,104 @@ + $this->validParams['survey_id'], + ]); + } catch (Exception $e) { + throw new api_Exception('The survey doesn`t exists.', 'survey_does_not_exists'); + } + + if (!empty($survey['default_number_of_contacts']) && count($this->validParams['contact_ids']) > $survey['default_number_of_contacts']) { + throw new api_Exception('You can reserve no more than ' . $survey['default_number_of_contacts'] . ' contacts per interviewer at one time.', 'too_much_contacts_per_interviewer_at_one_time'); + } + + $surveyActivityTypesIds = CRM_CiviMobileAPI_Utils_Survey::getSurveyActivityTypesIds(); + + $activities = civicrm_api3('Activity', 'get', [ + 'sequential' => 1, + 'is_deleted' => 0, + 'source_record_id' => $survey['id'], + 'activity_type_id' => ['IN' => $surveyActivityTypesIds], + 'target_contact_id' => ['IN' => $this->validParams['contact_ids']] + ]); + + if ($activities['count'] > 0) { + throw new api_Exception('Some contacts already reserved.', 'some_contacts_already_reserved'); + } + + if (!empty($survey['max_number_of_contacts'])) { + $reservedRespondents = civicrm_api3('CiviMobileSurveyRespondent', 'get', [ + 'sequential' => 1, + 'survey_id' => $survey['id'], + 'interviewer_id' => $this->validParams['interviewer_id'], + ]); + + if ($reservedRespondents['count'] + count($this->validParams['contact_ids']) > $survey['max_number_of_contacts']) { + throw new api_Exception('You can reserve no more than ' . $survey['max_number_of_contacts'] . ' contacts per interviewer.', 'too_much_contacts_per_interviewer'); + } + } + + foreach ($this->validParams['contact_ids'] as $id) { + civicrm_api3('Activity', 'create', [ + 'source_contact_id' => CRM_Core_Session::getLoggedInContactID(), + 'source_record_id' => $survey['id'], + 'target_id' => $id, + 'subject' => $survey['title'] . ' - Respondent Reservation', + 'activity_type_id' => $survey['activity_type_id'], + 'status_id' => "Scheduled", + 'assignee_contact_id' => $this->validParams['interviewer_id'], + ]); + } + + return ['message' => 'Contacts successfully reserved.']; + } + + /** + * Returns validated params + * + * @param $params + * + * @return array + * @throws api_Exception` + */ + protected function getValidParams($params) { + if (!CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToReserveRespondents()) { + throw new API_Exception(ts('Permission is required.')); + } + + $loggedInContactId = CRM_Core_Session::getLoggedInContactID(); + + if (!empty($this->validParams['interviewer_id']) && + $this->validParams['interviewer_id'] != $loggedInContactId && + !CRM_CiviMobileAPI_Utils_Permission::isEnoughPermissionToChangeInterviewer() + ) { + throw new API_Exception(ts('Permission is required.')); + } + + $params['interviewer_id'] = !empty($params['interviewer_id']) ? $params['interviewer_id'] : $loggedInContactId; + + $params['contact_ids'] = explode(',', $params['contact_ids']); + + $contacts = civicrm_api3('Contact', 'get', [ + 'id' => ['IN' => $params['contact_ids']], + 'options' => ['limit' => 0], + 'check_permissions' => true + ]); + + if (count($params['contact_ids']) != $contacts['count']) { + throw new api_Exception('Some contacts don`t exists or you don`t have permissions to view them.', 'some_contacts_do_not_exists'); + } + + return $params; + } + +} diff --git a/CRM/CiviMobileAPI/ApiWrapper/Contribution.php b/CRM/CiviMobileAPI/ApiWrapper/Contribution.php index b63b84a..6a5c5fd 100644 --- a/CRM/CiviMobileAPI/ApiWrapper/Contribution.php +++ b/CRM/CiviMobileAPI/ApiWrapper/Contribution.php @@ -56,7 +56,7 @@ class CRM_CiviMobileAPI_ApiWrapper_Contribution implements API_Wrapper { return $result; } - if (empty($apiRequest['params']['return']) || stristr($apiRequest['params']['return'], 'financial_type_name') !== FALSE) { + if (empty($apiRequest['params']['return']) || (!is_array($apiRequest['params']['return']) && stristr($apiRequest['params']['return'], 'financial_type_name') !== FALSE || in_array('financial_type_name', $apiRequest['params']['return']))) { if ($apiRequest['action'] == 'getsingle') { $result['financial_type_name'] = $this->getFinancialTypeName($result); } @@ -81,7 +81,7 @@ class CRM_CiviMobileAPI_ApiWrapper_Contribution implements API_Wrapper { return $result; } - if (empty($apiRequest['params']['return']) || stristr($apiRequest['params']['return'], 'total_amount') !== FALSE) { + if (empty($apiRequest['params']['return']) || (!is_array($apiRequest['params']['return']) && stristr($apiRequest['params']['return'], 'total_amount') !== FALSE || in_array('total_amount', $apiRequest['params']['return']))) { if ($apiRequest['action'] == 'getsingle') { $result['format_total_amount'] = CRM_Utils_Money::format($result['total_amount'], $result['currency']); } diff --git a/CRM/CiviMobileAPI/ApiWrapper/Event.php b/CRM/CiviMobileAPI/ApiWrapper/Event.php index b81c7db..4ccc028 100644 --- a/CRM/CiviMobileAPI/ApiWrapper/Event.php +++ b/CRM/CiviMobileAPI/ApiWrapper/Event.php @@ -54,6 +54,12 @@ class CRM_CiviMobileAPI_ApiWrapper_Event implements API_Wrapper { if ($apiRequest['action'] == 'get' && !empty($result['values'])) { foreach ($result['values'] as $key => $event) { + $result['values'][$key]['registered_participants_count'] = civicrm_api3('Participant', 'get', [ + 'sequential' => 1, + 'return' => ["id"], + 'event_id' => $event['id'], + ])['count']; + if (isset($event['currency'])) { if (!empty($event['currency'])) { $result['values'][$key]['currency_symbol'] = CRM_CiviMobileAPI_Utils_Currency::getSymbolByName($event['currency']); diff --git a/CRM/CiviMobileAPI/ApiWrapper/Membership/Get.php b/CRM/CiviMobileAPI/ApiWrapper/Membership/Get.php index 6947f47..9d61d73 100644 --- a/CRM/CiviMobileAPI/ApiWrapper/Membership/Get.php +++ b/CRM/CiviMobileAPI/ApiWrapper/Membership/Get.php @@ -66,9 +66,26 @@ class CRM_CiviMobileAPI_ApiWrapper_Membership_Get implements API_Wrapper { * @return array */ private function getAdditionalInfo($membership, $apiRequest) { + if (!empty($apiRequest['params']['return']) && is_array($apiRequest['params']['return'])) { + return []; + } + $config = CRM_Core_Config::singleton(); $additionalInfo = []; + if (!empty($apiRequest['params']['membership_contact_id'])) { + try { + $lastPayment = civicrm_api3('MembershipPayment', 'getsingle', [ + 'return' => ["contribution_id.receive_date", "membership_id.contact_id"], + 'membership_id' => $membership['id'], + 'membership_id.contact_id' => $apiRequest['params']['membership_contact_id'], + 'options' => ['sort' => "contribution_id.receive_date desc", 'limit' => 1], + ]); + + $additionalInfo['last_payment_receive_date'] = $lastPayment['contribution_id.receive_date']; + } catch (Exception $e) {} + } + if (empty($apiRequest['params']['return']) || stristr($apiRequest['params']['return'], 'renewal_amount') !== false) { $membershipTypeId = !empty($membership['membership_type_id']) ? $membership['membership_type_id'] : CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $membership['id'], 'membership_type_id'); @@ -93,6 +110,10 @@ class CRM_CiviMobileAPI_ApiWrapper_Membership_Get implements API_Wrapper { * @return array */ private function fillRelatedCount($apiRequest, $result) { + if (!empty($apiRequest['params']['return']) && is_array($apiRequest['params']['return'])) { + return $result; + } + if (!(empty($apiRequest['params']['return']) || stristr($apiRequest['params']['return'], 'related_count') !== false)) { return $result; } @@ -147,6 +168,10 @@ class CRM_CiviMobileAPI_ApiWrapper_Membership_Get implements API_Wrapper { * @return mixed */ private function fillByRelationship($apiRequest, $result) { + if (!empty($apiRequest['params']['return']) && is_array($apiRequest['params']['return'])) { + return $result; + } + if (!(empty($apiRequest['params']['return']) || stristr($apiRequest['params']['return'], 'by_relationship_contact_id') !== false)) { return $result; } @@ -189,9 +214,9 @@ class CRM_CiviMobileAPI_ApiWrapper_Membership_Get implements API_Wrapper { WHEN contact_id_b = %1 AND contact_id_a = %2 THEN 'a_b' END AS 'direction' FROM civicrm_relationship - WHERE relationship_type_id IN ($ownerRelationshipTypes) + WHERE relationship_type_id IN ($ownerRelationshipTypes) AND ( - (contact_id_a = %1 AND contact_id_b = %2 ) + (contact_id_a = %1 AND contact_id_b = %2 ) OR (contact_id_b = %1 AND contact_id_a = %2 ) ) "; diff --git a/CRM/CiviMobileAPI/ApiWrapper/Survey/Getsingle.php b/CRM/CiviMobileAPI/ApiWrapper/Survey/Getsingle.php new file mode 100644 index 0000000..bf64c46 --- /dev/null +++ b/CRM/CiviMobileAPI/ApiWrapper/Survey/Getsingle.php @@ -0,0 +1,31 @@ +addFormRule([CRM_CiviMobileAPI_Form_Session::class, 'validateForm']); + if ($this->getAction() == CRM_Core_Action::ADD || $this->getAction() == CRM_Core_Action::UPDATE) { + $this->addFormRule([self::class, 'validateForm']); + } } /** @@ -293,57 +295,55 @@ class CRM_CiviMobileAPI_Form_Session extends CRM_Core_Form { */ public static function validateForm($values) { $errors = []; - if ($values["_qf_Session_submit"] != 'Delete') { - if (!empty($values['speakers'])) { - $values['speakers'] = explode(',', $values['speakers']); - } - $sessionId = isset($values['session_id']) ? $values['session_id'] : NULL; - $startTime = $values["date"] . ' ' . $values["start_time"]; - $endTime = $values["date"] . ' ' . $values["end_time"]; - try { - $event = CRM_Event_BAO_Event::findById($values["event_id"]); - } catch (Exception $e) { - $errors["event_id"] = E::ts('Invalid eventId parameter.'); - return $errors; - } - if (empty($values["title"])) { - $errors["title"] = E::ts('Title can`t be empty!'); - } - if (strlen($values["title"]) > 255) { - $errors["title"] = E::ts('Title length must be less than 255 characters.'); - } - if (strtotime($startTime) >= strtotime($endTime)) { - $errors["start_time"] = E::ts('Start time can`t be later than End time.'); - } elseif (strtotime($startTime) + 15*60 > strtotime($endTime)) { - $errors["start_time"] = E::ts('Event Session duration can`t be less than 15 min.'); - } - $startEventDate = strtotime(date('Y-m-d',strtotime($event->start_date))); - if (strtotime($values["date"]) < $startEventDate) { - $errors["date"] = E::ts('Session start date can`t be early than start time on the Event. (Start time on Event: ' . $event->start_date . ')'); - } elseif (strtotime($startTime) < strtotime($event->start_date)) { - $errors["start_time"] = E::ts('Start date can`t be early than start time on Event. (Start time on Event: ' . $event->start_date . ')'); - } - if (!empty($event->end_date) && (strtotime($values["date"]) > strtotime($event->end_date))) { - $errors["date"] = E::ts('End date can`t be later than end date on Event. (End time on Event: ' . $event->end_date . ')'); - } elseif (!empty($event->end_date) && (strtotime($endTime) > strtotime($event->end_date))) { - $errors["end_time"] = E::ts('End time can`t be later than end time on Event. (End time on Event: ' . $event->end_date . ')'); - } - if (!empty($values['speakers']) && !CRM_CiviMobileAPI_Utils_Agenda_Speakers::issetSpeakers($values['speakers'], $values["event_id"])) { - $errors["speakers"] = E::ts('Some speakers does not exists.'); - } - if (isset($values["speakers"]) && CRM_CiviMobileAPI_BAO_EventSession::isSpeakersBusy($values["speakers"], $sessionId, $startTime, $endTime)) { - $errors["speakers"] = E::ts('Some speakers are busy on other Event Session at this time.'); + if (!empty($values['speakers'])) { + $values['speakers'] = explode(',', $values['speakers']); + } + $sessionId = isset($values['session_id']) ? $values['session_id'] : NULL; + $startTime = $values["date"] . ' ' . $values["start_time"]; + $endTime = $values["date"] . ' ' . $values["end_time"]; + try { + $event = CRM_Event_BAO_Event::findById($values["event_id"]); + } catch (Exception $e) { + $errors["event_id"] = E::ts('Invalid eventId parameter.'); + return $errors; + } + if (empty($values["title"])) { + $errors["title"] = E::ts('Title can`t be empty!'); + } + if (strlen($values["title"]) > 255) { + $errors["title"] = E::ts('Title length must be less than 255 characters.'); + } + if (strtotime($startTime) >= strtotime($endTime)) { + $errors["start_time"] = E::ts('Start time can`t be later than End time.'); + } elseif (strtotime($startTime) + 15*60 > strtotime($endTime)) { + $errors["start_time"] = E::ts('Event Session duration can`t be less than 15 min.'); + } + $startEventDate = strtotime(date('Y-m-d',strtotime($event->start_date))); + if (strtotime($values["date"]) < $startEventDate) { + $errors["date"] = E::ts('Session start date can`t be early than start time on the Event. (Start time on Event: ' . $event->start_date . ')'); + } elseif (strtotime($startTime) < strtotime($event->start_date)) { + $errors["start_time"] = E::ts('Start date can`t be early than start time on Event. (Start time on Event: ' . $event->start_date . ')'); + } + if (!empty($event->end_date) && (strtotime($values["date"]) > strtotime($event->end_date))) { + $errors["date"] = E::ts('End date can`t be later than end date on Event. (End time on Event: ' . $event->end_date . ')'); + } elseif (!empty($event->end_date) && (strtotime($endTime) > strtotime($event->end_date))) { + $errors["end_time"] = E::ts('End time can`t be later than end time on Event. (End time on Event: ' . $event->end_date . ')'); + } + if (!empty($values['speakers']) && !CRM_CiviMobileAPI_Utils_Agenda_Speakers::issetSpeakers($values['speakers'], $values["event_id"])) { + $errors["speakers"] = E::ts('Some speakers does not exists.'); + } + if (isset($values["speakers"]) && CRM_CiviMobileAPI_BAO_EventSession::isSpeakersBusy($values["speakers"], $sessionId, $startTime, $endTime)) { + $errors["speakers"] = E::ts('Some speakers are busy on other Event Session at this time.'); + } + if (!empty($values["venue_id"])) { + if (!CRM_CiviMobileAPI_Utils_Agenda_Venue::issetVenue($values['venue_id'], $values["event_id"])) { + $errors["venue_id"] = E::ts('Venue does not exists.'); } - if (!empty($values["venue_id"])) { - if (!CRM_CiviMobileAPI_Utils_Agenda_Venue::issetVenue($values['venue_id'], $values["event_id"])) { - $errors["venue_id"] = E::ts('Venue does not exists.'); - } - if (CRM_CiviMobileAPI_BAO_EventSession::isVenueBusy($values["venue_id"], $sessionId, $startTime, $endTime)) { - $errors["venue_id"] = E::ts('Venue is booked on other Event Session at this time.'); - } - } else { - $errors["venue_id"] = E::ts('Venue is required.'); + if (CRM_CiviMobileAPI_BAO_EventSession::isVenueBusy($values["venue_id"], $sessionId, $startTime, $endTime)) { + $errors["venue_id"] = E::ts('Venue is booked on other Event Session at this time.'); } + } else { + $errors["venue_id"] = E::ts('Venue is required.'); } return empty($errors) ? TRUE : $errors; diff --git a/CRM/CiviMobileAPI/Form/Settings.php b/CRM/CiviMobileAPI/Form/Settings.php index f74db25..fc53409 100644 --- a/CRM/CiviMobileAPI/Form/Settings.php +++ b/CRM/CiviMobileAPI/Form/Settings.php @@ -46,6 +46,9 @@ class CRM_CiviMobileAPI_Form_Settings extends CRM_Core_Form { if (in_array('CiviEvent', $enabledComponents)) { $possibleItemsToDisplayInPublicArea[] = 'Events'; } + if (in_array('CiviCampaign', $enabledComponents)) { + $possibleItemsToDisplayInPublicArea[] = 'Petitions'; + } $this->assign('isWritable', CRM_CiviMobileAPI_Utils_Extension::directoryIsWritable()); $this->assign('serverKeyValidMessage', $serverKeyValidMessage); diff --git a/CRM/CiviMobileAPI/Hook/BuildForm/ContributionPayment.php b/CRM/CiviMobileAPI/Hook/BuildForm/ContributionPayment.php index 7fa874b..f40e98c 100644 --- a/CRM/CiviMobileAPI/Hook/BuildForm/ContributionPayment.php +++ b/CRM/CiviMobileAPI/Hook/BuildForm/ContributionPayment.php @@ -23,12 +23,7 @@ class CRM_CiviMobileAPI_Hook_BuildForm_ContributionPayment { } if ($session->get('contribution_is_civimobile') && in_array($formName, $customizeForms)) { - $contactId = CRM_CiviMobileAPI_Authentication_AuthenticationHelper::authenticateContact(); - if ($contactId) { - $defaults = []; - CRM_Core_BAO_UFGroup::setProfileDefaults($contactId, $form->_fields, $defaults); - $form->setDefaults($defaults); - } + CRM_CiviMobileAPI_Authentication_AuthenticationHelper::authenticateContact(); $this->customizeContributionPayment(); } diff --git a/CRM/CiviMobileAPI/Install/Entity/CustomField.php b/CRM/CiviMobileAPI/Install/Entity/CustomField.php index 4d3c910..598c2f1 100644 --- a/CRM/CiviMobileAPI/Install/Entity/CustomField.php +++ b/CRM/CiviMobileAPI/Install/Entity/CustomField.php @@ -22,6 +22,7 @@ class CRM_CiviMobileAPI_Install_Entity_CustomField extends CRM_CiviMobileAPI_Ins const QR_IMAGE = 'civi_mobile_qr_image'; const PUBLIC_KEY = 'public_key'; const AGENDA_PARTICIPANT_BIO = 'civi_mobile_agenda_participant_bio'; + const SURVEY_GOTV_STATUS = 'civi_mobile_survey_gotv_status'; /** * Params for checking Entity existence @@ -86,6 +87,15 @@ class CRM_CiviMobileAPI_Install_Entity_CustomField extends CRM_CiviMobileAPI_Ins 'html_type' => 'TextArea', 'data_type' => 'Memo', ], + [ + 'name' => self::SURVEY_GOTV_STATUS, + 'label' => E::ts('Is GOTV?'), + 'custom_group_id' => CRM_CiviMobileAPI_Install_Entity_CustomGroup::SURVEY, + 'html_type' => 'Radio', + 'data_type' => 'Boolean', + 'is_view' => 1, + 'default_value' => 0 + ], ]; } diff --git a/CRM/CiviMobileAPI/Install/Entity/CustomGroup.php b/CRM/CiviMobileAPI/Install/Entity/CustomGroup.php index 09ddac3..a97b97f 100644 --- a/CRM/CiviMobileAPI/Install/Entity/CustomGroup.php +++ b/CRM/CiviMobileAPI/Install/Entity/CustomGroup.php @@ -14,6 +14,7 @@ class CRM_CiviMobileAPI_Install_Entity_CustomGroup extends CRM_CiviMobileAPI_Ins const CONTACT_SETTINGS = 'contact_settings'; const PUBLIC_INFO = 'civi_mobile_public_info'; const AGENDA_PARTICIPANT = 'civi_mobile_agenda_participant'; + const SURVEY = 'civi_mobile_survey'; /** * Entity name @@ -62,6 +63,13 @@ class CRM_CiviMobileAPI_Install_Entity_CustomGroup extends CRM_CiviMobileAPI_Ins 'is_public' => 0, 'is_reserved' => 1 ], + [ + 'name' => self::SURVEY, + 'title' => E::ts('Survey`s additional info'), + 'extends' => 'Activity', + 'is_public' => 0, + 'is_reserved' => 1 + ], ]; } diff --git a/CRM/CiviMobileAPI/Page/Checklist.php b/CRM/CiviMobileAPI/Page/Checklist.php index c0ec1de..5992cc1 100644 --- a/CRM/CiviMobileAPI/Page/Checklist.php +++ b/CRM/CiviMobileAPI/Page/Checklist.php @@ -25,7 +25,8 @@ class CRM_CiviMobileAPI_Page_Checklist extends CRM_Core_Page { 'restPathUrl' => $restPathUrl, 'restUrl' => $restUrl, 'checklist_params' => $checklist->getCheckedItemsResult(), - 'system_info' => $checklist->getSystemInfoReport() + 'system_info' => $checklist->getSystemInfoReport(), + 'info' => $checklist->getInfoItems() ]); CRM_Core_Resources::singleton()->addStyleFile('com.agiliway.civimobileapi', 'css/civimobileapiChecklist.css', 200, 'html-header'); diff --git a/CRM/CiviMobileAPI/Page/PublicApi/Api.php b/CRM/CiviMobileAPI/Page/PublicApi/Api.php index b3e9ff8..a426910 100644 --- a/CRM/CiviMobileAPI/Page/PublicApi/Api.php +++ b/CRM/CiviMobileAPI/Page/PublicApi/Api.php @@ -68,7 +68,8 @@ class CRM_CiviMobileAPI_Page_PublicApi_Api extends CRM_CiviMobileAPI_Page_Public 'loc_block_id.address_id.postal_code', 'loc_block_id.address_id.geo_code_1', 'loc_block_id.address_id.geo_code_2', - 'url' + 'url', + 'registered_participants_count' ], 'middleware' => [ [ @@ -380,10 +381,6 @@ class CRM_CiviMobileAPI_Page_PublicApi_Api extends CRM_CiviMobileAPI_Page_Public 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', 'method' => 'isAllowPublicInfoApi', ], - [ - 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', - 'method' => 'forbiddenForJoomla', - ], ], 'transforms' => [] ] @@ -425,10 +422,6 @@ class CRM_CiviMobileAPI_Page_PublicApi_Api extends CRM_CiviMobileAPI_Page_Public 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', 'method' => 'isAllowPublicInfoApi', ], - [ - 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', - 'method' => 'forbiddenForJoomla', - ], ], 'transforms' => [] ] @@ -453,10 +446,6 @@ class CRM_CiviMobileAPI_Page_PublicApi_Api extends CRM_CiviMobileAPI_Page_Public 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', 'method' => 'isAllowPublicInfoApi', ], - [ - 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', - 'method' => 'forbiddenForJoomla', - ], ], 'transforms' => [] ] @@ -489,15 +478,75 @@ class CRM_CiviMobileAPI_Page_PublicApi_Api extends CRM_CiviMobileAPI_Page_Public 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', 'method' => 'isAllowPublicInfoApi', ], + ], + 'transforms' => [] + ] + ] + ], + [ + 'entityName' => 'CiviMobileSurvey', + 'availableActions' => [ + [ + 'actionName' => 'get_structure', + 'actionPermissions' => ['sign CiviCRM Petition'], + 'availableParams' => [ + 'id' + ], + 'availableReturnFields' => [ + 'id', + 'title', + 'is_active', + 'is_petition', + 'activity_type_id', + 'profiles', + ], + 'middleware' => [ [ 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', - 'method' => 'forbiddenForJoomla', + 'method' => 'isAllowPublicInfoApi', + ], + ], + 'transforms' => [] + ], + [ + 'actionName' => 'sign', + 'actionPermissions' => ['sign CiviCRM Petition'], + 'availableParams' => [ + 'survey_id', + 'values', + ], + 'availableReturnFields' => [ + 'message', + ], + 'middleware' => [ + [ + 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', + 'method' => 'isAllowPublicInfoApi', + ], + ], + 'transforms' => [] + ], + [ + 'actionName' => 'get_contact_surveys', + 'actionPermissions' => ['sign CiviCRM Petition'], + 'availableParams' => [ + 'survey_id' + ], + 'availableReturnFields' => [ + 'id', + 'title', + 'is_active' + ], + 'middleware' => [ + [ + 'class' => 'CRM_CiviMobileAPI_Page_PublicApi_Middleware', + 'method' => 'isAllowPublicInfoApi', ], ], 'transforms' => [] ] - ] - ] + ], + ], ]; } diff --git a/CRM/CiviMobileAPI/Page/PublicApi/ApiBase.php b/CRM/CiviMobileAPI/Page/PublicApi/ApiBase.php index db21b38..8410d3e 100644 --- a/CRM/CiviMobileAPI/Page/PublicApi/ApiBase.php +++ b/CRM/CiviMobileAPI/Page/PublicApi/ApiBase.php @@ -38,6 +38,9 @@ abstract class CRM_CiviMobileAPI_Page_PublicApi_ApiBase extends CRM_Core_Page { JsonResponse::sendErrorResponse(E::ts('Not valid request')); } + $session = CRM_Core_Session::singleton(); + $session->set('userID', ''); + $this->requestJsonData = $this->findRequestJsonData(); $this->requestEntity = $this->findRequestEntityName(); $this->requestAction = $this->findRequestActionName(); diff --git a/CRM/CiviMobileAPI/Page/PublicSettings.php b/CRM/CiviMobileAPI/Page/PublicSettings.php index e898e0b..e615ceb 100644 --- a/CRM/CiviMobileAPI/Page/PublicSettings.php +++ b/CRM/CiviMobileAPI/Page/PublicSettings.php @@ -29,6 +29,7 @@ class CRM_CiviMobileAPI_Page_PublicSettings extends CRM_Core_Page { 'is_wp_rest_plugin_active' => (int) (new CRM_CiviMobileAPI_Utils_RestPath())->isWpRestPluginActive(), 'cms' => CRM_CiviMobileAPI_Utils_CmsUser::getInstance()->getSystem(), 'crm_version' => CRM_Utils_System::version(), + 'time_zone_utc_offset' => CRM_CiviMobileAPI_Utils_Cms::getTimeZoneUTCOffset(), 'civicrm_enable_components' => CRM_CiviMobileAPI_Utils_CiviCRM::getEnabledComponents(), 'ext_version' => CRM_CiviMobileAPI_Utils_VersionController::getInstance()->getCurrentFullVersion(), 'is_civimobile_ext_has_right_folder_name' => (int) CRM_CiviMobileAPI_Utils_Extension::hasExtensionRightFolderName(), diff --git a/CRM/CiviMobileAPI/Upgrader.php b/CRM/CiviMobileAPI/Upgrader.php index 45d923c..17ebc28 100644 --- a/CRM/CiviMobileAPI/Upgrader.php +++ b/CRM/CiviMobileAPI/Upgrader.php @@ -142,6 +142,17 @@ class CRM_CiviMobileAPI_Upgrader extends CRM_CiviMobileAPI_Upgrader_Base { } } + public function upgrade_0018() { + try { + (new CRM_CiviMobileAPI_Install_Entity_CustomGroup())->install(); + (new CRM_CiviMobileAPI_Install_Entity_CustomField())->install(); + } catch (Exception $e) { + return FALSE; + } + + return TRUE; + } + /** * Installs scheduled job * diff --git a/CRM/CiviMobileAPI/Utils/Checklist.php b/CRM/CiviMobileAPI/Utils/Checklist.php index d22a295..70a9cae 100644 --- a/CRM/CiviMobileAPI/Utils/Checklist.php +++ b/CRM/CiviMobileAPI/Utils/Checklist.php @@ -14,6 +14,11 @@ class CRM_CiviMobileAPI_Utils_Checklist { */ private $systemInfo = []; + /** + * @var array + */ + private $infoItems = []; + /** * Returns all checked items in object * @@ -55,6 +60,24 @@ class CRM_CiviMobileAPI_Utils_Checklist { return $this->systemInfo; } + /** + * Calls all available info methods and returns report + * Runs all methods which name starts from '_info' + * + * @return array + */ + public function getInfoItems() { + $classMethods = get_class_methods($this); + + foreach ($classMethods as $method) { + if (preg_match('/^_info/', $method)) { + $this->$method(); + } + } + + return $this->infoItems; + } + /** * Checks Extension Version */ @@ -95,7 +118,7 @@ class CRM_CiviMobileAPI_Utils_Checklist { $this->checkedItems['is_civimobile_ext_has_right_folder_name'] = [ 'title' => 'Is CivimobileAPI`s folder name correct?', - 'message' => $isRightExtensionFolderName ? 'Folder name is correct.' : 'You should rename CivimobileAPI extension`s folder to "' . CRM_CiviMobileAPI_ExtensionUtil::LONG_NAME . '" and then reinstall extension.', + 'message' => $isRightExtensionFolderName ? 'Folder name is correct.' : 'You should rename CivimobileAPI extension folder to "' . CRM_CiviMobileAPI_ExtensionUtil::LONG_NAME . '" and then reinstall extension.', 'status' => $isRightExtensionFolderName ? 'success' : 'error', ]; } @@ -107,8 +130,8 @@ class CRM_CiviMobileAPI_Utils_Checklist { if (CRM_CiviMobileAPI_Utils_Extension::hasExtensionRightFolderName()) { $isDirectoryWritable = CRM_CiviMobileAPI_Utils_Extension::directoryIsWritable(); $this->checkedItems['is_directory_writable'] = [ - 'title' => 'Is CiviMobileAPI extension`s directory writable?', - 'message' => $isDirectoryWritable ? 'Extension directory is writable.' : 'Please give permissions to write for CiviMobileAPI extension`s directory.', + 'title' => 'Is CiviMobileAPI extension directory writable?', + 'message' => $isDirectoryWritable ? 'Extension directory is writable.' : 'Please give permissions to write to CiviMobileAPI extension directory.', 'status' => $isDirectoryWritable ? 'success' : 'warning', ]; } @@ -120,13 +143,26 @@ class CRM_CiviMobileAPI_Utils_Checklist { public function _checkIsAdditionWpRestPluginInstalled() { if (CRM_CiviMobileAPI_Utils_CmsUser::getInstance()->getSystem() == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS) { $this->checkedItems['is_wp_rest_plugin_active']['title'] = 'Do you have the additional plugin for Wordpress?'; + $isWpRestPluginActive = (new CRM_CiviMobileAPI_Utils_RestPath())->isWpRestPluginActive(); - $this->checkedItems['is_wp_rest_plugin_active'] = [ - 'title' => 'Do you have the additional plugin for Wordpress?', - 'message' => $isWpRestPluginActive ? 'You have the additional plugin for Wordpress.' : 'You don`t have the additional plugin for Wordpress. CivimobileAPI cannot work without this plugin. You can read about this plugin on https://github.com/mecachisenros/civicrm-wp-rest', - 'status' => $isWpRestPluginActive ? 'success' : 'error', - ]; + if (version_compare(CRM_Utils_System::version(), '5.25.0', '>=')) { + if ($isWpRestPluginActive) { + $this->checkedItems['is_wp_rest_plugin_active']['message'] = 'For CiviCRM version 5.25.0 or higher you do not need to install CiviCRM WP REST API Wrapper plugin on WordPress. You should uninstall it for CiviMobile to work properly.'; + $this->checkedItems['is_wp_rest_plugin_active']['status'] = 'warning'; + } else { + $this->checkedItems['is_wp_rest_plugin_active']['message'] = 'For CiviCRM version 5.25.0 or higher you do not need to install CiviCRM WP REST API Wrapper plugin on WordPress.'; + $this->checkedItems['is_wp_rest_plugin_active']['status'] = 'success'; + } + } else { + if ($isWpRestPluginActive) { + $this->checkedItems['is_wp_rest_plugin_active']['message'] = 'You have the additional plugin for Wordpress.'; + $this->checkedItems['is_wp_rest_plugin_active']['status'] = 'success'; + } else { + $this->checkedItems['is_wp_rest_plugin_active']['message'] = 'You don`t have the additional plugin for Wordpress. CivimobileAPI cannot work without this plugin. You can read about this plugin here https://github.com/mecachisenros/civicrm-wp-rest'; + $this->checkedItems['is_wp_rest_plugin_active']['status'] = 'error'; + } + } } } @@ -138,7 +174,7 @@ class CRM_CiviMobileAPI_Utils_Checklist { $this->checkedItems['is_server_key_valid'] = [ 'title' => 'Is server key valid?', - 'message' => $isServerKeyValid ? 'Your server key is valid.' : 'Your server key is invalid. Please add correct server key on CiviMobile Settings to activate Push Notifications on application.', + 'message' => $isServerKeyValid ? 'Your server key is valid.' : 'Your server key is invalid. Please add correct server key to CiviMobile Settings to activate Push Notifications.', 'status' => $isServerKeyValid ? 'success' : 'warning', ]; } @@ -151,7 +187,7 @@ class CRM_CiviMobileAPI_Utils_Checklist { $this->checkedItems['is_curl_enabled'] = [ 'title' => 'Is curl php-extension enabled?', - 'message' => $isCurlEnabled ? 'Curl php-extension is available on your web server.' : 'Curl php-extension is not available on your web server. It`s necessary for PushNotifications.', + 'message' => $isCurlEnabled ? 'Curl php-extension is available on your web server.' : 'Curl php-extension is not available on your web server. It`s required for PushNotifications.', 'status' => $isCurlEnabled ? 'success' : 'error', ]; } @@ -161,12 +197,12 @@ class CRM_CiviMobileAPI_Utils_Checklist { */ public function _checkCron() { $checkCron = CRM_Utils_Check_Component_Env::checkLastCron(); - $this->checkedItems['last_cron']['title'] = 'Is CRON running correct?'; + $this->checkedItems['last_cron']['title'] = 'Is CRON running correctly?'; switch ($checkCron[0]->getLevel()) { case CRM_Utils_Check::severityMap(\Psr\Log\LogLevel::INFO): $this->checkedItems['last_cron']['status'] = 'success'; - $this->checkedItems['last_cron']['message'] = 'CRON is running correct.'; + $this->checkedItems['last_cron']['message'] = 'CRON is running correctly.'; break; case CRM_Utils_Check::severityMap(\Psr\Log\LogLevel::WARNING): case CRM_Utils_Check::severityMap(\Psr\Log\LogLevel::ERROR): @@ -176,6 +212,33 @@ class CRM_CiviMobileAPI_Utils_Checklist { } } + /** + * Checks is conflict WP plugins installed + */ + public function _checkConflictWPPlugins() { + if (CRM_CiviMobileAPI_Utils_CmsUser::getInstance()->getSystem() == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS) { + include_once(ABSPATH . 'wp-admin/includes/plugin.php'); + + if (function_exists('is_plugin_active')) { + foreach (CRM_CiviMobileAPI_Utils_Cms_Wordpress::getConflictPlugins() as $path => $name) { + if (is_plugin_active($path)) { + $this->checkedItems[] = [ + 'title' => E::ts('Is "%1" plugin active?', [1 => $name]), + 'message' => E::ts('CiviMobile may not work properly if "%1" plugin is installed.', [1 => $name]), + 'status' => 'warning', + ]; + } + } + } + } + } + + public function _infoConflictWPPlugins() { + if (CRM_CiviMobileAPI_Utils_CmsUser::getInstance()->getSystem() == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS) { + $this->infoItems[] = E::ts('If you have a problems with authorization on CiviMobile application please try to deactivate plugins one by one to detect which plugin blocks CiviMobile.'); + } + } + /** * Adds CiviCRM version to $systemInfo */ @@ -196,6 +259,16 @@ class CRM_CiviMobileAPI_Utils_Checklist { ]; } + /** + * Adds CMS version to $systemInfo + */ + public function _siCMSVersion() { + $this->systemInfo[] = [ + 'title' => 'CMS version', + 'message' => CRM_CiviMobileAPI_Utils_Cms::getCMSVersion(), + ]; + } + /** * Adds current and latest available versions to $systemInfo */ diff --git a/CRM/CiviMobileAPI/Utils/CiviCRM.php b/CRM/CiviMobileAPI/Utils/CiviCRM.php index 557a32d..86384f6 100644 --- a/CRM/CiviMobileAPI/Utils/CiviCRM.php +++ b/CRM/CiviMobileAPI/Utils/CiviCRM.php @@ -27,4 +27,27 @@ class CRM_CiviMobileAPI_Utils_CiviCRM { return $enableComponents; } + /** + * @return string + */ + public static function getRenewalMembershipContributionPageUrl() { + $pageId = Civi::settings()->get('default_renewal_contribution_page'); + + if (!empty($pageId)) { + $currentCMS = CRM_CiviMobileAPI_Utils_CmsUser::getInstance()->getSystem(); + + $url = CRM_Utils_System::url('civicrm/contribute/transact', ['id' => $pageId, 'civimobile' => 1, 'reset' => 1], TRUE, NULL, FALSE); + + if ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_JOOMLA) { + $url = preg_replace('/administrator\//', 'index.php', $url); + } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS ) { + $url = str_replace("wp-admin/admin.php", "index.php", $url); + } + + return $url; + } + + return ''; + } + } diff --git a/CRM/CiviMobileAPI/Utils/Cms.php b/CRM/CiviMobileAPI/Utils/Cms.php index 68584cf..0383039 100644 --- a/CRM/CiviMobileAPI/Utils/Cms.php +++ b/CRM/CiviMobileAPI/Utils/Cms.php @@ -13,13 +13,11 @@ class CRM_CiviMobileAPI_Utils_Cms { public static function getSiteName() { $currentCMS = CRM_CiviMobileAPI_Utils_CmsUser::getInstance()->getSystem(); - if ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS ) { + if ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS) { return get_bloginfo('name'); - } - elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_JOOMLA ) { + } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_JOOMLA) { return JFactory::getConfig()->get('sitename'); - } - elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL6 || $currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL7) { + } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL6 || $currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL7) { return variable_get('site_name', ''); } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL8) { @@ -40,8 +38,7 @@ class CRM_CiviMobileAPI_Utils_Cms { if ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS && function_exists('get_feed_link')) { return get_feed_link('rss2'); - } - elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_JOOMLA ) { + } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_JOOMLA) { return str_replace("/administrator/", "/", $config->userFrameworkBaseURL) . "?format=feed&type=rss"; } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL6 || $currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL7 || $currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL8) { @@ -51,4 +48,28 @@ class CRM_CiviMobileAPI_Utils_Cms { return ''; } + /** + * @return string + */ + public static function getCMSVersion() { + $currentCMS = CRM_CiviMobileAPI_Utils_CmsUser::getInstance()->getSystem(); + + if ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL6 || $currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_DRUPAL7) { + return VERSION; + } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_WORDPRESS && function_exists('get_bloginfo')) { + return get_bloginfo('version'); + } elseif ($currentCMS == CRM_CiviMobileAPI_Utils_CmsUser::CMS_JOOMLA) { + return defined('Joomla\CMS\Version::RELEASE') ? Joomla\CMS\Version::RELEASE : ''; + } + + return ''; + } + + /** + * @return int + */ + public static function getTimeZoneUTCOffset() { + return date('Z') / 3600; + } + } diff --git a/CRM/CiviMobileAPI/Utils/Cms/Wordpress.php b/CRM/CiviMobileAPI/Utils/Cms/Wordpress.php new file mode 100644 index 0000000..c0c3490 --- /dev/null +++ b/CRM/CiviMobileAPI/Utils/Cms/Wordpress.php @@ -0,0 +1,15 @@ + 'WP Hardening', + 'better-wp-security/better-wp-security.php' => 'iThemes Security' + ]; + } + +} \ No newline at end of file diff --git a/CRM/CiviMobileAPI/Utils/Permission.php b/CRM/CiviMobileAPI/Utils/Permission.php index d7b0c94..09074e6 100644 --- a/CRM/CiviMobileAPI/Utils/Permission.php +++ b/CRM/CiviMobileAPI/Utils/Permission.php @@ -155,6 +155,9 @@ class CRM_CiviMobileAPI_Utils_Permission { $profileCreate = CRM_Core_Permission::check('profile create'); $accessUploadedFiles = CRM_Core_Permission::check('access uploaded files'); $viewAgenda = CRM_Core_Permission::check('view Agenda'); + $signPetition = CRM_Core_Permission::check('sign CiviCRM Petition'); + $profileView = CRM_Core_Permission::check('profile view'); + $accessAllCustomData = CRM_Core_Permission::check('access all custom data'); } catch (Exception $e) { return []; } @@ -165,7 +168,9 @@ class CRM_CiviMobileAPI_Utils_Permission { 'view_public_participant' => $viewAllEvent && $viewEventParticipants ? 1 : 0, 'edit_public_participant' => $viewEventParticipants && $viewAllEvent && $editEventParticipants ? 1 : 0, 'access_uploaded_files' => $accessUploadedFiles ? 1 : 0, - 'view_agenda' => $viewAgenda ? 1 : 0 + 'view_agenda' => $viewAgenda ? 1 : 0, + 'view_petition' => $signPetition && $profileView && $accessAllCustomData ? 1 : 0, + 'sign_petition' => $signPetition && $profileCreate && $accessAllCustomData ? 1 : 0, ]; } @@ -327,4 +332,200 @@ class CRM_CiviMobileAPI_Utils_Permission { return FALSE; } + /** + * Is enough permission to get surveys list + */ + public static function isEnoughPermissionToGetSurveysList() { + if (CRM_Core_Permission::check('administer CiviCRM')) { + return true; + } + + if (CRM_Core_Permission::check('administer CiviCampaign') + || CRM_Core_Permission::check('manage campaign') + || CRM_Core_Permission::check('reserve campaign contacts') + || CRM_Core_Permission::check('release campaign contacts') + || CRM_Core_Permission::check('interview campaign contacts') + || CRM_Core_Permission::check('gotv campaign contacts') + || CRM_Core_Permission::check('sign CiviCRM Petition') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to change Interviewer + */ + public static function isEnoughPermissionToChangeInterviewer() { + if (CRM_Core_Permission::check('administer CiviCRM')) { + return true; + } + + if (CRM_Core_Permission::check('administer CiviCampaign')) { + return true; + } + + return false; + } + + /** + * Is enough permission to get respondents + */ + public static function isEnoughPermissionToGetRespondents() { + if (CRM_Core_Permission::check('administer CiviCRM') + || CRM_Core_Permission::check('manage campaign')) { + return true; + } + + if (CRM_Core_Permission::check('interview campaign contacts') + || CRM_Core_Permission::check('gotv campaign contacts') + || CRM_Core_Permission::check('release campaign contacts') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to reserve respondents + */ + public static function isEnoughPermissionToReserveRespondents() { + if (CRM_Core_Permission::check('administer CiviCRM') + || CRM_Core_Permission::check('manage campaign')) { + return true; + } + + if (CRM_Core_Permission::check('reserve campaign contacts') + && CRM_Core_Permission::check('interview campaign contacts') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to view respondent details + */ + public static function isEnoughPermissionToViewRespondentDetails() { + if (CRM_Core_Permission::check('administer CiviCRM') + || CRM_Core_Permission::check('administer CiviCampaign')) { + return true; + } + + if (CRM_Core_Permission::check('profile view') + && CRM_Core_Permission::check('interview campaign contacts') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to edit respondent details + */ + public static function isEnoughPermissionToEditRespondentDetails() { + if (CRM_Core_Permission::check('administer CiviCRM') + || CRM_Core_Permission::check('administer CiviCampaign')) { + return true; + } + + if (CRM_Core_Permission::check('profile create') + && CRM_Core_Permission::check('interview campaign contacts') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to release respondents + */ + public static function isEnoughPermissionToReleaseRespondents() { + if (CRM_Core_Permission::check('administer CiviCRM') + || CRM_Core_Permission::check('administer CiviCampaign')) { + return true; + } + + if (CRM_Core_Permission::check('release campaign contacts') + && CRM_Core_Permission::check('interview campaign contacts') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to GOTV respondents + */ + public static function isEnoughPermissionToGotvRespondents() { + if (CRM_Core_Permission::check('administer CiviCRM') + || CRM_Core_Permission::check('administer CiviCampaign')) { + return true; + } + + if (CRM_Core_Permission::check('gotv campaign contacts') + && CRM_Core_Permission::check('interview campaign contacts') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to view petition answers + */ + public static function isEnoughPermissionToViewPetitionAnswers() { + if (CRM_Core_Permission::check('administer CiviCRM')) { + return true; + } + + if (CRM_Core_Permission::check('profile view')) { + return true; + } + + return false; + } + + /** + * Is enough permission to sign petition + */ + public static function isEnoughPermissionToSignPetition() { + if (CRM_Core_Permission::check('administer CiviCRM')) { + return true; + } + + if (CRM_Core_Permission::check('profile create') + && CRM_Core_Permission::check('access all custom data') + && CRM_Core_Permission::check('sign CiviCRM Petition') + ) { + return true; + } + + return false; + } + + /** + * Is enough permission to view petition + */ + public static function isEnoughPermissionToViewPetition() { + if (CRM_Core_Permission::check('administer CiviCRM')) { + return true; + } + + if (CRM_Core_Permission::check('profile view') + && CRM_Core_Permission::check('access all custom data') + && CRM_Core_Permission::check('sign CiviCRM Petition') + ) { + return true; + } + + return false; + } } diff --git a/CRM/CiviMobileAPI/Utils/RestPath.php b/CRM/CiviMobileAPI/Utils/RestPath.php index 480864b..59c5ff6 100644 --- a/CRM/CiviMobileAPI/Utils/RestPath.php +++ b/CRM/CiviMobileAPI/Utils/RestPath.php @@ -58,6 +58,8 @@ class CRM_CiviMobileAPI_Utils_RestPath { return false; } + include_once(ABSPATH.'wp-admin/includes/plugin.php'); + if (function_exists('is_plugin_active')) { $pathPlugin = 'civicrm-wp-rest/civicrm-wp-rest.php'; if (is_plugin_active($pathPlugin)) { @@ -65,13 +67,6 @@ class CRM_CiviMobileAPI_Utils_RestPath { } } - if (class_exists('CiviCRM_WP_REST\Controller\Rest')) { - $restController = new CiviCRM_WP_REST\Controller\Rest(); - if (method_exists($restController, 'get_endpoint')) { - return true; - } - } - return false; } diff --git a/CRM/CiviMobileAPI/Utils/Survey.php b/CRM/CiviMobileAPI/Utils/Survey.php new file mode 100644 index 0000000..344196d --- /dev/null +++ b/CRM/CiviMobileAPI/Utils/Survey.php @@ -0,0 +1,24 @@ + "value", + 'option_group_id' => "activity_type", + 'component_id' => "CiviCampaign", + 'options' => ['limit' => 0], + ]); + + $surveyActivityTypesIds = []; + + foreach ($surveyActivityTypes['values'] as $type) { + $surveyActivityTypesIds[] = $type['value']; + } + + return $surveyActivityTypesIds; + } +} diff --git a/README.md b/README.md index b9c0d3c..82f4922 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ The **CiviMobileAPI** extension is a CiviCRM component that allows to use a mobi - **Push-notifications** - notifications about the updates in the system are displayed on the dashboard of the mobile phone. - **Public Area** - supports user account setup in CiviCRM, public events view and registration for unauthenticated users. - **News** – RSS feed reader keeps users informed about latest news updates organization shares. +- **Surveys** – ability to conduct surveys with all updated survey details, walk lists, respondent statuses at hand and data available for analysis in real-time. +- **Petitions** – support a broader campaign by engaging registered and unregistered users to sign a petition within the app. - **Working Offline** - can work in the offline mode. - **Settings** - users can configure a set of parameters customizing the view and work of the application. - **9 locales** - supports: English, German, French, Italian, Spanish, Dutch, Hungarian, Polish and Ukrainian. diff --git a/api/v3/CiviMobilePermission.php b/api/v3/CiviMobilePermission.php index dca6b95..414ab66 100644 --- a/api/v3/CiviMobilePermission.php +++ b/api/v3/CiviMobilePermission.php @@ -275,6 +275,22 @@ function civicrm_api3_civi_mobile_permission_get() { 'view' => $viewAgenda ? 1 : 0 ]; + $permissions['surveys'] = [ + 'administer_civi_campaign' => CRM_Core_Permission::check('administer CiviCampaign') ? 1 : 0, + 'manage_campaign' => CRM_Core_Permission::check('manage campaign') ? 1 : 0, + 'reserve_campaign_contacts' => CRM_Core_Permission::check('reserve campaign contacts') ? 1 : 0, + 'release_campaign_contacts' => CRM_Core_Permission::check('release campaign contacts') ? 1 : 0, + 'interview_campaign_contacts' => CRM_Core_Permission::check('interview campaign contacts') ? 1 : 0, + 'gotv_campaign_contacts' => CRM_Core_Permission::check('gotv campaign contacts') ? 1 : 0, + 'sign_civicrm_petition' => CRM_Core_Permission::check('sign CiviCRM Petition') ? 1 : 0, + ]; + + $permissions['profile'] = [ + 'view' => CRM_Core_Permission::check('profile view'), + 'create' => CRM_Core_Permission::check('profile create'), + 'edit' => CRM_Core_Permission::check('profile edit'), + ]; + $nullObject = CRM_Utils_Hook::$_nullObject; CRM_Utils_Hook::singleton() ->commonInvoke(1, $permissions, $nullObject, $nullObject, $nullObject, $nullObject, $nullObject, 'civimobile_permission', ''); diff --git a/api/v3/CiviMobileSurvey.php b/api/v3/CiviMobileSurvey.php new file mode 100644 index 0000000..92d8d6e --- /dev/null +++ b/api/v3/CiviMobileSurvey.php @@ -0,0 +1,149 @@ +getResult(); + return civicrm_api3_create_success($result); +} + +/** + * @param $params + */ +function _civicrm_api3_civi_mobile_survey_get_contact_surveys_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + ]; + $params['title'] = [ + 'title' => 'Title', + 'description' => ts('Title'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + ]; + $params['contact_id'] = [ + 'title' => 'Contact ID', + 'description' => ts('Contact ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + ]; + $params['activity_type_id'] = [ + 'title' => 'Activity type ID', + 'description' => ts('Activity type ID'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 0, + ]; + $params['is_signed'] = [ + 'title' => 'Is signed?', + 'description' => ts('Is signed?'), + 'type' => CRM_Utils_Type::T_BOOLEAN, + 'api.required' => 0, + ]; +} + +/** + * Returns info about fields for petition + * + * @param $params + * @return array + * @throws api_Exception + */ +function civicrm_api3_civi_mobile_survey_get_structure($params) { + $result = (new CRM_CiviMobileAPI_Api_CiviMobileSurvey_GetStructure($params))->getResult(); + return civicrm_api3_create_success($result); +} + +/** + * @param $params + */ +function _civicrm_api3_civi_mobile_survey_get_structure_spec(&$params) { + $params['id'] = [ + 'title' => 'Survey ID', + 'description' => ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; +} + +/** + * Signs petition + * + * @param $params + * @return array + * @throws api_Exception + */ +function civicrm_api3_civi_mobile_survey_sign($params) { + $result = (new CRM_CiviMobileAPI_Api_CiviMobileSurvey_Sign($params))->getResult(); + return civicrm_api3_create_success($result); +} + +/** + * @param $params + */ +function _civicrm_api3_civi_mobile_survey_sign_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; + $params['contact_id'] = [ + 'title' => 'Contact ID', + 'description' => ts('Contact ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + ]; + $params['values'] = [ + 'title' => 'Values', + 'description' => ts('Values'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + ]; + $params['note'] = [ + 'title' => 'Note', + 'description' => ts('Note'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['result'] = [ + 'title' => 'Result', + 'description' => ts('Result'), + 'type' => CRM_Utils_Type::T_STRING, + ]; +} + +/** + * Signs petition + * + * @param $params + * @return array + * @throws api_Exception + */ +function civicrm_api3_civi_mobile_survey_get_signed_values($params) { + $result = (new CRM_CiviMobileAPI_Api_CiviMobileSurvey_GetSignedValues($params))->getResult(); + return civicrm_api3_create_success($result); +} + +/** + * @param $params + */ +function _civicrm_api3_civi_mobile_survey_get_signed_values_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; + $params['contact_id'] = [ + 'title' => 'Contact ID', + 'description' => ts('Contact ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; +} diff --git a/api/v3/CiviMobileSurveyInterviewer.php b/api/v3/CiviMobileSurveyInterviewer.php new file mode 100644 index 0000000..da479e4 --- /dev/null +++ b/api/v3/CiviMobileSurveyInterviewer.php @@ -0,0 +1,23 @@ +getResult(); + + return civicrm_api3_create_success($result); +} + +function _civicrm_api3_civi_mobile_survey_interviewer_get_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => E::ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; +} diff --git a/api/v3/CiviMobileSurveyRespondent.php b/api/v3/CiviMobileSurveyRespondent.php new file mode 100644 index 0000000..004c973 --- /dev/null +++ b/api/v3/CiviMobileSurveyRespondent.php @@ -0,0 +1,217 @@ +getResult(); + + return civicrm_api3_create_success($result); +} + +/** + * @param array $params array or parameters determined by getfields + */ +function _civicrm_api3_civi_mobile_survey_respondent_reserve_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => E::ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; + $params['contact_ids'] = [ + 'title' => 'Contact IDs', + 'description' => E::ts('Contact IDs'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + ]; + $params['interviewer_id'] = [ + 'title' => 'Interviewer ID', + 'description' => E::ts('Interviewer ID'), + 'type' => CRM_Utils_Type::T_INT, + ]; +} + +/** + * @param array $params + * + * @return array + */ +function civicrm_api3_civi_mobile_survey_respondent_get($params) { + $result = (new CRM_CiviMobileAPI_Api_CiviMobileSurveyRespondent_Get($params))->getResult(); + + return civicrm_api3_create_success($result); +} + +/** + * @param array $params array or parameters determined by getfields + */ +function _civicrm_api3_civi_mobile_survey_respondent_get_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => E::ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; + $params['interviewer_id'] = [ + 'title' => 'Interviewer ID', + 'description' => E::ts('Interviewer ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 0, + ]; + $params['survey_status'] = [ + 'title' => 'Status', + 'description' => E::ts('Status'), + 'type' => CRM_Utils_Type::T_STRING, + 'options' => [ + 'Reserved' => E::ts('Reserved'), + 'Interviewed' => E::ts('Interviewed'), + 'GOTV' => E::ts('GOTV'), + ], + ]; + $params['group'] = [ + 'title' => 'Group', + 'description' => E::ts('Group'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['contact_type'] = [ + 'title' => 'Contact type', + 'description' => E::ts('Contact type'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['display_name'] = [ + 'title' => 'Display name', + 'description' => E::ts('Display name'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['city'] = [ + 'title' => 'Primary Address City', + 'description' => E::ts('Primary Address City'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['street_address'] = [ + 'title' => 'Primary Address Street Address', + 'description' => E::ts('Primary Address Street Address'), + 'type' => CRM_Utils_Type::T_STRING, + ]; +} + +/** + * @param array $params + * + * @return array + */ +function civicrm_api3_civi_mobile_survey_respondent_release($params) { + $result = (new CRM_CiviMobileAPI_Api_CiviMobileSurveyRespondent_Release($params))->getResult(); + + return civicrm_api3_create_success($result); +} + +/** + * @param array $params array or parameters determined by getfields + */ +function _civicrm_api3_civi_mobile_survey_respondent_release_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => E::ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; + $params['contact_ids'] = [ + 'title' => 'Contact IDs', + 'description' => E::ts('Contact IDs'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + ]; + $params['interviewer_id'] = [ + 'title' => 'Interviewer ID', + 'description' => E::ts('Interviewer ID'), + 'type' => CRM_Utils_Type::T_INT, + ]; +} + +/** + * @param array $params + * + * @return array + */ +function civicrm_api3_civi_mobile_survey_respondent_gotv($params) { + $result = (new CRM_CiviMobileAPI_Api_CiviMobileSurveyRespondent_Gotv($params))->getResult(); + + return civicrm_api3_create_success($result); +} + +/** + * @param array $params array or parameters determined by getfields + */ +function _civicrm_api3_civi_mobile_survey_respondent_gotv_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => E::ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; + $params['contact_ids'] = [ + 'title' => 'Contact IDs', + 'description' => E::ts('Contact IDs'), + 'type' => CRM_Utils_Type::T_STRING, + 'api.required' => 1, + ]; + $params['interviewer_id'] = [ + 'title' => 'Interviewer ID', + 'description' => E::ts('Interviewer ID'), + 'type' => CRM_Utils_Type::T_INT, + ]; +} + +/** + * @param array $params + * + * @return array + */ +function civicrm_api3_civi_mobile_survey_respondent_get_to_reserve($params) { + $result = (new CRM_CiviMobileAPI_Api_CiviMobileSurveyRespondent_GetToReserve($params))->getResult(); + + return civicrm_api3_create_success($result); +} + +/** + * @param array $params array or parameters determined by getfields + */ +function _civicrm_api3_civi_mobile_survey_respondent_get_to_reserve_spec(&$params) { + $params['survey_id'] = [ + 'title' => 'Survey ID', + 'description' => E::ts('Survey ID'), + 'type' => CRM_Utils_Type::T_INT, + 'api.required' => 1, + ]; + $params['group'] = [ + 'title' => 'Group', + 'description' => E::ts('Group'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['contact_type'] = [ + 'title' => 'Contact type', + 'description' => E::ts('Contact type'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['city'] = [ + 'title' => 'Primary Address City', + 'description' => E::ts('Primary Address City'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['street_address'] = [ + 'title' => 'Primary Address Street Address', + 'description' => E::ts('Primary Address Street Address'), + 'type' => CRM_Utils_Type::T_STRING, + ]; + $params['display_name'] = [ + 'title' => 'Display name', + 'description' => E::ts('Display name'), + 'type' => CRM_Utils_Type::T_STRING, + ]; +} diff --git a/api/v3/CiviMobileSystem.php b/api/v3/CiviMobileSystem.php index 0bbb5f7..1d6c4e6 100644 --- a/api/v3/CiviMobileSystem.php +++ b/api/v3/CiviMobileSystem.php @@ -17,7 +17,8 @@ function civicrm_api3_civi_mobile_system_get($params) { 'ext_version' => CRM_CiviMobileAPI_Utils_VersionController::getInstance()->getCurrentFullVersion(), 'site_name' => CRM_CiviMobileAPI_Utils_Extension::getSiteName(), 'is_showed_news' => CRM_CiviMobileAPI_Utils_Extension::isShowedNews(), - 'news_rss_feed_url' => CRM_CiviMobileAPI_Utils_Extension::newsRssFeedUrl() + 'news_rss_feed_url' => CRM_CiviMobileAPI_Utils_Extension::newsRssFeedUrl(), + 'renewal_membership_contribution_page_url' => CRM_CiviMobileAPI_Utils_CiviCRM::getRenewalMembershipContributionPageUrl(), ]; return civicrm_api3_create_success($result, $params); diff --git a/api/v3/CiviMobileVenue.php b/api/v3/CiviMobileVenue.php index edd5326..080e07d 100644 --- a/api/v3/CiviMobileVenue.php +++ b/api/v3/CiviMobileVenue.php @@ -189,7 +189,8 @@ function civicrm_api3_civi_mobile_venue_delete($params) { } catch (Exception $e) { throw new api_Exception('Venue does not exists.', 'venue_does not exists.'); } - CRM_CiviMobileAPI_Utils_Agenda_Venue::removeVenueAttach($params['id']); + + CRM_Core_BAO_File::deleteEntityFile('civicrm_civimobile_location_venue', $params['id']); $venue->del($params['id']); return civicrm_api3_create_success([ diff --git a/civimobileapi.php b/civimobileapi.php index d42f18a..c1e4d0a 100644 --- a/civimobileapi.php +++ b/civimobileapi.php @@ -197,6 +197,10 @@ function civimobileapi_civicrm_apiWrappers(&$wrappers, $apiRequest) { if ($apiRequest['action'] == 'get') { $wrappers[] = new CRM_CiviMobileAPI_ApiWrapper_EntityTag_Get(); } + } elseif ($apiRequest['entity'] == 'Survey') { + if ($apiRequest['action'] == 'getsingle') { + $wrappers[] = new CRM_CiviMobileAPI_ApiWrapper_Survey_Getsingle(); + } } } @@ -238,7 +242,17 @@ function civimobileapi_civicrm_alterAPIPermissions($entity, $action, &$params, & ($entity == 'state_province' and $action == 'get') || ($entity == 'civi_mobile_available_contact_group' and $action == 'get') || ($entity == 'civi_mobile_tag_structure' and $action == 'get') || - ($entity == 'civi_mobile_custom_fields' and $action == 'get') + ($entity == 'civi_mobile_custom_fields' and $action == 'get') || + + ($entity == 'civi_mobile_survey_respondent' and $action == 'reserve') || + ($entity == 'civi_mobile_survey_respondent' and $action == 'get') || + ($entity == 'civi_mobile_survey_respondent' and $action == 'release') || + ($entity == 'civi_mobile_survey_respondent' and $action == 'gotv') || + ($entity == 'civi_mobile_survey_respondent' and $action == 'get_to_reserve') || + ($entity == 'civi_mobile_survey' and $action == 'get_contact_surveys') || + ($entity == 'civi_mobile_survey' and $action == 'get_structure') || + ($entity == 'civi_mobile_survey' and $action == 'sign') || + ($entity == 'civi_mobile_survey' and $action == 'get_signed_values') ) { $params['check_permissions'] = FALSE; } @@ -611,6 +625,15 @@ function civimobileapi_civicrm_navigationMenu(&$menu) { 'separator' => NULL, ]; _civimobileapi_civix_insert_navigation_menu($menu, 'Administer/CiviEvent/', $civiMobileEventLocations); + + $civiMobileSettings = [ + 'name' => E::ts('CiviMobile Checklist'), + 'url' => 'civicrm/civimobile/checklist', + 'permission' => 'administer CiviCRM', + 'operator' => NULL, + 'separator' => NULL, + ]; + _civimobileapi_civix_insert_navigation_menu($menu, 'Administer/CiviMobile/', $civiMobileSettings); } /** @@ -681,3 +704,15 @@ function civimobileapi_civicrm_alterContent(&$content, $context, $tplName, &$obj } } } + +function civimobileapi_civicrm_postSave_civicrm_activity($dao) { + if (isset($_POST['hasVoted']) && !is_null($dao->status_id)) { + $hasVoted = CRM_Utils_String::strtoboolstr(CRM_Utils_Type::escape($_POST['hasVoted'], 'String')); + $gotvCustomFieldName = 'custom_' . CRM_CiviMobileAPI_Utils_CustomField::getId(CRM_CiviMobileAPI_Install_Entity_CustomGroup::SURVEY,CRM_CiviMobileAPI_Install_Entity_CustomField::SURVEY_GOTV_STATUS); + + civicrm_api3('Activity', 'create', [ + $gotvCustomFieldName => $hasVoted, + 'id' => $dao->id + ]); + } +} diff --git a/css/civimobileapiChecklist.css b/css/civimobileapiChecklist.css index 0977adf..527e6ee 100644 --- a/css/civimobileapiChecklist.css +++ b/css/civimobileapiChecklist.css @@ -31,7 +31,7 @@ } .checklist-table-cell.full-cell { - width: 50%; + width: calc(100% - 20px); } .checklist-table-cell.status-icon { @@ -50,3 +50,16 @@ .checklist-table-cell.status-icon .fa-exclamation-triangle { color: orange; } + +.checklist-info-table { + margin-top: 10px; +} + +.checklist-preloader { + margin: 15px 0; + text-align: center; +} + +.checklist-preloader img { + width: 60px; +} diff --git a/css/civimobileapiSettings.css b/css/civimobileapiSettings.css index f8a9b8c..2b336e0 100644 --- a/css/civimobileapiSettings.css +++ b/css/civimobileapiSettings.css @@ -12,6 +12,11 @@ padding: 0.25em 0.5em; } +#itemsToShowMessage .crm-marker { + padding: 0; + margin: 0; +} + .crm-container table.form-layout-compressed { width: 100%; } diff --git a/info.xml b/info.xml index 9027cf7..c2e667c 100644 --- a/info.xml +++ b/info.xml @@ -14,8 +14,8 @@ https://civimobile.org http://www.gnu.org/licenses/agpl-3.0.html - 2020-12-07 - 5.4.0 + 2021-01-25 + 5.5.0 4.7 5.20 diff --git a/sql/create_event_session_speaker.sql b/sql/create_event_session_speaker.sql index 1ada239..c0added 100644 --- a/sql/create_event_session_speaker.sql +++ b/sql/create_event_session_speaker.sql @@ -7,4 +7,4 @@ CREATE TABLE IF NOT EXISTS `civicrm_civimobile_event_session_speaker` ( FOREIGN KEY (`event_session_id`) REFERENCES `civicrm_civimobile_event_session` (`id`) ON DELETE CASCADE - ON UPDATE NO ACTION); + ON UPDATE NO ACTION) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/templates/CRM/CiviMobileAPI/Form/Settings.tpl b/templates/CRM/CiviMobileAPI/Form/Settings.tpl index 338b0a4..1dee8e0 100644 --- a/templates/CRM/CiviMobileAPI/Form/Settings.tpl +++ b/templates/CRM/CiviMobileAPI/Form/Settings.tpl @@ -329,6 +329,10 @@ shownItems.push("Events*"); $(".spec-event-note").show(); } + if (possibleItemsToDisplayInPublicArea.indexOf('Petitions') !== -1) { + shownItems.push("Petitions*"); + $(".spec-event-note").show(); + } } if (shownItems.length === 0) { diff --git a/templates/CRM/CiviMobileAPI/Page/Checklist.tpl b/templates/CRM/CiviMobileAPI/Page/Checklist.tpl index 9d445ac..b08f57d 100644 --- a/templates/CRM/CiviMobileAPI/Page/Checklist.tpl +++ b/templates/CRM/CiviMobileAPI/Page/Checklist.tpl @@ -3,7 +3,7 @@ {foreach from=$checklist_params item=param}
- +
{$param.title} @@ -15,15 +15,32 @@ {/foreach}
+
+ preloader +
+ +
+ {foreach from=$info item=infoItem} +
+
+ +
+
+ {$infoItem} +
+
+ {/foreach} +
+

System Info

{foreach from=$system_info item=param}
-
+
{$param.title}
-
+
{$param.message}
@@ -54,7 +71,7 @@ }).then(function(result) { $.get(restUrl, function(data) { if (JSON.stringify(result) === JSON.stringify(data)) { - $("#checklist-items-block").append(generateCheckBlock('Is rest url correct?', 'Rest url is not correct.', 'success')); + $("#checklist-items-block").append(generateCheckBlock('Is rest url correct?', 'Rest url is correct.', 'success')); } else { $("#checklist-items-block").append(generateCheckBlock('Is rest url correct?', 'Rest url is not correct.', 'error')); } @@ -64,12 +81,14 @@ $.get(restPathUrl, function(data) { if (JSON.stringify(result) === JSON.stringify(data)) { - $("#checklist-items-block").append(generateCheckBlock('Is rest path correct?', 'Rest path is not correct.', 'success')); + $("#checklist-items-block").append(generateCheckBlock('Is rest path correct?', 'Rest path is correct.', 'success')); } else { $("#checklist-items-block").append(generateCheckBlock('Is rest path correct?', 'Rest path is not correct.', 'error')); } + $('.checklist-preloader').remove(); }).fail(function() { $("#checklist-items-block").append(generateCheckBlock('Is rest path correct?', 'Rest path is not correct.', 'error')); + $('.checklist-preloader').remove(); }); }); -- GitLab