function patterns_execute_pattern in Patterns 5
Same name and namespace in other branches
- 6.2 patterns.module \patterns_execute_pattern()
- 6 patterns.module \patterns_execute_pattern()
2 calls to patterns_execute_pattern()
File
- ./
patterns.module, line 831 - Enables extremely simple adding/removing features to your site with minimal to no configuration
Code
function patterns_execute_pattern($pattern, $reverse = false, $interact = false, $jump = null) {
patterns_load();
set_time_limit(0);
if (!is_object($pattern)) {
$pattern = patterns_get_pattern($pattern);
if (!$pattern) {
return false;
}
}
$errors = $action_list = $identifiers = array();
$error = true;
// Pattern info
$status = $pattern->status;
$title = $pattern->title;
$pid = $pattern->pid;
// From here on out just need the actual pattern data
$pattern = $pattern->pattern;
// Split the pattern up into modules and actions. Submit modules as its
// own pattern programattically.
$modules = $actions = array();
for ($i = 0; $tag = $pattern[$i]; $i++) {
if ($tag['tag'] == 'modules') {
$modules = $tag;
}
else {
if ($tag['tag'] == 'actions') {
$actions = $tag;
unset($actions['tag']);
}
}
}
// If there are no actions or modules, most likely the pattern
// was not created correctly.
if (empty($actions) && empty($modules)) {
drupal_set_message(t('Could not recognize pattern %title, aborting.', array(
'%title' => $title,
)), 'error');
return true;
}
if ($modules && (!$interact || $interact && !$jump)) {
// Make the modules look like a normal pattern so they can be executed
// on their own.
$obj = new stdClass();
$obj->title = t('Enable/disable %title pattern modules', array(
'%title' => $title,
));
$obj->status = $status;
$obj->pattern = array(
array(
'tag' => 'actions',
$modules,
),
);
$modules = $obj;
// Modules need to be enabled first so the rest of the pattern
// can proceed smoothly.
if (!$reverse) {
$error = patterns_execute_pattern($modules, $reverse, $interact);
module_rebuild_cache();
}
}
// Keep a list of what modules handle what tags
$tag_modules = patterns_invoke($empty, 'tag modules');
// If an interactive pattern needs resuming, remove the
// already executed actions
if ($interact && $jump > 0) {
array_splice($actions, 0, $jump);
}
// Prepare actions for validation/processing
foreach ($actions as $key => $data) {
patterns_invoke($actions[$key], 'prepare');
}
// Reverse a pattern for disabling
if ($reverse && $status) {
$actions = array_reverse($actions);
foreach ($actions as $key => $data) {
$continue = patterns_invoke($data, 'reverse');
if ($continue === false) {
drupal_set_message(t('[Error] Disabling of this pattern is not supported at this time.'));
return false;
}
$actions[$key] = $data;
}
}
// Pre validate tags with their appropriate components
foreach ($actions as $key => $data) {
if (!array_key_exists($data['tag'], $tag_modules)) {
$errors[$data['tag']][] = t('Invalid Pattern: <%tag> is not a valid tag', array(
'%tag' => $data['tag'],
));
}
else {
$error = patterns_invoke($data, 'pre-validate');
if ($error) {
$errors[$data['tag']][] = t('Invalid Pattern: !msg', array(
'!msg' => $error,
));
}
}
}
if (count($errors)) {
foreach ($errors as $error) {
drupal_set_message(implode('<br>', $error), 'error');
}
return;
}
// Build and execute a list of actions
foreach ($actions as $key => $data) {
// Prepare actions for processing, ensure smooth pattern executions, and return form ids for execution
$return = patterns_invoke($data, 'form_id');
// If prepare removed the data, dont continue with this action
if (!$data || !$return) {
continue;
}
if (is_string($return)) {
$form_ids = array(
$return,
);
}
else {
if ($return) {
$form_ids = $return;
}
}
// Build the action
foreach ($form_ids as $form_id) {
$clone = $data;
$error = patterns_invoke($clone, 'validate', $form_id);
if ($error) {
if (is_array($error)) {
foreach ($error as $msg) {
drupal_set_message($msg, 'error');
}
$errors[$clone['tag']] = t('Broken Pattern: %msg', array(
'%msg' => implode('<br>', $error),
));
}
else {
drupal_set_message($error, 'error');
$errors[$clone['tag']] = t('Broken Pattern: %msg', array(
'%msg' => $error,
));
}
return;
}
// If tokens are enabled, apply tokens to the action values
// before processing
if (module_exists('token')) {
_patterns_recurse_tokens($clone, $identifiers);
//array_walk($clone, '_patterns_replace_tokens', $identifiers);
}
// Get the form data for the action
$values = patterns_invoke($clone, 'build', $form_id);
// Dont execute the action if a string was returned, indicating the pattern component
// most likely handled the action on its own and this is the message to display.
if (is_string($values)) {
drupal_set_message($values);
}
else {
// Get any extra parameters required for the action
$params = patterns_invoke($clone, 'params', $form_id, $values);
if (isset($params) && !is_array($params)) {
$params = array(
$params,
);
}
// Execute action
patterns_execute_action($form_id, $values, $params);
if (form_get_errors()) {
$descriptions = patterns_invoke($clone, 'actions');
drupal_set_message(t('An error occured running action #%num (%action)', array(
'%num' => $key + 1,
'%action' => $descriptions[$form_id],
)), 'error');
$error = true;
break;
}
}
patterns_invoke($clone, 'cleanup', $form_id);
// Clear the cache in case it causes problems
cache_clear_all();
}
if ($error) {
break;
}
// Get any primary identifiers from the action for further actions to take advantage of
$id = null;
$id = patterns_invoke($clone, 'identifier', $form_id);
if (isset($id)) {
$identifiers[$key + 1] = $id;
}
}
if (empty($errors)) {
if ($reverse) {
if ($modules) {
// Modules need to be disabled last so the rest of the pattern
// can reverse itself properly
$error = patterns_execute_pattern($modules, $reverse, $interact);
}
// Mark pattern as disabled
if ($pid) {
db_query('UPDATE {patterns} SET status = 0 WHERE pid = %d', $pid);
}
drupal_set_message(t('Pattern reversed successfully.'));
}
else {
// Mark pattern as enabled
if ($pid) {
db_query('UPDATE {patterns} SET status = 1, enabled = "%s" WHERE pid = %d', time(), $pid);
}
drupal_set_message(t('Pattern ran successfully.'));
}
}
return !$error;
}