Commit e6e2712d authored by Amit Asaravala's avatar Amit Asaravala
Browse files

by aasarava: updated to Drupal 6

parent 38abff40
......@@ -90,6 +90,12 @@ See INSTALL.txt for installation and administration instructions.
VII. CREDITS:
Version 6.x-dev by:
- Amit Asaravala
Drupal username: aasarava
http://www.returncontrol.com
amit [at] returncontrol.com
Version 5.x-2.0 by:
- Amit Asaravala
Drupal username: aasarava
......
......@@ -2,3 +2,5 @@
name = Scanner
description = Do Search and Replace on the content of nodes.
core = 6.x
\ No newline at end of file
......@@ -6,42 +6,75 @@
* Search and Replace Scanner install - creates necessary tables.
*/
/**
* Implementation of hook_schema().
*/
function scanner_schema() {
$schema['scanner'] = array(
'description' => t('Holds info on recent replacements in case undo is needed.'),
'fields' => array(
'undo_id' => array(
'description' => t('Row identifier'),
'type' => 'serial',
'not null' => TRUE,
),
'undo_data' => array(
'description' => t('What was changed'),
'type' => 'text',
'size' => 'big',
'not null' => TRUE,
),
'undone' => array(
'description' => t('Whether the replacement has been undone'),
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
),
'searched' => array(
'description' => t('Text that was searched for'),
'type' => 'varchar',
'length' => 256,
'not null' => TRUE,
),
'replaced' => array(
'description' => t('Text that was used as replacement'),
'type' => 'varchar',
'length' => 256,
'not null' => TRUE,
),
'count' => array(
'description' => t('How many fields were modified on replacement'),
'type' => 'int',
'not null' => TRUE,
),
'time' => array(
'description' => t('How long the replacement took'),
'type' => 'int',
'not null' => TRUE,
),
),
'primary key' => array('undo_id'),
);
return $schema;
}
/**
* Implementation of hook_install().
*/
function scanner_install() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'mysqli':
case 'mysql':
$ret[] = db_query("
CREATE TABLE {scanner} (
undo_id int(11) NOT NULL,
undo_data longtext NOT NULL,
undone tinyint(4) NOT NULL,
searched varchar(256) NOT NULL,
replaced varchar(256) NOT NULL,
count int(11) NOT NULL,
time int(11) NOT NULL,
PRIMARY KEY (undo_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;");
break;
}
if (!in_array(false, $ret)) {
drupal_set_message(t('Scanner module installed successfully.'));
}
else {
drupal_set_message(t('The installation of the scanner module was unsuccessful due to a database error. You may have to install the tables by hand.'), 'error');
}
// Create tables.
drupal_install_schema('scanner');
}
/**
* Implementation of hook_uninstall().
*/
function scanner_uninstall() {
db_query('DROP TABLE {scanner}');
// Remove tables.
drupal_uninstall_schema('scanner');
db_query("DELETE FROM {variable} WHERE name LIKE 'scanner_%'");
}
......@@ -57,66 +57,87 @@ define('SCANNER_STATUS_GO_REPLACE', 3);
/**
* Implementation of hook_menu().
*/
function scanner_menu($may_cache) {
global $user;
$items = array();
function scanner_menu() {
if ($may_cache) {
$items[] = array(
'path' => 'admin/content/scanner',
'title' => t('Search and Replace Scanner'),
'callback' => 'scanner_view',
'access' => user_access('perform search and replace'),
$items['admin/content/scanner'] = array(
'title' => 'Search and Replace Scanner',
'description' => t('Find (and replace) keywords in all your content.'),
'page callback' => 'scanner_view',
'access arguments' => array('perform search and replace'),
);
$items[] = array(
'path' => 'admin/content/scanner/scan',
$items['admin/content/scanner/scan'] = array(
'title' => t('Search'),
'access' => user_access('perform search and replace'),
'access arguments' => array('perform search and replace'),
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/content/scanner/scan/confirm',
$items['admin/content/scanner/scan/confirm'] = array(
'title' => t('Confirm Replace'),
'access' => user_access('perform search and replace'),
'callback' => 'drupal_get_form',
'callback arguments' => array('scanner_confirm_form'),
'access arguments' => array('perform search and replace'),
'page callback' => 'drupal_get_form',
'page arguments' => array('scanner_confirm_form'),
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => 'admin/content/scanner/undo/confirm',
$items['admin/content/scanner/undo/confirm'] = array(
'title' => t('Confirm Undo'),
'access' => user_access('perform search and replace'),
'callback' => 'drupal_get_form',
'callback arguments' => array('scanner_undo_confirm_form'),
'access arguments' => array('perform search and replace'),
'page callback' => 'drupal_get_form',
'page arguments' => array('scanner_undo_confirm_form'),
'type' => MENU_CALLBACK,
);
$items[] = array( // Shows up on scanner page as tab.
'path' => 'admin/content/scanner/settings',
'callback' => 'drupal_get_form',
'callback arguments' => array('scanner_admin_form'),
'access' => user_access('administer scanner settings'),
'type' => MENU_LOCAL_TASK,
$items['admin/content/scanner/settings'] = array( // Shows up on scanner page as tab.
'title' => t('Settings'),
'page callback' => 'drupal_get_form',
'page arguments' => array('scanner_admin_form'),
'access arguments' => array('administer scanner settings'),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items[] = array( // Shows up on scanner page as tab.
'path' => 'admin/content/scanner/undo',
'callback' => 'scanner_undo_page',
'access' => user_access('perform search and replace'),
'type' => MENU_LOCAL_TASK,
$items['admin/content/scanner/undo'] = array( // Shows up on scanner page as tab.
'title' => t('Undo'),
'page callback' => 'scanner_undo_page',
'access arguments' => array('perform search and replace'),
'type' => MENU_LOCAL_TASK,
);
$items[] = array( // Shows up on admin page.
'path' => 'admin/settings/scanner',
'callback' => 'drupal_get_form',
'callback arguments' => array('scanner_admin_form'),
'access' => user_access('administer scanner settings'),
$items['admin/settings/scanner'] = array( // Shows up on admin page.
'title' => t('Search and Replace Scanner'),
'description' => t('Configure defaults and what fields can be searched and replaced.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('scanner_admin_form'),
'access arguments' => array('administer scanner settings'),
);
}
return $items;
}
function scanner_theme() {
return array(
'scanner_results' => array(
'file' => 'scanner.module',
'arguments' => array(
'results' => NULL,
),
),
'scanner_item' => array(
'file' => 'scanner.module',
'arguments' => array(
'item' => NULL,
),
),
'scanner_replace_results' => array(
'file' => 'scanner.module',
'arguments' => array(
'results' => NULL,
),
),
'scanner_replace_item' => array(
'file' => 'scanner.module',
'arguments' => array(
'item' => NULL,
),
),
);
}
/**
* Implementation of hook_perm().
*/
......@@ -210,7 +231,7 @@ function scanner_view() {
* @param str $replace - string to substitute.
* @return $form
*/
function scanner_form() {
function scanner_form(&$form_state) {
$form = array();
$search = $_SESSION['scanner_search'];
......@@ -355,8 +376,8 @@ function scanner_form() {
/**
* Validate form input.
*/
function scanner_form_validate($form_id, $form_values) {
$search = trim($form_values['search']);
function scanner_form_validate($form, &$form_state) {
$search = trim($form_state['values']['search']);
if ($search == '') {
form_set_error('search', t('Please enter some keywords.'));
}
......@@ -365,32 +386,37 @@ function scanner_form_validate($form_id, $form_values) {
/**
* Handles submission of the search and replace form.
*
* @param $form_id
* @param $form_values
* @param $form
* @param $form_state
* @return the new path that will be goto'ed.
*/
function scanner_form_submit($form_id, $form_values) {
function scanner_form_submit($form, &$form_state) {
//save form input:
$_SESSION['scanner_search'] = $form_values['search'];
$_SESSION['scanner_preceded'] = $form_values['preceded'];
//$_SESSION['scanner_notpreceded'] = $form_values['notpreceded'];
$_SESSION['scanner_followed'] = $form_values['followed'];
//$_SESSION['scanner_notfollowed'] = $form_values['notfollowed'];
$_SESSION['scanner_mode'] = $form_values['mode'];
$_SESSION['scanner_wholeword'] = $form_values['wholeword'];
$_SESSION['scanner_published'] = $form_values['published'];
$_SESSION['scanner_regex'] = $form_values['regex'];
$_SESSION['scanner_terms'] = array_filter($form_values['terms']);
$_SESSION['scanner_replace'] = $form_values['replace'];
if ($form_values['op'] == 'Replace') {
$_SESSION['scanner_search'] = $form_state['values']['search'];
$_SESSION['scanner_preceded'] = $form_state['values']['preceded'];
//$_SESSION['scanner_notpreceded'] = $form_state['values']['notpreceded'];
$_SESSION['scanner_followed'] = $form_state['values']['followed'];
//$_SESSION['scanner_notfollowed'] = $form_state['values']['notfollowed'];
$_SESSION['scanner_mode'] = $form_state['values']['mode'];
$_SESSION['scanner_wholeword'] = $form_state['values']['wholeword'];
$_SESSION['scanner_published'] = $form_state['values']['published'];
$_SESSION['scanner_regex'] = $form_state['values']['regex'];
$_SESSION['scanner_terms'] = $form_state['values']['terms'];
$_SESSION['scanner_replace'] = $form_state['values']['replace'];
/* TODO The 'op' element in the form values is deprecated.
Each button can have #validate and #submit functions associated with it.
Thus, there should be one button that submits the form and which invokes
the normal form_id_validate and form_id_submit handlers. Any additional
buttons which need to invoke different validate or submit functionality
should have button-specific functions. */
if ($form_state['values']['op'] == 'Replace') {
$_SESSION['scanner_status'] = SCANNER_STATUS_GO_CONFIRM;
}
else {
$_SESSION['scanner_status'] = SCANNER_STATUS_GO_SEARCH;
}
return 'admin/content/scanner';
$form_state['redirect'] = 'admin/content/scanner';
}
......@@ -399,6 +425,39 @@ function scanner_form_submit($form_id, $form_values) {
* replacing things they don't intend to.
*/
function scanner_confirm_form() {
//using set_html_head because it seems unecessary to load a separate css
// file for just one declaration:
//you can override the styles by declaring with something "higher up"
// the chain, like: #wrapper #scanner-confirm-form .scanner-buttons .scanner-button-msg {...}
drupal_set_html_head('
<style type="text/css">
#scanner-confirm-form .scanner-buttons .scanner-button-msg {
position:absolute;
top:0; left:0; z-index:100;
width:100%; height:100%;
background-color:#000; opacity:0.75;
font-size:1.2em;
}
#scanner-confirm-form .scanner-buttons .scanner-button-msg p {
color:#fff;
}
</style>
');
//javascript to prevent further clicks on confirmation button after it's clicked once.
//unfortunately we can't just use css disable to disable the button because then
// the op values aren't sent to drupal correctly.
drupal_add_js("
$(document).ready(function() {
$('input[@type=submit][@value=Yes, Continue]').click(function() {
$('.scanner-buttons').css('position','relative')
.append('<div class=\"scanner-button-msg\"><p>Replacing items... please wait...</p></div>')
$('.scanner-button-msg').click(function() { return false; });
return true;
});
});
", 'inline');
$form = array();
$search = $_SESSION['scanner_search'];
......@@ -467,10 +526,12 @@ function scanner_confirm_form() {
$form['confirm'] = array(
'#type' => 'submit',
'#value' => t('Yes, Continue'),
'#prefix' => '<div class="scanner-buttons">', //see suffix in cancel button element
);
$form['cancel'] = array(
'#type' => 'submit',
'#value' => t('No, Cancel'),
'#suffix' => '</div>', //see prefix in confirm button element
);
return $form;
......@@ -480,15 +541,21 @@ function scanner_confirm_form() {
/**
* Submission handling for scanner confirmation form.
*/
function scanner_confirm_form_submit($form_id, $form_values) {
if ($form_values['op'] == t('Yes, Continue')) {
function scanner_confirm_form_submit($form, &$form_state) {
/* TODO The 'op' element in the form values is deprecated.
Each button can have #validate and #submit functions associated with it.
Thus, there should be one button that submits the form and which invokes
the normal form_id_validate and form_id_submit handlers. Any additional
buttons which need to invoke different validate or submit functionality
should have button-specific functions. */
if ($form_state['values']['op'] == t('Yes, Continue')) {
$_SESSION['scanner_status'] = SCANNER_STATUS_GO_REPLACE;
}
else {
unset($_SESSION['scanner_status']);
}
return 'admin/content/scanner';
$form_state['redirect'] = 'admin/content/scanner';
}
function scanner_undo_page() {
......@@ -500,10 +567,10 @@ function scanner_undo_page() {
$query = 'undo_id='. $sandr->undo_id;
if ($sandr->undone) {
$operation = l('Redo', 'admin/content/scanner/undo/confirm', array(), $query);
$operation = l('Redo', 'admin/content/scanner/undo/confirm', array('query' => $query));
}
else {
$operation = l('Undo', 'admin/content/scanner/undo/confirm', array(), $query);
$operation = l('Undo', 'admin/content/scanner/undo/confirm', array('query' => $query));
}
$rows[] = array(
......@@ -560,10 +627,16 @@ function scanner_undo_confirm_form() {
return $form;
}
function scanner_undo_confirm_form_submit($form_id, $form) {
function scanner_undo_confirm_form_submit($form, &$form_state) {
if ($form['op'] == t('Yes, Continue')) {
$undo = db_fetch_object(db_query('SELECT undo_data, undone FROM {scanner} WHERE undo_id = %d', $form['undo_id']));
/* TODO The 'op' element in the form values is deprecated.
Each button can have #validate and #submit functions associated with it.
Thus, there should be one button that submits the form and which invokes
the normal form_id_validate and form_id_submit handlers. Any additional
buttons which need to invoke different validate or submit functionality
should have button-specific functions. */
if ($form_state['values']['op'] == t('Yes, Continue')) {
$undo = db_fetch_object(db_query('SELECT undo_data, undone FROM {scanner} WHERE undo_id = %d', $form_state['values']['undo_id']));
$undos = unserialize($undo->undo_data);
......@@ -589,14 +662,15 @@ function scanner_undo_confirm_form_submit($form_id, $form) {
}
drupal_set_message($count .' '. t('Nodes reverted'));
db_query('UPDATE {scanner} SET undone = %d WHERE undo_id = %d', $undone, $form['undo_id']);
db_query('UPDATE {scanner} SET undone = %d WHERE undo_id = %d', $undone, $form_state['values']['undo_id']);
}
else {
drupal_set_message(t('Undo / Redo canceled'));
}
return 'admin/content/scanner/undo';
$form_state['redirect'] = 'admin/content/scanner/undo';
$form_state['nid'] = $node->nid;
}
/**
......@@ -734,16 +808,16 @@ function scanner_execute($searchtype = 'search') {
// checking for possible timeout
// if within 5 seconds of timeout - attempt to expand environment
if (time() >= ($start_time + $max_execution_time - 5)) {
if(!$expanded) {
if (!$expanded) {
if ($user->uid > 0) {
$verbose = TRUE;
}
else {
$verbose = FALSE;
}
if(_scanner_change_env('max_execution_time', '600', $verbose)) {
drupal_set_message(t('Default max_execution_time too small and changed to 10 minutes.'),'error');
$max_execution_time = 600;
if (_scanner_change_env('max_execution_time', '600', $verbose)) {
drupal_set_message(t('Default max_execution_time too small and changed to 10 minutes.'), 'error');
$max_execution_time = 600;
}
$expanded = TRUE;
}
......@@ -752,11 +826,11 @@ function scanner_execute($searchtype = 'search') {
$shutting_down = TRUE;
variable_set('scanner_partially_processed_'. $user->uid, $processed);
variable_set('scanner_partial_undo_'. $user->uid, $undo_data);
if($searchtype == 'search') {
drupal_set_message(t('Did not have enough time to complete search.'),'error');
if ($searchtype == 'search') {
drupal_set_message(t('Did not have enough time to complete search.'), 'error');
}
else {
drupal_set_message(t('Did not have enough time to complete. Please re-submit replace'),'error');
drupal_set_message(t('Did not have enough time to complete. Please re-submit replace'), 'error');
}
break 2;
}
......@@ -848,7 +922,7 @@ function scanner_execute($searchtype = 'search') {
} //end foreach
// if completed
if(!$shutting_down) {
if (!$shutting_down) {
variable_del('scanner_partially_processed_'. $user->uid);
variable_del('scanner_partial_undo_'. $user->uid);
}
......@@ -858,8 +932,7 @@ function scanner_execute($searchtype = 'search') {
}
else { //searchtype == 'replace'
if (count($undo_data) && !$shutting_down) {
$undo_id = db_next_id('{scanner}_undo_id');
db_query('INSERT INTO {scanner} (undo_id, undo_data, undone, searched, replaced, count, time) VALUES (%d, "%s", %d, "%s", "%s", %d, %d)', $undo_id, serialize($undo_data), 0, $search, $replace, count($undo_data), time());
db_query('INSERT INTO {scanner} (undo_data, undone, searched, replaced, count, time) VALUES ("%s", %d, "%s", "%s", %d, %d)', serialize($undo_data), 0, $search, $replace, count($undo_data), time());
}
return theme('scanner_replace_results', $results);
......@@ -1014,21 +1087,25 @@ function _scanner_get_all_tables_map() {
}
//now build list of CCK-based text fields:
$results = db_query("SELECT nfi.field_name, nfi.type_name, nf.db_storage ".
"FROM {node_field_instance} nfi INNER JOIN {node_field} nf USING (field_name) ".
"WHERE nfi.widget_type='text'");
while ($field=db_fetch_array($results)) {
if ( $field['db_storage'] ) {
$table = 'content_type_'. $field['type_name'];
}
else {
$table = 'content_'. $field['field_name'];
}
$tables_map[] = array( // Modify to match current CCK storage rules.
'type' => $field['type_name'],
'field' => $field['field_name'] .'_value',
'table' => $table,
if(module_exists('content')) {
$results = db_query(
"SELECT nfi.field_name, nfi.type_name, nf.db_storage ".
"FROM {content_node_field_instance} nfi INNER JOIN {content_node_field} nf USING (field_name) ".
"WHERE nfi.widget_type IN ('text_textarea', 'text_textfield')"
);
while ($field=db_fetch_array($results)) {
if ( $field['db_storage'] ) {
$table = 'content_type_'. $field['type_name'];
}
else {
$table = 'content_'. $field['field_name'];
}
$tables_map[] = array( // Modify to match current CCK storage rules.
'type' => $field['type_name'],
'field' => $field['field_name'] .'_value',
'table' => $table,
);
}
}
return $tables_map;
}
......@@ -1122,7 +1199,7 @@ function theme_scanner_results($results) {
function theme_scanner_item($item) {
$item['count'] = $item['count'] > 0 ? $item['count'] : 'One or more';
$output .= '<li class="scanner-result">';
$output .= '<span class="scanner-title">'. l($item['title'], 'node/' . $item['nid']) .'</span><br />';
$output .= '<span class="scanner-title">'. l($item['title'], 'node/'. $item['nid']) .'</span><br />';
$output .= '<span class="scanner-info">['. $item['count'] .' matches in '. $item['type'] .' '. $item['field'] .'field:]</span><br />';
$output .= '<span class="scanner-text">'. $item['text'] .'</span>';
$output .= '</li>';
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment