3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
21 class CRM_Core_BAO_Domain
extends CRM_Core_DAO_Domain
{
24 * Cache for a domain's location array
27 private $_location = NULL;
30 * Flushes the cache set by getDomain.
32 * @see CRM_Core_BAO_Domain::getDomain()
33 * @param CRM_Core_DAO_Domain $domain
35 public static function onPostSave($domain) {
36 Civi
::$statics[__CLASS__
]['current'] = NULL;
40 * Retrieve DB object and copy to defaults array.
42 * @param array $params
43 * Array of criteria values.
44 * @param array $defaults
45 * Array to be populated with found values.
48 * The DAO object, if found.
52 public static function retrieve($params, &$defaults) {
53 return self
::commonRetrieve(self
::class, $params, $defaults);
57 * Get the current domain.
59 * @return \CRM_Core_BAO_Domain
60 * @throws \CRM_Core_Exception
62 public static function getDomain() {
63 $domain = Civi
::$statics[__CLASS__
]['current'] ??
NULL;
65 $domain = new CRM_Core_BAO_Domain();
66 $domain->id
= CRM_Core_Config
::domainID();
67 if (!$domain->find(TRUE)) {
68 throw new CRM_Core_Exception('No domain in DB');
70 Civi
::$statics[__CLASS__
]['current'] = $domain;
76 * @param bool $skipUsingCache
80 * @throws \CRM_Core_Exception
82 public static function version($skipUsingCache = FALSE) {
83 if ($skipUsingCache) {
84 Civi
::$statics[__CLASS__
]['current'] = NULL;
87 return self
::getDomain()->version
;
91 * Is a database update required to apply latest schema changes.
95 * @throws \CRM_Core_Exception
97 public static function isDBUpdateRequired() {
98 $dbVersion = self
::version();
99 $codeVersion = CRM_Utils_System
::version();
100 return version_compare($dbVersion, $codeVersion) < 0;
104 * Checks that the current DB schema is at least $min version
106 * @param string|int $min
109 public static function isDBVersionAtLeast($min) {
110 return version_compare(self
::version(), $min, '>=');
116 protected static function getMissingDomainFromEmailMessage(): string {
117 $url = CRM_Utils_System
::url('civicrm/admin/options/from_email_address',
120 $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]);
125 * Get the location values of a domain.
127 * @return CRM_Core_BAO_Location[]|NULL
129 public function getLocationValues() {
130 if ($this->_location
== NULL) {
132 'contact_id' => $this->contact_id
,
134 $this->_location
= CRM_Core_BAO_Location
::getValues($params, TRUE);
136 if (empty($this->_location
)) {
137 $this->_location
= NULL;
140 return $this->_location
;
146 * @param array $params
149 * @return CRM_Core_DAO_Domain
151 public static function edit($params, $id) {
153 return self
::writeRecord($params);
157 * Create or update domain.
159 * @param array $params
160 * @return CRM_Core_DAO_Domain
162 public static function create($params) {
163 return self
::writeRecord($params);
169 public static function multipleDomains() {
170 $session = CRM_Core_Session
::singleton();
172 $numberDomains = $session->get('numberDomains');
173 if (!$numberDomains) {
174 $query = 'SELECT count(*) from civicrm_domain';
175 $numberDomains = CRM_Core_DAO
::singleValueQuery($query);
176 $session->set('numberDomains', $numberDomains);
178 return $numberDomains > 1;
182 * @param bool $skipFatal
183 * @param bool $returnString
184 * If you are using this second parameter you probably are better
185 * calling `getFromEmail()` which will return an actual string.
188 * name & email for domain
190 * @throws \CRM_Core_Exception
192 public static function getNameAndEmail($skipFatal = FALSE, $returnString = FALSE) {
193 $fromEmailAddress = CRM_Core_OptionGroup
::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1');
194 if (!empty($fromEmailAddress)) {
196 // Return a string like: "Demonstrators Anonymous" <info@example.org>
197 return $fromEmailAddress;
199 foreach ($fromEmailAddress as $key => $value) {
200 $email = CRM_Utils_Mail
::pluckEmailFromHeader($value);
201 $fromArray = explode('"', $value);
202 $fromName = $fromArray[1] ??
NULL;
205 return [$fromName, $email];
212 $status = self
::getMissingDomainFromEmailMessage();
214 throw new CRM_Core_Exception($status);
218 * Get the domain email in a format suitable for using as the from address.
221 * @throws \CRM_Core_Exception
223 public static function getFromEmail(): string {
224 $email = CRM_Core_OptionGroup
::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1');
225 $email = current($email);
227 throw new CRM_Core_Exception(self
::getMissingDomainFromEmailMessage());
233 * @param int $contactID
235 * @return bool|null|object|string
237 * @throws \CRM_Core_Exception
239 public static function addContactToDomainGroup($contactID) {
240 $groupID = self
::getGroupId();
243 $contactIDs = [$contactID];
244 CRM_Contact_BAO_GroupContact
::addContactsToGroup($contactIDs, $groupID);
252 * @return bool|null|object|string
254 * @throws \CRM_Core_Exception
256 public static function getGroupId() {
257 static $groupID = NULL;
263 $domainGroupID = Civi
::settings()->get('domain_group_id');
264 $multisite = Civi
::settings()->get('is_enabled');
266 if ($domainGroupID) {
267 $groupID = $domainGroupID;
269 elseif ($multisite) {
270 // create a group with that of domain name
271 $title = self
::getDomain()->name
;
272 $groupID = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group',
273 $title, 'id', 'title', TRUE
276 return $groupID ?
$groupID : FALSE;
280 * @param int $groupId
284 * @throws \CRM_Core_Exception
286 public static function isDomainGroup($groupId) {
287 $domainGroupID = self
::getGroupId();
288 return $domainGroupID == (bool) $groupId;
294 * @throws \CRM_Core_Exception
296 public static function getChildGroupIds() {
297 $domainGroupID = self
::getGroupId();
300 if ($domainGroupID) {
301 $childGrps = CRM_Contact_BAO_GroupNesting
::getChildGroupIds($domainGroupID);
302 $childGrps[] = $domainGroupID;
308 * Retrieve a list of contact-ids that belongs to current domain/site.
312 * @throws \CRM_Core_Exception
314 public static function getContactList() {
315 $siteGroups = CRM_Core_BAO_Domain
::getChildGroupIds();
318 if (!empty($siteGroups)) {
321 FROM civicrm_contact cc
322 INNER JOIN civicrm_group_contact gc ON
323 (gc.contact_id = cc.id AND gc.status = 'Added' AND gc.group_id IN (" . implode(',', $siteGroups) . "))";
325 $dao = CRM_Core_DAO
::executeQuery($query);
326 while ($dao->fetch()) {
327 $siteContacts[] = $dao->id
;
330 return $siteContacts;
334 * CRM-20308 & CRM-19657
335 * Return domain information / user information for the usage in receipts
336 * Try default from address then fall back to using logged in user details
338 * @throws \CiviCRM_API3_Exception
340 public static function getDefaultReceiptFrom() {
341 $domain = civicrm_api3('domain', 'getsingle', ['id' => CRM_Core_Config
::domainID()]);
342 if (!empty($domain['from_email'])) {
343 return [$domain['from_name'], $domain['from_email']];
345 if (!empty($domain['domain_email'])) {
346 return [$domain['name'], $domain['domain_email']];
351 if (!Civi
::settings()->get('allow_mail_from_logged_in_contact')) {
352 return [$userName, $userEmail];
355 $userID = CRM_Core_Session
::getLoggedInContactID();
356 if (!empty($userID)) {
357 [$userName, $userEmail] = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
359 // If still empty fall back to the logged in user details.
360 // return empty values no matter what.
361 return [$userName, $userEmail];
365 * Get address to be used for system from addresses when a reply is not expected.
367 public static function getNoReplyEmailAddress() {
368 $emailDomain = CRM_Core_BAO_MailSettings
::defaultDomain();
369 return "do-not-reply@$emailDomain";