View source
<?php
module_load_include('inc', 'patterns', 'includes/variables');
module_load_include('inc', 'patterns', 'includes/config');
module_load_include('inc', 'patterns', 'includes/path');
module_load_include('inc', 'patterns', 'includes/utils');
module_load_include('inc', 'patterns', 'includes/tagmodules');
module_load_include('inc', 'patterns', 'includes/db');
module_load_include('inc', 'patterns', 'includes/error');
module_load_include('inc', 'patterns', 'includes/forms/forms');
module_load_include('inc', 'patterns', 'includes/parser/parser');
module_load_include('inc', 'patterns', 'includes/history');
module_load_include('inc', 'patterns', 'includes/io/io');
module_load_include('inc', 'patterns', 'includes/io/import');
module_load_include('inc', 'patterns', 'includes/io/download');
module_load_include('inc', 'patterns', 'includes/api/api');
module_load_include('inc', 'patterns', 'theme/theme');
module_load_include('inc', 'patterns', 'includes/feed');
module_load_include('inc', 'patterns', 'includes/servers');
module_load_include('inc', 'patterns', 'includes/forms/first_install');
function patterns_menu() {
$items = array();
$first_install = variable_get(PATTERNS_FIRST_INSTALL, TRUE);
if ($first_install) {
module_load_include('inc', 'patterns', 'includes/forms/first_install');
$items['admin/patterns'] = array(
'title' => 'Patterns',
'description' => 'Patterns was just installed or important updates have been found',
'page callback' => 'patterns_first_install_page',
'access arguments' => array(
'administer patterns',
),
);
return $items;
}
$items['admin/patterns'] = array(
'title' => 'Patterns',
'description' => 'Administer patterns available for your site',
'page callback' => 'patterns_list',
'access arguments' => array(
'administer patterns',
),
);
$items['admin/patterns/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
if (patterns_utils_is_public_page_enabled()) {
$items[variable_get('patterns_public_url', '')] = array(
'title' => 'Public',
'type' => MENU_LOCAL_TASK,
'description' => 'Patterns',
'page callback' => 'patterns_list_public',
'access arguments' => array(
'public patterns',
),
'weight' => -9,
);
}
$items['admin/patterns/enable'] = array(
'title' => 'Enable Pattern',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_enable_pattern',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/edit/%'] = array(
'title' => 'Edit Pattern',
'page callback' => 'patterns_edit_page',
'page arguments' => array(
3,
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/quickrun'] = array(
'title' => 'Quick Run',
'page callback' => 'patterns_editor',
'page arguments' => array(
'patterns_quickrun',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/lab'] = array(
'title' => 'Lab',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_lab',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_LOCAL_TASK,
);
$items['admin/patterns/create/%'] = array(
'title' => 'Create a new Pattern',
'page callback' => 'patterns_editor_create_page',
'page arguments' => array(
3,
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/settings'] = array(
'title' => 'Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_config_settings',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
);
$items['admin/patterns/trash'] = array(
'title' => 'Move Pattern to Recycle Bin',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_trash_pattern',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/restore'] = array(
'title' => 'Restore a pattern from the recycle bin',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_restore_pattern',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/remove'] = array(
'title' => 'Remove Pattern',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_remove_pattern',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/refresh'] = array(
'title' => 'Refresh Patterns',
'page callback' => 'patterns_io_get_patterns_service',
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/validate'] = array(
'title' => 'Validate Pattern YAML Source',
'page callback' => 'patterns_validate_service',
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['patterns/patterns.xml'] = array(
'title' => 'Published Patterns',
'page callback' => 'patterns_feed',
'access arguments' => array(
'get patterns',
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['patterns/get'] = array(
'title' => 'Download Pattern Source',
'page callback' => 'patterns_io_get_pattern_service',
'access arguments' => array(
'get patterns',
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['admin/patterns/import'] = array(
'title' => 'Import',
'page callback' => 'patterns_editor',
'page arguments' => array(
'patterns_import_source',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_LOCAL_TASK,
);
$items['admin/patterns/import/source'] = array(
'title' => 'Import Source Code',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/patterns/import/file'] = array(
'title' => 'Import File',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_import_file',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_LOCAL_TASK,
);
$items['admin/patterns/import/url'] = array(
'title' => 'Import from URL',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_import_url',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_LOCAL_TASK,
);
$items['admin/patterns/publish'] = array(
'title' => 'Publish Pattern',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_publish_pattern',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/unpublish'] = array(
'title' => 'Unpublish Pattern',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'patterns_unpublish_pattern',
),
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/info'] = array(
'title' => 'Info',
'page callback' => 'patterns_info_page',
'access arguments' => array(
'administer patterns',
),
'weight' => 15,
'type' => MENU_LOCAL_TASK,
);
$items['admin/patterns/check'] = array(
'title' => 'Pattern Modules',
'page callback' => 'patterns_modules_page',
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
return $items;
}
function patterns_libraries_info() {
$libraries = array();
$libraries['codemirror'] = array(
'name' => 'codemirror',
'vendor url' => 'http://codemirror.net/',
'download url' => 'https://github.com/marijnh/CodeMirror/',
'version arguments' => array(
'file' => 'package.json',
'pattern' => '@"version":"([0-9a-zA-Z\\.-]+)"@',
),
'files' => array(
'js' => array(
'lib/codemirror.js',
'addon/search/search.js',
'addon/search/searchcursor.js',
'addon/dialog/dialog.js',
'addon/mode/loadmode.js',
'mode/yaml/yaml.js',
'mode/xml/xml.js',
'mode/php/php.js',
),
'css' => array(
'lib/codemirror.css',
'theme/default.css',
'addon/dialog/dialog.css',
),
),
);
return $libraries;
}
function patterns_list() {
$form = array();
if (!patterns_engine_is_on()) {
$settings = l(t('settings'), 'admin/patterns/settings');
drupal_set_message(check_plain(t('Patterns engine is off. You can change the state of the engine from the !settings page.', array(
'!settings' => $settings,
))), 'warning');
}
if (!patterns_parser_ready()) {
$messages = t('No available patterns parser was found.</br>');
$messages .= t('Go to the !modules page to enable more Patterns parsers.', array(
'!modules' => l(t('modules'), 'admin/modules'),
));
drupal_set_message(check_plain($messages), 'warning');
}
drupal_add_js('misc/ajax.js');
drupal_add_css(drupal_get_path('module', 'patterns') . '/css/patterns.css');
drupal_add_js(drupal_get_path('module', 'patterns') . '/js/patterns.js');
$form['commands'] = array(
'#type' => 'fieldset',
'#title' => 'Commands',
);
$form['commands']['refresh'] = array(
'#type' => 'button',
'#value' => t('Refresh All'),
'#attributes' => array(
'style' => 'float:right',
'id' => 'refresh-all',
),
);
$form['commands']['create'] = array(
'#type' => 'button',
'#value' => t('Create New'),
'#attributes' => array(
'style' => 'float:right',
),
'#prefix' => '<a href="' . url('admin/patterns/import') . '">',
'#suffix' => '</a>',
);
if (patterns_engine_is_on()) {
$form['commands']['quickrun'] = array(
'#type' => 'button',
'#value' => t('Quick Run'),
'#attributes' => array(
'style' => 'float:right',
),
'#prefix' => '<a href="' . url('admin/patterns/quickrun') . '">',
'#suffix' => '</a>',
);
}
$output = drupal_render($form);
if (variable_get('patterns_refresh_components', TRUE)) {
patterns_io_load_components();
}
$patterns = patterns_io_get_patterns(variable_get('patterns_refresh_from_fs', TRUE));
$output .= theme('patterns_list', $patterns);
return $output;
}
function patterns_list_public() {
drupal_add_css(drupal_get_path('module', 'patterns') . '/css/patterns.css');
drupal_add_js(drupal_get_path('module', 'patterns') . '/js/patterns.js');
$patterns = patterns_io_get_public_patterns(variable_get('patterns_refresh_from_fs', TRUE), FALSE);
$output = theme('patterns_list', $patterns);
return $output;
}
function patterns_enable_pattern($form, &$form_state, $pid) {
$form = array();
if (!patterns_engine_is_on()) {
drupal_set_message(t('Patterns engine is off. You can change the state of the engine from the settings page if you want to execute the pattern. This attempt has been logged.'), 'warning');
watchdog('patterns', 'Attempt to run a pattern with engine off.');
drupal_goto('admin/patterns');
return $form;
}
if (!patterns_parser_ready()) {
$messages = t('No available patterns parser was found.</br>');
$messages .= t('Go to the !modules page to enable more Patterns parsers.', array(
'!modules' => l(t('modules'), 'admin/modules'),
));
drupal_set_message(check_plain($messages), 'warning');
return $form;
}
$pattern = patterns_utils_if_invalid_go_back($pid);
if (patterns_db_is_pattern_updated($pid)) {
$form['modified'] = array(
'#markup' => t('A more recent version of this pattern was found in the file system. The version stored in the database is going to be executed. If unsure,') . ' ' . l(t('click here to check it out.'), 'admin/patterns/edit/' . $pid),
'#prefix' => '<div id="important"><strong>',
'#suffix' => '</strong></br></br></div>',
);
}
$scan = patterns_scan_pattern($pattern->pattern);
if (!_patterns_scan_validate_patternscan($scan, TRUE, PATTERNS_VALIDATE_ALL, TRUE)) {
$link = l(t('syntax and content'), '/admin/patterns/edit/' . $pid);
$form['invalid'] = array(
'#markup' => t('This pattern did not pass the validation. This may be due to an error in the pattern itself, or to the current configuration of your database. If you are trying to run interdependent actions in the same pattern (E.g. creating a vocabulary and then adding a term) this could be normal.'),
'#prefix' => '<div id="important"><strong>Ooops! </strong>',
);
}
$form['pid'] = array(
'#type' => 'value',
'#value' => $pid,
);
$form = patterns_forms_get_execution_options($form);
$disclaimer = t('Please be sure to backup your site before running a pattern. Patterns are not guaranteed to be reversible in case they do not execute well or if unforeseen side effects occur.');
return confirm_form($form, t('Proceed with running pattern %pattern?', array(
'%pattern' => $pattern->title,
)), 'admin/patterns', $disclaimer);
}
function patterns_enable_pattern_validate($form, &$form_state) {
if (!in_array($form_state['values']['mode'], array(
PATTERNS_EXEC_BATCH,
PATTERNS_EXEC_PHP,
))) {
form_error($element, t('Mode must be one of \'batch\' or \'php\'.'));
}
return TRUE;
}
function patterns_enable_pattern_submit($form, &$form_state) {
$pid = $form_state['values']['pid'];
patterns_io_load_components();
$pattern = patterns_get_pattern($pid);
patterns_start_engine($pattern, $form_state['values'], $form_state['values']['mode']);
$form_state['redirect'] = 'admin/patterns';
}
function patterns_restore_pattern($form, &$form_state, $pid = NULL) {
$pattern = patterns_utils_if_invalid_go_back($pid);
$form['pid'] = array(
'#type' => 'value',
'#value' => $pid,
);
$form['name'] = array(
'#type' => 'value',
'#value' => @$pattern->name,
);
$disclaimer = t('Restored patterns can be trashed again later on.');
return confirm_form($form, t('Proceed with restoring pattern %pattern from the trash bin?', array(
'%pattern' => $pattern->title,
)), 'admin/patterns', $disclaimer);
}
function patterns_restore_pattern_submit($form, &$form_state) {
$pid = $form_state['values']['pid'];
$name = $form_state['values']['name'];
$result = patterns_db_restore_pattern($pid);
$params = array(
'%name' => @$pattern->name,
);
if ($result) {
drupal_set_message(t('Pattern %name was correctly restored from the trash bin.', $params));
}
else {
drupal_set_message(t('An error occurred. Patterns was unable to restore pattern %name from the trash bin.', $params), 'error');
}
$form_state['redirect'] = 'admin/patterns';
}
function patterns_trash_pattern($form, &$form_state, $pid = NULL) {
$pattern = patterns_utils_if_invalid_go_back($pid);
$form['pid'] = array(
'#type' => 'value',
'#value' => $pid,
);
$form['name'] = array(
'#type' => 'value',
'#value' => @$pattern->name,
);
$disclaimer = t('Trashed patterns can be restored later on.');
return confirm_form($form, t('Proceed with moving pattern %pattern into the trash bin?', array(
'%pattern' => $pattern->title,
)), 'admin/patterns', $disclaimer);
}
function patterns_trash_pattern_submit($form, &$form_state) {
$pid = $form_state['values']['pid'];
$name = $form_state['values']['name'];
$id = !empty($name) ? $name : $pid;
$result = patterns_db_trash_pattern($pid);
if (!$result) {
drupal_set_message(t('Pattern %id could not be moved into the trash bin.', array(
'%id' => $id,
)), 'error');
}
else {
drupal_set_message(t('Pattern %id successfully moved into the trash bin.', array(
'%id' => $id,
)), 'status');
}
$form_state['redirect'] = 'admin/patterns';
}
function patterns_remove_pattern($form, &$form_state, $pid = NULL) {
$pattern = patterns_utils_if_invalid_go_back($pid);
$form['pid'] = array(
'#type' => 'value',
'#value' => $pid,
);
$form['name'] = array(
'#type' => 'value',
'#value' => @$pattern->name,
);
$disclaimer = t('This operation cannot be undone. Are you sure?');
return confirm_form($form, t('Proceed with removing pattern %pattern?', array(
'%pattern' => $pattern->title,
)), 'admin/patterns', $disclaimer);
}
function patterns_remove_pattern_submit($form, &$form_state) {
$pid = $form_state['values']['pid'];
$name = $form_state['values']['name'];
$id = !empty($name) ? $name : $pid;
$result = patterns_io_remove_pattern($pid, TRUE);
$form_state['redirect'] = 'admin/patterns';
}
function patterns_start_engine($pattern, $params = array(), $mode = 'batch') {
module_load_include('inc', 'patterns', 'includes/core/common');
module_load_include('inc', 'patterns', 'includes/core/modules');
module_load_include('inc', 'patterns', 'includes/core/token');
module_load_include('inc', 'patterns', 'includes/core/' . $mode);
if (empty($pattern)) {
drupal_set_message(t('The pattern seems empty...I cannot run it!'), 'error');
return FALSE;
}
if (!patterns_engine_is_on()) {
drupal_set_message(t('Patterns engine is off. You can change the state of the engine from the settings page if you want to execute the pattern. This attempt has been logged.'), 'warning');
watchdog('patterns', 'Attempt to run a pattern with engine off.');
return FALSE;
}
$patterns_details = patterns_parser_get_pattern_details($pattern, PATTERNS_VALIDATE_TAG_EXISTS);
if ($patterns_details === FALSE) {
drupal_set_message(t('Fatal errors where found in the pattern. Aborting.'), 'error');
return FALSE;
}
$pid = key($patterns_details);
$pattern_details = current($patterns_details);
$info = $pattern_details['info'];
$infos = array(
$pid => $info,
);
$modules = $pattern_details['modules'];
$installed_modules = patterns_install_modules($modules);
if (!$installed_modules['success']) {
drupal_set_message($installed_modules['error_message'], 'error');
return FALSE;
}
$sections = $pattern_details['sections'];
if (!isset($params['quickrun']) || !$params['quickrun']) {
if (!is_object($pattern)) {
$pattern = patterns_get_pattern($pattern);
if (!$pattern) {
return FALSE;
}
}
}
if (isset($params['run-subpatterns'])) {
$pattern->subpatterns_run_mode = $params['run-subpatterns'];
}
$actions_map = array(
'patterns' => $infos,
'map' => NULL,
);
drupal_set_time_limit(0);
$fun = 'patterns_execute_pattern_' . $mode;
$fun($pattern, $params, $patterns_details, $actions_map);
if (!empty($installed_modules['installed'])) {
patterns_disable_modules($installed_modules['installed']);
}
return TRUE;
}
function patterns_invoke($hook, $action, &$data = NULL, $form_id = NULL, &$extra = NULL) {
$tag_modules = patterns_tagmodules_get_index($data);
$tag = $data['tag'];
unset($data['tag']);
if (isset($tag_modules[$tag])) {
$module = $tag_modules[$tag]['module'];
$func = $module . '_patterns_' . $hook;
if (function_exists($func)) {
if ($form_id) {
$return = $func($action, $form_id, $data, $extra);
}
else {
$return = $func($action, $tag, $data, $extra);
}
}
else {
$msg = t('Function %func not found. Hook %hook skipped', array(
'%func' => $func,
'%hook' => $hook,
));
$return = patterns_results(PATTERNS_SUCCESS, $msg);
}
}
else {
$msg = t('Required patterns tag %tag is not provided by any component.', array(
'%tag' => $tag,
));
$return = patterns_results(PATTERNS_ERR, $msg);
}
if (!_patterns_is_patterns_results($return)) {
if ($return === TRUE) {
$return = array(
'status' => PATTERNS_SUCCESS,
);
}
elseif ($return === FALSE) {
$msg = t('Unspecified error occurred in %func.', array(
'%func' => $func,
));
$return = patterns_results(PATTERNS_ERR, $msg);
}
else {
$msg = t('The return value of %func is not properly formatted.', array(
'%func' => $func,
));
$return = patterns_results(PATTERNS_ERR, $msg);
}
}
$return['details']['action'] = $action;
$return['details']['hook'] = $hook;
$return['details']['function'] = $func;
$data['tag'] = $tag;
return $return;
}
function patterns_get_pattern_obj($pattern = array()) {
$pattern = is_object($pattern) ? $pattern : (object) $pattern;
$defaults = array(
'pid' => '',
'name' => '',
'status' => 0,
'public' => 0,
'updated' => '',
'enabled' => '',
'title' => t('New Pattern'),
'pattern' => '',
);
foreach ($defaults as $key => $value) {
if (!isset($pattern->{$key})) {
$pattern->{$key} = $value;
}
}
return $pattern;
}
function patterns_get_include_mode($mode = NULL) {
if (!is_null($mode)) {
if (patterns_parser_is_valid_include_mode($mode)) {
return $mode;
}
}
$mode = variable_get('patterns_default_include_mode', PATTERNS_INCLUDE_NEVER);
if (!patterns_parser_is_valid_include_mode($mode)) {
$mode = PATTERNS_INCLUDE_NEVER;
}
return $mode;
}
function patterns_install_modules_in_pattern($pattern) {
$pattern = _patterns_db_get_pattern_array($pattern);
if (!$pattern) {
return FALSE;
}
$modules = patterns_parser_extract_modules($pattern);
$results = patterns_install_modules($modules);
if (!$results['success']) {
drupal_set_message($results['error_message'], 'error');
return FALSE;
}
return TRUE;
}
function patterns_engine_is_on() {
return variable_get('patterns_engine_state', 'off') === 'on';
}