forked from aronbudinszky/WordPress-Simple-Fields
-
Notifications
You must be signed in to change notification settings - Fork 0
/
simple_fields.php
4639 lines (3640 loc) · 174 KB
/
simple_fields.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
/*
Plugin Name: Simple Fields
Plugin URI: http://simple-fields.com
Description: Add groups of textareas, input-fields, dropdowns, radiobuttons, checkboxes and files to your edit post screen.
Version: 1.4.11
Author: Pär Thernström
Author URI: http://eskapism.se/
License: GPL2
*/
/* Copyright 2010 Pär Thernström (email: [email protected])
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Class to keep all simple fields stuff together a bit better
*/
class simple_fields {
const DEBUG_ENABLED = false; // set to true to enable some debug output
public
// Looks something like this: "Simple-Fields-GIT/simple_fields.php"
$plugin_foldername_and_filename,
// array with registered field type objects
$registered_field_types,
// key to use in cache
$ns_key
;
private
$wpml_context = "Simple Fields";
/**
* Init is where we setup actions and filers and loads stuff and a little bit of this and that
*
*/
function init() {
define( "SIMPLE_FIELDS_VERSION", "1.4.11");
define( "SIMPLE_FIELDS_URL", plugins_url(basename(dirname(__FILE__))). "/");
define( "SIMPLE_FIELDS_NAME", "Simple Fields");
load_plugin_textdomain( 'simple-fields', null, basename(dirname(__FILE__)).'/languages/');
// setup cache
// based on stuff found here:
// http://core.trac.wordpress.org/ticket/4476
$ns_key = wp_cache_get( 'simple_fields_namespace_key', 'simple_fields' );
if ( $ns_key === false ) {
wp_cache_set( 'simple_fields_namespace_key', 1, 'simple_fields' );
// echo "cache key init set";
}
$this->ns_key = wp_cache_get( 'simple_fields_namespace_key', 'simple_fields' );
// echo "ns_key is: $this->ns_key"; // 1
require( dirname(__FILE__) . "/functions.php" );
require( dirname(__FILE__) . "/class_simple_fields_field.php" );
// require( dirname(__FILE__) . "/field_types/field_example.php" );
// require( dirname(__FILE__) . "/field_types/field_minimalistic_example.php" );
// Load field types
require( dirname(__FILE__) . "/field_types/field_divider.php" );
require( dirname(__FILE__) . "/field_types/field_date_v2.php" );
// Load option pages
require( dirname(__FILE__) . "/inc-admin-options-export-import.php" );
require( dirname(__FILE__) . "/inc-admin-options-debug.php" );
$this->plugin_foldername_and_filename = basename(dirname(__FILE__)) . "/" . basename(__FILE__);
$this->registered_field_types = array();
// Actions and filters
add_action( 'admin_init', array($this, 'admin_init') );
add_action( 'admin_init', array($this, 'check_upgrade_stuff') );
add_action( 'admin_init', array($this, "options_page_save" ));
add_action( 'admin_enqueue_scripts', array($this, 'admin_enqueue_scripts') );
add_action( 'admin_menu', array($this, "admin_menu") );
add_action( 'admin_head', array($this, 'admin_head') );
add_action( 'admin_head', array($this, 'settings_admin_head') );
add_action( 'admin_head', array($this, 'admin_head_select_file') );
add_filter( 'plugin_row_meta', array($this, 'set_plugin_row_meta'), 10, 2 );
add_action( 'admin_footer', array($this, 'admin_footer') );
add_action( 'admin_init', array($this,'post_admin_init') );
add_action( 'dbx_post_sidebar', array($this, 'post_dbx_post_sidebar') );
add_action( 'save_post', array($this, 'save_postdata') );
add_action( 'save_post', array($this, 'clear_caches') );
add_action( 'edit_attachment', array($this, 'save_postdata') );
add_action( "simple_fields_get_selected_connector_for_post", array($this, "set_post_connector_from_template"), 10, 2 );
// Query filters
add_action( 'pre_get_posts', array($this, 'action_pre_get_posts_meta') );
add_action( 'plugins_loaded', array($this, 'plugins_loaded') );
add_action( 'init', array($this, "maybe_add_debug_info") );
// Hacks for media select dialog
add_filter( 'media_send_to_editor', array($this, 'media_send_to_editor'), 15, 2 );
add_filter( 'media_upload_tabs', array($this, 'media_upload_tabs'), 15 );
add_filter( 'media_upload_form_url', array($this, 'media_upload_form_url') );
// Ajax calls
add_action( 'wp_ajax_simple_fields_metabox_fieldgroup_add', array($this, 'metabox_fieldgroup_add') );
add_action( 'wp_ajax_simple_fields_field_type_post_dialog_load', array($this, 'field_type_post_dialog_load') );
add_action( 'wp_ajax_simple_fields_field_group_add_field', array($this, 'field_group_add_field') );
// Options page
add_action("simple_fields_options_print_nav_tabs", array($this, "promote_ep_on_nav_tabs"));
add_action("simple_fields_options_print_nav_tabs", array($this, "get_options_nav_tabs"));
// Add to debug bar if debug is enabled
add_filter( 'debug_bar_panels', array($this, "debug_panel_insert") );
// Enable slugs as meta keys. Works. Enable by setting, by default for new installs, or require filter hook like below?
/*
add_filter("simple_fields_get_meta_key_template", function($str) {
$str = '_simple_fields_fieldGroupSlug_%4$s_fieldSlug_%5$s_numInSet_%3$s';
return $str;
});
*/
// Setup things for WPML-support
add_action("init", array($this, "setup_wpml_support"));
// Boot up
do_action("simple_fields_init", $this);
}
/**
* Init support for WPML translations
*/
function setup_wpml_support() {
// If wpml is not active then don't do anything
if ( ! $this->is_wpml_active()) return;
// http://wpml.org/documentation/support/translation-for-texts-by-other-plugins-and-themes/
// 1. Register the strings that need translation
// icl_register_string($context, $name, $value)
// run on settings screen, go through all fields and register string
add_action("simple_fields_settings_admin_head", array($this, "register_wpml_strings"));
// 2. Using the translation when displaying
// icl_t($context, $name, $value)
}
/**
* Make sure a field group has the correct format
* It can be wrong because prior to version ?.? the options
* for a field was not stored in the options array. but nowadays we
* assume it is. so..if it's not: fix that!
*
* @param array $fieldgroup Field group to normalize
* @return array $fieldgroup Normalized/fixed field group
*/
function normalize_fieldgroups( $field_groups ) {
// wierd, but i moved to code so this is the way it is..
foreach ( $field_groups as & $fieldgroup_by_reference ) {
// If field was not added with code then move all options to the options-array
if ( ! isset($fieldgroup_by_reference["added_with_code"]) || false === $fieldgroup_by_reference["added_with_code"] ) {
foreach ($fieldgroup_by_reference["fields"] as & $field_by_reference) {
#if ( "drps" === $field_by_reference["slug"] ) {
// make sure field has an options-key that is an array
if ( ! isset( $field_by_reference["options"] ) || ! is_array( $field_by_reference["options"] ) ) $field_by_reference["options"] = array();
foreach ( $field_by_reference as $field_key => $field_vals ) {
// if field has key with name
// type_<textarea|post|taxonyterm|dropdown|whatever>_options
// then move that info to the field[options]-array
if ( 1 === preg_match('/type_([a-z]+)/', $field_key, $field_key_matches) ) {
// $field_key_matches[1] = field type
$field_key_type = $field_key_matches[1];
// make sure field type is key in options array
if ( ! isset( $field_by_reference["options"][ $field_key_type ] ) || ! is_array( $field_by_reference["options"][ $field_key_type ] ) ) $field_by_reference["options"][ $field_key_type ] = array();
// move keys to options array
// keys with name dropdown_num_, checkbox_num_, radiobutton_num_ need special treatment
$values = array();
$values_index = 0;
// check if checked by default exists
$checked_by_default_num = false;
if ( isset( $field_vals["checked_by_default_num"] ) ) {
$checked_by_default_num = $field_vals["checked_by_default_num"];
if ( 1 === preg_match('/_num_([\d]+)/', $checked_by_default_num, $checked_num_matches ) ) {
$checked_by_default_num = (int) $checked_num_matches[1];
}
}
foreach ( $field_vals as $field_vals_key => $field_vals_val ) {
if ( 1 === preg_match('/([a-z]+)_num_(\d+)/i', $field_vals_key, $matches) ) {
// $matches[1] = field type
// $matches[2] = field type num
#sf_d($field_vals_key, '$field_vals_key');
#sf_d($field_vals_val, '$field_vals_val');
$values[ $values_index ] = $field_vals_val;
$values[ $values_index ]["num"] = (int) $matches[2];
if ( false !== $checked_by_default_num && $checked_by_default_num === $values[ $values_index ]["num"] ) {
$values[ $values_index ]["checked"] = true;
$field_by_reference["options"][ $field_key_type ]["checked_by_default_num"] = $field_key_type . "_num_" . $checked_by_default_num;
}
$values_index++;
} else {
// "regular" option key key
$field_by_reference["options"][ $field_key_type ][ $field_vals_key ] = $field_vals_val;
}
if ($values) {
$field_by_reference["options"][ $field_key_type ]["values"] = $values;
}
} // foreach field vals
} // if type_
// sf_d($field);
} // foreach field key
#}
} // foreach field
} // if not added with code
}
return $field_groups;
} // func
/**
* Register strings so they are translateable with WPML
*/
function register_wpml_strings() {
// sometimes icl_register_string does not exist,
// probably because simple fields hooks on tings early
// when wpml is not loaded (like when saving)
if ( ! function_exists("icl_register_string" ) ) return;
// Get all fieldgroups and fields
$field_groups = $this->get_field_groups();
foreach ($field_groups as & $fieldgroup_by_reference) {
// register name and description of each field group
icl_register_string($this->wpml_context, "Field group name, " . $fieldgroup_by_reference["slug"], $fieldgroup_by_reference["name"]);
icl_register_string($this->wpml_context, "Field group description, " . $fieldgroup_by_reference["slug"], $fieldgroup_by_reference["description"]);
// register name for each field
foreach ($fieldgroup_by_reference["fields"] as $field) {
icl_register_string($this->wpml_context, "Field name, " . $field["slug"], $field["name"]);
icl_register_string($this->wpml_context, "Field description, " . $field["slug"], $field["description"]);
// register names for dropdowns and radiobuttons
// several fields can have the same slug, if they are in different field groups
// how to solve that?
// - can't prefix with field group, because they can be in several of those
// - can't prefix with id because can be different between dev/prod/live-servers
// to much to worry about here, let's go with just the slug and then it's up to the
// user to not use a slug more than once.
if ( isset( $field["options"] ) && is_array( $field["options"] ) ) {
if ( isset( $field["options"]["radiobuttons"]["values"] ) && is_array( $field["options"]["radiobuttons"]["values"] ) ) {
foreach ( $field["options"]["radiobuttons"]["values"] as $one_radio_option_key => $one_radio_option_val) {
$string_name = "Field radiobuttons value, " . $field["slug"] . " " . "radiobutton_num_" . $one_radio_option_val["num"];
// sf_d($this->wpml_context);sf_d($string_name);sf_d($one_radio_option_val["value"]);
icl_register_string($this->wpml_context, $string_name, $one_radio_option_val["value"]);
} // foreach
} // if radiobuttons
if ( isset( $field["options"]["dropdown"]["values"] ) && is_array( $field["options"]["dropdown"]["values"] ) ) {
foreach ( $field["options"]["dropdown"]["values"] as $one_dropdown_val) {
$string_name = "Field dropdown value, " . $field["slug"] . " " . "dropdown_num_" . $one_dropdown_val["num"];
// sf_d($string_name);
icl_register_string($this->wpml_context, $string_name, $one_dropdown_val["value"]);
} // foreach
} // if dropdowns
} // if options
/*
// @todo: make above for dropdowns too
} elseif ( isset( $field["type_dropdown_options"] ) && is_array( $field["type_radiobuttons_options"] ) ) {
foreach ( $field["type_radiobuttons_options"] as $one_radio_option_key => $one_radio_option_val) {
// only values like radiobutton_num_2 are allowed
if ( strpos($one_radio_option_key, "radiobutton_num_") === FALSE) continue;
icl_register_string($this->wpml_context, "Field checkbox value, " . $field["slug"] . " " . $one_radio_option_key, $one_radio_option_val["value"]);
}
}
*/
} // foreach
} // foreach field groups
// Get and register post connectors
$post_connectors = $this->get_post_connectors();
foreach ($post_connectors as $connector) {
icl_register_string($this->wpml_context, "Post connector name, " . $connector["slug"], $connector["name"]);
}
} // func
/**
* Get maybe translated string
* If WPML is installed and activated then icl_t() is used on the string
* If WPML is not installed, then it's just returned unmodified
*
* @param string $name Name to use in icl_t
* @param string $value Value to use in icl_t
*/
function get_string($name = "", $value = "") {
if ( $this->is_wpml_active() && function_exists("icl_t") ) {
$value = icl_t($this->wpml_context, $name, $value);
// $value = "WPML: $value"; // debug to check that function actually runs
return $value;
} else {
return $value;
}
}
/**
* If sf_meta_key is set then that is assumed to be the slugs of a field group and a field
* and the meta_key of the value will be replaced by the meta_key value of that simple field-field
*/
function action_pre_get_posts_meta( $query ) {
$sf_meta_key = $query->get("sf_meta_key");
if ( ! empty( $sf_meta_key ) ) {
$field = $this->get_field_by_fieldgroup_and_slug_string( $sf_meta_key );
if ( false !== $field ) {
$field_meta_key = $this->get_meta_key( $field["field_group"]["id"], $field["id"], 0, $field["field_group"]["slug"], $field["slug"] );
$query->set("meta_key", $field_meta_key );
}
}
}
/**
* Inserts debug panel to debug bar
* Called form debug bar filter "debug_bar_panels", so will only be run'ed when debug bar is activated
*/
function debug_panel_insert( $panels ) {
$options = $this->get_options();
// if (isset($options["debug_type"]) && $options["debug_type"] !== 0) {
// 1 = debug for admins only, 2 = debug for all
//if ( ($options["debug_type"] === 1 && current_user_can("edit_themes")) || $options["debug_type"] === 2) {
include_once( dirname(__FILE__) . "/class_simple_fields_debug_panel.php" );
$panels[] = new class_simple_fields_debug_panel;
//}
//}
return $panels;
}
// check some things regarding update
function check_upgrade_stuff() {
global $wpdb;
$db_version = (int) get_option("simple_fields_db_version");
if ($db_version === 0) {
// 1 = the first version, nothing done during update
$new_db_version = 1;
} else if ( 1 === $db_version ) {
// if prev db version was 1 then clear cache so field group options get updated
$this->clear_caches();
$new_db_version = 2;
}
if ( isset( $new_db_version ) ) {
update_option("simple_fields_db_version", $new_db_version);
}
}
/**
* When all plugins have loaded = simple fields has also loaded = safe to add custom field types
*/
function plugins_loaded() {
do_action("simple_fields_register_field_types");
}
/**
* Gets the pattern that are allowed for slugs
* @return string
*/
function get_slug_pattern() {
$pattern = "[A-Za-z0-9_]+";
$pattern = apply_filters( "simple_fields_get_slug_pattern", $pattern);
return $pattern;
}
/**
* Get the title for a slug
* I.e. the help text that the input field will show when the slug pattern is not matched
*/
function get_slug_title() {
return __("Allowed chars: a-z and underscore.", 'simple-fields');
}
/**
* Returns a post connector
* @param int $connector_id
*/
function get_connector_by_id($connector_id) {
$connectors = $this->get_post_connectors();
if (isset($connectors[$connector_id])) {
return $connectors[$connector_id];
} else {
return FALSE;
}
}
/**
* If setting debug = true then output some debug stuff a little here and there
* Hopefully this saves us some var_dump/sf_d/echo all the time
* usage:
* first set DEBUG_ENABLED = true in beginning of class
* then:
* simple_fields("Saved post connector", array("description" => $value, "description n" => $value_n));
*/
public static function debug($description, $details) {
if (self::DEBUG_ENABLED) {
echo "<pre class='sf_box_debug'>";
echo "<strong>".$description."</strong>";
if ($details) {
echo "<br>";
echo htmlspecialchars(print_r($details, TRUE), ENT_QUOTES, 'UTF-8');
} else {
echo "<br><Empty thing.>";
}
echo "</pre>";
}
}
/**
* Run action if we are on a settings/options page that belongs to Simple Fields
*/
function settings_admin_head() {
$is_on_simple_fields_page = FALSE;
$page_type = "";
$current_screen = get_current_screen();
if ($current_screen->id === "settings_page_simple-fields-options") {
$is_on_simple_fields_page = TRUE;
$page_type = "settings";
}
if ( ! $is_on_simple_fields_page ) return;
if ("settings" === $page_type) {
do_action("simple_fields_settings_admin_head");
}
}
/**
* Enqueue styles and scripts, but on on pages that use simple fields
* Should speed up the loading of other pages a bit
*/
function admin_enqueue_scripts($hook) {
// pages to load on = admin/settings page for SF + edit post
$is_on_simple_fields_page = FALSE;
$page_type = "";
$current_screen = get_current_screen();
if ($current_screen->base == "post" && in_array($current_screen->post_type, $this->get_post_connector_attached_types())) {
$is_on_simple_fields_page = TRUE;
$page_type = "post";
} elseif ($current_screen->base === "media-upload") {
$is_on_simple_fields_page = TRUE;
$page_type = "media-upload";
} elseif ($current_screen->id === "settings_page_simple-fields-options") {
$is_on_simple_fields_page = TRUE;
$page_type = "settings";
}
if ( ! $is_on_simple_fields_page ) return;
if ("settings" === $page_type) {
// Settings page
wp_enqueue_style('simple-fields-styles', SIMPLE_FIELDS_URL.'styles.css', false, SIMPLE_FIELDS_VERSION);
} else {
// Edit post etc.
wp_enqueue_script("thickbox");
wp_enqueue_style("thickbox");
wp_enqueue_script("jscolor", SIMPLE_FIELDS_URL . "jscolor/jscolor.js"); // color picker for type color
wp_enqueue_script("simple-fields-date", SIMPLE_FIELDS_URL . "datepicker/date.js"); // date picker for type date
// Date picker for type date
wp_enqueue_script("sf-jquery-datepicker", SIMPLE_FIELDS_URL . "datepicker/jquery.datePicker.js");
wp_enqueue_style('sf-jquery-datepicker', SIMPLE_FIELDS_URL.'datepicker/datePicker.css', false, SIMPLE_FIELDS_VERSION);
// Chosen for multi selects
wp_enqueue_script("chosen.jquery", SIMPLE_FIELDS_URL . "js/chosen/chosen.jquery.min.js");
wp_enqueue_style("chosen", SIMPLE_FIELDS_URL.'js/chosen/chosen.css', false, SIMPLE_FIELDS_VERSION);
wp_enqueue_style('simple-fields-styles-post', SIMPLE_FIELDS_URL.'styles-edit-post.css', false, SIMPLE_FIELDS_VERSION);
// Media must be enqueued if we are editing a post with no editor (probably custom post type)
wp_enqueue_media(); // edit-form-advanced passes this also: array( 'post' => $post_ID
}
// Common scripts
wp_enqueue_script("jquery-ui-core");
wp_enqueue_script("jquery-ui-sortable");
wp_enqueue_script("jquery-ui-dialog");
wp_enqueue_script("jquery-effects-highlight");
wp_register_script('simple-fields-scripts', SIMPLE_FIELDS_URL.'scripts.js', false, SIMPLE_FIELDS_VERSION);
wp_localize_script('simple-fields-scripts', 'sfstrings', array(
'page_type' => $page_type,
'txtDelete' => __('Delete', 'simple-fields'),
'confirmDelete' => __('Delete this field?', 'simple-fields'),
'confirmDeleteGroup' => __('Delete this group?', 'simple-fields'),
'confirmDeleteConnector' => __('Delete this post connector?', 'simple-fields'),
'confirmDeleteRadio' => __('Delete radio button?', 'simple-fields'),
'confirmDeleteDropdown' => __('Delete dropdown value?', 'simple-fields'),
'adding' => __('Adding...', 'simple-fields'),
'add' => __('Add', 'simple-fields'),
'confirmRemoveGroupConnector' => __('Remove field group from post connector?', 'simple-fields'),
'confirmRemoveGroup' => __('Remove this field group?', 'simple-fields'),
'context' => __('Context', 'simple-fields'),
'normal' => __('normal'),
'advanced' => __('advanced'),
'side' => __('side'),
'low' => __('low'),
'high' => __('high'),
));
wp_enqueue_script('simple-fields-scripts');
// Common styles
wp_enqueue_style('wp-jquery-ui-dialog');
// Hook for plugins
do_action("simple_fields_enqueue_scripts", $this);
}
/**
* Stuff that is being runned only when in admin (i.e. not on front of site)
*/
function admin_init() {
define( "SIMPLE_FIELDS_FILE", menu_page_url("simple-fields-options", false) );
}
/**
* Add settings link to plugin page
* Hopefully this helps some people to find the settings page quicker
*/
function set_plugin_row_meta($links, $file) {
if ($file == $this->plugin_foldername_and_filename) {
return array_merge(
$links,
array( sprintf( '<a href="options-general.php?page=%s">%s</a>', "simple-fields-options", __('Settings') ) )
);
}
return $links;
}
/**
* Return an array of the post types that we have set up post connectors for
*
* Format of return:
*
* Array
* (
* [0] => post
* [1] => page
* [2] => testposttype
* )
*
* @param return array
*/
function get_post_connector_attached_types() {
global $sf;
$post_connectors = $this->get_post_connectors();
$arr_post_types = array();
foreach ($post_connectors as $one_post_connector) {
$arr_post_types = array_merge($arr_post_types, (array) $one_post_connector["post_types"]);
}
$arr_post_types = array_unique($arr_post_types);
return $arr_post_types;
}
/**
* Get default connector for a post type
* If no connector has been set, __none__ is returned
*
* @param string $post_type
* @return mixed int connector id or string __none__ or __inherit__
*/
function get_default_connector_for_post_type($post_type) {
$post_type_defaults = $this->get_post_type_defaults();
$selected_post_type_default = (isset($post_type_defaults[$post_type]) ? $post_type_defaults[$post_type] : "__none__");
$selected_post_type_default = apply_filters( "simple_fields_get_default_connector_for_post_type", $selected_post_type_default, $post_type );
return $selected_post_type_default;
}
/**
* Output HTML for dialog in bottom
*/
function admin_footer() {
// HTML for post dialog
?><div class="simple-fields-meta-box-field-group-field-type-post-dialog hidden"></div><?php
}
/**
* output nonce
*/
function post_dbx_post_sidebar() {
?>
<input type="hidden" name="simple_fields_nonce" id="simple_fields_nonce" value="<?php echo wp_create_nonce( plugin_basename(__FILE__) ); ?>" />
<?php
}
/**
* Saves simple fields data when post is being saved
*/
function save_postdata($post_id = null, $post = null) {
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
// so not checking nonce can lead to errors, for example losing post connector
if (!isset($_POST['simple_fields_nonce']) || !wp_verify_nonce( $_POST['simple_fields_nonce'], plugin_basename(__FILE__) )) {
return $post_id;
}
// verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) { return $post_id; }
// why dont' we want to save revisions? i'll do that from now on, let's se what happens
// dont's save if is revision
// preview is a revison? should save then so preview with fields work
// if (wp_is_post_revision($post_id) !== FALSE) return $post_id;
// attach post connector
// only save if being found in post variable, beacuse it may not exist if meta box is hidden/not outputted on page
if ( isset($_POST["simple_fields_selected_connector"]) ) {
$simple_fields_selected_connector = (isset($_POST["simple_fields_selected_connector"])) ? $_POST["simple_fields_selected_connector"] : null;
update_post_meta($post_id, "_simple_fields_selected_connector", $simple_fields_selected_connector);
}
$post_id = (int) $post_id;
$fieldgroups = (isset($_POST["simple_fields_fieldgroups"])) ? $_POST["simple_fields_fieldgroups"] : null;
$field_groups_option = $this->get_field_groups();
if ( !$table = _get_meta_table("post") ) { return false; }
global $wpdb;
// We have a post_id and we have fieldgroups
if ($post_id && is_array($fieldgroups)) {
// Delete all exisiting custom fields meta that are not part of the keep-list
$post_meta = get_post_custom($post_id);
// new format.. can be anything... how to get it?
$arr_meta_keys_to_keep = array(
"_simple_fields_been_saved",
"_simple_fields_selected_connector"
);
foreach ($post_meta as $meta_key => $meta_val) {
if ( strpos($meta_key, "_simple_fields_") === 0 ) {
// this is a meta for simple fields, check if it should be kept or deleted
if ( ! in_array($meta_key, $arr_meta_keys_to_keep ) ) {
delete_post_meta($post_id, $meta_key);
}
}
}
// cleanup missing keys, due to checkboxes not being checked
$fieldgroups_fixed = $fieldgroups;
foreach ($fieldgroups as $one_field_group_id => $one_field_group_fields) {
foreach ($one_field_group_fields as $posted_id => $posted_vals) {
if ($posted_id == "added") {
continue;
}
$fieldgroups_fixed[$one_field_group_id][$posted_id] = array();
// loopa igenom "added"-värdena och fixa så att allt finns
foreach ($one_field_group_fields["added"] as $added_id => $added_val) {
$fieldgroups_fixed[$one_field_group_id][$posted_id][$added_id] = @$fieldgroups[$one_field_group_id][$posted_id][$added_id];
}
}
}
$fieldgroups = $fieldgroups_fixed;
// Save info about the fact that this post have been saved. This info is used to determine if a post should get default values or not.
update_post_meta($post_id, "_simple_fields_been_saved", "1");
// Loop through each fieldgroups
#sf_d($fieldgroups, '$fieldgroups');
foreach ($fieldgroups as $one_field_group_id => $one_field_group_fields) {
// Loop through each field in each field group
#simple_fields::debug("one_field_group_fields", $one_field_group_fields);
#sf_d($one_field_group_fields);
// Get info about the field group that are saved
// (We only get ID:s posted, so no meta info about the group)
$arr_fieldgroup_info = $this->get_field_group( $one_field_group_id );
foreach ($one_field_group_fields as $one_field_id => $one_field_values) {
// one_field_id = id på fältet vi sparar. t.ex. id:et på "måndag" eller "tisdag"
// one_field_values = sparade värden för detta fält, sorterat i den ordning som syns i admin
// dvs. nyaste överst (med key "new0"), och sedan key 0, key 1, osv.
#simple_fields::debug("save, loop fields, one_field_id", $one_field_id);
#simple_fields::debug("save, loop fields, one_field_values", $one_field_values);
// determine type of field we are saving
$field_info = isset($field_groups_option[$one_field_group_id]["fields"][$one_field_id]) ? $field_groups_option[$one_field_group_id]["fields"][$one_field_id] : NULL;
$field_type = $field_info["type"]; // @todo: this should be a function
#simple_fields::debug("save, field_type", $field_type);
$do_wpautop = false;
if ($field_type == "textarea" && isset($field_info["type_textarea_options"]["use_html_editor"]) && $field_info["type_textarea_options"]["use_html_editor"] == 1) {
// it's a tiny edit area, so use wpautop to fix p and br
$do_wpautop = true;
}
$do_wpautop = apply_filters("simple_fields_save_postdata_do_wpautop", $do_wpautop, $post_id);
// save entered value for each added group
$num_in_set = 0;
foreach ($one_field_values as $one_field_value) {
// $one_field_id may be "added" because it's... a special kind of input field
$arr_field_info = array();
$one_field_slug = "";
if ("added" === $one_field_id) {
$one_field_slug = "added";
} else {
#sf_d($arr_fieldgroup_info["fields"], 'fields');
foreach ($arr_fieldgroup_info["fields"] as $one_field_in_fieldgroup) {
if ( intval( $one_field_in_fieldgroup["id"] ) === intval( $one_field_id ) ) {
$arr_field_info = $one_field_in_fieldgroup;
break;
}
}
$one_field_slug = $arr_field_info["slug"];
#sf_d($one_field_slug, 'one_field_slug');
#sf_d($one_field_id, 'one_field_id');
#exit;
}
$custom_field_key = $this->get_meta_key( $one_field_group_id, $one_field_id, $num_in_set, $arr_fieldgroup_info["slug"], $one_field_slug );
$custom_field_value = $one_field_value;
/*sf_d($custom_field_key, '$custom_field_key');
sf_d($one_field_group_id, '$one_field_group_id');
sf_d($one_field_id, '$one_field_id');
sf_d($num_in_set, 'num_in_set');
sf_d($arr_fieldgroup_info["slug"], 'arr_fieldgroup_info["slug"]');
sf_d($one_field_slug, 'one_field_slug');*/
if (array_key_exists($field_type, $this->registered_field_types)) {
// Custom field type
$custom_field_value = $this->registered_field_types[$field_type]->edit_save($custom_field_value);
/*
Date field:
Array
(
[date_unixtime] => 1351983600000
)
Map field:
Array
(
[lat] => 59.312089
[lng] => 18.074117
[name] => Monki Skrapan
[formatted_address] => Götgatan 78, Stockholm, Sverige
[address_components] => [{\"long_name\":\"78\",\"short_name\":\"78\",\"types\":[\"street_number\"]},{\"long_name\":\"Götgatan\",\"short_name\":\"Götgatan\",\"types\":[\"route\"]},{\"long_name\":\"Södermalm\",\"short_name\":\"Södermalm\",\"types\":[\"sublocality\",\"political\"]},{\"long_name\":\"Stockholm\",\"short_name\":\"Stockholm\",\"types\":[\"locality\",\"political\"]},{\"long_name\":\"Stockholms län\",\"short_name\":\"Stockholms län\",\"types\":[\"administrative_area_level_2\",\"political\"]},{\"long_name\":\"SE\",\"short_name\":\"SE\",\"types\":[\"country\",\"political\"]},{\"long_name\":\"11830\",\"short_name\":\"11830\",\"types\":[\"postal_code\"]}]
)
*/
//echo "xxx save value for custom field type"; sf_d($custom_field_value);
} else {
// core/legacy field type
if ($do_wpautop) {
$custom_field_value = wpautop($custom_field_value);
}
}
// echo "<br>Saving value for post with id $post_id. Custom_field_key is $custom_field_key, custom_field_value is:";sf_d($custom_field_value);
update_post_meta($post_id, $custom_field_key, $custom_field_value);
$num_in_set++;
}
}
}
// if array
} else if (empty($fieldgroups)) {
// if fieldgroups are empty we still need to save it
// remove existing simple fields custom fields for this post
// @todo: this should also be using wordpress own functions
// TODO: use new meta keys names
$wpdb->query("DELETE FROM $table WHERE post_id = $post_id AND meta_key LIKE '_simple_fields_fieldGroupID_%'");
}
// echo "end save";
} // save postdata
/**
* adds a fieldgroup through ajax = also fetch defaults
* called when clicking "+ add" in post edit screen
*/
function metabox_fieldgroup_add() {
global $sf;
$simple_fields_new_fields_count = (int) $_POST["simple_fields_new_fields_count"];
$post_id = (int) $_POST["post_id"];
$field_group_id = (int) $_POST["field_group_id"];
$num_in_set = "new{$simple_fields_new_fields_count}";
$this->meta_box_output_one_field_group($field_group_id, $num_in_set, $post_id, true);
exit;
}
/**
* Output the html for a field group in the meta box on the post edit screen
* Also called from ajax when clicking "+ add"
*/
function meta_box_output_one_field_group($field_group_id, $num_in_set, $post_id, $use_defaults) {
$post = get_post($post_id);
$field_groups = $this->get_field_groups();
$current_field_group = $field_groups[$field_group_id];
$repeatable = (bool) $current_field_group["repeatable"];
$field_group_css = "simple-fields-fieldgroup-$field_group_id";
/* if (isset($current_field_group["slug"]) && !empty($current_field_group["slug"])) {
$field_group_css .= " simple-fields-fieldgroup-" . $current_field_group["slug"];
}*/
?><li class="sf-cf simple-fields-metabox-field-group <?php echo $field_group_css ?>">
<?php // must use this "added"-thingie do be able to track added field group that has no added values (like unchecked checkboxes, that we can't detect ?>
<input type="hidden" name="simple_fields_fieldgroups[<?php echo $field_group_id ?>][added][<?php echo $num_in_set ?>]" value="1" />
<div class="simple-fields-metabox-field-group-handle"></div>
<?php
// if repeatable: add remove-link
if ($repeatable) {
?><div class="hidden simple-fields-metabox-field-group-delete"><a href="#" title="<?php _e('Remove field group', 'simple-fields') ?>"></a></div><?php
}
// Output content for each field in this fieldgroup
// LI = fieldgroup
// DIV = field
foreach ($current_field_group["fields"] as $field) {
if ($field["deleted"]) { continue; }
$field_id = $field["id"];
$field_unique_id = "simple_fields_fieldgroups_{$field_group_id}_{$field_id}_{$num_in_set}";
$field_name = "simple_fields_fieldgroups[$field_group_id][$field_id][$num_in_set]";
$field_class = "simple-fields-fieldgroups-field-{$field_group_id}-{$field_id} ";
$field_class .= "simple-fields-fieldgroups-field-type-" . $field["type"];
if (isset($field["slug"]) && !empty($field["slug"])) {
$field_class .= " simple-fields-fieldgroups-field-slug-" . $field["slug"];
}
// Fetch saved value for field from db/post meta
// Returned value is:
// - string if core fields
// - array if field type extension, unless the field extension overrides this
$custom_field_key = $this->get_meta_key($field_group_id, $field_id, $num_in_set, $current_field_group["slug"], $field["slug"]);
/*sf_d($field_group_id, '$field_group_id');
sf_d($field_id, '$field_id');
sf_d($num_in_set, '$num_in_set');
sf_d($current_field_group["slug"], '$current_field_group["slug"]');
sf_d($field["slug"], '$field["slug"]');
sf_d($custom_field_key, '$custom_field_key');*/
$saved_value = get_post_meta($post_id, $custom_field_key, true);
// Options, common for all fields
$field_maybe_translated_name = $this->get_string( "Field name, " . $field["slug"], $field["name"] );
$description = "";
if ( ! empty( $field["description"] ) ) {
$description = sprintf("<div class='simple-fields-metabox-field-description'>%s</div>", esc_html( $this->get_string("Field description, " . $field["slug"], $field["description"] ) ) );
}