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/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' => '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' => 'patterns_publish_pattern',
'access arguments' => array(
'administer patterns',
),
'type' => MENU_CALLBACK,
);
$items['admin/patterns/unpublish'] = array(
'title' => 'Unpublish Pattern',
'page callback' => '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_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($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>',
);
$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_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($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)) {
$link = l('syntax and content', '/admin/patterns/edit/' . $pid);
$errors = implode('<br/> ', _patterns_scan_analyze_patternscan($scan));
$form['invalid'] = array(
'#markup' => t('This pattern is invalid. Please check !stuff before running it.', array(
'!stuff' => $link,
)),
'#prefix' => '<div id="important"><strong>Ooops! </strong>',
'#suffix' => '<p>' . $errors . '</p>',
);
return $form;
}
$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($pid = NULL) {
$pattern = patterns_utils_if_invalid_go_back($pid);
$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');
}
drupal_goto('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!'));
return FALSE;
}
$patterns_details = patterns_parser_get_pattern_details($pattern);
if ($patterns_details === FALSE) {
drupal_set_message(t('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'] = $form_id;
$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;
}