OSDN Git Service

初回コミット(v2.6.17.1)
[magic3/magic3.git] / widgets / ec_disp / include / container / ec_dispProductWidgetContainer.php
1 <?php
2 /**
3  * index.php用コンテナクラス
4  *
5  * PHP versions 5
6  *
7  * LICENSE: This source file is licensed under the terms of the GNU General Public License.
8  *
9  * @package    Magic3 Framework
10  * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
11  * @copyright  Copyright 2006-2013 Magic3 Project.
12  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
13  * @version    SVN: $Id: ec_dispProductWidgetContainer.php 5559 2013-01-16 13:09:11Z fishbone $
14  * @link       http://www.magic3.org
15  */
16 require_once($gEnvManager->getContainerPath() . '/baseWidgetContainer.php');
17 require_once($gEnvManager->getCurrentWidgetDbPath() .   '/ec_dispDb.php');
18 require_once($gEnvManager->getCommonPath() . '/valueCheck.php');
19
20 class ec_dispProductWidgetContainer extends BaseWidgetContainer
21 {
22         private $db;                    // DB接続オブジェクト
23         private $langId;                // 現在の言語ID
24         private $viewStyle;             // 表示スタイル
25         private $categoryId;            // カテゴリーID
26         private $productId;                     // 製品ID
27         private $defaultImageSWidth;            // 画像小幅
28         private $defaultImageSHeight;           // 画像小高さ
29         private $defaultImageMWidth;            // 画像中幅
30         private $defaultImageMHeight;           // 画像中高さ
31         private $productExists;                         // 商品が存在するかどうか
32         private $subcategoryExists;                             // サブカテゴリーが存在するかどうか
33         private $currentPageUrl;                        // 現在のページURL
34         private $ecObj;                                 // EC共通ライブラリオブジェクト
35         private $showStock;                             // 在庫表示するかどうか
36         private $contentNoStock;                // 在庫なし時コンテンツ
37         private $headTitle;             // METAタグタイトル
38         private $headDesc;              // METAタグ要約
39         private $headKeyword;   // METAタグキーワード
40         private $categoryTitleSeparator;        // カテゴリータイトル作成用セパレータ
41         const PRICE_OBJ_ID = "eclib";           // 価格計算オブジェクトID
42         const STANDARD_PRICE = 'selling';               // 通常価格
43         const PRODUCT_IMAGE_MEDIUM = 'standard-product';                // 中サイズ商品画像ID
44         const PRODUCT_IMAGE_SMALL = 'small-product';            // 小サイズ商品画像ID
45         const PRODUCT_IMAGE_LARGE = 'large-product';            // 大サイズ商品画像ID
46         const PRODUCT_STATUS_NEW = 'new';               // 商品ステータス新規
47         const PRODUCT_STATUS_SUGGEST = 'suggest';               // 商品ステータスおすすめ
48         const DEFAULT_TAX_TYPE = 'sales';                       // デフォルト税種別
49         const VIEW_STYLE_SMALL = 'small';                       // 表示スタイル(小)
50         const VIEW_STYLE_MEDIUM = 'medium';                     // 表示スタイル(中)
51         const VIEW_STYLE_LARGE = 'large';                       // 表示スタイル(大)
52         const PRODUCT_CLASS_DEFAULT = '';                       // 商品クラス(一般商品)
53         const PRODUCT_TYPE_DEFAULT = '';                // 商品タイプデフォルト
54         const DEFAULT_PRODUCT_COUNT = 10;                               // デファオルとの表示項目数
55         const DEFAULT_TARGET_WIDGET = 'ec_main';                // 呼び出しウィジェットID
56         const DEFAULT_STOCK_VIEW_FORMAT = '0:なし;3:残り僅か($1);:あり($1)';
57         const DEFAULT_PRODUCT_IMAGE_TYPE = 'c.jpg';                     // 商品画像ファイルのタイプ
58         const PRODUCT_IMAGE_DIR = '/widgets/product/image/';                            // 商品画像格納ディレクトリ
59         const MAX_CATEGORY_LEVEL = 5;                   // カテゴリー階層最大数
60         const DEFAULT_LIST_TITLE = '商品一覧';              // デフォルト一覧タイトル
61         const DEFAULT_SEARCH_LIST_TITLE = '検索結果';               // デフォルト検索結果商品一覧タイトル
62         const DEFAULT_CATEGORY_LIST_TITLE = '「$1」の商品一覧';          // カテゴリー表示時タイトル
63         const DEFAULT_CATEGORY_TITLE_SEPARATOR = '-';           // デフォルトのカテゴリータイトル作成用セパレータ
64         //const DEFAULT_TITLE_SEPARATOR = '-';          // デフォルトのタイトル作成用セパレータ
65         // Eコマース設定DB値
66         const CF_E_HIERARCHICAL_CATEGORY        = 'hierarchical_category';      // 階層化商品カテゴリー
67         
68         /**
69          * コンストラクタ
70          */
71         function __construct()
72         {
73                 // 親クラスを呼び出す
74                 parent::__construct();
75                 
76                 // DBオブジェクト作成
77                 $this->db = new ec_dispDb();
78                 
79                 // 価格計算用オブジェクト取得
80                 $this->ecObj = $this->gInstance->getObject(self::PRICE_OBJ_ID);
81         }
82         /**
83          * テンプレートファイルを設定
84          *
85          * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
86          * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
87          *
88          * @param RequestManager $request               HTTPリクエスト処理クラス
89          * @param object         $param                 任意使用パラメータ。そのまま_assign()に渡る
90          * @return string                                               テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
91          */
92         function _setTemplate($request, &$param)
93         {
94                 $act = $request->trimValueOf('act');
95                 $this->productId = $request->trimValueOf(M3_REQUEST_PARAM_PRODUCT_ID);  // 製品ID
96                 if (empty($this->productId)) $this->productId = $request->trimValueOf(M3_REQUEST_PARAM_PRODUCT_SHORT);          // 略式コンテンツID
97                 
98                 if ($act == 'inputbasketbylist'){               // 商品リストからの選択の場合
99                         return 'main.tmpl.html';
100                 } else {
101                         if ($act == 'search' || empty($this->productId)){               // 商品一覧のとき
102                                 return 'main.tmpl.html';
103                         } else {                        // 商品詳細表示
104                                 return 'main_detail.tmpl.html';
105                         }
106                 }
107         }
108         /**
109          * テンプレートにデータ埋め込む
110          *
111          * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
112          *
113          * @param RequestManager $request               HTTPリクエスト処理クラス
114          * @param object         $param                 任意使用パラメータ。_setTemplate()と共有。
115          * @param                                                               なし
116          */
117         function _assign($request, &$param)
118         {
119                 // 現在日時を取得
120                 $this->currentDay = date("Y/m/d");              // 日
121                 $this->currentHour = (int)date("H");            // 時間
122                 $this->langId   = $this->gEnv->getCurrentLanguage();            // 表示言語を取得
123                 $this->currentPageUrl = $this->gEnv->createCurrentPageUrl();// 現在のページURL
124                 
125                 // 保存値取得
126                 $categoryListTitle = self::DEFAULT_CATEGORY_LIST_TITLE; // カテゴリー表示時タイトル
127                 $this->categoryTitleSeparator = self::DEFAULT_CATEGORY_TITLE_SEPARATOR; // カテゴリータイトル作成用セパレータ
128                 $productCount = self::DEFAULT_PRODUCT_COUNT;                                            // 商品表示数
129                 $targetWidget = self::DEFAULT_TARGET_WIDGET;            // カート表示ウィジェット
130                 $this->showStock                = 0;                            // 在庫表示するかどうか
131                 $stockViewFormat        = self::DEFAULT_STOCK_VIEW_FORMAT;      // 在庫表示フォーマット
132                 $this->contentNoStock = '';                                                             // 在庫なし時コンテンツ
133                 $paramObj = $this->getWidgetParamObj();
134                 if (!empty($paramObj)){
135                         if (!empty($paramObj->categoryListTitle)) $categoryListTitle = $paramObj->categoryListTitle;    // カテゴリー表示時タイトル
136                         if (!empty($paramObj->categoryTitleSeparator)) $this->categoryTitleSeparator = $paramObj->categoryTitleSeparator;       // カテゴリータイトル作成用セパレータ
137                         $productCount = $paramObj->productCount;                // 商品表示数
138                         $targetWidget = $paramObj->targetWidget;                // カート表示ウィジェット
139                         $this->showStock                = $paramObj->showStock;                         // 在庫表示するかどうか
140                         $stockViewFormat        = $paramObj->stockViewFormat;   // 在庫表示フォーマット
141                         $this->contentNoStock           = $paramObj->contentNoStock;    // 在庫なし時コンテンツ
142                 }
143
144                 // 表示モードを取得
145                 $this->viewStyle = $request->trimValueOf(M3_REQUEST_PARAM_VIEW_STYLE);          // 表示モード
146                 if (empty($this->viewStyle)) $this->viewStyle = self::VIEW_STYLE_MEDIUM;
147                 
148                 // 画像情報を取得
149                 $this->defaultImageSWidth = 0;
150                 $this->defaultImageSHeight = 0;
151                 $ret = $this->db->getProductImageInfo(self::PRODUCT_IMAGE_SMALL, $row);
152                 if ($ret){
153                         $this->defaultImageSWidth = $row['is_width'];
154                         $this->defaultImageSHeight = $row['is_height'];
155                 }
156                 $this->defaultImageMWidth = 0;
157                 $this->defaultImageMHeight = 0;
158                 $ret = $this->db->getProductImageInfo(self::PRODUCT_IMAGE_MEDIUM, $row);
159                 if ($ret){
160                         $this->defaultImageMWidth = $row['is_width'];
161                         $this->defaultImageMHeight = $row['is_height'];
162                 }
163                 $this->defaultImageLWidth = 0;
164                 $this->defaultImageLHeight = 0;
165                 $ret = $this->db->getProductImageInfo(self::PRODUCT_IMAGE_LARGE, $row);
166                 if ($ret){
167                         $this->defaultImageLWidth = $row['is_width'];
168                         $this->defaultImageLHeight = $row['is_height'];
169                 }
170                                 
171                 // パラメータを取得
172                 // カテゴリーを取得
173                 $categoryId = $request->trimValueOf('category');        // カテゴリーID
174                 $this->categoryId = $categoryId;
175                 $categoryArray = explode(',', $categoryId);
176                 if (!ValueCheck::isNumeric($categoryArray)){
177                         $categoryId = '';               // すべて数値であるかチェック
178                         $categoryArray = array();
179                 }
180                 if (!empty($categoryArray) && $this->ecObj->getConfig(self::CF_E_HIERARCHICAL_CATEGORY)){                       // サブカテゴリーを取得する場合
181                         $categoryArray = array_unique($this->getSubCategory($categoryArray));
182                         $categoryId = implode(',', $categoryArray);
183                 }
184                 
185                 $pageNo = $request->trimValueOf(M3_REQUEST_PARAM_PAGE_NO);                              // ページ番号
186                 if (empty($pageNo)) $pageNo = 1;
187                 $quantity = $request->trimValueOf('item_quantity');             // 数量
188                 if (empty($quantity)) $quantity = 1;
189                 
190                 // DBの保存設定値を取得
191 /*              $maxListCount = self::DEFAULT_LIST_COUNT;
192                 $count = intval($this->db->getConfig(self::DISP_PRODUCT_COUNT));                                                // 商品一覧の商品表示数
193                 if ($count > 0) $maxListCount = $count;*/
194                 
195                 $act = $request->trimValueOf('act');
196                 
197                 if ($act == 'search'){                  // 検索
198                         $keyword = $request->trimValueOf('keyword');
199                 } else if ($act == 'inputbasket' || $act == 'inputbasketbylist'){                       // カートに入れる処理の場合
200                         // クッキー読み込み、カートIDを取得
201                         $cartId = $request->getCookieValue(M3_COOKIE_CART_ID);
202                         if (empty($cartId)){    // カートIDが設定されていないとき
203                                 // カートIDを生成
204                                 $cartId = $this->ecObj->createCartId();
205                         }
206                         $request->setCookieValue(M3_COOKIE_CART_ID, $cartId);
207
208                         // ####### カートに商品を追加 ########
209                         // 商品名と価格を取得
210                         if (!empty($this->productId)){
211                                 // カートの情報を取得
212                                 $cartSerial = 0;                // カートシリアル番号
213                                 $cartItemSerial = 0;    // カート商品シリアル番号
214                                 $userId = $this->gEnv->getCurrentUserId();
215                                 $ret = $this->ecObj->db->getCartHead($cartId, $this->langId, $row);
216                                 if ($ret){
217                                         $cartSerial = $row['sh_serial'];
218                                         if ($userId == 0) $userId = $row['sh_id'];
219                                 }
220                                 
221                                 // 商品情報を取得
222                                 $isValidItem = true;            // 現在のカートのデータが有効かどうか
223                                 $ret = $this->db->getProductByProductId($this->productId, $this->langId, $row, $row2, $row3, $row4, $row5);
224                                 if ($ret){
225                                         // 価格を取得
226                                         $priceArray = $this->getPrice($row2, self::STANDARD_PRICE);
227                                         $price = $priceArray['pp_price'];       // 価格
228                                         $currency = $priceArray['pp_currency_id'];      // 通貨
229                                         $taxType = $row['pt_tax_type_id'];                                      // 税種別                    
230
231                                         // 価格作成
232                                         $this->ecObj->setCurrencyType($currency, $this->langId);                // 通貨設定
233                                         $this->ecObj->setTaxType($taxType, $this->langId);              // 税種別設定
234                                         $totalPrice = $this->ecObj->getPriceWithTax($price, $dispPrice);        // 税込み価格取得
235                                 } else {                // 商品情報が取得できないときは、カートの商品をキャンセル
236                                         $isValidItem = false;
237                                 }
238                                 // カートにある商品を取得
239                                 if ($isValidItem && $cartSerial > 0){
240                                         $ret = $this->ecObj->db->getCartItem($cartSerial, self::PRODUCT_CLASS_DEFAULT, $this->productId, self::PRODUCT_TYPE_DEFAULT, $cartItemRow);
241                                         if ($ret){              // 取得できたときは価格をチェック
242                                                 if ($cartItemRow['si_available']){              // データが有効のとき
243                                                         // 価格が変更されているときはカートの商品を無効にする
244                                                         $cart_item_currency = $cartItemRow['si_currency_id'];
245                                                         $cart_item_quantity = $cartItemRow['si_quantity'];
246                                                         $cart_item_price = $cartItemRow['si_subtotal'];
247                                                         $cartItemSerial = $cartItemRow['si_serial'];
248                                                         
249                                                         if ($cart_item_currency != $currency) $isValidItem = false;             // 通貨が変更のときはレコードを無効化
250                                                         if ($totalPrice * $cart_item_quantity != $cart_item_price) $isValidItem = false;                // 価格が変更のときはレコードを無効化
251                                                 } else {
252                                                         $isValidItem = false;
253                                                 }
254                                         }
255                                 }
256                                 // カート商品情報を更新
257                                 if ($isValidItem){
258                                         // カートに商品を追加
259                                         $ret = $this->ecObj->db->addCartItem($cartSerial, $cartItemSerial, $cartId, self::PRODUCT_CLASS_DEFAULT, $this->productId, self::PRODUCT_TYPE_DEFAULT, $this->langId, 
260                                                                                                                 $currency, $totalPrice, $quantity);
261                                 } else {
262                                         // カート商品の無効化
263                                         $ret = $ecLibObj->db->voidCartItem($cartSerial, $cartItemSerial);
264                                 }
265                         }
266                         // 商品一覧からの選択の場合は製品IDをリセット
267                         if ($act == 'inputbasketbylist') $this->productId = 0;
268                         
269                         // カート画面を表示
270                         $cartPage = $this->createCmdUrlToWidget($targetWidget, 'task=cart');
271                         $this->gPage->redirect($cartPage);
272                         return;
273                 }
274                 // ####### 商品情報の表示 #######
275                 if (empty($this->productId)){           // 商品一覧表示のとき
276                         if ($this->showStock){                          // 在庫表示する場合
277                                 $this->tmpl->setAttribute('show_stock', 'visibility', 'visible');
278                                 $this->contentNoStock = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $this->contentNoStock);// マクロ変換
279                         }
280                                 
281                         // 検索からの一覧または、カテゴリー指定の一覧
282                         if ($act == 'search'){
283                                 // キーワード分割
284                                 $parsedKeywords = $this->gInstance->getTextConvManager()->parseSearchKeyword($keyword);
285                                 
286                                 // 検索キーワードを記録
287                                 //$this->gInstance->getAnalyzeManager()->logSearchWord($this->gEnv->getCurrentWidgetId(), $keyword);
288                                 for ($i = 0; $i < count($parsedKeywords); $i++){
289                                         $this->gInstance->getAnalyzeManager()->logSearchWord($this->gEnv->getCurrentWidgetId(), $parsedKeywords[$i]);
290                                 }
291                                 
292                                 //$totalCount = $this->db->getProductCountByKeyword($keyword, $this->langId, 1);
293                                 $totalCount = $this->db->getProductCountByKeyword($parsedKeywords, $this->langId, 1);
294                                 $pageCount = (int)(($totalCount -1) / $productCount) + 1;               // 総ページ数
295                                 
296                                 // 表示するページ番号の修正
297                                 if ($pageNo < 1) $pageNo = 1;
298                                 if ($pageNo > $pageCount) $pageNo = $pageCount;
299                                 
300                                 // 商品リストを表示
301                                 //$this->db->getProductByKeyword($keyword, $this->langId, $productCount, ($pageNo -1) * $productCount, array($this, 'productListLoop'));
302                                 $this->db->getProductByKeyword($parsedKeywords, $this->langId, $productCount, ($pageNo -1) * $productCount, array($this, 'productListLoop'));
303
304                                 // ページング用リンク作成
305                                 $pageLink = '';
306                                 if ($pageCount > 1){    // ページが2ページ以上のときリンクを作成
307                                         for ($i = 1; $i <= $pageCount; $i++){
308                                                 $linkUrl = $this->currentPageUrl . '&task=product&act=search&keyword=' . urlencode($keyword) . '&page=' . $i;
309                                                 if ($i == $pageNo){
310                                                         $link = '&nbsp;' . $i;
311                                                 } else {
312                                                         $link = '&nbsp;<a href="' . $this->getUrl($linkUrl, true) . '" >' . $i . '</a>';
313                                                 }
314                                                 $pageLink .= $link;
315                                         }
316                                 }
317                                 $this->tmpl->addVar("show_productlist", "page_link", $pageLink);
318                                 
319                                 // 商品があるかチェック
320                                 $title = self::DEFAULT_SEARCH_LIST_TITLE;               // デフォルトの検索結果タイトル
321                                 $this->headTitle = $title;              // METAタグタイトル
322                                 if ($this->productExists){
323                                         $this->tmpl->setAttribute('show_productlist', 'visibility', 'visible');
324                                         $this->tmpl->addVar("show_productlist", "title", $this->convertToDispString($title));// タイトルを設定
325                                         if (empty($keyword)) $keyword = 'なし';
326                                         $this->tmpl->addVar("show_productlist", "detail", 'キーワード=' . $keyword . '&nbsp;&nbsp;' . $totalCount . '件');// 詳細
327                                 } else {
328                                         $this->tmpl->setAttribute('no_item_message', 'visibility', 'visible');
329                                         $this->tmpl->addVar("no_item_message", "title", $this->convertToDispString($title));// タイトルを設定
330                                         if (empty($keyword)) $keyword = 'なし';
331                                         $this->tmpl->addVar("no_item_message", "detail", 'キーワード=' . $keyword . '&nbsp;&nbsp;' . $totalCount . '件');// 詳細
332                                 }
333                         } else {
334                                 // タイトルの取得
335                                 $titleArray = array();
336                                 $menuItems = $this->gEnv->getSelectedMenuItems();
337                                 for ($i = 0; $i < count($menuItems); $i++){
338                                         $titleArray[] = $menuItems[$i]->title;
339                                 }
340                                 //$title = $menuItem['title'];
341                                 $title = implode($this->categoryTitleSeparator, $titleArray);
342                                 if (empty($title)){
343                                         $title = self::DEFAULT_LIST_TITLE;              // デフォルトのタイトル
344                                 } else {
345                                         $title = str_replace('$1', $title, $categoryListTitle);
346                                 }
347                                 
348                                 // 指定カテゴリーの商品を取得
349                                 if (!empty($categoryId)){
350                                         // 総数を取得
351                                         $totalCount = $this->db->getProductCountByCategoryId($categoryId, $this->langId);
352                                         $pageCount = (int)(($totalCount -1) / $productCount) + 1;               // 総ページ数
353                         
354                                         // 表示するページ番号の修正
355                                         if ($pageNo < 1) $pageNo = 1;
356                                         if ($pageNo > $pageCount) $pageNo = $pageCount;
357
358                                         // 商品リストを表示
359                                         $this->db->getProductByCategoryId($categoryId, $this->langId, $productCount, ($pageNo -1) * $productCount, array($this, 'productListLoop'));
360
361                                         // ページング用リンク作成
362                                         // ##### カテゴリーはアクセス時のパラメータを使用 #####
363                                         $pageLink = '';
364                                         if ($pageCount > 1){    // ページが2ページ以上のときリンクを作成
365                                                 for ($i = 1; $i <= $pageCount; $i++){
366                                                         $linkUrl = $this->currentPageUrl . '&category=' . $this->categoryId . '&page=' . $i;
367                                                         if ($i == $pageNo){
368                                                                 $link = '&nbsp;' . $i;
369                                                         } else {
370                                                                 $link = '&nbsp;<a href="' . $this->getUrl($linkUrl, true) . '" >' . $i . '</a>';
371                                                         }
372                                                         $pageLink .= $link;
373                                                 }
374                                         }
375                                         $this->tmpl->addVar("show_productlist", "page_link", $pageLink);
376                                 }
377                 
378                                 // サブカテゴリーと商品リストの表示制御
379                                 // サブカテゴリーがあるかチェック
380                                 if ($this->subcategoryExists) $this->tmpl->setAttribute('show_subcategory', 'visibility', 'visible');
381                                 // 商品があるかチェック
382                                 if ($this->productExists) $this->tmpl->setAttribute('show_productlist', 'visibility', 'visible');
383                                 // 登録項目がないとき
384                                 if (!empty($categoryId) && !$this->subcategoryExists && !$this->productExists){
385                                         $this->tmpl->setAttribute('no_item_message', 'visibility', 'visible');
386                                         $this->tmpl->addVar("no_item_message", "detail", '項目がありません');// 詳細
387                                 }
388                                 
389                                 // タイトルを設定
390                                 $this->headTitle = $title;              // METAタグタイトル
391                                 $this->tmpl->addVar("show_productlist", "title", $this->convertToDispString($title));
392                         }
393                 } else {                // 商品詳細表示のとき
394                         // 表示モードは画像大
395                         $this->viewStyle = self::VIEW_STYLE_LARGE;
396                         
397                         $ret = $this->db->getProductByProductId($this->productId, $this->langId, $row, $row2, $row3, $row4, $row5);
398                         if ($ret){
399                                 // 取得値を設定
400                                 //$this->serialNo = $row['pt_serial'];          // シリアル番号
401                                 $this->productId = $row['pt_id'];       // 商品ID
402                                 //$this->langId = $row['pt_language_id'];
403
404                                 $unitTypeId = $row['pt_unit_type_id'];  // 単位
405                                 // 単位情報を取得
406                                 $unitType = '';
407                                 if ($this->db->getUnitTypeRecord($unitTypeId, $this->langId, $unitRow)){
408                                         $unitType = $unitRow['ut_symbol'];
409                                 }
410                                 $unitQuantity = $row['pt_unit_quantity'];               // 数量
411                                 $description = $row['pt_description'];                  // 説明
412                                 $description_short = $row['pt_description_short'];              // 簡易説明
413                                 //$keyword = $row['pt_search_keyword'];                                 // 検索キーワード
414                                 $this->headTitle = $row['pt_name'];             // METAタグタイトル
415                                 $this->headDesc = $row['pt_description_short'];         // METAタグ要約
416                                 $this->headKeyword = $row['pt_meta_keywords'];                  // METAタグキーワード
417                                 $url = $row['pt_site_url'];                                                     // 詳細情報URL
418                                 $this->taxType = $row['pt_tax_type_id'];                                        // 税種別
419                                 //$adminNote = $row['pt_admin_note'];           // 管理者用備考
420                         
421                                 // 価格を取得
422                                 $priceArray = $this->getPrice($row2, self::STANDARD_PRICE);
423                                 $price = $priceArray['pp_price'];       // 価格
424                                 $currency = $priceArray['pp_currency_id'];      // 通貨
425                                 $taxType = $row['pt_tax_type_id'];                                      // 税種別
426                                 $lang = $row['pt_language_id'];                                 // 言語                               
427                                 $prePrice = $this->convertToDispString($priceArray['cu_symbol']);
428                                 $postPrice = $this->convertToDispString($priceArray['cu_post_symbol']);
429                         
430                                 // 表示額作成
431                                 $this->ecObj->setCurrencyType($currency, $lang);                // 通貨設定
432                                 $this->ecObj->setTaxType($taxType, $lang);              // 税種別設定
433                                 $totalPrice = $this->ecObj->getPriceWithTax($price, $dispPrice);        // 税込み価格取得
434                         
435                                 // 画像を取得
436                                 $imageArray = $this->getImage($row3, self::PRODUCT_IMAGE_SMALL);// 商品画像小
437                                 $imageUrl_s = $imageArray['im_url'];    // URL
438                                 $imageArray = $this->getImage($row3, self::PRODUCT_IMAGE_MEDIUM);// 商品画像中
439                                 $imageUrl_m = $imageArray['im_url'];    // URL
440                                 $imageArray = $this->getImage($row3, self::PRODUCT_IMAGE_LARGE);// 商品画像大
441                                 $imageUrl_l = $imageArray['im_url'];    // URL
442                                                         
443                                 // 画像を配列に保存
444                                 $images = array();// 画像URL保存用
445                                 $images[] = $imageUrl_s;
446                                 $images[] = $imageUrl_m;
447                                 $images[] = $imageUrl_l;
448                         
449                                 // 商品ステータスを取得
450                                 $statusArray = $this->getStatus($row4, self::PRODUCT_STATUS_NEW);// 新規
451                                 $new = $statusArray['ps_value'];
452                                 $statusArray = $this->getStatus($row4, self::PRODUCT_STATUS_SUGGEST);// おすすめ
453                                 $suggest = $statusArray['ps_value'];
454                         
455                                 // 画像中
456 /*                              $destImg_m = '';
457                                 if ($this->viewStyle == self::VIEW_STYLE_MEDIUM){
458                                         $imageUrl_m = $this->getProperImage($images, 1);
459                                         if (empty($imageUrl_m)){
460                                                 $destImg_m = '<img id="preview_img_medium" style="display:none;" ';
461                                                 $destImg_m .= 'width="' . $this->defaultImageMWidth . '" ';
462                                                 $destImg_m .= 'height="' . $this->defaultImageMHeight . '" ';
463                                                 $destImg_m .= '/>';
464                                         } else {
465                                                 // URLマクロ変換
466                                                 $imgUrl = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $imageUrl_m);
467                                                 $destImg_m = '<img id="preview_img_medium" src="' . $this->getUrl($imgUrl) . '" ';
468                                                 $destImg_m .= 'width="' . $this->defaultImageMWidth . '"';
469                                                 $destImg_m .= ' height="' . $this->defaultImageMHeight . '"';
470                                                 $destImg_m .= ' />';
471                                         }
472                                 }*/
473                                 // 画像大
474                                 $destImg_l = '';
475                                 if ($this->viewStyle == self::VIEW_STYLE_LARGE){
476                                         $imageUrl = $this->getProperImage($images, 2);
477                                         $imageUrl_l = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $imageUrl);
478                                         $imagePath_l = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getSystemRootPath(), $imageUrl);
479                                         if (!file_exists($imagePath_l)){
480                                                 $imageUrl_l = $this->getProductImageUrl('0_' . $this->defaultImageLWidth . 'x' . $this->defaultImageLHeight . self::DEFAULT_PRODUCT_IMAGE_TYPE);
481                                         }
482                                         $destImg_l = '<img class="product_image_large" src="' . $this->getUrl($imageUrl_l) . '" ';
483                                         $destImg_l .= 'width="' . $this->defaultImageLWidth . '"';
484                                         $destImg_l .= ' height="' . $this->defaultImageLHeight . '"';
485                                         $destImg_l .= ' />';
486                                 }
487                                 $this->tmpl->addVar("_widget", "id", $row['pt_id']);            // 商品ID
488                                 $this->tmpl->addVar("_widget", "name", $row['pt_name']);                // 名前
489                                 $this->tmpl->addVar("_widget", "code", $row['pt_code']);                // 商品コード
490                                 $this->tmpl->addVar("_widget", "description", $row['pt_description']);          // 説明
491                                 $this->tmpl->addVar("_widget", "desc_short", $row['pt_description_short']);             // 簡易説明         
492                                 $this->tmpl->addVar("show_cart", "unit_type", $unitType);               // 単位タイプ
493                                 $this->tmpl->addVar("show_cart", "quantity", '1');              // 数量デフォルト値
494                                 
495                                 //$this->tmpl->addVar("_widget", "url", $url);                          // 詳細情報URL
496                                 //$this->tmpl->addVar("_widget", "admin_note", $adminNote);                     // 管理者用備考
497                                 $this->tmpl->addVar("_widget", "disp_total_price", $prePrice . $dispPrice . $postPrice);                // 税込み価格
498 //                              $this->tmpl->addVar("_widget", "image_m", $destImg_m);          // 画像
499                                 $this->tmpl->addVar("_widget", "image_l", $destImg_l);          // 画像
500                                 $this->tmpl->addVar("_widget", "productid_key", M3_REQUEST_PARAM_PRODUCT_ID);           // 商品IDキー
501                                 
502                                 // 在庫表示
503                                 if ($this->showStock){                          // 在庫表示する場合
504                                         $stockCount = intval($row['pe_stock_count']);           // 表示在庫数
505                                         $this->tmpl->setAttribute('show_stock', 'visibility', 'visible');
506                                         if (empty($stockViewFormat)) $stockViewFormat = self::DEFAULT_STOCK_VIEW_FORMAT;                // フォーマットが空の場合はデフォルトフォーマットで表示
507
508                                         // 在庫表示用メッセージを取得
509                                         $stockMsgArray = parseUserCustomParam($stockViewFormat);        // メッセージを配列化
510
511                                         $stockMsg = '--該当なし--';
512                                         $foreValue = -1;
513                                         for ($i = 0; $i < count($stockMsgArray); $i++){
514                                                 if ($stockMsgArray[$i]->key == '' || ($foreValue < $stockCount && $stockCount <= $stockMsgArray[$i]->key)) break;
515                                                 $foreValue = $stockMsgArray[$i]->key;
516                                         }
517                                         if ($i < count($stockMsgArray)){
518                                                 $stockMsg = str_replace('$1', $stockCount, $stockMsgArray[$i]->value);
519                                         }
520                                         $this->tmpl->addVar("show_stock", "stock", '在庫: ' . $stockMsg);   // 在庫数表示
521                                         
522                                         // 在庫なし時のメッセージ表示
523                                         if ($stockCount <= 0){          // 在庫ない場合
524                                                 $this->tmpl->setAttribute('show_cart', 'visibility', 'hidden');
525                                                 $this->tmpl->setAttribute('show_no_stock', 'visibility', 'visible');
526                                                 
527                                                 // マクロ変換
528                                                 $this->contentNoStock = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $this->contentNoStock);
529                                                 $this->tmpl->addVar("show_no_stock", 'content', $this->contentNoStock);
530                                         }
531                                 }
532                         } else {                // 商品情報が見つからないとき
533                                 // テンプレートファイルを強制入れ替え
534                                 $this->replaceTemplateFile('message.tmpl.html');
535                                 $this->SetMsg(self::MSG_APP_ERR, "商品が見つかりません");
536                         }
537                 }
538         }
539         /**
540          * ヘッダ部メタタグの設定
541          *
542          * HTMLのheadタグ内に出力する。
543          * _assign()よりも後に実行される。
544          *
545          * @param RequestManager $request               HTTPリクエスト処理クラス
546          * @param object         $param                 任意使用パラメータ
547          * @return array                                                設定データ。連想配列で「title」「description」「keywords」を設定。
548          */
549         function _setHeadMeta($request, &$param)
550         {
551                 $headData = array(      'title' => $this->headTitle,
552                                                         'description' => $this->headDesc,
553                                                         'keywords' => $this->headKeyword);
554                 return $headData;
555         }
556         /**
557          * 取得したデータをテンプレートに設定する
558          *
559          * @param int $index                    行番号(0~)
560          * @param array $fetchedRow             フェッチ取得した行
561          * @param object $param                 未使用
562          * @return bool                                 true=処理続行の場合、false=処理終了の場合
563          */
564         function productListLoop($index, $fetchedRow, $param)
565         {
566                 $images = array();// 画像URL保存用
567                 
568                 // 商品の詳細情報を取得
569                 $ret = $this->db->getProductBySerial($fetchedRow['pt_serial'], $row, $row2, $row3, $row4);
570                 if ($ret){      
571                         // 価格を取得
572                         $priceArray = $this->getPrice($row2, self::STANDARD_PRICE);
573                         $price = $priceArray['pp_price'];       // 価格
574                         $currency = $priceArray['pp_currency_id'];      // 通貨
575                         $taxType = $row['pt_tax_type_id'];                                      // 税種別
576                         $lang = $row['pt_language_id'];                                 // 言語
577                         $prePrice = $this->convertToDispString($priceArray['cu_symbol']);
578                         $postPrice = $this->convertToDispString($priceArray['cu_post_symbol']);
579
580                         // 表示額作成
581                         $this->ecObj->setCurrencyType($currency, $lang);                // 通貨設定
582                         $this->ecObj->setTaxType($taxType, $lang);              // 税種別設定
583                         $totalPrice = $this->ecObj->getPriceWithTax($price, $dispPrice);        // 税込み価格取得
584                         
585                         // 画像を取得
586                         $imageArray = $this->getImage($row3, self::PRODUCT_IMAGE_SMALL);// 商品画像小
587                         $imageUrl_s = $imageArray['im_url'];    // URL
588                         $imageArray = $this->getImage($row3, self::PRODUCT_IMAGE_MEDIUM);// 商品画像中
589                         $imageUrl_m = $imageArray['im_url'];    // URL
590                         $imageArray = $this->getImage($row3, self::PRODUCT_IMAGE_LARGE);// 商品画像大
591                         $imageUrl_l = $imageArray['im_url'];    // URL
592                         
593                         // 画像を配列に保存
594                         $images[] = $imageUrl_s;
595                         $images[] = $imageUrl_m;
596                         $images[] = $imageUrl_l;
597                                                 
598                         // 商品ステータスを取得
599                         $statusArray = $this->getStatus($row4, self::PRODUCT_STATUS_NEW);// 新規
600                         $new = $statusArray['ps_value'];
601                         $statusArray = $this->getStatus($row4, self::PRODUCT_STATUS_SUGGEST);// おすすめ
602                         $suggest = $statusArray['ps_value'];
603                 }
604                 // 画像中
605                 $destImg_m = '';
606                 if ($this->viewStyle == self::VIEW_STYLE_MEDIUM){
607                         $imageUrl = $this->getProperImage($images, 1);
608                         $imageUrl_m = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getRootUrl(), $imageUrl);
609                         $imagePath_m = str_replace(M3_TAG_START . M3_TAG_MACRO_ROOT_URL . M3_TAG_END, $this->gEnv->getSystemRootPath(), $imageUrl);
610                         if (!file_exists($imagePath_m)){
611                                 $imageUrl_m = $this->getProductImageUrl('0_' . $this->defaultImageMWidth . 'x' . $this->defaultImageMHeight . self::DEFAULT_PRODUCT_IMAGE_TYPE);
612                         }
613                         $destImg_m = '<img class="product_image_medium" src="' . $this->getUrl($imageUrl_m) . '" ';
614                         $destImg_m .= 'width="' . $this->defaultImageMWidth . '"';
615                         $destImg_m .= ' height="' . $this->defaultImageMHeight . '"';
616                         $destImg_m .= ' />';
617                 }
618                 // 項目選択のラジオボタンの状態
619                 $id = $this->convertToDispString($row['pt_id']);
620                 $selected = '';
621                 if ($id == $this->productId){
622                         $selected = 'checked';
623                 }
624                 
625                 $visible = '';
626                 if ($row['pt_visible']){        // 項目の表示
627                         $visible = 'checked';
628                 }
629                 
630                 // 商品詳細リンクを作成
631                 $name = '詳細';               // 名前
632                 //$linkUrl = $this->gEnv->getDefaultUrl() . '?' . M3_REQUEST_PARAM_PRODUCT_ID . '=' . $row['pt_id'];
633                 $linkUrl = $this->currentPageUrl;
634                 if (!empty($this->categoryId)) $linkUrl .= '&category=' . $this->categoryId;
635                 $linkUrl .= '&' . M3_REQUEST_PARAM_PRODUCT_ID . '=' . $row['pt_id'];
636                 $link = '<a href="' . $this->getUrl($linkUrl, true) . '" >' . $name . '</a>';
637                 
638                 // 画像にリンクを付ける
639 //              if (!empty($destImg_s)) $destImg_s = '<a href="' . $this->getUrl($linkUrl, true) . '" >' . $destImg_s . '</a>';
640                 if (!empty($destImg_m)) $destImg_m = '<a href="' . $this->getUrl($linkUrl, true) . '" >' . $destImg_m . '</a>';
641                 
642                 // 在庫表示
643                 if ($this->showStock){                          // 在庫表示する場合
644                         $stockCount = intval($row['pe_stock_count']);           // 表示在庫数
645                         if (empty($stockViewFormat)) $stockViewFormat = self::DEFAULT_STOCK_VIEW_FORMAT;                // フォーマットが空の場合はデフォルトフォーマットで表示
646
647                         // 在庫表示用メッセージを取得
648                         $stockMsgArray = parseUserCustomParam($stockViewFormat);        // メッセージを配列化
649
650                         $stockMsg = '--該当なし--';
651                         $foreValue = -1;
652                         for ($i = 0; $i < count($stockMsgArray); $i++){
653                                 if ($stockMsgArray[$i]->key == '' || ($foreValue < $stockCount && $stockCount <= $stockMsgArray[$i]->key)) break;
654                                 $foreValue = $stockMsgArray[$i]->key;
655                         }
656                         if ($i < count($stockMsgArray)){
657                                 $stockMsg = str_replace('$1', $stockCount, $stockMsgArray[$i]->value);
658                         }
659                         
660                         $this->tmpl->clearTemplate('show_stock');
661                         $stockRow = array(
662                                 'stock' => '在庫: ' . $stockMsg                     // 在庫数表示
663                         );
664                         $this->tmpl->addVars('show_stock', $stockRow);
665                         $this->tmpl->parseTemplate('show_stock', 'a');
666                         
667                         // 在庫なし時のメッセージ表示
668                         if ($stockCount <= 0){          // 在庫ない場合   
669                                 $this->tmpl->addVar('cart_option', 'carttype', 'content');              // コンテンツ表示
670                                 $this->tmpl->addVar("cart_option", 'content', $this->contentNoStock);
671                         }
672                 }
673                 $this->tmpl->addVar("cart_option", 'id', $id);
674                 
675                 $itemRow = array(
676                         'no' => $index + 1,                                                                                                     // 行番号
677                         'serial' => $this->convertToDispString($row['pt_serial']),      // シリアル番号
678                         'id' => $id,                    // ID
679 //                      'image_s' => $destImg_s,                // 画像
680                         'image_m' => $destImg_m,                // 画像
681                         'image_l_url' => $this->getUrl($imageUrl_l),            // ツールチップ用画像URL
682                         'name' => $this->convertToDispString($row['pt_name']),          // 名前
683                         'code' => $this->convertToDispString($row['pt_code']),          // 商品コード
684                         'disp_total_price' => $prePrice . $dispPrice . $postPrice,                              // 税込み価格
685                         'description_short' => $row['pt_description_short'],                            // 簡易説明
686                         'product_link' => $link                                                                                         // 商品詳細リンク
687                 );
688                 $this->tmpl->addVars('productlist', $itemRow);
689                 $this->tmpl->parseTemplate('productlist', 'a');
690                 
691                 // 表示中のコンテンツIDを保存
692                 $this->dispContIdArray[] = $row['pt_id'];
693                 
694                 $this->productExists = true;                            // 商品が存在するかどうか
695                 return true;
696         }
697         /**
698          * 価格取得
699          *
700          * @param array         $srcRows                        価格リスト
701          * @param string        $priceType                      価格のタイプ
702          * @return array                                                取得した価格行
703          */
704         function getPrice($srcRows, $priceType)
705         {
706                 for ($i = 0; $i < count($srcRows); $i++){
707                         if ($srcRows[$i]['pp_price_type_id'] == $priceType){
708                                 return $srcRows[$i];
709                         }
710                 }
711                 return array();
712         }
713         /**
714          * 画像取得
715          *
716          * @param array         $srcRows                        画像リスト
717          * @param string        $imageType                      画像タイプ
718          * @return array                                                取得した行
719          */
720         function getImage($srcRows, $sizeType)
721         {
722                 for ($i = 0; $i < count($srcRows); $i++){
723                         if ($srcRows[$i]['im_size_id'] == $sizeType){
724                                 return $srcRows[$i];
725                         }
726                 }
727                 return array();
728         }
729         /**
730          * 商品ステータス取得
731          *
732          * @param array         $srcRows                        取得行
733          * @param string        $type                   商品ステータスタイプ
734          * @return array                                                取得した行
735          */
736         function getStatus($srcRows, $type)
737         {
738                 for ($i = 0; $i < count($srcRows); $i++){
739                         if ($srcRows[$i]['ps_type'] == $type){
740                                 return $srcRows[$i];
741                         }
742                 }
743                 return array();
744         }
745         /**
746          * 最適な画像を取得
747          *
748          * @param array         $images                 画像へのパス(優先順)
749          * @param int           $index                  目的の画像のインデックス番号
750          * @return string                                       パス
751          */
752         function getProperImage($images, $index)
753         {
754                 // 指定画像が存在する場合はそのまま返す
755                 if (!empty($images[$index])) return $images[$index];
756                 
757                 for ($i = $index + 1; $i < count($images); $i++){
758                         if (!empty($images[$i])) return $images[$i];
759                 }
760                 for ($i = 0; $i < $index; $i++){
761                         if (!empty($images[$i])) return $images[$i];
762                 }
763                 return '';
764         }
765         /**
766          * 商品画像URL取得
767          *
768          * @param string $filename              ファイル名
769          * @return string                               URL
770          */
771         function getProductImageUrl($filename)
772         {
773                 return $this->gEnv->getResourceUrl() . self::PRODUCT_IMAGE_DIR . $filename;
774         }
775         /**
776          * サブカテゴリーを取得
777          *
778          * @param array $category               カテゴリー
779          * @return array                                すべてのカテゴリーID
780          */
781         function getSubCategory($category, $level = 0)
782         {
783                 if (empty($category)) return array();
784                 
785                 $destCategory = $category;
786                 
787                 for ($i = 0; $i < count($category); $i++){
788                         $addCategory = $this->_getChildCategory($category[$i]);
789                         $destCategory = array_merge($destCategory, $addCategory);
790                 }
791                 return $destCategory;
792         }
793         /**
794          * サブカテゴリーを取得
795          *
796          * @param int $categoryId               カテゴリーId
797          * @return array                                すべてのカテゴリーID
798          */
799         function _getChildCategory($categoryId, $level = 0)
800         {
801                 $destCategory = array();
802                 
803                 // メニューの階層を制限
804                 if ($level >= self::MAX_CATEGORY_LEVEL) return $destCategory;
805                 $level++;
806                 
807                 // 子カテゴリーを取得
808                 $ret = $this->db->getChildCategory($categoryId, $this->langId, $rows);
809                 if ($ret){
810                         for ($i = 0; $i < count($rows); $i++){
811                                 $childCategory = $rows[$i]['pc_id'];
812                                 if (!in_array($childCategory, $destCategory)){
813                                         $addCategoryArray = $this->_getChildCategory($childCategory, $level);
814                                         for ($j = 0; $j < count($addCategoryArray); $j++){
815                                                 $addCategory = $addCategoryArray[$j];
816                                                 if (!in_array($addCategory, $destCategory)) $destCategory[] = $addCategory;
817                                         }
818                                         $destCategory[] = $childCategory;
819                                 }
820                         }
821                 }
822                 return $destCategory;
823         }
824 }
825 ?>