Merge pull request #24117 from civicrm/5.52
[civicrm-core.git] / CRM / Core / BAO / Domain.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
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 |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17
18/**
19 *
20 */
21class CRM_Core_BAO_Domain extends CRM_Core_DAO_Domain {
22
6a488035
TO
23 /**
24 * Cache for a domain's location array
518fa0ee 25 * @var array
6a488035
TO
26 */
27 private $_location = NULL;
28
d357f225
CW
29 /**
30 * Flushes the cache set by getDomain.
31 *
32 * @see CRM_Core_BAO_Domain::getDomain()
33 * @param CRM_Core_DAO_Domain $domain
34 */
35 public static function onPostSave($domain) {
acd447a1
EM
36 // We want to clear out any cached tokens.
37 // Editing a domain is so rare we can risk being heavy handed.
38 Civi::cache('metadata')->clear();
d357f225
CW
39 Civi::$statics[__CLASS__]['current'] = NULL;
40 }
41
6a488035 42 /**
4f940304 43 * Retrieve DB object and copy to defaults array.
6a488035 44 *
6a0b768e 45 * @param array $params
4f940304 46 * Array of criteria values.
6a0b768e 47 * @param array $defaults
4f940304 48 * Array to be populated with found values.
6a488035 49 *
4f940304
CW
50 * @return self|null
51 * The DAO object, if found.
52 *
53 * @deprecated
6a488035 54 */
4f940304
CW
55 public static function retrieve($params, &$defaults) {
56 return self::commonRetrieve(self::class, $params, $defaults);
6a488035
TO
57 }
58
59 /**
d357f225 60 * Get the current domain.
77b97be7 61 *
2149f4bd 62 * @return \CRM_Core_BAO_Domain
63 * @throws \CRM_Core_Exception
6a488035 64 */
d357f225
CW
65 public static function getDomain() {
66 $domain = Civi::$statics[__CLASS__]['current'] ?? NULL;
67 if (!$domain) {
6a488035
TO
68 $domain = new CRM_Core_BAO_Domain();
69 $domain->id = CRM_Core_Config::domainID();
70 if (!$domain->find(TRUE)) {
2149f4bd 71 throw new CRM_Core_Exception('No domain in DB');
6a488035 72 }
d357f225 73 Civi::$statics[__CLASS__]['current'] = $domain;
6a488035
TO
74 }
75 return $domain;
76 }
77
b5c2afd0
EM
78 /**
79 * @param bool $skipUsingCache
80 *
d357f225 81 * @return string
527745f0 82 *
83 * @throws \CRM_Core_Exception
b5c2afd0 84 */
2aa397bc 85 public static function version($skipUsingCache = FALSE) {
d357f225
CW
86 if ($skipUsingCache) {
87 Civi::$statics[__CLASS__]['current'] = NULL;
88 }
89
90 return self::getDomain()->version;
6a488035
TO
91 }
92
1fbda76b 93 /**
94 * Is a database update required to apply latest schema changes.
95 *
96 * @return bool
97 *
98 * @throws \CRM_Core_Exception
99 */
100 public static function isDBUpdateRequired() {
d357f225 101 $dbVersion = self::version();
1fbda76b 102 $codeVersion = CRM_Utils_System::version();
103 return version_compare($dbVersion, $codeVersion) < 0;
104 }
105
d51a6a62
CW
106 /**
107 * Checks that the current DB schema is at least $min version
108 *
aec7c57d 109 * @param string|int $min
d51a6a62
CW
110 * @return bool
111 */
112 public static function isDBVersionAtLeast($min) {
113 return version_compare(self::version(), $min, '>=');
114 }
115
bd6ce89b
EM
116 /**
117 * @return string
118 */
119 protected static function getMissingDomainFromEmailMessage(): string {
120 $url = CRM_Utils_System::url('civicrm/admin/options/from_email_address',
121 'reset=1'
122 );
123 $status = ts("There is no valid default from email address configured for the domain. You can configure here <a href='%1'>Configure From Email Address.</a>", [1 => $url]);
124 return $status;
125 }
126
6a488035 127 /**
fe482240 128 * Get the location values of a domain.
6a488035 129 *
d357f225 130 * @return CRM_Core_BAO_Location[]|NULL
6a488035 131 */
d357f225 132 public function getLocationValues() {
6a488035 133 if ($this->_location == NULL) {
be2fb01f 134 $params = [
d357f225 135 'contact_id' => $this->contact_id,
be2fb01f 136 ];
6a488035
TO
137 $this->_location = CRM_Core_BAO_Location::getValues($params, TRUE);
138
139 if (empty($this->_location)) {
140 $this->_location = NULL;
141 }
142 }
143 return $this->_location;
144 }
145
146 /**
6a5fec96 147 * Update a domain.
6a488035 148 *
c490a46a 149 * @param array $params
100fef9d 150 * @param int $id
da6b46f4 151 *
f54abaae 152 * @deprecated
527745f0 153 * @return CRM_Core_DAO_Domain
acd447a1 154 * @throws \CRM_Core_Exception
6a488035 155 */
acd447a1 156 public static function edit($params, $id): CRM_Core_DAO_Domain {
6a5fec96
CW
157 $params['id'] = $id;
158 return self::writeRecord($params);
6a488035
TO
159 }
160
161 /**
6a5fec96 162 * Create or update domain.
6a488035 163 *
f54abaae 164 * @deprecated
c490a46a 165 * @param array $params
527745f0 166 * @return CRM_Core_DAO_Domain
6a488035 167 */
00be9182 168 public static function create($params) {
6a5fec96 169 return self::writeRecord($params);
6a488035
TO
170 }
171
b5c2afd0
EM
172 /**
173 * @return bool
174 */
00be9182 175 public static function multipleDomains() {
6a488035
TO
176 $session = CRM_Core_Session::singleton();
177
178 $numberDomains = $session->get('numberDomains');
179 if (!$numberDomains) {
527745f0 180 $query = 'SELECT count(*) from civicrm_domain';
6a488035
TO
181 $numberDomains = CRM_Core_DAO::singleValueQuery($query);
182 $session->set('numberDomains', $numberDomains);
183 }
63d76404 184 return $numberDomains > 1;
6a488035
TO
185 }
186
b5c2afd0
EM
187 /**
188 * @param bool $skipFatal
518fa0ee 189 * @param bool $returnString
bd6ce89b
EM
190 * If you are using this second parameter you probably are better
191 * calling `getFromEmail()` which will return an actual string.
527745f0 192 *
a6c01b45
CW
193 * @return array
194 * name & email for domain
527745f0 195 *
196 * @throws \CRM_Core_Exception
b5c2afd0 197 */
beac1417 198 public static function getNameAndEmail($skipFatal = FALSE, $returnString = FALSE) {
6a488035
TO
199 $fromEmailAddress = CRM_Core_OptionGroup::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1');
200 if (!empty($fromEmailAddress)) {
beac1417
MW
201 if ($returnString) {
202 // Return a string like: "Demonstrators Anonymous" <info@example.org>
203 return $fromEmailAddress;
204 }
6a488035 205 foreach ($fromEmailAddress as $key => $value) {
353ffa53 206 $email = CRM_Utils_Mail::pluckEmailFromHeader($value);
6a488035 207 $fromArray = explode('"', $value);
9c1bc317 208 $fromName = $fromArray[1] ?? NULL;
6a488035
TO
209 break;
210 }
be2fb01f 211 return [$fromName, $email];
6a488035 212 }
beac1417
MW
213
214 if ($skipFatal) {
be2fb01f 215 return [NULL, NULL];
6a488035
TO
216 }
217
bd6ce89b 218 $status = self::getMissingDomainFromEmailMessage();
6a488035 219
527745f0 220 throw new CRM_Core_Exception($status);
6a488035
TO
221 }
222
bd6ce89b
EM
223 /**
224 * Get the domain email in a format suitable for using as the from address.
225 *
226 * @return string
227 * @throws \CRM_Core_Exception
228 */
229 public static function getFromEmail(): string {
230 $email = CRM_Core_OptionGroup::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1');
231 $email = current($email);
232 if (!$email) {
233 throw new CRM_Core_Exception(self::getMissingDomainFromEmailMessage());
234 }
235 return $email;
236 }
237
b5c2afd0 238 /**
100fef9d 239 * @param int $contactID
b5c2afd0
EM
240 *
241 * @return bool|null|object|string
527745f0 242 *
243 * @throws \CRM_Core_Exception
b5c2afd0 244 */
00be9182 245 public static function addContactToDomainGroup($contactID) {
6a488035
TO
246 $groupID = self::getGroupId();
247
248 if ($groupID) {
be2fb01f 249 $contactIDs = [$contactID];
6a488035
TO
250 CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIDs, $groupID);
251
252 return $groupID;
253 }
254 return FALSE;
255 }
256
b5c2afd0
EM
257 /**
258 * @return bool|null|object|string
527745f0 259 *
260 * @throws \CRM_Core_Exception
b5c2afd0 261 */
00be9182 262 public static function getGroupId() {
6a488035
TO
263 static $groupID = NULL;
264
265 if ($groupID) {
266 return $groupID;
267 }
268
aaffa79f 269 $domainGroupID = Civi::settings()->get('domain_group_id');
270 $multisite = Civi::settings()->get('is_enabled');
6a488035
TO
271
272 if ($domainGroupID) {
273 $groupID = $domainGroupID;
274 }
275 elseif ($multisite) {
276 // create a group with that of domain name
d357f225 277 $title = self::getDomain()->name;
6a488035 278 $groupID = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group',
2aa397bc 279 $title, 'id', 'title', TRUE
6a488035 280 );
6a488035
TO
281 }
282 return $groupID ? $groupID : FALSE;
283 }
284
b5c2afd0 285 /**
100fef9d 286 * @param int $groupId
b5c2afd0
EM
287 *
288 * @return bool
527745f0 289 *
290 * @throws \CRM_Core_Exception
b5c2afd0 291 */
00be9182 292 public static function isDomainGroup($groupId) {
6a488035 293 $domainGroupID = self::getGroupId();
63d76404 294 return $domainGroupID == (bool) $groupId;
6a488035
TO
295 }
296
b5c2afd0
EM
297 /**
298 * @return array
527745f0 299 *
300 * @throws \CRM_Core_Exception
b5c2afd0 301 */
00be9182 302 public static function getChildGroupIds() {
6a488035 303 $domainGroupID = self::getGroupId();
be2fb01f 304 $childGrps = [];
6a488035
TO
305
306 if ($domainGroupID) {
307 $childGrps = CRM_Contact_BAO_GroupNesting::getChildGroupIds($domainGroupID);
308 $childGrps[] = $domainGroupID;
309 }
310 return $childGrps;
311 }
312
b5c2afd0 313 /**
100fef9d 314 * Retrieve a list of contact-ids that belongs to current domain/site.
c490a46a 315 *
b5c2afd0 316 * @return array
527745f0 317 *
318 * @throws \CRM_Core_Exception
b5c2afd0 319 */
00be9182 320 public static function getContactList() {
6a488035 321 $siteGroups = CRM_Core_BAO_Domain::getChildGroupIds();
be2fb01f 322 $siteContacts = [];
6a488035
TO
323
324 if (!empty($siteGroups)) {
325 $query = "
326 SELECT cc.id
327 FROM civicrm_contact cc
328 INNER JOIN civicrm_group_contact gc ON
329 (gc.contact_id = cc.id AND gc.status = 'Added' AND gc.group_id IN (" . implode(',', $siteGroups) . "))";
330
331 $dao = CRM_Core_DAO::executeQuery($query);
332 while ($dao->fetch()) {
333 $siteContacts[] = $dao->id;
334 }
335 }
336 return $siteContacts;
337 }
96025800 338
b5bfb58f
SL
339 /**
340 * CRM-20308 & CRM-19657
beac1417
MW
341 * Return domain information / user information for the usage in receipts
342 * Try default from address then fall back to using logged in user details
527745f0 343 *
344 * @throws \CiviCRM_API3_Exception
b5bfb58f 345 */
b1273714 346 public static function getDefaultReceiptFrom() {
be2fb01f 347 $domain = civicrm_api3('domain', 'getsingle', ['id' => CRM_Core_Config::domainID()]);
b5bfb58f 348 if (!empty($domain['from_email'])) {
be2fb01f 349 return [$domain['from_name'], $domain['from_email']];
b5bfb58f
SL
350 }
351 if (!empty($domain['domain_email'])) {
be2fb01f 352 return [$domain['name'], $domain['domain_email']];
b5bfb58f 353 }
b5bfb58f
SL
354 $userName = '';
355 $userEmail = '';
4c981f37
MW
356
357 if (!Civi::settings()->get('allow_mail_from_logged_in_contact')) {
be2fb01f 358 return [$userName, $userEmail];
4c981f37
MW
359 }
360
2dbdb9b9 361 $userID = CRM_Core_Session::getLoggedInContactID();
b5bfb58f 362 if (!empty($userID)) {
bd6ce89b 363 [$userName, $userEmail] = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID);
b5bfb58f
SL
364 }
365 // If still empty fall back to the logged in user details.
366 // return empty values no matter what.
be2fb01f 367 return [$userName, $userEmail];
b5bfb58f
SL
368 }
369
576fcb9c 370 /**
371 * Get address to be used for system from addresses when a reply is not expected.
372 */
373 public static function getNoReplyEmailAddress() {
374 $emailDomain = CRM_Core_BAO_MailSettings::defaultDomain();
375 return "do-not-reply@$emailDomain";
376 }
377
6a488035 378}