web-dev-qa-db-ja.com

Profile2モジュールのフィールドに基づいてノード作成フォームのフィールドに事前入力する方法は?

ビジネスアカウントが求人を一覧表示するために使用できるコンテンツタイプ(「求人一覧」)と、ビジネスの住所、組織名、業種などの分類用語を含む各ビジネスのProfile2プロファイルがあります。

求人情報を掲載する企業の95%が同じ情報を使用します。プロフィール情報をそのまま使用することもできますが、求人情報フォームを変更したい5%を考慮する必要があります。たとえば、仕事が別の州または国にあり、それを説明する必要がある場合があります。この状況を処理する最良の方法は、プロフィールと求人の一覧フォームの両方に同じフィールドを設定することですが、企業が求人の一覧フォームの情報を変更できるようにすることです。

デフォルトでビジネスプロフィール情報を使用して求人リストフォームに事前入力することは理にかなっています。これを行うにはどうすればよいですか?ルールを使用する予定でしたが、元のノード作成フォームが作成される前に、ルールの単一のオプションが見つかりません。

hook_form_alter()を使用して元のノードの作成に関するプロファイル情報にアクセスし、その情報を使用してデフォルト値を設定する必要がありますか?

7
Adam S

ノードがNIDを持っているかどうかを確認するためにテストするヘルパーモジュールにhook_form_FORM_ID_alter()関数を作成しました。次に、フォームのデフォルト値に会社のプロファイル情報を入力して、後で変更できるようにします。

// We need to set the default of the Job Listing fields on a new Job Listing form */
function helper_form_job_listing_node_form_alter(&$form, &$form_state) {
  // test if node for has been assigned a NID. If not then populate fields with default data */
  if (empty($form['nid']['#value']) && (!isset($form['#node']->op))){
    $profile = profile2_load_by_user ($form['uid']['#value'], 'business_profile'); 
    // We currently do not know what the profile language is */
    // Organization name
    if (isset($profile->field_job_organization['und'][0]['value'])){
      $form['field_job_organization']['und'][0]['value']['#default_value'] =  $profile->field_job_organization['und'][0]['value'];
    }
    // Set the default address
    if (isset($profile->field_resume_address['und'][0]['thoroughfare'])) {
      $form['field_resume_address']['und'][0]['#address']['thoroughfare'] = $profile->field_resume_address['und'][0]['thoroughfare'];
    }
    if (isset($profile->field_resume_address['und'][0]['locality'])) {
      $form['field_resume_address']['und'][0]['#address']['locality'] = $profile->field_resume_address['und'][0]['locality']; 
    }
    if (isset($profile->field_resume_address['und'][0]['administrative_area'])) {
      $form['field_resume_address']['und'][0]['#address']['administrative_area'] = $profile->field_resume_address['und'][0]['administrative_area'];                  
    }
    if (isset($profile->field_resume_address['und'][0]['country'])) { 
      $form['field_resume_address']['und'][0]['#address']['country'] = $profile->field_resume_address['und'][0]['country'];  
    }
    if (isset($profile->field_resume_address['und'][0]['premise'])) {
      $form['field_resume_address']['und'][0]['#address']['premise'] = $profile->field_resume_address['und'][0]['premise']; 
    }
    if (isset($profile->field_resume_address['und'][0]['postal_code'])) {
      $form['field_resume_address']['und'][0]['#address']['postal_code'] = $profile->field_resume_address['und'][0]['postal_code']; 
    }  
  }                                                              
}
7
Adam S

同じ要件があり、上記のコードを使用して開始しました。残念ながら、上記のコードは複数の国の選択を考慮していないため、国固有のフィールド(州、州など)の動的フィールドの性質を考慮に入れています。住所フィールドを事前入力するための新しい機能を組み合わせましたが、適切な国に切り替えることができました。

= mrfelton drupal commerceの同様の住所集団機能の patch を書いた人)から、これを行う方法に関するコードのスニペットを受け取りました。ありがとうそのインスピレーションのために。

これが、フィールドアドレスデータを事前入力するために使用した私の関数です。これを改善し、コミュニティに還元してください。


    //method to prepopulate the address field including switching to the right country context
function field_prepopulate_field_widget_form_alter(&$element, &$form_state, $context) {
    // Forms where the pre-population is supposed to occur
    $validforms = array(
            "job_listing_node_form",
            "job_editing_node_form",
            "some_other_node_form"
    ); 

    // Check that I am on the right form
    if(in_array($form_state['build_info']['form_id'], $validforms)) {
        // Check that I am changing the right field
        if($context['field']['field_name'] == 'field_address') {
            global $user;
            $user_fields = user_load($user->uid);
            if (isset($user_fields->field_address) && !empty($user_fields->field_address)) {
                // use field_get_items function to avoid the entire language nonsense (tongue-in-cheek) in the array
                $address_data = field_get_items('user', $user_fields, 'field_address');
                //This may look redundant but is important - fill the address fields out once so that the right country is set
                foreach($address_data[0] as $key => $value) {
                    $context['items'][$context['delta']][$key] = $value;
                }
                // regenerate the widget so that the right country specific fields are rendered
                $format = addressfield_field_widget_form($context['form'], $form_state, $context['field'], $context['instance'], $context['langcode'], $context['items'], $context['delta'], array());

                // Switch out the form elements with our newly generated ones.
                foreach ($element as $key => $value) {
                    if (isset($format[$key])) {
                        $element[$key] = $format[$key];
                    }
                }

                // Set the detault values.
                $element['#address'] = $address_data[0];
            }
        }
    }
}

4
christowm

endless summerからの回答に基づいて、より一般的な(ただし完全ではない)モジュールを作成しました。これは、プロファイルとノードのフィールド名が同じであり、指定されたプロファイルのすべてのフィールドに事前入力されることを前提としています。

function helper_form_job_listing_node_form_alter(&$form, &$form_state) 
{
    if (!empty($form['nid']['#value']) || isset($form['#node']->op))
    {
        return;
    }
    $profile = profile2_load_by_user ($form['uid']['#value'], 'business_profile'); 
    if (isset($profile)) {
        helper_prepopulate($profile, $form);
    }                                                              
}

function helper_prepopulate(&$source, &$destination) 
{
    foreach($source as $fieldName => $sourceValue)
    {
        if(substr($fieldName, 0, strlen('field_')) !== 'field_' ||
            !isset($destination[$fieldName]['und'][0]) ||
            !isset($sourceValue['und'][0])) 
        { 
            continue; 
        }
        if(isset($destination[$fieldName]['und'][0]['#addressfield']) &&
            $destination[$fieldName]['und'][0]['#addressfield'])
        {
            foreach($sourceValue['und'][0] as $addressFieldName => $addressvalue)
            {
                $destination[$fieldName]['und'][0]['#address'][$addressFieldName] = $addressvalue;
            }
        }
        else if(isset($destination[$fieldName]['und'][0]['#type']) &&
            $destination[$fieldName]['und'][0]['#type'] == 'date_combo')
        {
            $destination[$fieldName]['und'][0]['#default_value']['value'] = $sourceValue['und'][0]['value'];    
        }
        else
        {
            $destination[$fieldName]['und'][0]['value']['#default_value'] = $sourceValue['und'][0]['value'];
        }
    }
}
1
Martin