| 1 |
<?php |
| 2 |
|
| 3 |
/** |
| 4 |
* |
| 5 |
* |
| 6 |
* @since 4.10.0 |
| 7 |
*/ |
| 8 |
require_once plugin_dir_path( __DIR__ ) . 'lists/class-cf7sg-dynamic-list.php'; |
| 9 |
|
| 10 |
class CF7SG_Dynamic_Select extends CF7SG_Dynamic_list{ |
| 11 |
|
| 12 |
public function __construct(){ |
| 13 |
parent::__construct('dynamic_select',__( 'dynamic-dropdown', 'cf7_2_post' )); |
| 14 |
} |
| 15 |
/** |
| 16 |
* define the style optoins for the dynamic list construct. |
| 17 |
* the stule unique slug will be inserted as class in the cf7 tag object, allowing the field styling. |
| 18 |
* @return Array an array of style-slug => style label. |
| 19 |
*/ |
| 20 |
public function admin_generator_tag_styles(){ |
| 21 |
add_action('cf7sg_'.$this->tag_id.'_admin_tag_style-select2', array($this,'custom_select2')); |
| 22 |
return array( |
| 23 |
'select' => __('HTML Select field','cf7-grid-layout'), |
| 24 |
'select2' => '<a target="_blank" href="https://select2.org/getting-started/basic-usage">'.__('jQuery Select2','cf7-grid-layout').'</a>' |
| 25 |
); |
| 26 |
} |
| 27 |
/** |
| 28 |
* custom html + js script for select2 option. |
| 29 |
*/ |
| 30 |
public function custom_select2(){ |
| 31 |
/* |
| 32 |
the class $tag_id along with the style slug is used to buitl the input id attribute, |
| 33 |
so this input field is: $this->tag_id.'-'.'select2'; |
| 34 |
Here an optional 'tags' class will be aded to the CF7 tag object when select2 style is chosen. |
| 35 |
*/ |
| 36 |
?> |
| 37 |
<span class="display-none"> |
| 38 |
<input id="select2-tags" type="checkbox" disabled value="tags"/> |
| 39 |
<a target="_blank" href="https://select2.org/tagging"><?=__('Enable user options','cf7-grid-layout')?></a> |
| 40 |
</span> |
| 41 |
<script type="text/javascript"> |
| 42 |
(function($){ |
| 43 |
let $tags = $('#select2-tags'), $select2 = $('#<?=$this->tag_id?>-select2'); |
| 44 |
$tags.change(function(e){ |
| 45 |
if($tags.is(':checked')){ |
| 46 |
$select2.val('select2 tags').change(); |
| 47 |
} |
| 48 |
}); |
| 49 |
$('.list-style.<?=$this->tag_id?>').change(function(e){ |
| 50 |
if($select2.is(':checked')){ |
| 51 |
$tags.prop('disabled', false); |
| 52 |
$tags.parent().show(); |
| 53 |
}else{ |
| 54 |
$tags.prop('checked', false); |
| 55 |
$tags.prop('disabled', true); |
| 56 |
$tags.parent().hide(); |
| 57 |
$select2.val('select2'); |
| 58 |
} |
| 59 |
}); |
| 60 |
})(jQuery); |
| 61 |
</script> |
| 62 |
<?php |
| 63 |
} |
| 64 |
/** |
| 65 |
* Register a [dynamic_display] shortcode with CF7. |
| 66 |
* called by funciton above |
| 67 |
* This function registers a callback function to expand the shortcode for the googleMap form fields. |
| 68 |
* @since 1.0.0 |
| 69 |
* @param Array $attrs array of attribute key=>value pairs to be included in the html element tag. |
| 70 |
* @param Array $options array of value=>label pairs of options. |
| 71 |
* @param Array $option_attrs array of value=>attribute pairs for each options, such as permalinks for post sources.. |
| 72 |
* @param Boolean $is_multiselect if the field has multiple selection enabled.. |
| 73 |
* @return String an html string representing the input field to a=be added to the field wrapper and into the form. |
| 74 |
*/ |
| 75 |
|
| 76 |
public function get_dynamic_html_field( $attrs, $options, $option_attrs, $is_multiselect, $selected){ |
| 77 |
$attributes =''; |
| 78 |
foreach($attrs as $key=>$value){ |
| 79 |
if('name'==$key && $is_multiselect) $value.='[]'; |
| 80 |
$attributes .= ' '.$key.'="'.$value.'"'; |
| 81 |
} |
| 82 |
$html = '<select value="'.$selected.'"'.$attributes.'>'.PHP_EOL; |
| 83 |
foreach($options as $value=>$label){ |
| 84 |
$attributes =''; |
| 85 |
if(isset($option_attrs[$value])) $attributes = ' '.$option_attrs[$value]; |
| 86 |
if($value==$selected) $attributes .=' selected="selected"'; |
| 87 |
$html .= '<option value="'.$value.'"'.$attributes.'>'.$label.'</option>'.PHP_EOL; |
| 88 |
} |
| 89 |
$html .='</select>'.PHP_EOL; |
| 90 |
return $html; |
| 91 |
} |
| 92 |
|
| 93 |
/** |
| 94 |
* Function to get classes to be added to the form wrapper. |
| 95 |
* these classes will be passed in the resource enqueue action, allowing for specific js/css resources |
| 96 |
* to be queued up and loaded on the page where the form is being displayed. |
| 97 |
* @param WPCF7_FormTag cf7 tag object for the form field. |
| 98 |
* @param int $form_id cf7 fomr post ID.. |
| 99 |
* @return Array an array of classes to be added to the form to which this tag belonggs to. |
| 100 |
*/ |
| 101 |
public function get_form_classes($tag, $form_id){ |
| 102 |
/* Bookeeping, set up tagged select2 fields to filter newly added options in case Post My CF7 Form plugin is running */ |
| 103 |
$class = $tag->get_class_option(''); |
| 104 |
|
| 105 |
$form_classes = array(); |
| 106 |
if(strpos($class, 'select2')){ |
| 107 |
$form_classes[] = 'has-select2'; |
| 108 |
//track this field if user sets custom options. |
| 109 |
if(strpos($class, 'tags')){ |
| 110 |
$tagged_fields = get_post_meta($form_id, '_cf7sg_select2_tagged_fields', true); |
| 111 |
if(empty($tagged_fields)){ |
| 112 |
$tagged_fields = array(); |
| 113 |
} |
| 114 |
if( !isset($tagged_fields[$tag->name]) ){ |
| 115 |
$tagged_fields[$tag->name] = $source; |
| 116 |
update_post_meta($form_id, '_cf7sg_select2_tagged_fields',$tagged_fields); |
| 117 |
} |
| 118 |
} |
| 119 |
} |
| 120 |
if(false != strpos($class, 'nice-select') || false !=strpos($class, 'ui-select')){ |
| 121 |
$form_classes[] = 'has-nice-select'; |
| 122 |
} |
| 123 |
return $form_classes; |
| 124 |
} |
| 125 |
/** |
| 126 |
* Save new options for select2 with tags optoin enabled. |
| 127 |
*/ |
| 128 |
public function save_form_2_post($post_id, $form_id, $cf7_key, $post_fields, $post_meta_fields, $submitted_data){ |
| 129 |
$tagged_fields = get_post_meta($form_id, '_cf7sg_select2_tagged_fields', true); |
| 130 |
if(empty($tagged_fields)){ |
| 131 |
return; |
| 132 |
} |
| 133 |
|
| 134 |
foreach($tagged_fields as $field_name=>$source){ |
| 135 |
$value = $submitted_data[$field_name]; |
| 136 |
$is_array = true; |
| 137 |
if(!is_array($value)){ |
| 138 |
$value = array($value); |
| 139 |
$is_array = false; |
| 140 |
} |
| 141 |
switch($source['source']){ |
| 142 |
case 'taxonomy': |
| 143 |
$taxonomy = $source['taxonomy']; |
| 144 |
$idx=0; |
| 145 |
foreach($value as $term){ |
| 146 |
if(!term_exists($term, $taxonomy)){ |
| 147 |
/** |
| 148 |
* Filter custom options from tag enabled select2 dynamic-dropdown fields |
| 149 |
* where the source of options come from taxonomy terms. Filter is fired when a new value is submitted. The pluign inserts a new term by default as per submitted value. |
| 150 |
* @param string $term the new term submitted by the user. |
| 151 |
* @param string $field_name the name of the form field. |
| 152 |
* @param string $taxonomy the taxonomy to which this is added. |
| 153 |
* @param array $submitted_data array of other submitted $field=>$value pairs. |
| 154 |
* @param string $cf7_key the form unique key. |
| 155 |
* @return string the new term name to insert. |
| 156 |
* @since 2.0.0 |
| 157 |
*/ |
| 158 |
$term = apply_filters('cf7sg_dynamic_dropdown_new_term', $term, $field_name, $taxonomy, $submitted_data, $cf7_key); |
| 159 |
$new_term = wp_insert_term($term, $taxonomy); |
| 160 |
if(!is_wp_error($new_term)){ |
| 161 |
$new_term = get_term($new_term['term_id'], $taxonomy); |
| 162 |
$value[$idx] = $new_term->slug; |
| 163 |
} |
| 164 |
} |
| 165 |
$idx++; |
| 166 |
} |
| 167 |
break; |
| 168 |
case 'post': |
| 169 |
$args = array( |
| 170 |
'post_type' => $source['post'], |
| 171 |
'post_status' => 'publish', |
| 172 |
'posts_per_page' => -1 |
| 173 |
); |
| 174 |
if(!empty($source['taxonomy'])){ |
| 175 |
$tax = array(); |
| 176 |
if(sizeof($source['taxonomy']) > 1){ |
| 177 |
$tax['relation'] = 'AND'; |
| 178 |
} |
| 179 |
foreach($source['taxonomy'] as $term => $taxonomy){ |
| 180 |
$tax[]=array( |
| 181 |
'taxonomy' => $taxonomy, |
| 182 |
'field' => 'slug', |
| 183 |
'terms' => $term |
| 184 |
); |
| 185 |
} |
| 186 |
$args['tax_query'] = $tax; |
| 187 |
} |
| 188 |
$args = apply_filters('cf7sg_dynamic_dropdown_post_query', $args, $tag->name, $cf7_key); |
| 189 |
$posts = get_posts($args); |
| 190 |
$options = array(); |
| 191 |
if(!empty($posts)){ |
| 192 |
foreach($posts as $post){ |
| 193 |
$options[$post->post_name] = $post->post_title; |
| 194 |
} |
| 195 |
} |
| 196 |
$idx=0; |
| 197 |
foreach($value as $slug){ |
| 198 |
if(!isset($options[$slug])){ |
| 199 |
$args = $source; |
| 200 |
$post_type = $source['post']; |
| 201 |
$title = $slug; |
| 202 |
$post_name = ''; |
| 203 |
/** |
| 204 |
* Filter custom options from tag enabled select2 dynamic-dropdown fields |
| 205 |
* where the source of options come from post titles. Filter is fired when a new value is submitted. |
| 206 |
* This plugin does not take any further action, ie no post of $post_type will be created. It is upto you to do so and return the slug of the newly created post. |
| 207 |
* @param string $post_name the new post slug. |
| 208 |
* @param string $field_name the name of the form field. |
| 209 |
* @param string $title new value being submitted for a new post title. |
| 210 |
* @param string $post_type the post type from which this dropdown was built |
| 211 |
* @param array $args an array of additional parameters that was set in the tag, for example the taxonomy and terms from which to filter the posts for the dynamic list. |
| 212 |
* @param array $submitted_data array of other submitted $field=>$value pairs. |
| 213 |
* @param string $cf7_key the form unique key. |
| 214 |
*/ |
| 215 |
$value[$idx] = apply_filters('cf7sg_dynamic_dropdown_new_post', $post_name, $field_name, $title, $post_type, $args, $submitted_data, $cf7_key); |
| 216 |
} |
| 217 |
$idx++; |
| 218 |
} |
| 219 |
break; |
| 220 |
case 'filter': |
| 221 |
$values = $value; |
| 222 |
/** |
| 223 |
* Filter custom otions from tag enabled select2 dynamic-dropdown fields |
| 224 |
* where the source of options come from a filter. Filter is fired when values are submitted. |
| 225 |
* Return updated values if any are custom values so that saved/draft submissions will reflect the correct value saved in the DB, |
| 226 |
* @param array $values an array submitted values (several values can be submitted in the case of a tabbed/table input field). |
| 227 |
* @param string $field_name the name of the form field. |
| 228 |
* @param array $submitted_data array of other submitted $field=>$value pairs. |
| 229 |
* @param string $cf7_key the form unique key. |
| 230 |
*/ |
| 231 |
$value = apply_filters('cf7sg_dynamic_dropdown_filter_select2_submission', $values, $field_name, $submitted_data, $cf7_key); |
| 232 |
break; |
| 233 |
} |
| 234 |
//Save the modified value, find which post field the field is mapped to |
| 235 |
if(!$is_array){ |
| 236 |
$value = $value[0]; |
| 237 |
} |
| 238 |
if( isset($post_fields[$field_name]) ){ |
| 239 |
$post_key = $post_fields[$field_name]; |
| 240 |
switch($post_key){ |
| 241 |
case 'title': |
| 242 |
case 'author': |
| 243 |
case 'excerpt': |
| 244 |
$post_key = 'post_'.$post_key; |
| 245 |
break; |
| 246 |
case 'editor': |
| 247 |
$post_key ='post_content'; |
| 248 |
break; |
| 249 |
case 'slug': |
| 250 |
$post_key ='post_name'; |
| 251 |
break; |
| 252 |
} |
| 253 |
wp_update_post(array( |
| 254 |
'ID' => $post_id, |
| 255 |
$post_key => $value |
| 256 |
)); |
| 257 |
}else if( isset($post_meta_fields[$field_name]) ){ |
| 258 |
update_post_meta($post_id, $post_meta_fields[$field_name], $value); |
| 259 |
} |
| 260 |
} |
| 261 |
} |
| 262 |
public function register_styles($airplane){ |
| 263 |
$ff = ''; |
| 264 |
if(!defined('WP_DEBUG') || !WP_DEBUG){ |
| 265 |
$ff = '.min'; |
| 266 |
} |
| 267 |
$plugin_dir = plugin_dir_url( __DIR__ ); |
| 268 |
wp_register_style('jquery-nice-select-css', "$plugin_dir../assets/jquery-nice-select/css/nice-select{$ff}.css", array(), '1.1.0', 'all' ); |
| 269 |
/** @since 3.2.1 use cloudflare for live sites */ |
| 270 |
if( $airplane || (defined('WP_DEBUG') && WP_DEBUG) ){ |
| 271 |
wp_register_style('select2-style', "$plugin_dir../assets/select2/css/select2.min.css", array(), '4.0.13', 'all' ); |
| 272 |
debug_msg($plugin_dir); |
| 273 |
}else{ |
| 274 |
wp_register_style('select2-style', '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css', array(), '4.0.13','all'); |
| 275 |
} |
| 276 |
} |
| 277 |
public function register_scripts($airplane){ |
| 278 |
/** @since 3.2.1 use cloudflare for live sites */ |
| 279 |
$plugin_dir = plugin_dir_url( __DIR__ ); |
| 280 |
if( $airplane || (defined('WP_DEBUG') && WP_DEBUG) ){ |
| 281 |
wp_register_script('jquery-select2', "$plugin_dir../assets/select2/js/select2.min.js", array( 'jquery' ), '4.0.13', true ); |
| 282 |
}else{ |
| 283 |
wp_register_script('jquery-select2', '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js', array( 'jquery' ), '4.0.13', true ); |
| 284 |
} |
| 285 |
wp_register_script('jquery-nice-select', "$plugin_dir../assets/jquery-nice-select/js/jquery.nice-select.min.js", array( 'jquery' ), '1.1.0', true ); |
| 286 |
|
| 287 |
//listen for script enqueue action. |
| 288 |
add_action('smart_grid_enqueue_scripts', function($cf7_key, $atts, $classes){ |
| 289 |
//check for classes set in get_form_classes()method above. |
| 290 |
if(in_array('has-select2', $classes)){ |
| 291 |
wp_enqueue_style('select2-style'); |
| 292 |
wp_enqueue_script('jquery-select2'); |
| 293 |
} |
| 294 |
if(in_array('has-nice-select', $classes)){ |
| 295 |
wp_enqueue_style('jquery-nice-select-css'); |
| 296 |
wp_enqueue_script('jquery-nice-select'); |
| 297 |
} |
| 298 |
},10,3); |
| 299 |
} |
| 300 |
} |
| 301 |
|
| 302 |
if( !function_exists('cf7sg_create_dynamic_select_tag') ){ |
| 303 |
function cf7sg_create_dynamic_select_tag(){ |
| 304 |
//check if there is an existing instance in memory. |
| 305 |
$new_instance = CF7SG_Dynamic_Select::get_instances('dynamic_select'); |
| 306 |
if(false === $new_instance) $new_instance = new CF7SG_Dynamic_Select(); |
| 307 |
return $new_instance; |
| 308 |
} |
| 309 |
} |
| 310 |
add_action('cf7sg_register_dynamic_lists', 'cf7sg_create_dynamic_select_tag'); |
| 311 |
|