app/Customize/Service/LmHelper.php line 935

Open in your IDE?
  1. <?php
  2. /**
  3.  * @version EC=CUBE4
  4.  * @copyright 株式会社 翔 kakeru.co.jp
  5.  * @author Kawai
  6.  * 2021年11月16日作成
  7.  * 2022年01月25日更新 都道府県、支払い方法等のマスタ情報取得用メソッドの追加 by worker_g
  8.  *
  9.  *
  10.  * ランドマークヘルパー
  11.  * twig
  12.  * {{% set hoge = Service('Customize\\Service\\LmHelper').hoge(Email) %}
  13.  *
  14.  *                               C= C= C= ┌(;・_・)┘トコトコ
  15.  ******************************************************/
  16. namespace Customize\Service;
  17. use Eccube\Common\EccubeConfig;
  18. use InvalidArgumentException;
  19. use Lm\Engine\EC\Entity\OrderHeaderExtended;
  20. use Lm\Entity\OrderHeader;
  21. use Lm\Service\Db\SqlService;
  22. use Lm\Service\Db\DbManager;
  23. use Symfony\Component\DependencyInjection\ContainerInterface;
  24. use Symfony\Component\HttpFoundation\Request;
  25. use Symfony\Component\HttpFoundation\RequestStack;
  26. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  27. use Customize\Service\MobileDetector as LmMobileDetector;
  28. class LmHelper
  29. {
  30.     const IS_NOT_NULLABLE 1;
  31.     /**
  32.      * @var EccubeConfig
  33.      */
  34.     protected $eccubeConfig;
  35.     /**
  36.      * @var PrefectureService
  37.      */
  38.     protected $PrefectureService;
  39.     /**
  40.      * @var CartHelper
  41.      */
  42.     protected $CartHelper;
  43.     /**
  44.      * @var Request|null
  45.      */
  46.     protected $Request;
  47.     protected $session;
  48.     protected $mobileDetector;
  49.     /**
  50.      * @param ContainerInterface $Container
  51.      * @param EccubeConfig $eccubeConfig
  52.      * @param PrefectureService $prefectureService
  53.      */
  54.     public function __construct(EccubeConfig      $eccubeConfig,
  55.                                 PrefectureService $prefectureService,
  56.                                 CartHelper        $CartHelper,
  57.                                 RequestStack      $requestStack,
  58.                                 SessionInterface  $session,
  59.                                 LmMobileDetector  $mobileDetector
  60.     )
  61.     {
  62.         $this->eccubeConfig $eccubeConfig;
  63.         $this->PrefectureService $prefectureService;
  64.         $this->CartHelper $CartHelper;
  65.         $this->Request $requestStack->getCurrentRequest();
  66.         $this->session $session;
  67.         $this->mobileDetector $mobileDetector;
  68.     }
  69.     /**
  70.      * @param $text
  71.      * @return string
  72.      */
  73.     public static function display_text($text)
  74.     {
  75.         return nl2br(str_replace(">""&gt;"str_replace("<""&lt;"stripslashes($text))));
  76.     }
  77.     /**
  78.      * @param $text
  79.      * @return string
  80.      */
  81.     public static function display_form_text($text)
  82.     {
  83.         return htmlspecialchars($textENT_QUOTES);
  84.     }
  85.     /**
  86.      * ページングリンクの生成を行う。
  87.      * 第2引数に数値を渡した場合、総レコード数として解釈。
  88.      * 第2引数に配列(全レコード)を渡した場合、配列より総レコード数を算出。
  89.      * 総レコード数と第3引数(1ページあたりの表示件数)より総ページ数を算出。
  90.      *
  91.      * TODO: 共通テンプレート(*.twig)の作成
  92.      *
  93.      * @param int $page
  94.      * @param int|array $pages
  95.      * @param int $items_per_page
  96.      * @param int $max_paging_links
  97.      * @param array $params
  98.      * @return array
  99.      */
  100.     public static function paging($page$pages$items_per_page 10$max_paging_links 10$params = [])
  101.     {
  102.         // 総レコード数の解釈
  103.         if (is_array($pages)) {
  104.             $total_count count($pages);
  105.         } else if (is_numeric($pages)) {
  106.             $total_count $pages;
  107.         } else {
  108.             throw new InvalidArgumentException();
  109.         }
  110.         // 総ページ数 = 総レコード数 / 1ページあたりの表示件数
  111.         $pages ceil($total_count $items_per_page);
  112.         // ページオフセット(当該ページの開始レコード位置)の算出
  113.         $page_offset = ($page 1) * $items_per_page;
  114.         // 返り値の用意
  115.         $ret = array(
  116.             'page' => $page,
  117.             'page_offset' => $page_offset,
  118.             'pages' => $pages,
  119.             'page_list' => array(),
  120.             'total_count' => $total_count,
  121.             'prev' => null,
  122.             'next' => null,
  123.             'params_url' => null,
  124.             'start_no' => $page_offset 1,
  125.             'end_no' => $items_per_page $page,
  126.         );
  127.         //$max_paging_linksはページ番号の表示数
  128.         $next $page 1;
  129.         $prev $page 1;
  130.         //ページ番号リンク用
  131.         $start = ($page floor($max_paging_links 2) > 0) ? ($page floor($max_paging_links 2)) : 1;//始点
  132.         $end = ($start 1) ? ($page floor($max_paging_links 2)) : $max_paging_links;//終点
  133.         $start = ($pages $end) ? $start - ($end $pages) : $start;//始点再計算
  134.         if ($page 1) {
  135.             $ret['prev'] = self::display_text($prev);
  136.         }
  137.         //最初のページへのリンク
  138.         if ($start >= floor($max_paging_links 2)) {
  139.             $ret['page_list'][] = self::display_text(1);
  140.             if ($start floor($max_paging_links 2)) $ret['page_list'][] = null//ドットの表示
  141.         }
  142.         for ($i $start$i <= $end$i++) {//ページリンク表示ループ
  143.             if ($i <= $pages && $i 0)//1以上最大ページ数以下の場合
  144.                 $ret['page_list'][] = self::display_text($i);//ページ番号リンク表示
  145.         }
  146.         //最後のページへのリンク
  147.         if ($pages $end) {
  148.             if ($pages $end$ret['page_list'][] = null;    //ドットの表示
  149.             $ret['page_list'][] = self::display_text($pages);
  150.         }
  151.         if ($page $pages) {
  152.             $ret['next'] = self::display_text($next);
  153.         }
  154.         // TODO: $params_url -> 改善の余地あり?
  155.         $params_url '';
  156.         if (!empty($params)) {
  157. //            if (isset($params['id']) && ctype_digit($params['id'])) {
  158. //                $params_url .= "id={$params['id']}&";
  159. //            }
  160. //            if (isset($params['category']) && ctype_digit($params['category'])) {
  161. //                $params_url .= "category={$params['category']}&";
  162. //            }
  163. //            if (isset($params['goods_id']) && ctype_digit($params['goods_id'])) {
  164. //                $params_url .= "goods_id={$params['goods_id']}&";
  165. //            }
  166.             $params_url http_build_query($params);
  167.             $params_url "?{$params_url}";
  168.         }
  169.         $ret['params_url'] = $params_url;
  170.         return $ret;
  171.     }
  172.     /**
  173.      * @param $goodsId
  174.      * @param $filename
  175.      * @return string
  176.      */
  177.     public function getGoodsImageUrl($goodsId$filename)
  178.     {
  179.         //
  180.         $url $this->getConfig('CFIMG_GOODS_URL');
  181.         //
  182.         $folder substr($goodsId, -11);
  183.         $folder "{$folder}/{$goodsId}";
  184.         //
  185.         $ret "{$url}/{$folder}/{$filename}";
  186.         //
  187.         return $ret;
  188.     }
  189.     /**
  190.      * @return PrefectureService
  191.      */
  192.     public function pref()
  193.     {
  194.         return $this->PrefectureService;
  195.     }
  196.     /**
  197.      * EC-CUBEコンフィグ項目の値を取得する
  198.      *
  199.      * @param array|string|int $key
  200.      * string|int ・・・ 指定されたキーのコンフィグ項目の値を取得する。
  201.      * array ・・・・・・ キーを階層構造で指定することで再帰的に走査し、任意の階層のコンフィグ項目を取得する。
  202.      * @param array|null $_config 指定不可。再帰処理用。
  203.      * @return mixed
  204.      */
  205.     public function getConfig($key$_config null)
  206.     {
  207.         //
  208.         if ($_config === null) {
  209.             //
  210.             $_config $this->eccubeConfig;
  211.         }
  212.         //
  213.         if (is_array($key)) {
  214.             //
  215.             if (count($key) !== 1) {
  216.                 //
  217.                 throw new \Exception('キーの階層構造が不正です');
  218.             }
  219.             //
  220.             $childKey key($key);
  221.             //
  222.             return $this->getConfig($key[$childKey], $_config[$childKey]);
  223.         } else {
  224.             return $_config[$key] ?? null;
  225.         }
  226.     }
  227.     /**
  228.      * @return mixed
  229.      */
  230.     public function getPaymentTypeList()
  231.     {
  232.         return $this->getConfig('PAYMENT_TYPE_LIST');
  233.     }
  234.     /**
  235.      * @return mixed
  236.      */
  237.     public function getSiteTypeList()
  238.     {
  239.         return $this->getConfig('SITE_TYPE_LIST');
  240.     }
  241.     /**
  242.      * カートタイプを返す
  243.      *  dtb_cart cart_typr
  244.      *
  245.      * @return int CrtType
  246.      */
  247.     public function getCartType()
  248.     {
  249.         return $this->CartHelper->GetCartType();
  250.     }
  251.     /**
  252.      * 全ての文字をHTML用に変換
  253.      *
  254.      * @param string
  255.      * @return string
  256.      */
  257.     public static function displayText($text)
  258.     {
  259.         return nl2br(str_replace(">""&gt;"str_replace("<""&lt;"stripslashes($text))));
  260.     }
  261.     /**
  262.      * TODO: キャッシュ使用可否判定
  263.      *
  264.      * @return bool
  265.      */
  266.     public function useCache()
  267.     {
  268.         return false;
  269.     }
  270.     /**
  271.      * TODO: キャッシュロード
  272.      *
  273.      * @param string $dataCacheId
  274.      * @param Request $request
  275.      * @return array
  276.      */
  277.     public function loadCache($dataCacheId$request)
  278.     {
  279.         return null;
  280.     }
  281.     /**
  282.      * TODO: キャッシュにデータ保存
  283.      *
  284.      * @param string $dataCacheId
  285.      * @param array $data
  286.      * @return なし
  287.      */
  288.     public function saveCache($dataCacheId$data)
  289.     {
  290.         return null;
  291.     }
  292.     /**
  293.      * キーワード分解
  294.      *
  295.      * @param string $keyword
  296.      * @param bool $trim
  297.      * @return array
  298.      */
  299.     public function getKeywords($keyword$trim true)
  300.     {
  301.         $searchtext str_replace(' '' '$keyword);
  302.         $tmpArray preg_split('/[ ]+/'$searchtext);
  303.         $keywords = array();
  304.         $searchSimilarWordsService = new SearchSimilarWordsService();
  305.         foreach ($tmpArray as $keyword) {
  306.             // 曖昧検索(search_similar_words)処理の経由
  307.             array_push($keywords$searchSimilarWordsService->getValidKeyword($keyword$trim));
  308.         }
  309.         return $keywords;
  310.     }
  311.     /**
  312.      * 指定した日時がLM休日かどうか判定する
  313.      *
  314.      * @param int $time
  315.      * @return bool
  316.      */
  317.     protected function getLmHoliday($time)
  318.     {
  319.         // 休日テーブルを照会
  320.         $sql = new SqlService();
  321.         $sql->Table('holiday_calendar_table');
  322.         $sql->Where(sprintf('holiday_year = 0 OR holiday_year = %d'intval(date("Y"$time))));
  323.         $sql->Where(sprintf('holiday_month = 0 OR holiday_month = %d'intval(date("m"$time))));
  324.         $sql->Where(sprintf('holiday_day = 0 OR holiday_day = %d'intval(date("d"$time))));
  325.         $sql->Where(sprintf('holiday_week = 0 OR holiday_week = %d', (date("w"$time) + 1)));
  326.         $sql->Where(sprintf('holiday_count = 0 OR holiday_count = %d', (intval((date("d"$time) - 1) / 7) + 1)));
  327.         $sql->Where('holiday_year = 0 AND holiday_month = 0 AND holiday_day = 0 AND holiday_count = 0 AND holiday_week = 0'"AND NOT");
  328.         /*
  329.         ※元クエリ内容
  330.                 $strSQL = "select * from holiday_calendar_table
  331.                         where ( holiday_year = 0 or holiday_year = " . intval(date("Y", $today)) . " )
  332.                         and ( holiday_month = 0 or holiday_month = " . intval(date("m", $today)) . " )
  333.                         and ( holiday_day = 0 or holiday_day = " . intval(date("d", $today)) . " )
  334.                         and ( holiday_week = 0 or holiday_week = " . (date("w", $today) + 1) . " )
  335.                         and ( holiday_count = 0 or holiday_count = " . (intval((date("d", $today) - 1) / 7) + 1) . " )
  336.                         and not ( holiday_year = 0 and holiday_month = 0 and holiday_day = 0 and holiday_count = 0 and holiday_week = 0 )"
  337.         */
  338.         $result $sql->Find();
  339.         return !empty($result);
  340.     }
  341.     /**
  342.      * 指定した日時が指定の仕入先の休日に該当するかどうか判定する
  343.      *
  344.      * @param int $time
  345.      * @param int array $shiiresakiList  仕入先コード(複数可能)
  346.      * @return bool
  347.      */
  348.     protected function getShiiresakiHoliday($time$shiiresakiList)
  349.     {
  350.         // 仕入先休日テーブルを照会
  351.         $sql = new SqlService();
  352.         $sql->Table('shiiresaki_yasumi_table');
  353.         if (count($shiiresakiList) === 1) {
  354.             $sql->Where(sprintf('shiiresaki_id = %d'$shiiresakiList[0]));
  355.         } else {
  356.             $sql->Where('shiiresaki_id IN (' join(','$shiiresakiList) . ')');
  357.         }
  358.         $sql->Where("holiday = '" date('Y-m-d'$time) . "'");
  359.         /*
  360.         ※元クエリ内容
  361.                     $strSQL = "SELECT * FROM shiiresaki_yasumi_table
  362.                     WHERE shiiresaki_id = $sid
  363.                     AND holiday = '$searchDate'";
  364.         */
  365.         $result $sql->Find();
  366.         return !empty($result);
  367.     }
  368.     /**
  369.      * LM休日及び仕入先休日を元に、指定した日時から指定営業日経過後の「営業日」を算出する
  370.      *
  371.      * @param int $time 基準日時
  372.      * @param int $days 指定営業日
  373.      * @param int array $shiiresakiList  仕入先コード(複数可能)デフォルトは 16=長瀞
  374.      * @return string Ymd  見つからない場合は null
  375.      */
  376.     public function getWorkingDate($time$days$shiiresakiList = [16])
  377.     {
  378.         $ret null;
  379.         $cnt 0;
  380.         $base date("Y-m-d"$time);
  381.         // 最大30日間内で検索し、見つからない場合はエラーとする
  382.         $max_date 30;
  383.         for ($i 0$i <= $days$i++) {
  384.             $find false;
  385.             for ($j 0$j $max_date$j++) {
  386.                 $targetDate strtotime($base " " $cnt " day");
  387.                 // LM休日判定
  388.                 $isLmHoliday $this->getLmHoliday($targetDate);
  389.                 if (!$isLmHoliday) {
  390.                     if ($shiiresakiList) {
  391.                         // 仕入先休日判定
  392.                         $isShiiresakiHoliday $this->getShiiresakiHoliday($targetDate$shiiresakiList);
  393.                         if (!$isShiiresakiHoliday) {
  394.                             $find true;
  395.                             break;
  396.                         }
  397.                     } else {
  398.                         // 仕入先判定なし
  399.                         $find true;
  400.                         break;
  401.                     }
  402.                 }
  403.                 $cnt++;
  404.             }
  405.             // 見つかった場合は次の日に進める
  406.             $cnt $find $cnt $cnt;
  407.         }
  408.         return $find date('Ymd'$targetDate) : null;
  409.     }
  410.     /**
  411.      * 都道府県IDを元に離島かどうか判断し配送日を返す
  412.      *
  413.      * @param int $prefectureId
  414.      * @return int
  415.      */
  416.     protected function getIslandByPrefecture($prefectureId)
  417.     {
  418.         $ret 1;
  419.         if ($prefectureId == or $prefectureId >= 36) {
  420.             $ret 2;
  421.         }
  422.         return $ret;
  423.     }
  424.     /**
  425.      * 郵便番号を元に離島かどうか判断し配送日を返す
  426.      *
  427.      * @param string $postcode
  428.      * @param int $prefectureId
  429.      * @return int
  430.      */
  431.     protected function getIslandByPostcode($postcode$prefectureId)
  432.     {
  433.         $ret 1;
  434.         // 郵便番号補正
  435.         if (!strstr($postcode'-')) {
  436.             $postcode preg_replace("/^(\d{3})(\d{4})$/""$1-$2"$postcode);
  437.         }
  438.         // 離島郵便番号テーブルを照会
  439.         $sql = new SqlService();
  440.         $sql->Table('island_table');
  441.         $sql->Where("island_postcode = '" $postcode "' OR island_postcode = '" substr($postcode03) . "-0000'");
  442.         /*
  443.         ※元クエリ内容
  444.                 $strSQL = "SELECT * FROM island_table WHERE island_postcode = '" . $post_code . "'";
  445.                 $strSQL = "SELECT * FROM island_table WHERE island_postcode = '" . substr(str_replace("-", "", $post_code), 0, 3) . "-0000'";
  446.         */
  447.         $result $sql->Find();
  448.         if (!empty($result)) {
  449.             $ret 2;
  450.         } else {
  451.             $ret $this->getIslandByPrefecture($prefectureId);
  452.         }
  453.         return $ret;
  454.     }
  455.     /**
  456.      * TODO: 商品IDを元に、仕入先毎のお届け予定日に関する情報を取得する
  457.      *
  458.      * @param int $goodsId
  459.      * @return array
  460.      */
  461.     protected function getShiiresakiSendDateByGoodsId($goodsId)
  462.     {
  463.         $ret = [
  464.             'shiiresaki_id' => -1,
  465.             'shiiresaki_senddate' => 0,
  466.             'send_limit' => 0,
  467.         ];
  468.         // 商品・仕入先テーブルを結合して情報取得
  469.         $sql = new SqlService();
  470.         $sql->Selects('shiiresaki_id');
  471.         $sql->Selects("DATE_FORMAT( T.shiiresaki_shimekiri_time, '%H%i' ) AS `sdate`");
  472.         $sql->Selects("shiiresaki_senddate");
  473.         $sql->Table('shiiresaki_table');
  474.         $sql->Join('goods_table''shiiresaki_id = goods_shiiresaki''INNER');
  475.         $sql->Where(sprintf('T1.goods_id = %d', (int)$goodsId));
  476.         /*
  477.         ※元クエリ内容
  478.                     $strSQL = "select shiiresaki_id, date_format( shiiresaki_shimekiri_time, '%H%i' ) as sdate, shiiresaki_senddate
  479.                             from goods_table
  480.                             inner join shiiresaki_table on goods_shiiresaki = shiiresaki_id
  481.                             where goods_id = " . $data_id;
  482.         */
  483.         $result $sql->Find();
  484.         if (!empty($result)) {
  485.             // 発注締切時間の後
  486.             $send_limit 0;
  487.             if (date("Hi") >= $result['sdate']) {
  488.                 $send_limit 1;
  489.             }
  490.             $ret = [
  491.                 'shiiresaki_id' => $result['shiiresaki_id'],
  492.                 'shiiresaki_senddate' => $result['shiiresaki_senddate'],
  493.                 'send_limit' => $send_limit,
  494.             ];
  495.         }
  496.         return $ret;
  497.     }
  498.     /**
  499.      * 商品IDを元に、指定した日時より直近の商品のお届け予定日を算出する
  500.      *
  501.      * @param int $time
  502.      * @param int $prefectureId
  503.      * @param string $postcode
  504.      * @param int $goodsId
  505.      * @return string Ymd  見つからない場合は null
  506.      */
  507.     public function getSendSchedule($time$prefectureId$postcode null$goodsId null)
  508.     {
  509.         // 起点日
  510.         $base $time $time time();
  511.         // 配送日数
  512.         $deliverDays 0;
  513.         // 仕入先配送日数
  514.         $deliverDaysShiiresaki 0;
  515.         // 休日判定対象の仕入先(デフォルトは物流業者=76)
  516.         $shiiresakiList = [76];
  517.         // 締切時間判定
  518.         $timeLimit false;
  519.         // 発注締切時間(12:00)を判定
  520.         if ($time && date("Hi"$base) >= 1200) {
  521.             $timeLimit true;
  522.         }
  523.         // 商品指定
  524.         if ($goodsId !== null) {
  525.             // 商品仕入先別の配送日を計算
  526.             $shiiresakiSendInfo $this->getShiiresakiSendDateByGoodsId($goodsId);
  527.             if ($shiiresakiSendInfo['shiiresaki_id'] !== -&& !$time) {
  528.                 $shiiresakiList[] = $shiiresakiSendInfo['shiiresaki_id'];
  529.             }
  530.             // 発送締切時間
  531.             $timeLimit = ($shiiresakiSendInfo['send_limit'] > 0) ? true false;
  532.             // 仕入先配送日数を加算
  533.             $deliverDaysShiiresaki $shiiresakiSendInfo['shiiresaki_senddate'];
  534.         }
  535.         // 発送締切時間を超える場合は日数加算
  536.         $deliverDays = ($timeLimit) ? $deliverDays $deliverDays;
  537.         // ここまででいったん休日判定計算する
  538.         $dt $this->getWorkingDate($base$deliverDays$shiiresakiList);
  539.         $base strtotime($dt);
  540.         // 曜日を判定
  541.         $week date("w"mktime(000date("m"$base), date("d"$base), date("Y"$base)));
  542.         if ($week == 5) {
  543.             // 計算した日付が金曜の場合は月曜まで進めて計算する
  544.             $deliverDays = ($deliverDaysShiiresaki 0) ? $deliverDaysShiiresaki 0;
  545.             $base mktime(000date("m"$base), date("d"$base) + $deliverDaysdate("Y"$base));
  546.             $dt $this->getWorkingDate($base$deliverDays$shiiresakiList);
  547.         } else {
  548.             $deliverDays $deliverDaysShiiresaki;
  549.             $deliverDays $deliverDays $deliverDays $deliverDays 1;
  550.             $dt $this->getWorkingDate($base$deliverDays$shiiresakiList);
  551.         }
  552.         // 都道府県別に配送日数を計算(郵便番号指定があれば離島テーブルより計算)
  553.         if ($postcode !== null) {
  554.             $deliverDays $this->getIslandByPostcode($postcode$prefectureId);
  555.         } else {
  556.             $deliverDays $this->getIslandByPrefecture($prefectureId);
  557.         }
  558.         // 配送日数を加算して返す(休日判定無し)
  559.         $base strtotime($dt);
  560.         $base mktime(000date("m"$base), date("d"$base) + $deliverDaysdate("Y"$base));
  561.         return date('Ymd'$base);
  562.     }
  563.     /**
  564.      * TODO: 曜日を取得
  565.      * @return mixed
  566.      */
  567.     public function getDayOfWeek()
  568.     {
  569.         return $this->getConfig('DOW_LIST');
  570.     }
  571.     /**
  572.      * TODO: その他手数料を取得
  573.      * @return mixed
  574.      */
  575.     public function getNewKakuninOtherAmounts()
  576.     {
  577.         return $this->getConfig('NEW_KAKUNIN_OTHER_AMOUNTS_LIST');
  578.     }
  579.     /**
  580.      * TODO: プリント種類を取得
  581.      * @return mixed
  582.      */
  583.     public function getPrintName()
  584.     {
  585.         return $this->getConfig('PRINT_NAME');
  586.     }
  587.     /**
  588.      * シークレットプレビュー中か否か
  589.      *
  590.      * @return bool
  591.      */
  592.     public static function isSecret()
  593.     {
  594.         return self::checkIsPermittedIpAddress([
  595.             0,  // 0:CS
  596.             1,  // 1:管理者
  597.             51// 51: BPデザイナー
  598.         ]);
  599.     }
  600.     /**
  601.      * アクセス元IPアドレスが、指定された権限において許可されたものか判定する
  602.      *
  603.      * TODO: $_SERVERの使用廃止
  604.      *
  605.      * @param array $permissionIdList
  606.      * @param $ipAddress
  607.      * @return bool
  608.      */
  609.     public static function checkIsPermittedIpAddress(array $permissionIdList = [
  610.         0// 0:CS
  611.         1// 1:管理者
  612.     ],                                                     $ipAddress null)
  613.     {
  614.         $ipAddress $ipAddress ?: $_SERVER['HTTP_X_FORWARDED_FOR'] ?: $_SERVER['REMOTE_ADDR'];
  615.         $ipAddress explode(', '$ipAddress);
  616.         $ipAddress $ipAddress[0];
  617.         $ip_range_list self::getIpRangeListByPermissionIdList($permissionIdList);
  618.         $client_ip ip2long($ipAddress);
  619.         $is_admin false;
  620.         foreach ($ip_range_list as $ip_range) {
  621.             list($ip_from$ip_to) = explode(' '$ip_range);
  622.             if ($client_ip ip2long($ip_from) || $client_ip ip2long($ip_to)) {
  623.                 continue;
  624.             }
  625.             $is_admin true;
  626.             break;
  627.         }
  628.         return $is_admin;
  629.     }
  630.     /**
  631.      * 指定された権限における許可IPリストを取得する
  632.      *
  633.      * @param $permissionIdList
  634.      * @return string[]
  635.      */
  636.     public static function getIpRangeListByPermissionIdList($permissionIdList)
  637.     {
  638.         //
  639.         $result = (new SqlService())
  640.             ->Select('T1.login_client_ip')
  641.             ->Table('auth_admin_table')
  642.             ->Join('login_table''aa_id = login_client_type''INNER')
  643.             ->Set('aa_id', (array)$permissionIdList'IN')
  644.             ->GroupBy('T1.login_client_ip')
  645.             ->Order('aa_id''ASC')
  646.             ->FindAll();
  647.         //
  648.         $result array_unique(explode(','implode(','array_filter(array_map(function ($item) {
  649.             return $item['login_client_ip'];
  650.         }, $result), function ($item) {
  651.             return !empty($item);
  652.         }))));
  653.         //
  654.         sort($result);
  655.         //
  656.         return $result;
  657.     }
  658.     /**
  659.      * 一時ファイルを作成する
  660.      *
  661.      * @param $fp
  662.      * @param $filename
  663.      * @return bool
  664.      */
  665.     public static function createTempfile(&$filename)
  666.     {
  667.         $fp tmpfile();
  668.         $meta stream_get_meta_data($fp);
  669.         $filename $meta['uri'];
  670.         return $fp;
  671.     }
  672.     public function getPageType()
  673.     {
  674.         //
  675.         $result = [
  676.             'type' => '',
  677.             'value' => '',
  678.         ];
  679.         //
  680.         $route $this->Request->get('_route');
  681.         //
  682.         if ($route === 'item/detail') {
  683.             //
  684.             $result['type'] = 'item';
  685.             $result['value'] = $this->Request->get('goodsId');
  686.         } else if ($route === 'page/main-category') {
  687.             //
  688.             $result['type'] = 'main-category';
  689.             $result['value'] = $this->Request->get('mc');
  690.         } else if ($route === 'page/sub-category') {
  691.             //
  692.             $result['type'] = 'category';
  693.             $result['value'] = $this->Request->get('ct');
  694.         } else if ($route === 'homepage') {
  695.             //
  696.             $result['type'] = 'top';
  697.             $result['value'] = null;
  698.         } else {
  699.             //
  700.             $result['type'] = 'other';
  701.             $result['value'] = null;
  702.         }
  703.         //
  704.         return $result;
  705.     }
  706.     static function hoge_dump($array$maxLevel 1$_level 0)
  707.     {
  708.         foreach ($array as $key => $value) {
  709.             $type gettype($value);
  710.             $type = ($type === 'object') ? get_class($value) : $type;
  711.             //
  712.             echo str_repeat('    '$_level) . "{$key}({$type}): " . (($type === 'DateTime' $value->format('Y-m-d H:i:s') : (is_object($value) ? '(Object)' : (is_array($value) ? '(Array)' $value)))), PHP_EOL;
  713.             if (($_level $maxLevel)) {
  714.                 //
  715.                 if (preg_match('/(?:Entity|PersistentCollection)/'$type)) {
  716.                     self::hoge_dump($value->toArray(), $maxLevel$_level 1);
  717.                 } else if (preg_match('/(?:array)/i'$type)) {
  718.                     self::hoge_dump($value$maxLevel$_level 1);
  719.                 } else {
  720.                     self::hoge_dump((array)($value), $maxLevel$_level 1);
  721.                 }
  722.             }
  723.         }
  724.     }
  725.     public function filterImagePathEnabled()
  726.     {
  727.         //
  728.         $config $this->eccubeConfig['Filter']['ImagePath'];
  729.         //
  730.         $configEnabled = !empty($config['Enabled']);
  731.         //
  732.         return $configEnabled;
  733.     }
  734.     public function filterSliderEnabled()
  735.     {
  736.         //
  737.         $config $this->eccubeConfig['Filter']['Slider'];
  738.         //
  739.         $configEnabled = !empty($config['Enabled']);
  740.         //
  741.         $requestDisabled $this->Request->get('slider') === 'false';
  742.         //
  743.         return $configEnabled && !$requestDisabled;
  744.     }
  745.     public function filterRemoveCommentEnabled()
  746.     {
  747.         //
  748.         $config $this->eccubeConfig['Filter']['RemoveComment'];
  749.         //
  750.         $configEnabled = !empty($config['Enabled']);
  751.         //
  752.         $requestDisabled $this->Request->get('cb') === 'true';
  753.         //
  754.         return $configEnabled && !$requestDisabled;
  755.     }
  756.     public function filterAjaxPriceEnabled()
  757.     {
  758.         //
  759.         $config $this->eccubeConfig['Filter']['AjaxPrice'];
  760.         //
  761.         $configEnabled = !empty($config['Enabled']);
  762.         //
  763.         $requestDisabled $this->Request->get('cb') === 'true';
  764.         //
  765.         return $configEnabled && !$requestDisabled;
  766.     }
  767.     public function filterWebpEnabled()
  768.     {
  769.         //
  770.         $config $this->eccubeConfig['Filter']['Webp'];
  771.         //
  772.         $configEnabled = !empty($config['Enabled']);
  773.         //
  774.         $requestDisabled $this->Request->get('webp') === 'false';
  775.         //
  776.         return $configEnabled && !$requestDisabled;
  777.     }
  778.     /**
  779.      * {[EC-CUBE]商品規格1ID} を {[LM]商品カラーID} に変換する
  780.      *
  781.      * @param $src
  782.      * @return int
  783.      * @throws \Exception
  784.      */
  785.     public function convClassCategory1IdToGclId($src)
  786.     {
  787.         //
  788.         $offset = (int)$this->getConfig([
  789.             'DbConvert' => [
  790.                 'ProductClassCategory' => [
  791.                     'offset' => '1'
  792.                 ]
  793.             ]
  794.         ]);
  795.         //
  796.         $dst $src $offset;
  797.         //
  798.         return $dst;
  799.     }
  800.     /**
  801.      * {[LM]商品カラーID} を {[EC-CUBE]商品規格1ID} に変換する
  802.      *
  803.      * @param $src
  804.      * @return int
  805.      * @throws \Exception
  806.      */
  807.     public function convGclIdToClassCategory1Id($src)
  808.     {
  809.         //
  810.         $offset = (int)$this->getConfig([
  811.             'DbConvert' => [
  812.                 'ProductClassCategory' => [
  813.                     'offset' => '1'
  814.                 ]
  815.             ]
  816.         ]);
  817.         //
  818.         $dst $src $offset;
  819.         //
  820.         return $dst;
  821.     }
  822.     /**
  823.      * {[EC-CUBE]商品規格2ID} を {[LM]商品サイズID} に変換する
  824.      *
  825.      * @param $src
  826.      * @return int
  827.      * @throws \Exception
  828.      */
  829.     public function convClassCategory2IdToGpId($src)
  830.     {
  831.         //
  832.         $offset = (int)$this->getConfig([
  833.             'DbConvert' => [
  834.                 'ProductClassCategory' => [
  835.                     'offset' => '2'
  836.                 ]
  837.             ]
  838.         ]);
  839.         //
  840.         $dst $src $offset;
  841.         //
  842.         return $dst;
  843.     }
  844.     public function convClassCategory2IdToGpIdRe($dst)
  845.     {
  846.         $offset = (int)$this->getConfig([
  847.             'DbConvert' => [
  848.                 'ProductClassCategory' => [
  849.                     'offset' => '2'
  850.                 ]
  851.             ]
  852.         ]);
  853.         $src $dst $offset;
  854.         return $src;
  855.     }
  856.     /**
  857.      * {[LM]商品サイズID} を {[EC-CUBE]商品規格2ID} に変換する
  858.      *
  859.      * @param $src
  860.      * @return int
  861.      * @throws \Exception
  862.      */
  863.     public function convGpIdToClassCategory2Id($src)
  864.     {
  865.         //
  866.         $offset = (int)$this->getConfig([
  867.             'DbConvert' => [
  868.                 'ProductClassCategory' => [
  869.                     'offset' => '2'
  870.                 ]
  871.             ]
  872.         ]);
  873.         //
  874.         $dst $src $offset;
  875.         //
  876.         return $dst;
  877.     }
  878.     public function getIntegerArray($array)
  879.     {
  880.         foreach ($array as $key => $item) {
  881.             if (!ctype_digit($item)) {
  882.                 unset($array[$key]);
  883.             }
  884.         }
  885.         return $array;
  886.     }
  887.     /**
  888.      * @param OrderHeaderExtended|OrderHeader|array|int $order
  889.      * @return string
  890.      * @throws \Exception
  891.      */
  892.     public function convertOrderToOrderId($order)
  893.     {
  894.         /**
  895.          * @var OrderHeaderExtended $orderHeaderEx
  896.          */
  897.         if ($orderHeaderEx OrderHeaderExtended::factory($order)) {
  898.             //
  899.             return $orderHeaderEx->getOrderNo();
  900.         } else {
  901.             //
  902.             return $order;
  903.         }
  904.     }
  905.     /**
  906.      * @param string $url
  907.      * @return string|null
  908.      */
  909.     public function getRedirectUrl($url)
  910.     {
  911.         //
  912.         $result = (new SqlService())
  913.             ->Select('ru_uri_after')
  914.             ->Table('redirect_url_table')
  915.             ->Set('ru_type''0')
  916.             ->Set('ru_uri_before'$url)
  917.             ->Limit(1)
  918.             ->Find();
  919.         //
  920.         if (!empty($result)) {
  921.             //
  922.             return $result['ru_uri_after'];
  923.         }
  924.         //
  925.         return null;
  926.     }
  927.     public function getBackUrl()
  928.     {
  929.         $domain $this->eccubeConfig['UT_URL'];
  930.         $referer $this->session->remove('referer');
  931.         if ($referer && strpos($referer$domain) !== false) {
  932.             return $referer;
  933.         }
  934.         return $domain;
  935.     }
  936.     public function isValidationPass($var$length$isNotNull$type$format)
  937.     {
  938.         $var mb_convert_encoding($var"EUC-JP""UTF-8");
  939.         //タグチェック
  940.         if (stristr($var">") || stristr($var"<")) {
  941.             return false;
  942.         }
  943.         //NULLチェック
  944.         if ($isNotNull == self::IS_NOT_NULLABLE && $var == "") {
  945.             return false;
  946.         } elseif ($isNotNull != self::IS_NOT_NULLABLE && $var == "") {
  947.             return true;
  948.         }
  949.         //型ごとのチェック処理
  950.         switch ($type) {
  951.             case 1:    //英数字
  952.                 for ($i 0$i strlen($var); $i++) {
  953.                     if (!(stristr("abcdefghijklmnopqrstuvwxyz_-@#1234567890./:?~:=&"substr($var$i1)))) {
  954.                         return false;
  955.                     }
  956.                 }
  957.                 return $length >= strlen($var);
  958.             case 2:    //数字
  959.                 for ($i 0$i strlen($var); $i++) {
  960.                     if (!(stristr("0123456789"substr($var$i1)))) {
  961.                         return false;
  962.                     }
  963.                 }
  964.                 return $length >= strlen($var);
  965.             case 3:    //日付
  966.                 switch ($format) {
  967.                     case "YYYY/MM/DD HH:MM:SS":
  968.                         if (substr($var101) != " ") {
  969.                             return false;
  970.                         }
  971.                         if (!(substr($var112) >= "00" && substr($var112) <= "23")) {
  972.                             return false;
  973.                         }
  974.                         if (substr($var131) != ":") {
  975.                             return false;
  976.                         }
  977.                         if (!(substr($var142) >= "00" && substr($var142) <= "59")) {
  978.                             return false;
  979.                         }
  980.                         if (substr($var161) != ":") {
  981.                             return false;
  982.                         }
  983.                         if (!(substr($var172) >= "00" && substr($var172) <= "59")) {
  984.                             return false;
  985.                         }
  986.                         if (!strtotime(substr($var118))) {
  987.                             return false;
  988.                         }
  989.                         if (strlen($var) != 19) {
  990.                             return false;
  991.                         }
  992.                     case "YYYY/MM/DD":
  993.                         if (!(substr($var82) >= "01" && substr($var82) <= "31")) {
  994.                             return false;
  995.                         }
  996.                         if (substr($var71) != "/") {
  997.                             return false;
  998.                         }
  999.                         if (strlen($var) != 10) {
  1000.                             return false;
  1001.                         }
  1002.                     case "YYYY/MM":
  1003.                         if (!(substr($var04) >= && substr($var04) <= 9999)) {
  1004.                             return false;
  1005.                         }
  1006.                         if (!(substr($var52) >= && substr($var52) <= 12)) {
  1007.                             return false;
  1008.                         }
  1009.                         if (substr($var41) != "/") {
  1010.                             return false;
  1011.                         }
  1012.                         if (strlen($var) != 7) {
  1013.                             return false;
  1014.                         }
  1015.                         break;
  1016.                     default:
  1017.                         return false;
  1018.                 }
  1019.                 if ($format == "YYYY/MM") {
  1020.                     $checkDay "$var/01";
  1021.                 } else {
  1022.                     $checkDay $var;
  1023.                 }
  1024.                 //日付の妥当性を確認
  1025.                 return checkdate(substr($checkDay52), substr($checkDay82), substr($checkDay04));
  1026.             case 4:    //電話、郵便番号
  1027.                 for ($i 0$i strlen($var); $i++) {
  1028.                     if (!(stristr("1234567890-"substr($var$i1)))) {
  1029.                         return false;
  1030.                     }
  1031.                 }
  1032.                 return $length >= strlen($var);
  1033.             case 5:    //分数
  1034.                 if (strlen($var) > $length) {
  1035.                     return false;
  1036.                 }
  1037.                 $check explode("/"$var2);
  1038.                 for ($i 0$i strlen($check[0]); $i++) {
  1039.                     if (!(stristr("0123456789"substr($check[0], $i1))) && $i == && substr($check[0], $i1) != "-") {
  1040.                         return false;
  1041.                     }
  1042.                 }
  1043.                 //文字に/が含まれている場合は、分母もチェック
  1044.                 if (strstr($var"/")) {
  1045.                     for ($i 0$i strlen($check[1]); $i++) {
  1046.                         if (!(stristr("0123456789"substr($check[1], $i1)))) {
  1047.                             return false;
  1048.                         }
  1049.                     }
  1050.                     //分母が0でないかチェック
  1051.                     if ($check[1] < 1) {
  1052.                         return false;
  1053.                     }
  1054.                 }
  1055.                 break;
  1056.             case 6:    //半角文字
  1057.                 for ($i 0$i strlen($var); $i++) {
  1058.                     if (!(stristr("abcdefghijklmnopqrstuvwxyz_-+*@1234567890./:?~:=ABCDEFGHIJKLMNOPQRSTUVWXYZ#&"substr($var$i1)))) {
  1059.                         return false;
  1060.                     }
  1061.                 }
  1062.                 return $length >= strlen($var);
  1063.             case 7:    //メール
  1064.                 return preg_match("/^[^@]+@[^.]+\..+/"$var);
  1065.             case 8:    //数字(小数)
  1066.                 for ($i 0$i strlen($var); $i++) {
  1067.                     if (!(stristr("0123456789."substr($var$i1)))) {
  1068.                         return false;
  1069.                     }
  1070.                 }
  1071.                 return (float)$var > (float)$length;
  1072.             default:
  1073.                 return $length >= strlen($var);
  1074.         }
  1075.         return true;
  1076.     }
  1077.     /***
  1078.      * @param $birthday
  1079.      * @return int
  1080.      */
  1081.     public function calculateAge($birthday): ?int
  1082.     {
  1083.         if (empty($birthday)) {
  1084.             return null;
  1085.         }
  1086.         $today = new \DateTime();
  1087.         $birthdate = new \DateTime($birthday);
  1088.         $age $today->diff($birthdate)->y;
  1089.         return $age;
  1090.     }
  1091.     public function getCacheKey($masterCacheKey$Datas)
  1092.     {
  1093.         $device $this->mobileDetector->isMobile() ? 'sp' 'pc';
  1094.         $suffix hash('sha256'base64_encode(serialize($Datas)));
  1095.         return "{$masterCacheKey}__{$device}__{$suffix}";
  1096.     }
  1097.     public function hasSusoage($Carts null)
  1098.     {
  1099.         //
  1100.         return GoodsService::isSusoageExistInJanIdList(array_map(function ($ProductClass) {
  1101.             //
  1102.             return $ProductClass->getId();
  1103.         }, $this->getEstimateProductClasses($Carts)));
  1104.     }
  1105.     public function hasKyouei($Carts null)
  1106.     {
  1107.         //
  1108.         return GoodsService::isKyoueiExistInJanIdList(array_map(function ($ProductClass) {
  1109.             //
  1110.             return $ProductClass->getId();
  1111.         }, $this->getAllProductClasses($Carts)));
  1112.     }
  1113.     public function hasShishu($Carts null)
  1114.     {
  1115.         if (!$Carts) {
  1116.             $Carts $this->CartHelper->getCarts();
  1117.         }
  1118.         $flag true;
  1119.         $hasProduct false;
  1120.         foreach ($Carts as $Cart) {
  1121.             //
  1122.             foreach ($Cart->getCartItems() as $CartItem) {
  1123.                 //
  1124.                 $options $CartItem->getOptions();
  1125.                 if ($CartItem->isProduct() && !empty($options)) {
  1126.                     $flagItem false;
  1127.                     $hasProduct true;
  1128.                     //
  1129.                     $options json_decode($optionstrue);
  1130.                     if (isset($options['print']) && is_array($options['print'])) {
  1131.                         $prints $options['print'];
  1132.                         foreach ($prints as $print) {
  1133.                             if ($print['position'] == 3) {
  1134.                                 $flagItem true;
  1135.                             }
  1136.                         }
  1137.                     }
  1138.                     $flag $flag && $flagItem;
  1139.                 }
  1140.             }
  1141.         }
  1142.         //
  1143.         return $flag && $hasProduct;
  1144.     }
  1145.     /**
  1146.      * @return ProductClass[]
  1147.      */
  1148.     public function getEstimateProductClasses($Carts null)
  1149.     {
  1150.         /**
  1151.          * @var ProductClass[] $ProductClasses
  1152.          */
  1153.         $ProductClasses = [];
  1154.         //
  1155.         if (!$Carts) {
  1156.             $Carts $this->CartHelper->getCarts();
  1157.         }
  1158.         foreach ($Carts as $Cart) {
  1159.             //
  1160.             foreach ($Cart->getCartItems() as $CartItem) {
  1161.                 //
  1162.                 if ($CartItem->isProduct() && !empty($CartItem->getOptions())) {
  1163.                     //
  1164.                     $ProductClasses[] = $CartItem->getProductClass();
  1165.                 }
  1166.             }
  1167.         }
  1168.         //
  1169.         return $ProductClasses;
  1170.     }
  1171.     public function hasNotEstimate($Carts null)
  1172.     {
  1173.         if (!$Carts) {
  1174.             $Carts $this->CartHelper->getCarts();
  1175.         }
  1176.         foreach ($Carts as $Cart) {
  1177.             //
  1178.             foreach ($Cart->getCartItems() as $CartItem) {
  1179.                 //
  1180.                 if ($CartItem->isProduct() && (!$CartItem->getEstimateId() || !$CartItem->getOptions())) {
  1181.                     //
  1182.                     return true;
  1183.                 }
  1184.             }
  1185.         }
  1186.         return false;
  1187.     }
  1188.     /**
  1189.      * @return ProductClass[]
  1190.      */
  1191.     public function getAllProductClasses($Carts null)
  1192.     {
  1193.         /**
  1194.          * @var ProductClass[] $ProductClasses
  1195.          */
  1196.         $ProductClasses = [];
  1197.         if (!$Carts) {
  1198.             $Carts $this->CartHelper->getCarts();
  1199.         }
  1200.         //
  1201.         foreach ($Carts as $Cart) {
  1202.             //
  1203.             foreach ($Cart->getCartItems() as $CartItem) {
  1204.                 //
  1205.                 if ($CartItem->isProduct()) {
  1206.                     //
  1207.                     $ProductClasses[] = $CartItem->getProductClass();
  1208.                 }
  1209.             }
  1210.         }
  1211.         //
  1212.         return $ProductClasses;
  1213.     }
  1214. }