一度、決めたベストアンサーを選び直し出来ないようにしたい。

Events happening in the community are now at Drupal community events on www.drupal.org.
bzj00220's picture

best answer というモジュールをインストールしました。
http://drupal.org/project/best_answer
これはいくつか書かれた回答のなかからベストアンサーを決めるためのモジュールです。

このモジュールは何回でもベストアンサーの選び直しができるような仕様になっているようです。

私の想定している使い方だとベストアンサーは1度、設定したら二度と変更できないようにしたいのですがそのような設定は出来るのでしょうか?
設定をいくら探してもそのような設定項目がないようなので教えて下さい。

もし、そのような設定項目がないようでしたらルールの設定などで選び直しを禁止する方法があればそれでも結構です。
いつも質問ばかりで申し訳ありません。
よろしくお願いします。

Comments

結局、モジュールをカスタマイズしました

bzj00220's picture

best answerモジュールの中のファイルbest_answer.moduleの原文と
翻訳したものを印刷して眺めていると
function _best_answer_update_best_answer
という文字をみつけました。

書かれているphpの意味はわからないのですが
コメント部分を読むとどこでどのような処理を行なっているかが
なんとなくわかったので、不要と思われる部分を
コメントアウトして試してみたところ
一度決めたベストアンサーを変更できなくなりました。

今のところ、不具合は起きておりません。

ベストアンサーを決めたあとでも
ベストアンサーを決めるための☆印が表示されている点がちょっと不満ですが
今の段階ではこれで我慢することにしました。

お騒がせしました。m(__)m

やっぱりダメでした

bzj00220's picture

上記のやり方でOKと思っていたのですが、
単純にコメントアウトしただけだと、
単にベストアンサーが選べなくなっていただけでした。

また、別の方法を探しています。
どなたかいい情報があったら教えて下さい。

blauerberg's picture

さらっとコードを見ただけですが、best_answer_node_view()の_best_answer_update_best_answer()を呼んでいる所で、

