Changeset 185
- Timestamp:
- 03/21/08 22:54:40 (8 months ago)
- Files:
-
- trunk/Phergie/Plugin/Lart.php (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Phergie/Plugin/Lart.php
r106 r185 54 54 * @var PDOStatement 55 55 */ 56 protected $select; 56 protected $defination; 57 58 /** 59 * Prepared statement for selecting the alias of a given definition 60 * 61 * @var PDOStatement 62 */ 63 protected $alias; 57 64 58 65 /** … … 62 69 */ 63 70 protected $delete; 71 72 /** 73 * MAn array used to store recursive aliases for the getAliases function 74 * 75 * @var array 76 */ 77 protected $aCache; 64 78 65 79 /** … … 74 88 // Initialize the database connection 75 89 $db = $this->dir . 'lart.db'; 76 $create = !file_exists($db);77 90 $this->db = new PDO('sqlite:' . $db); 78 91 92 // Check to see if the table exists 93 $table = $this->db 94 ->query('SELECT COUNT(*) FROM sqlite_master WHERE name = ' . $this->db->quote('lart')) 95 ->fetchColumn(); 96 79 97 // Create database tables if necessary 80 if ($create) { 98 if (!$table) { 99 $this->debug('Creating the database schema'); 81 100 $this->db->exec(' 82 CREATE TABLE lart ( name VARCHAR(255), definition TEXT);101 CREATE TABLE lart (name VARCHAR(255), definition TEXT, hostmask VARCHAR(50), tstamp VARCHAR(19)); 83 102 CREATE UNIQUE INDEX lart_name ON lart (name) 84 103 '); 85 104 } 105 unset($table); 106 107 // Get the list of columns from the table 108 $table = $this->db 109 ->query('PRAGMA table_info('.$this->db->quote('lart').')') 110 ->fetchAll(); 111 112 $columns = array(); 113 foreach($table as $key => $column) { 114 $columns[] = $column['name']; 115 } 116 117 // Update table as neccessary 118 if (!in_array('hostmask', $columns)) { 119 $this->debug('Updating the databae schema'); 120 $this->db->exec(' 121 BEGIN TRANSACTION; 122 CREATE TEMPORARY TABLE lart_backup (name VARCHAR(255), definition TEXT); 123 INSERT INTO lart_backup SELECT name, definition FROM lart; 124 DROP TABLE lart; 125 CREATE TABLE lart (name VARCHAR(255), definition TEXT, hostmask VARCHAR(50), tstamp VARCHAR(19)); 126 INSERT INTO lart SELECT name, definition, NULL, NULL FROM lart_backup; 127 DROP TABLE lart_backup; 128 COMMIT; 129 CREATE UNIQUE INDEX lart_name ON lart (name) 130 '); 131 } 132 unset($table, $key, $column, $columns); 86 133 87 134 // Initialize prepared statements for common operations 88 135 $this->replace = $this->db->prepare(' 89 REPLACE INTO lart (name, definition) VALUES (:name, :definition) 136 REPLACE INTO lart (name, definition, hostmask, tstamp) VALUES (:name, :definition, :hostmask, :tstamp) 137 '); 138 $this->defination = $this->db->prepare(' 139 SELECT definition FROM lart WHERE LOWER(name) = LOWER(:name) 140 '); 141 $this->alias = $this->db->prepare(' 142 SELECT name FROM lart WHERE LOWER(definition) = LOWER(:definition) 90 143 '); 91 144 $this->select = $this->db->prepare(' 92 SELECT definition FROM lart WHERE name = :name145 SELECT * FROM lart WHERE LOWER(name) = LOWER(:name) 93 146 '); 94 147 $this->delete = $this->db->prepare(' 95 DELETE FROM lart WHERE name = :name148 DELETE FROM lart WHERE LOWER(name) = LOWER(:name) 96 149 '); 97 150 } catch (PDOException $e) { } … … 109 162 public static function checkDependencies(Phergie_Driver_Abstract $client, array $plugins) 110 163 { 111 if (!extension_loaded('PDO') 164 if (!extension_loaded('PDO') 112 165 || !extension_loaded('pdo_sqlite')) { 113 166 return false; … … 128 181 { 129 182 if (!isset($this->cache[$term])) { 130 $this-> select->execute(array(':name' => $term));131 $definition = $this-> select->fetchColumn();183 $this->defination->execute(array(':name' => $term)); 184 $definition = $this->defination->fetchColumn(); 132 185 if ($definition) { 133 186 $this->cache[$term] = $definition; … … 140 193 141 194 /** 195 * Retrieves the alias for a given definition if it exists from the database 196 * and returns it otherwise return FALSE. 197 * 198 * @param string $term Term to search for 199 * @return mixed String containing the definition or FALSE if no alias exist 200 */ 201 protected function getAlias($definition) 202 { 203 $this->alias->execute(array(':definition' => $definition)); 204 $names = $this->alias->fetchAll(); 205 if ($names && count($names) > 0) { 206 return $names; 207 } else { 208 return false; 209 } 210 } 211 212 /** 142 213 * Searches for a definition for a given term, resolves definition aliases, 143 214 * handles cases of circular references, and sends the definition back to … … 153 224 } 154 225 155 $message = strtolower($message);156 226 $definition = $this->getDefinition($message); 157 227 $seen = array($message); … … 161 231 $redirect = $this->getDefinition($definition); 162 232 if ($redirect) { 163 $seen[] = $definition;233 $seen[] = strtolower($definition); 164 234 if (in_array($redirect, $seen)) { 235 $this->debug('Alias redirection loop detected'); 236 $this->deleteLart($message); 165 237 $mod = $this->getIni('gender') == 'F' ? 'her' : 'his'; 166 foreach ($seen as $term) {167 $this->delete->execute(array('name' => $term));168 }169 238 $this->doAction( 170 239 $this->event->getArgument(0), … … 177 246 } while($redirect); 178 247 179 $this->doPrivmsg($this->event->getSource(), $definition); 180 } 181 } 182 183 /** 184 * Performs a lookup for the contents of CTCP ACTION (/me) commands. 185 * 186 * @return void 187 */ 188 public function onAction() 248 $definition = trim($definition); 249 if (substr($definition, 0, 3) == '/me') { 250 $definition = trim(substr($definition, 3)); 251 $this->doAction($this->event->getSource(), $definition); 252 } else { 253 $this->doPrivmsg($this->event->getSource(), $definition); 254 } 255 } 256 } 257 258 /** 259 * Recursively gathers an array of aliases linking to the given term and 260 * for each term of that alias 261 * 262 * @param string $term Term to search for 263 * @return array An array of aliases for the given term 264 */ 265 public function getAliases($term, $recursive = true, $firstRun = true) 266 { 267 if (!is_array($this->aCache) || $firstRun) { 268 unset($this->aCache); $this->aCache = array(); 269 } 270 271 $alias = $this->getAlias($term); 272 if ($alias) { 273 foreach($alias as $key => $value) { 274 $name = $value['name']; 275 if (empty($name)) 276 continue; 277 if (!in_array($name, $this->aCache)) { 278 $this->aCache[] = strtolower($name); 279 if ($recursive) { 280 $this->getAliases($name, true, false); 281 } 282 } 283 } 284 } 285 if ($firstRun) { 286 $cache = $this->aCache; unset($this->aCache); 287 return $cache; 288 } 289 } 290 291 /** 292 * Deletes the given lart and optionally delete all aliases for that lart 293 * recursively. 294 * 295 * @param string $name Term to search for 296 * @param bool $recursive Whethere or not to recursively delete aliases 297 * @return void 298 */ 299 function deleteLart($name, $recursive = true) 300 { 301 if (!$recursive) { 302 $this->debug('Removing term: ' . $name); 303 $this->delete->execute(array(':name' => $name)); 304 } else { 305 $aliases = $this->getAliases($name); 306 $aliases[] = $name; 307 $aliases = array_unique($aliases); 308 309 $this->debug('Removing terms: ' . implode(', ', $aliases)); 310 foreach($aliases as $key => $alias) { 311 $this->delete->execute(array(':name' => $alias)); 312 unset($this->cache[$name]); 313 } 314 } 315 } 316 317 /** 318 * Performs a lookup for the contents of messages to the bot or a channel 319 * in which the bot is present. 320 * 321 * @return void 322 */ 323 public function onPrivmsg() 189 324 { 190 325 if (!$this->db) { … … 192 327 } 193 328 194 $this->checkLart($this->event->getArgument(1));195 }196 197 /**198 * Performs a lookup for the contents of messages to the bot or a channel199 * in which the bot is present.200 *201 * @return void202 */203 public function onPrivmsg()204 {205 if (!$this->db) {206 return;207 }208 209 329 $source = $this->event->getArgument(0); 210 330 $message = $this->event->getArgument(1); 211 $nick = $this->getIni('nick'); 331 $nick = preg_quote($this->getIni('nick')); 332 $hostmask = $this->event->getHostmask(); 333 $timenow = time(); 212 334 $today = date('md'); 213 335 … … 218 340 } 219 341 220 if (preg_match('/^(' . $nick . ':?\s*)?(.*?) is (.*)$/i', $message, $match)) { 342 if (preg_match('/^(' . $nick . '\s*:?\s+)?lartinfo\s+(.*?)$/i', $message, $match)) { 343 list (, $address, $name) = $match; 344 $name = trim(strtolower($name)); 345 if (!empty($name)) { 346 $this->select->execute(array(':name' => $name)); 347 $info = $this->select->fetch(); 348 if ($info && count($info) > 0) { 349 $name = $info['name']; 350 $desc = $info['definition']; 351 $host = (isset($info['hostmask']) ? substr($info['hostmask'], 0, strpos($info['hostmask'], '!')) : 'N/A'); 352 $time = (isset($info['tstamp']) ? $this->getCountdown(time() -$info['tstamp']) : 'N/A'); 353 $aliases = $this->getAliases($name, false); 354 $aliases = (count($aliases) > 0 ? implode(', ', $aliases) : 'N/A'); 355 356 $this->doPrivmsg($this->event->getSource(), 357 'Lart Info -> Term: '.$name.' | Defination: '.$desc.' | User: '.$host.' | Added: '.$time.' ago | Aliases: '.$aliases); 358 } 359 unset($info); 360 } 361 } else if (preg_match('/^(' . $nick . '\s*:?\s+)?(.*?)\s+is\s+(.*)$/i', $message, $match)) { 221 362 list (, $address, $name, $definition) = $match; 222 if (empty ($address) xor $source[0] == '#') { 223 $name = strtolower($name); 224 $this->replace->execute(array(':name' => $name, ':definition' => $definition)); 363 if (!empty($name) && !empty($definition) && (empty($address) xor $source[0] == '#')) { 364 $name = trim(strtolower($name)); 365 $definition = trim($definition); 366 367 $this->debug('Replacing term: ' . $name . ' = ' . $definition); 368 $this->replace->execute(array(':name' => $name, ':definition' => $definition, ':hostmask' => $hostmask, ':tstamp' => $timenow)); 225 369 $this->cache[$name] = $definition; 226 370 } 227 } else if (preg_match('/^(' . $nick . ' :?\s*)?forget(.*)$/i', $message, $match)) {371 } else if (preg_match('/^(' . $nick . '\s*:?\s+)?forget\s+(.*)$/i', $message, $match)) { 228 372 list (, $address, $name) = $match; 229 if ( empty ($address) xor $source[0] == '#') {230 $name = strtolower($name);231 $this->delete->execute(array(':name' => $name)); 232 unset($this->cache[$name]);373 if (!empty($name) && (empty($address) xor $source[0] == '#')) { 374 $name = trim(strtolower($name)); 375 376 $this->deleteLart($name); 233 377 } 234 378 } else { … … 236 380 } 237 381 } 382 383 /** 384 * Performs a lookup for the contents of CTCP ACTION (/me) commands. 385 * 386 * @return void 387 */ 388 public function onAction() 389 { 390 if (!$this->db) { 391 return; 392 } 393 394 $this->checkLart('/me ' . $this->event->getArgument(1)); 395 } 238 396 }