<?php
$time_start 
microtime(true);
// error_reporting(-1);
date_default_timezone_set('Asia/Tokyo');
mb_language('Japanese');
mb_internal_encoding('UTF-8');

// たぽろだ本体のURL (必須)
$tapoloda 'http://example.org/script/tapoloda.cgi';

// list.txtのパス (必須)
$listData '../updata/list.txt';

// たぼろだの名前 (任意)
$tapolodaName 'たぽろだβ';

//背景色 (任意)
$bgcolor '#f0f0f0';

// メールアドレス。 (任意)
// ページ下部などに連絡先として表示されます。
// @を_at_に変換した上でHTMLを出力するので、そのまま書いてください。
// 設定しない場合はページ下部の連絡先などが表示されません。
// $mail = 'info@example.org';
$mail '';

// <link rev="made" href="mailto:~を出力する(1)か否(0)か。 (任意)
// $mailが指定されていない場合、ここで1を指定しても出力されません。
// madeはメールアドレスの最後の'.'が'_dot_'に変換されて出力されます。
$madeLink 1;

// カテゴリのリスト (任意)
// 通常は変更の必要がありませんが、tapolib.plの%DAI_CATEGORYを
// 変更している場合は修正が必要です。
$cat_str = array( '10' => '画像''20' => '動画''30' => '音',
                  
'40' => '文章''50' => 'プログラム''90' => 'その他',
                  
'15' => '(18禁)画像''25' => '(18禁)動画''35' => '(18禁)音',
                  
'45' => '(18禁)文章''55' => '(18禁)プログラム''95' => '(18禁)その他');

// -------- 設定はここまで --------

/*
 * Copyright (c) 2010, hitobashira.org
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this 
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the hitobashira.org nor the names of its contributors may 
 *    be used to endorse or promote products derived from this software without 
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
 */



// 特に理由がなければ以下は弄らないでください。
// 後から色々追加したりしたせいで、かなり汚い(酷い)コードになってます。

// 検索文字列とページタイトル関連の処理
if (!empty($_GET['q'])) {
    
$enclist mb_list_encodings();
    if (empty(
$_GET['ie'])) $_GET['ie'] = null;
    if (
array_search($enclist$_GET['ie']) !== false) {
        
$s_query mb_convert_encoding(htmlspecialchars($_GET['q']), 'UTF-8'$_GET['ie']);
    } else {
        
$s_query mb_convert_encoding(htmlspecialchars($_GET['q']), 'UTF-8''auto');
    }
} else { 
$s_query null; }
$s_price = empty($_GET['p']) ? null htmlspecialchars($_GET['p']);  // moritapo
$s_cat   = empty($_GET['c']) ? null htmlspecialchars($_GET['c']);  // category

