Bug(バグ) #2366
Minoru Takai さんが13年以上前に更新
h3. Overview (現象) 新規にOpenPNE3.4をインストールし、/messageに遷移すると以下のようなFatal errorが発生する。 /message/sendListなどでも同様のエラーが発生する。 Fatal error: Call to undefined function op_link_to_member() in /home/user/sns/34x.example.jp/plugins/opMessagePlugin/apps/pc_frontend/modules/message/templates/listSuccess.php on line 135 ※原因がplugin側にあるという確証を得る調査はまだ行われていないため、このチケットの作成プロジェクトに誤りがあった場合、作成すべきプロジェクトに変更して下さい。 h3. 再現バージョン * OpenPNE3.4.16 h3. 再現ブランチ * remotes/origin/stable-3.4.x h3. 再現手順 1. 新規にOpenPNE3.4を設置する(この際使用するbranchはremotes/origin/stable-3.4.x) 2. OpenPNE君で(/message)に遷移する h3. Causes (原因) op_link_to_member() は #840 によって追加されたヘルパー関数だが、 #840 の対応内容の事情により 3.4 向けのバックポートは行なわれていなかった。 つまり 3.4 系ではこの関数は使えないことになる。しかし、コア側とバージョンが対応しないプラグインにおいて op_link_to_member() を使っている箇所があり、今回の問題が生じている。 発覚しているのは opMessagePlugin であり、このプラグインで op_link_to_member() を使ったのは 0.9.2 からであるらしい。 opMessagePlugin-0.9.2 がバンドルされているのは OpenPNE-3.4.15, OpenPNE-3.6beta12 からである。 h3. Way to fix (修正内容) 考えられる修正方針を示しておきます。思いついたものを示しているだけで、これに限るわけではありません。 * opMessagePlugin-0.9.2 では op_link_to_member() が定義されていることを前提とすることを許し、 ** (1) OpenPNE-3.4.15 以降では opMessagePlugin-0.9.1 以前をバンドルするようにする ** (2) OpenPNE-3.4.15 以降で、 op_link_to_member() を定義する(関数を定義するだけで、 #840 で定義された関数と同等の処理を実装する必要はない) * OpenPNE-3.4 系では op_link_to_member() が定義されていないことを前提とし、 ** (3) OpenPNE-3.4.15 以降では opMessagePlugin-0.9.1 以前をバンドルするようにする ** (4) opMessagePlugin-0.9.2 で op_link_to_member() が定義されているかどうかを確認した上でコールするようにする *** コールしている箇所が少なければ (4) を採用してもよいかもしれないが、コア側で定義されているかどうかを多くの箇所で気にする必要があるのであれば を採用してもよいかもしれませんが、コア側で定義されているかどうかを多くの箇所で気にする必要があるのであれば (5) または (6) の対応が考えられる。 の方が適切でしょう。 *** しかし、 (5) にも (6) にも回避しなければならない問題があるため (4) の対応が簡単かもしれない。 ** (5) opMessagePlugin-0.9.2 で op_link_to_member() が定義されていなければその関数を定義する(関数の実装は #840 と同等の処理である必要はありません:未定義の関数が呼ばれることを避けるだけで十分です) <pre> // PHP では以下のようなことが可能です function op_link_to_member() { return 'defined in core'; } if (!function_exists('op_link_to_member')) { function op_link_to_member() { return 'defined in opMessagePlugin'; } } var_dump(op_link_to_member()); </pre> *** この対応は、コア側のヘルパー関数の定義が先に読み込まれていることを前提としなければならない。 ** (6) opMessagePlugin-0.9.2 では op_link_to_member() を直接使わず、 opMessagePlugin 独自の op_bc_link_to_member() などを定義して使う(bc は Backward Compatible の意)。 *** op_link_to_member() をコールしたい箇所では op_bc_link_to_member() を呼び、 opMessagePlugin ではヘルパー関数として次のような関数を定義する <pre> function op_bc_link_to_member($value, $options = array(), $routeName = '@obj_member_profile') { if (!function_exists('op_link_to_member')) { return op_link_to_member($value, $options, $routeName); } return link_to($member->getName(), 'member/profile?id='.$value; } </pre> *** しかし op_bc_link_to_member() という関数で対応してしまうと、同じ発想で別のプラグインが対応できなくなる問題が生じる。 **** だからといって op_bc_link_to_member() 自体が定義済みかどうかを確認するのは冗長ではないか(そもそもこのような場合に (6) の対応を取ることや、その場合の関数名の命名規則についての共通認識がないことは好ましくない)。 **** しかし op_message_bc_link_to_member() のようにプラグイン名を紐付けて関数の多重定義の衝突を防ぐにしても、その関数名がどのような名前であると適切かについて考えなければならない。 ※ 「OpenPNE-3.4.15 以降で」や「opMessagePlugin-0.9.2 で」と書いていますが、これらのバージョンは既にリリースされているため、これに後続するバージョンで対応する必要があります。