function relationship()

in web/wp-content/plugins/acf-extended/includes/fields-settings/bidirectional.php [601:743]


    function relationship($type, $r_id, $p_field, $p_value){
        
        // get Related Field Configuration
        $r_fields = acf_get_array($p_field['acfe_bidirectional']['acfe_bidirectional_related']);
        
        foreach($r_fields as $r_field_key){
            
            $r_field = acf_get_field($r_field_key);
            
            // get if bidirectional is active
            if(!$this->get_field_bidirectional($r_field)) continue;
            
            // get Related Data Type ({post_id}, user_{id} ...)
            $r_mtype = '';
            if($p_field['type'] === 'user'){
                $r_mtype = 'user_';
            }elseif($p_field['type'] === 'taxonomy'){
                $r_mtype = 'term_';
            }
            
            // get Related Field Ancestors
            $r_field_ancestors = acf_get_field_ancestors($r_field);
            
            // ancestors - complex field (group|clone)
            if(!empty($r_field_ancestors)){
                
                // get ancestors
                $r_field_ancestors = array_reverse($r_field_ancestors);
                $r_field_ancestors_fields = array_map('acf_get_field', $r_field_ancestors);
                
                // get top ancestor
                $r_ref_field = $r_field_ancestors_fields[0];
                $r_ref_values = acf_get_array(acf_get_value($r_mtype.$r_id, $r_ref_field));
                
                // get values
                $r_values = acf_get_array($this->get_value_from_ancestor($r_ref_values, $r_field));
                
                // unset top ancestor for update (not needed)
                unset($r_field_ancestors_fields[0]);
                
                // add related field to get
                $r_values_query = array($r_field['key']);
                
                // if > 1 ancestors, return ancestors keys only
                if(!empty($r_field_ancestors_fields)){
                    
                    $r_field_ancestors_keys = array_map(function($field){
                        return $field['key'];
                    }, $r_field_ancestors_fields);
                    
                    // add ancestors to get
                    $r_values_query = array_merge($r_field_ancestors_keys, $r_values_query);
                    
                }
                
            }
            
            // no Ancestors - simple field
            else{
                
                // reference field
                $r_ref_field = $r_field;
                
                // values
                $r_values = acf_get_array(acf_get_value($r_mtype.$r_id, $r_field));
                
            }
            
            // convert strings to integers
            $r_values = acf_parse_types($r_values);
            
            // add Value
            if($type === 'add'){
                
                if(!in_array($p_value, $r_values)){
                    $r_values[] = $p_value;
                }
                
            }
            
            // remove Value
            elseif($type === 'remove'){
                
                $r_new_values = array();
                foreach($r_values as $r_value){
                    
                    if($r_value === $p_value) continue;
                    
                    $r_new_values[] = $r_value;
                    
                }
                
                $r_values = $r_new_values;
                
            }
            
            /**
             * post object & user 'allow multiple' disabled
             * value must not be inside array
             */
            if(($r_ref_field['type'] === 'post_object' || $r_ref_field['type'] === 'user') && empty($r_ref_field['multiple']) && isset($r_values[0])){
                
                // Get latest value
                $r_values = end($r_values);
                
            }
            
            // remove potential empty serialized array in meta value 'a:0:{}'
            if(empty($r_values)){
                $r_values = false;
            }
            
            /**
             * construct a value array in case of ancestors. ie:
             *
             * $related_values = Array(
             *     [field_aaa] => Array(
             *         [field_bbb] => Array(
             *             [0] => xxxx
             *         )
             *     )
             * )
             */
            if(!empty($r_field_ancestors)){
                
                for($i = count($r_values_query)-1; $i>=0; $i--){
                    $r_values = array($r_values_query[$i] => $r_values);
                }
                
            }
            
            // filter acf_update_value (to avoid infinite loop)
            acf_enable_filter('acfe/bidirectional');
            
                // update Related Field
                acf_update_value($r_values, $r_mtype.$r_id, $r_ref_field);
            
            // remove acf_update_value filter
            acf_disable_filter('acfe/bidirectional');
            
        }
        
    }