プロジェクト

全般

プロフィール

Bug(バグ) #1594

Yuya Watanabe約12年前に更新

h3. Overview (現象)

デイリーニュースに1つ以上ガジェットが登録されている場合、
デイリーニュース配信タスクを実行するとエラーが表示され、デイリーニュースが1通も送信されない。

h5. 実行するタスク

<pre>
$./symfony openpne:send-daily-news
</pre>

h5. 表示されるエラー

<pre>
Call to undefined method myUser::getMember.
</pre>

h3. 再現バージョン

h5. OpenPNE

* OpenPNE 3.7.0-dev
* OpenPNE 3.6beta12

h5. php

* PHP 5.2.13
* PHP 5.3.3
* PHP 5.3.5

h3. Causes (原因)

h3. Way to fix (修正内容)

h3. 報告元

http://sns.openpne.jp/diary/25133 より転載

<pre>
デイリーニュースが送れない、です。
PHP5.3.3の所為??それとも、3.7.0-devだから??

【環境】
Powered by OpenPNE 3.7.0-dev
# ./symfony plugin:list
Installed plugins:
symfony 1.4.6-stable
openpne 3.7.0dev-beta
opAuthMailAddressPlugin 1.3.1-devel
opAuthMobileUIDPlugin 1.3.0-devel
opAuthOpenIDPlugin 1.3.0-beta
opCommunityTopicPlugin 1.0.0.2-stable
opWebAPIPlugin 0.4.0-beta
opDiaryPlugin 1.3.1-beta
opBlogPlugin 1.0.1-stable
opOpenSocialPlugin 1.2.0.1-stable
opAshiatoPlugin 0.9.1-stable
opMessagePlugin 0.9.1-beta
opAlbumPlugin 0.9.4-beta
opIntroFriendPlugin 0.9.0.1-beta
opFavoritePlugin 1.0.0.3-beta
opRankingPlugin 1.0.0-beta

FreeBSD 7.2-RELEASE-p8
Apache/2.2.16 (FreeBSD)
PHP 5.3.3 with Suhosin-Patch Zend Engine v2.3.0
mysql 5.1.36

【現象】
コマンドラインで
#./symfony openpne:send-daily-news
を実行すると

Call to undefined method myUser::getMember.

というエラーがでて、デイリーニュースが送れない。
</pre>

h3. 原因

下記コマンドを実行した時にデイリーニュース用のガジェットが表示可能かのロジックが正しくない.
<pre>
$ ./symfony openpne:send-daily-news
</pre>

lib/task/openpneSendDailyNewsTask.class.php の下記部分が実行され,61 行目が実行される.
<pre>
27 protected function execute($arguments = array(), $options = array())
28 {
...
56 $filteredGadgets = array();
57 if ($gadgets)
58 {
59 foreach ($gadgets as $gadget)
60 {
61 if ($gadget->isEnabled())
62 {
63 $filteredGadgets[] = array(
64 'component' => array('module' => $gadget->getComponentModule(), 'action' => $gadget->getComponentAction()),
65 'gadget' => $gadget,
66 'member' => $member,
67 );
68 }
69 }
70 }
</pre>

ここで isEnabled() を見てみると,sfContext で得られる getUser() で使えるかどうかを決定している.しかし,タスクで実行しているためここで得られる User は実際にメールを送信したい Member を含む User ではなくタスクを実行した時の User (ここでは apps/api/lib/myUser.class.php )である.エラー自体はここで User から getMember() を呼び出すことができないという問題であるが,エラーが発生していなくても正しく動作しないものと思われる.

lib/model/doctrine/Gadget.class.php
<pre>
66 public function isEnabled()
67 {
68 $list = $this->getGadgetConfigList();
69 if (empty($list[$this->name]))
70 {
71 return false;
72 }
73
74 $controller = sfContext::getInstance()->getController();
75 if (!$controller->componentExists($this->getComponentModule(), $this->getComponentAction()))
76 {
77 return false;
78 }
79
80 $member = sfContext::getInstance()->getUser()->getMember();
81 $isEnabled = $this->isAllowed($member, 'view');
82
83 return $isEnabled;
84 }
</pre>

h3. 修正案

表示可能かどうかを見たいメンバを Gadget の isEnable() メソッドの引数に与えるようにする.
<pre>
diff --git a/lib/model/doctrine/Gadget.class.php b/lib/model/doctrine/Gadget.class.php
index 4cb5053..80ab1cd 100644
--- a/lib/model/doctrine/Gadget.class.php
+++ b/lib/model/doctrine/Gadget.class.php
@@ -63,7 +63,7 @@ class Gadget extends BaseGadget implements opAccessControlRecordInterface
return $list[$this->name]['component'][1];
}

- public function isEnabled()
+ public function isEnabled($member = null)
{
$list = $this->getGadgetConfigList();
if (empty($list[$this->name]))
@@ -77,7 +77,10 @@ class Gadget extends BaseGadget implements opAccessControlRecordInterface
return false;
}

- $member = sfContext::getInstance()->getUser()->getMember();
+ if (is_null($member))
+ {
+ $member = sfContext::getInstance()->getUser()->getMember();
+ }
$isEnabled = $this->isAllowed($member, 'view');

return $isEnabled;
diff --git a/lib/task/openpneSendDailyNewsTask.class.php b/lib/task/openpneSendDailyNewsTask.class.php
index f70f082..3a7d9a9 100644
--- a/lib/task/openpneSendDailyNewsTask.class.php
+++ b/lib/task/openpneSendDailyNewsTask.class.php
@@ -58,7 +58,7 @@ EOF;
{
foreach ($gadgets as $gadget)
{
- if ($gadget->isEnabled())
+ if ($gadget->isEnabled($member))
{
$filteredGadgets[] = array(
'component' => array('module' => $gadget->getComponentModule(), 'action' => $gadget->getComponentAction()),
</pre>

戻る