source: branches/version-2_4-dev/data/class/pages/LC_Page_Sitemap.php @ 18573

Revision 18573, 10.9 KB checked in by shutta, 14 years ago (diff)

コミュニティ版の r18397 をマージ。

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id Revision Date
  • Property svn:mime-type set to text/x-httpd-php
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2007 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24// {{{ requires
25require_once(CLASS_PATH . "pages/LC_Page.php");
26
27/**
28 * Sitemapプロトコル ファイル生成モジュール.
29 * PHP versions 4 and 5
30 *
31 * <pre>
32 * このモジュールは Sitemapプロトコルに対応した XMLファイルを出力する.
33 * EC-CUBE インストールディレクトリの htmlディレクトリへ配置することにより動作する.
34 *
35 * このモジュールにより, 以下のページのサイトマップが生成される.
36 * 1. $staticURL で指定したページ
37 * 2. 管理画面のデザイン管理から生成したページ
38 * 3. 公開されているすべての商品一覧ページ
39 * 4. 公開されているすべての商品詳細ページ
40 * 5. html/mobile 以下の上記ページ
41 *
42 * このモジュールを設置後, 各検索エンジンにサイトマップを登録することにより, 検索エンジンの
43 * インデックス化が促進される.
44 * </pre>
45 * @see https://www.google.com/webmasters/tools/siteoverview?hl=ja
46 * @see https://siteexplorer.search.yahoo.com/mysites
47 *
48 * @author Kentaro Ohkouchi
49 * @version $Id:sitemap.php 15532 2007-08-31 14:39:46Z nanasess
50 *
51 * :TODO: 各ページの changefreq や priority を指定できるようにする
52 * :TODO: filemtime 関数を使えば、静的なページの更新時間も取得できそう
53 */
54class LC_Page_Sitemap extends LC_Page {
55
56    // }}}
57    // {{{ properties
58
59    /** 動的に生成しないページの配列 */
60    var $staticURL;
61
62
63    /** ページデータ */
64    var $arrPageData;
65
66    /** ページリスト */
67    var $arrPageList;
68
69
70    // }}}
71    // {{{ functions
72
73    /**
74     * Page を初期化する.
75     *
76     * @return void
77     */
78    function init() {
79        parent::init();
80        $this->staticURL = array(SITE_URL, MOBILE_SITE_URL, SITE_URL . "rss/index.php");
81    }
82
83    /**
84     * Page のプロセス.
85     *
86     * @return void
87     */
88    function process() {
89        // ページのデータを取得
90        $this->arrPageList = $this->getPageData();
91
92        $objQuery = new SC_Query();
93
94        //キャッシュしない(念のため)
95        header("Paragrama: no-cache");
96
97        //XMLテキスト
98        header("Content-type: application/xml; charset=utf-8");
99
100        // 必ず UTF-8 として出力
101        mb_http_output("UTF-8");
102        ob_start('mb_output_handler');
103
104        print("<?xml version='1.0' encoding='UTF-8'?>\n");
105        print("<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n");
106
107        // 静的なページを処理
108        foreach($this->staticURL as $url) {
109            $this->createSitemap($url, '', 'daily', 1.0);
110        }
111
112        // TOPページを処理
113        $topPage = $this->getTopPage($this->arrPageList);
114        $this->createSitemap($topPage[0]['url'],
115                             $this->date2W3CDatetime($topPage[0]['update_date']),
116                             'daily', 1.0);
117
118        // 編集可能ページを処理
119        $editablePages = $this->getEditablePage($this->arrPageList);
120        foreach($editablePages as $editablePage) {
121            $this->createSitemap($editablePage['url'],
122                                 $this->date2W3CDatetime($editablePage['update_date']));
123        }
124
125        // 商品一覧ページを処理
126        $products = $this->getAllProducts();
127        foreach($products as $product) {
128            $this->createSitemap($product['url'], '', 'daily');
129        }
130        $mobileProducts = $this->getAllProducts(true);
131        foreach($mobileProducts as $mobileProduct) {
132            $this->createSitemap($mobileProduct['url'], '', 'daily');
133        }
134
135        // 商品詳細ページを処理
136        $details = $this->getAllDetail();
137        foreach($details as $detail) {
138            $this->createSitemap($detail['url'],
139                                 $this->date2W3CDatetime($detail['update_date']));
140        }
141        $mobileDetails = $this->getAllDetail(true);
142        foreach($mobileDetails as $mobileDetail) {
143            $this->createSitemap($mobileDetail['url'],
144                                 $this->date2W3CDatetime($mobileDetail['update_date']));
145        }
146
147        print("</urlset>\n");
148    }
149
150    /**
151     * デストラクタ.
152     *
153     * @return void
154     */
155    function destroy() {
156        parent::destroy();
157    }
158
159    /**
160     * Sitemap の <url /> を生成する.
161     *
162     * @param string $loc ページの URL ※必須
163     * @param string $lastmod ファイルの最終更新日 YYYY-MM-DD or W3C Datetime 形式
164     * @param string $changefreq ページの更新頻度
165     * @param double $priority URL の優先度
166     * @return Sitemap 形式の <url />
167     * @see https://www.google.com/webmasters/tools/docs/ja/protocol.html#xmlTagDefinitions
168     * TODO Smarty に移行すべき?
169     */
170    function createSitemap($loc, $lastmod = "", $changefreq = "",
171                           $priority = "") {
172        printf("\t<url>\n");
173        printf("\t\t<loc>%s</loc>\n", htmlentities($loc, ENT_QUOTES, "UTF-8"));
174        if (!empty($lastmod)) {
175            printf("\t\t<lastmod>%s</lastmod>\n", $lastmod);
176        }
177        if (!empty($changefreq)) {
178            printf("\t\t<changefreq>%s</changefreq>\n", $changefreq);
179        }
180        if(!empty($priority)) {
181            printf("\t\t<priority>%01.1f</priority>\n", $priority);
182        }
183        printf("\t</url>\n");
184    }
185
186    /**
187     * TOPページの情報を取得する.
188     *
189     * @param array $pageData すべてのページ情報の配列
190     * @return array TOPページの情報
191     */
192    function getTopPage($pageData) {
193        $arrRet = array();
194        foreach($pageData as $page) {
195            if ($page['page_id'] == "1") {
196                $page['url'] = SITE_URL . $page['url'];
197                $arrRet[0] = $page;
198                return $arrRet;
199            }
200        }
201    }
202
203    /**
204     * すべての編集可能ページの情報を取得する.
205     *
206     * @param array $pageData すべてのページ情報の配列
207     * @return array 編集可能ページ
208     */
209    function getEditablePage($pageData) {
210        $arrRet = array();
211        $i = 0;
212        foreach($pageData as $page) {
213            if ($page['page_id'] > 4) {
214                $arrRet[$i] = $page;
215                $i++;
216            }
217        }
218        return $arrRet;
219    }
220
221    /**
222     * すべての商品一覧ページを取得する.
223     *
224     * @param boolean $isMobile モバイルページを取得する場合 true
225     * @return array 検索エンジンからアクセス可能な商品一覧ページの情報
226     */
227    function getAllProducts($isMobile = false) {
228        $conn = new SC_DBConn();
229        $sql = "SELECT category_id FROM dtb_category WHERE del_flg = 0";
230        $result = $conn->getAll($sql);
231
232        $mobile = "";
233        if ($isMobile) {
234            $mobile = "mobile/";
235        }
236
237        $arrRet = array();
238        for ($i = 0; $i < count($result); $i++) {
239            // :TODO: カテゴリの最終更新日を取得できるようにする
240            $page = array("url" => SITE_URL . sprintf("%sproducts/list.php?category_id=%d", $mobile, $result[$i]['category_id']));
241            $arrRet[$i] = $page;
242        }
243        return $arrRet;
244    }
245
246    /**
247     * すべての商品詳細ページを取得する.
248     *
249     * @param boolean $isMobile モバイルページを取得する場合 true
250     * @return array 検索エンジンからアクセス可能な商品詳細ページの情報
251     */
252    function getAllDetail($isMobile = false) {
253        $conn = new SC_DBConn();
254        $sql = "SELECT product_id, update_date FROM dtb_products WHERE del_flg = 0 AND status = 1";
255        $result = $conn->getAll($sql);
256
257        if ($isMobile) {
258            $detail_p_html = MOBILE_DETAIL_P_HTML;
259        } else {
260            $detail_p_html = DETAIL_P_HTML;
261        }
262
263        $arrRet = array();
264        foreach ($result as $row) {
265            $page["update_date"] = $row['update_date'];
266            $page["url"] = SITE_URL . substr($detail_p_html, strlen(URL_DIR)) . $row['product_id'];
267
268            $arrRet[] = $page;
269        }
270        return $arrRet;
271    }
272
273
274    /**
275     * ブロック情報を取得する.
276     *
277     * @param string $where WHERE句
278     * @param array  $arrVal WHERE句の値を格納した配列
279     * @return ブロック情報
280     */
281    function getPageData($where = '', $arrVal = ''){
282        $objDBConn = new SC_DbConn;     // DB操作オブジェクト
283        $sql = "";                      // データ取得SQL生成用
284        $arrRet = array();              // データ取得用
285
286        // SQL生成(url と update_date 以外は不要?)
287        $sql .= " SELECT";
288        $sql .= " page_id";             // ページID
289        $sql .= " ,page_name";          // 名称
290        $sql .= " ,url";                // URL
291        $sql .= " ,php_dir";            // php保存先ディレクトリ
292        $sql .= " ,tpl_dir";            // tpl保存先ディdレクトリ
293        $sql .= " ,filename";           // ファイル名称
294        $sql .= " ,header_chk ";        // ヘッダー使用FLG
295        $sql .= " ,footer_chk ";        // フッター使用FLG
296        $sql .= " ,author";             // authorタグ
297        $sql .= " ,description";        // descriptionタグ
298        $sql .= " ,keyword";            // keywordタグ
299        $sql .= " ,update_url";         // 更新URL
300        $sql .= " ,create_date";        // データ作成日
301        $sql .= " ,update_date";        // データ更新日
302        $sql .= " FROM ";
303        $sql .= "     dtb_pagelayout";
304
305        // where句の指定があれば追加
306        if ($where != '') {
307            $sql .= " WHERE " . $where;
308        }
309
310        $sql .= " ORDER BY  page_id";
311
312        return $objDBConn->getAll($sql, $arrVal);
313    }
314
315    /**
316     * date形式の文字列を W3C Datetime 形式に変換して出力する.
317     *
318     * @param date $date 変換する日付
319     * @return void
320     */
321    function date2W3CDatetime($date) {
322        $arr = array();
323        // 正規表現で文字列を抽出
324        ereg("^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})",
325             $date, $arr);
326        // :TODO: time zone も取得するべき...
327        return sprintf("%04d-%02d-%02dT%02d:%02d:%02d+09:00",
328                       $arr[1], $arr[2], $arr[3], $arr[4], $arr[5], $arr[6]);
329    }
330
331}
332
333?>
Note: See TracBrowser for help on using the repository browser.