/** * 新着まとめ読み <a> * * @return string HTML */ function getShinchakuMatomeATag($aThreadList, $shinchaku_num) { global $_conf; static $upper_toolbar_done_ = false; $shinchaku_matome_atag = ''; // 倉庫なら新着まとめのリンクはなし if ($aThreadList->spmode == 'soko') { return $shinchaku_matome_atag = ''; } $attrs = array(); if (UA::isIPhoneGroup()) { $attrs['class'] = 'button'; } // 上下あるツールバーの下だけにアクセスキーをつける if ($upper_toolbar_done_) { $attrs[$_conf['accesskey_for_k']] = $_conf['k_accesskey']['matome']; } $upper_toolbar_done_ = true; $qs = array('host' => $aThreadList->host, 'bbs' => $aThreadList->bbs, 'spmode' => $aThreadList->spmode, 'nt' => date('gis'), UA::getQueryKey() => UA::getQueryValue()); $label = "{$_conf['k_accesskey']['matome']}.新まとめ"; if ($shinchaku_num) { $shinchaku_matome_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['read_new_k_php'], array_merge($qs, array('norefresh' => '1'))), hs("{$label}({$shinchaku_num})"), $attrs); } else { $shinchaku_matome_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['read_new_k_php'], $qs), hs($label), $attrs); } return $shinchaku_matome_atag; }
/** * @access public * @return string HTML */ function getSbToolbarShinchakuMatomeHtml($aThreadList, $shinchaku_num) { global $_conf; static $new_matome_i_ = 0; $new_matome_i_++; $shinchaku_matome_ht = ''; // 倉庫でなければ if ($aThreadList->spmode != 'soko') { $shinchaku_num_ht = ''; if ($shinchaku_num) { $shinchaku_num_ht = " (<span id=\"smynum{$new_matome_i_}\" class=\"matome_num\">{$shinchaku_num}</span>)"; } $shinchaku_matome_ht = P2View::tagA(UriUtil::buildQueryUri($_conf['read_new_php'], array('host' => $aThreadList->host, 'bbs' => $aThreadList->bbs, 'spmode' => $aThreadList->spmode, 'norefresh' => 1, 'nt' => date('gis'), UA::getQueryKey() => UA::getQueryValue())), '新着まとめ読み' . $shinchaku_num_ht, array('id' => "smy{$new_matome_i_}", 'class' => 'matome', 'onClick' => 'chNewAllColor();')); } return $shinchaku_matome_ht; }
/** * datのレスメッセージをHTML表示用メッセージに変換して返す * * @access private * @param string $msg * @param integer $resnum レス番号 * @param ref bool $has_aa AAを含んでいるかどうか。この渡し方はイマイチぽ。レス単位でオブジェクトにした方がいいかな。 * @return string HTML */ function transMsg($msg, $resnum, &$has_aa) { global $_conf; global $res_filter, $word_fm; $this->str_to_link_rest = $this->str_to_link_limit; $ryaku = false; // 2ch旧形式のdat if ($this->thread->dat_type == '2ch_old') { $msg = str_replace('@`', ',', $msg); $msg = preg_replace('/&([^;])/', '&$1', $msg); } // DAT中にある>>1のリンクHTMLを取り除く $msg = $this->removeResAnchorTagInDat($msg); // AAチェック $has_aa = $this->detectAA($msg); // {{{ 大きさ制限 // AAの強制省略。 $aa_ryaku_flag = false; if ($_conf['k_aa_ryaku_size'] && strlen($msg) > $_conf['k_aa_ryaku_size'] and $has_aa == 2) { $aa_ryaku_flag = true; } if (!(UA::isIPhoneGroup() && !$aa_ryaku_flag) and empty($_GET['k_continue']) and $_conf['ktai_res_size'] && strlen($msg) > $_conf['ktai_res_size'] || $aa_ryaku_flag) { // <br>以外のタグを除去し、長さを切り詰める $msg = strip_tags($msg, '<br>'); if ($aa_ryaku_flag) { $ryaku_size = min($_conf['k_aa_ryaku_size'], $_conf['ktai_ryaku_size']); $ryaku_st = 'AA略'; } else { $ryaku_size = $_conf['ktai_ryaku_size']; $ryaku_st = '略'; } $msg = mb_strcut($msg, 0, $ryaku_size); $msg = preg_replace('/ *<[^>]*$/i', '', $msg); // >>1, >1, >1, >>1を引用レスポップアップリンク化 $msg = preg_replace_callback($this->getAnchorRegex('/%full%/'), array($this, 'quote_msg_callback'), $msg); $msg .= P2View::tagA(UriUtil::buildQueryUri($_conf['read_php'], array('host' => $this->thread->host, 'bbs' => $this->thread->bbs, 'key' => $this->thread->key, 'ls' => $resnum, 'k_continue' => '1', 'offline' => '1', UA::getQueryKey() => UA::getQueryValue())), $ryaku_st); return $msg; } // }}} // 引用やURLなどをリンク $msg = preg_replace_callback($this->str_to_link_regex, array($this, 'link_callback'), $msg, $this->str_to_link_limit); // 2ch BEアイコン if (in_array($_conf['show_be_icon'], array(1, 3))) { $msg = preg_replace('{sssp://(img\\.2ch\\.net/ico/[\\w\\d()\\-]+\\.[a-z]+)}', '<img src="http://$1" border="0">', $msg); } return $msg; }
/** * @return string HTML */ function _getReadATag($aThread) { global $_conf; $ttitle_hs = hs($aThread->ttitle_hc); if ($_conf['k_save_packet']) { $ttitle_hs = mb_convert_kana($ttitle_hs, 'rnsk'); } return $read_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['read_php'], array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key, 'offline' => '1', 'rescount' => $aThread->rescount, UA::getQueryKey() => UA::getQueryValue())) . '#r' . rawurlencode($aThread->rescount), $ttitle_hs); }
$auth_ctl_html = sprintf('docomo端末ID認証登録済[%s]<br>', $atag); } else { if ($_login->pass_x) { $uri = UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('ctl_regist_docomo' => '1', 'regist_docomo' => '1', 'guid' => 'ON', UA::getQueryKey() => UA::getQueryValue())); $atag = sprintf('<a href="%s" utn>%s</a>', $uri, 'docomo端末IDで認証を登録'); $auth_ctl_html = sprintf('[%s]<br>', $atag); } } // Cookie認証 } else { if ($_login->checkUserPwWithCid($_COOKIE['cid'])) { $atag = P2View::tagA(UriUtil::buildQueryUri('cookie.php', array('ctl_regist_cookie' => '1', UA::getQueryKey() => UA::getQueryValue())), '解除'); $auth_cookie_html = sprintf('cookie認証登録済[%s]<br>', $atag); } else { if ($_login->pass_x) { $atag = P2View::tagA(UriUtil::buildQueryUri('cookie.php', array('ctl_regist_cookie' => '1', 'regist_cookie' => '1', UA::getQueryKey() => UA::getQueryValue())), 'cookieに認証を登録'); $auth_cookie_html = sprintf('[%s]<br>', $atag); } } } // Cookie認証登録解除処理 _preExecCheckRegistCookie(); //================================================================= // HTMLプリント //================================================================= $p_htm['body_onload'] = ''; if (!$_conf['ktai']) { $p_htm['body_onload'] = ' onLoad="setWinTitle();"'; } $body_at = P2View::getBodyAttrK(); P2Util::headerNoCache();
/** * SETTING.TXT をダウンロードして、パースして、キャッシュする * * @access public * @return true|null|false 成功|更新なし(キャッシュ)|失敗 */ function downloadSettingTxt() { global $_conf; $perm = $_conf['dl_perm'] ? $_conf['dl_perm'] : 0606; FileCtl::mkdirFor($this->setting_txt); // 板ディレクトリが無ければ作る $modified = null; if (file_exists($this->setting_srd) && file_exists($this->setting_txt)) { // 更新しない場合は、その場で抜けてしまう if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) { return null; // キャッシュが新しい場合も抜ける } elseif ($this->isSettingSrdCacheFresh()) { return null; } $modified = gmdate('D, d M Y H:i:s', filemtime($this->setting_txt)) . ' GMT'; } // DL /* // PHP5 if (!class_exists('HTTP_Request', false)) { require 'HTTP/Request.php'; } */ require_once 'HTTP/Request.php'; $params = array(); $params['timeout'] = $_conf['fsockopen_time_limit']; if ($_conf['proxy_use']) { $params['proxy_host'] = $_conf['proxy_host']; $params['proxy_port'] = $_conf['proxy_port']; } $req = new HTTP_Request($this->url, $params); $modified && $req->addHeader('If-Modified-Since', $modified); $req->addHeader('User-Agent', 'Monazilla/1.00 (' . $_conf['p2uaname'] . '/' . $_conf['p2version'] . ')'); $response = $req->sendRequest(); $error_msg = null; if (PEAR::isError($response)) { $error_msg = $response->getMessage(); } else { $code = $req->getResponseCode(); if ($code == 302) { // ホストの移転を追跡 require_once P2_LIB_DIR . '/BbsMap.php'; $new_host = BbsMap::getCurrentHost($this->host, $this->bbs); if ($new_host != $this->host) { $aNewSettingTxt = new SettingTxt($new_host, $this->bbs); return $aNewSettingTxt->downloadSettingTxt(); } } if (!($code == 200 || $code == 206 || $code == 304)) { //var_dump($req->getResponseHeader()); $error_msg = $code; } } // DLエラー if (strlen($error_msg)) { P2Util::pushInfoHtml(sprintf('<div>Error: %s<br>p2 info - %s に接続できませんでした。</div>', hs($error_msg), P2View::tagA(P2Util::throughIme($this->url), hs($this->url), array('target' => $_conf['ext_win_target'])))); touch($this->setting_txt); // DL失敗した場合(404)も touch する touch($this->setting_srd); return false; } $body = $req->getResponseBody(); // DL成功して かつ 更新されていたら保存 if ($body && $code != 304) { // したらば or be.2ch.net ならEUCをSJISに変換 if (P2Util::isHostJbbsShitaraba($this->host) || P2Util::isHostBe2chNet($this->host)) { $body = mb_convert_encoding($body, 'SJIS-win', 'eucJP-win'); } if (false === FileCtl::filePutRename($this->setting_txt, $body)) { die('Error: cannot write file'); } chmod($this->setting_txt, $perm); // パースして if (!$this->setSettingArrayFromSettingTxt()) { return false; } // srd保存する if (!$this->saveSettingSrd($this->setting_array)) { return false; } } else { // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる touch($this->setting_txt); // 同時にキャッシュもtouchしないと、setting_txtとsetting_srdで更新時間がずれて、 // 毎回ここまで処理が来る(サーバへのヘッダリクエストが飛ぶ)場合がある。 touch($this->setting_srd); } return true; }
/** * @return string <a> */ function _getDatSokoATag($aThreadList) { global $_conf; $dat_soko_atag = ''; if (!$aThreadList->spmode or $aThreadList->spmode == 'taborn') { $uri = UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $aThreadList->host, 'bbs' => $aThreadList->bbs, 'norefresh' => '1', 'spmode' => 'soko', UA::getQueryKey() => UA::getQueryValue())); $dat_soko_atag = P2View::tagA($uri, hs('dat倉庫')); } return $dat_soko_atag; }
/** * お気に板をHTML表示する * * @access public * @return void */ function printFavItaHtml() { global $_conf, $matome_i, $STYLE; // favita読み込み $favitas = array(); if (file_exists($_conf['favita_path'])) { if ($lines = file($_conf['favita_path'])) { foreach ($lines as $l) { if (preg_match("/^\t?(.+)\t(.+)\t(.+)\$/", trim($l), $matches)) { $favitas[] = array('host' => $matches[1], 'bbs' => $matches[2], 'itaj' => $matches[3]); } } } } // 空っぽなら if (!$favitas) { echo <<<EOP <div class="menu_cate"><b>お気に板</b> [<a href="editfavita.php" target="subject">編集</a>]<br> <div class="itas" id="c_favita">(空っぽ)</div> </div> EOP; return; } // 新着数を表示する場合・まとめてプリフェッチ if ($_conf['enable_menu_new'] && !empty($_GET['shownew'])) { if ($_conf['expack.use_pecl_http'] == 1) { require_once P2_LIB_DIR . '/P2HttpExt.php'; P2HttpRequestPool::fetchSubjectTxt($favitas); $GLOBALS['expack.subject.multi-threaded-download.done'] = true; } } $csrfid = P2Util::getCsrfId(); echo <<<EOP <div class="menu_cate"><b><a class="menu_cate" href="javascript:void(0);" onClick="showHide('c_favita', 'itas_hide');" target="_self">お気に板</a></b> [<a href="editfavita.php" target="subject">編集</a>]<br> <div class="itas" id="c_favita"> EOP; foreach ($favitas as $favita) { extract($favita); // $host, $bbs, $itaj $itaj_en = base64_encode($itaj); $uri = UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('host' => $host, 'bbs' => $bbs, 'setfavita' => '0', 'csrfid' => $csrfid)); $star_atag = P2View::tagA($uri, '★', array('target' => '_self', 'class' => 'fav', 'title' => "「{$itaj}」をお気に板から外す", 'onClick' => "return confirmSetFavIta('" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $itaj) . "');")); // 新着数を表示する場合 if ($_conf['enable_menu_new'] && !empty($_GET['shownew'])) { $matome_i++; // $host, $bbs $spmode = ''; $shinchaku_num = 0; $_newthre_num = 0; include './subject_new.php'; // $shinchaku_num, $_newthre_num がセットされる $newthre_ht = ''; if ($_newthre_num) { $newthre_ht = "{$_newthre_num}"; } $subject_uri = UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en)); $subject_atag = P2View::tagA($subject_uri, hs($itaj), array('onClick' => "chMenuColor('{$matome_i}');")); $read_new_uri = UriUtil::buildQueryUri($_conf['read_new_php'], array('host' => $host, 'bbs' => $bbs)); $read_new_attr = array('target' => 'read', 'id' => "un{$matome_i}", 'onClick' => "chUnColor('{$matome_i}');"); if ($shinchaku_num > 0) { $read_new_attr['class'] = 'newres_num'; } else { $read_new_attr['class'] = 'newres_num_zero'; } $read_new_atag = P2View::tagA($read_new_uri, hs($shinchaku_num), $read_new_attr); echo <<<EOP {$star_atag} {$subject_atag} <span id="newthre{$matome_i}" class="newthre_num">{$newthre_ht}</span> ({$read_new_atag})<br> EOP; // 新着数を表示しない場合 } else { $subject_uri = UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en)); $subject_atag = P2View::tagA($subject_uri, hs($itaj)); echo "{$star_atag} {$subject_atag}<br>"; } ob_flush(); flush(); } // foreach echo " </div>\n"; echo "</div>\n"; }
/** * @return void HTML出力 */ function _printEditSortTrHtml($host, $bbs, $itaj) { global $_conf; $itaj_en = base64_encode($itaj); ?> <tr> <td> <?php echo P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $host, 'bbs' => $bbs, UA::getQueryKey() => UA::getQueryValue())), hs($itaj), array('title' => "{$host}/{$bbs}")); ?> </td> <td>[ <?php echo P2View::tagA(UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en, 'setfavita' => 'top', 'csrfid' => P2Util::getCsrfId(), UA::getQueryKey() => UA::getQueryValue())), hs('▲'), array('class' => 'te', 'title' => '一番上に移動')); ?> </td> <td> <?php echo P2View::tagA(UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en, 'setfavita' => 'up', 'csrfid' => P2Util::getCsrfId(), UA::getQueryKey() => UA::getQueryValue())), hs('↑'), array('class' => 'te', 'title' => '一つ上に移動')); ?> </td> <td> <?php echo P2View::tagA(UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en, 'setfavita' => 'down', 'csrfid' => P2Util::getCsrfId(), UA::getQueryKey() => UA::getQueryValue())), hs('↓'), array('class' => 'te', 'title' => '一つ下に移動')); ?> </td> <td> <?php echo P2View::tagA(UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('host' => $host, 'bbs' => $bbs, 'itaj_en' => $itaj_en, 'setfavita' => 'bottom', 'csrfid' => P2Util::getCsrfId(), UA::getQueryKey() => UA::getQueryValue())), hs('▼'), array('class' => 'te', 'title' => '一番下に移動')); ?> ]</td> <td>[<?php echo P2View::tagA(UriUtil::buildQueryUri($_SERVER['SCRIPT_NAME'], array('host' => $host, 'bbs' => $bbs, 'setfavita' => '0', 'csrfid' => P2Util::getCsrfId(), UA::getQueryKey() => UA::getQueryValue())), hs('削除'), array('title' => '削除')); ?> ]</td> </tr> <?php }
/** * ファイルをダウンロード保存する * * @access public * @param $options array('disp_error' => true, 'use_tmp_file' => false, 'modified' = null) * @return WapResponse|false */ function fileDownload($url, $localfile, $options = array()) { global $_conf; $me = __CLASS__ . '::' . __FUNCTION__ . '()'; $disp_error = isset($options['disp_error']) ? $options['disp_error'] : true; $use_tmp_file = isset($options['use_tmp_file']) ? $options['use_tmp_file'] : false; $modified = isset($options['modified']) ? $options['modified'] : null; if (strlen($localfile) == 0) { trigger_error("{$me}, localfile is null", E_USER_WARNING); return false; } $perm = isset($_conf['dl_perm']) ? $_conf['dl_perm'] : 0606; // {{{ modifiedの指定 // 指定なし(null)なら、ファイルの更新時間 if (is_null($modified) && file_exists($localfile)) { $modified = gmdate("D, d M Y H:i:s", filemtime($localfile)) . " GMT"; // UNIX TIME } elseif (is_numeric($modified)) { $modified = gmdate("D, d M Y H:i:s", $modified) . " GMT"; // 日付時間文字列 } elseif (is_string($modified)) { // $modified はそのまま } else { // modified ヘッダはなし $modified = false; } // }}} // DL require_once P2_LIB_DIR . '/wap.class.php'; $wap_ua = new WapUserAgent(); $wap_ua->setTimeout($_conf['fsockopen_time_limit']); $wap_req = new WapRequest(); $wap_req->setUrl($url); $modified and $wap_req->setModified($modified); if ($_conf['proxy_use']) { $wap_req->setProxy($_conf['proxy_host'], $_conf['proxy_port']); } $wap_res = $wap_ua->request($wap_req); if (!$wap_res or !$wap_res->is_success() && $disp_error) { $url_t = P2Util::throughIme($wap_req->url); $atag = P2View::tagA($url_t, hs($wap_req->url), array('target' => $_conf['ext_win_target'])); $msgHtml = sprintf('<div>Error: %s %s<br>p2 info - %s に接続できませんでした。</div>', hs($wap_res->code), hs($wap_res->message), $atag); P2Util::pushInfoHtml($msgHtml); } // 更新されていたらファイルに保存 if ($wap_res->is_success() && $wap_res->code != '304') { if ($use_tmp_file) { if (!is_dir($_conf['tmp_dir'])) { if (!FileCtl::mkdirR($_conf['tmp_dir'])) { die("Error: {$me}, cannot mkdir."); return false; } } if (false === FileCtl::filePutRename($localfile, $wap_res->content)) { trigger_error("{$me}, FileCtl::filePutRename() return false. " . $localfile, E_USER_WARNING); die("Error: {$me}, cannot write file."); return false; } } else { if (false === file_put_contents($localfile, $wap_res->content, LOCK_EX)) { die("Error: {$me}, cannot write file."); return false; } } chmod($localfile, $perm); } return $wap_res; }
/** * @return string HTML */ function _getRecentNewLinkHtml() { global $_conf; list($matome_i, $shinchaku_num) = _initMenuNewSp('recent'); // 新着数を初期化取得 $id = "sp{$matome_i}"; $recent_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], array('spmode' => 'recent', 'norefresh' => '1')), '最近読んだスレ', array('onClick' => "chMenuColor('{$id}');", 'accesskey' => $_conf['pc_accesskey']['recent'])); $recent_new_attrs = array('id' => "un{$id}", 'onClick' => "chUnColor('{$id}');", 'target' => 'read'); if ($shinchaku_num > 0) { $recent_new_attrs['class'] = 'newres_num'; } else { $recent_new_attrs['class'] = 'newres_num_zero'; } $recent_new_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['read_new_php'], array('spmode' => 'recent')), hs($shinchaku_num), $recent_new_attrs); return "{$recent_atag} ({$recent_new_atag})"; }
/** * スレッド一覧をHTML表示する (PC用 <tr>〜</tr>) * * @access public * @return void */ function sb_print($aThreadList) { global $_conf, $sb_view, $p2_setting, $STYLE; $GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('sb_print()'); if (!$aThreadList->threads) { echo '<tr><td> 該当サブジェクトはなかったぽ</td></tr>'; $GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('sb_print()'); return; } // 変数 ================================================ // >>1 表示 $onlyone_bool = false; if ($_conf['sb_show_one'] == 1 or $_conf['sb_show_one'] == 2 and ereg('news', $aThreadList->bbs) || $aThreadList->bbs == 'bizplus') { // spmodeは除く if (empty($aThreadList->spmode)) { $onlyone_bool = true; } } // チェックボックス $checkbox_bool = false; if ($aThreadList->spmode == 'taborn' || $aThreadList->spmode == 'soko') { $checkbox_bool = true; } // 板名 $ita_name_bool = false; if ($aThreadList->spmode && $aThreadList->spmode != 'taborn' && $aThreadList->spmode != 'soko') { $ita_name_bool = true; } $norefresh_q = '&norefresh=1'; // ソート ================================================== // 現在のソート形式をclass指定でCSSカラーリング $class_sort_midoku = ''; // 新着 $class_sort_res = ''; // レス $class_sort_no = ''; // No. $class_sort_title = ''; // タイトル $class_sort_ita = ''; // 板 $class_sort_spd = ''; // すばやさ $class_sort_ikioi = ''; // 勢い $class_sort_bd = ''; // スレ立て日 $class_sort_fav = ''; // お気に入り if ($GLOBALS['now_sort']) { $nowsort_code = <<<EOP \$class_sort_{$GLOBALS['now_sort']}=' class="now_sort"'; EOP; eval($nowsort_code); } $sortq_spmode = ''; $sortq_host = ''; $sortq_ita = ''; // spmode時 if ($aThreadList->spmode) { $sortq_spmode = "&spmode={$aThreadList->spmode}"; } // spmodeでない、または、spmodeがあぼーん or dat倉庫なら if (!$aThreadList->spmode || $aThreadList->spmode == "taborn" || $aThreadList->spmode == "soko") { $sortq_host = "&host={$aThreadList->host}"; $sortq_ita = "&bbs={$aThreadList->bbs}"; } $midoku_sort_ht = "<td class=\"tu\" nowrap><a{$class_sort_midoku} href=\"{$_conf['subject_php']}?sort=midoku{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\" style=\"white-space:nowrap;\"><nobr>新着</nobr></a></td>"; //===================================================== // テーブルヘッダHTML表示 //===================================================== echo '<tr class="tableheader">' . "\n"; // 並替 if ($sb_view == "edit") { echo '<td class="te"> </td>'; } // 新着 if ($sb_view != "edit") { echo $midoku_sort_ht; } // レス数 if ($sb_view != "edit") { echo "<td class=\"tn\" nowrap><a{$class_sort_res} href=\"{$_conf['subject_php']}?sort=res{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\">レス</a></td>"; } // >>1 if ($onlyone_bool) { echo '<td class="t"> </td>'; } // チェックボックス if ($checkbox_bool) { echo '<td class="tc"><input id="allbox" name="allbox" type="checkbox" onClick="checkAll();" title="すべての項目を選択、または選択解除"></td>'; } // No. $title = empty($aThreadList->spmode) ? " title=\"2ch標準の並び順番号\"" : ''; echo "<td class=\"to\"><a{$class_sort_no} href=\"{$_conf['subject_php']}?sort=no{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\"{$title}>No.</a></td>"; // タイトル echo "<td class=\"tl\"><a{$class_sort_title} href=\"{$_conf['subject_php']}?sort=title{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\">タイトル</a></td>"; // 板 if ($ita_name_bool) { echo "<td class=\"t\"><a{$class_sort_ita} href=\"{$_conf['subject_php']}?sort=ita{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\">板</a></td>"; } // すばやさ if ($_conf['sb_show_spd']) { echo "<td class=\"ts\"><a{$class_sort_spd} href=\"{$_conf['subject_php']}?sort=spd{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\">すばやさ</a></td>"; } // 勢い if ($_conf['sb_show_ikioi']) { echo "<td class=\"ti\"><a{$class_sort_ikioi} href=\"{$_conf['subject_php']}?sort=ikioi{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\" title=\"一日あたりのレス数\">勢い</a></td>"; } // スレ立て日 echo "<td class=\"t\"><a{$class_sort_bd} href=\"{$_conf['subject_php']}?sort=bd{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\">スレ立て日</a></td>"; // お気に入り if ($_conf['sb_show_fav'] and $aThreadList->spmode != "taborn") { echo "<td class=\"t\"><a{$class_sort_fav} href=\"{$_conf['subject_php']}?sort=fav{$sortq_spmode}{$sortq_host}{$sortq_ita}{$norefresh_q}\" target=\"_self\" title=\"お気にスレ\">☆</a></td>"; } echo "\n</tr>\n"; //===================================================== //テーブルボディ //===================================================== //spmodeがあればクエリー追加 if ($aThreadList->spmode) { $spmode_q = "&spmode={$aThreadList->spmode}"; } else { $spmode_q = ''; } $sid_q = defined('SID') && strlen(SID) ? '&' . hs(SID) : ''; $i = 0; foreach ($aThreadList->threads as $aThread) { $i++; $midoku_ari = ''; $anum_ht = ''; // #r1 $offline_q = ''; $bbs_q = "&bbs=" . $aThread->bbs; $key_q = "&key=" . $aThread->key; if ($aThreadList->spmode != 'taborn') { if (!$aThread->torder) { $aThread->torder = $i; } } // td欄 cssクラス if ($i % 2 == 0) { $class_t = ' class="t"'; // 基本 $class_te = ' class="te"'; // 並び替え $class_tu = ' class="tu"'; // 新着レス数 $class_tn = ' class="tn"'; // レス数 $class_tc = ' class="tc"'; // チェックボックス $class_to = ' class="to"'; // オーダー番号 $class_tl = ' class="tl"'; // タイトル $class_ts = ' class="ts"'; // すばやさ $class_ti = ' class="ti"'; // 勢い } else { $class_t = ' class="t2"'; $class_te = ' class="te2"'; $class_tu = ' class="tu2"'; $class_tn = ' class="tn2"'; $class_tc = ' class="tc2"'; $class_to = ' class="to2"'; $class_tl = ' class="tl2"'; $class_ts = ' class="ts2"'; $class_ti = ' class="ti2"'; } // 新着レス数 ============================================= $unum_ht_c = " "; // 既得済み if ($aThread->isKitoku()) { // $ttitle_en_q は節減省略 $onclick_at = " onClick=\"return !deleLog('host={$aThread->host}{$bbs_q}{$key_q}{$sid_q}', {$STYLE['info_pop_size']}, 'subject', this);\""; $title_at = ' title="クリックするとログ削除"'; $unum_ht_c = "<a class=\"un\" href=\"{$_conf['subject_php']}?host={$aThread->host}{$bbs_q}{$key_q}{$spmode_q}&dele=1\" target=\"_self\"{$onclick_at}{$title_at}>{$aThread->unum}</a>"; $anum = $aThread->rescount - $aThread->unum + 1 - $_conf['respointer']; if ($anum > $aThread->rescount) { $anum = $aThread->rescount; } $anum_ht = '#r' . $anum; // {{{ 新着あり if ($aThread->unum > 0) { $midoku_ari = true; $dele_log_qs = $thread_qs = array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key); if (defined('SID') && strlen(SID)) { $dele_log_qs[session_name()] = session_id(); } $dele_log_q = UriUtil::buildQuery($dele_log_qs); $unum_ht_c = P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], array_merge($thread_qs, array('spmode' => $aThreadList->spmode, 'dele' => '1', UA::getQueryKey() => UA::getQueryValue()))), hs($aThread->unum), array('id' => "un{$i}", 'class' => 'un_a', 'target' => '_self', 'title' => 'クリックするとログ削除', 'onClick' => sprintf("return !deleLog('%s', %s, 'subject', this);", str_replace("'", "\\'", $dele_log_q), $STYLE['info_pop_size']))); } // }}} // subject.txtにない時 if (!$aThread->isonline) { // JavaScriptでの確認ダイアログあり $unum_ht_c = "<a class=\"un_n\" href=\"{$_conf['subject_php']}?host={$aThread->host}{$bbs_q}{$key_q}{$spmode_q}&dele=true\" target=\"_self\" onClick=\"if (!window.confirm('ログを削除しますか?')) {return false;} return !deleLog('host={$aThread->host}{$bbs_q}{$key_q}{$sid_q}', {$STYLE['info_pop_size']}, 'subject', this)\"{$title_at}>-</a>"; } } $unum_ht = "<td{$class_tu}>" . $unum_ht_c . "</td>"; // 総レス数 $rescount_ht = "<td{$class_tn}>{$aThread->rescount}</td>"; // {{{ 板名 $ita_td_ht = ''; if ($ita_name_bool) { $ita_name = $aThread->itaj ? $aThread->itaj : $aThread->bbs; $ita_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $aThread->host, 'bbs' => $aThread->bbs)), $ita_name, array('target' => '_self')); $ita_td_ht = "<td{$class_t} nowrap>{$ita_atag}</td>"; } // }}} // お気に入り if ($_conf['sb_show_fav'] and $aThreadList->spmode != 'taborn') { $favmark = !empty($aThread->fav) ? '★' : '+'; $favvalue = !empty($aThread->fav) ? 0 : 1; $favtitle = $favvalue ? 'お気にスレに追加' : 'お気にスレから外す'; $setfav_q = '&setfav=' . $favvalue; // $ttitle_en_q も付けた方がいいが、節約のため省略する $fav_ht = <<<EOP <td{$class_t}><a class="fav" href="info.php?host={$aThread->host}{$bbs_q}{$key_q}{$setfav_q}" target="info" onClick="return setFavJs('host={$aThread->host}{$bbs_q}{$key_q}', '{$favvalue}', {$STYLE['info_pop_size']}, 'subject', this);" title="{$favtitle}">{$favmark}</a></td> EOP; } // torder(info) ================================================= // お気にスレ if ($aThread->fav) { $torder_st = "<b>{$aThread->torder}</b>"; } else { $torder_st = $aThread->torder; } $torder_ht = "<a id=\"to{$i}\" class=\"info\" href=\"info.php?host={$aThread->host}{$bbs_q}{$key_q}\" target=\"_self\" onClick=\"return !openSubWin('info.php?host={$aThread->host}{$bbs_q}{$key_q}&popup=1{$sid_q}',{$STYLE['info_pop_size']},0,0)\">{$torder_st}</a>"; // title ================================================= $chUnColor_ht = ''; $rescount_q = "&rc=" . $aThread->rescount; // dat倉庫 or 殿堂なら if ($aThreadList->spmode == "soko" || $aThreadList->spmode == "palace") { $rescount_q = ''; $offline_q = "&offline=1"; $anum_ht = ''; } // タイトル未取得or全角空白なら(IEで全角空白もリンククリックできないので) if (!$aThread->ttitle_ht or $aThread->ttitle_ht == ' ') { $aThread->ttitle_ht = "http://{$aThread->host}/test/read.cgi/{$aThread->bbs}/{$aThread->key}/"; } if ($aThread->similarity) { $aThread->ttitle_ht .= sprintf(' <var>(%0.1f)</var>', $aThread->similarity * 100); } // 元スレ $moto_thre_ht = ''; if ($_conf['sb_show_motothre']) { if (!$aThread->isKitoku()) { $moto_thre_ht = '<a class="thre_title" href="' . hs($aThread->getMotoThread()) . '">・</a> '; } } // 新規スレ if ($aThread->new) { $classtitle_q = ' class="thre_title_new"'; } else { $classtitle_q = ' class="thre_title"'; } // スレリンク if (!empty($_REQUEST['find_cont']) && strlen($GLOBALS['word_fm'])) { $word_q = "&word=" . urlencode($GLOBALS['word']) . "&method=" . urlencode($GLOBALS['sb_filter']['method']); $rescount_q = ''; $offline_q = '&offline=1'; $anum_ht = ''; } else { $word_q = ''; } $thre_url = "{$_conf['read_php']}?host={$aThread->host}{$bbs_q}{$key_q}{$rescount_q}{$offline_q}{$word_q}{$anum_ht}"; if ($midoku_ari) { $chUnColor_ht = "chUnColor('{$i}');"; } $change_color = " onClick=\"chTtColor('{$i}');{$chUnColor_ht}\""; // オンリー>>1 if ($onlyone_bool) { $one_ht = "<td{$class_t}><a href=\"{$_conf['read_php']}?host={$aThread->host}{$bbs_q}{$key_q}{$rescount_q}&onlyone=true\">>>1</a></td>"; } else { $one_ht = ''; } // チェックボックス $checkbox_ht = ''; if ($checkbox_bool) { $checked_ht = ''; if ($aThreadList->spmode == "taborn") { if (!$aThread->isonline) { $checked_ht = " checked"; } // or ($aThread->rescount >= 1000) } $checkbox_ht = "<td{$class_tc}><input name=\"checkedkeys[]\" type=\"checkbox\" value=\"{$aThread->key}\"{$checked_ht}></td>"; } // 並替 $edit_ht = ''; if ($sb_view == "edit") { $unum_ht = ''; $rescount_ht = ''; if ($aThreadList->spmode == "fav") { $setkey = "setfav"; } elseif ($aThreadList->spmode == "palace") { $setkey = "setpal"; } $narabikae_a = UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key, 'spmode' => $aThreadList->spmode, 'sb_view' => 'edit')); $edit_ht = <<<EOP \t\t<td{$class_te}> \t\t\t<a class="te" href="{$narabikae_a}&{$setkey}=top" target="_self">▲</a> \t\t\t<a class="te" href="{$narabikae_a}&{$setkey}=up" target="_self">↑</a> \t\t\t<a class="te" href="{$narabikae_a}&{$setkey}=down" target="_self">↓</a> \t\t\t<a class="te" href="{$narabikae_a}&{$setkey}=bottom" target="_self">▼</a> \t\t</td> EOP; } // すばやさ(= 時間/レス = レス間隔) $spd_ht = ''; if ($_conf['sb_show_spd']) { if ($spd_st = $aThread->getTimePerRes()) { $spd_ht = "<td{$class_ts}>{$spd_st}</td>"; } } // 勢い $ikioi_ht = ''; if ($_conf['sb_show_ikioi']) { if ($aThread->dayres > 0) { // 0.0 とならないように小数点第2位で切り上げ $dayres = ceil($aThread->dayres * 10) / 10; $dayres_st = sprintf("%01.1f", $dayres); } else { $dayres_st = "-"; } $ikioi_ht = "<td{$class_ti}>" . hs($dayres_st) . "</td>"; } // スレ立て日 //if (preg_match('/^\d{9,10}$/', $aThread->key) { if (631119600 < $aThread->key && $aThread->key < time() + 1000) { // 1990年- $birthday = date("y/m/d", $aThread->key); // (y/m/d H:i) } else { $birthday = '-'; } $birth_ht = "<td{$class_t}>{$birthday}</td>"; // スレッド一覧 table ボディ HTMLプリント <tr></tr> echo "<tr>\n{$edit_ht}\n{$unum_ht}\n{$rescount_ht}\n{$one_ht}\n{$checkbox_ht}\n<td{$class_to}>{$torder_ht}</td>\n<td{$class_tl} nowrap>{$moto_thre_ht}<a id=\"tt{$i}\" href=\"{$thre_url}\"{$classtitle_q}{$change_color}>{$aThread->ttitle_ht}</a></td>\n{$ita_td_ht}\n{$spd_ht}\n{$ikioi_ht}\n{$birth_ht}\n{$fav_ht}\n</tr>\n"; ob_flush(); flush(); } $GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('sb_print()'); }
/** * 引用変換(単独)(2009/05/06 範囲もこちらから) * * @access private * @return string HTML */ function quote_res_callback($s) { global $_conf; if (--$this->str_to_link_rest < 0) { return $s[0]; } list($full, $qsign, $appointed_num) = $s; $appointed_num = mb_convert_kana($appointed_num, 'n'); // 全角数字を半角数字に変換 if (preg_match('/\\D/', $appointed_num)) { $appointed_num = preg_replace('/\\D+/', '-', $appointed_num); return $this->quote_res_range_callback(array($full, $qsign, $appointed_num)); } if (preg_match('/^0/', $appointed_num)) { return $s[0]; } $qnum = intval($appointed_num); if ($qnum < 1 || $qnum >= $this->thread->rescount) { return $s[0]; } $read_url = UriUtil::buildQueryUri($_conf['read_php'], array('host' => $this->thread->host, 'bbs' => $this->thread->bbs, 'key' => $this->thread->key, 'offline' => '1', 'ls' => $appointed_num, UA::getQueryKey() => UA::getQueryValue())); $attributes = array(); if ($_conf['quote_res_view']) { $attributes = array('onmouseover' => "showResPopUp('q{$qnum}of{$this->thread->key}',event)", 'onclick' => 'var dummy=1; return false;'); } return P2View::tagA($read_url, "{$full}", $attributes); }
$ptitle_url = _getPageTitleUrl($aThreadList); // ページタイトル部分HTML $ptitle_ht = _getPageTitleHtml($aThreadList, $ptitle_url); // ビュー部分設定 ============================================== $edit_ht = ''; // スペシャルモード時 if ($aThreadList->spmode) { // お気にスレ or 殿堂なら if ($aThreadList->spmode == 'fav' or $aThreadList->spmode == 'palace') { $qs = array('spmode' => $aThreadList->spmode, 'norefresh' => '1', UA::getQueryKey() => UA::getQueryValue()); $attrs = array('class' => 'narabi', 'target' => '_self'); if ($sb_view == 'edit') { $edit_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], $qs), hs('並替'), $attrs); $edit_ht = $edit_atag; } else { $edit_atag = P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], array_merge(array('sb_view' => 'edit'), $qs)), hs('並替'), $attrs); $edit_ht = $edit_atag; } } } // フォーム hidden HTMLをセット $sb_form_hidden_ht = <<<EOP \t\t\t<input type="hidden" name="detect_hint" value="◎◇"> \t\t\t<input type="hidden" name="bbs" value="{$aThreadList->bbs}"> \t\t\t<input type="hidden" name="host" value="{$aThreadList->host}"> \t\t\t<input type="hidden" name="spmode" value="{$aThreadList->spmode}"> \t\t\t{$_conf['k_input_ht']} EOP; // {{{ 表示件数 フォームHTMLをセット $sb_disp_num_ht = ''; if (!$aThreadList->spmode || $aThreadList->spmode == "news") {
/** * @return string HTML */ function _getOffRecentATag($aThread, $offrecent_accesskey, $ttitle_en) { global $_conf; $preKey = ''; if (UA::isK() && $offrecent_accesskey) { $preKey = $offrecent_accesskey . '.'; } return P2View::tagA(UriUtil::buildQueryUri('info_i.php', array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key, 'offrecent' => '1', 'popup' => (int) (bool) geti($_GET['popup']), 'ttitle_en' => $ttitle_en, UA::getQueryKey() => UA::getQueryValue())), sprintf('%s履歴から外す', hs($preKey)), array('title' => 'このスレを「最近読んだスレ」と「書き込み履歴」から外します', 'accesskey' => $offrecent_accesskey)); }
/** * 書 <a> * * @return string HTML */ function _getDoResATag($aThread, $dores_st, $motothre_url) { global $_conf; $dores_atag = null; if ($_conf['disable_res']) { $dores_atag = P2View::tagA($motothre_url, hs("{$_conf['k_accesskey']['res']}.{$dores_st}"), array('target' => '_blank', $_conf['accesskey_for_k'] => $_conf['k_accesskey']['res'])); } else { $dores_atag = P2View::tagA(UriUtil::buildQueryUri('post_form.php', array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key, 'rescount' => $aThread->rescount, 'ttitle_en' => base64_encode($aThread->ttitle), UA::getQueryKey() => UA::getQueryValue())), hs("{$_conf['k_accesskey']['res']}.{$dores_st}"), array($_conf['accesskey_for_k'] => $_conf['k_accesskey']['res'])); } return $dores_atag; }
/** * 画像ポップアップ変換 * * @access private * @return string|false HTML */ function plugin_viewImage($url, $purl, $html) { global $_conf; // 表示制限 if (!isset($GLOBALS['pre_thumb_limit']) && $_conf['pre_thumb_limit']) { $GLOBALS['pre_thumb_limit'] = $_conf['pre_thumb_limit']; } if (!$_conf['preview_thumbnail'] || empty($GLOBALS['pre_thumb_limit'])) { return false; } if (preg_match('{^https?://.+?\\.(jpe?g|gif|png)$}i', $url) && empty($purl['query'])) { $GLOBALS['pre_thumb_limit']--; $img_tag = sprintf('<img class="thumbnail" src="%s" height="%s" weight="%s" hspace="4" vspace="4" align="middle">', hs($url), hs($_conf['pre_thumb_height']), hs($_conf['pre_thumb_width'])); switch ($_conf['iframe_popup']) { case 1: $view_img_ht = $this->iframePopup($url, $img_tag . $html, array('target' => $_conf['ext_win_target'])); break; case 2: // (p)の設定だが、画像サムネイルを利用する $view_img_ht = $this->iframePopup($url, array($html, $img_tag), array('target' => $_conf['ext_win_target'])); break; case 3: // p画像の設定だが、画像サムネイルを利用する $view_img_ht = $this->iframePopup($url, array($html, $img_tag), array('target' => $_conf['ext_win_target'])); break; default: $view_img_ht = P2View::tagA($url, "{$img_tag}{$html}", array('target' => $_conf['ext_win_target'])); } // ブラクラチェッカ (プレビューとは相容れないのでコメントアウト) /* if ($_conf['brocra_checker_use']) { $link_url_en = rawurlencode($url); $atag = P2View::tagA( "{$_conf['brocra_checker_url']}?{$_conf['brocra_checker_query']}={$link_url_en}", hs('チェック') array('target' => $_conf['ext_win_target']) ); $view_img_ht .= " [$atag]"; } */ return $view_img_ht; } return false; }
/** * レス記事をHTML表示する 携帯用 * * @access public * @param array * @return void */ function printArticlesHtmlK($datlines) { global $_conf; $hr = P2View::getHrHtmlK(); $n = 0; foreach ($datlines as $aline) { $n++; if ($n < $this->resrange['start'] or $n > $this->resrange['to']) { continue; } $aline = rtrim($aline); $ResArticle = $this->lineToRes($aline, $n); $daytime_hs = hs($ResArticle->daytime); $ttitle = html_entity_decode($ResArticle->ttitle, ENT_COMPAT, 'Shift_JIS'); $ttitle_hs = hs($ttitle); $msg_ht = $ResArticle->msg; // 大きさ制限 if (empty($_GET['k_continue'])) { if ($_conf['ktai_res_size'] && strlen($msg_ht) > $_conf['ktai_res_size']) { $msg_ht = substr($msg_ht, 0, $_conf['ktai_ryaku_size']); // 末尾に<br>があれば取り除く(不完全なものも含めて) $brtag = '<br>'; for ($i = 0; $i < strlen($brtag); $i++) { if (substr($msg_ht, -1) == $brtag[strlen($brtag) - $i - 1]) { $msg_ht = substr($msg_ht, 0, strlen($msg_ht) - 1); } } $msg_ht .= ' ' . P2View::tagA(UriUtil::buildQueryUri('read_res_hist.php', array('from' => $ResArticle->order, 'end' => $ResArticle->order, 'k_continue' => '1', UA::getQueryKey() => UA::getQueryValue())), hs('略')); } } // 番号 $res_ht = "[{$ResArticle->order}]"; // 名前 $array = explode('#', $ResArticle->name, 2); if (count($array) == 2) { $name_ht = sprintf('%s◆%s', $array[0], P2Util::mkTrip($array[1])); } else { $name_ht = hs($ResArticle->name); } $res_ht .= $name_ht . ':'; // メール if ($ResArticle->mail) { $res_ht .= hs($ResArticle->mail) . ':'; } // 日付とID $res_ht .= "{$daytime_hs}<br>\n"; // 板名 $res_ht .= P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $ResArticle->host, 'bbs' => $ResArticle->bbs, UA::getQueryKey() => UA::getQueryValue())), hs($ResArticle->itaj)) . ' / '; if ($ResArticle->key) { if (empty($ResArticle->resnum) || $ResArticle->resnum == 1) { $ls_qs = array(); $footer_anchor = '#footer'; } else { $lf = max(1, $ResArticle->resnum - 0); $ls_qs = array('ls' => "{$lf}-"); $footer_anchor = "#r{$lf}"; } $time = time(); $ttitle_qs = array_merge(array('host' => $ResArticle->host, 'bbs' => $ResArticle->bbs, 'key' => $ResArticle->key, UA::getQueryKey() => UA::getQueryValue(), 'nt' => time()), $ls_qs); $res_ht .= P2View::tagA(UriUtil::buildQueryUri($_conf['read_php'], $ttitle_qs) . $footer_anchor, "{$ttitle_hs} "); } else { $res_ht .= "{$ttitle_hs}\n"; } // 削除 // $res_ht = "<dt><input name=\"checked_hists[]\" type=\"checkbox\" value=\"{$ResArticle->order},,,,{$daytime_hs}\"> "; $from_q = isset($_GET['from']) ? '&from=' . intval($_GET['from']) : ''; $dele_ht = "[<a href=\"read_res_hist.php?checked_hists[]={$ResArticle->order},,,," . hs(urlencode($ResArticle->daytime)) . "{$from_q}{$_conf['k_at_a']}\">削除</a>]"; $res_ht .= $dele_ht; $res_ht .= '<br>'; // 内容 $res_ht .= "{$msg_ht}{$hr}\n"; if ($_conf['k_save_packet']) { $res_ht = mb_convert_kana($res_ht, 'rnsk'); } echo $res_ht; } }
/** * 1- 101- 201- のリンクHTMLを取得する * _getHeadBarHtml() から呼ばれる * * @return string HTML */ function _getReadNaviRangeHtml($aThread, $rnum_range) { global $_conf; static $cache_ = array(); if (array_key_exists("{$aThread->host}/{$aThread->bbs}/{$aThread->key}", $cache_)) { return $cache_["{$aThread->host}/{$aThread->bbs}/{$aThread->key}"]; } $read_navi_range_ht = ''; for ($i = 1; $i <= $aThread->rescount; $i = $i + $rnum_range) { $ito = $i + $rnum_range - 1; $qs = array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key, 'ls' => "{$i}-{$ito}", UA::getQueryKey() => UA::getQueryValue()); if ($ito <= $aThread->gotnum) { $qs['offline'] = '1'; } $url = UriUtil::buildQueryUri($_conf['read_php'], $qs); $read_navi_range_ht .= P2View::tagA($url, "{$i}-") . "\n"; } return $cache_["{$aThread->host}/{$aThread->bbs}/{$aThread->key}"] = $read_navi_range_ht; }
/** * 2008/09/28 $_conf['k_to_index_ht'] を廃止して、こちらを利用する * * @static * @access public * @return string */ function getBackToIndexKATag() { global $_conf; $accessKeyValue = '0'; return P2View::tagA(UriUtil::buildQueryUri('index.php', array(UA::getQueryKey() => UA::getQueryValue())), hs($accessKeyValue . '.TOP'), array($_conf['accesskey_for_k'] => $accessKeyValue)); }
/** * お気に板をHTML表示する for 携帯 * * @access public * @return void */ function printFavItaHtml() { global $_conf; $csrfid = P2Util::getCsrfId(); $hr = P2View::getHrHtmlK(); $show_flag = false; if (file_exists($_conf['favita_path']) and $lines = file($_conf['favita_path'])) { echo 'お気に板 [<a href="editfavita.php?b=k">編集</a>]' . $hr; $i = 0; foreach ($lines as $l) { $i++; $l = rtrim($l); if (preg_match("/^\t?(.+)\t(.+)\t(.+)\$/", $l, $matches)) { $itaj = rtrim($matches[3]); $attr = array(); $key_num_st = ''; if ($i <= 9) { $attr[$_conf['accesskey_for_k']] = $i; $key_num_st = "{$i}."; } $atag = P2View::tagA(UriUtil::buildQueryUri($_conf['subject_php'], array('host' => $matches[1], 'bbs' => $matches[2], 'itaj_en' => base64_encode($itaj), UA::getQueryKey() => UA::getQueryValue())), UA::isIPhoneGroup() ? hs($itaj) : hs("{$key_num_st}{$itaj}"), $attr); if (UA::isIPhoneGroup()) { echo '<li>' . $atag . '</li>'; } else { echo $atag . '<br>'; } // [<a href="{$_SERVER['SCRIPT_NAME']}?host={$matches[1]}&bbs={$matches[2]}&setfavita=0&csrfid={$csrfid}&view=favita{$_conf['k_at_a']}">削</a>] $show_flag = true; } } if (UA::isIPhoneGroup()) { ?> </ul><?php } } if (!$show_flag) { ?> <p>お気に板はまだないようだ</p><?php } }
/** * 新着まとめ読みのキャッシュリンクHTMLを表示する * * @return void */ function _printMatomeCacheLinksHtml() { global $_conf; $max = $_conf['matome_cache_max']; $links = array(); for ($i = 0; $i <= $max; $i++) { $dnum = $i ? '.' . $i : ''; $file = $_conf['matome_cache_path'] . $dnum . $_conf['matome_cache_ext']; //echo '<!-- ' . $file . ' -->'; if (file_exists($file)) { $filemtime = filemtime($file); $date = date('Y/m/d G:i:s', $filemtime); $b = filesize($file) / 1024; $kb = round($b, 0); $atag = P2View::tagA(UriUtil::buildQueryUri('read_new.php', array('cview' => '1', 'cnum' => "{$i}", 'filemtime' => $filemtime)), hs($date), array('target' => 'read')); $links[] = sprintf('%s %dKB', $atag, $kb); } } if ($links) { echo '<ul><li class="group">新着まとめ読みの前回キャッシュ</li></ul><div id="usage" class="panel"><filedset>' . implode('<br>', $links) . '</fildset></div>' . "\n"; } }
// レス記事 HTML表示 //================================================================== if (UA::isK()) { $ResHist->printArticlesHtmlK($datlines); } else { $ResHist->printArticlesHtml($datlines); } //================================================================== // フッタHTML表示 //================================================================== // 携帯用表示 if (UA::isK()) { ?> <div id="footer" name="footer"><?php $ResHist->showNaviK('footer', $datlines_num); $atag = P2View::tagA('#header', hs($_conf['k_accesskey']['above'] . '.▲'), array($_conf['accesskey_for_k'] => $_conf['k_accesskey']['above'])); echo " {$atag}<br>"; echo "</div>"; ?> <p><?php echo P2View::getBackToIndexKATag(); ?> </p><?php // PC用表示 } else { ?> <hr> <table id="footer" width="100%" style="padding:0px 10px 0px 0px;"> <tr> <td align="right"><?php echo $toolbar_ht;
foreach ($formdata as $k => $v) { printf($row_format, $k, htmlspecialchars($v['word'], ENT_QUOTES), $v['ic'], $v['re'], htmlspecialchars($v['ht'], ENT_QUOTES), $v['hn'], htmlspecialchars($v['bbs'], ENT_QUOTES), htmlspecialchars($v['tt'], ENT_QUOTES), strlen($v['ht']) > 0 ? htmlspecialchars($v['ht'], ENT_QUOTES) : '--'); } echo $htm['form_submit']; } // PCなら if (!$_conf['ktai']) { echo '</table>' . "\n"; } ?> </form> <?php // 携帯なら if (UA::isK()) { echo P2View::getHrHtmlK(); echo P2View::tagA(UriUtil::buildQueryUri($_conf['editpref_php'], array(UA::getQueryKey() => UA::getQueryValue())), hs(sprintf('%s.設定編集', $_conf['k_accesskey']['up'])), array($_conf['accesskey_for_k'] => $_conf['k_accesskey']['up'])); echo P2View::getBackToIndexKATag(); } ?> </body></html> <?php /* * Local Variables: * mode: php * coding: cp932 * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode: nil * End: */ // vim: set syn=php fenc=cp932 ai et ts=4 sw=4 sts=4 fdm=marker:
/** * 新着まとめ読みのキャッシュリンクHTMLを表示する * * @return void */ function _printMatomeCacheLinksHtml() { global $_conf; $max = $_conf['matome_cache_max']; $links = array(); for ($i = 0; $i <= $max; $i++) { $dnum = $i ? '.' . $i : ''; $file = $_conf['matome_cache_path'] . $dnum . $_conf['matome_cache_ext']; //echo '<!-- ' . $file . ' -->'; if (file_exists($file)) { $filemtime = filemtime($file); $date = date('Y/m/d G:i:s', $filemtime); $b = filesize($file) / 1024; $kb = round($b, 0); $atag = P2View::tagA(UriUtil::buildQueryUri('read_new.php', array('cview' => '1', 'cnum' => "{$i}", 'filemtime' => $filemtime)), hs($date), array('target' => 'read')); $links[] = sprintf('%s %dKB', $atag, $kb); } } if ($links) { echo '<p>新着まとめ読みの前回キャッシュを表\示<br>' . implode('<br>', $links) . '</p>' . "\n"; if ($_conf['ktai']) { $hr = P2View::getHrHtmlK(); echo $hr . "\n"; } } }
/** * @return string HTML */ function _getPostLinkATag($aThread, $ttitle_en) { return $post_link_atag = P2View::tagA(UriUtil::buildQueryUri('post_form.php', array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key, 'rescount' => $aThread->rescount, 'ttitle_en' => $ttitle_en, UA::getQueryKey() => UA::getQueryValue())), '書'); }
/** * メニュー項目のリンクHTMLを取得する * * @access private * @param array $menuKIni メニュー項目 標準設定 * @param boolean $noLink リンクをつけないのならtrue * @return string HTML */ function _getMenuKLinkHtml($code, $menuKIni, $noLink = false) { global $_conf, $_login; static $accesskey_ = 0; // 無効なコード指定なら if (!isset($menuKIni[$code][0]) || !isset($menuKIni[$code][1])) { return false; } $accesskey = ++$accesskey_; if ($_conf['index_menu_k_from1']) { $accesskey = $accesskey + 1; if ($accesskey == 10) { $accesskey = 0; } } if ($accesskey > 9) { $accesskey = null; } $href = $menuKIni[$code][0] . '&user='******'&' . UA::getQueryKey() . '=' . UA::getQueryValue(); $name = $menuKIni[$code][1]; /*if (!is_null($accesskey)) { $name = $accesskey . '.' . $name; }*/ if ($noLink) { $linkHtml = hs($name); } else { $accesskeyAt = is_null($accesskey) ? '' : " {$_conf['accesskey_for_k']}=\"{$accesskey}\""; $linkHtml = "<a href=\"" . hs($href) . '">' . hs($name) . "</a>"; } // 特別 - #.ログ if ($code == 'res_hist') { $name = 'ログ'; if ($noLink) { $logHt = hs($name); } else { $newtime = date('gis'); $logHt = P2View::tagA(UriUtil::buildQueryUri('read_res_hist.php', array('nt' => $newtime, UA::getQueryKey() => UA::getQueryValue())), hs($name), array($_conf['accesskey_for_k'] => '#')); } $linkHtml .= ' </li><li>' . $logHt; } return $linkHtml; }
/** * >>1のみをプレビュー表示するためのHTMLを取得する(オンザフライに対応) * * @access public * @return string|false */ function previewOne() { global $_conf, $ptitle_ht; if (!($this->host && $this->bbs && $this->key)) { return false; } $first_line = ''; // ローカルdatから取得 if (is_readable($this->keydat)) { $fd = fopen($this->keydat, "rb"); $first_line = fgets($fd, 32800); fclose($fd); } if ($first_line) { // be.2ch.net ならEUC→SJIS変換 if (P2Util::isHostBe2chNet($this->host)) { $first_line = mb_convert_encoding($first_line, 'SJIS-win', 'eucJP-win'); } $first_datline = rtrim($first_line); if (strstr($first_datline, "<>")) { $datline_sepa = "<>"; } else { $datline_sepa = ","; $this->dat_type = "2ch_old"; } $d = explode($datline_sepa, $first_datline); $this->setTtitle($d[4]); // 便宜上 if (!$this->readnum) { $this->readnum = 1; } } // ローカルdatなければオンラインから if (!$first_line) { $url = $this->getDatUrl($this->host, $this->bbs, $this->key); $purl = parse_url($url); $purl['query'] = isset($purl['query']) ? '?' . $purl['query'] : ''; // プロキシ if ($_conf['proxy_use']) { $send_host = $_conf['proxy_host']; $send_port = $_conf['proxy_port']; $send_path = $url; } else { $send_host = $purl['host']; $send_port = isset($purl['port']) ? $purl['port'] : null; $send_path = $purl['path'] . $purl['query']; } // デフォルトを80 !$send_port and $send_port = 80; $request = 'GET ' . $send_path . " HTTP/1.0\r\n"; $request .= "Host: " . $purl['host'] . "\r\n"; $request .= 'User-Agent: ' . P2Util::getP2UA($withMonazilla = true) . "\r\n"; // $request .= "Range: bytes={$from_bytes}-\r\n"; // Basic認証用のヘッダ if (isset($purl['user']) && isset($purl['pass'])) { $request .= "Authorization: Basic " . base64_encode($purl['user'] . ":" . $purl['pass']) . "\r\n"; } $request .= "Connection: Close\r\n"; $request .= "\r\n"; // WEBサーバへ接続 $fp = fsockopen($send_host, $send_port, $errno, $errstr, $_conf['fsockopen_time_limit']); if (!$fp) { P2Util::pushInfoHtml(sprintf('<p>サーバ接続エラー: %s (%s)<br>p2 info - %s に接続できませんでした。</p>', $errstr, $errno, P2View::tagA(P2Util::throughIme($url), hs($url), array('target' => $_conf['ext_win_target'])))); $this->diedat = true; return false; } // HTTPリクエスト送信 fputs($fp, $request); // HTTPヘッダレスポンスを取得する $h = $this->freadHttpHeader($fp); if ($h === false) { fclose($fp); $this->_pushInfoHtmlFreadHttpHeaderError($url); $this->diedat = true; return false; } // {{{ HTTPコードをチェック $code = $h['code']; // Partial Content if ($code == "200") { // OK。何もしない // 予期しないHTTPコード。なかったと判断する } else { fclose($fp); $this->previewOneNotFound(); return false; } // }}} if (isset($h['headers']['Content-Length'])) { if (preg_match("/^([0-9]+)/", $h['headers']['Content-Length'], $matches)) { $onbytes = $h['headers']['Content-Length']; } } // bodyを一行目だけ読む $first_line = fgets($fp, 32800); fclose($fp); // be.2ch.net ならEUC→SJIS変換 if (P2Util::isHostBe2chNet($this->host)) { $first_line = mb_convert_encoding($first_line, 'SJIS-win', 'eucJP-win'); } $first_datline = rtrim($first_line); if (strstr($first_datline, '<>')) { $datline_sepa = '<>'; } else { $datline_sepa = ','; $this->dat_type = '2ch_old'; } $d = explode($datline_sepa, $first_datline); $this->setTtitle($d[4]); $this->onthefly = true; } // 厳密にはオンザフライではないが、個人にとっては(既読記録がされないという意味で)オンザフライ if (!$this->isKitoku()) { $this->onthefly = true; } $body = ''; if (!empty($this->onthefly)) { // PC if (UA::isPC()) { $body .= '<div><span class="onthefly">プレビュー</span></div>'; // 携帯 } else { $body .= '<div><font size="-1" color="#00aa00">プレビュー</font></div>'; } } UA::isPC() and $body .= '<dl>'; require_once P2_LIB_DIR . '/ShowThread.php'; // PC if (UA::isPC()) { require_once P2_LIB_DIR . '/ShowThreadPc.php'; $aShowThread = new ShowThreadPc($this); // 携帯 } else { require_once P2_LIB_DIR . '/ShowThreadK.php'; $aShowThread = new ShowThreadK($this); } $body .= $aShowThread->transRes($first_line, 1); // 1を表示 UA::isPC() and $body .= "</dl>\n"; return $body; }
/** * 「続きを読む」 <a> * * @return string HTML */ function _getTudukiATag($aThread, $tuduki_st) { global $_conf; return P2View::tagA(UriUtil::buildQueryUri($_conf['read_php'], array('host' => $aThread->host, 'bbs' => $aThread->bbs, 'key' => $aThread->key, 'ls' => $GLOBALS['last_hit_resnum'] . '-', 'offline' => '1')), hs($tuduki_st), array('accesskey' => $_conf['pc_accesskey']['tuduki'], 'title' => sprintf('アクセスキー[%s]', $_conf['pc_accesskey']['tuduki']), 'style' => 'white-space: nowrap;')); }
/** * subject.txtをダウンロードする * * @access public * @return array|null|false subject.txtの配列データ(eaccelerator, apc用)、またはnullを返す。 * 失敗した場合はfalseを返す。 */ function downloadSubject() { global $_conf; static $spentDlTime_ = 0; // DL所要合計時間 $perm = isset($_conf['dl_perm']) ? $_conf['dl_perm'] : 0606; $modified = false; if ($this->storage == 'file') { FileCtl::mkdirFor($this->subject_file); // 板ディレクトリが無ければ作る if (file_exists($this->subject_file)) { // ファイルキャッシュがあれば、DL制限時間をかける if (UA::isK()) { $dlSubjectTotalLimitTime = $_conf['dlSubjectTotalLimitTimeM']; } else { $dlSubjectTotalLimitTime = $_conf['dlSubjectTotalLimitTime']; } if ($dlSubjectTotalLimitTime and $spentDlTime_ > $dlSubjectTotalLimitTime) { return null; } // 条件によって、キャッシュを適用する // subject.php でrefresh指定がある時は、キャッシュを適用しない if (!(basename($_SERVER['SCRIPT_NAME']) == $_conf['subject_php'] && !empty($_REQUEST['refresh']))) { // キャッシュ適用指定時は、その場で抜ける if (!empty($_GET['norefresh']) || isset($_REQUEST['word'])) { return null; // 並列ダウンロード済の場合も抜ける } elseif (!empty($GLOBALS['expack.subject.multi-threaded-download.done'])) { return null; // 新規スレ立て時以外で、キャッシュが新鮮な場合も抜ける } elseif (empty($_POST['newthread']) and $this->isSubjectTxtFresh()) { return null; } } $modified = gmdate("D, d M Y H:i:s", filemtime($this->subject_file)) . " GMT"; } } $dlStartTime = $this->microtimeFloat(); // DL require_once 'HTTP/Request.php'; $params = array(); $params['timeout'] = $_conf['fsockopen_time_limit']; if ($_conf['proxy_use']) { $params['proxy_host'] = $_conf['proxy_host']; $params['proxy_port'] = $_conf['proxy_port']; } $req = new HTTP_Request($this->subject_url, $params); $modified && $req->addHeader('If-Modified-Since', $modified); $req->addHeader('User-Agent', sprintf('Monazilla/1.00 (%s/%s)', $_conf['p2uaname'], $_conf['p2version'])); $response = $req->sendRequest(); $error_msg = null; if (PEAR::isError($response)) { $error_msg = $response->getMessage(); } else { $code = $req->getResponseCode(); if ($code == 302) { // ホストの移転を追跡 require_once P2_LIB_DIR . '/BbsMap.php'; $new_host = BbsMap::getCurrentHost($this->host, $this->bbs); if ($new_host != $this->host) { $aNewSubjectTxt = new SubjectTxt($new_host, $this->bbs); return $aNewSubjectTxt->downloadSubject(); } } if (!($code == 200 || $code == 206 || $code == 304)) { //var_dump($req->getResponseHeader()); $error_msg = $code; } } if (!is_null($error_msg) && strlen($error_msg) > 0) { $attrs = array(); if ($_conf['ext_win_target']) { $attrs['target'] = $_conf['ext_win_target']; } $atag = P2View::tagA(P2Util::throughIme($this->subject_url), hs($this->subject_url), $attrs); $msg_ht = sprintf('<div>Error: %s<br>p2 info - %s に接続できませんでした。</div>', hs($error_msg), $atag); P2Util::pushInfoHtml($msg_ht); $body = ''; } else { $body = $req->getResponseBody(); } $dlEndTime = $this->microtimeFloat(); $dlTime = $dlEndTime - $dlStartTime; $spentDlTime_ += $dlTime; // DL成功して かつ 更新されていたら if ($body && $code != '304') { // したらば or be.2ch.net ならEUCをSJISに変換 if (P2Util::isHostJbbsShitaraba($this->host) || P2Util::isHostBe2chNet($this->host)) { $body = mb_convert_encoding($body, 'SJIS-win', 'eucJP-win'); } // eaccelerator or apcに保存する場合 if ($this->storage == 'eaccelerator' || $this->storage == 'apc') { $cache_key = "{$this->host}/{$this->bbs}"; $cont = rtrim($body); $lines = explode("\n", $cont); if ($this->storage == 'eaccelerator') { eaccelerator_lock($cache_key); eaccelerator_put($cache_key, $lines, $_conf['sb_dl_interval']); eaccelerator_unlock($cache_key); } else { apc_store($cache_key, $lines, $_conf['sb_dl_interval']); } return $lines; // ファイルに保存する場合 } else { if (false === FileCtl::filePutRename($this->subject_file, $body)) { // 保存に失敗はしても、既存のキャッシュが読み込めるならよしとしておく if (is_readable($this->subject_file)) { return null; } else { die("Error: cannot write file"); return false; } } chmod($this->subject_file, $perm); } } else { // touchすることで更新インターバルが効くので、しばらく再チェックされなくなる // (変更がないのに修正時間を更新するのは、少し気が進まないが、ここでは特に問題ないだろう) if ($this->storage == 'file') { touch($this->subject_file); } } return null; }