7 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
9 * @package Magic3 Framework
10 * @author 平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
11 * @copyright Copyright 2006-2012 Magic3 Project.
12 * @license http://www.gnu.org/copyleft/gpl.html GPL License
13 * @version SVN: $Id: s_photoTopWidgetContainer.php 5602 2013-02-06 14:17:57Z fishbone $
14 * @link http://www.magic3.org
16 require_once($gEnvManager->getCurrentWidgetContainerPath() . '/s_photoBaseWidgetContainer.php');
17 require_once($gEnvManager->getCurrentWidgetDbPath() . '/s_photoDb.php');
18 require_once($gEnvManager->getCurrentWidgetDbPath() . '/s_photo_categoryDb.php');
19 require_once($gEnvManager->getCurrentWidgetDbPath() . '/s_photo_commentDb.php');
20 require_once($gEnvManager->getCommonPath() . '/valueCheck.php');
22 class s_photoTopWidgetContainer extends s_photoBaseWidgetContainer
24 private $db; // DB接続オブジェクト
25 private $categoryDb; // DB接続オブジェクト
26 private $serialArray = array(); // 表示されている項目シリアル番号
27 private $photoArray; // 取得した写真
28 private $thumbnailSize; // デフォルトサムネールサイズ
29 private $thumbailSizeArray; // サムネールサイズ
30 private $notfoundThumbnailUrl; // サムネール画像が見つからない場合の画像
31 private $viewCount; // 表示項目数
32 private $viewOrder; // 表示順
33 private $shortTitleLength; // 略式写真タイトルの長さ
34 private $photoId; // 写真ID
35 private $startNo; // 先頭項目番号
36 private $currentDay; // 現在日
37 private $currentHour; // 現在時間
38 private $fieldInfoArray; // 検索条件項目
39 private $categoryInfoArray; // カテゴリー表示情報
40 private $categoryArray; // 選択中のカテゴリー
41 private $authorArray; // 選択中の著作者
42 private $sortKey; // ソートキー
43 private $sortDirection; // ソート方向
44 private $menuAuthorRows; // メニュー用の著作者情報
45 private $authCategory; // 参照可能なカテゴリー
46 private $authCategoryStr; // 参照可能なカテゴリー(表示用)
47 private $ecObj; // EC共通ライブラリオブジェクト
48 private $isExistsProduct; // 商品が存在するかどうか
49 private $prePrice; // 価格表示用
50 private $postPrice; // 価格表示用
51 private $categoryWithPwdArray; // パスワードが必要なカテゴリー
52 const CSS_FILE = '/style.css'; // CSSファイルのパス
53 const NOT_FOUND_ICON_FILE = '/images/system/notfound128.gif'; // 写真が見つからないアイコン
54 const BACK_ICON_FILE = '/images/system/back.png'; // 「戻る」アイコン
55 const PREV_ICON_FILE = '/images/system/previous.png'; // 「前へ」アイコン
56 const NEXT_ICON_FILE = '/images/system/next.png'; // 「次へ」アイコン
57 const PERMALINK_ICON_FILE = '/images/system/permalink.png'; // 「パーマリンク」アイコン
58 const LOAD_ICON_FILE = '/loader.gif'; // ロード中アイコン
59 const RATY_IMAGE_DIR = '/jquery/raty/img'; // jquery.raty画像パス
60 const LINK_PAGE_COUNT = 3; // リンクページ数
61 const BACK_BUTTON_TITLE = '戻る'; // 「戻る」ボタンタイトル
62 const PREV_BUTTON_TITLE = '前へ'; // 「前へ」ボタンタイトル
63 const NEXT_BUTTON_TITLE = '次へ'; // 「次へ」ボタンタイトル
64 const SEARCH_FIELD_HEAD = 'photo_main_item'; // フィールド名の先頭文字列
65 const SEARCH_FIELD_CLASS_HEAD = 'photo_main_'; // フィールドクラスの先頭文字列
66 const TARGET_WIDGET = 'photo_shop'; // 画像購入ウィジェット
67 const PRODUCT_CLASS = 'photo'; // 商品クラス
68 const TAX_TYPE = 'sales'; // 課税タイプ(外税)
69 const PRODUCT_TYPE_DOWNLOAD = 'download'; // 商品タイプ
70 const STANDARD_PRICE = 'selling'; // 通常価格
71 const PRICE_OBJ_ID = "eclib"; // 価格計算オブジェクトID
72 const DEFAULT_CURRENCY = 'JPY'; // デフォルト通貨
77 function __construct()
80 parent::__construct();
83 $this->notfoundThumbnailUrl = $this->getUrl($this->gEnv->getRootUrl() . self::NOT_FOUND_ICON_FILE);
88 * _assign()でデータを埋め込むテンプレートファイルのファイル名を返す。
89 * 読み込むディレクトリは、「自ウィジェットディレクトリ/include/template」に固定。
91 * @param RequestManager $request HTTPリクエスト処理クラス
92 * @param object $param 任意使用パラメータ。そのまま_assign()に渡る
93 * @return string テンプレートファイル名。テンプレートライブラリを使用しない場合は空文字列「''」を返す。
95 function _setTemplate($request, &$param)
97 $this->photoId = $request->trimValueOf(M3_REQUEST_PARAM_PHOTO_ID);
98 if (empty($this->photoId)) $this->photoId = $request->trimValueOf(M3_REQUEST_PARAM_PHOTO_ID_SHORT); // 略式ID
100 $act = $request->trimValueOf('act');
101 if ($act == 'search'){
102 return 'main_list.tmpl.html';
103 } else if ($act == 'inputcart'){ // カートに入れる
106 if (empty($this->photoId)){
107 return 'main_list.tmpl.html';
109 return 'photo_detail.tmpl.html';
116 * _setTemplate()で指定したテンプレートファイルにデータを埋め込む。
118 * @param RequestManager $request HTTPリクエスト処理クラス
119 * @param object $param 任意使用パラメータ。_setTemplate()と共有。
122 function _assign($request, &$param)
125 $now = date("Y/m/d H:i:s"); // 現在日時
126 $this->currentDay = date("Y/m/d"); // 日
127 $this->currentHour = (int)date("H"); // 時間
128 $this->currentPageUrl = $this->gEnv->createCurrentPageUrl();// 現在のページURL
130 $this->viewCount = self::$_configArray[photoCommonDef::CF_PHOTO_LIST_ITEM_COUNT]; // 表示項目数
131 $this->viewOrder = self::$_configArray[photoCommonDef::CF_PHOTO_LIST_ORDER]; // 表示順
132 $this->shortTitleLength = self::$_configArray[photoCommonDef::CF_PHOTO_TITLE_SHORT_LENGTH]; // 略式写真タイトルの長さ
135 $act = $request->trimValueOf('act');
137 if ($act == 'getlist'){ // 画像一覧Ajax取得
138 $this->getList($request);
139 } else if ($act == 'getdetail'){// 画像詳細Ajax取得
140 $this->getDetail($request);
141 } else if ($act == 'rate'){// 評価コメント投票
142 $this->rate($request);
143 } else if ($act == 'inputcart'){ // カートに入れる
144 $this->inputCart($request);
145 } else if ($act == 'downloadimage'){ // 画像ダウンロード
146 $this->downloadImage($request);
148 if (empty($this->photoId)){
149 $this->showList($request);
151 $this->showDetail($request);
156 * JavascriptライブラリをHTMLヘッダ部に設定
158 * JavascriptライブラリをHTMLのheadタグ内に追加出力する。
159 * _assign()よりも後に実行される。
161 * @param RequestManager $request HTTPリクエスト処理クラス
162 * @param object $param 任意使用パラメータ。
163 * @return string,array Javascriptライブラリ。出力しない場合は空文字列を設定。
165 function _addScriptLibToHead($request, &$param)
167 // 画像カテゴリーのパスワード制御を行う場合は暗号化ライブラリを追加
168 if (empty(self::$_configArray[photoCommonDef::CF_PHOTO_CATEGORY_PASSWORD])){
175 * CSSファイルをHTMLヘッダ部に設定
177 * CSSファイルをHTMLのheadタグ内に追加出力する。
178 * _assign()よりも後に実行される。
180 * @param RequestManager $request HTTPリクエスト処理クラス
181 * @param object $param 任意使用パラメータ。
182 * @return string CSS文字列。出力しない場合は空文字列を設定。
184 function _addCssFileToHead($request, &$param)
186 return $this->getUrl($this->gEnv->getCurrentWidgetCssUrl() . self::CSS_FILE);
191 * @param RequestManager $request HTTPリクエスト処理クラス
194 function showList($request)
197 $this->categoryDb = new s_photo_categoryDb();
200 $paramObj = $this->getWidgetParamObj();
201 if (empty($paramObj)){ // 保存値がないとき
202 $this->fieldInfoArray = array(); // 項目定義
205 $searchTemplate = $this->getParsedTemplateData(photoCommonDef::DEFAULT_SEARCH_AREA_TMPL, array($this, '_makeSearcheTemplate'));// デフォルト用の検索テンプレート
207 $searchTemplate = $paramObj->searchTemplate; // 検索用テンプレート
208 if (!empty($paramObj->fieldInfo)) $this->fieldInfoArray = $paramObj->fieldInfo; // 項目定義
211 $menuCategoryArray = array(); // メニュー項目用カテゴリー
212 $fieldCount = count($this->fieldInfoArray); // 検索項目数
213 for ($i = 0; $i < $fieldCount; $i++){
215 $itemType = $this->fieldInfoArray[$i]->itemType;
216 $itemCategory = $this->fieldInfoArray[$i]->category;
217 if ($itemType == 'category'){
218 if (!empty($itemCategory) && !in_array($itemCategory, $menuCategoryArray)) $menuCategoryArray[] = $itemCategory; // 親カテゴリー
219 //if (!in_array($itemCategory, $menuCategoryArray)) $menuCategoryArray[] = $itemCategory; // 親カテゴリー
224 $keyword = $request->trimValueOf(M3_REQUEST_PARAM_KEYWORD); // 検索キーワード
225 $paramPageNo = $request->trimValueOf(M3_REQUEST_PARAM_PAGE_NO); // ページ番号パラメータ
226 $pageNo = $request->trimIntValueOf(M3_REQUEST_PARAM_PAGE_NO, '1'); // ページ番号
227 $category = $request->trimValueOf('category'); // カテゴリー
228 $author = $request->trimValueOf('author'); // 著作者
229 $sort = $request->trimValueOf('sort'); // ソート順
230 $act = $request->trimValueOf('act');
232 // 画像カテゴリーにパスワード制限を掛けている場合の処理
233 if (!empty(self::$_configArray[photoCommonDef::CF_PHOTO_CATEGORY_PASSWORD])){
234 $this->authCategory = array(); // 参照可能なカテゴリー
237 $cid = $this->gAccess->getClientId();
239 // クライアントパラメータオブジェクトを取得
240 $clientObj = $this->getClientParamObj($cid, $this->gEnv->getCurrentWidgetId());
241 if (!empty($clientObj) && !empty($clientObj->authCategory)){
242 $this->authCategory = explode(',', $clientObj->authCategory);
245 if ($act == 'addcategory'){ // 参照カテゴリー追加のとき
246 $accessCategoryId = $request->trimValueOf('access_category'); // 参照するカテゴリー
247 $password = $request->trimValueOf('password');
249 // 画像カテゴリーのパスワードをチェック
250 $ret = $this->categoryDb->getCategoryByCategoryId($accessCategoryId, $this->_langId, $row);
251 if ($ret && !empty($row['hc_password']) && $row['hc_password'] == $password){
253 if (!in_array($accessCategoryId, $this->authCategory)) $this->authCategory[] = $accessCategoryId;
256 $clientObj->authCategory = implode(',', $this->authCategory);
257 $ret = $this->updateClientParamObj($cid, $this->gEnv->getCurrentWidgetId(), $clientObj);
258 $this->setGuidanceMsg('認証に成功しました');
260 // 認証に失敗した画像カテゴリーは削除する
261 $destAuthCategory = array();
262 for ($i = 0; $i < count($this->authCategory); $i++){
263 if ($this->authCategory[$i] != $accessCategoryId) $destAuthCategory[] = $this->authCategory[$i];
265 $this->authCategory = $destAuthCategory;
268 $clientObj->authCategory = implode(',', $this->authCategory);
269 $ret = $this->updateClientParamObj($cid, $this->gEnv->getCurrentWidgetId(), $clientObj);
270 $this->setAppErrorMsg('認証に失敗しました');
274 $this->tmpl->setAttribute('category_script', 'visibility', 'visible'); // 画像カテゴリースクリプト表示
275 // $this->tmpl->setAttribute('category_area', 'visibility', 'visible'); // 画像カテゴリーエリア表示
277 // // 画像カテゴリー選択メニュー作成
278 // $this->authCategoryStr = '';
279 // $this->categoryDb->getAllCategory($this->_langId, array($this, 'categoryListLoop'), true);
282 // $this->authCategoryStr = rtrim($this->authCategoryStr, ', ');
283 // $this->tmpl->addVar("category_area", "auth_category_list", $this->convertToDispString($this->authCategoryStr));
285 $this->categoryWithPwdArray = array(); // パスワードが必要なカテゴリー
286 $this->authCategoryStr = '';
287 $this->categoryDb->getAllCategory($this->_langId, array($this, 'categoryListLoop'), true);
289 $categoryWithPwdCount = count($this->categoryWithPwdArray);
290 if ($categoryWithPwdCount > 1){ // パスワードが必要なカテゴリーが複数の場合
291 // 認証されていないカテゴリーがある場合のみ表示
292 for ($i = 0; $i < $categoryWithPwdCount; $i++){
293 if (!in_array($this->categoryWithPwdArray[$i], $this->authCategory)) break; // 認証されていないとき
295 if ($i < $categoryWithPwdCount){
296 $this->tmpl->setAttribute('category_area', 'visibility', 'visible'); // 画像カテゴリーエリア表示
299 $this->authCategoryStr = rtrim($this->authCategoryStr, ', ');
300 $this->tmpl->addVar("category_area", "auth_category_list", $this->convertToDispString($this->authCategoryStr));
302 } else if ($categoryWithPwdCount == 1){ // 参照可能なカテゴリーが単数のとき
303 if (!in_array($this->categoryWithPwdArray[0], $this->authCategory)){ // 認証されていないとき
304 $this->tmpl->addVar("single_category_area", "value", $this->convertToDispString($this->categoryWithPwdArray[0]));
305 $this->tmpl->setAttribute('single_category_area', 'visibility', 'visible'); // 画像カテゴリーエリア表示
311 $this->checkInputValues($category, $author, $sort);
314 $urlParams = $this->createUrlParams($keyword, $category, $author, $sort);
317 $parsedKeywords = $this->gInstance->getTextConvManager()->parseSearchKeyword($keyword);
319 // ##### 検索キーワードを記録 #####
320 if (empty($paramPageNo)){ // 検索を実行した時点のみ記録
321 for ($i = 0; $i < count($parsedKeywords); $i++){
322 $this->gInstance->getAnalyzeManager()->logSearchWord($this->gEnv->getCurrentWidgetId(), $parsedKeywords[$i]);
327 $limitedCategory = $this->authCategory;
328 if (!is_null($limitedCategory) && count($limitedCategory) == 0) $limitedCategory = array('0'); // 空の場合はダミーのカテゴリーIDを追加
329 $totalCount = self::$_mainDb->searchPhotoItemCount($this->_langId, null/*開始日時*/, null/*終了日時*/, $parsedKeywords/*キーワード*/,
330 $this->categoryArray/*カテゴリー*/, $this->authorArray/*撮影者*/, $limitedCategory);
333 $this->calcPage($pageNo, $totalCount, $this->viewCount, $pageCount, $startNo, $endNo);
335 // 検索条件を設定した場合で画像数が0のときはメッセージ表示
336 if ($startNo > $endNo){
337 if (!empty($parsedKeywords) || !empty($this->categoryArray) || !empty($this->authorArray)) $this->setUserErrorMsg('画像が見つかりません');
341 $pageLink = $this->createPageLink($pageNo, $pageCount, self::LINK_PAGE_COUNT, $this->gEnv->createCurrentPageUrl(), $urlParams);
342 if (!empty($pageLink)){
343 $this->tmpl->setAttribute('page_link_top', 'visibility', 'visible'); // リンク表示
344 $this->tmpl->setAttribute('page_link_bottom', 'visibility', 'visible'); // リンク表示
345 $this->tmpl->addVar("page_link_top", "page_link", $pageLink);
346 $this->tmpl->addVar("page_link_bottom", "page_link", $pageLink);
350 $ajaxUrl = 'act=getlist&' . M3_REQUEST_PARAM_PAGE_NO . '=' . $pageNo . $urlParams;
353 $ret = $this->categoryDb->getAllCategoryForMenu($this->_langId, $menuCategoryArray, $rows);
356 $parentCategory = '';
357 $rowCount = count($rows);
358 for ($i = 0; $i < $rowCount; $i++){
360 if ($parentCategory == $line['hc_parent_id']){
361 $category[] = array('name' => $line['hc_name'], 'value' => $line['hc_id']);
363 if (!empty($category)) $this->categoryInfoArray[$parentCategory] = $category;
364 $parentCategory = $line['hc_parent_id'];
366 $category[] = array('name' => $line['hc_name'], 'value' => $line['hc_id']);
369 if (!empty($category)) $this->categoryInfoArray[$parentCategory] = $category;
372 // ##### 検索画面作成 #####
373 if (!empty(self::$_configArray[photoCommonDef::CF_PHOTO_CATEGORY_PASSWORD]) && empty($this->authCategory)){// 画像カテゴリーのパスワード制限ありで参照可能カテゴリーがないとき
374 $fieldOutput = ''; // 検索画面なし
376 $fieldOutput = $this->createFieldOutput($searchTemplate);
378 if (!empty($fieldOutput)){
379 $this->tmpl->setAttribute('search_area', 'visibility', 'visible'); // 検索エリア表示
380 $this->tmpl->addVar("search_area", "html", $fieldOutput);
381 $this->tmpl->addVar("search_area", "search_form_id", photoCommonDef::SEARCH_FORM_ID); // 検索フォームのタグID
383 $this->tmpl->addVar("_widget", "search_text_id", photoCommonDef::SEARCH_TEXT_ID); // 検索用テキストフィールドのタグID
384 $this->tmpl->addVar("_widget", "search_button_id", photoCommonDef::SEARCH_BUTTON_ID); // 検索用ボタンのタグID
385 $this->tmpl->addVar("_widget", "search_reset_id", photoCommonDef::SEARCH_RESET_ID); // 検索エリアリセットボタンのタグID
386 $this->tmpl->addVar("_widget", "search_sort_id", photoCommonDef::SEARCH_SORT_ID); // 検索エリアソート順のタグID
387 $this->tmpl->addVar("_widget", "search_form_id", photoCommonDef::SEARCH_FORM_ID); // 検索フォームのタグID
388 $this->tmpl->addVar("_widget", "keyword", addslashes($keyword)); // 検索キーワード(Javascript部)
389 $this->tmpl->addVar("_widget", "sort", $this->sortKey . '-' . $this->sortDirection); // デフォルトのソート順
391 $this->tmpl->setAttribute('search_script', 'visibility', 'visible'); // 検索エリア表示
392 $this->tmpl->addVar("search_script", "search_url", $this->getUrl($this->currentPageUrl));
393 $this->tmpl->addVar("search_script", "search_text_id", photoCommonDef::SEARCH_TEXT_ID); // 検索用テキストフィールドのタグID
394 $this->tmpl->addVar("search_script", "search_button_id", photoCommonDef::SEARCH_BUTTON_ID); // 検索用ボタンのタグID
395 $this->tmpl->addVar("search_script", "search_reset_id", photoCommonDef::SEARCH_RESET_ID); // 検索エリアリセットボタンのタグID
396 $this->tmpl->addVar("search_script", "search_sort_id", photoCommonDef::SEARCH_SORT_ID); // 検索エリアソート順のタグID
397 $this->tmpl->addVar("search_script", "search_form_id", photoCommonDef::SEARCH_FORM_ID); // 検索フォームのタグID
398 $this->tmpl->addVar("search_script", "keyword", addslashes($keyword)); // 検索キーワード(Javascript部)
399 $this->tmpl->addVar("search_script", "sort", $this->sortKey . '-' . $this->sortDirection); // デフォルトのソート順
403 $this->tmpl->addVar("_widget", "photo_count", $this->convertToDispString($this->viewCount));
404 $this->tmpl->addVar("_widget", "load_icon_url", $this->getUrl($this->gEnv->getCurrentWidgetImagesUrl() . self::LOAD_ICON_FILE)); // ロード中アイコン
405 $this->tmpl->addVar("_widget", "photo_detail_url", $this->getUrl($this->gEnv->getDefaultSmartphoneUrl(), true/*リンク用*/)); // 詳細画面へのリンク
406 $this->tmpl->addVar("_widget", "photo_detail_url_others", $urlParams); // 詳細画面へのリンクの付加URLパラメータ
407 $this->tmpl->addVar("_widget", "ajax_url", $ajaxUrl);
408 $this->tmpl->addVar('_widget', 'raty_image_url', $this->getUrl($this->gEnv->getScriptsUrl() . self::RATY_IMAGE_DIR)); // jquery.raty画像パス
413 * @param RequestManager $request HTTPリクエスト処理クラス
416 function getList($request)
418 $keyword = $request->trimValueOf(M3_REQUEST_PARAM_KEYWORD); // 検索キーワード
419 $pageNo = $request->trimIntValueOf(M3_REQUEST_PARAM_PAGE_NO, '1'); // ページ番号
420 $category = $request->trimValueOf('category'); // カテゴリー
421 $author = $request->trimValueOf('author'); // 著作者
422 $sort = $request->trimValueOf('sort'); // ソート順
424 // 画像カテゴリーにパスワード制限を掛けている場合の処理
425 if (!empty(self::$_configArray[photoCommonDef::CF_PHOTO_CATEGORY_PASSWORD])){
427 $this->authCategory = array();
428 $cid = $this->gAccess->getClientId(); // ブラウザのクライアントIDを取得
430 // クライアントパラメータオブジェクトを取得
431 $clientObj = $this->getClientParamObj($cid, $this->gEnv->getCurrentWidgetId());
432 if (!empty($clientObj) && !empty($clientObj->authCategory)){
433 $this->authCategory = explode(',', $clientObj->authCategory);
439 $this->checkInputValues($category, $author, $sort);
442 $urlParams = $this->createUrlParams($keyword, $category, $author, $sort);
445 $parsedKeywords = $this->gInstance->getTextConvManager()->parseSearchKeyword($keyword);
448 $this->thumbnailSize = intval(self::$_configArray[photoCommonDef::CF_DEFAULT_THUMBNAIL_SIZE]); // デフォルトサムネールサイズ
449 if ($this->thumbnailSize <= 0) $this->thumbnailSize = photoCommonDef::DEFAULT_THUMBNAIL_SIZE;
450 $this->thumbailSizeArray = trimExplode(',', self::$_configArray[photoCommonDef::CF_THUMBNAIL_SIZE]);
451 if (empty($this->thumbailSizeArray)) $this->thumbailSizeArray = array(photoCommonDef::DEFAULT_THUMBNAIL_SIZE);
454 $this->photoArray = array(); // 取得した写真
455 $this->startNo = $this->viewCount * ($pageNo -1) + 1;
456 $limitedCategory = $this->authCategory;
457 if (!is_null($limitedCategory) && count($limitedCategory) == 0) $limitedCategory = array('0'); // 空の場合はダミーのカテゴリーIDを追加
458 self::$_mainDb->searchPhotoItem($this->viewCount, $pageNo, $this->_langId, null/*開始日時*/, null/*終了日時*/, $parsedKeywords/*キーワード*/,
459 $this->categoryArray/*カテゴリー*/, $this->authorArray/*撮影者*/, $this->sortKey/*ソートキー*/, $this->sortDirection/*ソート方向*/,
460 array($this, 'viewListLoop'), $urlParams, $limitedCategory);
463 $this->gInstance->getAjaxManager()->addData('items', $this->photoArray);
464 $this->gInstance->getAjaxManager()->addData('pagecount', $pageCount); // 総ページ数
465 $this->gInstance->getAjaxManager()->addData('pageno', $pageNo); // 現在のページ番号
470 * @param RequestManager $request HTTPリクエスト処理クラス
473 function showDetail($request)
475 $commentDb = new s_photo_commentDb();
477 // 画像カテゴリーにパスワード制限を掛けている場合の処理
478 if (!empty(self::$_configArray[photoCommonDef::CF_PHOTO_CATEGORY_PASSWORD])){
480 $this->authCategory = array();
481 $cid = $this->gAccess->getClientId(); // ブラウザのクライアントIDを取得
483 // クライアントパラメータオブジェクトを取得
484 $clientObj = $this->getClientParamObj($cid, $this->gEnv->getCurrentWidgetId());
485 if (!empty($clientObj) && !empty($clientObj->authCategory)){
486 $this->authCategory = explode(',', $clientObj->authCategory);
491 $ret = self::$_mainDb->getSearchPhotoInfo($this->photoId, $this->_langId, $row, $categoryRows);
494 if (!is_null($this->authCategory)){
495 for ($i = 0; $i < count($categoryRows); $i++){
496 if (in_array($categoryRows[$i]['hc_id'], $this->authCategory)) break;
498 if ($i == count($categoryRows)){
499 $this->setUserErrorMsg('画像が見つかりません');
500 $this->writeUserError(__METHOD__, '不正な画像アクセスを検出しました。画像タイトル=' . $row['ht_name'], 2200, '公開画像ID=' . $this->photoId);
506 $itemNo = $request->trimValueOf(M3_REQUEST_PARAM_ITEM_NO); // 画像No
507 if (!ValueCheck::isNumeric($itemNo)) $itemNo = 1;
508 $keyword = $request->trimValueOf(M3_REQUEST_PARAM_KEYWORD); // 検索キーワード
509 $pageNo = $request->trimIntValueOf(M3_REQUEST_PARAM_PAGE_NO, '1'); // ページ番号
510 $category = $request->trimValueOf('category'); // カテゴリー
511 $author = $request->trimValueOf('author'); // 著作者
512 $sort = $request->trimValueOf('sort'); // ソート順
515 $this->checkInputValues($category, $author, $sort);
518 $urlParams = $this->createUrlParams($keyword, $category, $author, $sort);
521 $parsedKeywords = $this->gInstance->getTextConvManager()->parseSearchKeyword($keyword);
524 $pageNo = intval(($itemNo -1) / $this->viewCount) + 1;
526 $title = $alt = $row['ht_name'];
527 $author = $row['lu_name'];
528 $date = $row['ht_date']; // 撮影日
531 $imageMaxSize = intval(self::$_configArray[photoCommonDef::CF_DEFAULT_IMAGE_SIZE]);
532 if ($imageMaxSize <= 0) $imageMaxSize = photoCommonDef::DEFAULT_IMAGE_SIZE;
533 list($width, $height) = explode('x', $row['ht_image_size']);
534 if ($width > $height){
535 $height = round(($height / $width) * $imageMaxSize);
536 $width = $imageMaxSize;
538 $width = round(($width / $height) * $imageMaxSize);
539 $height = $imageMaxSize;
541 if (empty($width) || empty($height)){
542 $width = $height = $imageMaxSize;
546 $imagePath = photoCommonDef::getPublicImagePath($this->photoId);
547 if (file_exists($imagePath)){
548 $imageUrl = photoCommonDef::getPublicImageUrl($this->photoId);
550 $imageUrl = $this->notfoundThumbnailUrl;
554 $permaUrl = $this->getUrl($this->gEnv->getDefaultSmartphoneUrl() . '?'. M3_REQUEST_PARAM_PHOTO_ID . '=' . $this->photoId);
555 $permaLink = '<a href="' . $this->convertUrlToHtmlEntity($permaUrl) . '" data-ajax="false"><img src="' . $this->getUrl($this->gEnv->getRootUrl() . self::PERMALINK_ICON_FILE) .
556 '" width="' . photoCommonDef::BUTTON_ICON_SIZE . '" height="' . photoCommonDef::BUTTON_ICON_SIZE . '" title="パーマリンク" alt="パーマリンク" style="border:none;margin:0;padding:0;" /></a>';
559 $this->startNo = $request->trimIntValueOf(M3_REQUEST_PARAM_ITEM_NO, '1');
560 $limitedCategory = $this->authCategory;
561 if (!is_null($limitedCategory) && count($limitedCategory) == 0) $limitedCategory = array('0'); // 空の場合はダミーのカテゴリーIDを追加
562 self::$_mainDb->searchPhotoItemByNo(3, $this->startNo -1, $this->_langId, null/*開始日時*/, null/*終了日時*/, $parsedKeywords/*キーワード*/,
563 $this->categoryArray/*カテゴリー*/, $this->authorArray/*撮影者*/, $this->sortKey/*ソートキー*/, $this->sortDirection/*ソート方向*/,
564 array($this, 'prevNextListLoop'), $urlParams, $limitedCategory);
567 $backUrl = $this->currentPageUrl;
568 if ($pageNo > 1) $backUrl .= '&' . M3_REQUEST_PARAM_PAGE_NO . '=' . $pageNo;
569 $backUrl .= $urlParams;
573 for ($i = 0; $i < count($categoryRows); $i++){
574 if ($i > 0) $categoryStr .= ', ';
575 $categoryStr .= $categoryRows[$i]['hc_name'];
580 $ip = $this->gRequest->trimServerValueOf('REMOTE_ADDR');
581 $isRegistered = $commentDb->isExistsComment($this->photoId, $ip, $this->_langId);
582 if ($isRegistered) $rateDisabled = 'disabled';
585 $commentDb->getCommentByPublicPhotoId(photoCommonDef::DEFAULT_COMMENT_COUNT, 1/**/, $this->photoId, $this->_langId, array($this, 'commentListLoop'));
586 if (count($this->serialArray) == 0) $this->tmpl->setAttribute('itemlist', 'visibility', 'hidden');
589 $this->tmpl->setAttribute('photo_info_script', 'visibility', 'visible');
590 $this->tmpl->setAttribute('photo_info_area', 'visibility', 'visible');
593 if (!empty(self::$_configArray[photoCommonDef::CF_ONLINE_SHOP])){
594 $this->tmpl->setAttribute('product_script', 'visibility', 'visible');
595 $this->tmpl->setAttribute('product_info', 'visibility', 'visible');
598 if (!empty(self::$_configArray[photoCommonDef::CF_SELL_PRODUCT_PHOTO])){ // フォト関連商品販売をする場合
599 $this->ecObj = $this->gInstance->getObject(self::PRICE_OBJ_ID);
602 $ret = $this->ecObj->db->getCurrency(self::DEFAULT_CURRENCY, $this->_langId, $currencyRow);
604 $this->prePrice = $this->convertToDispString($currencyRow['cu_symbol']);
605 $this->postPrice = $this->convertToDispString($currencyRow['cu_post_symbol']);
608 self::$_mainDb->getAllProduct($this->_langId, array($this, 'productListLoop'));
609 if (empty($this->isExistsProduct)) $this->tmpl->setAttribute('product_list', 'visibility', 'hidden'); // 商品が存在しないとき
611 $this->tmpl->setAttribute('product_list', 'visibility', 'hidden');
615 if (!empty(self::$_configArray[photoCommonDef::CF_SELL_PRODUCT_DOWNLOAD])){ // ダウンロード販売をする場合
617 $canDownloadImage = false;
618 $ret = self::$_mainDb->getContentAccess($this->_userId, M3_VIEW_TYPE_PHOTO, $row['ht_id'], $accessRow);
620 if ($accessRow['cs_download']) $canDownloadImage = true;
623 if ($canDownloadImage){
624 $this->tmpl->setAttribute('product_download', 'visibility', 'visible');
626 $this->tmpl->setAttribute('product_cart', 'visibility', 'visible');
629 $this->tmpl->setAttribute('download_area', 'visibility', 'hidden');
633 $this->tmpl->addVar("photo_info_area", "photo_id", $this->photoId);
634 $this->tmpl->addVar("photo_info_area", "author", $this->convertToDispString($author));
635 $this->tmpl->addVar("photo_info_area", "place", $this->convertToDispString($row['ht_location']));
636 $this->tmpl->addVar("photo_info_area", "camera", $this->convertToDispString($row['ht_camera']));
637 $this->tmpl->addVar("photo_info_area", "note", $this->convertToDispString($row['ht_description']));
638 $this->tmpl->addVar("photo_info_area", "date", $this->convertToDispDate($date));
639 $this->tmpl->addVar("photo_info_area", "category", $this->convertToDispString($categoryStr));
640 $this->tmpl->addVar("photo_info_area", "img_url", $this->getUrl($imageUrl));
641 $this->tmpl->addVar("photo_info_area", "width", $width);
642 $this->tmpl->addVar("photo_info_area", "height", $height);
643 $this->tmpl->addVar("photo_info_area", "title", $this->convertToDispString($title));
644 $this->tmpl->addVar("photo_info_area", "permalink", $permaLink);
645 $this->tmpl->addVar("photo_info_area", "alt", $this->convertToDispString($alt));
646 $this->tmpl->addVar("photo_info_area", "back_url", $this->convertUrlToHtmlEntity($this->getUrl($backUrl, true/*リンク用*/)));// 「戻る」リンク
647 $this->tmpl->addVar("photo_info_area", "back_img_url", $this->getUrl($this->gEnv->getRootUrl() . self::BACK_ICON_FILE));// 「戻る」アイコン
648 $this->tmpl->addVar("photo_info_area", "icon_size", photoCommonDef::BUTTON_ICON_SIZE);
649 $this->tmpl->addVar("photo_info_area", "back_title", self::BACK_BUTTON_TITLE);
650 $this->tmpl->addVar("photo_info_area", "back_alt", self::BACK_BUTTON_TITLE);
652 $this->tmpl->addVar('photo_info_script', 'raty_image_url', $this->getUrl($this->gEnv->getScriptsUrl() . self::RATY_IMAGE_DIR)); // jquery.raty画像パス
653 $this->tmpl->addVar("photo_info_script", "init_rate", $this->convertToDispString($row['ht_rate_average'])); // 評価値
654 $this->tmpl->addVar("photo_info_area", "rate_disabled", $rateDisabled); // 「投票する」ボタン使用可否
655 $this->tmpl->addVar("photo_info_area", "comment_count", count($this->serialArray)); // コメント数
658 $postTicket = md5(time() . $this->gAccess->getAccessLogSerialNo());
659 $request->setSessionValue(M3_SESSION_POST_TICKET, $postTicket); // セッションに保存
660 $this->tmpl->addVar("photo_info_area", "ticket", $postTicket); // 画面に書き出し
663 if (!$this->gEnv->isSystemManageUser()){ // システム運用者以上の場合はカウントしない
665 $this->gInstance->getAnalyzeManager()->updateContentViewCount(photoCommonDef::REF_TYPE_CONTENT, $row['ht_id'], $this->currentDay, $this->currentHour);
668 self::$_mainDb->updatePhotoInfoViewCount($row['ht_serial']);
671 $this->setUserErrorMsg('画像が見つかりません');
677 * @param RequestManager $request HTTPリクエスト処理クラス
680 function getDetail($request)
686 * @param RequestManager $request HTTPリクエスト処理クラス
689 function rate($request)
691 $commentDb = new s_photo_commentDb();
692 $postTicket = $request->trimValueOf('ticket'); // POST確認用
693 $comment = $request->trimValueOf('comment');
694 $rateValue = $request->trimIntValueOf('value', '0');
695 $ip = $this->gRequest->trimServerValueOf('REMOTE_ADDR');
697 $retValue = 0; // 登録状況
698 if (!empty($postTicket) && $postTicket == $request->getSessionValue(M3_SESSION_POST_TICKET)){ // 正常なPOST値のとき
700 if (0 < $rateValue && $rateValue <= 5){
702 $isRegistered = $commentDb->isExistsComment($this->photoId, $ip, $this->_langId);
704 $ret = $commentDb->addCommentItem($this->photoId, $this->_langId, $ip, $rateValue, $comment, $rateAverage, $newSerial);
705 if ($ret) $ret = $commentDb->getCommentBySerial($newSerial, $row);
707 $rateValue = $row['hr_rate_value']; // 評価値
708 $comment = $row['hr_message']; // コメント
709 $regDate = $this->convertToDispDateTime($row['hr_regist_dt'], 0, 10); // 登録日付
710 $retValue = 1; // 登録成功
715 $request->unsetSessionValue(M3_SESSION_POST_TICKET); // セッション値をクリア
718 $this->gInstance->getAjaxManager()->addData('result', $retValue);
719 $this->gInstance->getAjaxManager()->addData('rate_average', $rateAverage); // 評価集計値
720 $this->gInstance->getAjaxManager()->addData('rate_value', $rateValue); // 評価値
721 $this->gInstance->getAjaxManager()->addData('comment', $comment); // コメント
722 $this->gInstance->getAjaxManager()->addData('reg_date', $regDate); // 登録日付
727 * @param RequestManager $request HTTPリクエスト処理クラス
730 function inputCart($request)
732 // Eコマースライブラリオブジェクト取得
733 $ecLibObj = $this->gInstance->getObject(photoCommonDef::EC_LIB_OBJ_ID);
734 if (is_null($ecLibObj)) return;
737 $quantity = $request->trimIntValueOf('quantity', '1'); // 数量
740 if (!$this->isPublicPhotoId($this->photoId, $this->_langId)) return; // 画像が非公開の場合は終了
743 $productType = $request->trimValueOf('product');
744 if ($productType != self::PRODUCT_TYPE_DOWNLOAD){
745 $ret = self::$_mainDb->getProductByProductId($productType, $this->_langId, $row);
750 $cartId = $request->getCookieValue(M3_COOKIE_CART_ID);
751 if (empty($cartId)){ // カートIDが設定されていないとき
753 $cartId = $ecLibObj->createCartId();
755 $request->setCookieValue(M3_COOKIE_CART_ID, $cartId);
757 // ####### カートに商品を追加 ########
760 $cartSerial = 0; // カートシリアル番号
761 $cartItemSerial = 0; // カート商品シリアル番号
762 $ret = $ecLibObj->db->getCartHead($cartId, $this->_langId, $row);
764 $cartSerial = $row['sh_serial'];
767 $isValidItem = true; // 現在のカートのデータが有効かどうか
768 $ret = self::$_mainDb->getPhotoInfoWithPrice($this->photoId, self::PRODUCT_CLASS, $productType, self::STANDARD_PRICE, $this->_langId, $row);
771 $productId = $row['ht_id']; // 画像商品ID
772 $price = $row['pp_price']; // 価格
773 $currency = $row['pp_currency_id']; // 通貨
774 $taxType = self::TAX_TYPE; // 税種別
777 $ecLibObj->setCurrencyType($currency, $this->_langId); // 通貨設定
778 $ecLibObj->setTaxType($taxType, $this->_langId); // 税種別設定
779 $totalPrice = $ecLibObj->getPriceWithTax($price, $dispPrice); // 税込み価格取得
780 } else { // 商品情報が取得できないときは、カートの商品をキャンセル
781 $this->writeError(__METHOD__, '商品情報が取得できません。', 1100,
782 '商品クラス=' . self::PRODUCT_CLASS . ', 画像ID=' . $this->photoId . ', 商品タイプ=' . $productType);// 運用ログに記録
783 $isValidItem = false;
787 if ($isValidItem && $cartSerial > 0){
788 $ret = $ecLibObj->db->getCartItem($cartSerial, self::PRODUCT_CLASS, $productId, $productType, $cartItemRow);
789 if ($ret){ // 取得できたときは価格をチェック
790 if ($cartItemRow['si_available']){ // データが有効のとき
791 // 価格が変更されているときはカートの商品を無効にする
792 $cartItemCurrency = $cartItemRow['si_currency_id'];
793 $cartItemQuantity = $cartItemRow['si_quantity'];
794 $cartItemPrice = $cartItemRow['si_subtotal'];
795 $cartItemSerial = $cartItemRow['si_serial'];
797 if ($cartItemCurrency != $currency) $isValidItem = false; // 通貨が変更のときはレコードを無効化
798 if ($totalPrice * $cartItemQuantity != $cartItemPrice) $isValidItem = false; // 価格が変更のときはレコードを無効化
800 $isValidItem = false;
807 if ($productType != self::PRODUCT_TYPE_DOWNLOAD || $cartItemQuantity == 0){
809 $ret = $ecLibObj->db->addCartItem($cartSerial, $cartItemSerial, $cartId, self::PRODUCT_CLASS, $productId, $productType, $this->_langId,
810 $currency, $totalPrice, $quantity);
814 $ret = $ecLibObj->db->voidCartItem($cartSerial, $cartItemSerial);
817 $cartPage = $this->createCmdUrlToWidget(self::TARGET_WIDGET, 'task=cart');
818 $this->gPage->redirect($cartPage);
823 * @param RequestManager $request HTTPリクエスト処理クラス
826 function downloadImage($request)
828 $ret = self::$_mainDb->getSearchPhotoInfo($this->photoId, $this->_langId, $row, $categoryRows);
830 $this->gOpeLog->writeUserAccess(__METHOD__, '不正なダウンロードを検出しました。画像情報が取得できません。', 2200, 'ダウンロードをブロックしました。公開画像ID=' . $this->photoId);
835 $canDownloadImage = false;
836 $ret = self::$_mainDb->getContentAccess($this->_userId, M3_VIEW_TYPE_PHOTO, $row['ht_id'], $accessRow);
838 if ($accessRow['cs_download']) $canDownloadImage = true;
840 if (!$canDownloadImage){
841 $this->gOpeLog->writeUserAccess(__METHOD__, '不正なダウンロードを検出しました。ダウンロード権限がありません。', 2200, 'ダウンロードをブロックしました。画像コード=' . $row['ht_code']);
846 $this->gPage->abortPage();
850 $mimeType = $row['ht_mime_type'];
851 if ($mimeType == image_type_to_mime_type(IMAGETYPE_GIF)){
853 } else if ($mimeType == image_type_to_mime_type(IMAGETYPE_JPEG)){
855 } else if ($mimeType == image_type_to_mime_type(IMAGETYPE_PNG)){
857 } else if ($mimeType == image_type_to_mime_type(IMAGETYPE_BMP)){
860 $downloadFilename = strtr($row['ht_name'], ' ', '_') . $ext; // 半角スペースを「_」に変換
863 $imagePath = $this->gEnv->getIncludePath() . photoCommonDef::PHOTO_DIR . $row['ht_dir'] . DIRECTORY_SEPARATOR . $row['ht_public_id'];
864 if (file_exists($imagePath)){
865 $ret = $this->gPage->downloadFile($imagePath, $downloadFilename);
868 if (!$this->gEnv->isSystemManageUser()){ // システム運用者以上の場合はカウントしない
869 $this->gInstance->getAnalyzeManager()->updateContentViewCount(photoCommonDef::REF_TYPE_DOWNLOAD, $row['ht_id'], $this->currentDay, $this->currentHour);
872 $this->gInstance->getAnalyzeManager()->logContentDownload(M3_VIEW_TYPE_PHOTO, $row['ht_id']);
874 } else { // 画像がみつからない場合
875 $this->writeError(__METHOD__, '画像が見つからないため、ダウンロードできません。', 1100, '画像コード=' . $row['ht_code'] . ',ファイル名=' . $imagePath);
879 $this->gPage->exitSystem();
882 * 取得したコンテンツ項目をテンプレートに設定する
884 * @param int $index 行番号
885 * @param array $fetchedRow 取得行
886 * @param object $param 任意使用パラメータ
887 * @return bool trueを返すとループ続行。falseを返すとその時点で終了。
889 function viewListLoop($index, $fetchedRow, $param)
891 $thumbnailSize = $this->thumbnailSize;
893 // サムネール画像が存在するかどうかチェック
894 $thumbnailPath = photoCommonDef::getThumbnailPath($fetchedRow['ht_public_id'], $thumbnailSize);
895 if (file_exists($thumbnailPath)){
896 $thumbnailUrl = $this->getUrl(photoCommonDef::getThumbnailUrl($fetchedRow['ht_public_id'], $thumbnailSize));
899 for ($i = 0; $i < count($this->thumbailSizeArray); $i++){
900 $thumbnailSize = $this->thumbailSizeArray[$i];
901 $thumbnailPath = photoCommonDef::getThumbnailPath($fetchedRow['ht_public_id'], $thumbnailSize);
902 if (file_exists($thumbnailPath)){
903 $thumbnailUrl = $this->getUrl(photoCommonDef::getThumbnailUrl($fetchedRow['ht_public_id'], $thumbnailSize));
907 if ($i == count($this->thumbailSizeArray)){ // サムネールが見つからないとき
908 $thumbnailUrl = $this->notfoundThumbnailUrl;
909 $thumbnailSize = $this->thumbnailSize;
912 $shortTitle = makeTruncStr($fetchedRow['ht_name'], $this->shortTitleLength);
915 'id' => $fetchedRow['ht_public_id'], // 公開画像ID
916 'no' => $this->startNo + $index, // 画像番号
917 'title' => $fetchedRow['ht_name'], // 写真タイトル
918 'title_short' => $shortTitle, // 略式写真タイトル
919 'score' => $fetchedRow['ht_rate_average'], // 評価値
920 'image_url' => $thumbnailUrl, // サムネール画像のURL
921 'image_size' => $thumbnailSize // サムネール画像サイズ
923 $this->photoArray[] = $row;
927 * 取得したコンテンツ項目をテンプレートに設定する
929 * @param int $index 行番号
930 * @param array $fetchedRow 取得行
931 * @param object $param 任意使用パラメータ
932 * @return bool trueを返すとループ続行。falseを返すとその時点で終了。
934 function commentListLoop($index, $fetchedRow)
937 'no' => $index + 1, // コメント番号
938 'rate_value' => $this->convertToDispString($fetchedRow['hr_rate_value']), // 評価値
939 'comment' => $this->convertToDispString($fetchedRow['hr_message']), // コメント
940 'date' => $this->convertToDispDateTime($fetchedRow['hr_regist_dt'], 0, 10) // 日付
942 $this->tmpl->addVars('itemlist', $row);
943 $this->tmpl->parseTemplate('itemlist', 'a');
944 $this->serialArray[] = $fetchedRow['hr_serial'];
948 * 前後のリンク項目をテンプレートに設定する
950 * @param int $index 行番号
951 * @param array $fetchedRow 取得行
952 * @param object $urlParams URL付加パラメータ(任意使用パラメータ)
953 * @return bool trueを返すとループ続行。falseを返すとその時点で終了。
955 function prevNextListLoop($index, $fetchedRow, $urlParams)
957 if ($index == 0 && $fetchedRow['ht_public_id'] != $this->photoId){ // 「前へ」リンクのとき
958 $this->tmpl->setAttribute('prev_link', 'visibility', 'visible'); // リンク表示
959 $this->tmpl->addVar("prev_link", "prev_img_url", $this->getUrl($this->gEnv->getRootUrl() . self::PREV_ICON_FILE));// 「前へ」アイコン
960 $this->tmpl->addVar("prev_link", "prev_title", self::PREV_BUTTON_TITLE);
961 $this->tmpl->addVar("prev_link", "prev_alt", self::PREV_BUTTON_TITLE);
962 $this->tmpl->addVar("prev_link", "icon_size", photoCommonDef::BUTTON_ICON_SIZE);
965 $linkUrl = $this->getUrl($this->gEnv->getDefaultSmartphoneUrl() . '?'. M3_REQUEST_PARAM_PHOTO_ID . '=' . $fetchedRow['ht_public_id'] .
966 '&' . M3_REQUEST_PARAM_ITEM_NO . '=' . ($this->startNo -1) . $urlParams, true/*リンク用*/);
967 $this->tmpl->addVar("prev_link", "prev_url", $this->convertUrlToHtmlEntity($linkUrl));
968 } else if ($index >= 1 && $fetchedRow['ht_public_id'] != $this->photoId){// 「次へ」リンクのとき
969 $this->tmpl->setAttribute('next_link', 'visibility', 'visible'); // リンク表示
970 $this->tmpl->addVar("next_link", "next_img_url", $this->getUrl($this->gEnv->getRootUrl() . self::NEXT_ICON_FILE));// 「次へ」アイコン
971 $this->tmpl->addVar("next_link", "next_title", self::NEXT_BUTTON_TITLE);
972 $this->tmpl->addVar("next_link", "next_alt", self::NEXT_BUTTON_TITLE);
973 $this->tmpl->addVar("next_link", "icon_size", photoCommonDef::BUTTON_ICON_SIZE);
976 $linkUrl = $this->getUrl($this->gEnv->getDefaultSmartphoneUrl() . '?'. M3_REQUEST_PARAM_PHOTO_ID . '=' . $fetchedRow['ht_public_id'] .
977 '&' . M3_REQUEST_PARAM_ITEM_NO . '=' . ($this->startNo +1) . $urlParams, true/*リンク用*/);
978 $this->tmpl->addVar("next_link", "next_url", $this->convertUrlToHtmlEntity($linkUrl));
984 * 取得したデータをテンプレートに設定する
986 * @param int $index 行番号(0~)
987 * @param array $fetchedRow フェッチ取得した行
988 * @param object $param 未使用
989 * @return bool true=処理続行の場合、false=処理終了の場合
991 function categoryListLoop($index, $fetchedRow, $param)
993 // パスワードが設定されていない場合は表示しない
994 if (empty($fetchedRow['hc_password'])) return true;
996 $id = $fetchedRow['hc_id'];// カテゴリ項目ID
997 $name = $fetchedRow['hc_name']; // カテゴリ項目名
999 $this->categoryWithPwdArray[] = $id; // パスワードが必要なカテゴリー
1001 // 既にアクセス可能になっているカテゴリーは表示しない
1002 if (in_array($id, $this->authCategory)){
1003 $this->authCategoryStr .= $name . ','; // 参照可能なカテゴリー(表示用)
1008 'value' => $this->convertToDispString($id), // カテゴリ項目ID
1009 'name' => $this->convertToDispString($name), // カテゴリ項目名
1010 'selected' => $selected // 選択中かどうか
1012 $this->tmpl->addVars('access_category_list', $row);
1013 $this->tmpl->parseTemplate('access_category_list', 'a');
1017 * 取得したデータをテンプレートに設定する
1019 * @param int $index 行番号(0~)
1020 * @param array $fetchedRow フェッチ取得した行
1021 * @param object $param 未使用
1022 * @return bool true=処理続行の場合、false=処理終了の場合
1024 function productListLoop($index, $fetchedRow, $param)
1026 $ret = self::$_mainDb->getProductBySerial($fetchedRow['hp_serial'], $row, $row2, $row3);
1027 if (!$ret) return true;
1030 $priceArray = $this->getPrice($row2, self::STANDARD_PRICE);
1031 $price = $priceArray['pp_price']; // 価格
1032 $currency = $priceArray['pp_currency_id']; // 通貨
1033 $taxType = $fetchedRow['hp_tax_type_id']; // 税種別
1036 $this->ecObj->setCurrencyType($currency, $this->_langId); // 通貨設定
1037 $this->ecObj->setTaxType($taxType, $this->_langId); // 税種別設定
1038 $totalPrice = $this->ecObj->getPriceWithTax($price, $dispPrice); // 税込み価格取得
1042 'product_name' => $this->convertToDispString($fetchedRow['hp_name']), // 商品名
1043 'product_detail' => $this->convertToDispString($fetchedRow['hp_description_short']), // 簡易商品説明
1044 'disp_total_price' => $this->prePrice . $dispPrice . $this->postPrice, // 税込み価格
1045 'product' => $this->convertToDispString($fetchedRow['hp_id']) // フォト商品ID
1047 $this->tmpl->addVars('product_list', $row);
1048 $this->tmpl->parseTemplate('product_list', 'a');
1053 $this->tmpl->addVars('product_script_list', $row2);
1054 $this->tmpl->parseTemplate('product_script_list', 'a');
1055 $this->isExistsProduct = true; // 商品が存在するかどうか
1061 * HTMLのheadタグ内に出力する。
1062 * _assign()よりも後に実行される。
1064 * @param RequestManager $request HTTPリクエスト処理クラス
1065 * @param object $param 任意使用パラメータ
1066 * @return array 設定データ。連想配列で「title」「description」「keywords」を設定。
1068 function _setHeadMeta($request, &$param)
1070 $headData = array( 'title' => $this->headTitle,
1071 'description' => $this->headDesc,
1072 'keywords' => $this->headKeyword);
1076 * 検索テンプレートデータ作成処理コールバック
1078 * @param object $tmpl テンプレートオブジェクト
1081 function _makeSearcheTemplate($tmpl)
1083 $tmpl->addVar("_tmpl", "search_text_id", photoCommonDef::SEARCH_TEXT_ID); // 検索用テキストフィールドのタグID
1084 $tmpl->addVar("_tmpl", "search_button_id", photoCommonDef::SEARCH_BUTTON_ID); // 検索用ボタンのタグID
1085 $tmpl->addVar("_tmpl", "search_reset_id", photoCommonDef::SEARCH_RESET_ID); // 検索エリアリセットボタンのタグID
1086 $tmpl->addVar("_tmpl", "search_sort_id", photoCommonDef::SEARCH_SORT_ID); // 検索エリアソートメニューのタグID
1091 * @param int $pageNo ページ番号(1~)。ページ番号が範囲外にある場合は自動的に調整
1092 * @param int $totalCount 総項目数
1093 * @param int $viewItemCount 1ページあたりの項目数
1094 * @param int $pageCount 戻り値、ページ総数(1~)。
1095 * @param int $startNo 戻り値、先頭項目番号(1~)。
1096 * @param int $endNo 戻り値、最後項目番号(1~)。
1099 function calcPage(&$pageNo, $totalCount, $viewItemCount, &$pageCount, &$startNo, &$endNo)
1102 $pageCount = (int)(($totalCount -1) / $viewItemCount) + 1; // 総ページ数
1103 if ($pageNo < 1) $pageNo = 1;
1104 if ($pageNo > $pageCount) $pageNo = $pageCount;
1105 $startNo = ($pageNo -1) * $viewItemCount +1; // 先頭の行番号
1106 $endNo = $pageNo * $viewItemCount > $totalCount ? $totalCount : $pageNo * $viewItemCount;// 最後の行番号
1111 * @param string $templateData テンプレートデータ
1112 * @return string フィールドデータ
1114 function createFieldOutput($templateData)
1116 $fieldOutput = $templateData;
1118 $fieldCount = count($this->fieldInfoArray);
1119 for ($i = 0; $i < $fieldCount; $i++){
1120 $infoObj = $this->fieldInfoArray[$i];
1121 $itemType = $infoObj->itemType; // カテゴリ種別
1122 $selectType = $infoObj->selectType; // 選択タイプ
1123 $category = $infoObj->category; // カテゴリ
1126 if ($itemType == 'category'){ // カテゴリーの場合
1127 $selItems = $this->categoryInfoArray[$category]; // カテゴリ項目
1128 $selItemCount = count($selItems);
1129 $inputValues = $this->categoryArray;
1130 } else if ($itemType == 'author'){ // 撮影者の場合
1131 if (empty($this->menuAuthorRows)){
1132 $ret = self::$_mainDb->getAllUserForMenu(photoCommonDef::USER_OPTION, $this->menuAuthorRows);
1134 $selItems = array();
1135 for ($j = 0; $j < count($this->menuAuthorRows); $j++){
1136 $selItems[] = array('name' => $this->menuAuthorRows[$j]['lu_name'], 'value' => $this->menuAuthorRows[$j]['lu_account']);
1138 $selItemCount = count($selItems);
1139 $inputValues = $this->authorArray;
1143 $fieldName = self::SEARCH_FIELD_HEAD . ($i + 1);
1145 switch ($selectType){
1146 case 'single': // 単一選択
1147 $inputTag .= '<select id="' . $fieldName . '" name="' . $fieldName . '" class="' . self::SEARCH_FIELD_CLASS_HEAD . $itemType . '" >' . M3_NL;
1148 $inputTag .= '<option value="">-- 選択なし --</option>' . M3_NL;
1149 for ($j = 0; $j < $selItemCount; $j++){
1152 $value = $selItems[$j]['value'];
1153 $name = $selItems[$j]['name'];
1154 if ($itemType == 'category'){ // カテゴリーの場合
1155 for ($k = 0; $k < count($inputValues); $k++){
1156 $inputValuesLine = $inputValues[$k];
1157 if (in_array($value, $inputValuesLine)){
1158 $param[] = 'selected';
1163 if (in_array($value, $inputValues)) $param[] = 'selected';
1165 if (count($param) > 0) $paramStr = ' ' . implode($param, ' ');
1166 $inputTag .= '<option value="' . $this->convertToDispString($value) . '"' . $paramStr . '>' . $this->convertToDispString($name) . '</option>' . M3_NL;
1168 $inputTag .= '</select>' . M3_NL;
1170 case 'multi': // 複数選択
1172 for ($j = 0; $j < $selItemCount; $j++){
1175 $value = $selItems[$j]['value'];
1176 $name = $selItems[$j]['name'];
1177 if ($itemType == 'category'){ // カテゴリーの場合
1178 for ($k = 0; $k < count($inputValues); $k++){
1179 $inputValuesLine = $inputValues[$k];
1180 if (in_array($value, $inputValues)){
1181 $param[] = 'checked';
1186 if (in_array($value, $inputValues)) $param[] = 'checked';
1188 $param[] = 'class="' . self::SEARCH_FIELD_CLASS_HEAD . $itemType . '"'; // クラス名追加
1189 if (count($param) > 0) $paramStr = ' ' . implode($param, ' ');
1190 $inputTag .= '<label><input type="checkbox" name="' . $fieldName . '" value="' . $this->convertToDispString($value) . '"'
1191 . $paramStr . ' />' . $this->convertToDispString($name) . '</label>';
1198 $keyTag = M3_TAG_START . M3_TAG_MACRO_ITEM_KEY . ($i + 1) . M3_TAG_END;
1199 $fieldOutput = str_replace($keyTag, $inputTag, $fieldOutput);
1201 return $fieldOutput;
1204 * POST,GETパラメータエラーチェック
1206 * @param string $category 画像カテゴリー
1207 * @param string $author 著作者
1208 * @param string $sort ソート順
1209 * @return bool true=正常、false=異常
1211 function checkInputValues($category, $author, $sort)
1213 $retStatus = true; // 処理状態
1216 // 検索条件フィールド内はOR、フィールド間はAND検索
1217 // フィールド内の結果は「,」区切りで、フィールド間の結果は「+」または「 」で区切る
1218 $this->categoryArray = array();
1219 $pos = strpos($category, '+'); // カテゴリは「+」または「 」で区切る
1220 if ($pos === false){
1221 $categorysArray = explode(' ', $category);
1223 $categorysArray = explode('+', $category);
1225 for ($i = 0; $i < count($categorysArray); $i++){
1226 $categoryArray = array();
1227 $categorySrcArray = explode(',', $categorysArray[$i]);
1228 for ($j = 0; $j < count($categorySrcArray); $j++){
1229 if (!empty($categorySrcArray[$j])) $categoryArray[] = $categorySrcArray[$j];
1231 if (!ValueCheck::isNumeric($categoryArray)){ // すべて数値であるかチェック
1232 $this->categoryArray = array(); // エラーの場合は初期化
1236 if (!empty($categoryArray)) $this->categoryArray[] = $categoryArray;
1239 $this->authorArray = explode(',', $author);
1240 if (!empty($this->authorArray)){
1242 $ret = self::$_mainDb->getAllUserForMenu(photoCommonDef::USER_OPTION, $this->menuAuthorRows);
1244 $userArray = array();
1245 for ($i = 0; $i < count($this->menuAuthorRows); $i++){
1246 $userArray[] = $this->menuAuthorRows[$i]['lu_account'];
1248 for ($i = 0; $i < count($this->authorArray); $i++){
1249 if (!in_array($this->authorArray[$i], $userArray)){
1258 $this->authorArray = array(); // 選択中の著作者
1263 list($this->sortKey, $this->sortDirection) = explode('-', $sort);
1264 if (!in_array($this->sortKey, array('index', 'date', 'rate', 'ref')) || !in_array($this->sortDirection, array('0', '1'))){
1265 //$this->sortKey = 'date'; // デフォルト値
1266 //$this->sortDirection = '0';
1267 $this->sortKey = self::$_configArray[photoCommonDef::CF_PHOTO_LIST_SORT_KEY];
1268 if ($this->sortKey == '') $this->sortKey = photoCommonDef::DEFAULT_PHOTO_LIST_SORT_KEY;
1269 $this->sortDirection = self::$_configArray[photoCommonDef::CF_PHOTO_LIST_ORDER];
1270 if ($this->sortDirection == '') $this->sortDirection = photoCommonDef::DEFAULT_PHOTO_LIST_ORDER;// デフォルトの画像一覧並び順(降順)
1278 * @param string $photoId 画像ID
1279 * @param string $lang 言語ID
1280 * @return bool true=公開中、false=非公開
1282 function isPublicPhotoId($photoId, $lang)
1284 $ret = self::$_mainDb->getSearchPhotoInfo($photoId, $lang, $row, $categoryRows);
1290 * @param string $keyword 検索キーワード
1291 * @param string $category 画像カテゴリー
1292 * @param string $author 著作者
1293 * @param string $sort ソート順
1294 * @return string URLパラメータ
1296 function createUrlParams($keyword, $category, $author, $sort)
1299 if (!empty($keyword)) $params .= '&' . M3_REQUEST_PARAM_KEYWORD . '=' . urlencode($keyword);// 検索キーワード
1300 if (!empty($category)){
1301 // カテゴリーの半角スペースは「+」に変換
1302 $category = str_replace(' ', '+', $category);
1303 $params .= '&category' . '=' . $category;// カテゴリー
1305 if (!empty($author)) $params .= '&author' . '=' . $author;// 撮影者
1306 if (!empty($sort)) $params .= '&sort' . '=' . $sort;// ソート順
1310 * クライアントパラメータオブジェクトを取得
1312 * @param string $clientId クライアントID
1313 * @param string $widgetId ウィジェットID
1314 * @return object パラメータオブジェクト。取得できないときはnull。
1316 function getClientParamObj($clientId, $widgetId)
1318 $serializedParam = self::$_mainDb->getClientParam($clientId, $widgetId);
1319 if (empty($serializedParam)){
1320 $clientObj = new stdClass;
1323 return unserialize($serializedParam);
1327 * クライアントパラメータオブジェクトを更新
1329 * @param string $clientId クライアントID
1330 * @param string $widgetId ウィジェットID
1331 * @param object $obj 格納するウィジェットパラメータオブジェクト
1332 * @return bool true=更新成功、false=更新失敗
1334 function updateClientParamObj($clientId, $widgetId, $obj)
1339 $updateObj = serialize($obj);
1341 $ret = self::$_mainDb->updateClientParam($clientId, $widgetId, $updateObj);
1347 * @param array $srcRows 価格リスト
1348 * @param string $priceType 価格のタイプ
1349 * @return array 取得した価格行
1351 function getPrice($srcRows, $priceType)
1353 for ($i = 0; $i < count($srcRows); $i++){
1354 if ($srcRows[$i]['pp_price_type_id'] == $priceType){
1355 return $srcRows[$i];
1363 * @param int $pageNo ページ番号(1~)。
1364 * @param int $pageCount 総項目数
1365 * @param int $linkCount 最大リンク数
1366 * @param string $baseUrl リンク用のベースURL
1367 * @param string $urlParams オプションのURLパラメータ
1368 * @return string リンクHTML
1370 function createPageLink($pageNo, $pageCount, $linkCount, $baseUrl, $urlParams)
1372 //$linkOption = 'data-role="button" ';
1373 $linkOption = 'data-role="button" data-ajax="false" '; // jQuery MobileのAjaxでの画面遷移機能をオフ
1377 if ($pageCount > 1){ // ページが2ページ以上のときリンクを作成
1378 // ページ数1から$linkCountまでのリンクを作成
1379 $maxPageCount = $pageCount < $linkCount ? $pageCount : $linkCount;
1380 for ($i = 1; $i <= $maxPageCount; $i++){
1382 $link = '<span class="page_no"><a href="#" data-role="button" class="ui-disabled">' . $i . '</a></span>';
1384 $linkUrl = $this->getUrl($baseUrl . '&page=' . $i . $urlParams, true/*リンク用*/);
1385 $link = '<span class="page_no"><a href="' . $this->convertUrlToHtmlEntity($linkUrl) . '" ' . $linkOption . '>' . $i . '</a></span>';
1390 if ($pageCount > $linkCount){
1391 $pageLink .= '<span class="page_no"><a href="#" data-role="button" class="ui-disabled">...</a></span>';
1394 if ($pageNo > 1){ // 前ページがあるとき
1395 $linkUrl = $this->getUrl($baseUrl . '&page=' . ($pageNo -1) . $urlParams, true/*リンク用*/);
1396 $link = '<span class="page_prev"><a href="' . $this->convertUrlToHtmlEntity($linkUrl) . '" ' . $linkOption . '>前へ</a></span>';
1397 $pageLink = $link . $pageLink;
1399 if ($pageNo < $pageCount){ // 次ページがあるとき
1400 $linkUrl = $this->getUrl($baseUrl . '&page=' . ($pageNo +1) . $urlParams, true/*リンク用*/);
1401 $link = '<span class="page_next"><a href="' . $this->convertUrlToHtmlEntity($linkUrl) . '" ' . $linkOption . '>次へ</a></span>';