source: branches/version-2_13-dev/data/class/pages/LC_Page_Sitemap.php @ 22856

Revision 22856, 10.8 KB checked in by Seasoft, 11 years ago (diff)

#2043 (typo修正・ソース整形・ソースコメントの改善 for 2.13.0)

  • 主に空白・空白行の調整。もう少し整えたいが、一旦現状コミット。
  • 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-2013 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
24require_once CLASS_EX_REALDIR . 'page_extends/LC_Page_Ex.php';
25
26/**
27 * Sitemapプロトコル ファイル生成モジュール.
28 * PHP versions 4 and 5
29 *
30 * <pre>
31 * このモジュールは Sitemapプロトコルに対応した XMLファイルを出力する.
32 * EC-CUBE インストールディレクトリの htmlディレクトリへ配置することにより動作する.
33 *
34 * このモジュールにより, 以下のページのサイトマップが生成される.
35 * 1. $staticURL で指定したページ
36 * 2. 管理画面のデザイン管理から生成したページ
37 * 3. 公開されているすべての商品一覧ページ
38 * 4. 公開されているすべての商品詳細ページ
39 *
40 * このモジュールを設置後, 各検索エンジンにサイトマップを登録することにより, 検索エンジンの
41 * インデックス化が促進される.
42 * </pre>
43 * @see https://www.google.com/webmasters/tools/siteoverview?hl=ja
44 * @see https://siteexplorer.search.yahoo.com/mysites
45 *
46 * @author Kentaro Ohkouchi
47 * @version $Id:sitemap.php 15532 2007-08-31 14:39:46Z nanasess
48 *
49 * :TODO: 各ページの changefreq や priority を指定できるようにする
50 * :TODO: filemtime 関数を使えば、静的なページの更新時間も取得できそう
51 */
52class LC_Page_Sitemap extends LC_Page_Ex
53{
54    /** 動的に生成しないページの配列 */
55    var $staticURL;
56
57    /** ページリスト */
58    var $arrPageList;
59
60
61    /**
62     * Page を初期化する.
63     *
64     * @return void
65     */
66    function init()
67    {
68        parent::init();
69
70        $this->staticURL = array();
71
72        $this->staticURL[] = HTTP_URL . 'rss/' . DIR_INDEX_PATH;
73    }
74
75    /**
76     * Page のプロセス.
77     *
78     * @return void
79     */
80    function process()
81    {
82        // ページのデータを取得
83        // FIXME PCサイトのみに限定している。ある程度妥当だとは思うが、よりベターな方法はないだろうか。
84        $this->arrPageList = $this->getPageData('device_type_id = ?', DEVICE_TYPE_PC);
85
86        //キャッシュしない(念のため)
87        header('Paragrama: no-cache');
88
89        //XMLテキスト
90        header('Content-type: application/xml; charset=utf-8');
91
92        // 必ず UTF-8 として出力
93        mb_http_output('UTF-8');
94        ob_start('mb_output_handler');
95
96        echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
97        echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
98
99        // TOPページを処理
100        $arrTopPagesList = $this->getTopPage($this->arrPageList);
101        $this->createSitemap($arrTopPagesList[0]['url'],
102                             $this->date2W3CDatetime($arrTopPagesList[0]['update_date']),
103                             'daily', 1.0);
104
105        // 静的なページを処理
106        foreach ($this->staticURL as $url) {
107            $this->createSitemap($url, '', 'daily', 1.0);
108        }
109
110        // 編集可能ページを処理
111        $arrEditablePagesList = $this->getEditablePage($this->arrPageList);
112        foreach ($arrEditablePagesList as $arrEditablePage) {
113            $this->createSitemap($arrEditablePage['url'],
114                                 $this->date2W3CDatetime($arrEditablePage['update_date']));
115        }
116
117        // 商品一覧ページを処理
118        $arrProductPagesList = $this->getAllProducts();
119        foreach ($arrProductPagesList as $arrProductPage) {
120            $this->createSitemap($arrProductPage['url'], '', 'daily');
121        }
122
123        // 商品詳細ページを処理
124        $arrDetailPagesList = $this->getAllDetail();
125        foreach ($arrDetailPagesList as $arrDetailPage) {
126            $this->createSitemap($arrDetailPage['url'],
127                                 $this->date2W3CDatetime($arrDetailPage['update_date']));
128        }
129
130        echo '</urlset>' . "\n";
131    }
132
133    /**
134     * デストラクタ.
135     *
136     * @return void
137     */
138    function destroy()
139    {
140        parent::destroy();
141    }
142
143    /**
144     * Sitemap の <url /> を生成する.
145     *
146     * @param string $loc ページの URL ※必須
147     * @param string $lastmod ファイルの最終更新日 YYYY-MM-DD or W3C Datetime 形式
148     * @param string $changefreq ページの更新頻度
149     * @param double $priority URL の優先度
150     * @return Sitemap 形式の <url />
151     * @see https://www.google.com/webmasters/tools/docs/ja/protocol.html#xmlTagDefinitions
152     * TODO Smarty に移行すべき?
153     */
154    function createSitemap($loc, $lastmod = '', $changefreq = '', $priority = '')
155    {
156        printf("\t<url>\n");
157        printf("\t\t<loc>%s</loc>\n", htmlentities($loc, ENT_QUOTES, 'UTF-8'));
158        if (!empty($lastmod)) {
159            printf("\t\t<lastmod>%s</lastmod>\n", $lastmod);
160        }
161        if (!empty($changefreq)) {
162            printf("\t\t<changefreq>%s</changefreq>\n", $changefreq);
163        }
164        if (!empty($priority)) {
165            printf("\t\t<priority>%01.1f</priority>\n", $priority);
166        }
167        printf("\t</url>\n");
168    }
169
170    /**
171     * TOPページの情報を取得する.
172     *
173     * @param array $arrPageList すべてのページ情報の配列
174     * @return array TOPページの情報
175     */
176    function getTopPage($arrPageList)
177    {
178        $arrRet = array();
179        foreach ($arrPageList as $arrPage) {
180            if ($arrPage['page_id'] == '1') {
181                $arrRet[0] = $arrPage;
182                return $arrRet;
183            }
184        }
185    }
186
187    /**
188     * すべての編集可能ページの情報を取得する.
189     *
190     * @param array $arrPageList すべてのページ情報の配列
191     * @return array 編集可能ページ
192     */
193    function getEditablePage($arrPageList)
194    {
195        $arrRet = array();
196        foreach ($arrPageList as $arrPage) {
197            if ($arrPage['page_id'] > 4) {
198                $arrRet[] = $arrPage;
199            }
200        }
201
202        return $arrRet;
203    }
204
205    /**
206     * すべての商品一覧ページを取得する.
207     *
208     * @return array 検索エンジンからアクセス可能な商品一覧ページの情報
209     */
210    function getAllProducts()
211    {
212        // XXX: 商品登録の無いカテゴリは除外する方が良い気もする
213        $objQuery = SC_Query_Ex::getSingletonInstance();
214        $sql = 'SELECT category_id FROM dtb_category WHERE del_flg = 0';
215        $result = $objQuery->getAll($sql);
216
217        $arrRet = array();
218        foreach ($result as $row) {
219            // :TODO: カテゴリの最終更新日を取得できるようにする
220
221            $arrPage['url'] = HTTP_URL . 'products/list.php?category_id=' . $row['category_id'];
222            $arrRet[] = $arrPage;
223        }
224
225        return $arrRet;
226    }
227
228    /**
229     * すべての商品詳細ページを取得する.
230     *
231     * @return array 検索エンジンからアクセス可能な商品詳細ページの情報
232     */
233    function getAllDetail()
234    {
235        $objQuery = SC_Query_Ex::getSingletonInstance();
236        $sql = 'SELECT product_id, update_date FROM dtb_products WHERE ' . SC_Product_Ex::getProductDispConditions();
237        $result = $objQuery->getAll($sql);
238
239        $arrRet = array();
240        foreach ($result as $row) {
241            $arrPage['update_date'] = $row['update_date'];
242
243            $arrPage['url'] = HTTP_URL . substr(P_DETAIL_URLPATH, strlen(ROOT_URLPATH)) . $row['product_id'];
244            $arrRet[] = $arrPage;
245        }
246
247        return $arrRet;
248    }
249
250    /**
251     * ブロック情報を取得する.
252     *
253     * @param string $where WHERE句
254     * @param array  $arrVal WHERE句の値を格納した配列
255     * @return array $arrPageList ブロック情報
256     */
257    function getPageData($where = '', $arrVal = '')
258    {
259        $objQuery = SC_Query_Ex::getSingletonInstance();     // DB操作オブジェクト
260        $sql = '';                      // データ取得SQL生成用
261        $arrRet = array();              // データ取得用
262
263        // SQL生成(url と update_date 以外は不要?)
264        $sql .= ' SELECT';
265        $sql .= ' page_id';             // ページID
266        $sql .= ' ,page_name';          // 名称
267        $sql .= ' ,url';                // URL
268        $sql .= ' ,filename';           // ファイル名称
269        $sql .= ' ,header_chk ';        // ヘッダー使用FLG
270        $sql .= ' ,footer_chk ';        // フッター使用FLG
271        $sql .= ' ,author';             // authorタグ
272        $sql .= ' ,description';        // descriptionタグ
273        $sql .= ' ,keyword';            // keywordタグ
274        $sql .= ' ,update_url';         // 更新URL
275        $sql .= ' ,create_date';        // データ作成日
276        $sql .= ' ,update_date';        // データ更新日
277        $sql .= ' FROM ';
278        $sql .= '     dtb_pagelayout';
279
280        // where句の指定があれば追加
281        if ($where != '') {
282            $sql .= ' WHERE ' . $where;
283        }
284
285        $sql .= ' ORDER BY page_id';
286
287        $arrPageList = $objQuery->getAll($sql, $arrVal);
288
289        // URL にプロトコルの記載が無い場合、HTTP_URL を前置する。
290        foreach ($arrPageList as $key => $value) {
291            $arrPage =& $arrPageList[$key];
292            if (!preg_match('|^https?://|i', $arrPage['url'])) {
293                $arrPage['url'] = HTTP_URL . $arrPage['url'];
294            }
295            $arrPage['url'] = preg_replace('|/' . preg_quote(DIR_INDEX_FILE) . '$|', '/' . DIR_INDEX_PATH, $arrPage['url']);
296        }
297        unset($arrPage);
298
299        return $arrPageList;
300    }
301
302    /**
303     * date形式の文字列を W3C Datetime 形式に変換して出力する.
304     *
305     * @param date $date 変換する日付
306     * @return void
307     */
308    function date2W3CDatetime($date)
309    {
310        $arr = array();
311        // 正規表現で文字列を抽出
312        preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/', $date, $arr);
313        // :TODO: time zone も取得するべき...
314        return sprintf('%04d-%02d-%02dT%02d:%02d:%02d+09:00',
315                       $arr[1], $arr[2], $arr[3], $arr[4], $arr[5], $arr[6]);
316    }
317
318}
Note: See TracBrowser for help on using the repository browser.