プロジェクト

全般

プロフィール

Bug(バグ) #2008

Yuya Watanabe約12年前に更新

h3. Overview (現象)

config/OpenPNE.yml で80番以外のポート番号を含むURLをbase_urlに指定した場合、通知メール等に含まれるURLにポート番号が反映されない

h3. Environment (再現バージョン)

OpenPNE3.6beta8

h3. Way to repro (再現手順)

# config/OpenPNE.yml で80番以外のポート番号を含むURLをbase_urlに指定
# 招待メールを送ってみる
# 招待状本文中の「〜〜SNS に参加する」URLのリンクにポート番号が含まれない

例:<pre>
base_url: "http://sns.openpne.jp:8080"
</pre>→<pre>
...
■ ××××SNS に参加する
http://sns.openpne.jp/member/register/token/xyxyxyxyxyxyxyxy
...
</pre>

h3. Causes (原因)

parse_url(sfConfig::get('op_base_url')) の戻り値配列に含まれる port が使われていない

h3. Way to fix (修正内容)

* parse_url() の戻り値配列に含まれる port を保持.
* sfPatternRoutingを継承したクラス opPatternRouting を作成して修正.
* ベースにする URL は実際に生成するまで不明なため, opPatternRouting の generate() が呼び出されるときに決定するように修正を行った.


<pre>
diff --git a/lib/config/opApplicationConfiguration.class.php b/lib/config/opApplicationConfiguration.class.php
index cb69ad2..e6158f3 100644
--- a/lib/config/opApplicationConfiguration.class.php
+++ b/lib/config/opApplicationConfiguration.class.php
@@ -582,35 +582,9 @@ abstract class opApplicationConfiguration extends sfApplicationConfiguration sfConfig::set('sf_app', $application);
$configuration->setAppDir(sfConfig::get('sf_apps_dir').DIRECTORY_SEPARATOR.$application);

- $settings = sfDefineEnvironmentConfigHandler::getConfiguration($configuration->getConfigPaths('config/settings.yml'));
- $isNoScriptName = !empty($settings['.settings']['no_script_name']);
-
$options = $context->getRouting()->getOptions();
- $url = sfConfig::get('op_base_url');- if ('http://example.com' !== $url)
- {
- $parts = parse_url($url);
-
- $parts['path'] = isset($parts['path']) ? $parts['path'] : '';
- $options['context']['prefix'] =
- $this->getAppScriptName($application, sfConfig::get('sf_environment'), $parts['path'], $isNoScriptName);
-- if (isset($parts['host']))
- {
- $options['context']['host'] = $parts['host'];
- if (isset($parts['port']))
- {
- $options['context']['host'] .= ':'.$parts['port'];
- }
- }
- }
- else
- {
- $path = preg_replace('#/[^/]+\.php$#', '', $options['context']['prefix']);
- $options['context']['prefix'] = $this->getAppScriptName($application, sfConfig::get('sf_environment'), $path, $isNoScriptName);
- }

- $routing = new sfPatternRouting($context->getEventDispatcher(), null, $options);
+ $routing = new opPatternRouting($context->getEventDispatcher(), null, $options);
$routing->setRoutes($config->evaluate($configuration->getConfigPaths('config/routing.yml')));
$context->getEventDispatcher()->notify(new sfEvent($routing, 'routing.load_configuration'));

diff --git a/lib/routing/opPatternRouting.class.php b/lib/routing/opPatternRouting.class.php
new file mode 100644
index 0000000..9f8ac7e
--- /dev/null
+++ b/lib/routing/opPatternRouting.class.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * This file is part of the OpenPNE package.
+ * (c) OpenPNE Project (http://www.openpne.jp/)
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file and the NOTICE file that were distributed with this source code.
+ */
+class opPatternRouting extends sfPatternRouting
+{
+
+ public function generate($name, $params = array(), $absolute = false)
+ {
+ $app = sfConfig::get('sf_app');
+ $sslAppRequiredList = sfConfig::get('op_ssl_required_applications', array());
+ $sslActionRequiredList = sfConfig::get('op_ssl_required_actions', array($app => array()));
+
+ if (sfConfig::get('op_use_ssl', false)
+ && in_array($app, $sslAppRequiredList)
+ && isset($params['module']) && isset($params['action'])
+ && in_array($params['module'].'/'.$params['action'], $sslActionRequiredList[$app])
+ )
+ {
+ $this->options['context']['is_secure'] = true;
+ $sslBaseUrls = sfConfig::get('op_ssl_base_url');
+ $url = $sslBaseUrls[$app];
+ $isDefault = 'https://example.com' === $url;
+ }
+ else
+ {
+ $this->options['context']['is_secure'] = false;
+ $url = sfConfig::get('op_base_url');
+ $isDefault = 'http://example.com' === $url;
+ }
+
+ $parts = parse_url($url);
+
+ $configuration = sfContext::getInstance()->getConfiguration();
+ $settings = sfDefineEnvironmentConfigHandler::getConfiguration($configuration->getConfigPaths('config/settings.yml'));
+ $isNoScriptName = !empty($settings['.settings']['no_script_name']);
+
+ if (!$isDefault)
+ {
+ $parts['path'] = isset($parts['path']) ? $parts['path'] : '';
+ $this->options['context']['prefix'] =
+ $this->getAppScriptName($app, sfConfig::get('sf_environment'), $parts['path'], $isNoScriptName);
+
+ if (isset($parts['host']))
+ {
+ $this->options['context']['host'] = $parts['host'];
+ if (isset($parts['port']))
+ {
+ $this->options['context']['host'] .= ':'.$parts['port'];
+ }
+ }
+ }
+ else
+ {
+ $path = preg_replace('#/[^/]+\.php$#', '', $this->options['context']['prefix']);
+ $this->options['context']['prefix'] = $this->getAppScriptName($app, sfConfig::get('sf_environment'), $path, $isNoScriptName);
+ }
+
+ return parent::generate($name, $params, $absolute);
+ }
+
+ // equals opApplicationConfiguration#getAppScriptName
+ private function getAppScriptName($application, $env, $prefix, $isNoScriptName = false)
+ {
+ if ($isNoScriptName)
+ {
+ return $prefix;
+ }
+
+ if ('/' === $prefix)
+ {
+ $prefix = '';
+ }
+
+ $name = $prefix.'/'.$application;
+ if ($env !== 'prod')
+ {
+ $name .= '_'.$env;
+ }
+ $name .= '.php';
+
+ return $name;
+ }
+
+}
</pre>

h3. 備考

config/OpenPNE.yml.sample のように<pre>
base_url: "http://example.com"
</pre>が指定されていると、実際のリクエストからURLをポート番号込みで読み取って絶対URLを生成してくれる実装になっているが、op_base_url までは書き換えてくれないのでメールのフッタには http://example.com と表示される。

戻る