Drupal 7での柔軟なプロファイルの作成

更新済み:09.06.2012

Webformモジュールを変更せずに記事で説明されている機能を実装するWebform Multiple Conditionsモジュールを投稿します。



この記事では、アンケートやアンケートを作成するためにCMF Drupalでよく使用されるWebformモジュールのパッチを提案しました。 このパッチにより、管理インターフェースを介してフォームコンポーネントのいくつかの条件を指定し、それらの共同作業のロジックを制御できます。



はじめに



ウェブ開発者は、遅かれ早かれ、アンケートまたはアンケートを作成するタスクに直面すると思います。 もちろん、私たちの時代には、既成のソリューションを見つけることはそれほど難しくありません。ここにたくさんの選択肢があるのは良いことです。

上記の各オプションには長所と短所がありますが、ここでは焦点を当てませんが、仕事でDrupalを使用するすべての開発者に役立つ解決策を検討することを提案します。



動的な質問。



質問自体が前のページのユーザーの回答に依存し、サイト自体のエンド管理者に質問自体と作業のロジックを編集するための便利なインターフェースを提供する必要がある、いくつかの複雑で動的なアンケートを作成するタスクに直面するとします。

製品要件を示します。

  1. 管理インターフェースを介してアンケートを作成および編集するメカニズムが必要です。
  2. 複数のページにわたって徐々に質問を表示する機能が必要です。
  3. 特定の条件が満たされた場合にのみ質問を表示する機能。
  4. 条件には次のタイプがあります。「リストされた値の一部が選択されている」、「リストされた値の一部が選択されていない」、
  5. 一度に複数の条件が存在する可能性があります。
  6. 条件を組み合わせるときは、AND / OR演算子を使用できます。


このようなアンケートの例を次に示します。



画像



質問のある3つのページと結果のある1つのページがあります。 ユーザーが最初の2つの質問に「はい」と答えた場合、ページ2はまったく表示されない場合があります。 ユーザーが常に取得する3ページ目の質問の数は、最初の2つの質問に対する回答によって異なります。条件のみが「OR」によって既に結合されています。 お礼のテキストメッセージが常に結果ページに表示されます。 また、ユーザーが2ページ目を表示し、3番目の質問に肯定的に答えた場合、追加のテキストが表示されます。



Drupalで柔軟なプロファイルを作成します。



Drupal用に強力なWebformモジュールが開発れました。これは上記の要件の多くを実装するだけですが、残念ながらすべてではありません。

管理インターフェイスを使用してフォームを作成および編集したり、任意のコンポーネントをそれらに添付したり、コンポーネントに条件を追加したりすることもできますが、いくつかの条件を設定して結合することはできません。 さらに、 マークアップタイプの条件を割り当てることはできません。これにより、極端に静的なコンテンツを含む動的なフィードバックページを作成できなくなります。

この記事は、この欠点の修正に専念しています。

仕事には、次のものが必要です。

  1. Drupal 7.14
  2. Webform 7.x-3.18
DrupalWebformモジュールをインストールします。 その後、資料を追加するページ[コンテンツの追加-> Webform | / node / add / webform)に移動します。ここで、アンケートの名前を指定し、説明を入力します。

新しいノードを保存した後、編集用のページに戻り、[ Webform ]タブを選択します。

このタブで、質問とアンケートのページを担当するすべての必要なコンポーネントをフォームに添付します。



画像



質問を指定するために、テンプレート「question_X」に従ってコーディングを使用します。Xは質問のシリアル番号です。 簡単にするために、どこでも同じ答えを使用し、タイプSelectkey | output_value )のコンポーネントの要件に従ってエンコードします。



画像



2番目のページから始まる多くのコンポーネントについて、条件(条件ルール)を指定することができますが、1つだけであることに注意してください。



Webform機能の拡張



DrupalのWebformモジュールの動作を多少粗雑で非定型に変更し、時間を節約するために多くの変更を直接行うというタスクを解決します。 将来的には、それらを個別に分離し、個別のモジュールを作成することが可能になります( Webform Multiple Conditionsを参照)。

まず、インターフェイスを変更します。 コンポーネント設定ページに表示される可能な条件の数を1から10に増やしましょう。Drupal自体の要素には、 Forms API構造を返す関数が常にあります。 正確な名前を見つけるには、たとえばFirebugを使用するクライアントHTMLで、フォーム内にあるinput [name =” form_id”]要素の値を決定するだけで十分です。



