PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/vendors/php-irc/modules/iphp/iphp_mod.php

http://github.com/cakephp/cakebot
PHP | 397 lines | 335 code | 45 blank | 17 comment | 81 complexity | 2f573b93c5c342d72d5049cc10dbf25d MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. // TODO array_push returns &#38; need to fix that.
  4. // TODO: added the ability to tell someone else the funciton ifnormation, caches the word tell instead of the actual function.
  5. include_once('modules/iphp/iphp_config.php');
  6. class iphp_mod extends module
  7. {
  8. public $title = "iPHP";
  9. public $author = "Idle0ne";
  10. public $version = "1.0b";
  11. private $cache = array();
  12. private $query = null;
  13. private $useDb = FALSE;
  14. private $dbTable = '';
  15. private $useCache = TRUE;
  16. public function init()
  17. {
  18. // Add your timer declarations and whatever
  19. // else here...
  20. $this->useDb = IPHP_USE_DB;
  21. $this->dbTable = IPHP_DB_TABLE;
  22. $this->useCache = IPHP_USE_CACHE;
  23. }
  24. public function destroy()
  25. {
  26. // Put code here to destroy the timers that you created in init()
  27. // and whatever else cleanup code you want.
  28. }
  29. public function process_fetch( $line, $args )
  30. {
  31. if($args['nargs'] > 0)
  32. {
  33. if($args['nargs'] == 4)
  34. {
  35. $line['toWho'] = $args['arg2'];
  36. $line['toOther'] = TRUE;
  37. $this->query = strtolower(strip_tags($args['arg4']));
  38. if($this->query == "") $args['nargs'] = 0;
  39. }
  40. elseif( $args['nargs'] == 1 )
  41. {
  42. $line['toWho'] = $line['fromNick'];
  43. $line['toOther'] = FALSE;
  44. $this->query = strtolower(strip_tags($args['arg1']));
  45. if($this->query == "") $args['nargs'] = 0;
  46. }
  47. else
  48. {
  49. $args['nargs'] = 0;
  50. }
  51. }
  52. if ($args['nargs'] <= 0)
  53. {
  54. $this->ircClass->notice($line['fromNick'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - Usage: !iphp <function>" . DARK);
  55. return;
  56. }
  57. if($line['toOther'] === TRUE ) $this->ircClass->notice($line['fromNick'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - telling ".$line['toWho']." about ".$this->query . DARK);
  58. else $this->ircClass->notice($line['fromNick'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - Processing, please wait..." . DARK);
  59. if($this->useDb === TRUE)
  60. {
  61. $this->fetch_function_db( $line, $args );
  62. }
  63. else
  64. {
  65. $this->fetch_function( $line, $args );
  66. }
  67. }
  68. private function fetch_function( $line, $args )
  69. {
  70. if (($this->useCache === TRUE) && (isset($this->cache[$this->query]) && is_array($this->cache[$this->query])))
  71. {
  72. // increment the hits counter
  73. $this->cache[$this->query]['hits'] += 1;
  74. if(isset($this->cache[$this->query]['function']))
  75. {
  76. if($line['toOther'] === TRUE ) $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$line['fromNick']." wants you to know about ".$this->query . DARK);
  77. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - php.net response for ".$this->query . DARK);
  78. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$this->cache[$this->query]['function']." Function Reference" . DARK);
  79. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$this->cache[$this->query]['url'] . DARK);
  80. }
  81. elseif(isset($this->cache[$this->query]['matches']))
  82. {
  83. $this->ircClass->notice($line['fromNick'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - Could not find a perfect match for ".$this->query.", maybe one of the following (".$this->cache[$this->query]['count'].") suggestions: " . implode(', ', $this->cache[$this->query]['matches']) . "." . DARK);
  84. }
  85. else
  86. {
  87. // use the cached version
  88. if($line['toOther'] === TRUE ) $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$line['fromNick']." wants you to know about ".$this->query . DARK);
  89. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - php.net response for ".$this->query . DARK);
  90. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $this->cache[$this->query]['function'] . ' -- ' . $this->cache[$this->query]['description']);
  91. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $this->cache[$this->query]['versions']);
  92. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $this->cache[$this->query]['defenition']);
  93. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $this->cache[$this->query]['url']);
  94. }
  95. }
  96. else
  97. {
  98. $search = socket::generateGetQuery($this->query, "www.php.net", "/$this->query", "1.0");
  99. $this->ircClass->addQuery("www.php.net", 80, $search, $line, $this, "function_response");
  100. }
  101. }
  102. public function fetch_function_db( $line, $args )
  103. {
  104. $sql = "
  105. SELECT
  106. id, query, fromWho, toWho, mask, channel, function, library, versions, defenition, description, url, matches, timestamp
  107. FROM
  108. ".$this->dbTable."
  109. WHERE
  110. query='".$this->query."'
  111. ";
  112. echo $sql;
  113. $cacheResult = $this->db->query($sql);
  114. if($this->db->numRows($cacheResult) > 0) {
  115. $cache = $this->db->fetchArray($cacheResult);
  116. // update hits
  117. $sql = "UPDATE ".$this->dbTable." SET hits = hits+1 WHERE id = ".$cache['id'];
  118. $this->db->query($sql);
  119. }
  120. if (($this->useCache === TRUE) && (isset($cache['query']) && $cache['query'] != ""))
  121. {
  122. if(isset($cache['library']) && $cache['library'] != "")
  123. {
  124. if($line['toOther'] === TRUE ) $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$line['fromNick']." wants you to know about ".$this->query . DARK);
  125. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - php.net response for ".$this->query . DARK);
  126. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$cache['library']." Function Reference" . DARK);
  127. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$cache['url'] . DARK);
  128. }
  129. elseif(isset($cache['matches']) && $cache['matches'] != "")
  130. {
  131. $cache['matches'] = unserialize($cache['matches']);
  132. $cache['matchCount'] = count($cache['matches']);
  133. $message = DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - Could not find a perfect match for ".$this->query.".";
  134. if($cache['matchCount'] > 0) $message .= " Maybe one of the following (".$cache['matchCount'].") suggestions: " . implode(', ', $cache['matches']) . "." . DARK;
  135. else $message .= " I am unable to come up with any close matches, sorry." . DARK;
  136. $this->ircClass->notice($line['fromNick'], $message);
  137. }
  138. else
  139. {
  140. // use the cached version
  141. if($line['toOther'] === TRUE ) $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$line['fromNick']." wants you to know about ".$this->query . DARK);
  142. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - php.net response for ".$this->query . DARK);
  143. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $cache['function'] . ' -- ' . $cache['description']);
  144. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $cache['versions']);
  145. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $cache['defenition']);
  146. $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $cache['url']);
  147. }
  148. }
  149. else
  150. {
  151. $search = socket::generateGetQuery($this->query, "www.php.net", "/$this->query", "1.0");
  152. $this->ircClass->addQuery("www.php.net", 80, $search, $line, $this, "function_response");
  153. }
  154. }
  155. public function function_response($line, $args, $result, $site)
  156. {
  157. if ($result == QUERY_ERROR)
  158. {
  159. $this->ircClass->notice($line['fromNick'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - Error: " . $site);
  160. return;
  161. }
  162. $location = $this->checkLocation($site);
  163. if( count( $location ) >= 3 )
  164. {
  165. $domain = $location['scheme'] . '://' . $location['host'] . $location['path'];
  166. if(isset($location['query'])) {
  167. $domain .= '?' . $location['query'];
  168. $query = $location['query'];
  169. }
  170. else $query = "";
  171. $search = socket::generateGetQuery($query, $location['host'], $location['path'], "1.0");
  172. $this->ircClass->addQuery($location['host'], 80, $search, $line, $this, "function_response");
  173. }
  174. else
  175. {
  176. //$site = html_entity_decode($site);
  177. $site = str_replace("\n", "", $site);
  178. $site = str_replace("\r", "", $site);
  179. preg_match_all('/<base href="(.*?)" \/>/is', $site, $matches);
  180. // TODO: Fix the page url, seems to contain HTML ONLY SEEMS TO HAPPEN WHEN YOU CALL A FUNCTION THAT RETURNS A SEARCH
  181. $page_url = isset($matches[1][0]) ? $this->parse_php_url($matches[1][0]) : null;
  182. $response = array(
  183. 'query' => $this->query,
  184. 'fromWho' => $line['fromNick'],
  185. 'toWho' => '',
  186. 'mask' => $line['fromHost'],
  187. 'channel' => $line['to'],
  188. 'function' => '',
  189. 'versions' => '',
  190. 'defenition' => '',
  191. 'description' => '',
  192. 'url' => $page_url,
  193. 'matches' => '',
  194. 'library' => '',
  195. 'hits' => 1,
  196. 'timestamp' => time()
  197. );
  198. if(isset($line['toWho'])) $response['toWho'] = $line['toWho'];
  199. if( preg_match('/<li class="header up"><a href="funcref.php">Function Reference<\/a><\/li>/is', $site))
  200. {
  201. // found a function reference page
  202. preg_match_all('/<li class="active"><a href="(.*?)">(.*?)<\/a><\/li>/is', $site, $matches, PREG_PATTERN_ORDER);
  203. $response['library'] = $matches[2][0];
  204. $this->doCacheCheck($response);
  205. if($line['toOther'] === TRUE ) $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$line['fromNick']." wants you to know about ".$this->query . DARK);
  206. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - php.net response for ".$this->query . DARK);
  207. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$response['library']." Function Reference" . DARK);
  208. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $response['url'] . DARK);
  209. }
  210. elseif( preg_match('/Sorry, but the function <b>'.$this->query.'<\/b> is not in the online manual/is', $site))
  211. {
  212. // parse out the closest matches if there are any
  213. preg_match_all('/<a href="\/manual\/en\/function.(.*?)"><b>(.*?)<\/b><\/a><br \/>/is', $site, $matches);
  214. if(isset($matches[2]) && $matches[2] != "")
  215. {
  216. $response['matches'] = serialize($matches[2]);
  217. $response['matchCount'] = count($matches[2]);
  218. }
  219. else
  220. {
  221. $response['matches'] = serialize(array());
  222. $response['matchCount'] = 0;
  223. }
  224. $this->doCacheCheck($response);
  225. $message = DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - Could not find a perfect match for ".$this->query.".";
  226. if($response['matchCount'] > 0) $message .= " Maybe one of the following (".$response['matchCount'].") suggestions: " . implode(', ', unserialize($response['matches'])) . "." . DARK;
  227. else $message .= " I am unable to come up with any close matches, sorry." . DARK;
  228. $this->ircClass->notice($line['toWho'], $message);
  229. }
  230. else
  231. {
  232. // Grab the rest of the info from the page
  233. preg_match_all("/<\/A><P>(.*?)\((.*?)\)<\/P>(.*?)--(.*?)<\/DIV><DIVCLASS=\"(.*?)\"><ANAME=\"(.*?)\"><\/A><H2>Description<\/H2>(.*?)<BR>/is", $site, $matches, PREG_PATTERN_ORDER);
  234. $response['versions'] = isset($matches[2][0]) ? html_entity_decode($matches[2][0]) : null;
  235. $response['function'] = isset($matches[3][0]) ? trim(str_replace('&nbsp;', '', strip_tags($matches[3][0]))) : null;
  236. $response['description'] = isset($matches[4][0]) ? trim(str_replace('&nbsp;', '', strip_tags($matches[4][0]))) : null;
  237. $response['defenition'] = isset($matches[7][0]) ? trim(str_replace('&nbsp;', '', strip_tags($matches[7][0]))) : null;
  238. //$response['url'] = $this->parse_php_url($page_url);
  239. $this->doCacheCheck( $response );
  240. if($line['toOther'] === TRUE ) $this->ircClass->notice($line['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - ".$line['fromNick']." wants you to know about ".$this->query . DARK);
  241. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - php.net response for ".$this->query . DARK);
  242. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $response['function'] . ' -- ' . $response['description']);
  243. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $response['versions']);
  244. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $response['defenition']);
  245. $this->ircClass->notice($response['toWho'], DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - " . $response['url']);
  246. }
  247. }
  248. }
  249. private function parse_php_url($url)
  250. {
  251. $url = preg_replace('/http:\/\/([a-z])+[0-9]/', 'http://www', $url);
  252. $url = str_replace('/manual/en/function.'.str_replace('_', '-', $this->query).'.php', '/'.$this->query, $url);
  253. $url = str_replace('/manual/en/ref.'.str_replace('_', '-', $this->query).'.php', '/'.$this->query, $url);
  254. return $url;
  255. }
  256. private function doCacheCheck( $response )
  257. {
  258. if( $this->useDb === TRUE && $this->useCache === TRUE ) $this->cache_response_db( $response );
  259. elseif( $this->useDb === FALSE && $this->useCache === TRUE ) $this->cache_response( $response );
  260. }
  261. private function cache_response_db( $response )
  262. {
  263. foreach($response as $key => $val) $response[$key] = mysql_real_escape_string($val);
  264. $sql = "
  265. INSERT INTO ".$this->dbTable." (query, fromWho, toWho, mask, channel, function, library, versions, defenition, description, url, matches, hits, timestamp)
  266. VALUES ('".$this->query."', '".$response['fromWho']."', '".$response['toWho']."', '".$response['mask']."', '".$response['channel']."', '".$response['function']."', '".$response['library']."', '".$response['versions']."', '".$response['defenition']."', '".$response['description']."', '".$response['url']."', '".$response['matches']."', 1, ".$response['timestamp'].")
  267. ";
  268. $this->db->query($sql);
  269. }
  270. private function cache_response( $response )
  271. {
  272. $this->cache[$this->query] = array();
  273. foreach ($response as $key => $value) $this->cache[$this->query][$key] = $value;
  274. }
  275. private function checkLocation($site)
  276. {
  277. preg_match_all('/Location:(.*?)Content-Length:/is', $site, $matches);
  278. if( isset($matches[1][0]) && $matches[1][0] != "" )
  279. {
  280. if(strpos($matches[1][0], '%3F')) $parts = explode('%3F', $matches[1][0]);
  281. if(isset($parts[0])) $url = parse_url(trim($parts[0]));
  282. if( !isset($url) ) $url = parse_url(trim($matches[1][0]));
  283. if($url != "") return $url;
  284. else return FALSE;
  285. }
  286. else
  287. {
  288. preg_match_all('/Location:(.*?)Connection:/is', $site, $matches);
  289. if( isset($matches[1][0]) && $matches[1][0] != "" )
  290. {
  291. if(strpos($matches[1][0], '?')) $parts = explode('?', $matches[1][0]);
  292. $url = parse_url(trim($parts[0]));
  293. if($url != "") return $url;
  294. else return FALSE;
  295. }
  296. }
  297. return FALSE;
  298. }
  299. public function iphp_command($chat, $args)
  300. {
  301. switch($args['arg1'])
  302. {
  303. case 'cache':
  304. $this->cache($chat, $args['arg2']);
  305. break;
  306. case 'version':
  307. $chat->dccSend( DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - version: ".$this->version."." );
  308. break;
  309. }
  310. }
  311. private function cache($chat, $action)
  312. {
  313. switch($action)
  314. {
  315. case 'reset':
  316. if( $this->useCache === TRUE)
  317. {
  318. if( $this->useDb === TRUE)
  319. {
  320. $this->db->query("DELETE FROM ".$this->dbTable);
  321. }
  322. else
  323. {
  324. $this->cache = null;
  325. $this->cache = array();
  326. }
  327. }
  328. $chat->dccSend( DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - The cache has been reset." );
  329. break;
  330. case 'list':
  331. if( $this->useCache === TRUE )
  332. {
  333. if( $this->useDb === TRUE )
  334. {
  335. $cacheResult = $this->db->query("SELECT id FROM ". $this->dbTable);
  336. $count = $this->db->numRows($cacheResult);
  337. }
  338. else
  339. {
  340. $count = count($this->cache);
  341. }
  342. if($count > 0) $chat->dccSend( DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - cached functions (".$count.")");
  343. else $chat->dccSend( DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - There are 0 cached functions." );
  344. }
  345. else {
  346. $chat->dccSend( DARK . "[" . BRIGHT . 'iPHP' . DARK . "] - Caching is not turned on." );
  347. }
  348. break;
  349. }
  350. }
  351. }
  352. ?>