プロジェクト

全般

プロフィール

Bug(バグ) #837

プロフィール項目設定の文字数制限でmax=0,min=0と設定できてしまう

Kiwa Sakai約14年前に追加. 6年以上前に更新.

ステータス:
Fixed(完了)
優先度:
Normal(通常)
担当者:
対象バージョン:
開始日:
2010-03-11
期日:
進捗率:

100%

3.6 で発生するか:
Yes
3.8 で発生するか:
Unknown (未調査)

説明

現象

OpenPNE2→OpenPNE3のコンバート時、プロフィール項目で入力文字数の最小・最大を指定していなかったものがコンバート後に0~0文字になってしまう。
そのため、コンバート直後にプロフィールを編集すると「0文字以内で入力してください」というエラーメッセージが表示されてしまう。
コンバートでない場合でも、プロフィール項目の設定でmax=0,min=0と設定できてしまい、同様の不具合が起きる。

現象確認バージョン

OpenPNE3.0.9-dev
OpenPNE3.2.7-dev
OpenPNE3.4.7-dev
OpenPNE3.6beta1-dev

再現手順

1. OpenPNE2で以下のプロフィール項目を作成する

  • 項目名: 氏名
  • フォームタイプ: テキスト
  • 入力値タイプ: 文字列
  • 最小値~最大値: null ~ null
  • 正規表現: null

2. OpenPNE2→OpenPNE3のコンバートを行う
3. コンバート後、OpenPNE3の管理画面から1で作成したプロフィール項目の編集画面を開く
4. 最小値~最大値が 0~0 になっている


関連するチケット

関連している OpenPNE 3 - Backport(バックポート) #1274: プロフィール項目設定の文字数制限でmax=0,min=0と設定できてしまう Won't fix(対応せず) 2010-03-11
関連している OpenPNE 3 - Backport(バックポート) #1275: プロフィール項目設定の文字数制限でmax=0,min=0と設定できてしまう Fixed(完了) 2010-03-11
関連している OpenPNE 3 - Backport(バックポート) #1276: プロフィール項目設定の文字数制限でmax=0,min=0と設定できてしまう Fixed(完了) 2010-03-11
関連している OpenPNE 3 - Backport(バックポート) #1386: プロフィール項目設定の文字数制限でmax=0,min=0と設定できてしまう Fixed(完了) 2010-03-11
関連している OpenPNE 3 - Bug(バグ) #1449: opFormItemGenerator::generateValidator() の 数値用バリデータ生成時 ValueMax, ValueMin が 0の場合は 範囲指定されない Fixed(完了) 2010-07-28
関連している OpenPNE 3 - Bug(バグ) #940: プロフィール項目の日付やテキストの最小値を最大値より大きくして設定できてしまう Pending Fixing(修正待ち) 2010-04-05
関連している OpenPNE 3 - Bug(バグ) #1595: ProfileForm で日付型のプロフィール項目の最大値・最小値の入力欄に now などの strtotime() が解釈できる文字列を入力すると、そのプロフィール項目を保存した時点の日付が DB に保存されてしまう Fixed(完了) 2010-09-17
関連している OpenPNE 3 - Bug(バグ) #1478: OpenPNE2コンバーターでc_profileのval_maxおよびval_minの仕様の違いを吸収できていない Fixed(完了) 2010-08-04

関係しているリビジョン

リビジョン d41df217 (差分)
Minoru Takai13年以上前に追加