画像



この場合、値は"webform_component_edit_form"です。 この関数は、ファイル"/webform/includes/webform.components.inc"にあります。



529行目から、条件の原因となるコードが始まります。 ここで、送信時にフォームへの入力を処理する関数( webform_component_edit_form_validatewebform_component_edit_form_submit )の機能を損なうことなく、変更する必要があります。

コードをデバッグすると、コンポーネントのすべての追加構成がコンポーネントテーブルの[追加]フィールドに格納されていることに気付くことができます。



画像



したがって、要素を10回複製するだけで拡張しても問題ありません。 マジックナンバー10を弱い定数にします。つまり、Drupal variable_get関数を使用して定義します。これにより、この値を変更するための管理インターフェイスを作成できるようになります。

条件付きコンポーネントを表すすべてのコードを次のものに置き換えます。

if ($conditional_components) { $extra_cond = array( 'conditional_component' => array( '#type' => 'select', '#title' => t('Component'), '#options' => webform_component_list($node, $conditional_components, FALSE, TRUE), '#description' => t('Select another component to decide whether to show or hide this component. You can only select components occurring before the most recent pagebreak.') ), 'conditional_operator' => array( '#type' => 'select', '#title' => t('Operator'), '#options' => array( '=' => t('Is one of'), '!=' => t('Is not one of') ), '#description' => t('Determines whether the list below is inclusive or exclusive.') ), 'conditional_values' => array( '#type' => 'textarea', '#title' => t('Values'), '#description' => t('List values, one per line, that will trigger this action. If you leave this blank, this component will always display.') ) ); $extra = $component['extra']; for ($i = 0; $i < variable_get('webform:max_conditional_rules', 10); $i++) { $condition_id = 'condition_'. $i; if (isset($extra[$condition_id]['values'])) { $condition_component_struct = $extra[$condition_id]['values']; $extra_cond['conditional_component']['#default_value'] = $condition_component_struct['conditional_component']; $extra_cond['conditional_operator']['#default_value'] = $condition_component_struct['conditional_operator']; $extra_cond['conditional_values']['#default_value'] = $condition_component_struct['conditional_values']; } $form['extra'][$condition_id] = array( '#type' => 'fieldset', '#title' => t('Conditional rule !num', array('!num' => $i + 1, )), '#collapsed' => TRUE, '#collapsible' => TRUE, '#tree' => TRUE, 'values' => $extra_cond, ); } }
      
      







チェックを実行します。 最初のページ以外のページにある任意のコンポーネントの設定ページに移動します。 条件付きコンポーネントの数が増えていることがわかります。

このフォームにもう1つ追加の設定を追加します。複数の条件が同時にある場合に、条件を満たした場合の最終結果を計算するアルゴリズムの選択です。 ANDORの 2つのアルゴリズムを考えてみましょう。 これを行うには、前のコードの後に​​、すぐに次を追加します。

 $form['extra']['algorithm'] = array( '#type' => 'select', '#options' => array( 'and' => t('AND'), 'or' => t('OR'), ), '#title' => t('Algorithm to evaluate conditions'), '#default_value' => isset($extra['algorithm']) ? $extra['algorithm'] : 'and', );
      
      







これで、一度にいくつかの条件とそれらを結合するためのアルゴリズムができました。これはすでに良好ですが、管理インターフェースからのみです。 最終クライアントWebフォームを処理するとき、ユーザーがフィールドに入力すると、多くても1つの条件で機能し、組み合わせアルゴリズムについては何も知らない古いコードが残ります。

このコードを見つけることは残っています。 クライアント側からフォームページに移動し([表示]をクリックするだけで)、対応する入力[name = "form_id"]を見つけます。



画像



その値はwebform_client_form_1と等しく、この関数を正確に検索すると、結果は嘆かわしいです。 しかし、ご存知のように、Drupalにはhook_forms()を介し最終関数のform_idに一致するルールを設定する方法があり、対応するフックが見つかった場合、コールバックwebform_client_formの指示があり、この関数には次の場所があります:

 /** * Implements hook_forms(). * * All webform_client_form forms share the same form handler */ function webform_forms($form_id) { $forms = array(); if (strpos($form_id, 'webform_client_form_') === 0) { $forms[$form_id]['callback'] = 'webform_client_form'; } return $forms; }
      
      





