Merge pull request #24117 from civicrm/5.52
[civicrm-core.git] / CRM / PCP / Form / PCPAccount.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17
18 /**
19 * This class generates form components for processing a contribution.
20 */
21 class CRM_PCP_Form_PCPAccount extends CRM_Core_Form {
22
23 /**
24 * Variable defined for Contribution Page Id.
25 * @var int
26 */
27 public $_pageId = NULL;
28 public $_id = NULL;
29 public $_component = NULL;
30
31 /**
32 * Are we in single form mode or wizard mode?
33 *
34 * @var bool
35 */
36 public $_single;
37
38 /**
39 * Get the active UFGroups (profiles) on this form
40 * Many forms load one or more UFGroups (profiles).
41 * This provides a standard function to retrieve the IDs of those profiles from the form
42 * so that you can implement things such as "is is_captcha field set on any of the active profiles on this form?"
43 *
44 * NOT SUPPORTED FOR USE OUTSIDE CORE EXTENSIONS - Added for reCAPTCHA core extension.
45 *
46 * @return array
47 */
48 public function getUFGroupIDs() {
49 $ufGroupIDs = [];
50 if (!empty($this->_pageId)) {
51 $ufGroupIDs[] = CRM_PCP_BAO_PCP::getSupporterProfileId($this->_pageId, $this->_component);
52 }
53 return $ufGroupIDs;
54 }
55
56 public function preProcess() {
57 $session = CRM_Core_Session::singleton();
58 $config = CRM_Core_Config::singleton();
59 $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE);
60 $this->_pageId = CRM_Utils_Request::retrieve('pageId', 'Positive', $this);
61 $this->_component = CRM_Utils_Request::retrieve('component', 'String', $this);
62 $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
63
64 if (!$this->_pageId && $config->userFramework == 'Joomla' && $config->userFrameworkFrontend) {
65 $this->_pageId = $this->_id;
66 }
67
68 if ($this->_id) {
69 $contactID = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $this->_id, 'contact_id');
70 }
71
72 $this->_contactID = $contactID ?? CRM_Core_Session::getLoggedInContactID();
73 if (!$this->_pageId) {
74 if (!$this->_id) {
75 $msg = ts('We can\'t load the requested web page due to an incomplete link. This can be caused by using your browser\'s Back button or by using an incomplete or invalid link.');
76 CRM_Core_Error::statusBounce($msg);
77 }
78 else {
79 $this->_pageId = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP', $this->_id, 'page_id');
80 }
81 }
82
83 if (!$this->_pageId) {
84 CRM_Core_Error::statusBounce(ts('Could not find source page id.'));
85 }
86
87 $this->_single = $this->get('single');
88
89 if (!$this->_single) {
90 $this->_single = $session->get('singleForm');
91 }
92
93 $this->set('action', $this->_action);
94 $this->set('page_id', $this->_id);
95 $this->set('component_page_id', $this->_pageId);
96
97 // we do not want to display recently viewed items, so turn off
98 $this->assign('displayRecent', FALSE);
99
100 $this->assign('pcpComponent', $this->_component);
101
102 if ($this->_single) {
103 $this->setTitle(ts('Update Contact Information'));
104 }
105 }
106
107 /**
108 * @return array
109 */
110 public function setDefaultValues() {
111 $this->_defaults = [];
112 if ($this->_contactID) {
113 foreach ($this->_fields as $name => $dontcare) {
114 $fields[$name] = 1;
115 }
116
117 CRM_Core_BAO_UFGroup::setProfileDefaults($this->_contactID, $fields, $this->_defaults);
118
119 if (!empty($this->_defaults['image_URL'])) {
120 $this->assign("imageURL", CRM_Utils_File::getImageURL($this->_defaults['image_URL']));
121 $this->removeFileRequiredRules('image_URL');
122
123 $deleteExtra = json_encode(ts('Are you sure you want to delete the contact image?'));
124 $deleteURL = [
125 CRM_Core_Action::DELETE => [
126 'name' => ts('Delete Contact Image'),
127 'url' => 'civicrm/contact/image',
128 'qs' => 'reset=1&cid=' . $this->_contactID . '&action=delete',
129 'extra' => 'onclick = "' . htmlspecialchars("if (confirm($deleteExtra)) this.href+='&confirmed=1'; else return false;") . '"',
130 ],
131 ];
132 $deleteURL = CRM_Core_Action::formLink($deleteURL,
133 CRM_Core_Action::DELETE,
134 [
135 'id' => $this->_contactID,
136 ],
137 ts('more'),
138 FALSE,
139 'contact.image.delete',
140 'Contact',
141 $this->_contactID
142 );
143 $this->assign('deleteURL', $deleteURL);
144 }
145 }
146 //set custom field defaults
147 foreach ($this->_fields as $name => $field) {
148 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($name)) {
149 if (!isset($this->_defaults[$name])) {
150 CRM_Core_BAO_CustomField::setProfileDefaults($customFieldID, $name, $this->_defaults,
151 NULL, CRM_Profile_Form::MODE_REGISTER
152 );
153 }
154 }
155 }
156 return $this->_defaults;
157 }
158
159 /**
160 * Build the form object.
161 *
162 * @return void
163 */
164 public function buildQuickForm() {
165 $ufGroupID = CRM_PCP_BAO_PCP::getSupporterProfileId($this->_pageId, $this->_component);
166 if (CRM_PCP_BAO_PCP::checkEmailProfile($ufGroupID)) {
167 $this->assign('profileDisplay', TRUE);
168 }
169 $fields = NULL;
170 if ($this->_contactID) {
171 if (CRM_Core_BAO_UFGroup::filterUFGroups($ufGroupID, $this->_contactID)) {
172 $fields = CRM_Core_BAO_UFGroup::getFields($ufGroupID, FALSE, CRM_Core_Action::ADD);
173 }
174 $this->addFormRule(['CRM_PCP_Form_PCPAccount', 'formRule'], $this);
175 }
176 else {
177 CRM_Core_BAO_CMSUser::buildForm($this, $ufGroupID, TRUE);
178
179 $fields = CRM_Core_BAO_UFGroup::getFields($ufGroupID, FALSE, CRM_Core_Action::ADD);
180 }
181
182 if ($fields) {
183 $this->assign('fields', $fields);
184 foreach ($fields as $key => $field) {
185 if (isset($field['data_type']) && $field['data_type'] == 'File') {
186 // ignore file upload fields
187 continue;
188 }
189 CRM_Core_BAO_UFGroup::buildProfile($this, $field, CRM_Profile_Form::MODE_CREATE);
190 $this->_fields[$key] = $field;
191 }
192 }
193
194 if ($this->_component == 'contribute') {
195 $this->assign('campaignName', CRM_Contribute_PseudoConstant::contributionPage($this->_pageId));
196 }
197 elseif ($this->_component == 'event') {
198 $this->assign('campaignName', CRM_Event_PseudoConstant::event($this->_pageId));
199 }
200
201 // get the value from session, this is set if there is any file upload field
202 $uploadNames = $this->get('uploadNames');
203 if (!empty($uploadNames)) {
204 $buttonName = 'upload';
205 }
206 else {
207 $buttonName = 'next';
208 }
209
210 if ($this->_single) {
211 $button = [
212 [
213 'type' => $buttonName,
214 'name' => ts('Save'),
215 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
216 'isDefault' => TRUE,
217 ],
218 [
219 'type' => 'cancel',
220 'name' => ts('Cancel'),
221 ],
222 ];
223 }
224 else {
225 $button[] = [
226 'type' => $buttonName,
227 'name' => ts('Continue'),
228 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
229 'isDefault' => TRUE,
230 ];
231 }
232 $this->addFormRule(['CRM_PCP_Form_PCPAccount', 'formRule'], $this);
233 $this->addButtons($button);
234 }
235
236 /**
237 * Global form rule.
238 *
239 * @param array $fields
240 * The input form values.
241 * @param array $files
242 * The uploaded files if any.
243 * @param self $self
244 *
245 *
246 * @return bool|array
247 * true if no errors, else array of errors
248 */
249 public static function formRule($fields, $files, $self) {
250 $errors = [];
251 foreach ($fields as $key => $value) {
252 if (strpos($key, 'email-') !== FALSE && !empty($value)) {
253 $ufContactId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFMatch', $value, 'contact_id', 'uf_name');
254 if ($ufContactId && $ufContactId != $self->_contactID) {
255 $errors[$key] = ts('There is already an user associated with this email address. Please enter different email address.');
256 }
257 }
258 }
259 return empty($errors) ? TRUE : $errors;
260 }
261
262 /**
263 * Process the form submission.
264 *
265 *
266 * @return void
267 */
268 public function postProcess() {
269 $params = $this->controller->exportValues($this->getName());
270
271 if (!$this->_contactID && isset($params['cms_create_account'])) {
272 foreach ($params as $key => $value) {
273 if (substr($key, 0, 5) == 'email' && !empty($value)) {
274 list($fieldName, $locTypeId) = CRM_Utils_System::explode('-', $key, 2);
275 $isPrimary = 0;
276 if ($locTypeId == 'Primary') {
277 $locTypeDefault = CRM_Core_BAO_LocationType::getDefault();
278 $locTypeId = NULL;
279 if ($locTypeDefault) {
280 $locTypeId = $locTypeDefault->id;
281 }
282 $isPrimary = 1;
283 }
284
285 $params['email'] = [];
286 $params['email'][1]['email'] = $value;
287 $params['email'][1]['location_type_id'] = $locTypeId;
288 $params['email'][1]['is_primary'] = $isPrimary;
289 }
290 }
291 }
292
293 $this->_contactID = CRM_Contact_BAO_Contact::getFirstDuplicateContact($params, 'Individual', 'Unsupervised', [], FALSE);
294
295 if (!empty($params['image_URL'])) {
296 CRM_Contact_BAO_Contact::processImageParams($params);
297 }
298
299 $contactID = CRM_Contact_BAO_Contact::createProfileContact($params, $this->_fields, $this->_contactID);
300 $this->set('contactID', $contactID);
301
302 if (!empty($params['email'])) {
303 $params['email'] = $params['email'][1]['email'];
304 }
305
306 CRM_Contribute_BAO_Contribution_Utils::createCMSUser($params, $contactID, 'email');
307 }
308
309 }