Remove deprecated function.
[civicrm-core.git] / CRM / Core / CommunityMessages.php
CommitLineData
ecbe1139
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
ecbe1139 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
ecbe1139
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
ecbe1139
TO
27
28/**
29 * Manage the download, validation, and rendering of community messages
30 */
31class CRM_Core_CommunityMessages {
32
20eff8a7 33 const DEFAULT_MESSAGES_URL = 'https://alert.civicrm.org/alert?prot=1&ver={ver}&uf={uf}&sid={sid}&lang={lang}&co={co}';
dc92f2f8 34 const DEFAULT_PERMISSION = 'administer CiviCRM';
e8977170 35
ecbe1139 36 /**
0880a9d0 37 * Default time to wait before retrying.
ecbe1139 38 */
518fa0ee
SL
39 // 2 hours
40 const DEFAULT_RETRY = 7200;
ecbe1139
TO
41
42 /**
43 * @var CRM_Utils_HttpClient
44 */
45 protected $client;
46
47 /**
48 * @var CRM_Utils_Cache_Interface
49 */
50 protected $cache;
51
e8977170 52 /**
e97c66ff 53 * Url to retrieve community messages from.
54 *
55 * False means a retrieval will not be attempted.
56 *
57 * @var false|string
e8977170
TO
58 */
59 protected $messagesUrl;
60
847c93ac 61 /**
0880a9d0 62 * Create default instance.
847c93ac
TO
63 *
64 * @return CRM_Core_CommunityMessages
65 */
66 public static function create() {
67 return new CRM_Core_CommunityMessages(
a4704404 68 Civi::cache('community_messages'),
847c93ac
TO
69 CRM_Utils_HttpClient::singleton()
70 );
71 }
72
ecbe1139 73 /**
e97c66ff 74 * Class constructor.
75 *
ecbe1139
TO
76 * @param CRM_Utils_Cache_Interface $cache
77 * @param CRM_Utils_HttpClient $client
e97c66ff 78 * @param string|false $messagesUrl
ecbe1139 79 */
e8977170 80 public function __construct($cache, $client, $messagesUrl = NULL) {
ecbe1139
TO
81 $this->cache = $cache;
82 $this->client = $client;
e8977170 83 if ($messagesUrl === NULL) {
d356cdeb 84 $this->messagesUrl = Civi::settings()->get('communityMessagesUrl');
e8977170
TO
85 }
86 else {
87 $this->messagesUrl = $messagesUrl;
88 }
847c93ac
TO
89 if ($this->messagesUrl === '*default*') {
90 $this->messagesUrl = self::DEFAULT_MESSAGES_URL;
91 }
ecbe1139
TO
92 }
93
94 /**
e97c66ff 95 * Get the messages document (either from the cache or by downloading).
ecbe1139
TO
96 *
97 * @return NULL|array
98 */
99 public function getDocument() {
ecbe1139
TO
100 $isChanged = FALSE;
101 $document = $this->cache->get('communityMessages');
102
103 if (empty($document) || !is_array($document)) {
be2fb01f
CW
104 $document = [
105 'messages' => [],
518fa0ee
SL
106 // ASAP
107 'expires' => 0,
ecbe1139
TO
108 'ttl' => self::DEFAULT_RETRY,
109 'retry' => self::DEFAULT_RETRY,
be2fb01f 110 ];
ecbe1139
TO
111 $isChanged = TRUE;
112 }
113
114 if ($document['expires'] <= CRM_Utils_Time::getTimeRaw()) {
847c93ac 115 $newDocument = $this->fetchDocument();
8bfc3cb1 116 if ($newDocument && $this->validateDocument($newDocument)) {
ecbe1139
TO
117 $document = $newDocument;
118 $document['expires'] = CRM_Utils_Time::getTimeRaw() + $document['ttl'];
e8977170
TO
119 }
120 else {
d1b65097 121 // keep the old messages for now, try again later
ecbe1139
TO
122 $document['expires'] = CRM_Utils_Time::getTimeRaw() + $document['retry'];
123 }
124 $isChanged = TRUE;
125 }
126
127 if ($isChanged) {
128 $this->cache->set('communityMessages', $document);
129 }
130
131 return $document;
132 }
133
134 /**
0880a9d0 135 * Download document from URL and parse as JSON.
ecbe1139 136 *
72b3a70c
CW
137 * @return NULL|array
138 * parsed JSON
ecbe1139 139 */
847c93ac
TO
140 public function fetchDocument() {
141 list($status, $json) = $this->client->get($this->getRenderedUrl());
ecbe1139
TO
142 if ($status != CRM_Utils_HttpClient::STATUS_OK || empty($json)) {
143 return NULL;
144 }
145 $doc = json_decode($json, TRUE);
146 if (empty($doc) || json_last_error() != JSON_ERROR_NONE) {
147 return NULL;
148 }
149 return $doc;
150 }
151
847c93ac
TO
152 /**
153 * Get the final, usable URL string (after interpolating any variables)
154 *
155 * @return FALSE|string
156 */
157 public function getRenderedUrl() {
158 return CRM_Utils_System::evalUrl($this->messagesUrl);
159 }
160
161 /**
162 * @return bool
163 */
164 public function isEnabled() {
165 return $this->messagesUrl !== FALSE && $this->messagesUrl !== 'FALSE';
166 }
167
ecbe1139 168 /**
0880a9d0 169 * Pick a message to display.
ecbe1139 170 *
ecbe1139
TO
171 * @return NULL|array
172 */
dc92f2f8
TO
173 public function pick() {
174 $document = $this->getDocument();
be2fb01f 175 $messages = [];
dc92f2f8
TO
176 foreach ($document['messages'] as $message) {
177 if (!isset($message['perms'])) {
be2fb01f 178 $message['perms'] = [self::DEFAULT_PERMISSION];
dc92f2f8
TO
179 }
180 if (!CRM_Core_Permission::checkAnyPerm($message['perms'])) {
181 continue;
182 }
183
184 if (isset($message['components'])) {
185 $enabled = array_keys(CRM_Core_Component::getEnabledComponents());
186 if (count(array_intersect($enabled, $message['components'])) == 0) {
187 continue;
188 }
189 }
190
191 $messages[] = $message;
192 }
193 if (empty($messages)) {
194 return NULL;
195 }
196
197 $idx = rand(0, count($messages) - 1);
198 return $messages[$idx];
ecbe1139
TO
199 }
200
201 /**
202 * @param string $markup
203 * @return string
204 */
205 public static function evalMarkup($markup) {
d1b65097 206 $config = CRM_Core_Config::singleton();
be2fb01f 207 $vals = [
d1b65097
TO
208 'resourceUrl' => rtrim($config->resourceBase, '/'),
209 'ver' => CRM_Utils_System::version(),
210 'uf' => $config->userFramework,
211 'php' => phpversion(),
202407d7 212 'sid' => CRM_Utils_System::getSiteID(),
d1b65097
TO
213 'baseUrl' => $config->userFrameworkBaseURL,
214 'lang' => $config->lcMessages,
215 'co' => $config->defaultContactCountry,
be2fb01f
CW
216 ];
217 $vars = [];
d1b65097 218 foreach ($vals as $k => $v) {
847c93ac
TO
219 $vars['%%' . $k . '%%'] = $v;
220 $vars['{{' . $k . '}}'] = urlencode($v);
d1b65097
TO
221 }
222 return strtr($markup, $vars);
ecbe1139
TO
223 }
224
8bfc3cb1
TO
225 /**
226 * Ensure that a document is well-formed
227 *
228 * @param array $document
229 * @return bool
230 */
231 public function validateDocument($document) {
389bcebf 232 if (!isset($document['ttl']) || !is_int($document['ttl'])) {
8bfc3cb1
TO
233 return FALSE;
234 }
389bcebf 235 if (!isset($document['retry']) || !is_int($document['retry'])) {
8bfc3cb1
TO
236 return FALSE;
237 }
238 if (!isset($document['messages']) || !is_array($document['messages'])) {
239 return FALSE;
240 }
241 foreach ($document['messages'] as $message) {
242 // TODO validate $message['markup']
243 }
244
245 return TRUE;
246 }
247
ecbe1139 248}