PATH:
home
/
letacommog
/
rdvenunclick.fr1
/
wp-content
/
plugins
/
acf-extended
/
includes
/
fields-settings
<?php if(!defined('ABSPATH')) exit; if(!class_exists('acfe_bidirectional')): class acfe_bidirectional{ var $allowed_types = array('relationship', 'post_object', 'user', 'taxonomy'); function __construct(){ foreach($this->allowed_types as $allowed_type){ add_action('acf/render_field_settings/type=' . $allowed_type, array($this, 'field_settings_render')); add_filter('acf/update_field/type=' . $allowed_type, array($this, 'field_settings_update')); add_action('acf/delete_field/type=' . $allowed_type, array($this, 'field_settings_delete')); add_filter('acf/update_value/type=' . $allowed_type, array($this, 'update_value'), 11, 3); } add_action('wp_ajax_acfe/fields_settings/bidirectional/query', array($this, 'ajax_query')); add_action('wp_ajax_nopriv_acfe/fields_settings/bidirectional/query', array($this, 'ajax_query')); add_filter('acf/prepare_field/name=acfe_bidirectional_related', array($this, 'field_settings_default_value')); } /* * Field Settings */ function field_settings_render($field){ // Settings acf_render_field_setting($field, array( 'label' => __('Bidirectional'), 'key' => 'acfe_bidirectional', 'name' => 'acfe_bidirectional', 'instructions' => __('Set the field as bidirectional'), 'type' => 'group', 'required' => false, 'conditional_logic' => false, 'wrapper' => array( 'width' => '', 'class' => '', 'id' => '', ), 'layout' => 'block', 'sub_fields' => array( array( 'label' => false, 'key' => 'acfe_bidirectional_enabled', 'name' => 'acfe_bidirectional_enabled', 'type' => 'true_false', 'instructions' => '', 'required' => false, 'wrapper' => array( 'width' => '15', 'class' => 'acfe_width_auto', 'id' => '', ), 'message' => '', 'default_value' => false, 'ui' => true, 'ui_on_text' => '', 'ui_off_text' => '', 'conditional_logic' => false, ), array( 'label' => false, 'key' => 'acfe_bidirectional_related', 'name' => 'acfe_bidirectional_related', 'type' => 'select', 'instructions' => '', 'required' => false, 'wrapper' => array( 'width' => 50, 'class' => '', 'id' => '', ), 'choices' => array(), 'default_value' => array(), 'allow_null' => 1, 'multiple' => 1, 'ui' => 1, 'ajax' => 1, 'ajax_action' => 'acfe/fields_settings/bidirectional/query', 'return_format' => 'value', 'placeholder' => '', 'conditional_logic' => array( array( array( 'field' => 'acfe_bidirectional_enabled', 'operator' => '==', 'value' => '1', ), ), ), ), ), )); } /* * Field Settings: Ajax Query */ function ajax_query(){ // validate if (!acf_verify_ajax()){ die(); } $options = acf_parse_args($_POST, array( 'post_id' => 0, 's' => '', 'field_key' => '', 'paged' => 1 )); $response = $this->ajax_results($options); acf_send_ajax_results($response); } /* * Field Settings: Ajax Results */ function ajax_results($options = array()){ // Disable Filters acf_disable_filters(); // Get field groups $r_field_groups = acf_get_field_groups(); if(empty($r_field_groups)) return false; $choices = array(); foreach($r_field_groups as $r_field_group){ // Bypass ACFE native groups if(in_array($r_field_group['key'], array('group_acfe_author', 'group_acfe_dynamic_post_type', 'group_acfe_dynamic_taxonomy'))) continue; // Get related fields $r_fields = acf_get_fields($r_field_group['key']); if(empty($r_fields)) continue; // Filter & find possible related fields foreach($r_fields as $r_field){ $this->get_related_settings($r_field, $r_field_group, $choices); } } // vars $results = array(); $s = null; if(!empty($choices)){ // search if($options['s'] !== ''){ // strip slashes (search may be integer) $s = strval($options['s']); $s = wp_unslash($s); } foreach($choices as $field_group_title => $childs){ $field_group_title = strval($field_group_title); $childrens = array(); foreach($childs as $child_key => $child_label){ $child_label = strval($child_label); // if searching, but doesn't exist if(is_string($s) && stripos($child_label, $s) === false && stripos($field_group_title, $s) === false) continue(2); $childrens[] = array( 'id' => $child_key, 'text' => $child_label, ); } $results[] = array( 'text' => $field_group_title, 'children' => $childrens ); } } return array( 'results' => $results ); } /* * Field Setting: Get Related Settings */ function get_related_settings($r_field, $r_field_group, &$choices){ if(in_array($r_field['type'], array('repeater', 'flexible_content'))) return; // Recursive search for sub_fields (groups & clones) if(isset($r_field['sub_fields']) && !empty($r_field['sub_fields'])){ foreach($r_field['sub_fields'] as $r_sub_field){ // Recursive call $this->get_related_settings($r_sub_field, $r_field_group, $choices); } return; } // Allow only specific fields if(!in_array($r_field['type'], $this->allowed_types)) return false; $choices[$r_field_group['title']][$r_field['key']] = (!empty($r_field['label']) ? $r_field['label'] : $r_field['name']) . ' (' . $r_field['key'] . ')'; } /* * Field Setting: Default Value */ function field_settings_default_value($field){ if(!isset($field['value']) || empty($field['value'])) return $field; $values = acf_get_array($field['value']); $r_fields = array(); $r_field_update = false; foreach($values as $i => $value){ $r_field = acf_get_field($value); if($r_field){ $r_fields[] = $r_field; }else{ // Unset unset($values[$i]); $r_field_update = true; } } if($r_field_update){ $field['value'] = $values; acf_update_field($field); } foreach($r_fields as $r_field){ $field['choices'][$r_field['key']] = (!empty($r_field['label']) ? $r_field['label'] : $r_field['name']) . ' (' . $r_field['key'] . ')'; } return $field; } /* * Field Setting Update */ function field_settings_update($field){ $bypass = acf_is_filter_enabled('acfe/bidirectional_setting'); if($bypass) return $field; // Previous setting values $_field = acf_get_field($field['key']); // Turning off - Remove related field if($this->has_field_bidirectional($_field) && !$this->has_field_bidirectional($field)){ // Get related bidirectional related $r_fields = acf_get_array($_field['acfe_bidirectional']['acfe_bidirectional_related']); foreach($r_fields as $r_field_key){ $r_field = acf_get_field($r_field_key); if(!$this->has_field_bidirectional($r_field)) continue; $r_field_related = acf_get_array($r_field['acfe_bidirectional']['acfe_bidirectional_related']); if(in_array($field['key'], $r_field_related)){ foreach($r_field_related as $i => $r_field_r){ if($r_field_r !== $field['key']) continue; unset($r_field_related[$i]); } $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = $r_field_related; if(empty($r_field_related)){ $r_field['acfe_bidirectional']['acfe_bidirectional_enabled'] = false; $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = false; } acf_enable_filter('acfe/bidirectional_setting'); // Update related bidirectional acf_update_field($r_field); acf_disable_filter('acfe/bidirectional_setting'); } } } // Turning on (or already on) - Add related field elseif(($this->has_field_bidirectional($_field) && $this->has_field_bidirectional($field)) || (!$this->has_field_bidirectional($_field) && $this->has_field_bidirectional($field))){ // Get related bidirectional related $r_fields = acf_get_array($field['acfe_bidirectional']['acfe_bidirectional_related']); foreach($r_fields as $r_field_key){ $r_field = acf_get_field($r_field_key); // Reset related bidirectional related $r_field['acfe_bidirectional']['acfe_bidirectional_enabled'] = true; $r_field_related = array(); if(isset($r_field['acfe_bidirectional']['acfe_bidirectional_related'])) $r_field_related = acf_get_array($r_field['acfe_bidirectional']['acfe_bidirectional_related']); if(!in_array($field['key'], $r_field_related)){ $r_field_related[] = $field['key']; $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = $r_field_related; } acf_enable_filter('acfe/bidirectional_setting'); // Update related bidirectional acf_update_field($r_field); acf_disable_filter('acfe/bidirectional_setting'); } } // Return return $field; } /* * Field Setting: Delete */ function field_settings_delete($field){ if(!$this->has_field_bidirectional($field)) return; // Get related bidirectional related $r_fields = acf_get_array($field['acfe_bidirectional']['acfe_bidirectional_related']); foreach($r_fields as $r_field_key){ $r_field = acf_get_field($r_field_key); $r_field_related = acf_get_array($r_field['acfe_bidirectional']['acfe_bidirectional_related']); if(in_array($field['key'], $r_field_related)){ foreach($r_field_related as $i => $r_field_r){ if($r_field_r !== $field['key']) continue; unset($r_field_related[$i]); } $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = $r_field_related; if(empty($r_field_related)){ $r_field['acfe_bidirectional']['acfe_bidirectional_enabled'] = false; $r_field['acfe_bidirectional']['acfe_bidirectional_related'] = false; } // Update related bidirectional acf_update_field($r_field); } } } /* * Update Value */ function update_value($value, $post_id, $field){ $bypass = acf_is_filter_enabled('acfe/bidirectional'); if($bypass) return $value; // Check if bidirectional if(!$this->get_field_bidirectional($field)) return $value; // Decode current post_id (ie: user_1) $request = acf_decode_post_id($post_id); // Values $old_values = acf_get_array(acf_get_metadata($post_id, $field['name'])); $new_values = acf_get_array($value); // Bail early if no difference // if($old_values === $new_values) // return $value; // Values have been removed if(!empty($old_values)){ foreach($old_values as $r_id){ if(in_array($r_id, $new_values)) continue; $this->relationship('remove', $r_id, $field, $request['id']); } } // Values have been added if(!empty($new_values)){ foreach($new_values as $r_id){ if(in_array($r_id, $old_values)) continue; $this->relationship('add', $r_id, $field, $request['id']); } } $force_update = false; $force_update = apply_filters('acfe/bidirectional/force_update', $force_update, $field, $post_id); $force_update = apply_filters('acfe/bidirectional/force_update/type=' . $field['type'], $force_update, $field, $post_id); $force_update = apply_filters('acfe/bidirectional/force_update/name=' . $field['name'], $force_update, $field, $post_id); $force_update = apply_filters('acfe/bidirectional/force_update/key=' . $field['key'], $force_update, $field, $post_id); if($force_update){ // Force new values to be saved if(!empty($new_values)){ foreach($new_values as $r_id){ $this->relationship('add', $r_id, $field, $request['id']); } } } return $value; } /** * Establish Relationship * * $type: add|remove * $r_id: the post_id to add the relationship to * $p_field: the parent field * $p_id: the relationship to add */ function relationship($type = 'add', $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 - Complexe 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{ // Refence 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'); } } function get_value_from_ancestor($r_ref_values, $r_field){ foreach($r_ref_values as $r_ref_key => $r_ref_value){ if($r_ref_key != $r_field['key']){ if(is_array($r_ref_value)) return $this->get_value_from_ancestor($r_ref_value, $r_field); return false; } return $r_ref_value; } } function is_field_bidirectional($field){ return isset($field['acfe_bidirectional']['acfe_bidirectional_enabled']) && !empty($field['acfe_bidirectional']['acfe_bidirectional_enabled']); } function has_field_bidirectional($field){ return isset($field['acfe_bidirectional']['acfe_bidirectional_related']) && !empty($field['acfe_bidirectional']['acfe_bidirectional_related']); } function get_field_bidirectional($field){ if(!$this->is_field_bidirectional($field) || !$this->has_field_bidirectional($field)) return false; return $field['acfe_bidirectional']['acfe_bidirectional_related']; } } new acfe_bidirectional(); endif;
[+]
..
[-] validation.php
[edit]
[-] fields.php
[edit]
[-] permissions.php
[edit]
[-] bidirectional.php
[edit]
[-] settings.php
[edit]
[-] data.php
[edit]