0

I have a taxonomy multi-select list that is used to create/delete entries in a field collection in my node. I'm trying to make it so that if the user deselects an item from the taxonomy list, the corresponding field collection item is removed from the node. I'm running into an issue when the user deselects a single option because of the way my code runs but I can't figure out how to get around it:

  • I compare the selected options in my taxonomy list
  • I look for them in the field collection
  • If they don't match, I add the differences to two arrays
  • I loop through one array to remove the field collection item if it's not selected in the taxonomy list AND
  • I loop through the other array to add the field collection item if it's on the taxonomy list but not the field collections

With one option difference, my code seems to delete and add it back so there is no visible change. It works if I make multiple selection changes. I believe the issue is that ->delete() and ->save() save the node as well so my code runs more than it needs to.

function commitments_node_update($node) {

    if($node->type == 'commitment') {
        if (!empty($node->field_conditions['und'])) {
            $condition_name = array();
            $fc_name = array();
            //Create array of all FC conditions
            foreach ($node->field_conditions['und'] as $key => $value) {
                $fc = entity_load('field_collection_item', array($value['value']));
                foreach($fc as $condition) {
                    $fc_name[] = $condition->field_condition_title['und'][0]['value'];
                }
            }

            //Create array of all selected conditions
            foreach ($node->field_commitment_conditions['und'] as $conditions){
                $tid = $conditions['target_id'];
                $term = taxonomy_term_load($tid);
                $condition_name[$tid] = $term->name;

            }
            $fc_diffs = array_diff($fc_name, $condition_name);
            $condition_diffs = array_diff($condition_name, $fc_name);

            //Remove deselected conditions from FC
            foreach ($fc_diffs as $fc_diff) {
                foreach ($node->field_conditions['und'] as $item) {
                    $fc = entity_load_single('field_collection_item', $item['value']);
                        $fc_name_search = $fc->field_condition_title['und'][0]['value'];
                        if ($fc_diff == $fc_name_search) {
                            $fc->delete();
                        }
                }
            }

            //Add new conditions to FC      
            foreach ($condition_diffs as $key => $value) {
                $term = taxonomy_term_load($key);
                $condition = $term->field_condition['und'][0]['value'];
                $condition_name = $term->name;

                $condition_fc = entity_create('field_collection_item', array('field_name' => 'field_conditions'));
                $condition_fc->setHostEntity('node', $node);
                $condition_fc->field_condition_title[LANGUAGE_NONE][0]['value'] = $condition_name;
                $condition_fc->field_condition[LANGUAGE_NONE][0]['value'] = $condition;
                $condition_fc->save();
            }

        } 
    }
}
0

Thanks to #drupal on IRC, I now only run the code once by creating a static cache:

function commitments_node_update($node) {

    if($node->type == 'commitment') {
        if (!empty($node->field_conditions['und'])) {
            static $cache = array(); 
            if(array_key_exists($node->nid, $cache)) {
                return; 
            }
            $cache[$node->nid] = true;
            $condition_name = array();
            $fc_name = array();
            //Create array of all FC conditions
            foreach ($node->field_conditions['und'] as $key => $value) {
                $fc = entity_load('field_collection_item', array($value['value']));
                foreach($fc as $condition) {
                    $fc_name[] = $condition->field_condition_title['und'][0]['value'];
                }
            }

            //Create array of all selected conditions
            foreach ($node->field_commitment_conditions['und'] as $conditions){
                $tid = $conditions['target_id'];
                $term = taxonomy_term_load($tid);
                $condition_name[$tid] = $term->name;
            }

            $fc_diffs = array_diff($fc_name, $condition_name);
            $condition_diffs = array_diff($condition_name, $fc_name);

            //Remove deselected conditions from FC
            foreach ($fc_diffs as $fc_diff) {
                foreach ($node->field_conditions['und'] as $item) {
                    $fc = entity_load_single('field_collection_item', $item['value']);
                        $fc_name_search = $fc->field_condition_title['und'][0]['value'];
                        if ($fc_diff == $fc_name_search) {
                            $fc->delete();
                        }
                }
            }

            //Add new conditions to FC      
            foreach ($condition_diffs as $key => $value) {
                $term = taxonomy_term_load($key);
                $condition = $term->field_condition['und'][0]['value'];
                $condition_name = $term->name;

                $condition_fc = entity_create('field_collection_item', array('field_name' => 'field_conditions'));
                $condition_fc->setHostEntity('node', $node);
                $condition_fc->field_condition_title[LANGUAGE_NONE][0]['value'] = $condition_name;
                $condition_fc->field_condition[LANGUAGE_NONE][0]['value'] = $condition;
                $condition_fc->save();
            }
            unset($cache[$node->nid]);
        } 
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.