(fixes #837) changed to invalidate min/max limit, if (min,max) tuple is invalid (i.e. min>max or max<1)

リビジョン 808691c0 (差分)
Minoru Takai13年以上前に追加

(fixes #837, BP from #1276) changed to invalidate min/max limit, if (min,max) tuple is invalid (i.e. min>max or max<1)

履歴

#1 Shogo Kawahara約14年前に更新

2系から3系にコンバートするとき、
2系のDB上(c_profile)では値がないときdefaultとして0がセットされており、
3系ではmax, minともに0に変換されます。

これはコンバートの問題ではなく、max=0,min=0であったときは、
文字数制限をかけないなどの対応をするのが適切かと思います。

#2 Mutsumi Imamuraほぼ14年前に更新

  • 題名2系で入力文字数を指定していなかったプロフィール項目の文字数制限が、コンバート後に0~0文字になる から プロフィール項目設定の文字数制限でmax=0,min=0と設定できてしまう に変更
  • 対象バージョンOpenPNE 3.6beta1 にセット

#3 Kousuke Ebiharaほぼ14年前に更新

  • 対象バージョンOpenPNE 3.6beta1 から OpenPNE 3.7.0 に変更

#4 Minoru Takaiほぼ14年前に更新

  • ステータスNew(新規) から Accepted(着手) に変更
  • 担当者Minoru Takai にセット

#5 Minoru Takai13年以上前に更新

コンバート後の挙動を確認しました。

少なくとも2系では、最小値、最大値に関する制限が全くなく、min > max であるような指定や、文字列の長さとして負値を設定するようなことが可能になっています。

今回の問題は、最小値、最大値を未指定にしていた場合、コンバートすると3系で min, max が 0, 0 となってしまうというものですが、これは文字列の長さに関しては対応の仕様があるものの、数値の下限上限に関しては自然な対応が思いつきません。

数値に関して、2系で明示的に (min, max) = (1, 5) と指定していれば、数値として 1~5 が許されるプロフィール項目を意味します。 (min, max) = (1, 1) であれば 1 のみが許される項目になります。ここで、 (min, max) = (0, 0) が指定されていれば 0 のみが許される項目と考えるのが自然かと思われますが、これを (min, max) = (NULL, NULL) とみなすという対応は自然でしょうか。

と、ここまで書きましたが、

2系から3系にコンバートするとき、

2系のDB上(c_profile)では値がないときdefaultとして0がセットされており、
3系ではmax, minともに0に変換されます。

と示されている通り、2系では明示的に指定していても、(min, max) = (0, 0) の場合は下限上限なしという判断になっていました。ここで2つの対応方法が考えられます。

  • (1) 2系の設計が悪いだけなので、3系では特に何も対応しない(コンバート直後は min, max が 0, 0 になるが、それをプロフィール設定で変更してもらうことを仕様とする)。
  • (2) コンバート直後に「0文字以内で入力してください」というエラーが出ることを問題であると考え、(min, max) = (0, 0) だけは例外的に範囲指定がされていないものとして扱う。

文字列の長さに関して (min, max) = (0, 0) になるのが問題であると思っていたので、後者の対応を考えていましたが、数値の下限上限を考えると前者の方が好ましいように思いました(後者による対応は、数値 0 のみを入力として許すプロフィール項目の作成手段を提供しないことになります)。

コンバート直後に「0文字以内で入力してください」というエラーが出ることが問題かどうかの認識によって対応方法が異なるということを示しておきます。

#6 Minoru Takai13年以上前に更新

対応方法を更に示します。

  • (3) コンバート時に (min, max) = (0, 0) であるレコードを (NULL, NULL) に変換して保存する
  • (4) コンバート後に、どこかのタイミングで (0, 0) であるプロフィール項目の最小値最大値を持つレコードの値を (NULL, NULL) に変更する

(2)と(4) を併せた対応を考えていますが、修正すべきソースコードの箇所が分からず調査中です。

#7 Minoru Takai13年以上前に更新

対応方針

lib/util/opFormItemGenerator.class.php
generateValidator() メソッド内

    if ($field['ValueType'] === 'integer' || $field['FormType'] === 'date')
    {
      if (!empty($field['ValueMin']))
      {
        $option['min'] = $field['ValueMin'];
      }
      if (!empty($field['ValueMax']))
      {
        $option['max'] = $field['ValueMax'];
      }
    }
    else
    {
      if (isset($field['ValueMin']))
      {
        $option['min_length'] = $field['ValueMin'];
      }
      if (isset($field['ValueMax']))
      {
        $option['max_length'] = $field['ValueMax'];
      }
    }

後半 else ブロック内で、isset() に加えて、max > 0 という条件を与えます。
更に、2系あるいは #940 修正前の3系にて、大小関係が不正な (min, max) が指定されたプロフィール項目がある場合にも対応できるよう、 min <= max という if 文をラップします。

if (isset($field['ValueMax'])) ブロック内の末に以下の記述を追記します。

        if (1 > (int)$field['ValueMax'] || (isset($field['ValueMin']) && (int)$field['ValueMin'] > (int)$field['ValueMax']))
        {
          unset($option['min_length']);
          unset($option['max_length']);
        }

#8 Minoru Takai13年以上前に更新

  • ステータスAccepted(着手) から Pending Review(レビュー待ち) に変更
  • 進捗率0 から 50 に変更

更新履歴 d41df217719462f71f29c6f30b0b4ae549b627ed で適用されました。

#9 Shogo Kawahara13年以上前に更新

  • ステータスPending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
  • 進捗率50 から 70 に変更

#1449 での変更と合わさって若干冗長なコードになっている気もしますが、別問題としとします。

#10 Kousuke Ebihara13年以上前に更新

  • 3.6 で発生するかYes にセット

#11 Minoru Takai13年以上前に更新

  • ステータスPending Testing(テスト待ち) から Pending Review(レビュー待ち) に変更
  • 進捗率70 から 50 に変更

更新履歴 808691c0eaf4fbfb7fb5ffcd56ad8030634f0aae で適用されました。

↑3.4のコミットです

#12 Minoru Takai13年以上前に更新

  • ステータスPending Review(レビュー待ち) から Pending Testing(テスト待ち) に変更
  • 進捗率50 から 70 に変更

ステータスを正しいものに戻します。

#13 Fumie Toyooka12年以上前に更新

  • ステータスPending Testing(テスト待ち) から Fixed(完了) に変更
  • 進捗率70 から 100 に変更

テストOKです。

他の形式にエクスポート: Atom PDF