/** * ImageCache2 の一時的な有効・無効を切り替える * * @param bool $switch * @param bool $mobile * @return bool */ public static function set($switch, $mobile = false) { global $_conf; $switch_file = $_conf['expack.ic2.switch_path']; if (!file_exists($switch_file)) { FileCtl::make_datafile($switch_file); $flags = self::ENABLED_ALL; } else { $flags = self::ENABLED_ALL & filesize($switch_file); } if ($switch) { if ($mobile) { $flags |= self::ENABLED_MOBILE; } else { $flags |= self::ENABLED_PC; } } else { if ($mobile) { $flags &= ~self::ENABLED_MOBILE; } else { $flags &= ~self::ENABLED_PC; } } if ($flags > 0) { $data = str_repeat('*', $flags); } else { $data = ''; } return file_put_contents($switch_file, $data, LOCK_EX) === $flags; }
/** * チェックした書き込み記事を削除する * * @access public * @return boolean */ function deleMsg($checked_hists) { global $_conf; if (!($reslines = file($_conf['p2_res_hist_dat']))) { p2die(sprintf('%s を開けませんでした', $_conf['p2_res_hist_dat'])); return false; } $reslines = array_map('rtrim', $reslines); // ファイルの下に記録されているものが新しいので逆順にする $reslines = array_reverse($reslines); $neolines = array(); // チェックして整えて if ($reslines) { $rmnums = _getRmNums($checked_hists, $reslines); $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 (false === FileCtl::filePutRename($_conf['p2_res_hist_dat'], $cont)) { $errmsg = sprintf('p2 error: %s(), FileCtl::filePutRename() failed.', __FUNCTION__); trigger_error($errmsg, E_USER_WARNING); return false; } } return true; }
/** * チャットちゃんねる cha2.net の dat を読んで保存する関数 * (差分取得には未対応) * ※2ch互換として読み込んでいるので現在この関数は利用はしていない。@see TreadRead->downloadDat() * * @access public * @return boolean */ function downloadDatCha2(&$ThreadRead) { // {{{ 既得datの取得レス数が適性かどうかを念のためチェック if (file_exists($ThreadRead->keydat)) { $dls = file($ThreadRead->keydat); if (sizeof($dls) != $ThreadRead->gotnum) { // echo 'bad size!<br>'; unlink($ThreadRead->keydat); $ThreadRead->gotnum = 0; } } else { $ThreadRead->gotnum = 0; } // }}} if ($ThreadRead->gotnum == 0) { $file_append = false; $START = 1; } else { $file_append = true; $START = $ThreadRead->gotnum + 1; } // チャットちゃんねる $cha2url = "http://{$ThreadRead->host}/cgi-bin/{$ThreadRead->bbs}/dat/{$ThreadRead->key}.dat"; $datfile = $ThreadRead->keydat; FileCtl::mkdirFor($datfile); $cha2url_res = P2Util::fileDownload($cha2url, $datfile); if (!$cha2url_res or !$cha2url_res->is_success()) { $ThreadRead->diedat = true; return false; } $ThreadRead->isonline = true; return true; }
/** * ディレクトリに(アクセス拒否のための) .htaccess がなければ、自動で生成する * * @return void */ function makeDenyHtaccess($dir) { $hta = $dir . '/.htaccess'; if (!file_exists($hta)) { $data = 'Order allow,deny' . "\n" . 'Deny from all' . "\n"; FileCtl::file_write_contents($hta, $data); } }
/** * お気にスレをセットする関数 * * $setfav は、'0'(解除), '1'(追加), 'top', 'up', 'down', 'bottom' * * @access public * @return boolean */ function setFav($host, $bbs, $key, $setfav) { global $_conf; if (P2Validate::host($host) || P2Validate::bbs($bbs) || P2Validate::key($key)) { return false; } // スレッド.idx 記録 $data = _setFavToKeyIdx($host, $bbs, $key, $setfav); $newlines = array(); $before_line_num = 0; if (false === FileCtl::make_datafile($_conf['favlist_file'], $_conf['favlist_perm'])) { return false; } if (false === ($favlines = file($_conf['favlist_file']))) { return false; } // 最初に重複要素を削除しておく if (!empty($favlines)) { $i = -1; foreach ($favlines as $line) { $i++; $line = rtrim($line); $lar = explode('<>', $line); // 重複回避 if ($lar[1] == $key && $lar[11] == $bbs) { $before_line_num = $i; // 移動前の行番号をセット continue; // keyのないものは不正データなのでスキップ } elseif (!$lar[1]) { continue; } elseif (P2Validate::host($lar[10]) || P2Validate::bbs($lar[11]) || P2Validate::key($lar[1])) { continue; } else { $newlines[] = $line; } } } if (!empty($GLOBALS['brazil'])) { //$newlines = _removeLargeFavlistData($newlines); } // 記録データ設定 if ($setfav) { $newdata = implode('<>', array(geti($data[0]), $key, geti($data[2]), geti($data[3]), geti($data[4]), geti($data[5]), 1, geti($data[7]), geti($data[8]), geti($data[9]), $host, $bbs)); require_once P2_LIB_DIR . '/getSetPosLines.func.php'; $rec_lines = getSetPosLines($newlines, $newdata, $before_line_num, $setfav); } else { $rec_lines = $newlines; } if (false === file_put_contents($_conf['favlist_file'], $rec_lines ? implode("\n", $rec_lines) . "\n" : '', LOCK_EX)) { trigger_error(sprintf('file_put_contents(%s)', $_conf['favlist_file']), E_USER_WARNING); return false; } // お気にスレ共有 _setFavRank($host, $bbs, $key, $setfav, geti($data[0])); return true; }
/** * 検索履歴を読み込む */ 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 "あぼーん解除、完了しました。"; } */ }
/** * ファイル内容を読み込んで編集する関数 */ function editFile($path, $encode, $title) { global $_conf, $modori_url, $rows, $cols, $csrfid; if ($path == '') { p2die('path が指定されていません'); } $filename = basename($path); $ptitle = 'Edit: ' . p2h($title) . ' (' . $filename . ')'; //ファイル内容読み込み FileCtl::make_datafile($path) or p2die("cannot make file. ({$path})"); $cont = file_get_contents($path); if ($encode == "EUC-JP") { $cont = mb_convert_encoding($cont, 'CP932', 'CP51932'); } $cont_area = p2h($cont); if ($modori_url) { $modori_url_ht = "<p><a href=\"{$modori_url}\">Back</a></p>\n"; } else { $modori_url_ht = ''; } $rows_at = $rows > 0 ? sprintf(' rows="%d"', $rows) : ''; $cols_at = $cols > 0 ? sprintf(' cols="%d"', $cols) : ''; // プリント echo $_conf['doctype']; echo <<<EOHEADER <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Style-Type" content="text/css"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <meta name="ROBOTS" content="NOINDEX, NOFOLLOW"> {$_conf['extra_headers_ht']} <title>{$ptitle}</title> </head> <body onload="top.document.title=self.document.title;"> EOHEADER; $info_msg_ht = P2Util::getInfoHtml(); echo $modori_url_ht; echo $ptitle; echo <<<EOFORM <form action="{$_SERVER['SCRIPT_NAME']}" method="post" accept-charset="{$_conf['accept_charset']}"> <input type="hidden" name="file" value="{$filename}"> <input type="hidden" name="modori_url" value="{$modori_url}"> <input type="hidden" name="encode" value="{$encode}"> <input type="hidden" name="rows" value="{$rows}"> <input type="hidden" name="cols" value="{$cols}"> <input type="hidden" name="csrfid" value="{$csrfid}"> <input type="submit" name="submit" value="Save"> {$info_msg_ht}<br> <textarea style="font-size:9pt;" id="filecont" name="filecont" wrap="off"{$rows_at}{$cols_at}>{$cont_area}</textarea> {$_conf['detect_hint_input_ht']}{$_conf['k_input_ht']} </form> EOFORM; echo '</body></html>'; return true; }
/** * スレを殿堂入りにセットする関数 * * $set は、0(解除), 1(追加), top, up, down, bottom * * @access public * @return boolean */ function setPalace($host, $bbs, $key, $set) { global $_conf; $idxfile = P2Util::getKeyIdxFilePath($host, $bbs, $key); // 既に key.idx データがあるなら読み込む if (file_exists($idxfile) and $lines = file($idxfile)) { $l = rtrim($lines[0]); $data = explode('<>', $l); } if (false === FileCtl::make_datafile($_conf['palace_file'], $_conf['palace_perm'])) { return false; } if (false === ($pallines = file($_conf['palace_file']))) { return false; } $newlines = array(); $before_line_num = 0; // {{{ 最初に重複要素を削除しておく if (!empty($pallines)) { $i = -1; foreach ($pallines as $l) { $i++; $l = rtrim($l); $lar = explode('<>', $l); // 重複回避 if ($lar[1] == $key && $lar[11] == $bbs) { $before_line_num = $i; // 移動前の行番号をセット continue; // keyのないものは不正データなのでスキップ } elseif (!$lar[1]) { continue; } else { $newlines[] = $l; } } } // }}} if (!empty($GLOBALS['brazil'])) { //$newlines = _removeLargePallistData($newlines); } // 新規データ設定 if ($set) { $newdata = implode('<>', array(geti($data[0]), $key, geti($data[2]), geti($data[3]), geti($data[4]), geti($data[5]), geti($data[6]), geti($data[7]), geti($data[8]), geti($data[9]), $host, $bbs)); require_once P2_LIB_DIR . '/getSetPosLines.func.php'; $rec_lines = getSetPosLines($newlines, $newdata, $before_line_num, $set); } else { $rec_lines = $newlines; } if (false === FileCtl::filePutRename($_conf['palace_file'], $rec_lines ? implode("\n", $rec_lines) . "\n" : '')) { trigger_error(sprintf('p2 error: %s(), FileCtl::filePutRename() failed.', __FUNCTION__), E_USER_WARNING); return false; } return true; }
/** * コンストラクタ * * @param string $name ロック名(≒排他処理したいファイル名) * @param bool $remove ロックファイルを自動で削除するかどうか * @param string $suffix ロックファイル名の接尾辞 */ public function __construct($name, $remove = true, $suffix = '.lck') { $this->_filename = p2_realpath($name . $suffix); $this->_remove = $remove; FileCtl::mkdirFor($this->_filename); $this->_fh = fopen($this->_filename, 'wb'); if (!$this->_fh) { p2die("cannot create lockfile ({$this->_filename})."); } if (!flock($this->_fh, LOCK_EX)) { p2die("cannot get lock ({$this->_filename})."); } }
public function save($data) { global $_conf; $path = $_conf['pref_dir'] . '/' . $this->filename; $newdata = ''; foreach ($data as $na_info) { $a[0] = strtr(trim($na_info['match'], "\t\r\n"), "\t\r\n", " "); $a[1] = strtr(trim($na_info['replace'], "\t\r\n"), "\t\r\n", " "); if ($na_info['del'] || ($a[0] === '' || $a[1] === '')) { continue; } $newdata .= implode("\t", $a) . "\n"; } return FileCtl::file_write_contents($path, $newdata); }
/** * データを保存するP2KeyValueStoreオブジェクトを取得する * * @param string $databasePath * @param string $codec * @param string $tableName * @return P2KeyValueStore */ protected static function _getKVS($databasePath, $codec = P2KeyValueStore::CODEC_SERIALIZING, $tableName = null) { global $_conf; $id = $codec . ':' . $databasePath; if (array_key_exists($id, self::$_kvs)) { return self::$_kvs[$id]; } if (!file_exists($databasePath) && !is_dir(dirname($databasePath))) { FileCtl::mkdirFor($databasePath); } try { $kvs = P2KeyValueStore::getStore($databasePath, $codec, $tableName); self::$_kvs[$id] = $kvs; } catch (Exception $e) { p2die(get_class($e) . ': ' . $e->getMessage()); } return $kvs; }
/** * 登録されている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 changeSkin($skin) { global $_conf; if (!preg_match('/^\\w+$/', $skin)) { return "p2 error: 不正なスキン ({$skin}) が指定されました。"; } if ($skin == 'conf_style') { $newskin = './conf/conf_user_style.php'; } else { $newskin = './skin/' . $skin . '.php'; } if (file_exists($newskin)) { if (FileCtl::file_write_contents($_conf['expack.skin.setting_path'], $skin) !== FALSE) { return $skin; } else { return "p2 error: {$_conf['expack.skin.setting_path']} にスキン設定を書き込めませんでした。"; } } else { return "p2 error: 不正なスキン ({$skin}) が指定されました。"; } }
/** * ファイル内容を読み込んで表示する関数 */ function viewTxtFile($file, $encode) { if ($file == '') { p2die('file が指定されていません'); } $filename = basename($file); $ptitle = $filename; //ファイル内容読み込み $cont = FileCtl::file_read_contents($file); if ($cont === false) { $cont_area = ''; } else { if ($encode == 'EUC-JP') { $cont = mb_convert_encoding($cont, 'CP932', 'CP51932'); } elseif ($encode == 'UTF-8') { $cont = mb_convert_encoding($cont, 'CP932', 'UTF-8'); } $cont_area = htmlspecialchars($cont, ENT_QUOTES); } // プリント echo <<<EOHEADER <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta name="ROBOTS" content="NOINDEX, NOFOLLOW"> {$_conf['extra_headers_ht']} <title>{$ptitle}</title> <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> </head> <body onload="top.document.title=self.document.title;"> EOHEADER; P2Util::printInfoHtml(); echo "<pre>"; echo $cont_area; echo "</pre>"; echo '</body></html>'; return TRUE; }
/** * ファイル内容を読み込んで表示する関数 */ function viewTxtFile($file, $encode) { if (!$file) { p2die('file が指定されていません'); } $filename = basename($file); $ptitle = $filename; //ファイル内容読み込み $cont = FileCtl::file_read_contents(P2_BASE_DIR . DIRECTORY_SEPARATOR . $file); if ($cont === false) { $cont_area = ''; } else { if (strcasecmp($encode, 'EUC-JP') === 0) { $cont = mb_convert_encoding($cont, 'CP932', 'CP51932'); } elseif (strcasecmp($encode, 'UTF-8') === 0) { $cont = mb_convert_encoding($cont, 'CP932', 'UTF-8'); } $cont_area = p2h($cont); } // プリント echo <<<EOHEADER <!DOCTYPE html> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta name="ROBOTS" content="NOINDEX, NOFOLLOW"> {$_conf['extra_headers_ht']} <title>{$ptitle}</title> <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"> </head> <body onload="top.document.title=self.document.title;"> EOHEADER; P2Util::printInfoHtml(); echo "<pre>"; echo $cont_area; echo "</pre>"; echo '</body></html>'; return true; }
/** * チェックした書き込み記事を削除する */ 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.'); } } }
/** * 新着まとめ読みのキャッシュを残す * * @access public * register_shutdown_function() から呼ばれる。(相対パスのファイルは扱えない?) */ function saveMatomeCache() { global $_conf; if (!empty($GLOBALS['_is_matome_shinchaku_naipo'])) { return true; } // ローテーション $max = $_conf['matome_cache_max']; $i = $max; while ($i >= 0) { $di = $i == 0 ? '' : '.' . $i; $tfile = $_conf['matome_cache_path'] . $di . $_conf['matome_cache_ext']; $next = $i + 1; $nfile = $_conf['matome_cache_path'] . '.' . $next . $_conf['matome_cache_ext']; if (file_exists($tfile)) { if ($i == $max) { unlink($tfile); } else { if (strstr(PHP_OS, 'WIN') and file_exists($nfile)) { unlink($nfile); } rename($tfile, $nfile); } } $i--; } // 新規記録 $file = $_conf['matome_cache_path'] . $_conf['matome_cache_ext']; //echo "<!-- {$file} -->"; FileCtl::make_datafile($file, $_conf['p2_perm']); if (false === file_put_contents($file, $GLOBALS['_read_new_html'], LOCK_EX)) { trigger_error(sprintf('file_put_contents(%s)', $file), E_USER_WARNING); die('Error: cannot write file.'); return false; } return true; }
/** * みみずん対応板を読み込む */ public function load($type) { global $_conf; // 対応板の取得 switch ($type) { case 0: $url = 'http://mimizun.com/search/2chlive.html'; $path = $_conf['cache_dir'] . '/search.mimizun.com/2chlive.html'; $match = '{<input type="checkbox" name="idxname" value="_(.+?)">}'; break; case 1: $url = 'http://mimizun.com/search/2ch.html'; $path = $_conf['cache_dir'] . '/search.mimizun.com/2ch.html'; $match = '{<input type="checkbox" name="idxname" value="(.+?)">}'; break; } // キャッシュ用ディレクトリが無ければ作成 FileCtl::mkdir_for($path); // メニューのキャッシュ時間の10倍キャッシュ P2UtilWiki::cacheDownload($url, $path, $_conf['menu_dl_interval'] * 36000); $file = @file_get_contents($path); preg_match_all($match, $file, $boards); return $boards[1]; }
$redirect = isset($_REQUEST['r']) ? intval($_REQUEST['r']) : 1; // 表示方法 $rank = isset($_REQUEST['rank']) ? intval($_REQUEST['rank']) : 0; // レーティング $memo = isset($_REQUEST['memo']) && strlen($_REQUEST['memo']) > 0 ? $_REQUEST['memo'] : null; // メモ $referer = isset($_REQUEST['ref']) && strlen($_REQUEST['ref']) > 0 ? $_REQUEST['ref'] : null; // リファラ /*if (!isset($uri) && false !== ($url = getenv('PATH_INFO'))) { $uri = 'http:/' . $url; }*/ if (empty($id) && empty($uri) && empty($file)) { ic2_error('x06', 'URLまたはファイル名がありません。', false); } if (!is_dir($_conf['tmp_dir'])) { FileCtl::mkdirRecursive($_conf['tmp_dir']); } if (!empty($uri)) { $uri = preg_replace('{^(https?://)ime\\.(?:nu|st)/}', '\\1', $uri); $pURL = @parse_url($uri); if (!$pURL || $pURL['scheme'] != 'http' && $pURL['scheme'] != 'https' || empty($pURL['host']) || empty($pURL['path'])) { ic2_error('x06', '不正なURLです。', false); } // 強制あぼーんホストのとき if ($ini['Getter']['reject_hosts']) { $pattern = preg_quote($ini['Getter']['reject_hosts'], '/'); $pattern = str_replace(',', '|', $pattern); $pattern = '/(' . $pattern . ')$/i'; if (preg_match($pattern, $pURL['host'])) { ic2_error('x01', 'あぼーん対象ホストです。'); }
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; }
public function save($data) { global $_conf; if ($data) { $new_data = true; $this->data = $data; } elseif (!$this->isLoaded) { return; } else { $new_data = false; } // HITした時のみ更新する if ($this->hits > 0 || $new_data) { $cont = ''; foreach ($this->data as $v) { if ($v['del']) { continue; } // 必要ならここで古いデータはスキップ(削除)する if (!empty($v['lasttime']) && $_conf['ngaborn_daylimit']) { if (strtotime($v['lasttime']) < time() - 60 * 60 * 24 * $_conf['ngaborn_daylimit']) { continue; } } $a['word'] = strtr(trim($v['word'], "\t\r\n"), "\t\r\n", " "); $a['ignorecase'] = $v['ignorecase']; $a['regex'] = $v['regex']; $a['bbs'] = strtr(trim($v['bbs'], "\t\r\n"), "\t\r\n", " "); $a['lasttime'] = $v['lasttime']; $a['hits'] = $v['hits']; // lasttimeが設定されていなかったら現在時間を設定(本来なら登録時にするべき) if (empty($v['lasttime'])) { $v['lasttime'] = date(self::DATE_FORMAT); } $cont .= implode("\t", $v) . "\n"; } return FileCtl::file_write_contents($_conf['pref_dir'] . '/' . $this->filename); } }
/** * $subject_keys をシリアライズして保存する */ function saveSubjectKeys($subject_keys, $sb_keys_txt, $sb_keys_b_txt) { global $_conf; //$GLOBALS['debug'] && $GLOBALS['profiler']->enterSection('saveSubjectKeys()'); //if (file_exists($sb_keys_b_txt)) { unlink($sb_keys_b_txt); } if (empty($_REQUEST['norefresh']) && !empty($subject_keys)) { if (file_exists($sb_keys_txt)) { FileCtl::make_datafile($sb_keys_b_txt); copy($sb_keys_txt, $sb_keys_b_txt); } else { FileCtl::make_datafile($sb_keys_txt); } if ($sb_keys_cont = serialize($subject_keys)) { if (FileCtl::file_write_contents($sb_keys_txt, $sb_keys_cont) === false) { p2die('cannot write file.'); } } } //$GLOBALS['debug'] && $GLOBALS['profiler']->leaveSection('saveSubjectKeys()'); return true; }
/** * P2Clientクラスのインスタンスを生成する * * @param void * @return P2Client */ public static function getP2Client() { global $_conf; if (!is_dir($_conf['db_dir'])) { FileCtl::mkdirRecursive($_conf['db_dir']); } try { return new P2Client("http://{$_conf['p2_2ch_host']}/p2/", $_conf['p2_2ch_mail'], $_conf['p2_2ch_pass'], $_conf['db_dir'], (bool) $_conf['p2_2ch_ignore_cip']); } catch (P2Exception $e) { p2die($e->getMessage()); } }
} 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];
$new_login_pass = $_POST['form_new_login_pass']; // 入力チェック if (!preg_match('/^[0-9A-Za-z_]+$/', $new_login_pass)) { P2Util::pushInfoHtml("<p>rep2 error: {$p_str['password']}を半角英数字で入力して下さい。</p>"); } elseif ($new_login_pass != $_POST['form_new_login_pass2']) { P2Util::pushInfoHtml("<p>rep2 error: {$p_str['password']} と {$p_str['password']} (確認) が一致しませんでした。</p>"); // パスワード変更登録処理を行う } else { $crypted_login_pass = sha1($new_login_pass); $auth_user_cont = <<<EOP <?php \$rec_login_user_u = '{$_login->user_u}'; \$rec_login_pass_x = '{$crypted_login_pass}'; ?> EOP; FileCtl::make_datafile($_conf['auth_user_file'], $_conf['pass_perm']); // ファイルがなければ生成 $fp = @fopen($_conf['auth_user_file'], 'wb'); if (!$fp) { p2die("{$_conf['auth_user_file']} を保存できませんでした。認証ユーザ登録失敗。"); } flock($fp, LOCK_EX); fputs($fp, $auth_user_cont); flock($fp, LOCK_UN); fclose($fp); P2Util::pushInfoHtml('<p>○認証パスワードを変更登録しました</p>'); } } //==================================================== // 補助認証 //====================================================
/** * 指定したキーの書き込み履歴を削除する * * @access public * @return integer|false 削除したなら1, 削除対象がなければ2。失敗はfalse */ function offResHist($host, $bbs, $key) { global $_conf; if (!file_exists($_conf['res_hist_idx'])) { return 2; } $lines = file($_conf['res_hist_idx']); if ($lines === false) { return false; } $neolines = array(); // {{{ あれば削除 if (is_array($lines)) { foreach ($lines as $l) { $l = rtrim($l); $lar = explode('<>', $l); // 削除(スキップ) if ($lar[1] == $key && $lar[10] == $host && $lar[11] == $bbs) { $done = true; continue; } $neolines[] = $l; } } // }}} // {{{ 書き込む if (is_array($neolines)) { $cont = ''; foreach ($neolines as $l) { $cont .= $l . "\n"; } if (false === FileCtl::filePutRename($_conf['res_hist_idx'], $cont)) { $errmsg = sprintf('p2 error: %s(), FileCtl::filePutRename() failed.', __FUNCTION__); trigger_error($errmsg, E_USER_WARNING); return false; } } // }}} if (!empty($done)) { return 1; } else { return 2; } }
// ルールを適用する applyRules(); // ポストされた値 > 現在の値 > デフォルト値 の順で新しい設定を作成する $conf_save = array('.' => $_conf['p2version']); foreach ($conf_user_def as $k => $v) { if (array_key_exists($k, $_POST['conf_edit'])) { $conf_save[$k] = $_POST['conf_edit'][$k]; } elseif (array_key_exists($k, $_conf)) { $conf_save[$k] = $_conf[$k]; } else { $conf_save[$k] = $v; } } // シリアライズして保存 FileCtl::make_datafile($_conf['conf_user_file']); if (FileCtl::file_write_contents($_conf['conf_user_file'], serialize($conf_save)) === false) { P2Util::pushInfoHtml('<p>×設定を更新保存できませんでした</p>'); } else { P2Util::pushInfoHtml('<p>○設定を更新保存しました</p>'); // 変更があれば、内部データも更新しておく $_conf = array_merge($_conf, $conf_user_def, $conf_save); } unset($conf_save); // }}} // {{{ デフォルトに戻すボタンが押されていたら } elseif (!empty($_POST['submit_default'])) { if (file_exists($_conf['conf_user_file']) and unlink($_conf['conf_user_file'])) { P2Util::pushInfoHtml('<p>○設定をデフォルトに戻しました</p>'); // 変更があれば、内部データも更新しておく $_conf = array_merge($_conf, $conf_user_def); if (is_array($conf_save)) {
/** * Atom 0.3 を RSS 1.0 に変換する(PHP5, DOM & XSL) */ function atom_to_rss_by_xsl($input, $stylesheet, $output) { $xmlDoc = new DomDocument(); if ($xmlDoc->load(realpath($input))) { $xslDoc = new DomDocument(); $xslDoc->load(realpath($stylesheet)); $proc = new XSLTProcessor(); $proc->importStyleSheet($xslDoc); $rssDoc = $proc->transformToDoc($xmlDoc); $rssDoc->save($output); $rss_content = FileCtl::file_read_contents($output); } else { $rss_content = null; } if (!$rss_content) { P2Util::pushInfoHtml('<p>p2 error: XSL - AtomをRSSに変換できませんでした。</p>'); return FALSE; } return $rss_content; }
/** * brdファイルを生成する * * @access public * @return string|false 成功したら生成したbrdファイルのパスを返す */ function makeBrdFile($cachefile) { global $_conf; $cont = ''; $data = file($cachefile); $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) { // 2008/07/14 なぜここでこんな条件が必要だったのか不明。コメントアウトしてみる。 //if (strlen($GLOBALS['word']) > 0) { P2Util::pushInfoHtml(sprintf("<p>p2 error: %s から板メニューを生成することはできませんでした。</p>\n", hs($cachefile))); //} unlink($cachefile); return false; } $p2brdfile = BrdCtl::getP2BrdFile($cachefile); if (false === FileCtl::make_datafile($p2brdfile, $_conf['p2_perm'])) { return false; } if (false === FileCtl::filePutRename($p2brdfile, $cont)) { die(sprintf('p2 error: %s を更新できませんでした', hs($p2brdfile))); return false; } return $p2brdfile; }