/** * 検索履歴を読み込む */ function tgrep_read_recent_list() { global $_conf; $list = FileCtl::file_read_lines($_conf['expack.tgrep.recent_file'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($list)) { return array(); } return $list; }
/** * ■スレッドあぼーんを複数一括解除する */ function settaborn_off($host, $bbs, $taborn_off_keys) { if (!$taborn_off_keys) { return; } // p2_threads_aborn.idx のパス取得 $taborn_idx = P2Util::idxDirOfHostBbs($host, $bbs) . 'p2_threads_aborn.idx'; // p2_threads_aborn.idx がなければ if (!file_exists($taborn_idx)) { p2die('あぼーんリストが見つかりませんでした。'); } // p2_threads_aborn.idx 読み込み $taborn_lines = FileCtl::file_read_lines($taborn_idx, FILE_IGNORE_NEW_LINES); // 指定keyを削除 foreach ($taborn_off_keys as $val) { $neolines = array(); if ($taborn_lines) { foreach ($taborn_lines as $line) { $lar = explode('<>', $line); if ($lar[1] == $val) { // key発見 // echo "key:{$val} のスレッドをあぼーん解除しました。<br>"; $kaijo_attayo = true; continue; } if (!$lar[1]) { continue; } // keyのないものは不正データ $neolines[] = $line; } } $taborn_lines = $neolines; } // 書き込む if (file_exists($taborn_idx)) { copy($taborn_idx, $taborn_idx . '.bak'); // 念のためバックアップ } $cont = ''; if (is_array($taborn_lines)) { foreach ($taborn_lines as $l) { $cont .= $l . "\n"; } } if (FileCtl::file_write_contents($taborn_idx, $cont) === false) { p2die('cannot write file.'); } /* if (!$kaijo_attayo) { // echo "指定されたスレッドは既にあぼーんリストに載っていないようです。"; } else { // echo "あぼーん解除、完了しました。"; } */ }
/** * 登録されているRSS一覧を表示(携帯用) */ function print_rss_list_k() { global $_conf; $pageTitle = $_conf['expack.misc.multi_favs'] ? FavSetManager::getFavSetPageTitleHt('m_rss_set', 'RSS') : 'RSS'; echo $pageTitle; echo '<hr>'; $i = 1; if ($rss_list = FileCtl::file_read_lines($_conf['expack.rss.setting_path'], FILE_IGNORE_NEW_LINES)) { foreach ($rss_list as $rss_info) { $p = explode("\t", $rss_info); if (count($p) > 1) { $site = $p[0]; $xml = $p[1]; if (!empty($p[2])) { $atom = 1; $atom_q = '&atom=1'; } else { $atom = 0; $atom_q = ''; } if ($i <= 9) { $accesskey_at = $_conf['k_accesskey_at'][$i]; $accesskey_st = "{$i} "; } else { $accesskey_at = ''; $accesskey_st = ''; } $localpath = rss_get_save_path($xml); if (PEAR::isError($localpath)) { echo $accesskey_st . $site . ' ' . $localpath->getMessage() . "<br>\n"; } else { $mtime = file_exists($localpath) ? filemtime($localpath) : 0; $site_en = UrlSafeBase64::encode($site); $xml_en = rawurlencode($xml); $rss_q = sprintf('?xml=%s&site_en=%s%s&mt=%d', $xml_en, $site_en, $atom_q, $mtime); $rss_q_ht = p2h($rss_q); echo "{$accesskey_st}<a href=\"subject_rss.php{$rss_q_ht}\"{$accesskey_at}>{$site}</a><br>\n"; } $i++; } } } }
/** * チェックした書き込み記事を削除する */ function deleMsg($checked_hists) { global $_conf; $lock = new P2Lock($_conf['res_hist_dat'], false); // 読み込んで $reslines = FileCtl::file_read_lines($_conf['res_hist_dat'], FILE_IGNORE_NEW_LINES); if ($reslines === false) { p2die("{$_conf['res_hist_dat']} を開けませんでした"); } // ファイルの下に記録されているものが新しいので逆順にする $reslines = array_reverse($reslines); $neolines = array(); // チェックして整えて if ($reslines) { $n = 1; foreach ($reslines as $ares) { $rar = explode("<>", $ares); // 番号と日付が一致するかをチェックする if (checkMsgID($checked_hists, $n, $rar[2])) { $rmnums[] = $n; // 削除する番号を登録 } $n++; } $neolines = rmLine($rmnums, $reslines); P2Util::pushInfoHtml('<p>p2 info: ' . count($rmnums) . '件のレス記事を削除しました</p>'); } if (is_array($neolines)) { // 行順を戻す $neolines = array_reverse($neolines); $cont = ""; if ($neolines) { $cont = implode("\n", $neolines) . "\n"; } // 書き込む if (FileCtl::file_write_contents($_conf['res_hist_dat'], $cont) === false) { p2die('cannot write file.'); } } }
/** * host,bbsからお気に板をセットする * * @param string $host * @param string $bbs * @param int|string $setfavita 0(解除), 1(追加), 2(トグル), top, up, down, bottom * @param string $itaj * @param int|null $setnum * @return bool */ function setFavItaByHostBbs($host, $bbs, $setfavita, $itaj = null, $setnum = null) { global $_conf; // p2_favita.brd 読み込み $favita_brd = setFavItaGetBrdPath($setnum); $lines = FileCtl::file_read_lines($favita_brd, FILE_IGNORE_NEW_LINES); //================================================ // 処理 //================================================ $neolines = array(); $before_line_num = 0; $was_set = false; // 最初に重複要素を消去 if (!empty($lines)) { $i = -1; foreach ($lines as $l) { $i++; // {{{ 旧データ(ver0.6.0以下)移行措置 if ($l[0] != "\t") { $l = "\t" . $l; } // }}} $lar = explode("\t", $l); if ($lar[1] == $host and $lar[2] == $bbs) { // 重複回避 $before_line_num = $i; $was_set = true; continue; } elseif (!$lar[1] || !$lar[2]) { // 不正データ(host, bbsなし)もアウト continue; } else { $neolines[] = $l; } } } if ($setfavita == 2) { $setfavita = $was_set ? 0 : 1; } // 記録データ設定 if ($setfavita && $host && $bbs) { if (!is_string($itaj) || strlen($itaj) == 0) { $itaj = $bbs; } $newdata = "\t{$host}\t{$bbs}\t{$itaj}"; require_once P2_LIB_DIR . '/getsetposlines.inc.php'; $rec_lines = getSetPosLines($neolines, $newdata, $before_line_num, $setfavita); // 解除 } else { $rec_lines = $neolines; } $cont = ''; if (!empty($rec_lines)) { foreach ($rec_lines as $l) { $cont .= $l . "\n"; } } // 書き込む if (FileCtl::file_write_contents($favita_brd, $cont) === false) { p2die('cannot write file.'); } return true; }
if (is_array($channelInfo) && array_key_exists('title', $channelInfo)) { $site = mb_convert_encoding($channelInfo['title'], 'CP932', 'UTF-8,CP51932,CP932,ASCII'); } } } } // ログに記録する変数を最低限のサニタイズ $xml = preg_replace_callback('/\\s/', 'rawurlencode', $xml); $site = preg_replace('/\\s+/', ' ', $site); $site = p2h($site); // }}} // {{{ 読み込み // rss_pathファイルがなければ生成 FileCtl::make_datafile($_conf['expack.rss.setting_path']); // rss_path読み込み; $lines = FileCtl::file_read_lines($_conf['expack.rss.setting_path'], FILE_IGNORE_NEW_LINES); // }}} // {{{ 処理 // 最初に重複要素を消去 if ($lines) { $i = -1; unset($neolines); foreach ($lines as $l) { $i++; $lar = explode("\t", $l); if ($lar[1] == $xml) { // 重複回避 $before_line_num = $i; continue; } elseif (strlen($lar[1]) == 0) { // URLなしもアウト
/** * スレッドのdatをダウンロードし、保存する * * @param ThreadRead $thread * @return bool */ public static function invoke(ThreadRead $thread) { global $_conf; // {{{ 既得datの取得レス数が適正かどうかを念のためチェック if (file_exists($thread->keydat)) { $dls = FileCtl::file_read_lines($thread->keydat); if (!$dls || count($dls) != $thread->gotnum) { // echo 'bad size!<br>'; unlink($thread->keydat); $thread->gotnum = 0; } } else { $thread->gotnum = 0; } // }}} // {{{ offlaw.cgiからdatをダウンロード $host = $thread->host; $bbs = $thread->bbs; $key = $thread->key; if ($thread->gotnum == 0) { $option = ''; $append = false; } else { $option = sprintf('%d-', $thread->gotnum + 1); $append = true; } // http://[SERVER]/bbs/offlaw.cgi/[BBS]/[KEY]/[OPTION]; $url = "http://{$host}/bbs/offlaw.cgi/{$bbs}/{$key}/{$option}"; $tempfile = $thread->keydat . '.tmp'; FileCtl::mkdirFor($tempfile); if ($append) { touch($tempfile, filemtime($thread->keydat)); } elseif (file_exists($tempfile)) { unlink($tempfile); } $response = P2Util::fileDownload($url, $tempfile); if ($response->isError()) { if (304 != $response->code) { $thread->diedat = true; } return false; } // }}} // {{{ ダウンロードした各行をチェックしつつローカルdatに書き込み $lines = file($tempfile); unlink($tempfile); if ($append) { $fp = fopen($thread->keydat, 'ab'); } else { $fp = fopen($thread->keydat, 'wb'); } if (!$fp) { p2die("cannot write file. ({$thread->keydat})"); } flock($fp, LOCK_EX); foreach ($lines as $i => $line) { // 取得済みレス数をインクリメント $thread->gotnum++; // 行を分解、要素数チェック (厳密には === 6) $lar = explode('<>', rtrim($line)); if (count($lar) >= 5) { // レス番号は保存しないので取り出す $resnum = (int) array_shift($lar); // レス番号と取得済みレス数が異なっていたらあぼーん扱い while ($thread->gotnum < $resnum) { $abn = "あぼーん<>あぼーん<>あぼーん<>あぼーん<>"; if ($thread->gotnum == 1) { $abn .= $lar[4]; // スレタイトル } $abn .= "\n"; fwrite($fp, $abn); $thread->gotnum++; } // 行を書き込む fwrite($fp, implode('<>', $lar) . "\n"); } else { $thread->gotnum--; $lineno = $i + 1; P2Util::pushInfoHtml("<p>rep2 info: dat書式エラー: line {$lineno} of {$url}.</p>"); break; } } flock($fp, LOCK_UN); fclose($fp); // }}} $thread->isonline = true; return true; }
} else { P2Util::pushInfoHtml('<p>×設定を更新保存できませんでした</p>'); } // }}} // {{{ ■デフォルトに戻すボタンが押されていたら } elseif (!empty($_POST['submit_default'])) { if (@unlink($path)) { P2Util::pushInfoHtml('<p>○リストを空にしました</p>'); } else { P2Util::pushInfoHtml('<p>×リストを空にできませんでした</p>'); } } // }}} // {{{ リスト読み込み $formdata = array(); if ($lines = FileCtl::file_read_lines($path, FILE_IGNORE_NEW_LINES)) { $i = 0; foreach ($lines as $l) { $lar = explode("\t", $l); if (strlen($lar[0]) == 0) { continue; } $ar = array('cond' => $lar[0], 'word' => $lar[0], 'ht' => isset($lar[1]) ? $lar[1] : '--', 'hn' => isset($lar[2]) ? (int) $lar[2] : 0, 're' => '', 'ic' => '', 'bbs' => '', 'tt' => ''); // 板縛り if (preg_match('!<bbs>(.+?)</bbs>!', $ar['word'], $matches)) { $ar['bbs'] = $matches[1]; } $ar['word'] = preg_replace('!<bbs>(.*)</bbs>!', '', $ar['word']); // タイトル縛り if (preg_match('!<title>(.+?)</title>!', $ar['word'], $matches)) { $ar['tt'] = $matches[1];
/** * オンライン上のrep2-expack最新版をチェックする * * @return string HTML */ function checkUpdatan() { global $_conf, $p2web_url_r, $expack_url_r, $expack_dl_url_r, $expack_hist_url_r; $no_p2status_dl_flag = false; $ver_txt_url = $_conf['expack.web_url'] . 'version.txt'; $cachefile = P2Util::cacheFileForDL($ver_txt_url); FileCtl::mkdirFor($cachefile); if (file_exists($cachefile)) { // キャッシュの更新が指定時間以内なら if (filemtime($cachefile) > time() - $_conf['p2status_dl_interval'] * 86400) { $no_p2status_dl_flag = true; } } if (empty($no_p2status_dl_flag)) { P2Util::fileDownload($ver_txt_url, $cachefile); } $ver_txt = FileCtl::file_read_lines($cachefile, FILE_IGNORE_NEW_LINES); $update_ver = $ver_txt[0]; $kita = 'キタ━━━━(゚∀゚)━━━━!!!!!!'; //$kita = 'キタ*・゚゚・*:.。..。.:*・゚(゚∀゚)゚・*:.。. .。.:*・゚゚・*!!!!!'; $newversion_found_html = ''; if ($update_ver && version_compare($update_ver, $_conf['p2version'], '>')) { $newversion_found_html = <<<EOP <div class="kakomi"> {$kita}<br> オンライン上に 拡張パック の最新バージョンを見つけますた。<br> rep2-expack rev.{$update_ver} → <a href="{$expack_dl_url_r}"{$_conf['ext_win_target_at']}>ダウンロード</a> / <a href="{$expack_hist_url_r}"{$_conf['ext_win_target_at']}>更新記録</a> </div> <hr class="invisible"> EOP; } return $newversion_found_html; }
/** * お気にスレをセットする * * @param string $host * @param string $bbs * @param string $key * @param int|string $setfavita 0(解除), 1(追加), 2(トグル), top, up, down, bottom * @param string $ttitle * @param int|null $setnum * @return bool */ function setFav($host, $bbs, $key, $setfav, $ttitle = null, $setnum = null) { global $_conf; //================================================================== // key.idx //================================================================== // idxfileのパスを求めて $idxfile = P2Util::idxDirOfHostBbs($host, $bbs) . $key . '.idx'; // 板ディレクトリが無ければ作る // FileCtl::mkdirFor($idxfile); // 既にidxデータがあるなら読み込む if ($lines = FileCtl::file_read_lines($idxfile, FILE_IGNORE_NEW_LINES)) { $data = explode('<>', $lines[0]); } else { $data = array_fill(0, 12, ''); if (is_string($ttitle) && strlen($ttitle)) { $data[0] = p2h($ttitle, false); } } // {{{ スレッド.idx 記録 if (($setfav == '0' || $setfav == '1') && $_conf['favlist_idx'] == $_conf['orig_favlist_idx']) { // お気にスレから外した結果、idxの意味がなくなれば削除する if ($setfav == '0' and !$data[3] && !$data[4] && $data[9] <= 1) { @unlink($idxfile); } else { $sar = array($data[0], $key, $data[2], $data[3], $data[4], $data[5], $setfav, $data[7], $data[8], $data[9], $data[10], $data[11], $data[12]); P2Util::recKeyIdx($idxfile, $sar); } } // }}} //================================================================== // favlist.idx //================================================================== if (!is_null($setnum) && $_conf['expack.misc.multi_favs']) { if (0 < $setnum && $setnum <= $_conf['expack.misc.favset_num']) { $favlist_idx = $_conf['pref_dir'] . sprintf('/p2_favlist%d.idx', $setnum); } else { $favlist_idx = $_conf['orig_favlist_idx']; } } else { $favlist_idx = $_conf['favlist_idx']; } // favlistファイルがなければ生成 FileCtl::make_datafile($favlist_idx); // favlist読み込み $favlines = FileCtl::file_read_lines($favlist_idx, FILE_IGNORE_NEW_LINES); //================================================ // 処理 //================================================ $neolines = array(); $before_line_num = 0; $was_set = false; // 最初に重複要素を削除しておく if (!empty($favlines)) { $i = -1; foreach ($favlines as $l) { $i++; $lar = explode('<>', $l); // 重複回避 if ($lar[1] == $key && $lar[11] == $bbs) { $before_line_num = $i; // 移動前の行番号をセット $was_set = true; continue; // keyのないものは不正データなのでスキップ } elseif (!$lar[1]) { continue; } else { $neolines[] = $l; } } } if ($setfav == 2) { $setfav = $was_set ? 0 : 1; } // 記録データ設定 if ($setfav) { if (!function_exists('getSetPosLines')) { include P2_LIB_DIR . '/getsetposlines.inc.php'; } $newdata = "{$data[0]}<>{$key}<>{$data[2]}<>{$data[3]}<>{$data[4]}<>{$data[5]}<>1<>{$data[7]}<>{$data[8]}<>{$data[9]}<>{$host}<>{$bbs}"; $rec_lines = getSetPosLines($neolines, $newdata, $before_line_num, $setfav); } else { $rec_lines = $neolines; } $cont = ''; if (!empty($rec_lines)) { foreach ($rec_lines as $l) { $cont .= $l . "\n"; } } // 書き込む if (FileCtl::file_write_contents($favlist_idx, $cont) === false) { p2die('cannot write file.'); } //================================================ // お気にスレ共有 //================================================ if ($_conf['join_favrank'] && $_conf['favlist_idx'] == $_conf['orig_favlist_idx']) { if ($setfav == "0") { $act = "out"; } elseif ($setfav == "1") { $act = "add"; } else { return; } $itaj = P2Util::getItaName($host, $bbs); $post = array("host" => $host, "bbs" => $bbs, "key" => $key, "ttitle" => $data[0], "ita" => $itaj, "act" => $act); postFavRank($post); } return true; }
//================================================= // スレの指定 //================================================= kspDetectThread(); // global $host, $bbs, $key, $ls $aThread = new Thread(); // hostを分解してidxファイルのパスを求める if (!isset($aThread->keyidx)) { $aThread->setThreadPathInfo($host, $bbs, $key); } $aThread->itaj = P2Util::getItaName($host, $bbs); if (!$aThread->itaj) { $aThread->itaj = $aThread->bbs; } // idxファイルがあれば読み込む if ($lines = FileCtl::file_read_lines($aThread->keyidx, FILE_IGNORE_NEW_LINES)) { $idx_data = explode('<>', $lines[0]); } else { p2die('指定されたスレッドのidxがありません。'); } $aThread->getThreadInfoFromIdx(); //================================================= // 表示用変数を設定 //================================================= $ptitle_ht = $aThread->ttitle_hd; $thread_url = "{$_conf['read_php']}?host={$host}&bbs={$bbs}&key={$key}{$_conf['k_at_a']}"; $params = array(); if (!empty($_GET['from_read_new'])) { $params['from_read_new'] = '1'; } $default = !empty($_GET['spm_default']) ? intval($_GET['spm_default']) : '';
EOP; } $body_at = $_conf['ktai'] ? $_conf['k_colors'] : ' onload="top.document.title=self.document.title;"'; echo "</head><body{$body_at}>\n"; P2Util::printInfoHtml(); //================================================================ // メイン部分HTML表示 //================================================================ //================================================================ // お気に板 //================================================================ // favitaファイルがなければ生成 FileCtl::make_datafile($_conf['favita_brd']); // favita読み込み $lines = FileCtl::file_read_lines($_conf['favita_brd'], FILE_IGNORE_NEW_LINES); $okini_itas = array(); $i = 0; if (is_array($lines)) { foreach ($lines as $l) { if (preg_match("/^\t?(.+?)\t(.+?)\t(.+?)\$/", $l, $matches)) { $id = "li{$i}"; $okini_itas[$id]['itaj'] = $itaj = rtrim($matches[3]); $okini_itas[$id]['itaj_en'] = $itaj_en = UrlSafeBase64::encode($itaj); $okini_itas[$id]['host'] = $host = $matches[1]; $okini_itas[$id]['bbs'] = $bbs = $matches[2]; $okini_itas[$id]['itaj_view'] = p2h($itaj); $okini_itas[$id]['itaj_ht'] = "&itaj_en=" . $itaj_en; $okini_itas[$id]['value'] = StrCtl::toJavaScript("{$host}@{$bbs}@{$itaj_en}"); $i++; }
/** * フィードリストを表示する * * @param string $title * @param int $no * @return void */ function menu_iphone_show_feed_list($title, $no = null) { global $_conf; require_once P2EX_LIB_DIR . '/rss/common.inc.php'; echo "<ul id=\"rss{$no}\" title=\"{$title}\">"; $errors = array(); if ($rss_list = FileCtl::file_read_lines($_conf['expack.rss.setting_path'], FILE_IGNORE_NEW_LINES)) { foreach ($rss_list as $rss_info) { $p = explode("\t", $rss_info); if (count($p) > 1) { $site = $p[0]; $xml = $p[1]; if (!empty($p[2])) { $atom = 1; $atom_q = '&atom=1'; } else { $atom = 0; $atom_q = ''; } $localpath = rss_get_save_path($xml); if (PEAR::isError($localpath)) { $errors[] = array($site, $localpath->getMessage()); } else { $mtime = file_exists($localpath) ? filemtime($localpath) : 0; $site_en = UrlSafeBase64::encode($site); $xml_en = rawurlencode($xml); $rss_q = sprintf('?xml=%s&site_en=%s%s&mt=%d', $xml_en, $site_en, $atom_q, $mtime); $rss_q_ht = p2h($rss_q); echo "<li><a href=\"subject_rss.php{$rss_q_ht}\" target=\"_self\">{$site}</a></li>"; } } } } if (count($errors)) { echo '<li class="group">エラー</li>'; foreach ($errors as $error) { echo "<li>{$error[0]} - {$error[1]}</li>"; } } //echo '<li class="group"> </li>'; echo '<li><a href="editrss.php'; if ($_conf['expack.misc.multi_favs']) { echo '?m_rss_set=' . $no; } echo '" class="align-r" target="_self">編集</a></li>'; echo "</ul>\n"; }
$checked_hists = $_POST['checked_hists']; } elseif (isset($_GET['checked_hists'])) { $checked_hists = $_GET['checked_hists']; } $checked_hists and deleMsg($checked_hists); } // データPHP形式(p2_res_hist.dat.php, タブ区切り)の書き込み履歴を、dat形式(p2_res_hist.dat, <>区切り)に変換する P2Util::transResHistLogPhpToDat(); //====================================================================== // メイン //====================================================================== //================================================================== // 特殊DAT読み //================================================================== // 読み込んで if (!($datlines = FileCtl::file_read_lines($_conf['res_hist_dat'], FILE_IGNORE_NEW_LINES))) { echo '<html><head><title>', $ptitle, '</title></head>', '<body><p>書き込み履歴内容は空っぽのようです</p></body></html>'; exit; } // ファイルの下に記録されているものが新しい $datlines = array_reverse($datlines); $aResHist = new ResHist(); $aResHist->readLines($datlines); // HTMLプリント用変数 $htm['checkall'] = '全てのチェックボックスを <input type="button" onclick="hist_checkAll(true)" value="選択"> <input type="button" onclick="hist_checkAll(false)" value="解除">'; $htm['toolbar'] = <<<EOP チェックした項目を<input type="submit" name="submit" value="{$deletemsg_st}"> {$htm['checkall']} EOP;
function readNew($aThread) { global $_conf, $newthre_num, $STYLE; global $word; static $favlist_titles = null; if ($_conf['expack.misc.multi_favs'] && is_null($favlist_titles)) { $favlist_titles = FavSetManager::getFavSetTitles('m_favlist_set'); if (empty($favlist_titles)) { $favlist_titles = array(); } if (!isset($favlist_titles[0]) || $favlist_titles[0] == '') { $favlist_titles[0] = 'お気にスレ'; } for ($i = 1; $i <= $_conf['expack.misc.favset_num']; $i++) { if (!isset($favlist_titles[$i]) || $favlist_titles[$i] == '') { $favlist_titles[$i] = 'お気にスレ' . $i; } } } $newthre_num++; //========================================================== // idxの読み込み //========================================================== // hostを分解してidxファイルのパスを求める $aThread->setThreadPathInfo($aThread->host, $aThread->bbs, $aThread->key); // FileCtl::mkdirFor($aThread->keyidx); // 板ディレクトリが無ければ作る // この操作はおそらく不要 $aThread->itaj = P2Util::getItaName($aThread->host, $aThread->bbs); if (!$aThread->itaj) { $aThread->itaj = $aThread->bbs; } // idxファイルがあれば読み込む if ($lines = FileCtl::file_read_lines($aThread->keyidx, FILE_IGNORE_NEW_LINES)) { $data = explode('<>', $lines[0]); } else { $data = array_fill(0, 12, ''); } $aThread->getThreadInfoFromIdx(); //================================================================== // DATのダウンロード //================================================================== if (!($word and file_exists($aThread->keydat))) { $aThread->downloadDat(); } // DATを読み込み $aThread->readDat(); $aThread->setTitleFromLocal(); // ローカルからタイトルを取得して設定 //=========================================================== // 表示レス番の範囲を設定 //=========================================================== // 取得済みなら if ($aThread->isKitoku()) { $from_num = $aThread->readnum + 1 - $_conf['respointer'] - $_conf['before_respointer_new']; if ($from_num > $aThread->rescount) { $from_num = $aThread->rescount - $_conf['respointer'] - $_conf['before_respointer_new']; } if ($from_num < 1) { $from_num = 1; } //if (!$aThread->ls) { $aThread->ls = "{$from_num}-"; //} } $aThread->lsToPoint(); //================================================================== // ヘッダ 表示 //================================================================== $motothre_url = $aThread->getMotoThread(false, ''); $ttitle_en = UrlSafeBase64::encode($aThread->ttitle); $ttitle_en_q = '&ttitle_en=' . $ttitle_en; $bbs_q = '&bbs=' . $aThread->bbs; $key_q = '&key=' . $aThread->key; $host_bbs_key_q = 'host=' . $aThread->host . $bbs_q . $key_q; $popup_q = '&popup=1'; // require_once P2_LIB_DIR . '/read_header.inc.php'; $prev_thre_num = $newthre_num - 1; $next_thre_num = $newthre_num + 1; if ($prev_thre_num != 0) { $prev_thre_ht = "<a href=\"#ntt{$prev_thre_num}\">▲</a>"; } else { $prev_thre_ht = ''; } $next_thre_ht = "<a id=\"ntta{$next_thre_num}\" href=\"#ntt{$next_thre_num}\">▼</a>"; P2Util::printInfoHtml(); // ヘッダ部分HTML $read_header_ht = <<<EOP <table id="ntt{$newthre_num}" class="toolbar"> <tr> <td class="lblock"><h3 class="thread_title">{$aThread->ttitle_hd}</h3></td> <td class="rblock">{$prev_thre_ht} {$next_thre_ht}</td> </tr> </table> EOP; //================================================================== // ローカルDatを読み込んでHTML表示 //================================================================== $aThread->resrange['nofirst'] = true; $GLOBALS['newres_to_show_flag'] = false; if ($aThread->rescount) { $aShowThread = new ShowThreadPc($aThread, true); if ($_conf['expack.spm.enabled']) { $read_header_ht .= $aShowThread->getSpmObjJs(); } $res1 = $aShowThread->quoteOne(); $read_cont_ht = $res1['q']; $read_cont_ht .= $aShowThread->getDatToHtml(); // レス追跡カラー if ($_conf['backlink_coloring_track']) { $read_cont_ht .= $aShowThread->getResColorJs(); } // IDカラーリング if ($_conf['coloredid.enable'] > 0 && $_conf['coloredid.click'] > 0) { $read_header_ht .= $aShowThread->getIdColorJs(); } // 外部ツール $pluswiki_js = ''; if ($_conf['wiki.idsearch.spm.mimizun.enabled']) { require_once './plugin/mimizun/mimizun.class.php'; $mimizun = new mimizun(); $mimizun->host = $aThread->host; $mimizun->bbs = $aThread->bbs; if ($mimizun->isEnable()) { $pluswiki_js .= "WikiTools.addMimizun({$aShowThread->spmObjName});"; } } if ($_conf['wiki.idsearch.spm.hissi.enabled']) { require_once './plugin/hissi/hissi.class.php'; $hissi = new hissi(); $hissi->host = $aThread->host; $hissi->bbs = $aThread->bbs; if ($hissi->isEnable()) { $pluswiki_js .= "WikiTools.addHissi({$aShowThread->spmObjName});"; } } if ($_conf['wiki.idsearch.spm.stalker.enabled']) { require_once './plugin/stalker/stalker.class.php'; $stalker = new stalker(); $stalker->host = $aThread->host; $stalker->bbs = $aThread->bbs; if ($stalker->isEnable()) { $pluswiki_js .= "WikiTools.addStalker({$aShowThread->spmObjName});"; } } if ($pluswiki_js) { $read_header_ht .= <<<EOP <script type="text/javascript"> //<![CDATA[ {$pluswiki_js} //]]> </script> EOP; } unset($aShowThread); } //================================================================== // フッタ 表示 //================================================================== // $read_footer_navi_new 続きを読む 新着レスの表示 $newtime = date("gis"); // リンクをクリックしても再読込しない仕様に対抗するダミークエリー $info_st = '情報'; $delete_st = '削除'; $prev_st = '前'; $next_st = '次'; $dores_st = '書込'; $read_footer_navi_new = "<a href=\"{$_conf['read_php']}?{$host_bbs_key_q}&ls={$aThread->rescount}-&nt={$newtime}#r{$aThread->rescount}\">新着レスの表\示</a>"; if (!empty($_conf['disable_res'])) { $dores_ht = <<<EOP <a href="{$motothre_url}" target="_blank">{$dores_st}</a> EOP; } else { $dores_ht = <<<EOP <a href="post_form.php?{$host_bbs_key_q}&rescount={$aThread->rescount}{$ttitle_en_q}" target='_self' onclick="return OpenSubWin('post_form.php?{$host_bbs_key_q}&rescount={$aThread->rescount}{$ttitle_en_q}{$popup_q}&from_read_new=1',{$STYLE['post_pop_size']},1,0)">{$dores_st}</a> EOP; } // ツールバー部分HTML ======= // お気にマーク設定 $itaj_hd = htmlspecialchars($aThread->itaj, ENT_QUOTES); $similar_q = '&itaj_en=' . UrlSafeBase64::encode($aThread->itaj) . '&method=similar&word=' . rawurlencode($aThread->ttitle_hc); if ($_conf['expack.misc.multi_favs']) { $toolbar_setfav_ht = 'お気に['; $favdo = !empty($aThread->favs[0]) ? 0 : 1; $favdo_q = '&setfav=' . $favdo; $favmark = $favdo ? '+' : '★'; $favtitle = $favlist_titles[0] . ($favdo ? 'に追加' : 'から外す'); $setnum_q = '&setnum=0'; $toolbar_setfav_ht .= <<<EOP <span class="favdo set0"><a href="info.php?{$host_bbs_key_q}{$ttitle_en_q}{$favdo_q}{$setnum_q}" target="info" onclick="return setFavJs('{$host_bbs_key_q}{$ttitle_en_q}', '{$favdo}', {$STYLE['info_pop_size']}, 'read_new', this, '0');" title="{$favtitle}">{$favmark}</a></span> EOP; for ($i = 1; $i <= $_conf['expack.misc.favset_num']; $i++) { $favdo = !empty($aThread->favs[$i]) ? 0 : 1; $favdo_q = '&setfav=' . $favdo; $favmark = $favdo ? $i : '★'; $favtitle = $favlist_titles[$i] . ($favdo ? 'に追加' : 'から外す'); $setnum_q = '&setnum=' . $i; $toolbar_setfav_ht .= <<<EOP |<span class="favdo set{$i}"><a href="info.php?{$host_bbs_key_q}{$ttitle_en_q}{$favdo_q}{$setnum_q}" target="info" onclick="return setFavJs('{$host_bbs_key_q}{$ttitle_en_q}', '{$favdo}', {$STYLE['info_pop_size']}, 'read_new', this, '{$i}');" title="{$favtitle}">{$favmark}</a></span> EOP; } $toolbar_setfav_ht .= ']'; } else { $favdo = !empty($aThread->fav) ? 0 : 1; $favdo_q = '&setfav=' . $favdo; $favmark = $favdo ? '+' : '★'; $favtitle = $favdo ? 'お気にスレに追加' : 'お気にスレから外す'; $toolbar_setfav_ht = <<<EOP <span class="favdo"><a href="info.php?{$host_bbs_key_q}{$ttitle_en_q}{$favdo_q}" target="info" onclick="return setFavJs('{$host_bbs_key_q}{$ttitle_en_q}', '{$favdo}', {$STYLE['info_pop_size']}, 'read_new', this, '0');" title="{$favtitle}">お気に{$favmark}</a></span> EOP; } $toolbar_right_ht = <<<EOTOOLBAR <a href="{$_conf['subject_php']}?{$host_bbs_key_q}" target="subject" title="板を開く">{$itaj_hd}</a> <a href="info.php?{$host_bbs_key_q}{$ttitle_en_q}" target="info" onclick="return OpenSubWin('info.php?{$host_bbs_key_q}{$ttitle_en_q}{$popup_q}',{$STYLE['info_pop_size']},1,0)" title="スレッド情報を表\示">{$info_st}</a> {$toolbar_setfav_ht} <span><a href="info.php?{$host_bbs_key_q}{$ttitle_en_q}&dele=true" target="info" onclick="return deleLog('{$host_bbs_key_q}{$ttitle_en_q}', {$STYLE['info_pop_size']}, 'read_new', this);" title="ログを削除する">{$delete_st}</a></span> <!-- <a href="info.php?{$host_bbs_key_q}{$ttitle_en_q}&taborn=2" target="info" onclick="return OpenSubWin('info.php?{$host_bbs_key_q}{$ttitle_en_q}&popup=2&taborn=2',{$STYLE['info_pop_size']},0,0)" title="スレッドのあぼーん状態をトグルする">あぼん</a> --> <a href="{$motothre_url}" title="板サーバ上のオリジナルスレを表\示" onmouseover="showMotoLsPopUp(event, this)" onmouseout="hideMotoLsPopUp()">元スレ</a> <a href="{$_conf['subject_php']}?{$host_bbs_key_q}{$similar_q}" target="subject" title="タイトルが似ているスレッドを検索">似スレ</a> EOTOOLBAR; // レスのすばやさ $spd_ht = ""; if ($spd_st = $aThread->getTimePerRes() and $spd_st != "-") { $spd_ht = '<span class="spd" title="すばやさ=時間/レス">' . "" . $spd_st . "" . '</span>'; } // datサイズ if (file_exists($aThread->keydat) && ($dsize_ht = filesize($aThread->keydat))) { $dsize_ht = sprintf('<span class="spd" title="%s">%01.1fKB</span> |', 'datサイズ', $dsize_ht / 1024); } else { $dsize_ht = ''; } // IC2リンク、件数 if ($_conf['expack.ic2.enabled'] && $_conf['expack.ic2.thread_imagelink']) { $spanid = 'ic2_count_' . sprintf('%u', crc32($aThread->keydat)); $ic2navi = '<a href="iv2.php?field=memo&key=' . rawurlencode($aThread->ttitle) . '" target="_blank">キャッシュ画像' . ($_conf['expack.ic2.thread_imagecount'] ? '<span id="ic2_count_' . sprintf('%u', crc32($aThread->keydat)) . '"></span>' : '') . '</a> '; } // フッタ部分HTML $read_footer_ht = <<<EOP <table class="toolbar"> <tr> <td class="lblock">{$res1['body']} | <a href="{$_conf['read_php']}?{$host_bbs_key_q}&offline=1&rescount={$aThread->rescount}#r{$aThread->rescount}">{$aThread->ttitle_hd}</a> | {$dores_ht} {$dsize_ht} {$spd_ht}</td> <td class="rblock">{$ic2navi}{$toolbar_right_ht}</td> <td class="rblock"><a href="#ntt{$newthre_num}">▲</a></td> </tr> </table> EOP; // 透明あぼーんで表示がない場合はスキップ if ($GLOBALS['newres_to_show_flag']) { echo '<div style="width:100%;">' . "\n"; // ほぼIE ActiveXのGray()のためだけに囲ってある echo $read_header_ht; echo $read_cont_ht; echo $read_footer_ht; echo '</div>' . "\n\n"; echo '<hr>' . "\n\n"; } //================================================================== // key.idx の値設定 //================================================================== if ($aThread->rescount) { $aThread->readnum = min($aThread->rescount, max(0, $data[5], $aThread->resrange['to'])); $newline = $aThread->readnum + 1; // $newlineは廃止予定だが、旧互換用に念のため $sar = array($aThread->ttitle, $aThread->key, $data[2], $aThread->rescount, $aThread->modified, $aThread->readnum, $data[6], $data[7], $data[8], $newline, $data[10], $data[11], $aThread->datochiok); P2Util::recKeyIdx($aThread->keyidx, $sar); // key.idxに記録 } }
/** * スレッド情報を取得する * * @param string $host * @param string $bbs * @param string $key * @return object スレッド情報 */ function get_thread_info($host, $bbs, $key) { global $_conf; $group = P2Util::getHostGroupName($host); $info = new stdClass(); $info->type = 'thread'; $info->group = $group; $info->host = $host; $info->bbs = $bbs; $info->key = $key; $aThread = new Thread(); // hostを分解してidxファイルのパスを求める $aThread->setThreadPathInfo($host, $bbs, $key); $key_line = $aThread->getThreadInfoFromIdx(); // $aThread->length をset $aThread->getDatBytesFromLocalDat(); // 板名を取得 $aThread->itaj = P2Util::getItaName($host, $bbs); if (!$aThread->itaj) { if (isset($_GET['itaj_en'])) { $aThread->itaj = UrlSafeBase64::decode($_GET['itaj_en']); } else { $aThread->itaj = $bbs; } } $info->itaj = $aThread->itaj; // スレタイトルを取得 if (!$aThread->ttitle) { if (isset($_GET['ttitle_en'])) { $aThread->setTtitle(UrlSafeBase64::decode($_GET['ttitle_en'])); } else { $aThread->setTitleFromLocal(); } } $info->ttitle = $aThread->ttitle; // お気にスレ登録状況を取得 $favs = array(); if ($_conf['expack.misc.multi_favs']) { $favlist_titles = FavSetManager::getFavSetTitles('m_favlist_set'); for ($i = 0; $i <= $_conf['expack.misc.favset_num']; $i++) { if (!isset($favlist_titles[$i]) || $favlist_titles[$i] == '') { if ($i == 0) { $favtitle = 'お気にスレ'; } else { $favtitle = "お気にスレ{$i}"; } } else { $favtitle = $favlist_titles[$i]; } $favs[$i] = array('title' => $favtitle, 'set' => !empty($aThread->favs[$i])); } } else { $favs[0] = array('title' => 'お気にスレ', 'set' => !empty($aThread->fav)); } $info->favs = $favs; // 殿堂チェック $info->palace = false; if ($pallines = FileCtl::file_read_lines($_conf['palace_idx'], FILE_IGNORE_NEW_LINES)) { foreach ($pallines as $l) { $palarray = explode('<>', $l); if ($aThread->key == $palarray[1] && $aThread->bbs == $palarray[11]) { if (P2Util::getHostGroupName($palarray[10]) == $group) { $info->palace = true; break; } } } } // スレッドあぼーんチェック $info->taborn = false; $taborn_idx = P2Util::idxDirOfHostBbs($host, $bbs) . 'p2_threads_aborn.idx'; if ($tabornlines = FileCtl::file_read_lines($taborn_idx, FILE_IGNORE_NEW_LINES)) { foreach ($tabornlines as $l) { $tabornarray = explode('<>', $l); if ($key == $tabornarray[1]) { $info->taborn = true; break; } } } // ログ関連 $hasLog = false; if (file_exists($aThread->keydat)) { $info->keydat = $aThread->keydat; $info->length = $aThread->length; $hasLog = true; } else { $info->keydat = null; $info->length = -1; } if (file_exists($aThread->keyidx)) { $info->keyidx = $aThread->keyidx; $hasLog = true; } else { $info->keyidx = null; } if ($aThread->gotnum) { $info->gotnum = $aThread->gotnum; } elseif ($hasLog) { $info->gotnum = 0; } else { $info->gotnum = -1; } return $info; }
/** * 既得スレッドデータをkey.idxから取得する */ public function getThreadInfoFromIdx() { //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('getThreadInfoFromIdx'); if (!($lines = FileCtl::file_read_lines($this->keyidx))) { //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('getThreadInfoFromIdx'); return false; } $key_line = rtrim($lines[0]); $lar = explode('<>', $key_line); if (!$this->ttitle) { if ($lar[0]) { $this->setTtitle(rtrim($lar[0])); } } if ($lar[5]) { $this->readnum = intval($lar[5]); // 旧互換措置($lar[9] newlineの廃止) } elseif ($lar[9]) { $this->readnum = $lar[9] - 1; } if ($lar[3]) { $this->gotnum = intval($lar[3]); if ($this->rescount) { $this->unum = $this->rescount - $this->readnum; // machi bbs はsubjectの更新にディレイがあるようなので調整しておく if ($this->unum < 0) { $this->unum = 0; } $this->nunum = $this->unum; } } else { $this->gotnum = 0; } $this->fav = (int) $lar[6]; // あえてboolでなく if (isset($lar[12])) { $this->datochiok = $lar[12]; } /* // 現在key.idxのこのカラムは使用していない。datサイズは直接ファイルの大きさを読み取って調べる if ($lar[2]) { $this->length = $lar[2]; } */ if ($lar[4]) { $this->modified = $lar[4]; } //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('getThreadInfoFromIdx'); return $key_line; }
/** * お気に板をプリントする for 携帯 */ public function printFavIta() { global $_conf; $show_flag = false; // favita読み込み if ($lines = FileCtl::file_read_lines($_conf['favita_brd'], FILE_IGNORE_NEW_LINES)) { if ($_conf['expack.misc.multi_favs']) { $favset_title = FavSetManager::getFavSetPageTitleHt('m_favita_set', 'お気に板'); } else { $favset_title = 'お気に板'; } echo "<div>{$favset_title}"; if ($_conf['merge_favita']) { echo " (<a href=\"{$_conf['subject_php']}?spmode=merge_favita{$_conf['k_at_a']}{$_conf['m_favita_set_at_a']}\">まとめ</a>)"; } echo " [<a href=\"editfavita.php{$_conf['k_at_q']}{$_conf['m_favita_set_at_a']}\">編集</a>]<hr>"; $i = 0; foreach ($lines as $l) { $i++; if (preg_match("/^\t?(.+)\t(.+)\t(.+)\$/", $l, $matches)) { $itaj = rtrim($matches[3]); $itaj_view = p2h($itaj); $itaj_en = UrlSafeBase64::encode($itaj); if ($i <= 9) { $accesskey_at = $_conf['k_accesskey_at'][$i]; $accesskey_st = $_conf['k_accesskey_st'][$i]; } else { $accesskey_at = ''; $accesskey_st = ''; } echo <<<EOP <a href="{$_conf['subject_php']}?host={$matches[1]}&bbs={$matches[2]}&itaj_en={$itaj_en}{$_conf['k_at_a']}"{$accesskey_at}>{$accesskey_st}{$itaj_view}</a><br> EOP; // [<a href="{$_SERVER['SCRIPT_NAME']}?host={$matches[1]}&bbs={$matches[2]}&setfavita=0&view=favita{$_conf['k_at_a']}{$_conf['m_favita_set_at_a']}">削</a>] $show_flag = true; } } echo "</div>"; } if (empty($show_flag)) { echo "<p>お気に板はまだないようだ</p>"; } }
if (mt_rand(0, 99) == 0) { P2Util::garbageCollection($cache_options['cacheDir'], $cache_options['lifeTime'], 'cache_' . $cache_group_result); P2Util::garbageCollection($cache_options['cacheDir'], $cache_options['lifeTime'], 'cache_' . $cache_group_profile); } $errors = isset($search_result['errors']) ? $search_result['errors'] : null; $threads = isset($search_result['threads']) ? $search_result['threads'] : null; $profile = $search_profile['profile']; $modified = strtotime($search_profile['modified']); if ($errors) { $cache->remove($cache_id_result, $cache_group_result); $cache->remove($cache_id_profile, $cache_group_profile); } else { // 検索履歴を更新 if ($_conf['expack.tgrep.recent_num'] > 0) { FileCtl::make_datafile($_conf['expack.tgrep.recent_file'], $_conf['expack.tgrep.file_perm']); $tgrep_recent_list = FileCtl::file_read_lines($_conf['expack.tgrep.recent_file'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($tgrep_recent_list)) { $tgrep_recent_list = array(); } array_unshift($tgrep_recent_list, preg_replace('/[\\r\\n\\t]/', ' ', trim($_GET['Q']))); $tgrep_recent_list = array_unique($tgrep_recent_list); while (count($tgrep_recent_list) > $_conf['expack.tgrep.recent_num']) { array_pop($tgrep_recent_list); } $tgrep_recent_data = implode("\n", $tgrep_recent_list) . "\n"; if (FileCtl::file_write_contents($_conf['expack.tgrep.recent_file'], $tgrep_recent_data) === false) { p2die('cannot write file.'); } chmod($_conf['expack.tgrep.recent_file'], $_conf['p2_perm']); } }
/** * すべてのお気にスレ・お気に板を読み込む * * @param bool $force * @return void */ public static function loadAllFavSet($force = false) { global $_conf; static $done = false; if ($done && !$force) { return; } // キャッシュの有無をチェック $cache_file = $_conf['cache_dir'] . DIRECTORY_SEPARATOR . 'favset_cache.txt'; if ($force || !file_exists($cache_file)) { $use_cache = false; } else { $cache_mtime = filemtime($cache_file); if (filemtime(__FILE__) > $cache_mtime) { $use_cache = false; } else { $use_cache = true; } } // キャッシュが有効かどうかをチェック if ($use_cache && file_exists($_conf['orig_favlist_idx']) && filemtime($_conf['orig_favlist_idx']) > $cache_mtime) { $use_cache = false; } if ($use_cache && file_exists($_conf['orig_favita_brd']) && filemtime($_conf['orig_favita_brd']) > $cache_mtime) { $use_cache = false; } // 読み込み対象ファイルのリストを作成すると同時にキャッシュが有効かどうかをチェック $favlist_idxes = array($_conf['orig_favlist_idx']); $favita_brds = array($_conf['orig_favita_brd']); for ($i = 1; $i <= $_conf['expack.misc.favset_num']; $i++) { $favlist_idx = $_conf['pref_dir'] . DIRECTORY_SEPARATOR . sprintf('p2_favlist%d.idx', $i); if ($use_cache && file_exists($favlist_idx) && filemtime($favlist_idx) > $cache_mtime) { $use_cache = false; } $favlist_idxes[$i] = $favlist_idx; $favita_brd = $_conf['pref_dir'] . DIRECTORY_SEPARATOR . sprintf('p2_favita%d.brd', $i); if ($use_cache && file_exists($favita_brd) && filemtime($favita_brd) > $cache_mtime) { $use_cache = false; } $favita_brds[$i] = $favita_brd; } // キャッシュが有効なら、それを使う if ($use_cache) { $cache = unserialize(file_get_contents($cache_file)); if (is_array($cache)) { list($_conf['favlists'], $_conf['favitas']) = $cache; $done = true; return; } } // すべてのお気にスレを読み込む $_conf['favlists'] = array(); foreach ($favlist_idxes as $i => $favlist_idx) { $_conf['favlists'][$i] = array(); if ($favlines = FileCtl::file_read_lines($favlist_idx, FILE_IGNORE_NEW_LINES)) { foreach ($favlines as $l) { $lar = explode('<>', $l); // bbsのないものは不正データなのでスキップ if (!isset($lar[11])) { continue; } $key = $lar[1]; $host = $lar[10]; $bbs = $lar[11]; $group = P2Util::getHostGroupName($host); $_conf['favlists'][$i][] = array('group' => $group, 'host' => $host, 'bbs' => $bbs, 'key' => $key); } } } // すべてのお気に板を読み込む $_conf['favitas'] = array(); foreach ($favita_brds as $i => $favita_brd) { $_conf['favitas'][$i] = array(); if ($favlines = FileCtl::file_read_lines($favita_brd, FILE_IGNORE_NEW_LINES)) { foreach ($favlines as $l) { $lar = explode("\t", $l); $host = $lar[1]; $bbs = $lar[2]; $itaj = $lar[3]; $group = P2Util::getHostGroupName($host); $_conf['favitas'][$i][] = array('group' => $group, 'host' => $host, 'bbs' => $bbs, 'itaj' => $itaj); } } } //キャッシュに保存する if (!is_dir($_conf['pref_dir'])) { FileCtl::mkdirFor($cache_file); } file_put_contents($cache_file, serialize(array($_conf['favlists'], $_conf['favitas']))); $done = true; }
/** * brdファイルを生成する * * @return string brdファイルのパス */ public function makeBrdFile($cachefile) { global $_conf, $word; $p2brdfile = $cachefile . ".p2.brd"; FileCtl::make_datafile($p2brdfile); $data = FileCtl::file_read_lines($cachefile); $cont = ''; $this->setBrdMatch($cachefile); // パターンマッチ形式を登録 $this->setBrdList($data); // カテゴリーと板をセット if ($this->categories) { foreach ($this->categories as $cate) { if ($cate->num > 0) { $cont .= $cate->name . "\t0\n"; foreach ($cate->menuitas as $mita) { $cont .= "\t{$mita->host}\t{$mita->bbs}\t{$mita->itaj}\n"; } } } } if ($cont) { if (FileCtl::file_write_contents($p2brdfile, $cont) === false) { p2die("{$p2brdfile} を更新できませんでした"); } return $p2brdfile; } else { if (!$word) { P2Util::pushInfoHtml("<p>p2 error: {$cachefile} から板メニューを生成することはできませんでした。</p>"); } return false; } }
} elseif (strpos($mode, '_msg') !== false) { $popup = 1; // +Wiki:BEあぼーん } elseif (strstr($mode, '_be')) { $aborn_str = $aborn_be; } } if (!is_string($ttitle_en)) { $onear = $aThread->explodeDatLine($aThread->datlines[0]); $_GET['ttitle_en'] = $ttitle_en = UrlSafeBase64::encode($ttitle_name = $onear[4]); } } if ($popup == 2) { // あぼーん・NGワード登録 if (preg_match('/^(aborn|ng)_/', $mode) && ($aborn_str = trim($aborn_str)) !== '') { if (file_exists($path) && ($data = FileCtl::file_read_lines($path))) { $data = array_map('trim', $data); $data = array_filter($data, create_function('$v', 'return ($v !== "");')); array_unshift($data, $aborn_str); $data = array_unique($data); } else { $data = array($aborn_str); } $fp = fopen($path, 'wb'); flock($fp, LOCK_EX); fputs($fp, implode("\n", $data)); fputs($fp, "\n"); flock($fp, LOCK_UN); fclose($fp); } }
/** * readNgAbornFromFile */ protected static function _readNgAbornFromFile($filename) { global $_conf; $file = $_conf['pref_dir'] . '/' . $filename; $data = array(); if ($lines = FileCtl::file_read_lines($file)) { foreach ($lines as $l) { $lar = explode("\t", trim($l)); if (strlen($lar[0]) == 0) { continue; } $ar = array('cond' => $lar[0], 'word' => $lar[0], 'lasttime' => null, 'hits' => 0, 'regex' => false, 'ignorecase' => false); isset($lar[1]) && ($ar['lasttime'] = $lar[1]); isset($lar[2]) && ($ar['hits'] = (int) $lar[2]); if ($filename == 'p2_aborn_res.txt') { $data[] = $ar; continue; } // 板縛り if (preg_match('!<bbs>(.+?)</bbs>!', $ar['word'], $matches)) { $ar['bbs'] = explode(',', $matches[1]); } $ar['word'] = preg_replace('!<bbs>(.*)</bbs>!', '', $ar['word']); // タイトル縛り if (preg_match('!<title>(.+?)</title>!', $ar['word'], $matches)) { $ar['title'] = $matches[1]; } $ar['word'] = preg_replace('!<title>(.*)</title>!', '', $ar['word']); // 正規表現 if (preg_match('/^<(mb_ereg|preg_match|regex)(:[imsxeADSUXu]+)?>(.+)$/', $ar['word'], $matches)) { // マッチング関数とパターンを設定 if ($matches[1] == 'regex') { if (P2_MBREGEX_AVAILABLE) { $ar['regex'] = 'mb_ereg'; $ar['word'] = $matches[3]; } else { $ar['regex'] = 'preg_match'; $ar['word'] = '/' . str_replace('/', '\\/', $matches[3]) . '/'; } } else { $ar['regex'] = $matches[1]; $ar['word'] = $matches[3]; } // 大文字小文字を無視 if ($matches[2] && strpos($matches[2], 'i') !== false) { if ($ar['regex'] == 'mb_ereg') { $ar['regex'] = 'mb_eregi'; } else { $ar['word'] .= 'i'; } } // 大文字小文字を無視 } elseif (preg_match('/^<i>(.+)$/', $ar['word'], $matches)) { $ar['word'] = $matches[1]; $ar['ignorecase'] = true; } // 正規表現でないなら、エスケープされていない特殊文字をエスケープ /*if (!$ar['regex']) { $ar['word'] = htmlspecialchars($ar['word'], ENT_COMPAT, 'Shift_JIS', false); }*/ // 2chの仕様上、↑は期待通りの結果が得られないことが多いので、<>だけ実体参照にする if (!$ar['regex']) { $ar['word'] = str_replace(array('<', '>'), array('<', '>'), $ar['word']); } $data[] = $ar; } } return array('file' => $file, 'data' => $data); }
/** * 既読数をセットする * * @param string $host; * @param string $bbs; * @param int $key * @param int $readnum * @return bool */ function httpcmd_set_readnum($host, $bbs, $key, $readnum) { if (!is_numeric($readnum) || ($readnum = intval($readnum)) < 0) { return false; } $aThread = new Thread(); $aThread->setThreadPathInfo($host, $bbs, $key); $lines = FileCtl::file_read_lines($aThread->keyidx, FILE_IGNORE_NEW_LINES); if (!$lines) { return false; } $idx_data = explode('<>', $lines[0]); if (count($idx_data) < 12) { return false; } $idx_data[5] = $readnum; $idx_data[9] = $readnum > 0 ? $readnum - 1 : 0; P2Util::recKeyIdx($aThread->keyidx, $idx_data); return true; }
/** * アクセス情報をログに記録する */ public static function recAccessLog($logfile, $maxline = 100, $format = 'dataphp') { global $_conf, $_login; // ログファイルの中身を取得する if ($format == 'dataphp') { $lines = DataPhp::fileDataPhp($logfile); } else { $lines = FileCtl::file_read_lines($logfile); } if ($lines) { // 制限行調整 while (sizeof($lines) > $maxline - 1) { array_pop($lines); } } else { $lines = array(); } $lines = array_map('rtrim', $lines); // 変数設定 $date = date('Y/m/d (D) G:i:s'); // IPアドレスを取得 if (array_key_exists('HTTP_X_REAL_IP', $_SERVER)) { $remote_addr = $_SERVER["HTTP_X_REAL_IP"]; } else { $remote_addr = ''; } // HOSTを取得 if (array_key_exists('HTTP_X_REAL_IP', $_SERVER)) { $remote_host = gethostbyaddr($_SERVER['HTTP_X_REAL_IP']); } else { $remote_host = ''; } if (!$remote_host) { $remote_host = gethostbyaddr($_SERVER["HTTP_X_REAL_IP"]); } if ($remote_host == $_SERVER["HTTP_X_REAL_IP"]) { $remote_host = ''; } // UAを取得 if (array_key_exists('HTTP_USER_AGENT', $_SERVER)) { $user_agent = $_SERVER['HTTP_USER_AGENT']; } else { $user_agent = ''; } // リファラを取得 if (array_key_exists('HTTP_REFERER', $_SERVER)) { $referrer = $_SERVER['HTTP_REFERER']; } else { $referrer = ''; } $user = isset($_login->user_u) ? $_login->user_u : ''; // 新しいログ行を設定 $newdata = implode('<>', array($date, $remote_addr, $remote_host, $user_agent, $referrer, '', $user)); //$newdata = htmlspecialchars($newdata, ENT_QUOTES); // まずタブを全て外して $newdata = str_replace("\t", "", $newdata); // <>をタブに変換して $newdata = str_replace("<>", "\t", $newdata); // 新しいデータを一番上に追加 @array_unshift($lines, $newdata); $cont = implode("\n", $lines) . "\n"; FileCtl::make_datafile($logfile, $_conf['p2_perm']); // 書き込み処理 if ($format == 'dataphp') { DataPhp::writeDataPhp($logfile, $cont, $_conf['p2_perm']); } else { FileCtl::file_write_contents($logfile, $cont); } return true; }
function readNew($aThread) { global $_conf, $newthre_num, $STYLE; global $spmode, $word, $newtime; $orig_no_label = !empty($_conf['expack.iphone.toolbars.no_label']); $_conf['expack.iphone.toolbars.no_label'] = true; $newthre_num++; //========================================================== // idxの読み込み //========================================================== //hostを分解してidxファイルのパスを求める $aThread->setThreadPathInfo($aThread->host, $aThread->bbs, $aThread->key); //FileCtl::mkdirFor($aThread->keyidx); // 板ディレクトリが無ければ作る //この操作はおそらく不要 $aThread->itaj = P2Util::getItaName($aThread->host, $aThread->bbs); if (!$aThread->itaj) { $aThread->itaj = $aThread->bbs; } // idxファイルがあれば読み込む if ($lines = FileCtl::file_read_lines($aThread->keyidx, FILE_IGNORE_NEW_LINES)) { $data = explode('<>', $lines[0]); } else { $data = array_fill(0, 12, ''); } $aThread->getThreadInfoFromIdx(); //================================================================== // DATのダウンロード //================================================================== if (!($word and file_exists($aThread->keydat))) { $aThread->downloadDat(); } // DATを読み込み $aThread->readDat(); $aThread->setTitleFromLocal(); // ローカルからタイトルを取得して設定 //=========================================================== // 表示レス番の範囲を設定 //=========================================================== // 取得済みなら if ($aThread->isKitoku()) { $from_num = $aThread->readnum + 1 - $_conf['respointer'] - $_conf['before_respointer_new']; if ($from_num > $aThread->rescount) { $from_num = $aThread->rescount - $_conf['respointer'] - $_conf['before_respointer_new']; } if ($from_num < 1) { $from_num = 1; } //if (!$aThread->ls) { $aThread->ls = "{$from_num}-"; //} } $aThread->lsToPoint(); //================================================================== // ヘッダ 表示 //================================================================== $motothre_url = $aThread->getMotoThread(); $ttitle_en = UrlSafeBase64::encode($aThread->ttitle); $ttitle_en_q = '&ttitle_en=' . $ttitle_en; $bbs_q = '&bbs=' . $aThread->bbs; $key_q = '&key=' . $aThread->key; $host_bbs_key_q = 'host=' . $aThread->host . $bbs_q . $key_q; $popup_q = '&popup=1'; $itaj_hd = htmlspecialchars($aThread->itaj, ENT_QUOTES, 'Shift_JIS'); if ($spmode) { $read_header_itaj_ht = "({$itaj_hd})"; } else { $read_header_itaj_ht = ''; } if ($_conf['iphone']) { if ($read_header_itaj_ht !== '') { $read_header_itaj_ht = "<span class=\"btitle\">{$read_header_itaj_ht}</span>"; } $read_header_ht = <<<EOP <div class="ntoolbar mtoolbar mtoolbar_top" id="ntt{$newthre_num}"> <h2 class="ttitle">{$aThread->ttitle_hd} {$read_header_itaj_ht}</h2> EOP; $read_header_ht .= '<div class="mover">'; $read_header_ht .= toolbar_i_standard_button('img/gp2-down.png', '', sprintf('#ntt%d', $newthre_num + 1)); $read_header_ht .= '</div>'; $info_ht = P2Util::getInfoHtml(); if (strlen($info_ht)) { $read_header_ht .= "<div class=\"info\">{$info_ht}</div>"; } $read_header_ht .= '</div>'; } else { P2Util::printInfoHtml(); $read_header_ht = <<<EOP <hr><div id="ntt{$newthre_num}" name="ntt{$newthre_num}"><font color="{$STYLE['mobile_read_ttitle_color']}"><b>{$aThread->ttitle_hd}</b></font> {$read_header_itaj_ht} <a href="#ntt_bt{$newthre_num}">▼</a></div><hr> EOP; } //================================================================== // ローカルDatを読み込んでHTML表示 //================================================================== $aThread->resrange['nofirst'] = true; $GLOBALS['newres_to_show_flag'] = false; $read_cont_ht = ''; if ($aThread->rescount) { $aShowThread = new ShowThreadK($aThread, true); if ($_conf['iphone'] && $_conf['expack.spm.enabled']) { $read_cont_ht .= $aShowThread->getSpmObjJs(); } $read_cont_ht .= $aShowThread->getDatToHtml(); unset($aShowThread); } //================================================================== // フッタ 表示 //================================================================== // 表示範囲 if ($aThread->resrange['start'] == $aThread->resrange['to']) { $read_range_on = $aThread->resrange['start']; } else { $read_range_on = "{$aThread->resrange['start']}-{$aThread->resrange['to']}"; } $read_range_ht = "{$read_range_on}/{$aThread->rescount}"; // ツールバー部分HTML ======= if ($spmode) { $toolbar_itaj_ht = "(<a href=\"{$_conf['subject_php']}?{$host_bbs_key_q}{$_conf['k_at_a']}\">{$itaj_hd}</a>)"; } else { $toolbar_itaj_ht = ''; } if ($_conf['iphone']) { if ($toolbar_itaj_ht !== '') { $toolbar_itaj_ht = "<span class=\"btitle\">{$toolbar_itaj_ht}</span>"; } $read_footer_ht = <<<EOP <div class="ntoolbar mtoolbar mtoolbar_bottom" id="ntt_btm{$newthre_num}"> <table><tbody><tr> EOP; // 情報 $read_footer_ht .= '<td>'; $escaped_url = "info.php?{$host_bbs_key_q}{$ttitle_en_q}{$_conf['k_at_a']}"; $read_footer_ht .= toolbar_i_opentab_button('img/gp5-info.png', '', $escaped_url); $read_footer_ht .= '</td>'; // 表示範囲 $read_footer_ht .= "<td colspan=\"3\"><span class=\"large\">{$read_range_ht}</span></td>"; // ツール $read_footer_ht .= '<td>'; $escaped_url = "spm_k.php?{$host_bbs_key_q}&ls={$aThread->ls}&spm_default={$aThread->resrange['to']}{$_conf['k_at_a']}"; $read_footer_ht .= toolbar_i_opentab_button('img/glyphish/icons2/20-gear2.png', '', $escaped_url); $read_footer_ht .= '</td>'; // タイトル等 $read_footer_ht .= <<<EOP </tr></tbody></table> <div class="ttitle"><a href="{$_conf['read_php']}?{$host_bbs_key_q}&offline=1&rescount={$aThread->rescount}{$_conf['k_at_a']}" target="_blank">{$aThread->ttitle_hd}</a> {$toolbar_itaj_ht}</div> <div class="mover"> EOP; $read_footer_ht .= toolbar_i_standard_button('img/gp1-up.png', '', "#ntt{$newthre_num}"); $read_footer_ht .= '</div></div>'; } else { $read_footer_ht = <<<EOP <div id="ntt_bt{$newthre_num}" name="ntt_bt{$newthre_num}" class="read_new_toolbar"> {$read_range_ht} <a href="info.php?{$host_bbs_key_q}{$ttitle_en_q}{$_conf['k_at_a']}">情</a> <a href="spm_k.php?{$host_bbs_key_q}&ls={$aThread->ls}&spm_default={$aThread->resrange['to']}&from_read_new=1{$_conf['k_at_a']}">特</a> <br> <a href="{$_conf['read_php']}?{$host_bbs_key_q}&offline=1&rescount={$aThread->rescount}{$_conf['k_at_a']}#r{$aThread->rescount}">{$aThread->ttitle_hd}</a> {$toolbar_itaj_ht} <a href="#ntt{$newthre_num}">▲</a> </div> <hr> EOP; } // 透明あぼーんや表示数制限で新しいレス表示がない場合はスキップ if ($GLOBALS['newres_to_show_flag']) { echo $read_header_ht; echo $read_cont_ht; echo $read_footer_ht; } //================================================================== // key.idxの値設定 //================================================================== if ($aThread->rescount) { $aThread->readnum = min($aThread->rescount, max(0, $data[5], $aThread->resrange['to'])); $newline = $aThread->readnum + 1; // $newlineは廃止予定だが、旧互換用に念のため $sar = array($aThread->ttitle, $aThread->key, $data[2], $aThread->rescount, $aThread->modified, $aThread->readnum, $data[6], $data[7], $data[8], $newline, $data[10], $data[11], $aThread->datochiok); P2Util::recKeyIdx($aThread->keyidx, $sar); // key.idxに記録 } $_conf['expack.iphone.toolbars.no_label'] = $orig_no_label; }
/** * subject.txtを一括ダウンロード&保存する * * @param array|string $subjects * @param bool $force * @return void */ public static function fetchSubjectTxt($subjects, $force = false) { global $_conf; // {{{ ダウンロード対象を設定 // お気に板等の.idx形式のファイルをパース if (is_string($subjects)) { $lines = FileCtl::file_read_lines($subjects, FILE_IGNORE_NEW_LINES); if (!$lines) { return; } $subjects = array(); foreach ($lines as $l) { $la = explode('<>', $l); if (count($la) < 12) { continue; } $host = $la[10]; $bbs = $la[11]; if ($host === '' || $bbs === '') { continue; } $id = $host . '<>' . $bbs; if (isset($subjects[$id])) { continue; } $subjects[$id] = array($host, $bbs); } // [host, bbs] の連想配列を検証 } elseif (is_array($subjects)) { $originals = $subjects; $subjects = array(); foreach ($originals as $s) { if (!is_array($s) || !isset($s['host']) || !isset($s['bbs'])) { continue; } $id = $s['host'] . '<>' . $s['bbs']; if (isset($subjects[$id])) { continue; } $subjects[$id] = array($s['host'], $s['bbs']); } // 上記以外 } else { return; } if (!count($subjects)) { return; } // }}} // {{{ キューをセットアップ // キューおよびその他の変数を初期化 $queue = new P2HttpRequestQueue(); $hosts = array(); $time = time() - $_conf['sb_dl_interval']; $eucjp2sjis = null; // 各subject.txtへのリクエストをキューに追加 foreach ($subjects as $subject) { list($host, $bbs) = $subject; $file = P2Util::datDirOfHostBbs($host, $bbs) . 'subject.txt'; if (!$force && file_exists($file) && filemtime($file) > $time) { continue; } $url = 'http://' . $host . '/' . $bbs . '/subject.txt'; if (P2Util::isHostJbbsShitaraba($host) || P2Util::isHostBe2chNet($host)) { if ($eucjp2sjis === null) { $eucjp2sjis = new P2HttpCallback_SaveEucjpAsSjis(); } $req = new P2HttpGet($url, $file, null, $eucjp2sjis); } else { $req = new P2HttpGet($url, $file); } // 同一ホストに対しての同時接続は MAX_REQUESTS_PER_HOST まで if (!isset($hosts[$host])) { $hosts[$host] = new P2HttpRequestQueue(); $queue->push($req); } elseif (count($hosts[$host]) < self::MAX_REQUESTS_PER_HOST) { $queue->push($req); } else { $hosts[$host]->pop()->setNext($req); } $hosts[$host]->push($req); } // }}} // リクエストを送信 if (count($queue)) { self::send(new HttpRequestPool(), $queue); clearstatcache(); } }
/** * スレッドあぼーんをオンオフする * * $set は、0(解除), 1(追加), 2(トグル) */ function settaborn($host, $bbs, $key, $set) { global $_conf, $title_msg, $info_msg; //================================================================== // key.idx 読み込む //================================================================== // idxfileのパスを求めて $idx_host_bbs_dir_s = P2Util::idxDirOfHostBbs($host, $bbs); $idxfile = $idx_host_bbs_dir_s . $key . '.idx'; // データがあるなら読み込む if ($lines = FileCtl::file_read_lines($idxfile, FILE_IGNORE_NEW_LINES)) { $data = explode('<>', $lines[0]); } else { $data = array_fill(0, 12, ''); } //================================================================== // p2_threads_aborn.idxに書き込む //================================================================== // p2_threads_aborn.idx のパス取得 $taborn_idx = $idx_host_bbs_dir_s . 'p2_threads_aborn.idx'; // p2_threads_aborn.idx がなければ生成 FileCtl::make_datafile($taborn_idx); // p2_threads_aborn.idx 読み込み; $taborn_lines = FileCtl::file_read_lines($taborn_idx, FILE_IGNORE_NEW_LINES); $neolines = array(); $aborn_attayo = false; if ($taborn_lines) { foreach ($taborn_lines as $l) { $lar = explode('<>', $l); if ($lar[1] == $key) { $aborn_attayo = true; // 既にあぼーん中である if ($set == 0 or $set == 2) { $title_msg_pre = "+ あぼーん 解除しますた"; $info_msg_pre = "+ あぼーん 解除しますた"; } continue; } if (!$lar[1]) { continue; } // keyのないものは不正データ $neolines[] = $l; } } // 新規データ追加 if ($set == 1 or !$aborn_attayo && $set == 2) { $newdata = "{$data[0]}<>{$key}<><><><><><><><>"; $neolines ? array_unshift($neolines, $newdata) : ($neolines = array($newdata)); $title_msg_pre = "○ あぼーん しますた"; $info_msg_pre = "○ あぼーん しますた"; } // 書き込む $cont = ''; if (!empty($neolines)) { foreach ($neolines as $l) { $cont .= $l . "\n"; } } if (FileCtl::file_write_contents($taborn_idx, $cont) === false) { p2die('cannot write file.'); } $GLOBALS['title_msg'] = $title_msg_pre; $GLOBALS['info_msg'] = $info_msg_pre; return true; }
$aThreadList->setIta($host, $bbs, $p2_setting['itaj']); // スレッドあぼーんリスト読込 $taborn_file = $aThreadList->getIdxDir() . 'p2_threads_aborn.idx'; if ($tabornlines = FileCtl::file_read_lines($taborn_file, FILE_IGNORE_NEW_LINES)) { $ta_num = sizeof($tabornlines); foreach ($tabornlines as $l) { $data = explode('<>', $l); $ta_keys[$data[1]] = true; } } } // }}} // ソースリスト読込 $lines = $aThreadList->readList(); // {{{ お気にスレリスト 読込 if ($favlines = FileCtl::file_read_lines($_conf['favlist_idx'], FILE_IGNORE_NEW_LINES)) { foreach ($favlines as $l) { $data = explode('<>', $l); $fav_keys[$data[1]] = $data[11]; } } // }}} //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('HEAD'); //============================================================ // それぞれの行解析 //============================================================ //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('FORLOOP'); $linesize = sizeof($lines); $subject_txts = array(); for ($x = 0; $x < $linesize; $x++) { $aThread = new Thread();
} exit; } } else { if ($_conf['ktai']) { include P2_BASE_DIR . '/tgrepc.php'; } exit; } // }}} // {{{ リストを更新 if (!empty($_GET['query'])) { $purge = !empty($_GET['purge']); $query = preg_replace('/\\s+/', ' ', trim($_GET['query'])); FileCtl::make_datafile($list_file); $tgrep_list = FileCtl::file_read_lines($list_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($tgrep_list)) { $tgrep_list = array(); } if ($purge) { $tgrep_tmp_list = $tgrep_list; $tgrep_list = array(); foreach ($tgrep_tmp_list as $tgrep_tmp_query) { if ($tgrep_tmp_query != $query) { $tgrep_list[] = $tgrep_tmp_query; } } } else { array_unshift($tgrep_list, $query); } $tgrep_list = array_unique($tgrep_list);