source: branches/version-2_5-dev/data/class/pages/LC_Page_Sitemap.php @ 20764

Revision 20764, 11.4 KB checked in by nanasess, 13 years ago (diff)

#601 (コピーライトの更新)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2011 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_EX_REALDIR . 'page_extends/LC_Page_Ex.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_Ex {
55
56    // }}}
57    // {{{ properties
58
59    /** 動的に生成しないページの配列 */
60    var $staticURL;
61
62    /** ページリスト */
63    var $arrPageList;
64
65    // }}}
66    // {{{ functions
67
68    /**
69     * Page を初期化する.
70     *
71     * @return void
72     */
73    function init() {
74        parent::init();
75
76        $this->staticURL = array();
77
78        $this->staticURL[] = HTTP_URL . 'rss/' . DIR_INDEX_PATH;
79        if (USE_MOBILE !== false) {
80            $this->staticURL[] = HTTP_URL;
81        }
82    }
83
84    /**
85     * Page のプロセス.
86     *
87     * @return void
88     */
89    function process() {
90        // ページのデータを取得
91        $this->arrPageList = $this->getPageData();
92
93        $objQuery = SC_Query_Ex::getSingletonInstance();
94
95        //キャッシュしない(念のため)
96        header("Paragrama: no-cache");
97
98        //XMLテキスト
99        header("Content-type: application/xml; charset=utf-8");
100
101        // 必ず UTF-8 として出力
102        mb_http_output("UTF-8");
103        ob_start('mb_output_handler');
104
105        echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
106        echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
107
108        // TOPページを処理
109        $arrTopPagesList = $this->getTopPage($this->arrPageList);
110        $this->createSitemap($arrTopPagesList[0]['url'],
111                             $this->date2W3CDatetime($arrTopPagesList[0]['update_date']),
112                             'daily', 1.0);
113
114        // 静的なページを処理
115        foreach ($this->staticURL as $url) {
116            $this->createSitemap($url, '', 'daily', 1.0);
117        }
118
119        // 編集可能ページを処理
120        $arrEditablePagesList = $this->getEditablePage($this->arrPageList);
121        foreach ($arrEditablePagesList as $arrEditablePage) {
122            $this->createSitemap($arrEditablePage['url'],
123                                 $this->date2W3CDatetime($arrEditablePage['update_date']));
124        }
125
126        // 商品一覧ページを処理
127        $arrProductPagesList = $this->getAllProducts();
128        foreach ($arrProductPagesList as $arrProductPage) {
129            $this->createSitemap($arrProductPage['url'], '', 'daily');
130        }
131
132        // 商品詳細ページを処理
133        $arrDetailPagesList = $this->getAllDetail();
134        foreach ($arrDetailPagesList as $arrDetailPage) {
135            $this->createSitemap($arrDetailPage['url'],
136                                 $this->date2W3CDatetime($arrDetailPage['update_date']));
137        }
138
139        echo '</urlset>' . "\n";
140    }
141
142    /**
143     * デストラクタ.
144     *
145     * @return void
146     */
147    function destroy() {
148        parent::destroy();
149    }
150
151    /**
152     * Sitemap の <url /> を生成する.
153     *
154     * @param string $loc ページの URL ※必須
155     * @param string $lastmod ファイルの最終更新日 YYYY-MM-DD or W3C Datetime 形式
156     * @param string $changefreq ページの更新頻度
157     * @param double $priority URL の優先度
158     * @return Sitemap 形式の <url />
159     * @see https://www.google.com/webmasters/tools/docs/ja/protocol.html#xmlTagDefinitions
160     * TODO Smarty に移行すべき?
161     */
162    function createSitemap($loc, $lastmod = "", $changefreq = "",
163                           $priority = "") {
164        printf("\t<url>\n");
165        printf("\t\t<loc>%s</loc>\n", htmlentities($loc, ENT_QUOTES, "UTF-8"));
166        if (!empty($lastmod)) {
167            printf("\t\t<lastmod>%s</lastmod>\n", $lastmod);
168        }
169        if (!empty($changefreq)) {
170            printf("\t\t<changefreq>%s</changefreq>\n", $changefreq);
171        }
172        if(!empty($priority)) {
173            printf("\t\t<priority>%01.1f</priority>\n", $priority);
174        }
175        printf("\t</url>\n");
176    }
177
178    /**
179     * TOPページの情報を取得する.
180     *
181     * @param array $arrPageList すべてのページ情報の配列
182     * @return array TOPページの情報
183     */
184    function getTopPage($arrPageList) {
185        $arrRet = array();
186        foreach ($arrPageList as $arrPage) {
187            if ($arrPage['page_id'] == "1") {
188                $arrRet[0] = $arrPage;
189                return $arrRet;
190            }
191        }
192    }
193
194    /**
195     * すべての編集可能ページの情報を取得する.
196     *
197     * @param array $arrPageList すべてのページ情報の配列
198     * @return array 編集可能ページ
199     */
200    function getEditablePage($arrPageList) {
201        $arrRet = array();
202        foreach ($arrPageList as $arrPage) {
203            if ($arrPage['page_id'] > 4) {
204                $arrRet[] = $arrPage;
205            }
206        }
207        return $arrRet;
208    }
209
210    /**
211     * すべての商品一覧ページを取得する.
212     *
213     * @return array 検索エンジンからアクセス可能な商品一覧ページの情報
214     */
215    function getAllProducts() {
216
217        // XXX: 商品登録の無いカテゴリーは除外する方が良い気もする
218        $objQuery = SC_Query_Ex::getSingletonInstance();
219        $sql = "SELECT category_id FROM dtb_category WHERE del_flg = 0";
220        $result = $objQuery->getAll($sql);
221
222        $arrRet = array();
223        foreach ($result as $row) {
224            // :TODO: カテゴリの最終更新日を取得できるようにする
225
226            $arrPage['url'] = HTTP_URL . 'products/list.php?category_id=' . $row['category_id'];
227            $arrRet[] = $arrPage;
228
229            // モバイルサイト
230            if (USE_MOBILE !== false) {
231                $arrPage['url'] = HTTP_URL . 'products/list.php?category_id=' . $row['category_id'];
232                $arrRet[] = $arrPage;
233            }
234        }
235        return $arrRet;
236    }
237
238    /**
239     * すべての商品詳細ページを取得する.
240     *
241     * @return array 検索エンジンからアクセス可能な商品詳細ページの情報
242     */
243    function getAllDetail() {
244        $objQuery = SC_Query_Ex::getSingletonInstance();
245        $sql = "SELECT product_id, update_date FROM dtb_products WHERE del_flg = 0 AND status = 1";
246        $result = $objQuery->getAll($sql);
247
248        $arrRet = array();
249        foreach ($result as $row) {
250
251            $arrPage["update_date"] = $row['update_date'];
252
253            $arrPage['url'] = HTTP_URL . substr(P_DETAIL_URLPATH, strlen(ROOT_URLPATH)) . $row['product_id'];
254            $arrRet[] = $arrPage;
255
256            // モバイルサイト
257            if (USE_MOBILE !== false) {
258                $arrPage['url'] = HTTP_URL . substr(MOBILE_P_DETAIL_URLPATH, strlen(ROOT_URLPATH)) . $row['product_id'];
259                $arrRet[] = $arrPage;
260            }
261        }
262        return $arrRet;
263    }
264
265    /**
266     * ブロック情報を取得する.
267     *
268     * @param string $where WHERE句
269     * @param array  $arrVal WHERE句の値を格納した配列
270     * @return array $arrPageList ブロック情報
271     */
272    function getPageData($where = '', $arrVal = ''){
273        $objQuery = SC_Query_Ex::getSingletonInstance();     // DB操作オブジェクト
274        $sql = "";                      // データ取得SQL生成用
275        $arrRet = array();              // データ取得用
276
277        // SQL生成(url と update_date 以外は不要?)
278        $sql .= " SELECT";
279        $sql .= " page_id";             // ページID
280        $sql .= " ,page_name";          // 名称
281        $sql .= " ,url";                // URL
282        $sql .= " ,filename";           // ファイル名称
283        $sql .= " ,header_chk ";        // ヘッダー使用FLG
284        $sql .= " ,footer_chk ";        // フッター使用FLG
285        $sql .= " ,author";             // authorタグ
286        $sql .= " ,description";        // descriptionタグ
287        $sql .= " ,keyword";            // keywordタグ
288        $sql .= " ,update_url";         // 更新URL
289        $sql .= " ,create_date";        // データ作成日
290        $sql .= " ,update_date";        // データ更新日
291        $sql .= " FROM ";
292        $sql .= "     dtb_pagelayout";
293
294        // where句の指定があれば追加
295        if ($where != '') {
296            $sql .= " WHERE " . $where;
297        }
298
299        $sql .= " ORDER BY page_id";
300
301        $arrPageList = $objQuery->getAll($sql, $arrVal);
302
303        // URL にプロトコルの記載が無い場合、HTTP_URL を前置する。
304        foreach (array_keys($arrPageList) as $key) {
305            $arrPage =& $arrPageList[$key];
306            if (!preg_match('|^https?://|i', $arrPage['url'])) {
307                $arrPage['url'] = HTTP_URL . $arrPage['url'];
308            }
309            $arrPage['url'] = preg_replace('|/' . preg_quote(DIR_INDEX_FILE) . '$|', '/' . DIR_INDEX_PATH, $arrPage['url']);
310        }
311        unset($arrPage);
312
313        return $arrPageList;
314    }
315
316    /**
317     * date形式の文字列を W3C Datetime 形式に変換して出力する.
318     *
319     * @param date $date 変換する日付
320     * @return void
321     */
322    function date2W3CDatetime($date) {
323        $arr = array();
324        // 正規表現で文字列を抽出
325        preg_match("/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/",
326             $date, $arr);
327        // :TODO: time zone も取得するべき...
328        return sprintf("%04d-%02d-%02dT%02d:%02d:%02d+09:00",
329                       $arr[1], $arr[2], $arr[3], $arr[4], $arr[5], $arr[6]);
330    }
331
332}
333
334?>
Note: See TracBrowser for help on using the repository browser.