Bug(バグ) #4055
Youichi Kimura さんがほぼ8年前に更新
h3. Overview (現象) OpenPNE が http://example.com/sns/ のようにサブディレクトリ以下に設置されている場合に、通知センターから日記等にアクセスする場合、http://example.com/sns/diary/1 のようなURLになるべきであるが、http://example.com/diary/1 にアクセスしてしまう。 h3. Causes (原因) 通知センターに表示される通知のリンク先は、@opNotificationCenter::notify()@ の @url@ パラメーターによって指定される。 source:web/js/jquery.notify.js にて window.location に linkUrl を設定しているが linkUrl には、「/diary/1」等が設定されているため、そのまま window.location に設定すると、サブディレクトリが無視されてしまう。 <pre><code class="javascript"> このパラメーターを実装した当初は @diary/show?id=1@ や <code>@diary_show?id=1</code> のような @url_for@ ヘルパーに指定するための Internal URI の形式を想定していた。 $.fn.pushLink = function(settings){ settings = $.extend({ isDisableRead: false, }, settings); return this.each(function(){ var linkUrl = $(this).attr('data-location-url'); var notifyId = $(this).attr('data-notify-id'); $(this).click(function(){ if ( false == settings.isDisableRead ) { $.getJSON( openpne.apiBase + 'push/read.json' , { 'id': notifyId, 'apiKey': openpne.apiKey }, function(d){ window.location = linkUrl; }); } else { window.location = linkUrl; } }); }); しかし、実際には誤った実装によって Internal URI での指定は正しく機能していない状態となっていた。 }; (opJsonApiHelper が実行されるのは api アプリケーションであるため、@url_for@ ではなく @app_url_for@ を呼び出すのが正しい) source:apps/api/lib/helper/opJsonApiHelper.php@8205623#L203 <pre><code class="php"> 'url' => $notification['url'] ? url_for($notification['url'], array('abstract' => true)) : null, </code></pre> 通知センターによる通知機能を提供するプラグイン等では、上記の不具合を避けるために Internal URI ではなく @/diary/1@ などの URI を直接出力することで目的の URI へのリンクを実現している。 しかし、@/diary/1@ などの URI を指定した場合には、本来 @url_for@ や @app_url_for@ であれば自動的に付加されるサブディレクトリ部分の相対パス (@sfWebRequest::getRelativeUrlRoot()@ に相当) が付加されないため、当チケットで報告されているような OpenPNE をサブディレクトリに設置した場合のリンクの不具合が生じる。 h3. Way to fix (修正内容) JSON API の @/api.php/push/search.json@ の実装を修正し、@opNotificationCenter::notify()@ の @url@ パラメーターに Internal URI が指定された場合でも正しく動作するようにする。この場合は、API 実行時にサブディレクトリを考慮した URI が生成されるものとする。 また、@/diary/1@ のような URI を直接 @url@ パラメーターに指定していたプラグイン等との互換性を保つため、先頭が @/@ から始まる URI であった場合には @app_url_for@ ヘルパーを介さずに直接文字列を出力するように対応する。 #3365 にて追加された openpne.baseUrl を利用して、window.location にURLを設定する。 この場合は、API 側ではサブディレクトリ部分の付加は行わずに出力する。これは、opLikePlugin のようにプラグイン側で独自にサブディレクトリ部分を付加した URI を @url@ パラメーターに指定している実装が存在しており、一律な対応を執ることが困難なためである。