if ($best_answer) {

$lang = field_language('node', $question, 'field_best_answer');
if ($best_answer && isset($node->field_best_answer[$lang])) {

とかに直せばご希望の動きになるような気がします。
モジュール自体に手を入れるという解決策はイマイチなので、メンテナーの方に機能追加を依頼するか機能追加したパッチを送るのが一番良いです。

結局、外注さんにお願いしました

bzj00220's picture

blauerbergさんの方法も試してみたのですが上手く行かず、
結局、外注さんにお願いすることにしました。

モジュールを直すというよりも、別のモジュールを作ってもらって
ベストアンサーを選んだら、その後は変更できない仕組みにしてもらいました。
ありがとうございました。

blauerberg's picture

差し支えなければ、モジュールのコードを張ってもらえると、後々見た人が幸せになれます。

bzj00220's picture

そうですね。
こちらの掲示板にはお世話になっているので外注さんに聞いてみて問題がないようでしたら貼り付けます。

モジュールのコードです

bzj00220's picture

作って頂いた外注さんから了解が得られましたのでコードを公開します。
今後の方の参考になれば幸いです。

■best_answer_lock.info

; $Id: $
name = Best Answer Lock
description = Best Answerの選択されたベスト回答をロックします
core = 7.x
package = Answers
dependencies[] = best_answer
version = "7.x-0.3"

■best_answer_lock.install

<?php
// $Id$

/**
* @file
* Best Answerの選択されたベスト回答をロックします
*/

/**
* hook_uninstall()の実装
*/
function best_answer_lock_uninstall() {
variable_del('best_answer_lock_enabled');
}

■best_answer_lock.module

<?php
// $Id$

/**
* @file
* Best Answerの選択されたベスト回答をロックします
*/

/**
* hook_node_view()の実装
*/
function best_answer_lock_node_view($node, $view_mode = 'full') {
global $user;

// ベストアンサーを選択するとき確認画面を表示する
if ($node->type == 'question') {
$lock_flag = variable_get('best_answer_lock_enabled', 0);
if ($lock_flag == 0) {
return;
}
$best_answer = isset($_GET['best_answer_confirm']) ? check_plain($_GET['best_answer_confirm']) : NULL;
if ($best_answer) {
$form = drupal_get_form('best_answer_lock_confirm_form', $best_answer, $node->nid);
$node->content['best_answer_confirm'] = array(
'#type' => 'markup',
'#markup' => drupal_render($form),
);
return;
}
}

if ($node->type != 'answer') {
return;
}

$question = answers_field_get_node_reference($node, 'field_answer_question');
if ($user->uid != $question->uid) {
return;
}

$lock_flag = variable_get('best_answer_lock_enabled', 0);
if ($lock_flag == 0) {
return;
}

static $best_answer = array();
if (!isset($best_answer[$question->nid])) {
$answer_nid = best_answer_get_best_answer_nid($question->nid);
$best_answer = array();
$best_answer[$question->nid] = $answer_nid;
}

$answer_nid = $best_answer[$question->nid];
// ベストアンサーのノード?
if ($node->nid == $answer_nid) {
return;
}
// まだベストアンサーを選択していない
if ($answer_nid == 0) {
$redirect_path = url(
'node/' . $question->nid,
array(
'absolute' => TRUE,
'query' => array('best_answer_confirm' => $node->nid),
)
);
$node->content['select_best_answer']['#prefix'] = '';
$node->content['select_best_answer']['#suffix'] = '
';
return;
}

// ベストアンサー選択後は変えれなくする
$node->content['select_best_answer']['#prefix'] = '';
$node->content['select_best_answer']['#suffix'] = '';
$node->content['select_best_answer']['#disabled'] = TRUE;
}

/**
* hook_form_alter()の実装
*/
function best_answer_lock_form_alter(&$form, &$form_state, $form_id) {
if ($form_id != 'answers_settings') {
return;
}

$form['best_answer_settings']['best_answer_lock_enabled'] = array(
'#type' => 'checkbox',
'#title' => t('一度、ベストアンサーを選んだら変更できない'),
'#description' => t('チェックしますとベストアンサーの選び直しができなくなります。'),
'#default_value' => variable_get('best_answer_lock_enabled', 0),
);

// add in a submit handler before the standard handler
$form['#submit'][] = 'best_answer_lock_answers_settings_form_submit';
}

/**
* 設定内容(ロックするかどうかのフラグ)を保存
*/
function best_answer_lock_answers_settings_form_submit($form, &$form_state) {
$lock_flag = $form_state['values']['best_answer_lock_enabled'];
variable_set('best_answer_lock_enabled', $lock_flag);
}

/**
* ベストアンサー確認ページの生成
*/
function best_answer_lock_confirm_form($form, &$form_state, $best_answer, $question_nid) {
// submitに渡すパラメータをセット
$form['best_answer'] = array(
'#type' => 'value',
'#value' => $best_answer,
);
$form['question_nid'] = array(
'#type' => 'value',
'#value' => $question_nid,
);

// フォームを生成
$mynode = node_load($best_answer);
$msg = t('@titleをベストアンサーに設定します。よろしいですか?
※一度設定しますと元に戻せません',
array('@title' => $mynode->title));

$form['confirm'] = array('#type' => 'fieldset', '#title' => t('確認'));
$form['confirm']['actions'] = array('#type' => 'actions');
$form['confirm']['actions']['text'] = array('#markup' => '

' . $msg . '

');
$form['confirm']['actions']['ok'] = array(
'#type' => 'submit',
'#value' => t('OK'),
);
$form['confirm']['actions']['cancel'] = array(
'#type' => 'markup',
'#markup' => l(t('キャンセル'), 'node/' . $question_nid),
);

return $form;
}

/**
* ベストアンサー確認ページのサブミット
*/
function best_answer_lock_confirm_form_submit($form, &$form_state) {
$question_nid = $form_state['values']['question_nid'];
$best_answer = $form_state['values']['best_answer'];
$mynode = node_load($question_nid);
_best_answer_update_best_answer($mynode, $best_answer);
$form_state['redirect'] = 'node/' . $question_nid;
}

/**
* ベストアンサーのノードIDを取得
*/
function best_answer_get_best_answer_nid($question_nid) {
$result = db_query("select max(entity_id) as entity_id from {field_data_field_best_answer_p} " .
"where field_best_answer_p_value = 1 and entity_id in ( " .
"select entity_id from {field_data_field_answer_question} " .
"where field_answer_question_nid = :nid)",
array(':nid' => $question_nid));
$entity_id = $result->fetchField();
if (is_null($entity_id)) {
$entity_id = 0;
}
return $entity_id;
}

とても参考になります。

qchan's picture

bzj00220 さん、コード公開ありがとうございます。素晴らしい貢献だと思います。

コードを書かれた方にもコミュにティに参加してもらって情報交換できればいいですね。

日本 コミュニティ: Drupal Japan User Group

Group organizers

Group categories

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: