Version Description
- SAFE UPDATE: No data loss for those upgrading from version 1.0 or higher
- Preparing for PRO version
Download this release
Release Info
Developer | spwebguy |
Plugin | ![]() |
Version | 1.0.1 |
Comparing to | |
See all releases |
Version 1.0.1
- css/tmm_custom_style.css +93 -0
- css/tmm_custom_style.min.css +1 -0
- drkfr/Gruntfile.js +39 -0
- drkfr/class.drkfr-meta-box.php +379 -0
- drkfr/classes.fields.php +1675 -0
- drkfr/css/dist/drkfr.css +63 -0
- drkfr/css/dist/drkfr.min.css +63 -0
- drkfr/css/legacy.css +319 -0
- drkfr/css/src/file.css +166 -0
- drkfr/css/src/generic.css +55 -0
- drkfr/css/src/group.css +82 -0
- drkfr/css/src/layout.css +57 -0
- drkfr/css/src/misc-fields.css +71 -0
- drkfr/css/src/repeatable.css +88 -0
- drkfr/css/src/sortable.css +40 -0
- drkfr/css/vendor/jquery-ui/images/animated-overlay.gif +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-icons_222222_256x240.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-icons_2e83ff_256x240.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-icons_454545_256x240.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-icons_888888_256x240.png +0 -0
- drkfr/css/vendor/jquery-ui/images/ui-icons_cd0a0a_256x240.png +0 -0
- drkfr/css/vendor/jquery-ui/jquery-ui.css +1175 -0
- drkfr/css/vendor/jquery-ui/jquery-ui.min.css +5 -0
- drkfr/css/vendor/jquery-ui/jquery.ui.theme.css +406 -0
- drkfr/custom-meta-boxes.php +136 -0
- drkfr/fields-anywhere.php +92 -0
- drkfr/images/drkfr-icon-remove.png +0 -0
- drkfr/images/drkfr-icon-remove@2x.png +0 -0
- drkfr/images/wpspin-2x.gif +0 -0
- drkfr/images/wpspin.gif +0 -0
- drkfr/js/drkfr.js +315 -0
- drkfr/js/field-gmap.js +93 -0
- drkfr/js/field-wysiwyg.js +106 -0
- drkfr/js/field.colorpicker.js +18 -0
- drkfr/js/field.datetime.js +47 -0
- drkfr/js/field.select.js +29 -0
- drkfr/js/file-upload.js +129 -0
- drkfr/js/jquery.timePicker.min.js +20 -0
- drkfr/js/vendor/select2/.bower.json +25 -0
- drkfr/js/vendor/select2/.gitignore +2 -0
- drkfr/js/vendor/select2/LICENSE +18 -0
- drkfr/js/vendor/select2/README.md +99 -0
- drkfr/js/vendor/select2/bower.json +8 -0
- drkfr/js/vendor/select2/component.json +66 -0
- drkfr/js/vendor/select2/composer.json +29 -0
- drkfr/js/vendor/select2/package.json +20 -0
- drkfr/js/vendor/select2/release.sh +79 -0
- drkfr/js/vendor/select2/select2-bootstrap.css +87 -0
- drkfr/js/vendor/select2/select2-spinner.gif +0 -0
- drkfr/js/vendor/select2/select2.css +704 -0
- drkfr/js/vendor/select2/select2.jquery.json +36 -0
- drkfr/js/vendor/select2/select2.js +3508 -0
- drkfr/js/vendor/select2/select2.min.js +23 -0
- drkfr/js/vendor/select2/select2.png +0 -0
- drkfr/js/vendor/select2/select2_locale_ar.js +19 -0
- drkfr/js/vendor/select2/select2_locale_az.js +20 -0
- drkfr/js/vendor/select2/select2_locale_bg.js +20 -0
- drkfr/js/vendor/select2/select2_locale_ca.js +19 -0
- drkfr/js/vendor/select2/select2_locale_cs.js +51 -0
- drkfr/js/vendor/select2/select2_locale_da.js +19 -0
- drkfr/js/vendor/select2/select2_locale_de.js +18 -0
- drkfr/js/vendor/select2/select2_locale_el.js +19 -0
- drkfr/js/vendor/select2/select2_locale_en.js.template +20 -0
- drkfr/js/vendor/select2/select2_locale_es.js +17 -0
- drkfr/js/vendor/select2/select2_locale_et.js +19 -0
- drkfr/js/vendor/select2/select2_locale_eu.js +45 -0
- drkfr/js/vendor/select2/select2_locale_fa.js +21 -0
- drkfr/js/vendor/select2/select2_locale_fi.js +30 -0
- drkfr/js/vendor/select2/select2_locale_fr.js +18 -0
- drkfr/js/vendor/select2/select2_locale_gl.js +45 -0
- drkfr/js/vendor/select2/select2_locale_he.js +19 -0
- drkfr/js/vendor/select2/select2_locale_hr.js +24 -0
- drkfr/js/vendor/select2/select2_locale_hu.js +17 -0
- drkfr/js/vendor/select2/select2_locale_id.js +19 -0
- drkfr/js/vendor/select2/select2_locale_is.js +17 -0
- drkfr/js/vendor/select2/select2_locale_it.js +17 -0
- drkfr/js/vendor/select2/select2_locale_ja.js +17 -0
- drkfr/js/vendor/select2/select2_locale_ka.js +19 -0
- drkfr/js/vendor/select2/select2_locale_ko.js +19 -0
- drkfr/js/vendor/select2/select2_locale_lt.js +26 -0
- drkfr/js/vendor/select2/select2_locale_lv.js +19 -0
- drkfr/js/vendor/select2/select2_locale_mk.js +19 -0
- drkfr/js/vendor/select2/select2_locale_ms.js +19 -0
- drkfr/js/vendor/select2/select2_locale_nl.js +17 -0
- drkfr/js/vendor/select2/select2_locale_no.js +20 -0
- drkfr/js/vendor/select2/select2_locale_pl.js +25 -0
- drkfr/js/vendor/select2/select2_locale_pt-BR.js +17 -0
- drkfr/js/vendor/select2/select2_locale_pt-PT.js +17 -0
- drkfr/js/vendor/select2/select2_locale_ro.js +17 -0
- drkfr/js/vendor/select2/select2_locale_rs.js +19 -0
- drkfr/js/vendor/select2/select2_locale_ru.js +23 -0
- drkfr/js/vendor/select2/select2_locale_sk.js +50 -0
- drkfr/js/vendor/select2/select2_locale_sv.js +19 -0
- drkfr/js/vendor/select2/select2_locale_th.js +19 -0
- drkfr/js/vendor/select2/select2_locale_tr.js +19 -0
- drkfr/js/vendor/select2/select2_locale_ug-CN.js +16 -0
- drkfr/js/vendor/select2/select2_locale_uk.js +25 -0
- drkfr/js/vendor/select2/select2_locale_vi.js +20 -0
- drkfr/js/vendor/select2/select2_locale_zh-CN.js +16 -0
- drkfr/js/vendor/select2/select2_locale_zh-TW.js +16 -0
- drkfr/js/vendor/select2/select2x2.png +0 -0
- drkfr/phpunit.xml +14 -0
- img/links/customlink.png +0 -0
- img/links/facebook.png +0 -0
- img/links/googleplus.png +0 -0
- img/links/linkedin.png +0 -0
- img/links/twitter.png +0 -0
- readme.txt +76 -0
- tmm.php +305 -0
css/tmm_custom_style.css
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@charset "UTF-8";
|
2 |
+
.tmm_wrap {width:100%; margin-bottom:30px; text-align:center;}
|
3 |
+
.clearer {clear:both;}
|
4 |
+
|
5 |
+
.tmm_member {
|
6 |
+
margin-top:100px;
|
7 |
+
height:auto;
|
8 |
+
float: left;
|
9 |
+
text-align:center;
|
10 |
+
border-bottom:1px solid whitesmoke;
|
11 |
+
-webkit-box-shadow: 1px 0px 5px 0px rgba(0,0,0,0.05);
|
12 |
+
-moz-box-shadow: 1px 0px 5px 0px rgba(0,0,0,0.05);
|
13 |
+
box-shadow: 1px 0px 5px 0px rgba(0,0,0,0.05);
|
14 |
+
border-top:5px solid lightgrey;
|
15 |
+
border-bottom:8px solid whitesmoke;
|
16 |
+
}
|
17 |
+
|
18 |
+
.tmm_three_entries {clear:both;}
|
19 |
+
|
20 |
+
.tmm_3_columns .tmm_member {width: 31%; margin-right:1%; margin-left:1%;}
|
21 |
+
.tmm_4_columns .tmm_member {width: 23%; margin-right:1%; margin-left:1%;}
|
22 |
+
|
23 |
+
.tmm_member > img {
|
24 |
+
width:150px;
|
25 |
+
height:150px;
|
26 |
+
border:none;
|
27 |
+
-webkit-box-shadow: 2px 0px 15px 0px rgba(0,0,0,0.15);
|
28 |
+
-moz-box-shadow: 2px 0px 15px 0px rgba(0,0,0,0.15);
|
29 |
+
box-shadow: 2px 0px 15px 0px rgba(0,0,0,0.15);
|
30 |
+
border-radius:60px !important;
|
31 |
+
margin-top:-80px;
|
32 |
+
border:10px solid whitesmoke;
|
33 |
+
}
|
34 |
+
|
35 |
+
.tmm_4_columns .tmm_member > img {
|
36 |
+
width:100px;
|
37 |
+
height:100px;
|
38 |
+
margin-top:-70px;
|
39 |
+
border-radius:40px !important;
|
40 |
+
border:6px solid whitesmoke;
|
41 |
+
}
|
42 |
+
|
43 |
+
.tmm_member .tmm_textblock .tmm_scblock {padding-top:10px;}
|
44 |
+
.tmm_member .tmm_textblock {padding:10px 20px;}
|
45 |
+
.tmm_member .tmm_textblock .tmm_sociallink {clear:both; margin-bottom:20px;}
|
46 |
+
.tmm_member .tmm_textblock .tmm_sociallink img {border:none; width:24px; height:24px; box-shadow: 0 0 0 0;margin:10px 5px;}
|
47 |
+
.tmm_4_columns .tmm_member .tmm_textblock .tmm_sociallink img {width:21px; height:21px; margin:6px 3px;}
|
48 |
+
.tmm_member .tmm_textblock .tmm_sociallink img:hover {opacity:0.8;}
|
49 |
+
|
50 |
+
.tmm_names {font-size:22px; margin-bottom:8px; margin-top:10px; font-weight:300; line-height:24px;}
|
51 |
+
.tmm_4_columns .tmm_names {font-size:19px;}
|
52 |
+
.tmm_fname {display:inline;}
|
53 |
+
.tmm_lname {display:inline;}
|
54 |
+
.tmm_job {font-size:14px; color:#a2a5a4; text-transform:uppercase;}
|
55 |
+
.tmm_desc {padding:10px; margin-top:19px; margin-bottom:10px; font-size:14px;}
|
56 |
+
.tmm_4_columns .tmm_desc {padding:8px; margin-top:14px; margin-bottom:8px; font-size:13px;}
|
57 |
+
|
58 |
+
/* TABLETS */
|
59 |
+
@media only screen and (min-width: 40em) and (max-width: 64.063em) {
|
60 |
+
.tmm_4_columns .tmm_member {width: 40%; margin-left:5%; margin-right:5%;}
|
61 |
+
.tmm_names {font-size:17px; margin-bottom:8px; margin-top:10px; font-weight:300; line-height:24px;}
|
62 |
+
.tmm_job {font-size:13px; color:#a2a5a4; text-transform:uppercase;}
|
63 |
+
.tmm_desc {padding:10px; margin-top:19px; margin-bottom:10px; font-size:14px; line-height:23px;}
|
64 |
+
.tmm_4_columns .tmm_desc {font-size:15px; line-height:23px;}
|
65 |
+
.tmm_3_columns .tmm_member > img {
|
66 |
+
width:100px;
|
67 |
+
height:100px;
|
68 |
+
border-radius:40px !important;
|
69 |
+
border:9px solid whitesmoke;
|
70 |
+
}
|
71 |
+
.tmm_4_columns .tmm_member > img {
|
72 |
+
width:150px;
|
73 |
+
height:150px;
|
74 |
+
border-radius:60px !important;
|
75 |
+
border:9px solid whitesmoke;
|
76 |
+
}
|
77 |
+
.tmm_4_columns .tmm_member .tmm_textblock .tmm_sociallink img {width:24px; height:24px; margin:10px 5px;}
|
78 |
+
}
|
79 |
+
|
80 |
+
/* MOBILE */
|
81 |
+
@media only screen and (max-width: 40em) {
|
82 |
+
.tmm_member {width: 96%; margin:0 2%; margin-top:120px;}
|
83 |
+
.tmm_3_columns .tmm_member, .tmm_4_columns .tmm_member {width: 96%; margin:0 2%; margin-top:120px;}
|
84 |
+
.tmm_4_columns .tmm_desc {font-size:15px;}
|
85 |
+
.tmm_4_columns .tmm_member > img {
|
86 |
+
width:150px;
|
87 |
+
height:150px;
|
88 |
+
border-radius:60px !important;
|
89 |
+
border:9px solid whitesmoke;
|
90 |
+
}
|
91 |
+
.tmm_4_columns .tmm_names {font-size:22px;}
|
92 |
+
.tmm_4_columns .tmm_member .tmm_textblock .tmm_sociallink img {width:24px; height:24px; margin:10px 5px;}
|
93 |
+
}
|
css/tmm_custom_style.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
@charset "UTF-8";.tmm_wrap{width:100%;margin-bottom:30px;text-align:center}.clearer{clear:both}.tmm_member{margin-top:100px;height:auto;float:left;text-align:center;-webkit-box-shadow:1px 0 5px 0 rgba(0,0,0,.05);-moz-box-shadow:1px 0 5px 0 rgba(0,0,0,.05);box-shadow:1px 0 5px 0 rgba(0,0,0,.05);border-top:5px solid lightgrey;border-bottom:8px solid #f5f5f5}.tmm_three_entries{clear:both}.tmm_3_columns .tmm_member{width:31%;margin-right:1%;margin-left:1%}.tmm_4_columns .tmm_member{width:23%;margin-right:1%;margin-left:1%}.tmm_member>img{width:150px;height:150px;-webkit-box-shadow:2px 0 15px 0 rgba(0,0,0,.15);-moz-box-shadow:2px 0 15px 0 rgba(0,0,0,.15);box-shadow:2px 0 15px 0 rgba(0,0,0,.15);border-radius:60px!important;margin-top:-80px;border:10px solid #f5f5f5}.tmm_4_columns .tmm_member>img{width:100px;height:100px;margin-top:-70px;border-radius:40px!important;border:6px solid #f5f5f5}.tmm_member .tmm_textblock .tmm_scblock{padding-top:10px}.tmm_member .tmm_textblock{padding:10px 20px}.tmm_member .tmm_textblock .tmm_sociallink{clear:both;margin-bottom:20px}.tmm_member .tmm_textblock .tmm_sociallink img{border:none;width:24px;height:24px;box-shadow:0 0;margin:10px 5px}.tmm_4_columns .tmm_member .tmm_textblock .tmm_sociallink img{width:21px;height:21px;margin:6px 3px}.tmm_member .tmm_textblock .tmm_sociallink img:hover{opacity:.8}.tmm_names{font-size:22px;margin-bottom:8px;margin-top:10px;font-weight:300;line-height:24px}.tmm_4_columns .tmm_names{font-size:19px}.tmm_fname,.tmm_lname{display:inline}.tmm_job{font-size:14px;color:#a2a5a4;text-transform:uppercase}.tmm_desc{padding:10px;margin-top:19px;margin-bottom:10px;font-size:14px}.tmm_4_columns .tmm_desc{padding:8px;margin-top:14px;margin-bottom:8px;font-size:13px}@media only screen and (min-width:40em) and (max-width:64.063em){.tmm_4_columns .tmm_member{width:40%;margin-left:5%;margin-right:5%}.tmm_names{font-size:17px;margin-bottom:8px;margin-top:10px;font-weight:300;line-height:24px}.tmm_job{font-size:13px;color:#a2a5a4;text-transform:uppercase}.tmm_desc{padding:10px;margin-top:19px;margin-bottom:10px;font-size:14px;line-height:23px}.tmm_4_columns .tmm_desc{font-size:15px;line-height:23px}.tmm_3_columns .tmm_member>img{width:100px;height:100px;border-radius:40px!important;border:9px solid #f5f5f5}.tmm_4_columns .tmm_member>img{width:150px;height:150px;border-radius:60px!important;border:9px solid #f5f5f5}.tmm_4_columns .tmm_member .tmm_textblock .tmm_sociallink img{width:24px;height:24px;margin:10px 5px}}@media only screen and (max-width:40em){.tmm_3_columns .tmm_member,.tmm_4_columns .tmm_member,.tmm_member{width:96%;margin:120px 2% 0}.tmm_4_columns .tmm_desc{font-size:15px}.tmm_4_columns .tmm_member>img{width:150px;height:150px;border-radius:60px!important;border:9px solid #f5f5f5}.tmm_4_columns .tmm_names{font-size:22px}.tmm_4_columns .tmm_member .tmm_textblock .tmm_sociallink img{width:24px;height:24px;margin:10px 5px}}
|
drkfr/Gruntfile.js
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*global module:false*/
|
2 |
+
module.exports = function(grunt) {
|
3 |
+
|
4 |
+
// Project configuration.
|
5 |
+
grunt.initConfig({
|
6 |
+
// Metadata.
|
7 |
+
pkg: grunt.file.readJSON('package.json'),
|
8 |
+
banner: '/**\n' +
|
9 |
+
' * <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
|
10 |
+
'<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
|
11 |
+
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;' + ' License: <%= pkg.license %>\n' +
|
12 |
+
' */',
|
13 |
+
cssmin: {
|
14 |
+
combine: {
|
15 |
+
options: {
|
16 |
+
banner: '<%= banner %>'
|
17 |
+
},
|
18 |
+
files: {
|
19 |
+
'css/dist/DKTBS.min.css': [
|
20 |
+
'css/src/layout.css',
|
21 |
+
'css/src/generic.css',
|
22 |
+
'css/src/repeatable.css',
|
23 |
+
'css/src/sortable.css',
|
24 |
+
'css/src/group.css',
|
25 |
+
'css/src/file.css',
|
26 |
+
'css/src/misc-fields.css'
|
27 |
+
]
|
28 |
+
}
|
29 |
+
}
|
30 |
+
}
|
31 |
+
});
|
32 |
+
|
33 |
+
// These plugins provide necessary tasks.
|
34 |
+
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
35 |
+
|
36 |
+
// Default task.
|
37 |
+
grunt.registerTask('default', [ 'cssmin' ] );
|
38 |
+
|
39 |
+
};
|
drkfr/class.drkfr-meta-box.php
ADDED
@@ -0,0 +1,379 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Create meta boxes
|
5 |
+
*/
|
6 |
+
class drkfr_Meta_Box {
|
7 |
+
|
8 |
+
protected $_meta_box;
|
9 |
+
private $fields = array();
|
10 |
+
|
11 |
+
function __construct( $meta_box ) {
|
12 |
+
|
13 |
+
$this->_meta_box = $meta_box;
|
14 |
+
|
15 |
+
if ( empty( $this->_meta_box['id'] ) )
|
16 |
+
$this->_meta_box['id'] = sanitize_title( $this->_meta_box['title'] );
|
17 |
+
|
18 |
+
add_action( 'dbx_post_advanced', array( &$this, 'init_fields_for_post' ) );
|
19 |
+
add_action( 'drkfr_init_fields', array( &$this, 'init_fields' ) );
|
20 |
+
|
21 |
+
global $pagenow;
|
22 |
+
|
23 |
+
add_action( 'admin_menu', array( &$this, 'add' ) );
|
24 |
+
add_action( 'save_post', array( &$this, 'save_for_post' ) );
|
25 |
+
add_action( 'edit_attachment', array( &$this, 'save_for_post' ) );
|
26 |
+
add_action( 'drkfr_save_fields', array( &$this, 'save' ) );
|
27 |
+
|
28 |
+
add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ) );
|
29 |
+
add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_styles' ) );
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
public function init_fields( $post_id = 0 ) {
|
34 |
+
|
35 |
+
foreach ( $this->_meta_box['fields'] as $key => $field ) {
|
36 |
+
|
37 |
+
$values = array();
|
38 |
+
|
39 |
+
$args = $field;
|
40 |
+
unset( $args['id'] );
|
41 |
+
unset( $args['type'] );
|
42 |
+
unset( $args['name'] );
|
43 |
+
|
44 |
+
$class = _drkfr_field_class_for_type( $field['type'] );
|
45 |
+
|
46 |
+
// If we are on a post edit screen - get metadata value of the field for this post
|
47 |
+
if ( $post_id ) {
|
48 |
+
$values = (array) get_post_meta( $post_id, $field['id'], false );
|
49 |
+
}
|
50 |
+
|
51 |
+
if ( class_exists( $class ) ) {
|
52 |
+
$this->fields[] = new $class( $field['id'], $field['name'], (array) $values, $args );
|
53 |
+
}
|
54 |
+
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
58 |
+
|
59 |
+
public function init_fields_for_post() {
|
60 |
+
|
61 |
+
global $post, $temp_ID;
|
62 |
+
|
63 |
+
// Get the current ID
|
64 |
+
if( isset( $_GET['post'] ) )
|
65 |
+
$post_id = $_GET['post'];
|
66 |
+
|
67 |
+
elseif( isset( $_POST['post_ID'] ) )
|
68 |
+
$post_id = $_POST['post_ID'];
|
69 |
+
|
70 |
+
elseif ( ! empty( $post->ID ) )
|
71 |
+
$post_id = $post->ID;
|
72 |
+
|
73 |
+
if ( is_page() || ! isset( $post_id ) )
|
74 |
+
return false;
|
75 |
+
|
76 |
+
$this->init_fields( (int) $post_id );
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
function enqueue_scripts() {
|
81 |
+
|
82 |
+
wp_enqueue_script( 'drkfr-scripts', trailingslashit( drkfr_URL ) . 'js/drkfr.js', array( 'jquery' ) );
|
83 |
+
|
84 |
+
wp_localize_script( 'drkfr-scripts', 'drkfrData', array(
|
85 |
+
'strings' => array(
|
86 |
+
'confirmDeleteField' => __( 'Are you sure you want to delete this field?', 'drkfr' )
|
87 |
+
)
|
88 |
+
) );
|
89 |
+
|
90 |
+
foreach ( $this->fields as $field )
|
91 |
+
$field->enqueue_scripts();
|
92 |
+
|
93 |
+
}
|
94 |
+
|
95 |
+
function enqueue_styles() {
|
96 |
+
|
97 |
+
$suffix = drkfr_DEV ? '' : '.min';
|
98 |
+
|
99 |
+
if ( version_compare( get_bloginfo( 'version' ), '3.8', '>=' ) )
|
100 |
+
wp_enqueue_style( 'drkfr-styles', trailingslashit( drkfr_URL ) . "css/dist/drkfr$suffix.css" );
|
101 |
+
else
|
102 |
+
wp_enqueue_style( 'drkfr-styles', trailingslashit( drkfr_URL ) . 'css/legacy.css' );
|
103 |
+
|
104 |
+
foreach ( $this->fields as $field )
|
105 |
+
$field->enqueue_styles();
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
// Add metabox
|
110 |
+
function add() {
|
111 |
+
|
112 |
+
$this->_meta_box['context'] = empty($this->_meta_box['context']) ? 'normal' : $this->_meta_box['context'];
|
113 |
+
$this->_meta_box['priority'] = empty($this->_meta_box['priority']) ? 'low' : $this->_meta_box['priority'];
|
114 |
+
|
115 |
+
// Backwards compatablilty.
|
116 |
+
if ( isset( $this->_meta_box['show_on']['key'] ) ) {
|
117 |
+
$this->_meta_box['show_on'][ $this->_meta_box['show_on']['key'] ] = $this->_meta_box['show_on']['value'];
|
118 |
+
unset( $this->_meta_box['show_on']['key'] );
|
119 |
+
unset( $this->_meta_box['show_on']['value'] );
|
120 |
+
}
|
121 |
+
|
122 |
+
foreach ( (array) $this->_meta_box['pages'] as $page ) {
|
123 |
+
if ( $this->is_metabox_displayed() ) {
|
124 |
+
add_meta_box( $this->_meta_box['id'], $this->_meta_box['title'], array(&$this, 'show'), $page, $this->_meta_box['context'], $this->_meta_box['priority'] ) ;
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Handle 'Show On' and 'Hide On' Filters
|
132 |
+
*/
|
133 |
+
function is_metabox_displayed() {
|
134 |
+
$display = true;
|
135 |
+
$display = $this->add_for_id( $display );
|
136 |
+
$display = $this->hide_for_id( $display );
|
137 |
+
$display = $this->add_for_page_template( $display );
|
138 |
+
$display = $this->hide_for_page_template( $display );
|
139 |
+
return $display;
|
140 |
+
}
|
141 |
+
|
142 |
+
// Add drkfr for ID
|
143 |
+
function add_for_id( $display ) {
|
144 |
+
|
145 |
+
if ( ! isset( $this->_meta_box['show_on']['id'] ) ) {
|
146 |
+
return $display;
|
147 |
+
}
|
148 |
+
|
149 |
+
// Don't show drkfr if we can't identify ID of a post
|
150 |
+
$post_id = $this->get_post_id();
|
151 |
+
|
152 |
+
if ( ! isset( $post_id ) ) {
|
153 |
+
return false;
|
154 |
+
}
|
155 |
+
|
156 |
+
// If value isn't an array, turn it into one
|
157 |
+
$this->_meta_box['show_on']['id'] = ! is_array( $this->_meta_box['show_on']['id'] ) ? array( $this->_meta_box['show_on']['id'] ) : $this->_meta_box['show_on']['id'];
|
158 |
+
|
159 |
+
return in_array( $post_id, $this->_meta_box['show_on']['id'] );
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
// Hide drkfr for ID
|
164 |
+
function hide_for_id( $display ) {
|
165 |
+
|
166 |
+
if ( ! isset( $this->_meta_box['hide_on']['id'] ) ) {
|
167 |
+
return $display;
|
168 |
+
}
|
169 |
+
|
170 |
+
// Return if we can't identify ID of a post
|
171 |
+
$post_id = $this->get_post_id();
|
172 |
+
if ( ! isset( $post_id ) ) {
|
173 |
+
return $display;
|
174 |
+
}
|
175 |
+
|
176 |
+
// If value isn't an array, turn it into one
|
177 |
+
$this->_meta_box['hide_on']['id'] = ! is_array( $this->_meta_box['hide_on']['id'] ) ? array( $this->_meta_box['hide_on']['id'] ) : $this->_meta_box['hide_on']['id'];
|
178 |
+
|
179 |
+
return ! in_array( $post_id, $this->_meta_box['hide_on']['id'] );
|
180 |
+
|
181 |
+
}
|
182 |
+
|
183 |
+
// Add drkfr for Page Template
|
184 |
+
function add_for_page_template( $display ) {
|
185 |
+
|
186 |
+
if ( ! isset( $this->_meta_box['show_on']['page-template'] ) ) {
|
187 |
+
return $display;
|
188 |
+
}
|
189 |
+
|
190 |
+
// Return false if we can't identify ID of a post
|
191 |
+
$post_id = $this->get_post_id();
|
192 |
+
if ( ! isset( $post_id ) ) {
|
193 |
+
return false;
|
194 |
+
}
|
195 |
+
|
196 |
+
// Get current template
|
197 |
+
$current_template = get_post_meta( $post_id, '_wp_page_template', true );
|
198 |
+
|
199 |
+
// If value isn't an array, turn it into one
|
200 |
+
$this->_meta_box['show_on']['page-template'] = ! is_array( $this->_meta_box['show_on']['page-template'] ) ? array( $this->_meta_box['show_on']['page-template'] ) : $this->_meta_box['show_on']['page-template'];
|
201 |
+
|
202 |
+
return in_array( $current_template, $this->_meta_box['show_on']['page-template'] );
|
203 |
+
|
204 |
+
}
|
205 |
+
|
206 |
+
// Hide drkfr for Page Template
|
207 |
+
function hide_for_page_template( $display ) {
|
208 |
+
|
209 |
+
if ( ! isset( $this->_meta_box['hide_on']['page-template'] ) ) {
|
210 |
+
return $display;
|
211 |
+
}
|
212 |
+
|
213 |
+
// Return $display if we can't identify ID of a post and hence its current template
|
214 |
+
$post_id = $this->get_post_id();
|
215 |
+
|
216 |
+
if ( ! isset( $post_id ) ) {
|
217 |
+
return $display;
|
218 |
+
}
|
219 |
+
|
220 |
+
// Get current template
|
221 |
+
$current_template = get_post_meta( $post_id, '_wp_page_template', true );
|
222 |
+
|
223 |
+
// If value isn't an array, turn it into one
|
224 |
+
$this->_meta_box['hide_on']['page-template'] = ! is_array( $this->_meta_box['hide_on']['page-template'] ) ? array( $this->_meta_box['hide_on']['page-template'] ) : $this->_meta_box['hide_on']['page-template'];
|
225 |
+
|
226 |
+
return ! in_array( $current_template, $this->_meta_box['hide_on']['page-template'] );
|
227 |
+
|
228 |
+
}
|
229 |
+
|
230 |
+
// display fields
|
231 |
+
function show() { ?>
|
232 |
+
|
233 |
+
<input type="hidden" name="wp_meta_box_nonce" value="<?php esc_attr_e( wp_create_nonce( basename(__FILE__) ) ); ?>" />
|
234 |
+
|
235 |
+
<?php self::layout_fields( $this->fields );
|
236 |
+
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Layout an array of fields, depending on their 'cols' property.
|
241 |
+
*
|
242 |
+
* This is a static method so other fields can use it that rely on sub fields
|
243 |
+
*
|
244 |
+
* @param drkfr_Field[] $fields
|
245 |
+
*/
|
246 |
+
static function layout_fields( array $fields ) { ?>
|
247 |
+
|
248 |
+
<div class="drkfr_metabox">
|
249 |
+
|
250 |
+
<?php $current_colspan = 0;
|
251 |
+
|
252 |
+
foreach ( $fields as $field ) :
|
253 |
+
|
254 |
+
if ( $current_colspan == 0 ) : ?>
|
255 |
+
|
256 |
+
<div class="drkfr-row">
|
257 |
+
|
258 |
+
<?php endif;
|
259 |
+
|
260 |
+
$current_colspan += $field->args['cols'];
|
261 |
+
|
262 |
+
$classes = array( 'field', get_class($field) );
|
263 |
+
|
264 |
+
if ( ! empty( $field->args['repeatable'] ) )
|
265 |
+
$classes[] = 'repeatable';
|
266 |
+
|
267 |
+
if ( ! empty( $field->args['sortable'] ) )
|
268 |
+
$classes[] = 'drkfr-sortable';
|
269 |
+
|
270 |
+
$attrs = array(
|
271 |
+
sprintf( 'id="%s"', sanitize_html_class( $field->id ) ),
|
272 |
+
sprintf( 'class="%s"', esc_attr( implode(' ', array_map( 'sanitize_html_class', $classes ) ) ) )
|
273 |
+
);
|
274 |
+
|
275 |
+
// Field Repeatable Max.
|
276 |
+
if ( isset( $field->args['repeatable_max'] ) )
|
277 |
+
$attrs[] = sprintf( 'data-rep-max="%s"', intval( $field->args['repeatable_max'] ) );
|
278 |
+
|
279 |
+
?>
|
280 |
+
|
281 |
+
<div class="drkfr-cell-<?php echo intval( $field->args['cols'] ); ?>">
|
282 |
+
|
283 |
+
<div <?php echo implode( ' ', $attrs ); ?>>
|
284 |
+
<?php $field->display(); ?>
|
285 |
+
</div>
|
286 |
+
|
287 |
+
<input type="hidden" name="_drkfr_present_<?php esc_attr_e( $field->id ); ?>" value="1" />
|
288 |
+
|
289 |
+
</div>
|
290 |
+
|
291 |
+
<?php if ( $current_colspan == 12 || $field === end( $fields ) ) :
|
292 |
+
|
293 |
+
$current_colspan = 0; ?>
|
294 |
+
|
295 |
+
</div><!-- .drkfr-row -->
|
296 |
+
|
297 |
+
<?php endif; ?>
|
298 |
+
|
299 |
+
<?php endforeach; ?>
|
300 |
+
|
301 |
+
</div>
|
302 |
+
|
303 |
+
<?php }
|
304 |
+
|
305 |
+
function strip_repeatable( $values ) {
|
306 |
+
|
307 |
+
foreach ( $values as $key => $value ) {
|
308 |
+
|
309 |
+
if ( false !== strpos( $key, 'drkfr-group-x' ) || false !== strpos( $key, 'drkfr-field-x' ) )
|
310 |
+
unset( $values[$key] );
|
311 |
+
|
312 |
+
elseif ( is_array( $value ) )
|
313 |
+
$values[$key] = $this->strip_repeatable( $value );
|
314 |
+
|
315 |
+
}
|
316 |
+
|
317 |
+
return $values;
|
318 |
+
}
|
319 |
+
|
320 |
+
// Save data from metabox
|
321 |
+
function save( $post_id = 0 ) {
|
322 |
+
|
323 |
+
// Verify nonce
|
324 |
+
if ( ! isset( $_POST['wp_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['wp_meta_box_nonce'], basename( __FILE__ ) ) )
|
325 |
+
return $post_id;
|
326 |
+
|
327 |
+
foreach ( $this->_meta_box['fields'] as $field ) {
|
328 |
+
|
329 |
+
// Verify this meta box was shown on the page
|
330 |
+
if ( ! isset( $_POST['_drkfr_present_' . $field['id'] ] ) )
|
331 |
+
continue;
|
332 |
+
|
333 |
+
if ( isset( $_POST[ $field['id'] ] ) )
|
334 |
+
$value = (array) $_POST[ $field['id'] ];
|
335 |
+
else
|
336 |
+
$value = array();
|
337 |
+
|
338 |
+
$value = $this->strip_repeatable( $value );
|
339 |
+
|
340 |
+
if ( ! $class = _drkfr_field_class_for_type( $field['type'] ) ) {
|
341 |
+
do_action( 'drkfr_save_' . $field['type'], $field, $value );
|
342 |
+
}
|
343 |
+
|
344 |
+
$field_obj = new $class( $field['id'], $field['name'], $value, $field );
|
345 |
+
|
346 |
+
$field_obj->save( $post_id, $value );
|
347 |
+
|
348 |
+
}
|
349 |
+
|
350 |
+
// If we are not on a post, need to refresh the field objects to reflect new values, as we do not get a redirect
|
351 |
+
if ( ! $post_id ) {
|
352 |
+
$this->fields = array();
|
353 |
+
$this->init_fields();
|
354 |
+
}
|
355 |
+
}
|
356 |
+
|
357 |
+
// Save the on save_post hook
|
358 |
+
function save_for_post( $post_id ) {
|
359 |
+
|
360 |
+
// check autosave
|
361 |
+
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
|
362 |
+
return $post_id;
|
363 |
+
|
364 |
+
$this->save( $post_id );
|
365 |
+
|
366 |
+
}
|
367 |
+
|
368 |
+
function get_post_id() {
|
369 |
+
|
370 |
+
$post_id = isset( $_GET['post'] ) ? $_GET['post'] : null;
|
371 |
+
|
372 |
+
if ( ! $post_id && isset( $_POST['post_id'] ) ) {
|
373 |
+
$post_id = $_POST['post_id'];
|
374 |
+
}
|
375 |
+
|
376 |
+
return $post_id;
|
377 |
+
|
378 |
+
}
|
379 |
+
}
|
drkfr/classes.fields.php
ADDED
@@ -0,0 +1,1675 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Abstract class for all fields.
|
5 |
+
* Subclasses need only override html()
|
6 |
+
*
|
7 |
+
* @abstract
|
8 |
+
*/
|
9 |
+
abstract class drkfr_Field {
|
10 |
+
|
11 |
+
public $value;
|
12 |
+
public $field_index = 0;
|
13 |
+
|
14 |
+
public function __construct( $name, $title, array $values, $args = array() ) {
|
15 |
+
|
16 |
+
$this->id = $name;
|
17 |
+
$this->name = $name . '[]';
|
18 |
+
$this->title = $title;
|
19 |
+
$this->args = wp_parse_args( $args, $this->get_default_args() );
|
20 |
+
|
21 |
+
// Deprecated argument: 'std'
|
22 |
+
if ( ! empty( $this->args['std'] ) && empty( $this->args['default'] ) ) {
|
23 |
+
$this->args['default'] = $this->args['std'];
|
24 |
+
_deprecated_argument( 'drkfr_Field', '0.9', "field argument 'std' is deprecated, use 'default' instead" );
|
25 |
+
}
|
26 |
+
|
27 |
+
if ( ! empty( $this->args['options'] ) && is_array( reset( $this->args['options'] ) ) ) {
|
28 |
+
$re_format = array();
|
29 |
+
foreach ( $this->args['options'] as $option ) {
|
30 |
+
$re_format[$option['value']] = $option['name'];
|
31 |
+
}
|
32 |
+
$this->args['options'] = $re_format;
|
33 |
+
}
|
34 |
+
|
35 |
+
// If the field has a custom value populator callback
|
36 |
+
if ( ! empty( $args['values_callback'] ) )
|
37 |
+
$this->values = call_user_func( $args['values_callback'], get_the_id() );
|
38 |
+
else
|
39 |
+
$this->values = $values;
|
40 |
+
|
41 |
+
$this->value = reset( $this->values );
|
42 |
+
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Get the default args for the abstract field.
|
47 |
+
* These args are available to all fields.
|
48 |
+
*
|
49 |
+
* @return array $args
|
50 |
+
*/
|
51 |
+
public function get_default_args() {
|
52 |
+
return apply_filters(
|
53 |
+
'drkfr_field_default_args',
|
54 |
+
array(
|
55 |
+
'desc' => '',
|
56 |
+
'repeatable' => false,
|
57 |
+
'sortable' => false,
|
58 |
+
'repeatable_max' => null,
|
59 |
+
'show_label' => false,
|
60 |
+
'readonly' => false,
|
61 |
+
'disabled' => false,
|
62 |
+
'default' => '',
|
63 |
+
'cols' => '12',
|
64 |
+
'style' => '',
|
65 |
+
'class' => '',
|
66 |
+
'data_delegate' => null,
|
67 |
+
'save_callback' => null,
|
68 |
+
'string-repeat-field' => __( 'Add New', 'drkfr' ),
|
69 |
+
'string-delete-field' => __( 'Remove Field', 'drkfr' ),
|
70 |
+
),
|
71 |
+
get_class( $this )
|
72 |
+
);
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Enqueue all scripts required by the field.
|
77 |
+
*
|
78 |
+
* @uses wp_enqueue_script()
|
79 |
+
*/
|
80 |
+
public function enqueue_scripts() {
|
81 |
+
|
82 |
+
if ( isset( $this->args['sortable'] ) && $this->args['sortable'] )
|
83 |
+
wp_enqueue_script( 'jquery-ui-sortable' );
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Enqueue all styles required by the field.
|
89 |
+
*
|
90 |
+
* @uses wp_enqueue_style()
|
91 |
+
*/
|
92 |
+
public function enqueue_styles() {}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Output the field input ID attribute.
|
96 |
+
*
|
97 |
+
* If multiple inputs are required for a single field,
|
98 |
+
* use the append parameter to add unique identifier.
|
99 |
+
*
|
100 |
+
* @param string $append
|
101 |
+
* @return null
|
102 |
+
*/
|
103 |
+
public function id_attr( $append = null ) {
|
104 |
+
|
105 |
+
printf( 'id="%s"', esc_attr( $this->get_the_id_attr( $append ) ) );
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Output the for attribute for the field.
|
111 |
+
*
|
112 |
+
*
|
113 |
+
*
|
114 |
+
* If multiple inputs are required for a single field,
|
115 |
+
* use the append parameter to add unique identifier.
|
116 |
+
*
|
117 |
+
* @param string $append
|
118 |
+
* @return null
|
119 |
+
*/
|
120 |
+
public function get_the_id_attr( $append = null ) {
|
121 |
+
|
122 |
+
$id = $this->id;
|
123 |
+
|
124 |
+
if ( isset( $this->parent ) ) {
|
125 |
+
$parent_id = preg_replace( '/drkfr\-field\-(\d+|x)/', 'drkfr-group-$1', $this->parent->get_the_id_attr() );
|
126 |
+
$id = $parent_id . '[' . $id . ']';
|
127 |
+
}
|
128 |
+
|
129 |
+
$id .= '-drkfr-field-' . $this->field_index;
|
130 |
+
|
131 |
+
if ( ! is_null( $append ) )
|
132 |
+
$id .= '-' . $append;
|
133 |
+
|
134 |
+
$id = str_replace( array( '[', ']', '--' ), '-', $id );
|
135 |
+
|
136 |
+
return $id;
|
137 |
+
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Return the field input ID attribute value.
|
142 |
+
*
|
143 |
+
* If multiple inputs are required for a single field,
|
144 |
+
* use the append parameter to add unique identifier.
|
145 |
+
*
|
146 |
+
* @param string $append
|
147 |
+
* @return string id attribute value.
|
148 |
+
*/
|
149 |
+
public function for_attr( $append = null ) {
|
150 |
+
|
151 |
+
printf( 'for="%s"', esc_attr( $this->get_the_id_attr( $append ) ) );
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
public function name_attr( $append = null ) {
|
156 |
+
|
157 |
+
printf( 'name="%s"', esc_attr( $this->get_the_name_attr( $append ) ) );
|
158 |
+
|
159 |
+
}
|
160 |
+
|
161 |
+
public function get_the_name_attr( $append = null ) {
|
162 |
+
|
163 |
+
$name = str_replace( '[]', '', $this->name );
|
164 |
+
|
165 |
+
if ( isset( $this->parent ) ) {
|
166 |
+
$parent_name = preg_replace( '/drkfr\-field\-(\d+|x)/', 'drkfr-group-$1', $this->parent->get_the_name_attr() );
|
167 |
+
$name = $parent_name . '[' . $name . ']';
|
168 |
+
}
|
169 |
+
|
170 |
+
$name .= "[drkfr-field-$this->field_index]";
|
171 |
+
|
172 |
+
if ( ! is_null( $append ) )
|
173 |
+
$name .= $append;
|
174 |
+
|
175 |
+
return $name;
|
176 |
+
|
177 |
+
}
|
178 |
+
|
179 |
+
public function class_attr( $classes = '' ) {
|
180 |
+
|
181 |
+
if ( $classes = implode( ' ', array_map( 'sanitize_html_class', array_filter( array_unique( explode( ' ', $classes . ' ' . $this->args['class'] ) ) ) ) ) ) { ?>
|
182 |
+
|
183 |
+
class="<?php echo esc_attr( $classes ); ?>"
|
184 |
+
|
185 |
+
<?php }
|
186 |
+
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Get JS Safe ID.
|
191 |
+
*
|
192 |
+
* For use as a unique field identifier in javascript.
|
193 |
+
*/
|
194 |
+
public function get_js_id() {
|
195 |
+
|
196 |
+
return str_replace( array( '-', '[', ']', '--' ),'_', $this->get_the_id_attr() ); // JS friendly ID
|
197 |
+
|
198 |
+
}
|
199 |
+
|
200 |
+
public function boolean_attr( $attrs = array() ) {
|
201 |
+
|
202 |
+
if ( $this->args['readonly'] )
|
203 |
+
$attrs[] = 'readonly';
|
204 |
+
|
205 |
+
if ( $this->args['disabled'] )
|
206 |
+
$attrs[] = 'disabled';
|
207 |
+
|
208 |
+
$attrs = array_filter( array_unique( $attrs ) );
|
209 |
+
|
210 |
+
foreach ( $attrs as $attr )
|
211 |
+
echo esc_html( $attr ) . '="' . esc_attr( $attr ) . '"';
|
212 |
+
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Check if this field has a data delegate set
|
217 |
+
*
|
218 |
+
* @return boolean
|
219 |
+
*/
|
220 |
+
public function has_data_delegate() {
|
221 |
+
return (bool) $this->args['data_delegate'];
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Get the array of data from the data delegate
|
226 |
+
*
|
227 |
+
* @return array mixed
|
228 |
+
*/
|
229 |
+
protected function get_delegate_data() {
|
230 |
+
|
231 |
+
if ( $this->args['data_delegate'] )
|
232 |
+
return call_user_func_array( $this->args['data_delegate'], array( $this ) );
|
233 |
+
|
234 |
+
return array();
|
235 |
+
|
236 |
+
}
|
237 |
+
|
238 |
+
public function get_value() {
|
239 |
+
return ( $this->value || $this->value === '0' ) ? $this->value : $this->args['default'];
|
240 |
+
}
|
241 |
+
|
242 |
+
public function &get_values() {
|
243 |
+
return $this->values;
|
244 |
+
}
|
245 |
+
|
246 |
+
public function set_values( array $values ) {
|
247 |
+
|
248 |
+
$this->values = $values;
|
249 |
+
|
250 |
+
unset( $this->value );
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
public function parse_save_values() {}
|
255 |
+
|
256 |
+
public function parse_save_value() {}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* @todo this surely only works for posts
|
260 |
+
* @todo why do values need to be passed in, they can already be passed in on construct
|
261 |
+
*/
|
262 |
+
public function save( $post_id, $values ) {
|
263 |
+
|
264 |
+
// Don't save readonly values.
|
265 |
+
if ( $this->args['readonly'] )
|
266 |
+
return;
|
267 |
+
|
268 |
+
$this->values = $values;
|
269 |
+
$this->parse_save_values();
|
270 |
+
|
271 |
+
// Allow override from args
|
272 |
+
if ( ! empty( $this->args['save_callback'] ) ) {
|
273 |
+
|
274 |
+
call_user_func( $this->args['save_callback'], $this->values, $post_id );
|
275 |
+
|
276 |
+
return;
|
277 |
+
|
278 |
+
}
|
279 |
+
|
280 |
+
// If we are not on a post edit screen
|
281 |
+
if ( ! $post_id )
|
282 |
+
return;
|
283 |
+
|
284 |
+
delete_post_meta( $post_id, $this->id );
|
285 |
+
|
286 |
+
foreach( $this->values as $v ) {
|
287 |
+
|
288 |
+
$this->value = $v;
|
289 |
+
$this->parse_save_value();
|
290 |
+
|
291 |
+
if ( $this->value || $this->value === '0' )
|
292 |
+
add_post_meta( $post_id, $this->id, $this->value );
|
293 |
+
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
public function title() {
|
298 |
+
|
299 |
+
if ( $this->title ) { ?>
|
300 |
+
|
301 |
+
<div class="field-title">
|
302 |
+
<label <?php $this->for_attr(); ?>>
|
303 |
+
<?php echo esc_html( $this->title ); ?>
|
304 |
+
</label>
|
305 |
+
</div>
|
306 |
+
|
307 |
+
<?php }
|
308 |
+
|
309 |
+
}
|
310 |
+
|
311 |
+
public function description() {
|
312 |
+
|
313 |
+
if ( ! empty( $this->args['desc'] ) ) { ?>
|
314 |
+
|
315 |
+
<div class="drkfr_metabox_description">
|
316 |
+
<?php echo wp_kses_post( $this->args['desc'] ); ?>
|
317 |
+
</div>
|
318 |
+
|
319 |
+
<?php }
|
320 |
+
|
321 |
+
}
|
322 |
+
|
323 |
+
public function display() {
|
324 |
+
|
325 |
+
// If there are no values and it's not repeateble, we want to do one with empty string
|
326 |
+
if ( ! $this->get_values() && ! $this->args['repeatable'] )
|
327 |
+
$values = array( '' );
|
328 |
+
else
|
329 |
+
$values = $this->get_values();
|
330 |
+
|
331 |
+
$this->title();
|
332 |
+
|
333 |
+
$this->description();
|
334 |
+
|
335 |
+
$i = 0;
|
336 |
+
foreach ( $values as $key => $value ) {
|
337 |
+
|
338 |
+
$this->field_index = $i;
|
339 |
+
$this->value = $value; ?>
|
340 |
+
|
341 |
+
<div class="field-item" data-class="<?php echo esc_attr( get_class( $this ) ); ?>" style="position: relative; <?php echo esc_attr( $this->args['style'] ); ?>">
|
342 |
+
|
343 |
+
<?php if ( $this->args['repeatable'] ) : ?>
|
344 |
+
<button class="drkfr-delete-field" title="<?php echo esc_attr( $this->args['string-delete-field'] ); ?>">
|
345 |
+
<span class="drkfr-delete-field-icon">×</span>
|
346 |
+
</button>
|
347 |
+
<?php endif; ?>
|
348 |
+
|
349 |
+
<?php $this->html(); ?>
|
350 |
+
|
351 |
+
</div>
|
352 |
+
|
353 |
+
<?php
|
354 |
+
|
355 |
+
$i++;
|
356 |
+
|
357 |
+
}
|
358 |
+
|
359 |
+
// Insert a hidden one if it's repeatable
|
360 |
+
if ( $this->args['repeatable'] ) {
|
361 |
+
|
362 |
+
$this->field_index = 'x'; // x used to distinguish hidden fields.
|
363 |
+
$this->value = ''; ?>
|
364 |
+
|
365 |
+
<div class="field-item hidden" data-class="<?php echo esc_attr( get_class( $this ) ); ?>" style="position: relative; <?php echo esc_attr( $this->args['style'] ); ?>">
|
366 |
+
|
367 |
+
<?php if ( $this->args['repeatable'] ) : ?>
|
368 |
+
<button class="drkfr-delete-field" title="<?php echo esc_attr( $this->args['string-delete-field'] ); ?>">
|
369 |
+
<span class="drkfr-delete-field-icon">×</span>
|
370 |
+
<?php echo esc_html( $this->args['string-delete-field'] ); ?>
|
371 |
+
</button>
|
372 |
+
<?php endif; ?>
|
373 |
+
|
374 |
+
<?php $this->html(); ?>
|
375 |
+
|
376 |
+
</div>
|
377 |
+
|
378 |
+
<button class="button repeat-field"><?php echo esc_html( $this->args['string-repeat-field'] ); ?></button>
|
379 |
+
|
380 |
+
<?php }
|
381 |
+
|
382 |
+
}
|
383 |
+
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Standard text field.
|
388 |
+
*
|
389 |
+
* @extends drkfr_Field
|
390 |
+
*/
|
391 |
+
class drkfr_Text_Field extends drkfr_Field {
|
392 |
+
|
393 |
+
public function html() { ?>
|
394 |
+
|
395 |
+
<input type="text" <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr(); ?> <?php $this->name_attr(); ?> value="<?php echo esc_attr( $this->get_value() ); ?>" />
|
396 |
+
|
397 |
+
<?php }
|
398 |
+
}
|
399 |
+
|
400 |
+
class drkfr_Text_Small_Field extends drkfr_Text_Field {
|
401 |
+
|
402 |
+
public function html() {
|
403 |
+
|
404 |
+
$this->args['class'] .= ' drkfr_text_small';
|
405 |
+
|
406 |
+
parent::html();
|
407 |
+
|
408 |
+
}
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Field for image upload / file updoad.
|
413 |
+
*
|
414 |
+
* @todo ability to set image size (preview image) from caller
|
415 |
+
*/
|
416 |
+
class drkfr_File_Field extends drkfr_Field {
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Return the default args for the File field.
|
420 |
+
*
|
421 |
+
* @return array $args
|
422 |
+
*/
|
423 |
+
public function get_default_args() {
|
424 |
+
return array_merge(
|
425 |
+
parent::get_default_args(),
|
426 |
+
array(
|
427 |
+
'library-type' => array( 'video', 'audio', 'text', 'application' )
|
428 |
+
)
|
429 |
+
);
|
430 |
+
}
|
431 |
+
|
432 |
+
function enqueue_scripts() {
|
433 |
+
|
434 |
+
global $post_ID;
|
435 |
+
$post_ID = isset($post_ID) ? (int) $post_ID : 0;
|
436 |
+
|
437 |
+
parent::enqueue_scripts();
|
438 |
+
|
439 |
+
wp_enqueue_media( array( 'post' => $post_ID ));
|
440 |
+
wp_enqueue_script( 'drkfr-file-upload', trailingslashit( drkfr_URL ) . 'js/file-upload.js', array( 'jquery', 'drkfr-scripts' ) );
|
441 |
+
|
442 |
+
}
|
443 |
+
|
444 |
+
public function html() {
|
445 |
+
|
446 |
+
if ( $this->get_value() ) {
|
447 |
+
$src = wp_mime_type_icon( $this->get_value() );
|
448 |
+
$size = getimagesize( str_replace( site_url(), ABSPATH, $src ) );
|
449 |
+
$icon_img = '<img src="' . $src . '" ' . $size[3] . ' />';
|
450 |
+
}
|
451 |
+
|
452 |
+
$data_type = ( ! empty( $this->args['library-type'] ) ? implode( ',', $this->args['library-type'] ) : null );
|
453 |
+
|
454 |
+
?>
|
455 |
+
|
456 |
+
<div class="drkfr-file-wrap" <?php echo 'data-type="' . esc_attr( $data_type ) . '"'; ?>>
|
457 |
+
|
458 |
+
<div class="drkfr-file-wrap-placeholder"></div>
|
459 |
+
|
460 |
+
<button class="button drkfr-file-upload <?php echo esc_attr( $this->get_value() ) ? 'hidden' : '' ?>">
|
461 |
+
<?php esc_html_e( 'Add File', 'drkfr' ); ?>
|
462 |
+
</button>
|
463 |
+
|
464 |
+
<div class="drkfr-file-holder type-file <?php echo $this->get_value() ? '' : 'hidden'; ?>">
|
465 |
+
|
466 |
+
<?php if ( $this->get_value() ) : ?>
|
467 |
+
|
468 |
+
<?php if ( isset( $icon_img ) ) echo $icon_img; ?>
|
469 |
+
|
470 |
+
<div class="drkfr-file-name">
|
471 |
+
<strong><?php echo esc_html( basename( get_attached_file( $this->get_value() ) ) ); ?></strong>
|
472 |
+
</div>
|
473 |
+
|
474 |
+
<?php endif; ?>
|
475 |
+
|
476 |
+
</div>
|
477 |
+
|
478 |
+
<button class="drkfr-remove-file button <?php echo $this->get_value() ? '' : 'hidden'; ?>">
|
479 |
+
<?php esc_html_e( 'Remove', 'drkfr' ); ?>
|
480 |
+
</button>
|
481 |
+
|
482 |
+
<input type="hidden"
|
483 |
+
<?php $this->class_attr( 'drkfr-file-upload-input' ); ?>
|
484 |
+
<?php $this->name_attr(); ?>
|
485 |
+
value="<?php echo esc_attr( $this->value ); ?>"
|
486 |
+
/>
|
487 |
+
|
488 |
+
</div>
|
489 |
+
|
490 |
+
<?php }
|
491 |
+
|
492 |
+
}
|
493 |
+
|
494 |
+
class drkfr_Image_Field extends drkfr_File_Field {
|
495 |
+
|
496 |
+
/**
|
497 |
+
* Return the default args for the Image field.
|
498 |
+
*
|
499 |
+
* @return array $args
|
500 |
+
*/
|
501 |
+
public function get_default_args() {
|
502 |
+
return array_merge(
|
503 |
+
parent::get_default_args(),
|
504 |
+
array(
|
505 |
+
'size' => 'thumbnail',
|
506 |
+
'library-type' => array( 'image' ),
|
507 |
+
'show_size' => false
|
508 |
+
)
|
509 |
+
);
|
510 |
+
}
|
511 |
+
|
512 |
+
public function html() {
|
513 |
+
|
514 |
+
if ( $this->get_value() )
|
515 |
+
$image = wp_get_attachment_image_src( $this->get_value(), $this->args['size'], true );
|
516 |
+
|
517 |
+
// Convert size arg to array of width, height, crop
|
518 |
+
$size = $this->parse_image_size( $this->args['size'] );
|
519 |
+
|
520 |
+
// Inline styles
|
521 |
+
$styles = sprintf( 'width: %1$dpx; height: %2$dpx; line-height: %2$dpx', intval( $size['width'] ), intval( $size['height'] ) );
|
522 |
+
$placeholder_styles = sprintf( 'width: %dpx; height: %dpx;', intval( $size['width'] ) - 8, intval( $size['height'] ) - 8 );
|
523 |
+
|
524 |
+
$data_type = ( ! empty( $this->args['library-type'] ) ? implode( ',', $this->args['library-type'] ) : null );
|
525 |
+
|
526 |
+
?>
|
527 |
+
|
528 |
+
<div class="drkfr-file-wrap" style="<?php echo esc_attr( $styles ); ?>" data-type="<?php echo esc_attr( $data_type ); ?>">
|
529 |
+
|
530 |
+
<div class="drkfr-file-wrap-placeholder" style="<?php echo esc_attr( $placeholder_styles ); ?>">
|
531 |
+
|
532 |
+
<?php if ( $this->args['show_size'] ) : ?>
|
533 |
+
<span class="dimensions">
|
534 |
+
<?php printf( '%dpx × %dpx', intval( $size['width'] ), intval( $size['height'] ) ); ?>
|
535 |
+
</span>
|
536 |
+
<?php endif; ?>
|
537 |
+
|
538 |
+
</div>
|
539 |
+
|
540 |
+
<button class="button drkfr-file-upload <?php echo esc_attr( $this->get_value() ) ? 'hidden' : '' ?>" data-nonce="<?php echo wp_create_nonce( 'drkfr-file-upload-nonce' ); ?>">
|
541 |
+
<?php esc_html_e( 'Add Image', 'drkfr' ); ?>
|
542 |
+
</button>
|
543 |
+
|
544 |
+
<div class="drkfr-file-holder type-img <?php echo $this->get_value() ? '' : 'hidden'; ?>" data-crop="<?php echo (bool) $size['crop']; ?>">
|
545 |
+
|
546 |
+
<?php if ( ! empty( $image ) ) : ?>
|
547 |
+
<img src="<?php echo esc_url( $image[0] ); ?>" width="<?php echo intval( $image[1] ); ?>" height="<?php echo intval( $image[2] ); ?>" />
|
548 |
+
<?php endif; ?>
|
549 |
+
|
550 |
+
</div>
|
551 |
+
|
552 |
+
<button class="drkfr-remove-file button <?php echo $this->get_value() ? '' : 'hidden'; ?>">
|
553 |
+
<?php esc_html_e( 'Remove', 'drkfr' ); ?>
|
554 |
+
</button>
|
555 |
+
|
556 |
+
<input type="hidden"
|
557 |
+
<?php $this->class_attr( 'drkfr-file-upload-input' ); ?>
|
558 |
+
<?php $this->name_attr(); ?>
|
559 |
+
value="<?php echo esc_attr( $this->value ); ?>"
|
560 |
+
/>
|
561 |
+
|
562 |
+
</div>
|
563 |
+
|
564 |
+
<?php }
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Parse the size argument to get pixel width, pixel height and crop information.
|
568 |
+
*
|
569 |
+
* @param string $size
|
570 |
+
* @return array width, height, crop
|
571 |
+
*/
|
572 |
+
private function parse_image_size( $size ) {
|
573 |
+
|
574 |
+
// Handle string for built-in image sizes
|
575 |
+
if ( is_string( $size ) && in_array( $size, array( 'thumbnail', 'medium', 'large' ) ) ) {
|
576 |
+
return array(
|
577 |
+
'width' => get_option( $size . '_size_w' ),
|
578 |
+
'height' => get_option( $size . '_size_h' ),
|
579 |
+
'crop' => get_option( $size . '_crop' )
|
580 |
+
);
|
581 |
+
}
|
582 |
+
|
583 |
+
// Handle string for additional image sizes
|
584 |
+
global $_wp_additional_image_sizes;
|
585 |
+
if ( is_string( $size ) && isset( $_wp_additional_image_sizes[$size] ) ) {
|
586 |
+
return array(
|
587 |
+
'width' => $_wp_additional_image_sizes[$size]['width'],
|
588 |
+
'height' => $_wp_additional_image_sizes[$size]['height'],
|
589 |
+
'crop' => $_wp_additional_image_sizes[$size]['crop']
|
590 |
+
);
|
591 |
+
}
|
592 |
+
|
593 |
+
// Handle default WP size format.
|
594 |
+
if ( is_array( $size ) && isset( $size[0] ) && isset( $size[1] ) )
|
595 |
+
$size = array( 'width' => $size[0], 'height' => $size[1] );
|
596 |
+
|
597 |
+
return wp_parse_args( $size, array(
|
598 |
+
'width' => get_option( 'thumbnail_size_w' ),
|
599 |
+
'height' => get_option( 'thumbnail_size_h' ),
|
600 |
+
'crop' => get_option( 'thumbnail_crop' )
|
601 |
+
) );
|
602 |
+
|
603 |
+
}
|
604 |
+
|
605 |
+
/**
|
606 |
+
* Ajax callback for outputing an image src based on post data.
|
607 |
+
*
|
608 |
+
* @return null
|
609 |
+
*/
|
610 |
+
static function request_image_ajax_callback() {
|
611 |
+
|
612 |
+
if ( ! ( isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'drkfr-file-upload-nonce' ) ) )
|
613 |
+
return;
|
614 |
+
|
615 |
+
$id = intval( $_POST['id'] );
|
616 |
+
|
617 |
+
$size = array(
|
618 |
+
intval( $_POST['width'] ),
|
619 |
+
intval( $_POST['height'] ),
|
620 |
+
'crop' => (bool) $_POST['crop']
|
621 |
+
);
|
622 |
+
|
623 |
+
$image = wp_get_attachment_image_src( $id, $size );
|
624 |
+
echo reset( $image );
|
625 |
+
|
626 |
+
die(); // this is required to return a proper result
|
627 |
+
}
|
628 |
+
|
629 |
+
}
|
630 |
+
add_action( 'wp_ajax_drkfr_request_image', array( 'drkfr_Image_Field', 'request_image_ajax_callback' ) );
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Standard text meta box for a URL.
|
634 |
+
*
|
635 |
+
*/
|
636 |
+
class drkfr_URL_Field extends drkfr_Field {
|
637 |
+
|
638 |
+
public function html() { ?>
|
639 |
+
|
640 |
+
<input type="text" <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'drkfr_text_url code' ); ?> <?php $this->name_attr(); ?> value="<?php echo esc_attr( esc_url( $this->value ) ); ?>" />
|
641 |
+
|
642 |
+
<?php }
|
643 |
+
}
|
644 |
+
|
645 |
+
/**
|
646 |
+
* Date picker box.
|
647 |
+
*
|
648 |
+
*/
|
649 |
+
class drkfr_Date_Field extends drkfr_Field {
|
650 |
+
|
651 |
+
public function enqueue_scripts() {
|
652 |
+
|
653 |
+
parent::enqueue_scripts();
|
654 |
+
|
655 |
+
wp_enqueue_style( 'drkfr-jquery-ui', trailingslashit( drkfr_URL ) . 'css/vendor/jquery-ui/jquery-ui.css', '1.10.3' );
|
656 |
+
|
657 |
+
wp_enqueue_script( 'drkfr-datetime', trailingslashit( drkfr_URL ) . 'js/field.datetime.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-datepicker', 'drkfr-scripts' ) );
|
658 |
+
}
|
659 |
+
|
660 |
+
public function html() { ?>
|
661 |
+
|
662 |
+
<input <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'drkfr_text_small drkfr_datepicker' ); ?> type="text" <?php $this->name_attr(); ?> value="<?php echo esc_attr( $this->value ); ?>" />
|
663 |
+
|
664 |
+
<?php }
|
665 |
+
}
|
666 |
+
|
667 |
+
class drkfr_Time_Field extends drkfr_Field {
|
668 |
+
|
669 |
+
public function enqueue_scripts() {
|
670 |
+
|
671 |
+
parent::enqueue_scripts();
|
672 |
+
|
673 |
+
wp_enqueue_style( 'drkfr-jquery-ui', trailingslashit( drkfr_URL ) . 'css/vendor/jquery-ui/jquery-ui.css', '1.10.3' );
|
674 |
+
|
675 |
+
wp_enqueue_script( 'drkfr-timepicker', trailingslashit( drkfr_URL ) . 'js/jquery.timePicker.min.js', array( 'jquery', 'drkfr-scripts' ) );
|
676 |
+
wp_enqueue_script( 'drkfr-datetime', trailingslashit( drkfr_URL ) . 'js/field.datetime.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-datepicker', 'drkfr-scripts' ) );
|
677 |
+
}
|
678 |
+
|
679 |
+
public function html() { ?>
|
680 |
+
|
681 |
+
<input <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'drkfr_text_small drkfr_timepicker' ); ?> type="text" <?php $this->name_attr(); ?> value="<?php echo esc_attr( $this->value ); ?>"/>
|
682 |
+
|
683 |
+
<?php }
|
684 |
+
|
685 |
+
}
|
686 |
+
|
687 |
+
/**
|
688 |
+
* Date picker for date only (not time) box.
|
689 |
+
*
|
690 |
+
*/
|
691 |
+
class drkfr_Date_Timestamp_Field extends drkfr_Field {
|
692 |
+
|
693 |
+
public function enqueue_scripts() {
|
694 |
+
|
695 |
+
parent::enqueue_scripts();
|
696 |
+
|
697 |
+
wp_enqueue_style( 'drkfr-jquery-ui', trailingslashit( drkfr_URL ) . 'css/vendor/jquery-ui/jquery-ui.css', '1.10.3' );
|
698 |
+
|
699 |
+
wp_enqueue_script( 'drkfr-timepicker', trailingslashit( drkfr_URL ) . 'js/jquery.timePicker.min.js', array( 'jquery', 'drkfr-scripts' ) );
|
700 |
+
wp_enqueue_script( 'drkfr-datetime', trailingslashit( drkfr_URL ) . 'js/field.datetime.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-datepicker', 'drkfr-scripts' ) );
|
701 |
+
|
702 |
+
}
|
703 |
+
|
704 |
+
public function html() { ?>
|
705 |
+
|
706 |
+
<input <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'drkfr_text_small drkfr_datepicker' ); ?> type="text" <?php $this->name_attr(); ?> value="<?php echo $this->value ? esc_attr( date( 'm\/d\/Y', $this->value ) ) : '' ?>" />
|
707 |
+
|
708 |
+
<?php }
|
709 |
+
|
710 |
+
public function parse_save_values() {
|
711 |
+
|
712 |
+
foreach( $this->values as &$value )
|
713 |
+
$value = strtotime( $value );
|
714 |
+
|
715 |
+
sort( $this->values );
|
716 |
+
|
717 |
+
}
|
718 |
+
|
719 |
+
}
|
720 |
+
|
721 |
+
/**
|
722 |
+
* Date picker for date and time (seperate fields) box.
|
723 |
+
*
|
724 |
+
*/
|
725 |
+
class drkfr_Datetime_Timestamp_Field extends drkfr_Field {
|
726 |
+
|
727 |
+
public function enqueue_scripts() {
|
728 |
+
|
729 |
+
parent::enqueue_scripts();
|
730 |
+
|
731 |
+
wp_enqueue_style( 'drkfr-jquery-ui', trailingslashit( drkfr_URL ) . 'css/vendor/jquery-ui/jquery-ui.css', '1.10.3' );
|
732 |
+
|
733 |
+
wp_enqueue_script( 'drkfr-timepicker', trailingslashit( drkfr_URL ) . 'js/jquery.timePicker.min.js', array( 'jquery', 'drkfr-scripts' ) );
|
734 |
+
wp_enqueue_script( 'drkfr-datetime', trailingslashit( drkfr_URL ) . 'js/field.datetime.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-datepicker', 'drkfr-scripts' ) );
|
735 |
+
}
|
736 |
+
|
737 |
+
public function html() { ?>
|
738 |
+
|
739 |
+
<input <?php $this->id_attr('date'); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'drkfr_text_small drkfr_datepicker' ); ?> type="text" <?php $this->name_attr( '[date]' ); ?> value="<?php echo $this->value ? esc_attr( date( 'm\/d\/Y', $this->value ) ) : '' ?>" />
|
740 |
+
<input <?php $this->id_attr('time'); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'drkfr_text_small drkfr_timepicker' ); ?> type="text" <?php $this->name_attr( '[time]' ); ?> value="<?php echo $this->value ? esc_attr( date( 'h:i A', $this->value ) ) : '' ?>" />
|
741 |
+
|
742 |
+
<?php }
|
743 |
+
|
744 |
+
public function parse_save_values() {
|
745 |
+
|
746 |
+
// Convert all [date] and [time] values to a unix timestamp.
|
747 |
+
// If date is empty, assume delete. If time is empty, assume 00:00.
|
748 |
+
foreach( $this->values as $key => &$value ) {
|
749 |
+
if ( empty( $value['date'] ) )
|
750 |
+
unset( $this->values[$key] );
|
751 |
+
else
|
752 |
+
$value = strtotime( $value['date'] . ' ' . $value['time'] );
|
753 |
+
}
|
754 |
+
|
755 |
+
$this->values = array_filter( $this->values );
|
756 |
+
sort( $this->values );
|
757 |
+
|
758 |
+
parent::parse_save_values();
|
759 |
+
|
760 |
+
}
|
761 |
+
|
762 |
+
}
|
763 |
+
|
764 |
+
/**
|
765 |
+
* Standard text field.
|
766 |
+
*
|
767 |
+
* Args:
|
768 |
+
* - int "rows" - number of rows in the <textarea>
|
769 |
+
*/
|
770 |
+
class drkfr_Textarea_Field extends drkfr_Field {
|
771 |
+
|
772 |
+
public function html() { ?>
|
773 |
+
|
774 |
+
<textarea <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr(); ?> rows="<?php echo ! empty( $this->args['rows'] ) ? esc_attr( $this->args['rows'] ) : 4; ?>" <?php $this->name_attr(); ?>><?php echo esc_html( $this->value ); ?></textarea>
|
775 |
+
|
776 |
+
<?php }
|
777 |
+
|
778 |
+
}
|
779 |
+
|
780 |
+
/**
|
781 |
+
* Code style text field.
|
782 |
+
*
|
783 |
+
* Args:
|
784 |
+
* - int "rows" - number of rows in the <textarea>
|
785 |
+
*/
|
786 |
+
class drkfr_Textarea_Field_Code extends drkfr_Textarea_Field {
|
787 |
+
|
788 |
+
public function html() {
|
789 |
+
|
790 |
+
$this->args['class'] .= ' code';
|
791 |
+
|
792 |
+
parent::html();
|
793 |
+
|
794 |
+
}
|
795 |
+
|
796 |
+
}
|
797 |
+
|
798 |
+
/**
|
799 |
+
* Colour picker
|
800 |
+
*
|
801 |
+
*/
|
802 |
+
class drkfr_Color_Picker extends drkfr_Field {
|
803 |
+
|
804 |
+
public function enqueue_scripts() {
|
805 |
+
|
806 |
+
parent::enqueue_scripts();
|
807 |
+
|
808 |
+
wp_enqueue_script( 'drkfr-colorpicker', trailingslashit( drkfr_URL ) . 'js/field.colorpicker.js', array( 'jquery', 'wp-color-picker', 'drkfr-scripts' ) );
|
809 |
+
wp_enqueue_style( 'wp-color-picker' );
|
810 |
+
}
|
811 |
+
|
812 |
+
public function html() { ?>
|
813 |
+
|
814 |
+
<input <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'drkfr_colorpicker drkfr_text_small' ); ?> type="text" <?php $this->name_attr(); ?> value="<?php echo esc_attr( $this->get_value() ); ?>" />
|
815 |
+
|
816 |
+
<?php }
|
817 |
+
|
818 |
+
}
|
819 |
+
|
820 |
+
/**
|
821 |
+
* Standard radio field.
|
822 |
+
*
|
823 |
+
* Args:
|
824 |
+
* - bool "inline" - display the radio buttons inline
|
825 |
+
*/
|
826 |
+
class drkfr_Radio_Field extends drkfr_Field {
|
827 |
+
|
828 |
+
/**
|
829 |
+
* Return the default args for the Radio input field.
|
830 |
+
*
|
831 |
+
* @return array $args
|
832 |
+
*/
|
833 |
+
public function get_default_args() {
|
834 |
+
return array_merge(
|
835 |
+
parent::get_default_args(),
|
836 |
+
array(
|
837 |
+
'options' => array(),
|
838 |
+
)
|
839 |
+
);
|
840 |
+
}
|
841 |
+
|
842 |
+
public function html() {
|
843 |
+
|
844 |
+
if ( $this->has_data_delegate() )
|
845 |
+
$this->args['options'] = $this->get_delegate_data(); ?>
|
846 |
+
|
847 |
+
<?php foreach ( $this->args['options'] as $key => $value ): ?>
|
848 |
+
|
849 |
+
<input <?php $this->id_attr( 'item-' . $key ); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr(); ?> type="radio" <?php $this->name_attr(); ?> value="<?php echo esc_attr( $key ); ?>" <?php checked( $key, $this->get_value() ); ?> />
|
850 |
+
<label <?php $this->for_attr( 'item-' . $key ); ?> style="margin-right: 20px;">
|
851 |
+
<?php echo esc_html( $value ); ?>
|
852 |
+
</label>
|
853 |
+
|
854 |
+
<?php endforeach; ?>
|
855 |
+
|
856 |
+
<?php }
|
857 |
+
|
858 |
+
}
|
859 |
+
|
860 |
+
/**
|
861 |
+
* Standard checkbox field.
|
862 |
+
*
|
863 |
+
*/
|
864 |
+
class drkfr_Checkbox extends drkfr_Field {
|
865 |
+
|
866 |
+
public function title() {}
|
867 |
+
|
868 |
+
public function html() { ?>
|
869 |
+
|
870 |
+
<input <?php $this->id_attr(); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr(); ?> type="checkbox" <?php $this->name_attr(); ?> value="1" <?php checked( $this->get_value() ); ?> />
|
871 |
+
<label <?php $this->for_attr(); ?>><?php echo esc_html( $this->title ); ?></label>
|
872 |
+
|
873 |
+
<?php }
|
874 |
+
|
875 |
+
}
|
876 |
+
|
877 |
+
|
878 |
+
/**
|
879 |
+
* Standard title used as a splitter.
|
880 |
+
*
|
881 |
+
*/
|
882 |
+
class drkfr_Title extends drkfr_Field {
|
883 |
+
|
884 |
+
public function title() {
|
885 |
+
?>
|
886 |
+
|
887 |
+
<div class="field-title">
|
888 |
+
<h2 <?php $this->class_attr(); ?>>
|
889 |
+
<?php echo esc_html( $this->title ); ?>
|
890 |
+
</h2>
|
891 |
+
</div>
|
892 |
+
|
893 |
+
<?php
|
894 |
+
|
895 |
+
}
|
896 |
+
|
897 |
+
public function html() {}
|
898 |
+
|
899 |
+
}
|
900 |
+
|
901 |
+
/**
|
902 |
+
* wysiwyg field.
|
903 |
+
*
|
904 |
+
*/
|
905 |
+
class drkfr_wysiwyg extends drkfr_Field {
|
906 |
+
|
907 |
+
/**
|
908 |
+
* Return the default args for the WYSIWYG field.
|
909 |
+
*
|
910 |
+
* @return array $args
|
911 |
+
*/
|
912 |
+
public function get_default_args() {
|
913 |
+
return array_merge(
|
914 |
+
parent::get_default_args(),
|
915 |
+
array(
|
916 |
+
'options' => array(),
|
917 |
+
)
|
918 |
+
);
|
919 |
+
}
|
920 |
+
|
921 |
+
function enqueue_scripts() {
|
922 |
+
|
923 |
+
parent::enqueue_scripts();
|
924 |
+
|
925 |
+
wp_enqueue_script( 'drkfr-wysiwyg', trailingslashit( drkfr_URL ) . 'js/field-wysiwyg.js', array( 'jquery', 'drkfr-scripts' ) );
|
926 |
+
}
|
927 |
+
|
928 |
+
public function html() {
|
929 |
+
|
930 |
+
$id = $this->get_the_id_attr();
|
931 |
+
$name = $this->get_the_name_attr();
|
932 |
+
|
933 |
+
$field_id = $this->get_js_id();
|
934 |
+
|
935 |
+
printf( '<div class="drkfr-wysiwyg" data-id="%s" data-name="%s" data-field-id="%s">', $id, $name, $field_id );
|
936 |
+
|
937 |
+
if ( $this->is_placeholder() ) {
|
938 |
+
|
939 |
+
// For placeholder, output the markup for the editor in a JS var.
|
940 |
+
ob_start();
|
941 |
+
$this->args['options']['textarea_name'] = 'drkfr-placeholder-name-' . $field_id;
|
942 |
+
wp_editor( '', 'drkfr-placeholder-id-' . $field_id, $this->args['options'] );
|
943 |
+
$editor = ob_get_clean();
|
944 |
+
$editor = str_replace( array( "\n", "\r" ), "", $editor );
|
945 |
+
$editor = str_replace( array( "'" ), '"', $editor );
|
946 |
+
|
947 |
+
?>
|
948 |
+
|
949 |
+
<script>
|
950 |
+
if ( 'undefined' === typeof( drkfr_wysiwyg_editors ) )
|
951 |
+
var drkfr_wysiwyg_editors = {};
|
952 |
+
drkfr_wysiwyg_editors.<?php echo $field_id; ?> = '<?php echo $editor; ?>';
|
953 |
+
</script>
|
954 |
+
|
955 |
+
<?php
|
956 |
+
|
957 |
+
} else {
|
958 |
+
|
959 |
+
$this->args['options']['textarea_name'] = $name;
|
960 |
+
echo wp_editor( $this->get_value(), $id, $this->args['options'] );
|
961 |
+
|
962 |
+
}
|
963 |
+
|
964 |
+
echo '</div>';
|
965 |
+
|
966 |
+
}
|
967 |
+
|
968 |
+
/**
|
969 |
+
* Check if this is a placeholder field.
|
970 |
+
* Either the field itself, or because it is part of a repeatable group.
|
971 |
+
*
|
972 |
+
* @return bool
|
973 |
+
*/
|
974 |
+
public function is_placeholder() {
|
975 |
+
|
976 |
+
if ( isset( $this->parent ) && ! is_int( $this->parent->field_index ) )
|
977 |
+
return true;
|
978 |
+
|
979 |
+
else return ! is_int( $this->field_index );
|
980 |
+
|
981 |
+
}
|
982 |
+
|
983 |
+
}
|
984 |
+
|
985 |
+
/**
|
986 |
+
* Standard select field.
|
987 |
+
*
|
988 |
+
* @supports "data_delegate"
|
989 |
+
* @args
|
990 |
+
* 'options' => array Array of options to show in the select, optionally use data_delegate instead
|
991 |
+
* 'allow_none' => bool Allow no option to be selected (will palce a "None" at the top of the select)
|
992 |
+
* 'multiple' => bool whether multiple can be selected
|
993 |
+
*/
|
994 |
+
class drkfr_Select extends drkfr_Field {
|
995 |
+
|
996 |
+
public function __construct() {
|
997 |
+
|
998 |
+
$args = func_get_args();
|
999 |
+
|
1000 |
+
call_user_func_array( array( 'parent', '__construct' ), $args );
|
1001 |
+
|
1002 |
+
}
|
1003 |
+
|
1004 |
+
/**
|
1005 |
+
* Return the default args for the Select field.
|
1006 |
+
*
|
1007 |
+
* @return array $args
|
1008 |
+
*/
|
1009 |
+
public function get_default_args() {
|
1010 |
+
return array_merge(
|
1011 |
+
parent::get_default_args(),
|
1012 |
+
array(
|
1013 |
+
'options' => array(),
|
1014 |
+
'multiple' => false,
|
1015 |
+
'select2_options' => array(),
|
1016 |
+
)
|
1017 |
+
);
|
1018 |
+
}
|
1019 |
+
|
1020 |
+
public function parse_save_values(){
|
1021 |
+
|
1022 |
+
if ( isset( $this->parent ) && isset( $this->args['multiple'] ) && $this->args['multiple'] )
|
1023 |
+
$this->values = array( $this->values );
|
1024 |
+
|
1025 |
+
}
|
1026 |
+
|
1027 |
+
public function get_options() {
|
1028 |
+
|
1029 |
+
if ( $this->has_data_delegate() )
|
1030 |
+
$this->args['options'] = $this->get_delegate_data();
|
1031 |
+
|
1032 |
+
return $this->args['options'];
|
1033 |
+
}
|
1034 |
+
|
1035 |
+
public function enqueue_scripts() {
|
1036 |
+
|
1037 |
+
parent::enqueue_scripts();
|
1038 |
+
|
1039 |
+
wp_enqueue_script( 'select2', trailingslashit( drkfr_URL ) . 'js/vendor/select2/select2.js', array( 'jquery' ) );
|
1040 |
+
wp_enqueue_script( 'field-select', trailingslashit( drkfr_URL ) . 'js/field.select.js', array( 'jquery', 'select2', 'drkfr-scripts' ) );
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
public function enqueue_styles() {
|
1044 |
+
|
1045 |
+
parent::enqueue_styles();
|
1046 |
+
|
1047 |
+
wp_enqueue_style( 'select2', trailingslashit( drkfr_URL ) . 'js/vendor/select2/select2.css' );
|
1048 |
+
}
|
1049 |
+
|
1050 |
+
public function html() {
|
1051 |
+
|
1052 |
+
if ( $this->has_data_delegate() )
|
1053 |
+
$this->args['options'] = $this->get_delegate_data();
|
1054 |
+
|
1055 |
+
$this->output_field();
|
1056 |
+
|
1057 |
+
$this->output_script();
|
1058 |
+
|
1059 |
+
}
|
1060 |
+
|
1061 |
+
public function output_field() {
|
1062 |
+
|
1063 |
+
$val = (array) $this->get_value();
|
1064 |
+
|
1065 |
+
$name = $this->get_the_name_attr();
|
1066 |
+
$name .= ! empty( $this->args['multiple'] ) ? '[]' : null;
|
1067 |
+
|
1068 |
+
?>
|
1069 |
+
|
1070 |
+
<select
|
1071 |
+
<?php $this->id_attr(); ?>
|
1072 |
+
<?php $this->boolean_attr(); ?>
|
1073 |
+
<?php printf( 'name="%s"', esc_attr( $name ) ); ?>
|
1074 |
+
<?php printf( 'data-field-id="%s" ', esc_attr( $this->get_js_id() ) ); ?>
|
1075 |
+
<?php echo ! empty( $this->args['multiple'] ) ? 'multiple' : '' ?>
|
1076 |
+
<?php $this->class_attr( 'drkfr_select' ); ?>
|
1077 |
+
style="width: 100%"
|
1078 |
+
>
|
1079 |
+
|
1080 |
+
<?php if ( ! empty( $this->args['allow_none'] ) ) : ?>
|
1081 |
+
<option value=""></option>
|
1082 |
+
<?php endif; ?>
|
1083 |
+
|
1084 |
+
<?php foreach ( $this->args['options'] as $value => $name ): ?>
|
1085 |
+
<option <?php selected( in_array( $value, $val ) ) ?> value="<?php echo esc_attr( $value ); ?>"><?php echo esc_html( $name ); ?></option>
|
1086 |
+
<?php endforeach; ?>
|
1087 |
+
|
1088 |
+
</select>
|
1089 |
+
|
1090 |
+
<?php
|
1091 |
+
}
|
1092 |
+
|
1093 |
+
public function output_script() {
|
1094 |
+
|
1095 |
+
$options = wp_parse_args( $this->args['select2_options'], array(
|
1096 |
+
'placeholder' => __( 'Type to search', 'drkfr' ),
|
1097 |
+
'allowClear' => true,
|
1098 |
+
) );
|
1099 |
+
|
1100 |
+
?>
|
1101 |
+
|
1102 |
+
<script type="text/javascript">
|
1103 |
+
|
1104 |
+
(function($) {
|
1105 |
+
|
1106 |
+
var options = <?php echo json_encode( $options ); ?>
|
1107 |
+
|
1108 |
+
if ( 'undefined' === typeof( window.drkfr_select_fields ) )
|
1109 |
+
window.drkfr_select_fields = {};
|
1110 |
+
|
1111 |
+
var id = <?php echo json_encode( $this->get_js_id() ); ?>;
|
1112 |
+
window.drkfr_select_fields[id] = options;
|
1113 |
+
|
1114 |
+
})( jQuery );
|
1115 |
+
|
1116 |
+
</script>
|
1117 |
+
|
1118 |
+
<?php
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
}
|
1122 |
+
|
1123 |
+
class drkfr_Taxonomy extends drkfr_Select {
|
1124 |
+
|
1125 |
+
/**
|
1126 |
+
* Return the default args for the Taxonomy select field.
|
1127 |
+
*
|
1128 |
+
* @return array $args
|
1129 |
+
*/
|
1130 |
+
public function get_default_args() {
|
1131 |
+
return array_merge(
|
1132 |
+
parent::get_default_args(),
|
1133 |
+
array(
|
1134 |
+
'taxonomy' => '',
|
1135 |
+
'hide_empty' => false,
|
1136 |
+
)
|
1137 |
+
);
|
1138 |
+
}
|
1139 |
+
|
1140 |
+
|
1141 |
+
public function __construct() {
|
1142 |
+
|
1143 |
+
$args = func_get_args();
|
1144 |
+
|
1145 |
+
call_user_func_array( array( 'parent', '__construct' ), $args );
|
1146 |
+
|
1147 |
+
$this->args['data_delegate'] = array( $this, 'get_delegate_data' );
|
1148 |
+
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
public function get_delegate_data() {
|
1152 |
+
|
1153 |
+
$terms = $this->get_terms();
|
1154 |
+
|
1155 |
+
if ( is_wp_error( $terms ) ) {
|
1156 |
+
return array();
|
1157 |
+
}
|
1158 |
+
|
1159 |
+
$term_options = array();
|
1160 |
+
|
1161 |
+
foreach ( $terms as $term )
|
1162 |
+
$term_options[$term->term_id] = $term->name;
|
1163 |
+
|
1164 |
+
return $term_options;
|
1165 |
+
|
1166 |
+
}
|
1167 |
+
|
1168 |
+
private function get_terms() {
|
1169 |
+
|
1170 |
+
return get_terms( $this->args['taxonomy'], array( 'hide_empty' => $this->args['hide_empty'] ) );
|
1171 |
+
|
1172 |
+
}
|
1173 |
+
|
1174 |
+
}
|
1175 |
+
|
1176 |
+
/**
|
1177 |
+
* Post Select field.
|
1178 |
+
*
|
1179 |
+
* @supports "data_delegate"
|
1180 |
+
* @args
|
1181 |
+
* 'options' => array Array of options to show in the select, optionally use data_delegate instead
|
1182 |
+
* 'allow_none' => bool Allow no option to be selected (will palce a "None" at the top of the select)
|
1183 |
+
* 'multiple' => bool whether multiple can be selected
|
1184 |
+
*/
|
1185 |
+
class drkfr_Post_Select extends drkfr_Select {
|
1186 |
+
|
1187 |
+
public function __construct() {
|
1188 |
+
|
1189 |
+
$args = func_get_args();
|
1190 |
+
|
1191 |
+
call_user_func_array( array( 'parent', '__construct' ), $args );
|
1192 |
+
|
1193 |
+
if ( ! $this->args['use_ajax'] ) {
|
1194 |
+
|
1195 |
+
$this->args['data_delegate'] = array( $this, 'get_delegate_data' );
|
1196 |
+
|
1197 |
+
}
|
1198 |
+
|
1199 |
+
}
|
1200 |
+
|
1201 |
+
/**
|
1202 |
+
* Return the default args for the Post select field.
|
1203 |
+
*
|
1204 |
+
* @return array $args
|
1205 |
+
*/
|
1206 |
+
public function get_default_args() {
|
1207 |
+
return array_merge(
|
1208 |
+
parent::get_default_args(),
|
1209 |
+
array(
|
1210 |
+
'query' => array(),
|
1211 |
+
'use_ajax' => false,
|
1212 |
+
'multiple' => false,
|
1213 |
+
)
|
1214 |
+
);
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
public function get_delegate_data() {
|
1218 |
+
|
1219 |
+
$data = array();
|
1220 |
|