PageRenderTime 71ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/mixi/phpMixi.class.php

https://github.com/komagata/plnet
PHP | 979 lines | 641 code | 81 blank | 257 comment | 51 complexity | 519360466b8f9ecaaf718eab5e6b5dab MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * PHP_Mixi
  4. * mixi(mixi.jp)にアクセスするためのクラス
  5. *
  6. * @package PHP_Mixi
  7. * @author riaf <webmaster@riaf.org>
  8. * @since PHP 4.0.3
  9. * @version $Id: PHP_Mixi.php,v 0.1.1 2006/02/08 riaf Exp $
  10. */
  11. class PHP_Mixi {
  12. /**
  13. * @var string ログインメールアドレス
  14. */
  15. var $email = "";
  16. /**
  17. * @var string ログインパスワード
  18. */
  19. var $password = "";
  20. /**
  21. * @var string Mixiのアドレス
  22. */
  23. var $base_url = "http://mixi.jp/";
  24. /**
  25. * @var int キャッシュの設定
  26. */
  27. var $use_cache = false;
  28. /**
  29. * @var string キャッシュディレクトリ
  30. */
  31. var $cache_dir = "./cache/";
  32. /**
  33. * @var string キャッシュファイルの接頭語
  34. */
  35. var $cache_prefix = "phpmixi_";
  36. /**
  37. * @var string キャッシュファイルの拡張子(PHPとして動作するもの)
  38. */
  39. var $cache_ext = ".tmp.php";
  40. /**
  41. * @var string キャッシュの有効時間(秒)
  42. */
  43. var $cache_time = 3600;
  44. /**
  45. * @var string キャッシュファイル名のハッシュキー
  46. */
  47. var $cache_salt = "phpMixi";
  48. var $mixi_cal_icon = array(
  49. 'i_sc-.gif' => '予定',
  50. 'i_bd.gif' => '誕生日',
  51. 'i_iv1.gif' => '参加イベント',
  52. 'i_iv2.gif' => 'イベント'
  53. );
  54. var $mixi_diary_formval = array(
  55. 'id',
  56. 'news_id',
  57. 'diary_title',
  58. 'diary_body',
  59. 'photo1',
  60. 'photo2',
  61. 'photo3',
  62. 'orig_size',
  63. 'packed',
  64. 'post_key'
  65. );
  66. var $snoopy = null;
  67. var $contents = array();
  68. /**
  69. * 初期設定
  70. *
  71. * @param string $email
  72. * @param string $password
  73. * @param bool $use_cache
  74. * @return bool always true
  75. */
  76. function PHP_Mixi($email = "", $password = "", $use_cache = 0) /*{{{*/
  77. {
  78. $this->email = $email;
  79. $this->password = $password;
  80. $this->use_cache = $use_cache;
  81. if ($this->use_cache) {
  82. if (!defined('PHPMIXI_CACHE')) {
  83. define("PHPMIXI_CACHE", 1);
  84. }
  85. }
  86. require_once 'Snoopy.class.php';
  87. $this->snoopy = new Snoopy;
  88. $this->snoopy->agent = "phpMixi/0.1.1";
  89. return true;
  90. }/*}}}*/
  91. /**
  92. * ログイン
  93. *
  94. * @param string $url ログイン後に読み込むページ 設定することで、多少の高速化が図れる(?)
  95. * @return bool
  96. */
  97. function login($url = "home.pl")/*{{{*/
  98. {
  99. if ($this->is_logined()) {
  100. return true;
  101. }
  102. $param = array('email' => $this->email,
  103. 'password' => $this->password,
  104. 'next_url' => "/" . $url,
  105. 'sticky' => "on"
  106. );
  107. $this->snoopy->submit($this->base_url . "login.pl", $param);
  108. $this->contents[$this->base_url . $url] = $this->snoopy->results;
  109. return empty($this->snoopy->cookies['BF_SESSION']) ? false : true;
  110. }/*}}}*/
  111. /**
  112. * ログイン状態の確認。
  113. *
  114. * 手抜きもイイトコなので、何とかしたほうがいいかも…
  115. *
  116. * @return bool
  117. */
  118. function is_logined() // 手抜き /*{{{*/
  119. {
  120. return empty($this->snoopy->cookies['BF_SESSION']) ? false : true;
  121. }/*}}}*/
  122. /**
  123. * 簡略ログイン
  124. * cookie情報を強引に設定してログイン処理を省略
  125. *
  126. * @param string $session $_COOKIE['BF_SESSION']
  127. * @param string $stamp $_COOKIE['BF_STAMP']
  128. * @return bool always true
  129. */
  130. function ez_login($session, $stamp)/*{{{*/
  131. {
  132. $this->snoopy->cookies['BF_SESSION'] = $session;
  133. $this->snoopy->cookies['BF_STAMP'] = $stamp;
  134. return true;
  135. }/*}}}*/
  136. /**
  137. * ページ取得
  138. *
  139. * @param string $url URL
  140. * @param bool $cache false指定でキャッシュを無視する
  141. * @return string ページデータ
  142. */
  143. function fetch($url, $cache = true)/*{{{*/
  144. {
  145. $url = (strpos($url, "http://") !== false) ? $url : $this->base_url . $url;
  146. if ($this->use_cache && $cache) {
  147. $this->cache_set($url, $this->cache_salt);
  148. }
  149. if (empty($this->contents[$url])) {
  150. $this->snoopy->fetch($url);
  151. $this->contents[$url] = $this->snoopy->results;
  152. }
  153. if ($this->use_cache == 1 && $cache) {
  154. $this->cache_make($url, $this->cache_salt);
  155. }
  156. return $this->contents[$url];
  157. }/*}}}*/
  158. /**
  159. * FORM送信
  160. *
  161. * @param string $action 送信先
  162. * @param array $param 送信するデータ
  163. * @param string $files 送信するファイルのパス
  164. * @return string ページデータ
  165. */
  166. function submit($action, $param, $files = "")/*{{{*/
  167. {
  168. $action = (strpos($action, "http://") !== false) ? $action : $this->base_url . $action;
  169. if (empty($files)) {
  170. $this->snoopy->submit($action, $param);
  171. } else {
  172. $this->snoopy->submit($action, $param, $files);
  173. }
  174. return $this->snoopy->results;
  175. }/*}}}*/
  176. /**
  177. * メインメニューを取得
  178. *
  179. * @param string $url メインメニューを取得するページ
  180. * @return array
  181. */
  182. function parse_mainmenu($url = "home.pl")/*{{{*/
  183. {
  184. $content = $this->fetch($url);
  185. $item = array();
  186. if (preg_match('/<map name=mainmenu>(.*?)<\/map>/s', $content, $match)) {
  187. preg_match_all('/<area .*?alt=[\"\']?([^\s<>]*?)[\"\']? .*?href=[\"\']?([^\s<>]*?)[\"\']?>/i', $match[1], $result, PREG_SET_ORDER);
  188. foreach ($result as $myrow) {
  189. $item[] = array('link' => $this->base_url . $myrow[2],
  190. 'title' => $myrow[1]
  191. );
  192. }
  193. }
  194. return $item;
  195. }/*}}}*/
  196. /**
  197. * ツールバー(?)を取得
  198. *
  199. * @param string $url ツールバーを取得するページ
  200. * @return array
  201. */
  202. function parse_toolbar($url = "home.pl") /*{{{*/
  203. {
  204. $content = $this->fetch($url);
  205. $item = array();
  206. preg_match_all('/<td><img src=http:\/\/img\.mixi\.jp\/img\/b_left\.gif width=22 height=23><\/td>(.*?)<td><img src=http:\/\/img\.mixi\.jp\/img\/b_right\.gif width=23 height=23><\/td>/si', $content, $match);
  207. preg_match_all('/<a href=([^<> ]*?) .*?><img .*?alt=([^<> ]*?) .*?><\/a>/i', $match[1][0], $result, PREG_SET_ORDER);
  208. foreach ($result as $myrow) {
  209. $item[] = array("link" => $this->base_url . $myrow[1],
  210. "title" => $myrow[2]
  211. );
  212. }
  213. return $item;
  214. } /*}}}*/
  215. /**
  216. * 運営者からのお知らせ を取得
  217. *
  218. * @return array
  219. */
  220. function parse_information() /*{{{*/
  221. {
  222. $content = $this->fetch("home.pl");
  223. $item = array();
  224. preg_match_all('/<!-- start: お知らせ -->(.*?)<\/table>/s', $this->ts_strip_nl($content), $match);
  225. preg_match_all('/<tr><td>(.*?)<\/td><td>(.*?)<\/td><td>(.*?)<\/td><\/tr>/i', $match[1][0], $result, PREG_SET_ORDER);
  226. foreach ($result as $myrow) {
  227. preg_match('/<a href=[\"\']?(.*?)[\"\']?.*?>(.*?)<\/a>/i', $myrow[3], $ret);
  228. $item[] = array('link' => $this->base_url . $ret[1],
  229. 'title' => preg_replace('/^・&nbsp;/', '', strip_tags($myrow[1])),
  230. 'value' => $ret[2]
  231. );
  232. }
  233. return $item;
  234. } /*}}}*/
  235. /**
  236. * コミュニティ最新書き込み を取得
  237. *
  238. * 50件以上も取得できるようにしたいね……
  239. *
  240. * @param int $max 最大取得件数(50まで)
  241. * @return array
  242. */
  243. function parse_new_bbs($max = 10) /*{{{*/
  244. {
  245. $content = $this->fetch("new_bbs.pl");
  246. $item = array();
  247. preg_match('/<table border=0 cellspacing=1 cellpadding=4 width=630>(.*?)<\/table>/is', $content, $match);
  248. preg_match_all('/<td WIDTH=180><img.*?>(\d{4})年(\d{2})月(\d{2})日\s(\d{1,2}):(\d{2})<\/td>\s<td WIDTH=450>\s<a href=[\"\']?(view_[a-z]+\.pl\?id=\d+)[\"\']?>(.*?) \((\d+)\)<\/a> \((.*?)\)\s<\/td>/is', $match[1], $result, PREG_SET_ORDER);
  249. $i = 1;
  250. foreach($result as $myrow) {
  251. if ($i > $max) {
  252. break;
  253. }
  254. $item[] = array('date' => array('year' => $myrow[1], 'month' => $myrow[2], 'day' => $myrow[3], 'hour' => $myrow[4], 'minute' => $myrow[5]),
  255. 'link' => $this->base_url . $myrow[6],
  256. 'title' => $myrow[7],
  257. 'count' => $myrow[8],
  258. 'community' => $myrow[9]
  259. );
  260. $i++;
  261. }
  262. return $item;
  263. } /*}}}*/
  264. /**
  265. * カレンダーを取得
  266. *
  267. * @param int $year 年
  268. * @param int $month 月
  269. * @return array
  270. */
  271. function parse_show_calendar($year = 0, $month = 0) /*{{{*/
  272. {
  273. if (empty($year) || empty($month)) {
  274. $url = "show_calendar.pl";
  275. } else {
  276. $url = "show_calendar.pl?year=" . intval($year) . "&month=" . intval($month);
  277. }
  278. $content = $this->fetch($url);
  279. $term = $this->get_cal_term("", $content);
  280. preg_match('/<table width="670" border="0" cellspacing="1" cellpadding="3">(.*?)<\/table>/s', $content, $match);
  281. $content = preg_replace('/<tr align=center bgcolor=#FFF1C4>.*?<\/tr>/is', '', $match[1]);
  282. preg_match_all('/<td height=65 [^<>]*><font color=#996600>(\S*?)<\/font>(.*?)<\/td>/is', $content, $result, PREG_SET_ORDER);
  283. foreach($result as $myrow) {
  284. // $date = array("year" => $term['year'], "month" => $term['month'], "day" => intval($myrow[1]));
  285. $date = $this->mktime(0, 0, 0, $term['month'], $myrow[1], $term['year']);
  286. $schedule = explode("<br>", $myrow[2]);
  287. foreach($schedule as $desc) {
  288. if (preg_match('/<img SRC=(.*?) width=16 height=16 align=middle><a href=(\S*?)>(.*?)<\/a>/i', $desc, $ret)) {
  289. $icon = pathinfo($ret[1]);
  290. $item[] = array('title' => $ret[3], 'link' => $this->base_url . $ret[2], 'date' => $date , "category" => $this->mixi_cal_icon[$icon['basename']]);
  291. } else if (preg_match('/<a href=".*?" onClick="MM_openBrWindow\(\'(view_schedule\.pl\?id=\d+)\'.*?\)"><img src=(\S*?).*?>(.*?)<\/a>/i', $desc, $ret)) {
  292. $icon = pathinfo($ret[2]);
  293. $item[] = array('title' => $ret[3], 'link' => $this->base_url . $ret[1], 'date' => $date , "category" => $this->mixi_cal_icon[$icon['basename']]);
  294. }
  295. }
  296. }
  297. return $item;
  298. } /*}}}*/
  299. function parse_calendar($year = 0, $month = 0){ /*{{{*/
  300. return parse_show_calendar($year, $month);
  301. } /*}}}*/
  302. function &get_cal_term($act = "", &$content) /*{{{*/
  303. {
  304. $result = array();
  305. switch ($act) {
  306. case 'next':
  307. preg_match('/<a href="(calendar\.pl\?.*?)">([^<>]+?)&nbsp;&gt;&gt;/', $content, $match);
  308. $result = array("link" => $match[1], "title" => $match[2]);
  309. break;
  310. case 'prev':
  311. preg_match('/<a href="(calendar\.pl\?.*?)">&lt;&lt;&nbsp;([^<>]+)/', $content, $match);
  312. $result = array("link" => $match[1], "title" => $match[2]);
  313. break;
  314. default:
  315. preg_match('/<a href="calendar\.pl\?year=(\d+)&month=(\d+).*?">[^&]*?<\/a>/', $content, $match);
  316. $result = array("year" => intval($match[1]), "month" => intval($match[2]));
  317. }
  318. return $result;
  319. } /*}}}*/
  320. /**
  321. * 日記を取得
  322. *
  323. * @param int $id 日記のID
  324. * @param int $owner_id 著者のID
  325. * @return array
  326. */
  327. function parse_view_diary($id, $owner_id = 0) /*{{{*/
  328. {
  329. if (!empty($owner_id)) {
  330. $owner_id = "&owner_id=" . intval($owner_id);
  331. }
  332. $url = "view_diary.pl?id=" . intval($id) . $owner_id;
  333. $content = $this->fetch($url);
  334. $item = array();
  335. $pattern = '/<tr valign=top>.*?<td align=center rowspan=2 nowrap width=95 bgcolor=#FFD8B0>(\d{4})年(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})<\/td>';
  336. $pattern .= '.*?<td bgcolor=#FFF4E0 width=430>&nbsp;(.*?)<\/td>.*?<td class=h12>(.*?)<\/td>(.*)/is';
  337. preg_match($pattern, $content, $match);
  338. // $item['date'] = array("year" => $match[1],
  339. // "month" => $match[2],
  340. // "day" => $match[3],
  341. // "hour" => $match[4],
  342. // "minute" => $match[5],
  343. // "str" => sprintf("%04d年%02d月%02d日 %02d:%02d", $match[1], $match[2], $match[3], $match[4], $match[5])
  344. // );
  345. $item['date'] = $this->mktime($match[4], $match[5], 0, $match[2], $match[3], $match[1]);
  346. $item['subject'] = $match[6];
  347. $item['content'] = $match[7];
  348. preg_match_all('/<td rowspan="2" align="center" width="95" bgcolor="#f2ddb7" nowrap>\n(\d{4})年(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})<br>.*?<a href=[\"\']?(.+?)[\"\']?>(.+?)<\/a>.*?<td class=h12>(.+?)<\/td>/is', $match[8], $comment, PREG_SET_ORDER);
  349. foreach($comment as $res) {
  350. $item['comment'][] = array('date' => array("year" => $res[1], "month" => $res[2], "day" => $res[3], "hour" => $res[4], "minute" => $res[5], "str" => sprintf("%04d年%02d月%02d日 %02d:%02d", $res[1], $res[2], $res[3], $res[4], $res[5])),
  351. 'poster' => $res[6],
  352. 'name' => $res[7],
  353. 'content' => $res[8]
  354. );
  355. }
  356. return $item;
  357. } /*}}}*/
  358. /**
  359. * 日記のリストを取得
  360. *
  361. * アタマの処理が酷いけど…… 許してヽ( ゚д゚)ノクレヨ
  362. *
  363. * @param int $id 著者のID (省略で自分の)
  364. * @param int $year 年
  365. * @param int $month 月
  366. * @return array
  367. */
  368. function parse_list_diary($id = 0, $year = 0, $month = 0) /*{{{*/
  369. {
  370. $url = empty($id) ? "list_diary.pl" : "list_diary.pl?id=" . intval($id);
  371. if (!empty($year) && !empty($month)) {
  372. $url = empty($id) ? $url . "?year=" . $year . "&month=" . $month : $url . "&year=" . $year . "&month=" . $month;
  373. }
  374. $now = getdate();
  375. $year = empty($year) ? $now["year"] : $year;
  376. $content = $this->fetch($url);
  377. $pattern = '/<tr VALIGN=top>.*?<font COLOR=#996600>(\d{2})月(\d{2})日<br>(\d{1,2}):(\d{2})<\/font>';
  378. $pattern .= '.*?<td bgcolor=#F2DDB7>&nbsp;(.+?)<\/td>.*?<td CLASS=h120>\n(.*?)\n(.+?)\n<br>\n\n<\/td>';
  379. $pattern .= '.*?<a href="?(.+?)"?>コメント\((\d+)\)<\/a>/is';
  380. preg_match_all($pattern, $content, $result, PREG_SET_ORDER);
  381. $item = array();
  382. foreach($result as $myrow) {
  383. $date = $this->mktime($myrow[3], $myrow[4], 0,
  384. $myrow[1], $myrow[2], $year);
  385. //echo date("Y-m-d", $date)." <br />";
  386. /*
  387. var_dump(date("Y-m-d", $date));
  388. */
  389. list($myrow[8], $sharp) = split("#", $myrow[8]);
  390. $item[] = array('date' => $this->mktime($myrow[3], $myrow[4], 0, $myrow[1], $myrow[2], $year),
  391. 'subject' => $myrow[5],
  392. 'description' => $this->ts_strip_nl(strip_tags($myrow[7])),
  393. 'link' => $this->base_url . $myrow[8],
  394. 'count' => intval($myrow[9])
  395. );
  396. }
  397. return $item;
  398. } /*}}}*/
  399. /**
  400. * マイミクシィ最新日記を取得
  401. *
  402. * @param int $max 最大取得件数
  403. * @return array
  404. */
  405. function parse_new_friend_diary($max = 10) /*{{{*/
  406. {
  407. $content = $this->fetch("new_friend_diary.pl");
  408. $item = array();
  409. preg_match('/<table border=0 cellspacing=1 cellpadding=4 width=630>(.*?)<\/table>/is', $content, $match);
  410. preg_match_all('/<td width=180><img.*?>(\d{4})年(\d{2})月(\d{2})日\s(\d{1,2}):(\d{2})<\/td>\s<td width=450>\s?<a href=[\"\']?(view_diary\.pl\?[^>\s]+)[\"\']?>(.*?)<\/a>\s\((.*?)\)\s<\/td>/is', $match[1], $result, PREG_SET_ORDER);
  411. $i = 1;
  412. foreach($result as $myrow) {
  413. if ($i > $max) {
  414. break;
  415. }
  416. $item[] = array(
  417. // 'date' => array('year' => $myrow[1], 'month' => $myrow[2], 'day' => $myrow[3], 'hour' => $myrow[4], 'minute' => $myrow[5]),
  418. 'date' => $this->mktime($myrow[4], $myrow[5], 0, $myrow[2], $myrow[3], $myrow[1]),
  419. 'link' => $this->base_url . $myrow[6],
  420. 'title' => $myrow[7],
  421. 'name' => $myrow[8]
  422. );
  423. $i++;
  424. }
  425. return $item;
  426. } /*}}}*/
  427. /**
  428. * お気に入りを取得
  429. *
  430. * @param int $max 最大取得件数
  431. * @return array
  432. */
  433. function parse_list_bookmark($max = 10) /*{{{*/
  434. {
  435. $content = $this->fetch("list_bookmark.pl");
  436. preg_match('/<table border=0 cellspacing=1 cellpadding=4 width=630>(.*?)<!--フッタ-->/is', $content, $match);
  437. $pattern = '/<td width=90 .*?><a href="([^"]*show_friend\.pl\?id=\d+)"><img src="([^"]*)".*?>';
  438. $pattern .= '.*?<td colspan=2 bgcolor=#FFFFFF>(.*?) \((.*?)\)<\/td>';
  439. $pattern .= '.*?<td colspan=2 bgcolor=#FFFFFF>(.*?)<\/td>';
  440. $pattern .= '.*?<td bgcolor=#FFFFFF width=140>(.*?)<\/td>/is';
  441. preg_match_all($pattern, $match[1], $result, PREG_SET_ORDER);
  442. $item = array();
  443. $i = 1;
  444. foreach($result as $myrow) {
  445. if ($i > $max) {
  446. break;
  447. }
  448. $item[] = array('link' => $this->base_url . $myrow[1],
  449. 'image' => $myrow[2],
  450. 'name' => $myrow[3],
  451. 'sex' => $myrow[4],
  452. 'comment' => str_replace("<br>", "", $myrow[5]),
  453. 'lastlogin' => $myrow[6]
  454. );
  455. $i++;
  456. }
  457. return $item;
  458. } /*}}}*/
  459. /**
  460. * コミュニティ一覧を取得
  461. *
  462. * 全頁を自動で拾ったほうが良いかな?
  463. *
  464. * @param int $id 誰の?
  465. * @param int $page 何ページ目?
  466. * @return array
  467. */
  468. function parse_list_community($id = 0, $page = 0) /*{{{*/
  469. {
  470. $id = empty($id) ? $this->my_info('id') : $id;
  471. $page = empty($page) ? "" : "&page=" . $page;
  472. $content = $this->fetch("list_community.pl?id=" . $id . $page);
  473. preg_match('/<table border=0 cellspacing=1 cellpadding=2 width=560>(.+?)<\/table>/is', $content, $match);
  474. preg_match_all('/<tr align=center bgcolor=#FFFFFF>(.*?)<tr align=center bgcolor=#FFF4E0>(.*?)<\/tr>/is', $match[1], $set);
  475. $logos = "";
  476. foreach($set[1] as $val) {
  477. $logos .= $val;
  478. }
  479. $names = "";
  480. foreach($set[2] as $val) {
  481. $names .= $val;
  482. }
  483. preg_match_all('/<td width=20% height=100 background=http:\/\/img\.mixi\.jp\/img\/[0-9a-z-_]+\.gif>(<a.*?)<\/td>/i', $logos, $logo_set, PREG_SET_ORDER);
  484. preg_match_all('/<td>(.*?)<\/td>/i', $names, $name_set, PREG_SET_ORDER);
  485. $item = array();
  486. for($i = 0;$i < count($logo_set);$i++) {
  487. preg_match('/<a href=(.*?)><img SRC=(.*?) border=0><\/a>/', $logo_set[$i][1], $logo_matchs);
  488. preg_match('/(.*?)\((\d+)\)\s*$/', $name_set[$i][1], $name_matchs);
  489. $item[] = array('name' => $name_matchs[1],
  490. 'count' => intval($name_matchs[2]),
  491. 'link' => $this->base_url . $logo_matchs[1],
  492. 'logo' => $logo_matchs[2]
  493. );
  494. }
  495. return $item;
  496. } /*}}}*/
  497. function get_all_friend($id)
  498. {
  499. return $this->parse_list_friend($id);
  500. }
  501. /**
  502. * マイミクシィ一覧を取得
  503. *
  504. * 全頁を自動で拾ったほうが良いかな?
  505. *
  506. * @param int $id 誰の?
  507. * @param int $page 何ページ目?
  508. * @return array
  509. */
  510. function parse_list_friend($id = 0, $page = 0) /*{{{*/
  511. {
  512. $id = empty($id) ? "" : "id=" . $id;
  513. $page = empty($page) ? "" : "page=" . $page;
  514. $sep = "";
  515. $sep2 = "";
  516. if (!empty($id) || !empty($page)) {
  517. $sep = "?";
  518. }
  519. if (!empty($id) && !empty($page)) {
  520. $sep2 = "&";
  521. }
  522. $content = $this->fetch("list_friend.pl" . $sep . $id . $sep2 . $page);
  523. //preg_match_all('/<tr align=center bgcolor=#FFFFFF>(.*?)<tr align=center bgcolor=#FFF4E0>(.*?)<\/tr>/is', $match[1], $set);
  524. preg_match_all('/<tr ALIGN=center BGCOLOR=#FFFFFF>(.*?)<tr ALIGN=center BGCOLOR=#FFF4E0>(.*?)<\/tr>/is', $content, $set);
  525. $logos = "";
  526. foreach($set[1] as $val) {
  527. $logos .= $val;
  528. }
  529. $names = "";
  530. foreach($set[2] as $val) {
  531. $names .= $val;
  532. }
  533. //<a href=show_friend.pl?id=5736810><img SRC=http://img-p2.mixi.jp/photo/member/68/10/5736810_3127471233s.jpg border=0></a></td>
  534. preg_match_all('/<td WIDTH=20% HEIGHT=100 background=http:\/\/img.+?\.mixi\.jp\/.+?\.gif>(<a.+?)<\/td>/is', $logos, $logo_set, PREG_SET_ORDER);
  535. preg_match_all('/<td valign=top>(.*?)<\/td>/', $names, $name_set, PREG_SET_ORDER);
  536. /*
  537. var_dump($names);
  538. var_dump($name_set);
  539. */
  540. $item = array();
  541. for($i = 0;$i < count($logo_set);$i++) {
  542. preg_match('/<a href=(.*?)><img SRC=(.*?) border=0><\/a>/', $logo_set[$i][1], $logo_matchs);
  543. preg_match('/(.*?)\((\d+)\)\s*$/', $name_set[$i][1], $name_matchs);
  544. $name = preg_replace("/さん$/", '', $name_matchs[1]);
  545. list($url, $id) = split("=", $logo_matchs[1]);
  546. // var_dump($id);
  547. // var_dump($logo_matchs[1]);
  548. $item[] = array(
  549. 'name' => $name,
  550. 'count' => intval($name_matchs[2]),
  551. 'id' => $id,
  552. 'link' => $this->base_url . $logo_matchs[1],
  553. 'logo' => $logo_matchs[2]
  554. );
  555. }
  556. return $item;
  557. } /*}}}*/
  558. /**
  559. * プロフィールを取得
  560. *
  561. * @param int $id ID
  562. * @return array
  563. */
  564. function parse_show_friend($id = 0) /*{{{*/
  565. {
  566. $url = empty($id) ? "show_profile.pl" : "show_friend.pl?id=".$id;
  567. $content = $this->fetch($url);
  568. $item = array();
  569. // name
  570. preg_match('/<!--プロフィール-->(.*?)<!--プロフィールここまで-->/s', $content, $match);
  571. if (empty($match)) {
  572. preg_match('/<!-- start: プロフィール -->(.*?)<!-- end: プロフィール -->/is', $content, $match);
  573. }
  574. preg_match_all('/<td bgcolor=#F2DDB7.*?>(.*?)<\/td>.*?<td.*?>(.*?)<\/td>/is', $match[1], $result, PREG_SET_ORDER);
  575. $item = array();
  576. if (!empty($id)) {
  577. //preg_match('/<img alt="\*" src="http:\/\/img\.mixi\.jp\/img\/dot0\.gif" width="1" height="5"><br>(.*?)\((\d*)\)<br>.*?<span class="f08x">\((.*?)\)<\/span><br>/is', $content, $info);
  578. preg_match_all('/<\/font><\/td>\n<td( width="345")?>(.+)<\/td><\/tr>/', $content, $info);
  579. preg_match('/<td bgcolor="#F2DDB7" width="80"><font color="#996600">.+<\/font><\/td>\n<td class="h120">(.+)<\/td><\/tr>/', $content, $match_prof);
  580. preg_match('/<td align="center" background="http:\/\/img.mixi.jp\/img\/bg_line.gif"><img src="(.+)" alt=".+" vspace="2" \/>/', $content, $match_img);
  581. /*
  582. var_dump($match_prof);
  583. var_dump($info);
  584. var_dump($match_img);
  585. */
  586. $name = $this->ts_strip_nl($info[2][0]);
  587. $item['name'] = $name;
  588. $item['image'] = $match_img[1];
  589. if (isset($info[2][4])) {
  590. $item['interests'] = $info[2][4];
  591. }
  592. $item['description'] = $match_prof[1];
  593. $item['count'] = intval($info[2]);
  594. $item['lastlogin'] = $info[3];
  595. }
  596. foreach($result as $ret) {
  597. $ret[1] = $this->ts_strip_nl(str_replace("&nbsp;", "", strip_tags($ret[1])));
  598. if (in_array($ret[1], array("最新の日記", "最新のアルバム", "最新のおすすめレビュー"))) {
  599. continue;
  600. }
  601. $item[$ret[1]] = $ret[2];
  602. }
  603. return $item;
  604. } /*}}}*/
  605. function parse_list_message() /*{{{*/
  606. {
  607. return array();
  608. } /*}}}*/
  609. /**
  610. * ページ上部のバナー取得
  611. *
  612. * WWW:Mixiがこれを実装してるとのことなので、一応。
  613. *
  614. * @param string $url
  615. * @return array
  616. */
  617. function parse_banner($url = "home.pl") /*{{{*/
  618. {
  619. $content = $this->fetch($url);
  620. $item = array();
  621. preg_match('/<a href=(".*?"|\'.*?\'|[^<> ]*)\s[^<>]*?><img src=["\']?([^<>]*?)[\'"]? border=0 width=468 height=60 alt=["\']?([^<>]*?)[\'"]?><\/a>/is', $content, $match);
  622. $link = preg_replace('/(^"|^\'|"$|\'$)/', '', $match[1]);
  623. $item['link'] = (strpos($link, "http") !== false) ? $link : $this->base_url . $link;
  624. $item['image'] = $match[2];
  625. $item['subject'] = $match[3];
  626. return $item;
  627. } /*}}}*/
  628. /**
  629. * 日記を書く
  630. *
  631. * 返り値は bool であるべきでしょか?(日記全般で)
  632. *
  633. * @param string $diary_title 題名
  634. * @param string $diary_body 本文
  635. * @param string $photo1 写真1のパス
  636. * @param string $photo2 写真2のパス
  637. * @param string $photo3 写真3のパス
  638. * @param int $orig_size 圧縮設定
  639. * @param string $news_id
  640. * @return string
  641. */
  642. function add_diary($diary_title, $diary_body, $photo1 = "", $photo2 = "", $photo3 = "", $orig_size = 1, $news_id = "") /*{{{*/
  643. {
  644. $param = $this->_preview_diary($diary_title, $diary_body, $photo1, $photo2, $photo3, $orig_size, $news_id);
  645. $param['submit'] = "confirm";
  646. return $this->submit("add_diary.pl", $param);
  647. } /*}}}*/
  648. /**
  649. * 日記を編集する
  650. *
  651. * @param int $id 編集する日記のID
  652. * @param string $diary_title 題名
  653. * @param string $diary_body 本文
  654. * @param string $photo1 写真1のパス
  655. * @param string $photo2 写真2のパス
  656. * @param string $photo3 写真3のパス
  657. * @param int $orig_size 圧縮設定
  658. * @return string
  659. */
  660. function edit_diary($id, $diary_title, $diary_body, $photo1 = "", $photo2 = "", $photo3 = "", $orig_size = 1, $news_id = "") /*{{{*/
  661. {
  662. $url = "edit_diary.pl?id=" . $id;
  663. $content = $this->fetch($url);
  664. preg_match('/post_key value="(.+?)"/', $content, $match);
  665. $post['post_key'] = $match[1];
  666. $post['diary_title'] = $diary_title;
  667. $post['diary_body'] = $diary_body;
  668. $post['orig_size'] = $orig_size;
  669. $post['news_id'] = $news_id;
  670. $post['submit'] = "main";
  671. $post['form_date'] = "date";
  672. $file['photo1'] = $photo1;
  673. $file['photo2'] = $photo2;
  674. $file['photo3'] = $photo3;
  675. $action = "edit_diary.pl?id=" . $id;
  676. $this->snoopy->set_submit_multipart();
  677. $return = $this->submit($action, $post, $file);
  678. return $return;
  679. } /*}}}*/
  680. /**
  681. * 日記の削除
  682. *
  683. * @param int $id
  684. * @return string
  685. */
  686. function delete_diary($id) /*{{{*/
  687. {
  688. $url = "delete_diary.pl?id=" . $id;
  689. $content = $this->fetch($url);
  690. preg_match('/post_key value="(.+?)"/', $content, $match);
  691. $post['post_key'] = $match[1];
  692. $post['submit'] = "confirm";
  693. $action = "delete_diary.pl?id=" . $id;
  694. $this->snoopy->set_submit_normal();
  695. return $this->submit($action, $post);
  696. } /*}}}*/
  697. /**
  698. * 日記にコメントを付ける
  699. *
  700. * @param int $id コメントを付ける日記のID
  701. * @param string $comment コメント本文
  702. * @return string
  703. */
  704. function add_comment_diary($id, $comment) /*{{{*/
  705. {
  706. $post['comment_body'] = $comment;
  707. $action = "add_comment.pl?diary_id=" . $id;
  708. $this->snoopy->set_submit_normal();
  709. $return = $this->submit($action, $post);
  710. preg_match('/<form action="([^\s"]+)" method=post>(.*)書き込み/is', $return, $match);
  711. preg_match_all('/<input type=["\']?([^<>\s]*?)["\']? name=["\']?([^<>\s]*?)["\']? value=["\']?(.*?)["\']?>/is', $match[2], $post_part, PREG_SET_ORDER);
  712. $post = array();
  713. foreach($post_part as $part) {
  714. $post[$part[2]] = $part[3];
  715. }
  716. return $this->submit($match[1], $post);
  717. } /*}}}*/
  718. function _preview_diary($diary_title, $diary_body, $photo1 = "", $photo2 = "", $photo3 = "", $orig_size = 1, $news_id = "") /*{{{*/
  719. {
  720. $url = "list_diary.pl";
  721. $post = array();
  722. $post['id'] = $this->my_info('id');
  723. $post['news_id'] = $news_id;
  724. $post['diary_title'] = $diary_title;
  725. $post['diary_body'] = $diary_body;
  726. $post['orig_size'] = $orig_size;
  727. $post['submit'] = "main";
  728. $file['photo1'] = $photo1;
  729. $file['photo2'] = $photo2;
  730. $file['photo3'] = $photo3;
  731. $this->snoopy->set_submit_multipart();
  732. $return = $this->submit("add_diary.pl", $post, $file);
  733. preg_match_all('/<input type=["\']?([^<>\s]*?)["\']? name=["\']?([^<>\s]*?)["\']? value=["\']?(.*?)["\']?>/is', $return, $match, PREG_SET_ORDER);
  734. $part = array();
  735. foreach($match as $part) {
  736. if (!in_array($part[2], $this->mixi_diary_formval)) {
  737. continue;
  738. }
  739. $vars[$part[2]] = $part[3];
  740. }
  741. return $vars;
  742. } /*}}}*/
  743. function cache_set($url, $h = "") /*{{{*/
  744. {
  745. $path = $this->cache_url2filename($url);
  746. $filename = $this->cache_dir . $this->cache_prefix . md5($h . $this->email . $this->password . $path) . $this->cache_ext;
  747. if (file_exists($filename) && ((time() - filemtime($filename)) < $this->cache_time) && (empty($this->contents[$this->base_url . $path]))) {
  748. include($filename);
  749. if (!empty($cache)) {
  750. $this->contents[$this->base_url . $path] = $cache;
  751. }
  752. }
  753. } /*}}}*/
  754. function cache_make($url, $h = "") /*{{{*/
  755. {
  756. $path = $this->cache_url2filename($url);
  757. $filename = $this->cache_dir . $this->cache_prefix . md5($h . $this->email . $this->password . $path) . $this->cache_ext;
  758. if ((time() - @filemtime($filename)) > $this->cache_time) {
  759. $dat = '<?php if(!defined("PHPMIXI_CACHE")) exit; ?>';
  760. $dat .= '<?php' . "\n";
  761. $dat .= '$cache = <<<DAT' . "\n";
  762. $dat .= $this->contents[$this->base_url . $path];
  763. $dat .= "\n" . 'DAT;';
  764. $dat .= "\n" . '?>';
  765. $fp = fopen($filename, "w");
  766. flock($fp, 2);
  767. fputs($fp, $dat);
  768. fclose($fp);
  769. }
  770. } /*}}}*/
  771. function cache_clear($url, $h = "") /*{{{*/
  772. {
  773. $path = $this->cache_url2filename($url);
  774. $filename = $this->cache_dir . $this->cache_prefix . md5($h . $this->email . $this->password . $path) . $this->cache_ext;
  775. if (file_exists($filename)) {
  776. unlink($filename);
  777. }
  778. } /*}}}*/
  779. function cache_clear_all() /*{{{*/
  780. {
  781. if ($dh = opendir($this->cache_dir)) {
  782. while (($file = readdir($dh)) !== false) {
  783. if (preg_match('/^' . preg_quote($this->cache_prefix) . '/', $file)) {
  784. unlink($this->cache_dir . $file);
  785. }
  786. }
  787. closedir($dh);
  788. }
  789. } /*}}}*/
  790. function cache_url2filename($url) /*{{{*/
  791. {
  792. $parse = parse_url($url);
  793. $filename = str_replace('/', '', strrchr($parse['path'], "/"));
  794. if (isset($parse['query'])) {
  795. $filename .= "?" . $parse['query'];
  796. }
  797. return $filename;
  798. } /*}}}*/
  799. function my_info($key) /*{{{*/
  800. {
  801. if (!$this->is_logined()) {
  802. return false;
  803. }
  804. switch ($key) {
  805. case 'id':
  806. preg_match('/^([0-9]+)_.+?/', $this->snoopy->cookies['BF_SESSION'], $match);
  807. return intval($match[1]);
  808. break;
  809. }
  810. } /*}}}*/
  811. function mktime($hour = 0, $minute = 0, $second = 0, $month = 0, $day = 0, $year = 0, $is_dst = 0) /*{{{*/
  812. {
  813. return mktime($hour, $minute, $second, $month, $day, $year, $is_dst);
  814. } /*}}}*/
  815. function ts_strip_nl($text) /*{{{*/
  816. {
  817. $text = str_replace("\r\n", "\n", $text);
  818. $text = str_replace("\r", "\n", $text);
  819. $text = str_replace("\n", "", $text);
  820. return $text;
  821. } /*}}}*/
  822. /**
  823. * 新着日記一覧 を取得
  824. *
  825. * @return array
  826. */
  827. function search_diary()/*{{{*/
  828. {
  829. $url = "search_diary.pl";
  830. $content = $this->fetch($url);
  831. $item = array();
  832. $pattern = '/photo\/member\/(.+?)\".+?FFFFFF>(.+?) \((.+?)\).+?FFFFFF>(.+?)<\/td>.+?FFFFFF>(.+?)<\/td>.+?(\d{2})月(\d{2})日 (\d{2}):(\d{2}).+?view_diary\.pl\?id=(\d+)&owner_id=(\d+)/is';
  833. preg_match_all($pattern, $content, $match);
  834. for ( $i = 0; $i < count ( $match[1] ) - 1; $i++ )
  835. {
  836. $item[$i]['image'] = '<img src="http://img-p2.mixi.jp/photo/member/' . $match[1][$i] . '">';
  837. $item[$i]['name'] = $match[2][$i];
  838. $item[$i]['sex'] = $match[3][$i];
  839. $item[$i]['title'] = $match[4][$i];
  840. $item[$i]['content'] = $match[5][$i];
  841. $item[$i]['month'] = $match[6][$i];
  842. $item[$i]['date'] = $match[7][$i];
  843. $item[$i]['hour'] = $match[8][$i];
  844. $item[$i]['minute'] = $match[9][$i];
  845. $item[$i]['id'] = $match[10][$i];
  846. $item[$i]['owner_id']= $match[11][$i];
  847. $item[$i]['url'] = $this->base_url . 'view_diary.pl?id=' . $item[$i]['id'] . '&owner_id=' . $item[$i]['owner_id'];
  848. }
  849. return $item;
  850. }/*}}}*/
  851. /**
  852. * コミュニティー一覧 を取得
  853. * @param string $sort ソート
  854. * @param string $type キーワード検索
  855. * @param string $submit main
  856. * @param string $keyword キーワード
  857. * @param int $category_id カテゴリーID
  858. * @param int $page ページ
  859. *
  860. * @return array
  861. */
  862. function search_community($sort=member, $type=com, $submit=main, $keyword, $category_id=0, $page=1)/*{{{*/
  863. {
  864. $aryData["sort"] = $sort;
  865. $aryData["type"] = $type;
  866. $aryData["submit"] = $submit;
  867. $aryData["keyword"] = $keyword;
  868. $aryData["category_id"] = $category_id;
  869. $aryData["page"] = $page;
  870. $aryKeys = array_keys ( $aryData );
  871. foreach ( $aryKeys as $strKey )
  872. {
  873. $item[] = $strKey . '=' . $aryData[$strKey];
  874. }
  875. $url = "search_community.pl?" . join ( '&', $item );
  876. $content = $this->fetch($url);
  877. $item = array();
  878. if ( preg_match( "/\[ .*?$page <a/i", $content ) )
  879. {
  880. $item[0]["nextpage"] = TRUE;
  881. }
  882. $pattern = '/photo\/comm\/(.+?)\".+?FFFFFF>(.+?).+?FFFFFF>(.+?)<\/td>.+?FFFFFF>(.+?)<\/td>.+?FFFFFF>(.+?)<\/td>.+?view_community\.pl\?id=(\d+)/is';
  883. preg_match_all($pattern, $content, $match);
  884. for ( $i = 0; $i < count ( $match[1] ) - 1; $i++ )
  885. {
  886. $item[$i]['image'] = 'http://img-c3.mixi.jp/photo/comm/' . $match[1][$i];
  887. echo $item[$i]['name'] = $match[2][$i];
  888. $item[$i]['member'] = $match[3][$i];
  889. $item[$i]['discript'] = $match[4][$i];
  890. $item[$i]['category'] = $match[5][$i];
  891. $item[$i]['id'] = $match[6][$i];
  892. $item[$i]['url'] = $this->base_url . 'view_community.pl?id=' . $item[$i]['id'];
  893. }
  894. return $item;
  895. }/*}}}*/
  896. }
  897. ?>