Open nanasess opened 3 weeks ago
個別の案件では、 <!--{if $arrErr.quantity != ""}-->
でエラーの有無をチェックせずに、<span class="attention"><!--{$arrErr.quantity}--></span>
が直接埋め込まれているコードが大量にあったため、以下のような modifier を作成しました
/**
* $arrErrに対してのみ利用する想定のmodifier
* $arrErrの中から指定したKeyのエラーを探して返す
*
* php8でのWarning対応のために作成。
* エラーが発生したときのみ$arrErrにKeyが設定される設計なので、テンプレート側でKeyが含まれない可能性を考慮する必要がある。
* 用途を$arrErrに限定することを明示するためにfind_errというmodifier名にしている。
*
* @param ?array $arrErr $arrErr配列。 nullのケースがありうる。
* @param string $key 探したいエラーのKey。
*
* @return string Keyに該当するValueを返す。Keyが存在しない場合はnullを返す。
*
* @example <span class="attention"><!--{$arrErr|find_err:"shop_kana"}--></span>
*/
function smarty_modifier_find_err(?array $arrErr, string $key)
{
if (!is_array($arrErr)) {
return null;
}
return $arrErr[$key] ?? null;
}
これなら簡潔に書けて正規表現で一括置換もできるので便利なのですが、 modifier の名前がいまいちなのと、直感的に何をしているか解りづらいので却下かなぁと。
|default
を使えばずいぶん簡潔にできそう。
$arrErr
が null の場合があるので、そこだけ PHP で空の配列を作成しておく必要がありそう。
thx: https://x.com/tadsan/status/1850198026817823213
diff --git a/data/Smarty/templates/default/products/list.tpl b/data/Smarty/templates/default/products/list.tpl
index 79300d2b6..24deaeae6 100644
--- a/data/Smarty/templates/default/products/list.tpl
+++ b/data/Smarty/templates/default/products/list.tpl
@@ -139,7 +139,7 @@
<!--{/if}-->
<!--{assign var=id value=$arrProduct.product_id}-->
- <!--{assign var=arrErr value=$arrProduct.arrErr}-->
+ <!--{assign var=arrErr value=$arrProduct.arrErr|default:[]}-->
<!--▼商品-->
<form name="product_form<!--{$id|h}-->" action="?">
<input type="hidden" name="<!--{$smarty.const.TRANSACTION_ID_NAME}-->" value="<!--{$transactionid}-->" />
@@ -204,10 +204,10 @@
<!--▼規格1-->
<dt><!--{$tpl_class_name1[$id]|h}-->:</dt>
<dd>
- <select name="classcategory_id1" style="<!--{$arrErr.classcategory_id1|sfGetErrorColor}-->">
- <!--{html_options options=$arrClassCat1[$id] selected=$arrProduct.classcategory_id1}-->
+ <select name="classcategory_id1" style="<!--{sfGetErrorColor($arrErr.classcategory_id1|default:'')}-->">
+ <!--{html_options options=$arrClassCat1[$id] selected=$arrProduct.classcategory_id1|default:''}-->
</select>
- <!--{if $arrErr.classcategory_id1 != ""}-->
+ <!--{if $arrErr.classcategory_id1|isset}-->
<p class="attention">※ <!--{$tpl_class_name1[$id]}-->を入力して下さい。</p>
<!--{/if}-->
</dd>
@@ -218,9 +218,9 @@
<!--▼規格2-->
<dt><!--{$tpl_class_name2[$id]|h}-->:</dt>
<dd>
- <select name="classcategory_id2" style="<!--{$arrErr.classcategory_id2|sfGetErrorColor}-->">
+ <select name="classcategory_id2" style="<!--{sfGetErrorColor($arrErr.classcategory_id2|default:'')}-->">
</select>
- <!--{if $arrErr.classcategory_id2 != ""}-->
+ <!--{if $arrErr.classcategory_id2|isset}-->
<p class="attention">※ <!--{$tpl_class_name2[$id]}-->を入力して下さい。</p>
<!--{/if}-->
</dd>
@@ -231,8 +231,8 @@
<!--{/if}-->
<div class="cartin clearfix">
<div class="quantity">
- 数量:<input type="text" name="quantity" class="box" value="<!--{$arrProduct.quantity|default:1|h}-->" maxlength="<!--{$smarty.const.INT_LEN}-->" style="<!--{$arrErr.quantity|sfGetErrorColor}-->" />
- <!--{if $arrErr.quantity != ""}-->
+ 数量:<input type="text" name="quantity" class="box" value="<!--{$arrProduct.quantity|default:1|h}-->" maxlength="<!--{$smarty.const.INT_LEN}-->" style="<!--{sfGetErrorColor($arrErr.quantity|default:'')}-->" />
+ <!--{if $arrErr.quantity|isset}-->
<br /><span class="attention"><!--{$arrErr.quantity}--></span>
<!--{/if}-->
</div>
diff --git a/data/class/SC_CartSession.php b/data/class/SC_CartSession.php
index 645d99764..7e938a0d0 100644
--- a/data/class/SC_CartSession.php
+++ b/data/class/SC_CartSession.php
@@ -157,6 +157,22 @@ class SC_CartSession
}
}
}
+ } else {
+ $this->cartSession[$product_type_id] = [];
+ }
+
+ // カート内商品の最大要素番号までの要素が存在しない場合、要素を追加しておく
+ for ($i = 0; $i <= $max; $i++) {
+ if (!array_key_exists($i, $this->cartSession[$product_type_id])) {
+ $this->cartSession[$product_type_id][$i] = [
+ 'price' => 0,
+ 'quantity' => 0,
+ 'productsClass' => [
+ 'product_id' => null,
+ 'product_class_id' => null,
+ ],
+ ];
+ }
}
return $max;
diff --git a/data/class/helper/SC_Helper_Maker.php b/data/class/helper/SC_Helper_Maker.php
index 3370ca6df..2f989797b 100644
--- a/data/class/helper/SC_Helper_Maker.php
+++ b/data/class/helper/SC_Helper_Maker.php
@@ -45,9 +45,9 @@ class SC_Helper_Maker
if (!$has_deleted) {
$where .= ' AND del_flg = 0';
}
- $arrRet = $objQuery->select('*', 'dtb_maker', $where, [$maker_id]);
+ $arrRet = $objQuery->getRow('*', 'dtb_maker', $where, [$maker_id]);
- return $arrRet[0];
+ return $arrRet;
}
/**
diff --git a/data/class/pages/products/LC_Page_Products_List.php b/data/class/pages/products/LC_Page_Products_List.php
index c97724b12..6d740a387 100644
--- a/data/class/pages/products/LC_Page_Products_List.php
+++ b/data/class/pages/products/LC_Page_Products_List.php
@@ -338,7 +338,7 @@ class LC_Page_Products_List extends LC_Page_Ex
if (strlen($arrSearchData['maker_id']) > 0) {
$objMaker = new SC_Helper_Maker_Ex();
$maker = $objMaker->getMaker($arrSearchData['maker_id']);
- $arrSearch['maker'] = $maker['name'];
+ $arrSearch['maker'] = isset($maker['name']) ? $maker['name'] : null;
}
// 商品名検索条件
$arrSearch['maker'] = isset($maker['name']) ? $maker['name'] : null;
は、Null 合体演算子で書けません?
$arrErr.quantity
とかは、Smarty でなんとかして欲しい気もしますが、そんな動きは無いですかね・・・
@seasoftjapan
$arrSearch['maker'] = isset($maker['name']) ? $maker['name'] : null; は、Null 合体演算子で書けません?
$arrSearch['maker'] = $maker['name'] ?? null;
でいけますね。ありがとうございます!
@seasoftjapan
$arrErr.quantity とかは、Smarty でなんとかして欲しい気もしますが、そんな動きは無いですかね・・・
Smarty の中の人は、
といった対応を推奨しているようです。 https://github.com/smarty-php/smarty/discussions/749#discussioncomment-3426453
$arrErr
は値を入れておくわけにもいかないので悩ましいですね
| 面倒なら黙らせる
diff --git data/class/SC_View.php data/class/SC_View.php
index bab1244bc..26854e0cd 100644
--- data/class/SC_View.php
+++ data/class/SC_View.php
@@ -85,6 +85,7 @@ public function init()
$this->registFilter();
// smarty:nodefaultsの後方互換を維持
$this->_smarty->registerFilter('pre', [$this, 'lower_compatibility_smarty']);
+ $this->_smarty->muteUndefinedOrNullWarnings();
}
// テンプレートに値を割り当てる
黙りますね。(PHP 8.2 で確認。)
default 修飾子でテンプレートの記述量を増やすよりは、サクッと黙らせた方が良い気もしますがどうでしょうか。
実行コストが若干気になりますが、商品一覧画面でざっとトレースした感じですと、少なくとも現状のように Warning をログに吐く状態よりはマシな様子です。
@seasoftjapan 今後、 Warning が Fatal へ昇格する可能性を考えると、できるだけ対応しておきたい想いはあります。 とはいえ、現状は 2.13 からのバージョンアップが多いことを考えると、デフォルトでは黙らせておいた方がよさそうですね。 tpl が1000ページくらいあったりすると、さすがに対応するのしんどいので。。。
確かに、今の Smarty の実装だと、Fatal になったら動作しなそうですね。 技術的には PHP コードにコンパイルするときに対処できるはずなので、個人的にはそう舵切りして欲しいものですが。
Smarty 5 は null 合体演算子にも対応しているようですので、これを使える段階になったら、回避方法に新たな選択肢が加わりそうに思います。
ちなみに、Smarty のコード読んだら
|default:''
は、
|default
でも良いみたいですね。
default_modifiers に default を加えるとかも妄想しましたが、流石に現状では muteUndefinedOrNullWarnings() の方がマシだと思います。
@seasoftjapan
Smarty 5 は null 合体演算子にも対応しているようですので、
いま、 Smarty 5.4.1 なので使えると思います!
いま、 Smarty 5.4.1 なので使えると思います!
Smarty 5 は PHP 7 サポート外で、Smarty 4 かと思っていました。 composer.lock 確認したら、確かに 5.4.1 ですね。
今の時点で Warning 回避のために大量に書き足すのは抵抗ありますが、いよいよ Fatal になって、その時点の muteUndefinedOrNullWarnings() も駄目となったら、default で書き足すよりも意図が分かりやすそうですね。パフォーマンスの影響も少なそうですし。
PHP8 以降で大量に発生する Warning の対処で、 個人的には、ちまちまと 三項演算子 や |default:'' を駆使しまくって対処しておりましたが、 $this->_smarty->muteUndefinedOrNullWarnings();で、黙らせる事ができるんですね!すばらしいですね。
それほど遠くない今後Warning から Fatal への昇格がぞくぞくとありえるので、 実運用では$this->_smarty->muteUndefinedOrNullWarnings();で黙らせつつ、 ここではサクッと対処出来るところから順次対処して頂いた方がありがたいです。 かなりボリュームがあると思いますが。
個人的に対処すればいいのではという考えもあるのですが、 公式で対処していかないと決済モジュール等も追随してくれないので、少しずつでも公式ここで対処して欲しいというのが希望です。
併せてWeeklyビルドだと、決済モジュール側が追随してくれないので年一でもよいので版を上げて欲しいです。
null 合体演算子(??
) を利用すると以下のようなパッチとなります。
diff --git a/data/Smarty/templates/default/products/list.tpl b/data/Smarty/templates/default/products/list.tpl
index 79300d2b6..388168579 100644
--- a/data/Smarty/templates/default/products/list.tpl
+++ b/data/Smarty/templates/default/products/list.tpl
@@ -139,7 +139,7 @@
<!--{/if}-->
<!--{assign var=id value=$arrProduct.product_id}-->
- <!--{assign var=arrErr value=$arrProduct.arrErr}-->
+ <!--{assign var=arrErr value=$arrProduct.arrErr ?? []}-->
<!--▼商品-->
<form name="product_form<!--{$id|h}-->" action="?">
<input type="hidden" name="<!--{$smarty.const.TRANSACTION_ID_NAME}-->" value="<!--{$transactionid}-->" />
@@ -204,10 +204,10 @@
<!--▼規格1-->
<dt><!--{$tpl_class_name1[$id]|h}-->:</dt>
<dd>
- <select name="classcategory_id1" style="<!--{$arrErr.classcategory_id1|sfGetErrorColor}-->">
- <!--{html_options options=$arrClassCat1[$id] selected=$arrProduct.classcategory_id1}-->
+ <select name="classcategory_id1" style="<!--{sfGetErrorColor($arrErr.classcategory_id1 ?? '')}-->">
+ <!--{html_options options=$arrClassCat1[$id] selected=$arrProduct.classcategory_id1 ?? ''}-->
</select>
- <!--{if $arrErr.classcategory_id1 != ""}-->
+ <!--{if $arrErr.classcategory_id1|isset}-->
<p class="attention">※ <!--{$tpl_class_name1[$id]}-->を入力して下さい。</p>
<!--{/if}-->
</dd>
@@ -218,9 +218,9 @@
<!--▼規格2-->
<dt><!--{$tpl_class_name2[$id]|h}-->:</dt>
<dd>
- <select name="classcategory_id2" style="<!--{$arrErr.classcategory_id2|sfGetErrorColor}-->">
+ <select name="classcategory_id2" style="<!--{sfGetErrorColor($arrErr.classcategory_id2 ?? '')}-->">
</select>
- <!--{if $arrErr.classcategory_id2 != ""}-->
+ <!--{if $arrErr.classcategory_id2|isset}-->
<p class="attention">※ <!--{$tpl_class_name2[$id]}-->を入力して下さい。</p>
<!--{/if}-->
</dd>
@@ -231,8 +231,8 @@
<!--{/if}-->
<div class="cartin clearfix">
<div class="quantity">
- 数量:<input type="text" name="quantity" class="box" value="<!--{$arrProduct.quantity|default:1|h}-->" maxlength="<!--{$smarty.const.INT_LEN}-->" style="<!--{$arrErr.quantity|sfGetErrorColor}-->" />
- <!--{if $arrErr.quantity != ""}-->
+ 数量:<input type="text" name="quantity" class="box" value="<!--{$arrProduct.quantity|default:1|h}-->" maxlength="<!--{$smarty.const.INT_LEN}-->" style="<!--{sfGetErrorColor($arrErr.quantity ?? '')}-->" />
+ <!--{if $arrErr.quantity|isset}-->
<br /><span class="attention"><!--{$arrErr.quantity}--></span>
<!--{/if}-->
</div>
diff --git a/data/class/SC_CartSession.php b/data/class/SC_CartSession.php
index 645d99764..7e938a0d0 100644
--- a/data/class/SC_CartSession.php
+++ b/data/class/SC_CartSession.php
@@ -157,6 +157,22 @@ class SC_CartSession
}
}
}
+ } else {
+ $this->cartSession[$product_type_id] = [];
+ }
+
+ // カート内商品の最大要素番号までの要素が存在しない場合、要素を追加しておく
+ for ($i = 0; $i <= $max; $i++) {
+ if (!array_key_exists($i, $this->cartSession[$product_type_id])) {
+ $this->cartSession[$product_type_id][$i] = [
+ 'price' => 0,
+ 'quantity' => 0,
+ 'productsClass' => [
+ 'product_id' => null,
+ 'product_class_id' => null,
+ ],
+ ];
+ }
}
return $max;
diff --git a/data/class/helper/SC_Helper_Maker.php b/data/class/helper/SC_Helper_Maker.php
index 3370ca6df..2f989797b 100644
--- a/data/class/helper/SC_Helper_Maker.php
+++ b/data/class/helper/SC_Helper_Maker.php
@@ -45,9 +45,9 @@ class SC_Helper_Maker
if (!$has_deleted) {
$where .= ' AND del_flg = 0';
}
- $arrRet = $objQuery->select('*', 'dtb_maker', $where, [$maker_id]);
+ $arrRet = $objQuery->getRow('*', 'dtb_maker', $where, [$maker_id]);
- return $arrRet[0];
+ return $arrRet;
}
/**
diff --git a/data/class/pages/products/LC_Page_Products_List.php b/data/class/pages/products/LC_Page_Products_List.php
index c97724b12..43f663bd5 100644
--- a/data/class/pages/products/LC_Page_Products_List.php
+++ b/data/class/pages/products/LC_Page_Products_List.php
@@ -338,7 +338,7 @@ class LC_Page_Products_List extends LC_Page_Ex
if (strlen($arrSearchData['maker_id']) > 0) {
$objMaker = new SC_Helper_Maker_Ex();
$maker = $objMaker->getMaker($arrSearchData['maker_id']);
- $arrSearch['maker'] = $maker['name'];
+ $arrSearch['maker'] = $maker['name'] ?? null;
}
// 商品名検索条件
方針をまとめると、以下のような感じですね
$this->_smarty->muteUndefinedOrNullWarnings()
で黙らせる
refs #999
現在、 PHP8 で発生している Warning も解消していきたいのですが、商品一覧ページを対応してみたところ、以下のパッチのようなコードになってしまいます。 特に
$arrErr
の未定義要素のチェックに三項演算子を使用していますが、もう少し簡潔な記述ができないものかと悩んでおります。 良いアイディアがありましたらご意見ください🙇♂️