if (!empty($s_query)) {
    
// 検索文字が入力されている場合
    
$pageTitle "{$s_query}の検索結果";
    
$s_query explode(' '$s_query);    // search str (array)
    // 価格に9森以下が指定されている場合は無指定と見なす
    
if ($s_price <= 9$s_price 999999999;
    
// 存在しないカテゴリが指定された場合は無指定と見なす
    
if (isset($cat_str["$s_cat"]) === false$s_cat false;
} elseif (
$s_price >= 10) {
    
// 10モリタポ以上が入力されていて、検索文字列が入力されていない場合
    
$pageTitle "{$s_price}森以下の商品一覧";
    
$s_query null;
    if (isset(
$cat_str["$s_cat"]) === false)  $s_cat false;
} elseif (isset(
$cat_str["$s_cat"]) !== false) {
    
// カテゴリが選択されていて、モリタポも検索文字列も入力されていない場合
    
$s_query null;
    
$s_price 999999999;
    
$pageTitle "{$cat_str["$s_cat"]}カテゴリの商品一覧";
} else {
    
// 検索条件が指定されていない場合
    
$pageTitle "全商品一覧";
    
$s_query null;
    
$s_cat   false;
    
$s_price 999999999;
}

// カテゴリリストから検索フォーム用のhtmlを生成
$cat_form null;
foreach (
$cat_str as $key => $value) {
    
$cat_form .= "            <option value=\"{$key}\">{$value}</option>\n";
}

// 連絡先
// めんどくさいので、メールアドレスが正しいかどうかは'@'と'.'が含まれているかで判断しています。
// どうせ変なアドレス書いて連絡とれなくて困るのはこれの設置者本人だし。
if (strpos($mail'@') === false$mail null;
if (
strpos($mail'.') === false$mail null

if (empty(
$mail)) {
    
$made null;
    
$contact null;
} else {
    
// madeのアドレスは@が含まれていないとw3cのvaldatorで怒られるので、
    // @はそのままにして、アドレスの最後にある.を_dot_に変換しています。
    
$m_made    substr_replace($mail'_dot_'strrpos($mail'.'), 1);
    
$made      "\n    <link rev=\"made\" href=\"mailto:{$m_made}\" />";
    
$m_contact str_replace('@''_at_'$mail);
    
$contact   "\n何かあった場合、<a href=\"mailto:{$m_contact}?body=_at_は@に変換してください。\">{$m_contact}</a>に連絡してください。<br />";
}

// ページ上部 (HTMLヘッダ-検索フォーム-一覧のヘッダ)
echo <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
    <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
    <title>
{$pageTitle} - {$tapolodaName}</title>
    <meta http-equiv="content-style-type" content="text/css" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
{$made}
</head>
<body style="background: 
{$bgcolor};">
<div>
<h1>
{$tapolodaName}</h1>
<div style="font-size: small;">
    検索条件が入力されていない場合、現在購入可能な全商品を表示します。処理に若干の時間がかかるかもしれません。<br />
    検索文字列は半角スペースで区切って複数入力が可能です(この場合、AND検索になります)。<br />
    検索文字列の前に-が指定された場合、その文字列が含まれない商品を検索できます。<br />
    価格は10以上100000000以下の数値を指定する必要があります。それ以外が指定された場合は無指定となります。<br />
    検索対象は商品のタイトル、説明、ファイル名です。大文字小文字などは区別しません。<br />
    <span style="color:red;">実験中のため、不具合が発生する可能性があります。</span><br />
    なお、通常の一覧と違い、昇順になっています(下に行く程新しい/又は売れてる)。<br />
</div>
<form method="get" action="
{$_SERVER['SCRIPT_NAME']}">
    <div>
        <input type="text" name="q" id="q" size="25" tabindex="0" value="" />を含む、価格が
        <input type="text" name="p" id="p" size="5" maxlength="9" tabindex="1" value="" />森以下の商品を
        <select name="c" tabindex="2">
             <option value="0" selected="selected">全</option>
{$cat_form}         </select>
         カテゴリから<input type="submit" value="検索" tabindex="3" />
     </div>
 </form>
 
<table border="1" summary="検索結果。商品の一覧">
    <tr>
        <th>No.</th>
        <th>タイトル</th>
        <th>投稿者</th>
        <th>価格</th>
        <th>カテゴリ</th>
        <th>期限</th>
    </tr>
EOF;

$count  0;

// メインの処理
$handle = @fopen($listData"r");
if (
$handle) {
    
// list.txtの取得が問題なかった場合
    
while (!feof($handle)) {
        
$buffer fgets($handle);
        
$buffer mb_convert_encoding($buffer'UTF-8''SJIS');
        if (empty(
$buffer)) continue;
        
$itemData explode("\t"$buffer);
        
        
// 1文字目が#なのは購入不可なので飛ばす
        
if (substr($itemData[0], 01) == '#') continue;


        
// 分かり易いように$item_にデータを代入
        
$item_id    $itemData[1];
        
$item_term  $itemData[2];
        
$item_file  $itemData[3];
        
$item_title $itemData[6];
        
$item_price $itemData[7];
        
$item_owner $itemData[8];
        
$item_cat   $itemData[9];
        
$item_desc  str_replace('<br>'''$itemData[13]);

        
// 販売期限がすぎている物は飛ばす
        
if ($item_term <= date('Ymd.His')) {
            continue;
        }

        
// search
        
if (isset($s_query)) {
            
$s_query_cnt count($s_query);
            
$hit 0;
            foreach (
$s_query as $s_str) {
                if (
substr($s_str01) == '-') {
                    
// 検索文字列の1文字目が-の場合
                    
if (mb_stripos($item_titlesubstr($s_str1)) !== false) {
                        continue;
                    } elseif (
mb_stripos($item_descsubstr($s_str1)) !== false) {
                        continue;
                    } elseif (
mb_stripos($item_filesubstr($s_str1)) !== false) {
                        continue;
                    } else {
                        ++
$hit;
                    }
                } else {
                    
// 通常の検索
                    
if (mb_stripos($item_title$s_str) !== false) {
                        ++
$hit;
                    } elseif (
mb_stripos($item_desc$s_str) !== false) {
                        ++
$hit;
                    } elseif (
mb_stripos($item_file$s_str) !== false) {
                        ++
$hit;
                    }
                }
            }
            unset(
$s_str);

            
// 指定された文字列とhitした文字列の数が違う場合は飛ばす
            
if ($hit $s_query_cnt) {
                continue;
            }
        }

        
// 指定された価格より高い場合は飛ばす
        
if ($s_price $item_price) {
            continue;
        }
        
        
// 指定されたカテゴリでない場合は飛ばす
        
if ($s_cat) {
            if (
$item_cat != $s_cat) {
                continue;
            }
        }
        
        
        
// 日時を分かり易い形式に変換
        
$term_str sprintf('%s年%s月%s日 %s時%s分%s秒'substr($item_term04),
        
substr($item_term42),
        
substr($item_term62),
        
substr($item_term92),
        
substr($item_term112),
        
substr($item_term132));


        
// 検索に一致する商品を表示
        
echo <<<EOF

    <tr>
        <td>
{$count}</td>
        <td><a href="
{$tapoloda}?mode=cfi&amp;id={$item_id}">{$item_title}</a></td>
        <td>
{$item_owner}</td>
        <td>
{$item_price}森</td>
        <td>
{$cat_str["$item_cat"]}</td>
        <td>
{$term_str}</td>
    </tr>
EOF;
        ++
$count;
    }
    
fclose($handle);
} else {
    echo <<<EOF

<tr>
    <th colspan="6" style="align: center">
        データの取得に失敗しました。
    </th>
</tr>
EOF;
}

if (
$count == 0) {
    echo <<<EOF

<tr>
    <th colspan="6" style="align: center">
        一致する商品がありませんでした。
    </th>
</tr>
EOF;
}

$time_end microtime(true);
$run round($time_end $time_start4);

// ページ下部 (一覧フッタ-HTMLフッタ)
echo <<<EOF

</table>
<p>計
{$count}件見つかりました。&nbsp;({$run}秒)</p>
<p><a href="
{$tapoloda}">TOPに戻る</a></p>

<div style="font-size: x-small;text-align: right">
{$contact}
<!-- 別にどうでも良い表示だから消してもいいけどね。。。 -->
<a href="http://tapoloda.hitobashira.org/">tapoloda item search v0.5.1 by hitobashira.org</a>
</div>

</div>
</body>
</html>
EOF;