この関数(および送信時に実行される標準コールバック-webform_client_form_submit )には条件を処理するものはありませんが、そのコードを分析すると、送信されたコールバックのオーバーライドを次の方法で確認できます。

 $form['#submit'] = array('webform_client_form_pages', 'webform_client_form_submit');
      
      





webform_client_form_pages関数に進み 、その中に_webform_client_form_rule_checkの呼び出しを見つけましょう。これはTRUEまたはFALSEを返し、コンポーネントの表示またはスキップを制御します。 そして、これはまさに私たちが必要とするものです。

_webform_client_form_rule_checkでは$コンポーネント引数が関数に渡されます。これは、Webフォームの一部のコンポーネントの構成です。 そこからアルゴリズムとすべての条件に関する情報を取得します。

 $conditional_values = isset($component['extra']['conditional_values']) ? $component['extra']['conditional_values'] : NULL; $conditional_component = isset($component['extra']['conditional_component']) && isset($node->webform['components'][$component['extra']['conditional_component']]) ? $node->webform['components'][$component['extra']['conditional_component']] : NULL; $conditional_cid = $conditional_component['cid'];
      
      







また、最初にフラグを設定し、最終的に(選択したアルゴリズムに応じて)コンポーネントを表示するかどうかを決定します。

 $one_rule_passed = FALSE;
      
      





次のタスクは、次の直後に開始される即時検証コードを拡張することです。

 // Check the individual component rules. $show_component = $show_parent;
      
      





次のように進みます。各条件を順番に満たし、検証結果を配列で修正し、アルゴリズムに従って分析します。 「OR」アルゴリズムが使用される場合、少なくとも1つの正の結果が存在すると式全体が正になりますが、 「AND」アルゴリズムの場合、逆に1つの負の結果が式全体を負になります。

これを行うには、検証コードを次のコードに置き換えます。

 // Check the individual component rules. $show_component = $show_parent; if ($show_component && ($page_num == 0 || $component['page_num'] == $page_num) && $conditional_component && strlen(trim($conditional_values))) { $input_values = array(); if (isset($form_state)) { $input_value = isset($form_state['values']['submitted'][$conditional_cid]) ? $form_state['values']['submitted'][$conditional_cid] : NULL; $input_values = is_array($input_value) ? $input_value : array($input_value); } elseif (isset($submission)) { $input_values = isset($submission->data[$conditional_cid]['value']) ? $submission->data[$conditional_cid]['value'] : array(); } $test_values = array_map('trim', explode("\n", $conditional_values)); if (empty($input_values) && !empty($test_values)) { $show_component = FALSE; } else { foreach ($input_values as $input_value) { if ($show_component = in_array($input_value, $test_values)) { break; } } } if ($component['extra']['conditional_operator'] == '!=') { $show_component = !$show_component; } }
      
      







そして、アルゴリズムの結果の計算をすぐに決定します。

 // Make the final decision if ($component['extra']['algorithm'] == 'or') { $result = $one_rule_passed; } elseif ($component['extra']['algorithm'] == 'and') { $result = array_search(FALSE, $show_component) !== FALSE; } else { $result = TRUE; } // Allow other modules to alter conditional check result $context = array('node' => $node, 'component' => $component, 'show_component' => $show_component, 'one_rule_passed' => $one_rule_passed, ); drupal_alter('webform_conditional_rules_result', $result, $context); // Private component? if ($component['extra']['private']) { $result = webform_results_access($node); } return $result;
      
      





drupal_alterを呼び出すと、他のモジュールが必要に応じて結果を再定義できるようになります。これは、Drupal用のモジュールを開発するときに常に覚えておく必要があります。



これで、上記の記事で紹介したアンケートを実施するために必要なものがすべて揃いました。

これを行うには、管理インターフェイスでWebフォームコンポーネントのリストを含むページに戻り、 page_2コンポーネントのルールを設定します。



画像



3ページ目では、質問4のみにマッピングがあります(スキームに従って)。

  1. 質問1は[はい]の1つです
  2. 質問2は[いいえ]のいずれでもありません
  3. アルゴリズム「OR」を示します。


結果ページ4には、3番目の質問が肯定で答えられた場合にのみ追加情報が表示されます。

最後のコンポーネントのルールを定義します。

  1. 質問3は[はい]の1つです。


この記事で説明されているすべての手順を実行したら、クライアント側からフォームページに安全に移動し、必要なすべてが機能することを確認できます。



参照:




All Articles