source: branches/version-2_13-dev/data/class/helper/SC_Helper_PageLayout.php @ 23048

Revision 23048, 13.6 KB checked in by Seasoft, 11 years ago (diff)

#2327 (SC_Helper_PageLayout#sfGetPageLayout ページ情報が取得できない場合の動作が不定)

  • 本当は受け取り側でコントロールすべき気も。しかし、現実装では問題無さそうなので簡易に。
  • 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
24/**
25 * Webページのレイアウト情報を制御するヘルパークラス.
26 *
27 * @package Helper
28 * @author LOCKON CO.,LTD.
29 * @version $Id:SC_Helper_PageLayout.php 15532 2007-08-31 14:39:46Z nanasess $
30 */
31class SC_Helper_PageLayout
32{
33    /**
34     * ページのレイアウト情報を取得し, 設定する.
35     *
36     * 現在の URL に応じたページのレイアウト情報を取得し, LC_Page インスタンスに
37     * 設定する.
38     *
39     * @access public
40     * @param LC_Page $objPage LC_Page インスタンス
41     * @param boolean $preview プレビュー表示の場合 true
42     * @param string $url ページのURL($_SERVER['SCRIPT_NAME'] の情報)
43     * @param integer $device_type_id 端末種別ID
44     * @return void
45     */
46    function sfGetPageLayout(&$objPage, $preview = false, $url = '', $device_type_id = DEVICE_TYPE_PC)
47    {
48        // URLを元にページ情報を取得
49        if ($preview === false) {
50            $url = preg_replace('|^' . preg_quote(ROOT_URLPATH) . '|', '', $url);
51            $arrPageData = $this->getPageProperties($device_type_id, null, 'url = ?', array($url));
52        }
53        // プレビューの場合は, プレビュー用のデータを取得
54        else {
55            $arrPageData = $this->getPageProperties($device_type_id, 0);
56        }
57
58        if (empty($arrPageData[0])) {
59            trigger_error('ページ情報を取得できませんでした。', E_USER_ERROR);
60        }
61
62        $objPage->tpl_mainpage = $this->getTemplatePath($device_type_id) . $arrPageData[0]['filename'] . '.tpl';
63        $objPage->arrPageLayout =& $arrPageData[0];
64        if (strlen($objPage->arrPageLayout['author']) === 0) {
65            $arrInfo = SC_Helper_DB_Ex::sfGetBasisData();
66            $objPage->arrPageLayout['author'] = $arrInfo['company_name'];
67        }
68
69        // ページタイトルを設定
70        if (SC_Utils_Ex::isBlank($objPage->tpl_title)) {
71            $objPage->tpl_title = $objPage->arrPageLayout['page_name'];
72        }
73
74        // 該当ページのブロックを取得し, 配置する
75        $masterData = new SC_DB_MasterData_Ex();
76        $arrTarget = $masterData->getMasterData('mtb_target');
77        $arrBlocs = $this->getBlocPositions($device_type_id, $objPage->arrPageLayout['page_id']);
78        // 無効なプラグインのブロックを取り除く.
79        $objPlugin = SC_Helper_Plugin_Ex::getSingletonInstance();
80        $arrBlocs = $objPlugin->getEnableBlocs($arrBlocs);
81        // php_path, tpl_path が存在するものを, 各ターゲットに配置
82        foreach ($arrTarget as $target_id => $value) {
83            foreach ($arrBlocs as $arrBloc) {
84                if ($arrBloc['target_id'] != $target_id) {
85                    continue;
86                }
87                if (is_file($arrBloc['php_path'])
88                    || is_file($arrBloc['tpl_path'])) {
89                    $objPage->arrPageLayout[$arrTarget[$target_id]][] = $arrBloc;
90                } else {
91                    $error = "ブロックが見つかりません\n"
92                        . 'tpl_path: ' . $arrBloc['tpl_path'] . "\n"
93                        . 'php_path: ' . $arrBloc['php_path'];
94                    trigger_error($error, E_USER_WARNING);
95                }
96            }
97        }
98        // カラム数を取得する
99        $objPage->tpl_column_num = $this->getColumnNum($objPage->arrPageLayout);
100    }
101
102    /**
103     * ページの属性を取得する.
104     *
105     * この関数は, dtb_pagelayout の情報を検索する.
106     * $device_type_id は必須. デフォルト値は DEVICE_TYPE_PC.
107     * $page_id が null の場合は, $page_id が 0 以外のものを検索する.
108     *
109     * @access public
110     * @param integer $device_type_id 端末種別ID
111     * @param integer $page_id ページID; null の場合は, 0 以外を検索する.
112     * @param string $where 追加の検索条件
113     * @param array $arrParams 追加の検索パラメーター
114     * @return array ページ属性の配列
115     */
116    function getPageProperties($device_type_id = DEVICE_TYPE_PC, $page_id = null, $where = '', $arrParams = array())
117    {
118        $objQuery =& SC_Query_Ex::getSingletonInstance();
119        $where = 'device_type_id = ? ' . (SC_Utils_Ex::isBlank($where) ? $where : 'AND ' . $where);
120        if ($page_id === null) {
121            $where = 'page_id <> ? AND ' . $where;
122            $page_id = 0;
123        } else {
124            $where = 'page_id = ? AND ' . $where;
125        }
126        $objQuery->setOrder('page_id');
127        $arrParams = array_merge(array($page_id, $device_type_id), $arrParams);
128
129        return $objQuery->select('*', 'dtb_pagelayout', $where, $arrParams);
130    }
131
132    /**
133     * ブロック情報を取得する.
134     *
135     * @access public
136     * @param integer $device_type_id 端末種別ID
137     * @param string $where 追加の検索条件
138     * @param array $arrParams 追加の検索パラメーター
139     * @param boolean $has_realpath php_path, tpl_path の絶対パスを含める場合 true
140     * @return array ブロック情報の配列
141     */
142    function getBlocs($device_type_id = DEVICE_TYPE_PC, $where = '', $arrParams = array(), $has_realpath = true)
143    {
144        $objBloc = new SC_Helper_Bloc_Ex($device_type_id);
145        $arrBlocs = $objBloc->getWhere($where, $arrParams);
146        if ($has_realpath) {
147            $this->setBlocPathTo($device_type_id, $arrBlocs);
148        }
149
150        return $arrBlocs;
151    }
152
153    /**
154     * ブロック配置情報を取得する.
155     *
156     * @access public
157     * @param integer $device_type_id 端末種別ID
158     * @param integer $page_id ページID
159     * @param boolean $has_realpath php_path, tpl_path の絶対パスを含める場合 true
160     * @return array 配置情報を含めたブロックの配列
161     */
162    function getBlocPositions($device_type_id, $page_id, $has_realpath = true)
163    {
164        $objQuery =& SC_Query_Ex::getSingletonInstance();
165
166        $table = <<< __EOF__
167        dtb_blocposition AS pos
168            JOIN dtb_bloc AS bloc
169                ON bloc.bloc_id = pos.bloc_id
170                    AND bloc.device_type_id = pos.device_type_id
171__EOF__;
172        $where = 'bloc.device_type_id = ? AND ((anywhere = 1 AND pos.page_id != 0) OR pos.page_id = ?)';
173        $objQuery->setOrder('target_id, bloc_row');
174        $arrBlocs = $objQuery->select('*', $table, $where, array($device_type_id, $page_id));
175        if ($has_realpath) {
176            $this->setBlocPathTo($device_type_id, $arrBlocs);
177        }
178
179        //全ページ設定と各ページのブロックの重複を削除
180        $arrUniqBlocIds = array();
181        foreach ($arrBlocs as $index => $arrBloc) {
182            if ($arrBloc['anywhere'] == 1){
183                $arrUniqBlocIds[] = $arrBloc['bloc_id'];
184            }
185        }
186        foreach ($arrBlocs as $bloc_index => $arrBlocData) {
187            if (in_array($arrBlocData['bloc_id'], $arrUniqBlocIds) && $arrBlocData['anywhere'] == 0){
188                unset($arrBlocs[$bloc_index]);
189            }
190        }
191
192        return $arrBlocs;
193    }
194
195    /**
196     * ページ情報を削除する.
197     *
198     * XXX ファイルを確実に削除したかどうかのチェック
199     *
200     * @access public
201     * @param integer $page_id ページID
202     * @param integer $device_type_id 端末種別ID
203     * @return integer 削除数
204     */
205    function lfDelPageData($page_id, $device_type_id = DEVICE_TYPE_PC)
206    {
207        $objQuery =& SC_Query_Ex::getSingletonInstance();
208        // page_id が空でない場合にはdeleteを実行
209        if ($page_id != '') {
210            $arrPageData = $this->getPageProperties($device_type_id, $page_id);
211            $ret = $objQuery->delete('dtb_pagelayout', 'page_id = ? AND device_type_id = ?', array($page_id, $device_type_id));
212            // ファイルの削除
213            $this->lfDelFile($arrPageData[0]['filename'], $device_type_id);
214        }
215
216        return $ret;
217    }
218
219    /**
220     * ページのファイルを削除する.
221     *
222     * dtb_pagelayout の削除後に呼び出すこと。
223     *
224     * @access private
225     * @param string $filename
226     * @param integer $device_type_id 端末種別ID
227     * @return void // TODO boolean にするべき?
228     */
229    function lfDelFile($filename, $device_type_id)
230    {
231        $objQuery =& SC_Query_Ex::getSingletonInstance();
232
233        /*
234         * 同名ファイルの使用件数
235         * PHP ファイルは, 複数のデバイスで共有するため, device_type_id を条件に入れない
236         */
237        $exists = $objQuery->exists('dtb_pagelayout', 'filename = ?', array($filename));
238
239        if (!$exists) {
240            // phpファイルの削除
241            $del_php = HTML_REALDIR . $filename . '.php';
242            if (file_exists($del_php)) {
243                unlink($del_php);
244            }
245        }
246
247        // tplファイルの削除
248        $del_tpl = $this->getTemplatePath($device_type_id) . $filename . '.tpl';
249        if (file_exists($del_tpl)) {
250            unlink($del_tpl);
251        }
252    }
253
254    /**
255     * 編集可能ページかどうか.
256     *
257     * @access public
258     * @param integer $device_type_id 端末種別ID
259     * @param integer $page_id ページID
260     * @return 編集可能ページの場合 true
261     */
262    function isEditablePage($device_type_id, $page_id)
263    {
264        if ($page_id == 0) {
265            return false;
266        }
267        $arrPages = $this->getPageProperties($device_type_id, $page_id);
268        if ($arrPages[0]['edit_flg'] != 2) {
269            return true;
270        }
271
272        return false;
273    }
274
275    /**
276     * テンプレートのパスを取得する.
277     *
278     * @access public
279     * @param integer $device_type_id 端末種別ID
280     * @param boolean $isUser USER_REALDIR 以下のパスを返す場合 true
281     * @return string テンプレートのパス
282     */
283    function getTemplatePath($device_type_id = DEVICE_TYPE_PC, $isUser = false)
284    {
285        $templateName = '';
286        switch ($device_type_id) {
287            case DEVICE_TYPE_MOBILE:
288                $dir = MOBILE_TEMPLATE_REALDIR;
289                $templateName = MOBILE_TEMPLATE_NAME;
290                break;
291
292            case DEVICE_TYPE_SMARTPHONE:
293                $dir = SMARTPHONE_TEMPLATE_REALDIR;
294                $templateName = SMARTPHONE_TEMPLATE_NAME;
295                break;
296
297            case DEVICE_TYPE_PC:
298            default:
299                $dir = TEMPLATE_REALDIR;
300                $templateName = TEMPLATE_NAME;
301                break;
302        }
303        $userPath = USER_REALDIR;
304        if ($isUser) {
305            $dir = $userPath . USER_PACKAGE_DIR . $templateName . '/';
306        }
307
308        return $dir;
309    }
310
311    /**
312     * DocumentRoot から user_data のパスを取得する.
313     *
314     * 引数 $hasPackage を true にした場合は, user_data/packages/template_name
315     * を取得する.
316     *
317     * @access public
318     * @param integer $device_type_id 端末種別ID
319     * @param boolean $hasPackage パッケージのパスも含める場合 true
320     * @return string 端末に応じた DocumentRoot から user_data までのパス
321     */
322    function getUserDir($device_type_id = DEVICE_TYPE_PC, $hasPackage = false)
323    {
324        switch ($device_type_id) {
325        case DEVICE_TYPE_MOBILE:
326            $templateName = MOBILE_TEMPLATE_NAME;
327            break;
328
329        case DEVICE_TYPE_SMARTPHONE:
330            $templateName = SMARTPHONE_TEMPLATE_NAME;
331            break;
332
333        case DEVICE_TYPE_PC:
334        default:
335            $templateName = TEMPLATE_NAME;
336        }
337        $userDir = ROOT_URLPATH . USER_DIR;
338        if ($hasPackage) {
339            return $userDir . USER_PACKAGE_DIR . $templateName . '/';
340        }
341
342        return $userDir;
343    }
344
345    /**
346     * ブロックの php_path, tpl_path を設定する.
347     *
348     * @access private
349     * @param integer $device_type_id 端末種別ID
350     * @param array $arrBlocs 設定するブロックの配列
351     * @return void
352     */
353    function setBlocPathTo($device_type_id = DEVICE_TYPE_PC, &$arrBlocs = array())
354    {
355        foreach ($arrBlocs as $key => $value) {
356            $arrBloc =& $arrBlocs[$key];
357            $arrBloc['php_path'] = SC_Utils_Ex::isBlank($arrBloc['php_path']) ? '' : HTML_REALDIR . $arrBloc['php_path'];
358            $bloc_dir = $this->getTemplatePath($device_type_id) . BLOC_DIR;
359            $arrBloc['tpl_path'] = SC_Utils_Ex::isBlank($arrBloc['tpl_path']) ? '' : $bloc_dir . $arrBloc['tpl_path'];
360        }
361    }
362
363    /**
364     * カラム数を取得する.
365     *
366     * @access private
367     * @param array $arrPageLayout レイアウト情報の配列
368     * @return integer $col_num カラム数
369     */
370    function getColumnNum($arrPageLayout)
371    {
372        // メインは確定
373        $col_num = 1;
374        // LEFT NAVI
375        if (count($arrPageLayout['LeftNavi']) > 0) $col_num++;
376        // RIGHT NAVI
377        if (count($arrPageLayout['RightNavi']) > 0) $col_num++;
378
379        return $col_num;
380    }
381}
Note: See TracBrowser for help on using the repository browser.