? bot_views
Index: bot_factoid/bot_factoid.admin.inc
===================================================================
RCS file: bot_factoid/bot_factoid.admin.inc
diff -N bot_factoid/bot_factoid.admin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bot_factoid/bot_factoid.admin.inc	19 Dec 2009 08:41:33 -0000
@@ -0,0 +1,131 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Administrative page callbacks for the bot factoid module.
+ */
+
+/**
+ * Configures factoid learning.
+ */
+function bot_factoid_settings() {
+  $form['bot_factoid_stopwords'] = array(
+    '#default_value' => variable_get('bot_factoid_stopwords', _bot_factoid_stopwords()),
+    '#description' => t('List the words that cannot be the subject of a factoid.'),
+    '#title' => t('Stopwords'),
+    '#type' => 'textarea',
+  );
+
+  return system_settings_form($form);
+}
+
+
+/**
+ * Menu callback; handles pages for creating and editing factoids.
+ */
+function bot_factoid_admin_edit($id = 0) {
+  if ($id) {
+    $factoid = bot_factoid_load_by_id($id);
+    drupal_set_title(check_plain($factoid['subject']));
+    $output = drupal_get_form('bot_factoid_admin_form', $factoid);
+  }
+  else {
+    $output = drupal_get_form('bot_factoid_admin_form');
+  }
+
+  return $output;
+}
+
+/**
+ * Return a form for editing or creating a factoid.
+ *
+ * @ingroup forms
+ * @see bot_factoid_admin_form_validate()
+ * @see bot_factoid_admin_form_submit()
+ */
+function bot_factoid_admin_form(&$form_state, $edit = array('subject' => '', 'is_are' => '', 'statement' => '', 'id' => NULL)) {
+
+  $form['#factoid'] = $edit;
+
+  $form['subject'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Factoid subject'),
+    '#default_value' => $edit['subject'],
+    '#maxlength' => 128,
+    '#size' => 45,
+    '#description' => t('Specify the subject of the factoid.'),
+    '#required' => TRUE,
+  );
+  $form['is_are'] = array(
+    '#type' => 'radios',
+    '#options' => array('is' => t('is'), 'are' => t('are')),
+    '#title' => t('Factoid is/are'),
+    '#default_value' => $edit['is_are'],
+    '#description' => t('Specify wheter the subject is something or the subject relates to multiple objects. For example "Views is a great module." or "Logs are saved.".'),
+    '#required' => TRUE,
+  );
+  $form['statement'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Factoid statement'),
+    '#default_value' => $edit['statement'],
+    '#maxlength' => 255,
+    '#size' => 60,
+    '#description' => t('Specify the statement of the factoid. For example write "&lt;reply&gt;A module to create an IRC bot."'),
+    '#required' => TRUE,
+  );
+  if ($edit['id']) {
+    $form['id'] = array('#type' => 'hidden', '#value' => $edit['id']);
+    $form['submit'] = array('#type' => 'submit', '#value' => t('Update factoid'));
+  }
+  else {
+    $form['submit'] = array('#type' => 'submit', '#value' => t('Create new factoid'));
+  }
+
+  return $form;
+}
+
+/**
+ * Save a new URL alias to the database.
+ */
+function bot_factoid_admin_form_submit($form, &$form_state) {
+  $factoid = new stdClass();
+  $factoid->id = $form_state['values']['id'];
+  $factoid->subject = $form_state['values']['subject'];
+  $factoid->is_are = $form_state['values']['is_are'];
+  $factoid->statement = $form_state['values']['statement'];
+  // Try to save the factoid.
+  if (bot_factoid_save($factoid)) {
+    drupal_set_message(t('The factoid has been saved.'));
+    $form_state['redirect'] = 'bot/factoid';
+  }
+  else {
+    drupal_set_message(t('Errors while saving factoid.', 'error'));
+  }
+  return;
+}
+
+/**
+ * Menu callback; confirms deleting an URL alias
+ */
+function bot_factoid_admin_delete_confirm($form_state, $id) {
+  $factoid = bot_factoid_load_by_id($id);
+  if (user_access('administer bot factoids')) {
+    $form['id'] = array('#type' => 'value', '#value' => $id);
+    $output = confirm_form($form,
+      t('Are you sure you want to delete the factoid %subject?', array('%subject' => $factoid['subject'])),
+      isset($_GET['destination']) ? $_GET['destination'] : 'bot/factoid');
+  }
+  return $output;
+}
+
+/**
+ * Execute URL alias deletion
+ */
+function bot_factoid_admin_delete_confirm_submit($form, &$form_state) {
+  if ($form_state['values']['confirm']) {
+    bot_factoid_delete($form_state['values']['id']);
+    $form_state['redirect'] = 'bot/factoid';
+    return;
+  }
+}
Index: bot_factoid/bot_factoid.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/bot/bot_factoid/Attic/bot_factoid.install,v
retrieving revision 1.1.2.3.2.3
diff -u -p -r1.1.2.3.2.3 bot_factoid.install
--- bot_factoid/bot_factoid.install	2 May 2008 01:21:17 -0000	1.1.2.3.2.3
+++ bot_factoid/bot_factoid.install	19 Dec 2009 08:41:33 -0000
@@ -8,6 +8,13 @@ function bot_factoid_schema() {
   $schema['bot_factoid'] = array(
     'description' => t('The single table necessary for factoid storage.'),
     'fields' => array(
+      'id' => array(
+        'description' => t('A unique ID for this factoid.'),
+        'not null'    => TRUE,
+        'size'        => 'big',
+        'type'        => 'serial',
+        'unsigned'    => TRUE,
+      ),
       'subject' => array(
         'default'     => '',
         'description' => t('The word or phrase this factoid is about.'),
@@ -29,6 +36,7 @@ function bot_factoid_schema() {
         'type'        => 'text',
       ),
     ),
+    'primary key' => array('id'),
     'key' => array('subject'),
   );
 
@@ -36,6 +44,23 @@ function bot_factoid_schema() {
 }
 
 /**
+ * Implementation of hook_update_N().
+ *
+ * Add new column 'id'.
+ */
+function bot_factoid_update_6100() {
+  $ret = array();
+  db_add_field($ret, 'bot_factoid', 'id', array(
+    'description' => t('A unique ID for this factoid.'),
+    'not null'    => TRUE,
+    'size'        => 'big',
+    'type'        => 'serial',
+    'unsigned'    => TRUE,
+  ), array('primary key' => array('id')));
+  return $ret;
+}
+
+/**
  * Implementation of hook_install().
  */
 function bot_factoid_install() {
@@ -48,4 +73,4 @@ function bot_factoid_install() {
 function bot_factoid_uninstall() {
   drupal_uninstall_schema('bot_factoid');
   variable_del('bot_factoid_stopwords');
-}
\ No newline at end of file
+}
Index: bot_factoid/bot_factoid.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/bot/bot_factoid/Attic/bot_factoid.module,v
retrieving revision 1.1.2.6.2.16
diff -u -p -r1.1.2.6.2.16 bot_factoid.module
--- bot_factoid/bot_factoid.module	5 Mar 2009 14:09:36 -0000	1.1.2.6.2.16
+++ bot_factoid/bot_factoid.module	19 Dec 2009 08:41:34 -0000
@@ -32,12 +32,40 @@ function bot_factoid_menu() {
     'page callback'     => 'bot_factoid_overview',
     'title'             => 'Factoids',
   );
+  $items['bot/factoid/list'] = array(
+    'title' => 'List',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+  );
+  $items['bot/factoid/add'] = array(
+    'title' => 'Add factoid',
+    'page callback' => 'bot_factoid_admin_edit',
+    'access arguments' => array('administer bot factoids'),
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'bot_factoid.admin.inc',
+  );
+  $items['bot/factoid/edit'] = array(
+    'title' => 'Edit factoid',
+    'page callback' => 'bot_factoid_admin_edit',
+    'access arguments' => array('administer bot factoids'),
+    'type' => MENU_CALLBACK,
+    'file' => 'bot_factoid.admin.inc',
+  );
+  $items['bot/factoid/delete'] = array(
+    'title' => 'Delete factoid',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('bot_factoid_admin_delete_confirm'),
+    'access arguments' => array('administer bot factoids'),
+    'type' => MENU_CALLBACK,
+    'file' => 'bot_factoid.admin.inc',
+  );
   $items['admin/settings/bot/factoid'] = array(
-    'access arguments'  => array('administer bot'),
-    'description'       => 'Configure factoid learning with these settings.',
-    'page callback'     => 'drupal_get_form',
-    'page arguments'    => array('bot_factoid_settings'),
-    'title'             => 'Bot Factoid',
+    'access arguments' => array('administer bot'),
+    'description' => 'Configure factoid learning with these settings.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('bot_factoid_settings'),
+    'title' => 'Bot Factoid',
+    'file' => 'bot_factoid.admin.inc',
   );
 
   return $items;
@@ -47,7 +75,10 @@ function bot_factoid_menu() {
  * Implementation of hook_perm().
  */
 function bot_factoid_perm() {
-  return array('access bot factoids');
+  return array(
+    'access bot factoids',
+    'administer bot factoids',
+  );
 }
 
 /**
@@ -55,16 +86,25 @@ function bot_factoid_perm() {
  */
 function bot_factoid_overview() {
   $output = NULL; // NULL, NULL, the musical toot...
+  $administer_factoids = user_access('administer bot factoids');
   $headers = array(t('Subject'), t('Is/Are'), t('Statement'));
+  if ($administer_factoids) {
+  	$headers[] = array('data' => t('Operations'), 'colspan' => 2);
+  }
 
   $rows = array(); // storage of gimme-gimme awesomeness. wheedoggy!
-  $results = pager_query('SELECT subject, is_are, statement FROM {bot_factoid} ORDER BY subject', 25);
+  $results = pager_query('SELECT id, subject, is_are, statement FROM {bot_factoid} ORDER BY subject', 25);
   while ($result = db_fetch_object($results)) {
-    $rows[] = array(
+    $row = array(
       array('data' => check_plain($result->subject), 'class' => 'subject'),
       array('data' => check_plain($result->is_are), 'class' => 'is_are'),
-      array('data' => check_plain($result->statement), 'class' => 'statement')
+      array('data' => check_plain($result->statement), 'class' => 'statement'),
     );
+    if ($administer_factoids) {
+      $row[] = array('data' => l(t('edit'), 'bot/factoid/edit/'. $result->id));
+      $row[] = array('data' => l(t('delete'), 'bot/factoid/delete/'. $result->id));
+    }
+    $rows[] = $row;
   }
   $output .= theme('table', $headers, $rows, array('id' => 'factoids'));
   $output .= theme('pager', NULL, 25, 0);
@@ -114,14 +154,24 @@ function bot_factoid_irc_msg_channel($da
 
   // look for factoids to delete.
   if (preg_match("/^($addressed)forget( about)? (.*)$/i", $data->message, $matches)) {
-    bot_factoid_delete($matches[4]); // good night, sweetheart. baaah dum dum dum. it's time to GoOoOooOOoo.
-    bot_message($to, t("!nick: I've forgotten about !subject.", array('!nick' => $data->nick, '!subject' => $matches[4])));
+    // Look if we have such a factoid.
+    $factoid = bot_factoid_load($matches[4]);
+    if ($factoid) {
+      bot_factoid_delete($factoid->id); // good night, sweetheart. baaah dum dum dum. it's time to GoOoOooOOoo.
+      bot_message($to, t("!nick: I've forgotten about !subject.", array('!nick' => $data->nick, '!subject' => $matches[4])));
+    }
+    else {
+      bot_message($to, t("!nick: Sorry, but I didn't know about !subject to forget.", array('!nick' => $data->nick, '!subject' => $matches[4])));
+    }
   } // @todo delete message should be customizable. this one sucks.
 
   // look for factoids to learn.
-  if (bot_factoid_save($data->message)) {
-    bot_message($to, t("!nick: Okay.", array('!nick' => $data->nick)));
-    // @todo success message should be customizable. "Okay." sucks.
+  $factoid = bot_factoid_prepare($data->message);
+  if ($factoid) {
+    if (bot_factoid_save($factoid)) {
+      bot_message($to, t("!nick: Okay.", array('!nick' => $data->nick)));
+      // @todo success message should be customizable. "Okay." sucks.
+    }
   }
 }
 
@@ -135,12 +185,14 @@ function bot_factoid_irc_msg_query($data
 /**
  * Delete a factoid.
  *
- * @param $subject
- *   The subject you'd like to delete.
+ * @param $id
+ *   The id of the factoid you'd like to delete.
  */
-function bot_factoid_delete($subject) {
-  if (!$subject) { return 0; } // why do you not send me a subject? I like to reap, reap, reap.
-  db_query("DELETE FROM {bot_factoid} WHERE LOWER(subject) = '%s'", drupal_strtolower($subject));
+function bot_factoid_delete($id) {
+  if (!$id) { 
+    return 0; 
+  } // why do you not send me an id? I like to reap, reap, reap.
+  db_query("DELETE FROM {bot_factoid} WHERE id = '%d'", $id);
 }
 
 /**
@@ -157,7 +209,7 @@ function bot_factoid_delete($subject) {
  *   perform substitutions for "!who" (the nick asking for the factoid)
  *   and "!channel" (the channel the factoid is asked in.)
  * @return $factoid
- *   An object containing 'subject' (string), 'is_are' (string),
+ *   An object containing 'id' (int), 'subject' (string), 'is_are' (string),
  *   'statements' (array) and 'result' (string). The 'result' is
  *   the logical processing of the individual parts and should be
  *   ready for sending.
@@ -166,8 +218,9 @@ function bot_factoid_load($subject, $dat
   $factoid = array(); // holds everything about the fact.
   $is_are_counts = array(); // number of "is" "are" usage.
 
-  $results = db_query("SELECT is_are, statement FROM {bot_factoid} WHERE LOWER(subject) = '%s'", drupal_strtolower($subject));
+  $results = db_query("SELECT id, is_are, statement FROM {bot_factoid} WHERE LOWER(subject) = '%s'", drupal_strtolower($subject));
   while ($result = db_fetch_object($results)) { // Morbus flings his own poo. Not at people. But at glassware. GLASSSWARE!
+    $factoid['id'] = $result->id;
     if (strpos($result->statement, '<reply>') !== FALSE)  { $factoid['has_reply']++; }
     if (strpos($result->statement, '<action>') !== FALSE) { $factoid['has_action']++; }
 
@@ -212,7 +265,43 @@ function bot_factoid_load($subject, $dat
 }
 
 /**
- * Creates a factoid.
+ * Load a fatoid by its id.
+ *
+ * @param $id
+ *   Id of factoid to load.
+ * @return 
+ *   An object containing 'id' (int), 'subject' (string), 'is_are' (string) and
+ *   'statement' (string). 
+ */
+function bot_factoid_load_by_id($id) {
+  $result = db_fetch_object(db_query("SELECT id, subject, is_are, statement FROM {bot_factoid} WHERE id = %d", $id));
+  if ($result) {
+  	return (array)$result;
+  }
+  return FALSE;
+}
+
+/**
+ * Saves a factoid.
+ *
+ * @param $factoid
+ *   The factoid object to save. If $factoid->id is not set it is a new factoid.
+ */
+function bot_factoid_save($factoid) {
+    // if "also" starts the statement, we're adding.
+    if (!isset($factoid->id) || preg_match("/^also\s+/i", $factoid->statement)) {
+      // Add a new factoid.
+      $factoid->statement = preg_replace("/^also\s+/i", '', $factoid->statement);
+      return drupal_write_record('bot_factoid', $factoid);
+    }
+    else { 
+      // Update existing factoid.
+      return drupal_write_record('bot_factoid', $factoid, 'id');
+    }
+}
+
+/**
+ * Prepares a factoid object out of a user string.
  *
  * We expect a raw string right from the IRC user - we'll handle all the
  * checks for prefacing and "no," and "also", etc. Learning factoids
@@ -220,8 +309,11 @@ function bot_factoid_load($subject, $dat
  *
  * @param $string
  *   The user string that should be parsed for action.
+ * @return
+ *   A factoid object containing 'id' (int), 'subject' (string), 'is_are'
+ *   (string) and 'statement' (string).
  */
-function bot_factoid_save($string) {
+function bot_factoid_prepare($string) {
   $addressed = bot_name_regexp();
 
   // only process the string if it's one of:
@@ -238,47 +330,26 @@ function bot_factoid_save($string) {
     // remove "botmodule: no," and "no, bot_module".
     $factoid->subject = preg_replace("/^$addressed/i", '', $factoid->subject);
     $factoid->subject = preg_replace("/^no[:;,-]\s*($addressed)?/i", '', $factoid->subject);
-    if (preg_match('/^\s*$/', $factoid->subject)) { return 0; } // stop firing blanks.
+    if (preg_match('/^\s*$/', $factoid->subject)) { 
+      return FALSE; 
+    } // stop firing blanks.
 
     // check that it's not one of our stopwords.
     $stopwords = array_map('trim', explode("\n", variable_get('bot_factoid_stopwords', _bot_factoid_stopwords())));
     if (in_array(drupal_strtolower($factoid->subject), array_map('drupal_strtolower', $stopwords))) {
-      return 0;  // bad users deserve no feedback, so just return. UNHAPPILY.
+      return FALSE;  // bad users deserve no feedback, so just return. UNHAPPILY.
     }
 
     // due to interaction with bot_tell, we need to ignore factoids that look like they
     // could be messages left for bot_tell. hardcoding sucks, but this is best for now.
     if (module_exists('bot_tell') && preg_match('/^tell /', $factoid->subject)) {
-      return 0;
+      return FALSE;
     }
 
-    // if "also" starts the statement, we're adding.
-    if (preg_match("/^also\s+/i", $factoid->statement)) {
-      $factoid->statement = preg_replace("/^also\s+/i", '', $factoid->statement);
-    }
-    else { // get rid of existing mojo.
-      bot_factoid_delete($factoid->subject);
-    }
-
-    drupal_write_record('bot_factoid', $factoid);
-    return 1; // if we set something, be happy.
+    return $factoid; // if we set something, be happy.
   }
 
-  return 0;
-}
-
-/**
- * Configures factoid learning.
- */
-function bot_factoid_settings() {
-  $form['bot_factoid_stopwords'] = array(
-    '#default_value' => variable_get('bot_factoid_stopwords', _bot_factoid_stopwords()),
-    '#description'   => t('List the words that cannot be the subject of a factoid.'),
-    '#title'         => t('Stopwords'),
-    '#type'          => 'textarea',
-  );
-
-  return system_settings_form($form);
+  return FALSE;
 }
 
 /**
Index: bot_log/bot_log.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/bot/bot_log/Attic/bot_log.module,v
retrieving revision 1.1.2.7.2.7
diff -u -p -r1.1.2.7.2.7 bot_log.module
--- bot_log/bot_log.module	18 Mar 2009 16:47:30 -0000	1.1.2.7.2.7
+++ bot_log/bot_log.module	19 Dec 2009 08:41:35 -0000
@@ -420,4 +420,3 @@ function bot_log_settings(){
 
   return system_settings_form($form);
 }
-
