1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
|
|
* Contains rules integration for the system module needed during evaluation.
|
6 |
|
|
*
|
7 |
|
|
* @addtogroup rules
|
8 |
|
|
* @{
|
9 |
|
|
*/
|
10 |
|
|
|
11 |
|
|
/**
|
12 |
|
|
* Action: Show a drupal message.
|
13 |
|
|
*/
|
14 |
|
|
function rules_action_drupal_message($message, $status, $repeat) {
|
15 |
|
|
drupal_set_message(filter_xss_admin($message), $status, $repeat);
|
16 |
|
|
}
|
17 |
|
|
|
18 |
|
|
/**
|
19 |
|
|
* Action: Page redirect.
|
20 |
|
|
*
|
21 |
|
|
* @see rules_page_build()
|
22 |
|
|
* @see rules_drupal_goto_alter()
|
23 |
|
|
*/
|
24 |
|
|
function rules_action_drupal_goto($url, $force = FALSE, $destination = FALSE) {
|
25 |
|
|
// Don't let administrators lock them out from Rules administration pages.
|
26 |
|
|
if (isset($_GET['q']) && strpos($_GET['q'], 'admin/config/workflow/rules') === 0) {
|
27 |
|
|
rules_log('Skipped page redirect on Rules administration page.', array(), RulesLog::WARN);
|
28 |
|
|
return;
|
29 |
|
|
}
|
30 |
|
|
// Do not redirect during batch processing.
|
31 |
|
|
if (($batch = batch_get()) && isset($batch['current_set'])) {
|
32 |
|
|
rules_log('Skipped page redirect during batch processing.');
|
33 |
|
|
return;
|
34 |
|
|
}
|
35 |
|
|
|
36 |
|
|
// Keep the current destination parameter if there is one set.
|
37 |
|
|
if ($destination) {
|
38 |
|
|
$url .= strpos($url, '?') === FALSE ? '?' : '&';
|
39 |
|
|
$url .= drupal_http_build_query(drupal_get_destination());
|
40 |
|
|
}
|
41 |
|
|
// If force is enabled, remove any destination parameter.
|
42 |
|
|
if ($force && isset($_GET['destination'])) {
|
43 |
|
|
unset($_GET['destination']);
|
44 |
|
|
}
|
45 |
|
|
// We don't invoke drupal_goto() right now, as this would end the the current
|
46 |
|
|
// page execution unpredictly for modules. So we'll take over drupal_goto()
|
47 |
|
|
// calls from somewhere else via hook_drupal_goto_alter() and make sure
|
48 |
|
|
// a drupal_goto() is invoked before the page is output with
|
49 |
|
|
// rules_page_build().
|
50 |
|
|
$GLOBALS['_rules_action_drupal_goto_do'] = array($url, $force);
|
51 |
|
|
}
|
52 |
|
|
|
53 |
|
|
/**
|
54 |
|
|
* Action: Set breadcrumb.
|
55 |
|
|
*/
|
56 |
|
|
function rules_action_breadcrumb_set(array $titles, array $paths) {
|
57 |
|
|
$trail = array(l(t('Home'), ''));
|
58 |
|
|
foreach ($titles as $i => $title) {
|
59 |
|
|
// Skip empty titles.
|
60 |
|
|
if ($title = trim($title)) {
|
61 |
|
|
// Output plaintext instead of a link if there is a title
|
62 |
|
|
// without a path.
|
63 |
|
|
$path = trim($paths[$i]);
|
64 |
|
|
if (!empty($paths[$i]) && $paths[$i] != '<none>') {
|
65 |
|
|
$trail[] = l($title, trim($paths[$i]));
|
66 |
|
|
}
|
67 |
|
|
else {
|
68 |
|
|
$trail[] = check_plain($title);
|
69 |
|
|
}
|
70 |
|
|
}
|
71 |
|
|
}
|
72 |
|
|
drupal_set_breadcrumb($trail);
|
73 |
|
|
}
|
74 |
|
|
|
75 |
|
|
/**
|
76 |
|
|
* Action Implementation: Send mail.
|
77 |
|
|
*/
|
78 |
|
|
function rules_action_mail($to, $subject, $message, $from = NULL, $langcode, $settings, RulesState $state, RulesPlugin $element) {
|
79 |
|
|
$to = str_replace(array("\r", "\n"), '', $to);
|
80 |
|
|
$from = !empty($from) ? str_replace(array("\r", "\n"), '', $from) : NULL;
|
81 |
|
|
$params = array(
|
82 |
|
|
'subject' => $subject,
|
83 |
|
|
'message' => $message,
|
84 |
|
|
'langcode' => $langcode,
|
85 |
|
|
);
|
86 |
|
|
// Set a unique key for this mail.
|
87 |
|
|
$name = isset($element->root()->name) ? $element->root()->name : 'unnamed';
|
88 |
|
|
$key = 'rules_action_mail_' . $name . '_' . $element->elementId();
|
89 |
|
|
$languages = language_list();
|
90 |
|
|
$language = isset($languages[$langcode]) ? $languages[$langcode] : language_default();
|
91 |
|
|
|
92 |
|
|
$message = drupal_mail('rules', $key, $to, $language, $params, $from);
|
93 |
|
|
if ($message['result']) {
|
94 |
|
|
watchdog('rules', 'Successfully sent email to %recipient', array('%recipient' => $to));
|
95 |
|
|
}
|
96 |
|
|
}
|
97 |
|
|
|
98 |
|
|
/**
|
99 |
|
|
* Action: Send mail to all users of a specific role group(s).
|
100 |
|
|
*/
|
101 |
|
|
function rules_action_mail_to_users_of_role($roles, $subject, $message, $from = NULL, $settings, RulesState $state, RulesPlugin $element) {
|
102 |
|
|
$from = !empty($from) ? str_replace(array("\r", "\n"), '', $from) : NULL;
|
103 |
|
|
|
104 |
|
|
// All authenticated users, which is everybody.
|
105 |
|
|
if (in_array(DRUPAL_AUTHENTICATED_RID, $roles)) {
|
106 |
|
|
$result = db_query('SELECT mail FROM {users} WHERE uid > 0');
|
107 |
|
|
}
|
108 |
|
|
else {
|
109 |
|
|
$rids = implode(',', $roles);
|
110 |
|
|
// Avoid sending emails to members of two or more target role groups.
|
111 |
|
|
$result = db_query('SELECT DISTINCT u.mail FROM {users} u INNER JOIN {users_roles} r ON u.uid = r.uid WHERE r.rid IN ('. $rids .')');
|
112 |
|
|
}
|
113 |
|
|
|
114 |
|
|
// Now, actually send the mails.
|
115 |
|
|
$params = array(
|
116 |
|
|
'subject' => $subject,
|
117 |
|
|
'message' => $message,
|
118 |
|
|
);
|
119 |
|
|
// Set a unique key for this mail.
|
120 |
|
|
$name = isset($element->root()->name) ? $element->root()->name : 'unnamed';
|
121 |
|
|
$key = 'rules_action_mail_to_users_of_role_' . $name . '_' . $element->elementId(); $languages = language_list();
|
122 |
|
|
|
123 |
|
|
$message = array('result' => TRUE);
|
124 |
|
|
foreach ($result as $row) {
|
125 |
|
|
$message = drupal_mail('rules', $key, $row->mail, language_default(), $params, $from);
|
126 |
|
|
// If $message['result'] is FALSE, then it's likely that email sending is
|
127 |
|
|
// failing at the moment, and we should just abort sending any more. If
|
128 |
|
|
// however, $mesage['result'] is NULL, then it's likely that a module has
|
129 |
|
|
// aborted sending this particular email to this particular user, and we
|
130 |
|
|
// should just keep on sending emails to the other users.
|
131 |
|
|
// For more information on the result value, see drupal_mail().
|
132 |
|
|
if ($message['result'] === FALSE) {
|
133 |
|
|
break;
|
134 |
|
|
}
|
135 |
|
|
}
|
136 |
|
|
if ($message['result'] !== FALSE) {
|
137 |
|
|
$role_names = array_intersect_key(user_roles(TRUE), array_flip($roles));
|
138 |
|
|
watchdog('rules', 'Successfully sent email to the role(s) %roles.', array('%roles' => implode(', ', $role_names)));
|
139 |
|
|
}
|
140 |
|
|
}
|
141 |
|
|
|
142 |
|
|
/**
|
143 |
|
|
* Implements hook_mail().
|
144 |
|
|
*
|
145 |
|
|
* Set's the message subject and body as configured.
|
146 |
|
|
*/
|
147 |
|
|
function rules_mail($key, &$message, $params) {
|
148 |
|
|
|
149 |
|
|
$message['subject'] .= str_replace(array("\r", "\n"), '', $params['subject']);
|
150 |
|
|
$message['body'][] = $params['message'];
|
151 |
|
|
}
|
152 |
|
|
|
153 |
76e2e7c3
|
Assos Assos
|
/**
|
154 |
|
|
* Action: Block an IP address.
|
155 |
|
|
*/
|
156 |
|
|
function rules_action_block_ip($ip_address = NULL) {
|
157 |
|
|
if (empty($ip_address)) {
|
158 |
|
|
$ip_address = ip_address();
|
159 |
|
|
}
|
160 |
|
|
db_insert('blocked_ips')->fields(array('ip' => $ip_address))->execute();
|
161 |
|
|
watchdog('rules', 'Banned IP address %ip', array('%ip' => $ip_address));
|
162 |
|
|
}
|
163 |
|
|
|
164 |
85ad3d82
|
Assos Assos
|
/**
|
165 |
|
|
* A class implementing a rules input evaluator processing tokens.
|
166 |
|
|
*/
|
167 |
|
|
class RulesTokenEvaluator extends RulesDataInputEvaluator {
|
168 |
|
|
|
169 |
|
|
public function prepare($text, $var_info) {
|
170 |
|
|
$text = is_array($text) ? implode('', $text) : $text;
|
171 |
|
|
// Skip this evaluator if there are no tokens.
|
172 |
|
|
$this->setting = token_scan($text) ? TRUE : NULL;
|
173 |
|
|
}
|
174 |
|
|
|
175 |
|
|
/**
|
176 |
|
|
* We replace the tokens on our own as we cannot use token_replace(), because
|
177 |
|
|
* token usually assumes that $data['node'] is a of type node, which doesn't
|
178 |
|
|
* hold in general in our case.
|
179 |
|
|
* So we properly map variable names to variable data types and then run the
|
180 |
|
|
* replacement ourself.
|
181 |
|
|
*/
|
182 |
|
|
public function evaluate($text, $options, RulesState $state) {
|
183 |
|
|
$var_info = $state->varInfo();
|
184 |
|
|
$options += array('sanitize' => FALSE);
|
185 |
|
|
|
186 |
|
|
$replacements = array();
|
187 |
|
|
$data = array();
|
188 |
|
|
// We also support replacing tokens in a list of textual values.
|
189 |
|
|
$whole_text = is_array($text) ? implode('', $text) : $text;
|
190 |
|
|
foreach (token_scan($whole_text) as $var_name => $tokens) {
|
191 |
|
|
$var_name = str_replace('-', '_', $var_name);
|
192 |
|
|
if (isset($var_info[$var_name]) && ($token_type = _rules_system_token_map_type($var_info[$var_name]['type']))) {
|
193 |
|
|
// We have to key $data with the type token uses for the variable.
|
194 |
|
|
$data = rules_unwrap_data(array($token_type => $state->get($var_name)), array($token_type => $var_info[$var_name]));
|
195 |
|
|
$replacements += token_generate($token_type, $tokens, $data, $options);
|
196 |
|
|
}
|
197 |
|
|
else {
|
198 |
|
|
$replacements += token_generate($var_name, $tokens, array(), $options);
|
199 |
|
|
}
|
200 |
|
|
// Remove tokens if no replacement value is found. As token_replace() does
|
201 |
|
|
// if 'clear' is set.
|
202 |
|
|
$replacements += array_fill_keys($tokens, '');
|
203 |
|
|
}
|
204 |
|
|
|
205 |
|
|
// Optionally clean the list of replacement values.
|
206 |
|
|
if (!empty($options['callback']) && function_exists($options['callback'])) {
|
207 |
|
|
$function = $options['callback'];
|
208 |
|
|
$function($replacements, $data, $options);
|
209 |
|
|
}
|
210 |
|
|
|
211 |
|
|
// Actually apply the replacements.
|
212 |
|
|
$tokens = array_keys($replacements);
|
213 |
|
|
$values = array_values($replacements);
|
214 |
|
|
if (is_array($text)) {
|
215 |
|
|
foreach ($text as $i => $text_item) {
|
216 |
|
|
$text[$i] = str_replace($tokens, $values, $text_item);
|
217 |
|
|
}
|
218 |
|
|
return $text;
|
219 |
|
|
}
|
220 |
|
|
return str_replace($tokens, $values, $text);
|
221 |
|
|
}
|
222 |
|
|
|
223 |
|
|
/**
|
224 |
|
|
* Create documentation about the available replacement patterns.
|
225 |
|
|
*
|
226 |
|
|
* @param array $var_info
|
227 |
|
|
* Array with the available variables.
|
228 |
|
|
*
|
229 |
|
|
* @return array
|
230 |
|
|
* Renderable array with the replacement pattern documentation.
|
231 |
|
|
*/
|
232 |
|
|
public static function help($var_info) {
|
233 |
|
|
$render = array(
|
234 |
|
|
'#type' => 'fieldset',
|
235 |
|
|
'#title' => t('Replacement patterns'),
|
236 |
|
|
'#collapsible' => TRUE,
|
237 |
|
|
'#collapsed' => TRUE,
|
238 |
|
|
'#description' => t('Note that token replacements containing chained objects – such as [node:author:uid] – are not listed here, but are still available. The <em>data selection</em> input mode may help you find more complex replacement patterns. See <a href="@url">the online documentation</a> for more information about complex replacement patterns.',
|
239 |
|
|
array('@url' => rules_external_help('chained-tokens'))),
|
240 |
|
|
);
|
241 |
|
|
$token_info = token_info();
|
242 |
|
|
foreach ($var_info as $name => $info) {
|
243 |
|
|
$token_types[$name] = _rules_system_token_map_type($info['type']);
|
244 |
|
|
}
|
245 |
|
|
|
246 |
|
|
foreach ($token_types as $name => $token_type) {
|
247 |
|
|
if (isset($token_info['types'][$token_type])) {
|
248 |
|
|
$render[$name] = array(
|
249 |
|
|
'#theme' => 'table',
|
250 |
|
|
'#header' => array(t('Token'), t('Label'), t('Description')),
|
251 |
|
|
'#prefix' => '<h3>' . t('Replacement patterns for %label', array('%label' => $var_info[$name]['label'])) . '</h3>',
|
252 |
|
|
);
|
253 |
|
|
foreach ($token_info['tokens'][$token_type] as $token => $info) {
|
254 |
|
|
$token = '[' . str_replace('_', '-', $name) . ':' . $token . ']';
|
255 |
|
|
$render[$name]['#rows'][$token] = array(
|
256 |
|
|
check_plain($token),
|
257 |
|
|
check_plain($info['name']),
|
258 |
|
|
check_plain($info['description']),
|
259 |
|
|
);
|
260 |
|
|
}
|
261 |
|
|
}
|
262 |
|
|
}
|
263 |
|
|
return $render;
|
264 |
|
|
}
|
265 |
|
|
}
|
266 |
|
|
|
267 |
|
|
/**
|
268 |
|
|
* Looks for a token type mapping. Defaults to passing through the type.
|
269 |
|
|
*/
|
270 |
|
|
function _rules_system_token_map_type($type) {
|
271 |
|
|
$entity_info = entity_get_info();
|
272 |
|
|
if (isset($entity_info[$type]['token type'])) {
|
273 |
|
|
return $entity_info[$type]['token type'];
|
274 |
|
|
}
|
275 |
|
|
$cache = rules_get_cache();
|
276 |
|
|
if (isset($cache['data_info'][$type]['token type'])) {
|
277 |
|
|
return $cache['data_info'][$type]['token type'];
|
278 |
|
|
}
|
279 |
|
|
return $type;
|
280 |
|
|
}
|
281 |
|
|
|
282 |
|
|
/**
|
283 |
|
|
* @}
|
284 |
|
|
*/ |