Smart Custom Fields - Version 1.0.0

Version Description

  • Initial release.
Download this release

Release Info

Developer inc2734
Plugin Icon wp plugin Smart Custom Fields
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

classes/class.config.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCF_Config
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : September 23, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class SCF_Config {
12
+ /**
13
+ * name
14
+ */
15
+ const NAME = 'smart-custom-fields';
16
+
17
+ /**
18
+ * prefix
19
+ */
20
+ const PREFIX = 'smart-cf-';
21
+ }
classes/class.field-base.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Base
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ abstract class Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * $name
15
+ */
16
+ protected $name;
17
+
18
+ /**
19
+ * $label
20
+ */
21
+ protected $label;
22
+
23
+ /**
24
+ * $field
25
+ */
26
+ protected $field = array();
27
+
28
+ /**
29
+ * __construct
30
+ * @param array $options
31
+ */
32
+ public function __construct() {
33
+ $settings = $this->init();
34
+ if ( !empty( $settings['name'] ) ) {
35
+ $this->name = $settings['name'];
36
+ }
37
+ if ( !empty( $settings['label'] ) ) {
38
+ $this->label = $settings['label'];
39
+ }
40
+ if ( !$this->name || !$this->label ) {
41
+ exit;
42
+ }
43
+ if ( empty( $settings['optgroup'] ) ) {
44
+ $settings['optgroup'] = 'basic-fields';
45
+ }
46
+ add_filter( SCF_Config::PREFIX . 'add-fields', array( $this, 'add_fields' ) );
47
+ add_filter( SCF_Config::PREFIX . 'field-select-' . $settings['optgroup'], array( $this, 'field_select' ) );
48
+ add_action( SCF_Config::PREFIX . 'field-options', array( $this, '_display_field_options' ), 10, 3 );
49
+ }
50
+
51
+ /**
52
+ * init
53
+ * @return array ( name, label, optgroup )
54
+ */
55
+ abstract protected function init();
56
+
57
+ /**
58
+ * get_field
59
+ * @param array $field フィールドの情報
60
+ * @param int $index インデックス番号
61
+ * @param mixed $value 保存されている値(check のときだけ配列)
62
+ * @return string html
63
+ */
64
+ abstract public function get_field( $field, $index, $value );
65
+
66
+ /**
67
+ * add_fields
68
+ * @param array $fields
69
+ * @return array $fields
70
+ */
71
+ public function add_fields( $fields ) {
72
+ $fields[$this->name] = $this;
73
+ return $fields;
74
+ }
75
+
76
+ /**
77
+ * field_select
78
+ * @param array $options その optgroup に属するフィールドのリスト
79
+ * @return array $options
80
+ */
81
+ public function field_select( $options ) {
82
+ $options[$this->name] = $this->label;
83
+ return $options;
84
+ }
85
+
86
+ /**
87
+ * display_field_options
88
+ * @param int $group_key
89
+ * @param int $field_key
90
+ */
91
+ abstract protected function display_field_options( $group_key, $field_key );
92
+ public function _display_field_options( $group_key, $field_key, $field ) {
93
+ $this->field = $field;
94
+ ?>
95
+ <tr class="<?php echo esc_attr( SCF_Config::PREFIX . 'field-options' ); ?> <?php echo esc_attr( SCF_Config::PREFIX . 'field-options-' . $this->name ); ?> hide">
96
+ <td colspan="2">
97
+ <table>
98
+ <?php $this->display_field_options( $group_key, $field_key ); ?>
99
+ </table>
100
+ </td>
101
+ </tr>
102
+ <?php
103
+ }
104
+
105
+ /**
106
+ * get_name_attribute
107
+ * @param string $name 定義されたフィールドの name
108
+ * @param string $index 添字
109
+ * @return string
110
+ */
111
+ protected function get_name_attribute( $name, $index ) {
112
+ return SCF_Config::NAME . '[' . $name . '][_' . $index . ']';
113
+ }
114
+
115
+ /**
116
+ * get_disable_attribute
117
+ * @param string $index 添字
118
+ * @return bool $disabled
119
+ */
120
+ protected function get_disable_attribute( $index ) {
121
+ $disabled = false;
122
+ if ( is_null( $index ) ) {
123
+ $disabled = true;
124
+ }
125
+ return $disabled;
126
+ }
127
+
128
+ /**
129
+ * get_field_name
130
+ * フィールド設定画面で使用する name 属性を返す
131
+ */
132
+ protected function get_field_name( $group_key, $field_key, $name ) {
133
+ return sprintf(
134
+ '%s[%d][fields][%d][%s]',
135
+ SCF_Config::NAME,
136
+ $group_key,
137
+ $field_key,
138
+ $name
139
+ );
140
+ }
141
+
142
+ /**
143
+ * get_field_value
144
+ * フィールド設定画面で使用する value を返す
145
+ */
146
+ protected function get_field_value( $name ) {
147
+ return $this->get( $name, $this->field );
148
+ }
149
+
150
+ /**
151
+ * get
152
+ * @param string $key 取得したいデータのキー
153
+ * @param array $data データ配列
154
+ * @return mixed
155
+ */
156
+ protected function get( $key, array $data ) {
157
+ if ( isset( $data[$key] ) ) {
158
+ return $data[$key];
159
+ }
160
+ }
161
+
162
+ public function get_choices( $choices ) {
163
+ return explode( "\n", $choices );
164
+ }
165
+ }
classes/class.revisions.php ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Revisions
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : September 23, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Revisions {
12
+
13
+ /**
14
+ * __construct
15
+ */
16
+ public function __construct() {
17
+ add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 10, 4 );
18
+ add_action( 'wp_restore_post_revision', array( $this, 'wp_restore_post_revision' ), 10, 2 );
19
+ add_action( 'wp_insert_post', array( $this, 'wp_insert_post' ) );
20
+
21
+ // Always auto save when click preview button.
22
+ add_filter( '_wp_post_revision_fields', array( $this, '_wp_post_revision_fields' ) );
23
+ add_action( 'edit_form_after_title', array( $this, 'edit_form_after_title' ) );
24
+
25
+ // Add custom fields preview in revision diff page.
26
+ add_filter( '_wp_post_revision_field_' . SCF_Config::PREFIX . 'debug-preview', array( $this, '_wp_post_revision_field_debug_preview' ), 10, 3 );
27
+
28
+ // Save revision when changing custom fields.
29
+ add_filter( 'wp_save_post_revision_check_for_changes', array( $this, 'wp_save_post_revision_check_for_changes' ), 10, 3);
30
+ }
31
+
32
+ /**
33
+ * wp_restore_post_revision
34
+ * リビジョンから復元するときに呼び出される
35
+ * @param int $post_id
36
+ * @param int $revision_id
37
+ */
38
+ public function wp_restore_post_revision( $post_id, $revision_id ) {
39
+ $post = get_post( $post_id );
40
+ $revision = get_post( $revision_id );
41
+ $post_type = get_post_type();
42
+
43
+ $settings = SCF::get_settings( $post_type );
44
+ foreach ( $settings as $setting ) {
45
+ foreach ( $setting as $group ) {
46
+ foreach ( $group['fields'] as $field ) {
47
+ delete_post_meta( $post->ID, $field['name'] );
48
+ $value = SCF::get( $field['name'], $revision->ID );
49
+ if ( is_array( $value ) ) {
50
+ foreach ( $value as $val ) {
51
+ add_post_meta( $post->ID, $field['name'], $val );
52
+ }
53
+ } else {
54
+ add_post_meta( $post->ID, $field['name'], $value );
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ $repeat_multiple_data_name = SCF_Config::PREFIX . 'repeat-multiple-data';
61
+ delete_post_meta( $post->ID, $repeat_multiple_data_name );
62
+ $repeat_multiple_data = get_post_meta( $revision->ID, $repeat_multiple_data_name, true );
63
+ add_post_meta( $post->ID, $repeat_multiple_data_name, $repeat_multiple_data );
64
+ }
65
+
66
+ /**
67
+ * wp_insert_post
68
+ * @param int $post_id
69
+ */
70
+ public function wp_insert_post( $post_id ) {
71
+ if ( !isset( $_POST[SCF_Config::PREFIX . 'fields-nonce'] ) ) {
72
+ return;
73
+ }
74
+ if ( !wp_verify_nonce( $_POST[SCF_Config::PREFIX . 'fields-nonce'], SCF_Config::NAME . '-fields' ) ) {
75
+ return;
76
+ }
77
+ if ( !isset( $_POST[SCF_Config::NAME] ) ) {
78
+ return;
79
+ }
80
+ if ( wp_is_post_revision( $post_id ) ) {
81
+ // 繰り返しフィールドのチェックボックスは、普通のチェックボックスと混ざって
82
+ // 判別できなくなるのでわかるように保存しておく
83
+ $repeat_multiple_data = array();
84
+
85
+ $post_type = get_post_type();
86
+ $settings = SCF::get_settings( $post_type );
87
+ foreach ( $settings as $setting ) {
88
+ foreach ( $setting as $group ) {
89
+ $is_repeat = ( isset( $group['repeat'] ) && $group['repeat'] === true ) ? true : false;
90
+ foreach ( $group['fields'] as $field ) {
91
+ delete_metadata( 'post', $post_id, $field['name'] );
92
+
93
+ if ( $is_repeat && in_array( $field['type'], array( 'check', 'relation' ) ) ) {
94
+ $repeat_multiple_data_fields = $_POST[SCF_Config::NAME][$field['name']];
95
+ foreach ( $repeat_multiple_data_fields as $values ) {
96
+ if ( is_array( $values ) ) {
97
+ $repeat_multiple_data[$field['name']][] = count( $values );
98
+ } else {
99
+ $repeat_multiple_data[$field['name']][] = 0;
100
+ }
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ delete_metadata( 'post', $post_id, SCF_Config::PREFIX . 'repeat-multiple-data' );
108
+ if ( $repeat_multiple_data ) {
109
+ update_metadata( 'post', $post_id, SCF_Config::PREFIX . 'repeat-multiple-data', $repeat_multiple_data );
110
+ }
111
+
112
+ foreach ( $_POST[SCF_Config::NAME] as $name => $values ) {
113
+ foreach ( $values as $value ) {
114
+ if ( !is_array( $value ) ) {
115
+ add_metadata( 'post', $post_id, $name, $value );
116
+ } else {
117
+ foreach ( $value as $val ) {
118
+ add_metadata( 'post', $post_id, $name, $val );
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ /**
127
+ * get_post_metadata
128
+ * プレビューのときはプレビューのメタデータを返す
129
+ * @param mixed $value
130
+ * @param int $post_id
131
+ * @param string $meta_key
132
+ * @param bool $single
133
+ * @return mixed $value
134
+ */
135
+ public function get_post_metadata( $value, $post_id, $meta_key, $single ) {
136
+ if ( $preview_id = $this->get_preview_id( $post_id ) ) {
137
+ if ( $post_id !== $preview_id ) {
138
+ $value = get_post_meta( $preview_id, $meta_key, $single );
139
+ }
140
+ }
141
+ return $value;
142
+ }
143
+
144
+ /**
145
+ * get_preview_id
146
+ * @param int $post_id
147
+ * @return int $preview_id
148
+ */
149
+ protected function get_preview_id( $post_id ) {
150
+ global $post;
151
+ $preview_id = 0;
152
+ if ( isset( $post->ID ) && intval( $post->ID ) === intval( $post_id ) && is_preview() && $preview = wp_get_post_autosave( $post->ID ) ) {
153
+ $preview_id = $preview->ID;
154
+ }
155
+ return $preview_id;
156
+ }
157
+
158
+ /**
159
+ * _wp_post_revision_fields
160
+ * @param array $fields
161
+ * @return array $fields
162
+ */
163
+ public function _wp_post_revision_fields( $fields ){
164
+ $fields[SCF_Config::PREFIX . 'debug-preview'] = esc_html__( 'Smart Custom Fields', 'smart-custom-fields' );
165
+ return $fields;
166
+ }
167
+
168
+ /**
169
+ * edit_form_after_title
170
+ */
171
+ public function edit_form_after_title() {
172
+ printf(
173
+ '<input type="hidden" name="%1$s" value="%1$s" />',
174
+ SCF_Config::PREFIX . 'debug-preview'
175
+ );
176
+ }
177
+
178
+ /**
179
+ * _wp_post_revision_field_debug_preview
180
+ * @param $value
181
+ * @param $column
182
+ * @param array $post
183
+ * @return string
184
+ */
185
+ public function _wp_post_revision_field_debug_preview( $value = '', $column = null, $post ) {
186
+ if ( is_null( $column ) ) {
187
+ $column = SCF_Config::PREFIX . 'debug-preview';
188
+ }
189
+ $output = '';
190
+ $values = SCF::gets( $post->ID );
191
+ foreach ( $values as $key => $value ) {
192
+ $output .= '[' . $key . ']' . "\n";
193
+ if ( is_array( $value ) ) {
194
+ if ( isset( $value[0] ) && is_array( $value[0] ) ) {
195
+ foreach ( $value as $sub_field_values ) {
196
+ foreach ( $sub_field_values as $sub_field_key => $sub_field_value ) {
197
+ $output .= $sub_field_key . " : ";
198
+ if ( is_array( $sub_field_value ) ) {
199
+ $output .= implode( ', ', $sub_field_value ) . "\n";
200
+ } else {
201
+ $output .= $sub_field_value . "\n";
202
+ }
203
+ }
204
+ }
205
+ } else {
206
+ $output .= implode( ', ', $value ) . "\n";
207
+ }
208
+ } else {
209
+ $output .= $value . "\n";
210
+ }
211
+ }
212
+ return $output;
213
+ }
214
+
215
+ /**
216
+ * wp_save_post_revision_check_for_changes
217
+ * @return bool false ならリビジョンとして保存される。
218
+ */
219
+ public function wp_save_post_revision_check_for_changes( $check_for_changes = true, $last_revision, $post ) {
220
+ $post_meta = array();
221
+ $p = get_post_custom( $post->ID );
222
+ foreach ( $p as $key => $value ) {
223
+ $v = SCF::get( $key );
224
+ if ( !is_null( $v ) ) {
225
+ $post_meta[$key][] = $v;
226
+ }
227
+ }
228
+
229
+ if ( isset( $_POST[SCF_Config::NAME] ) && serialize( $post_meta ) != serialize( $_POST[SCF_Config::NAME] ) ) {
230
+ return false;
231
+ }
232
+ return true;
233
+ }
234
+ }
classes/class.scf.php ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCF
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : September 23, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class SCF {
12
+
13
+ /**
14
+ * データ取得処理は重いので、一度取得したデータは cache に保存する。
15
+ * キーに post_id を設定すること。
16
+ */
17
+ protected static $cache = array();
18
+
19
+ /**
20
+ * データ取得処理は重いので、一度取得した設定データは settings_posts_cache に保存する。
21
+ * キーに post_type を設定すること。
22
+ */
23
+ protected static $settings_posts_cache = array();
24
+
25
+ /**
26
+ * データ取得処理は重いので、一度取得した設定データは cache に保存する。
27
+ * キーに post_type を設定すること。
28
+ */
29
+ protected static $settings_cache = array();
30
+
31
+ /**
32
+ * データ取得処理は重いので、一度取得した設定データは cache に保存する。
33
+ * キーに post_id を設定すること。
34
+ */
35
+ protected static $repeat_multiple_data_cache = array();
36
+
37
+ /**
38
+ * gets
39
+ * その投稿の全てのメタデータを良い感じに取得
40
+ * @param $post_id
41
+ * @return array
42
+ */
43
+ public static function gets( $post_id = null ) {
44
+ if ( is_null( $post_id ) ) {
45
+ $post_id = get_the_ID();
46
+ }
47
+ $post_id = self::get_real_post_id( $post_id );
48
+
49
+ $repeat_multiple_data = self::get_repeat_multiple_data( $post_id );
50
+
51
+ // 設定画面で未設定のメタデータは投稿が保持していても出力しないようにしないといけないので
52
+ // 設定データを取得して出力して良いか判別する
53
+ $post_type = get_post_type();
54
+ $settings = self::get_settings( $post_type );
55
+
56
+ $return_post_meta = array();
57
+ foreach ( $settings as $setting ) {
58
+ foreach ( $setting as $group ) {
59
+ // グループ名と一致する場合はそのグループ内のフィールドを配列で返す
60
+ $is_repeat = ( isset( $group['repeat'] ) && $group['repeat'] === true ) ? true : false;
61
+ if ( $is_repeat && !empty( $group['group-name'] ) ) {
62
+ $return_post_meta[$group['group-name']] = self::get_sub_field( $post_id, $group['group-name'], $group['fields'] );
63
+ }
64
+ // グループ名と一致しない場合は一致するフィールドを返す
65
+ else {
66
+ foreach ( $group['fields'] as $field ) {
67
+ $return_post_meta[$field['name']] = $post_meta = self::get_field( $post_id, $field, $is_repeat );
68
+ }
69
+ }
70
+ }
71
+ }
72
+ return $return_post_meta;
73
+ }
74
+
75
+ /**
76
+ * get
77
+ * その投稿の任意のメタデータを良い感じに取得
78
+ * @param string $name グループ名もしくはフィールド名
79
+ * @param int $post_id
80
+ * @return mixed
81
+ */
82
+ public static function get( $name, $post_id = null ) {
83
+ if ( is_null( $post_id ) ) {
84
+ $post_id = get_the_ID();
85
+ }
86
+
87
+ $post_id = self::get_real_post_id( $post_id );
88
+
89
+ if ( self::get_cache( $post_id, $name ) ) {
90
+ return self::get_cache( $post_id, $name );
91
+ }
92
+
93
+ $repeat_multiple_data = self::get_repeat_multiple_data( $post_id );
94
+
95
+ // 設定画面で未設定のメタデータは投稿が保持していても出力しないようにしないといけないので
96
+ // 設定データを取得して出力して良いか判別する
97
+ $post_type = get_post_type();
98
+ $settings = self::get_settings( $post_type );
99
+
100
+ foreach ( $settings as $setting ) {
101
+ foreach ( $setting as $group ) {
102
+ // グループ名と一致する場合はそのグループ内のフィールドを配列で返す
103
+ $is_repeat = ( isset( $group['repeat'] ) && $group['repeat'] === true ) ? true : false;
104
+ if ( $is_repeat && !empty( $group['group-name'] ) && $group['group-name'] === $name ) {
105
+ return self::get_sub_field( $post_id, $name, $group['fields'] );
106
+ }
107
+ // グループ名と一致しない場合は一致するフィールドを返す
108
+ else {
109
+ foreach ( $group['fields'] as $field ) {
110
+ if ( $field['name'] !== $name ) {
111
+ continue;
112
+ }
113
+ $post_meta = self::get_field( $post_id, $field, $is_repeat );
114
+ if ( !is_null( $post_meta ) ) {
115
+ return $post_meta;
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ protected static function get_real_post_id( $post_id ) {
124
+ if ( is_preview() ) {
125
+ $preview_post = wp_get_post_autosave( $post_id );
126
+ if ( isset( $preview_post->ID ) ) {
127
+ $post_id = $preview_post->ID;
128
+ }
129
+ }
130
+ return $post_id;
131
+ }
132
+
133
+ /**
134
+ * save_cache
135
+ * @param int $post_id
136
+ * @param string $name
137
+ * @param mixed $data
138
+ */
139
+ protected static function save_cache( $post_id, $name, $data ) {
140
+ self::$cache[$post_id][$name] = $data;
141
+ }
142
+
143
+ /**
144
+ * get_cache
145
+ * @param int $post_id
146
+ * @param string $name
147
+ * @return mixed
148
+ */
149
+ protected static function get_cache( $post_id, $name = null ) {
150
+ if ( is_null( $name ) ) {
151
+ if ( isset( self::$cache[$post_id] ) ) {
152
+ return self::$cache[$post_id];
153
+ }
154
+ } else {
155
+ if ( isset( self::$cache[$post_id][$name] ) ) {
156
+ return self::$cache[$post_id][$name];
157
+ }
158
+ }
159
+ }
160
+
161
+ /**
162
+ * get_sub_field
163
+ * @param int $post_id
164
+ * @param string $group_name
165
+ * @param array $fields
166
+ * @return mixed $post_meta
167
+ */
168
+ protected static function get_sub_field( $post_id, $group_name, $fields ) {
169
+ $post_meta = array();
170
+ foreach ( $fields as $field ) {
171
+ $_post_meta = get_post_meta( $post_id, $field['name'] );
172
+ // チェックボックスの場合
173
+ $repeat_multiple_data = self::get_repeat_multiple_data( $post_id );
174
+ if ( is_array( $repeat_multiple_data ) && array_key_exists( $field['name'], $repeat_multiple_data ) ) {
175
+ $start = 0;
176
+ foreach ( $repeat_multiple_data[$field['name']] as $repeat_multiple_key => $repeat_multiple_value ) {
177
+ if ( $repeat_multiple_value === 0 ) {
178
+ $value = array();
179
+ } else {
180
+ $value = array_slice( $_post_meta, $start, $repeat_multiple_value );
181
+ $start += $repeat_multiple_value;
182
+ }
183
+ $post_meta[$repeat_multiple_key][$field['name']] = $value;
184
+ }
185
+ }
186
+ // チェックボックス以外
187
+ else {
188
+ foreach ( $_post_meta as $_post_meta_key => $value ) {
189
+ if ( in_array( $field['type'], array( 'textarea', 'wysiwyg' ) ) ) {
190
+ $value = apply_filters( 'the_content', $value );
191
+ } elseif ( $field['type'] === 'relation' ) {
192
+ if ( get_post_status( $value ) !== 'publish' )
193
+ continue;
194
+ }
195
+ $post_meta[$_post_meta_key][$field['name']] = $value;
196
+ }
197
+ }
198
+ }
199
+ self::save_cache( $post_id, $group_name, $post_meta );
200
+ return $post_meta;
201
+ }
202
+
203
+ /**
204
+ * get_field
205
+ * @param int $post_id
206
+ * @param array $field
207
+ * @param bool $is_repeat
208
+ * @return mixed $post_meta
209
+ */
210
+ protected static function get_field( $post_id, $field, $is_repeat, $name = null ) {
211
+ if ( in_array( $field['type'], array( 'check', 'relation' ) ) || $is_repeat ) {
212
+ $post_meta = get_post_meta( $post_id, $field['name'] );
213
+ } else {
214
+ $post_meta = get_post_meta( $post_id, $field['name'], true );
215
+ }
216
+ if ( in_array( $field['type'], array( 'textarea', 'wysiwyg' ) ) ) {
217
+ if ( is_array( $post_meta ) ) {
218
+ $_post_meta = array();
219
+ foreach ( $post_meta as $key => $value ) {
220
+ $_post_meta[$key] = apply_filters( 'the_content', $value );
221
+ }
222
+ $post_meta = $_post_meta;
223
+ } else {
224
+ $post_meta = apply_filters( 'the_content', $post_meta );
225
+ }
226
+ } elseif ( $field['type'] === 'relation' ) {
227
+ $_post_meta = array();
228
+ foreach ( $post_meta as $post_id ) {
229
+ if ( get_post_status( $post_id ) !== 'publish' )
230
+ continue;
231
+ $_post_meta[] = $post_id;
232
+ }
233
+ $post_meta = $_post_meta;
234
+ }
235
+ self::save_cache( $post_id, $field['name'], $post_meta );
236
+ return $post_meta;
237
+ }
238
+
239
+ /**
240
+ * save_settings_posts_cache
241
+ * @param int $post_type
242
+ * @param array $posts
243
+ */
244
+ protected static function save_settings_posts_cache( $post_type, array $posts = array() ) {
245
+ self::$settings_posts_cache[$post_type] = $posts;
246
+ }
247
+
248
+ /**
249
+ * get_settings_posts
250
+ * @param int $post_type
251
+ * @param array $settings
252
+ */
253
+ public static function get_settings_posts( $post_type ) {
254
+ $posts = array();
255
+ if ( isset( self::$settings_posts_cache[$post_type] ) ) {
256
+ return self::$settings_posts_cache[$post_type];
257
+ }
258
+ $posts = get_posts( array(
259
+ 'post_type' => SCF_Config::NAME,
260
+ 'posts_per_page' => -1,
261
+ 'meta_query' => array(
262
+ array(
263
+ 'key' => SCF_Config::PREFIX . 'condition',
264
+ 'compare' => 'LIKE',
265
+ 'value' => $post_type,
266
+ ),
267
+ ),
268
+ ) );
269
+ self::save_settings_posts_cache( $post_type, $posts );
270
+ return $posts;
271
+ }
272
+
273
+ /**
274
+ * save_settings_cache
275
+ * @param int $post_type
276
+ * @param array $settings
277
+ */
278
+ protected static function save_settings_cache( $post_type, array $settings = array() ) {
279
+ self::$settings_cache[$post_type] = $settings;
280
+ }
281
+
282
+ /**
283
+ * get_settings
284
+ * @param int $post_type
285
+ * @param array $settings
286
+ */
287
+ public static function get_settings( $post_type ) {
288
+ $settings = array();
289
+ if ( isset( self::$settings_cache[$post_type] ) ) {
290
+ return self::$settings_cache[$post_type];
291
+ }
292
+ if ( empty( $settings ) ) {
293
+ $cf_posts = self::get_settings_posts( $post_type );
294
+ foreach ( $cf_posts as $_post ) {
295
+ $setting = array();
296
+ $_setting = get_post_meta( $_post->ID, SCF_Config::PREFIX . 'setting', true );
297
+ if ( is_array( $_setting ) ) {
298
+ $setting = $_setting;
299
+ }
300
+ $settings[] = $setting;
301
+ }
302
+ }
303
+ self::save_settings_cache( $post_type, $settings );
304
+ return $settings;
305
+ }
306
+
307
+ /**
308
+ * save_repeat_multiple_data_cache
309
+ * @param int $post_id
310
+ * @param mixed $repeat_multiple_data
311
+ */
312
+ protected static function save_repeat_multiple_data_cache( $post_id, $repeat_multiple_data ) {
313
+ self::$repeat_multiple_data_cache[$post_id] = $repeat_multiple_data;
314
+ }
315
+
316
+ /**
317
+ * get_repeat_multiple_data
318
+ * @param int $post_id
319
+ * @return mixed
320
+ */
321
+ public static function get_repeat_multiple_data( $post_id ) {
322
+ $repeat_multiple_data = array();
323
+ if ( isset( self::$repeat_multiple_data_cache[$post_id] ) ) {
324
+ return self::$repeat_multiple_data_cache[$post_id];
325
+ }
326
+ if ( empty( $repeat_multiple_data ) ) {
327
+ $_repeat_multiple_data = get_post_meta( $post_id, SCF_Config::PREFIX . 'repeat-multiple-data', true );
328
+ if ( $_repeat_multiple_data ) {
329
+ $repeat_multiple_data = $_repeat_multiple_data;
330
+ }
331
+ }
332
+ self::save_repeat_multiple_data_cache( $post_id, $repeat_multiple_data );
333
+ return $repeat_multiple_data;
334
+ }
335
+
336
+ /**
337
+ * is_empty
338
+ * null もしくは空値の場合は true
339
+ * @param mixed $value
340
+ * @return bool
341
+ */
342
+ public static function is_empty( &$value ) {
343
+ if ( isset( $value ) ) {
344
+ if ( is_null( $value ) || $value === '' ) {
345
+ return true;
346
+ }
347
+ return false;
348
+ }
349
+ return true;
350
+ }
351
+ }
classes/class.settings.php ADDED
@@ -0,0 +1,331 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Settings
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : September 23, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Settings {
12
+
13
+ /**
14
+ * __construct
15
+ */
16
+ public function __construct() {
17
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
18
+ add_action( 'save_post', array( $this, 'save_post' ) );
19
+ add_action( 'init', array( $this, 'register_post_type' ) );
20
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
21
+ }
22
+
23
+ /**
24
+ * admin_enqueue_scripts
25
+ */
26
+ public function admin_enqueue_scripts() {
27
+ if ( get_post_type() === SCF_Config::NAME ) {
28
+ wp_enqueue_style(
29
+ SCF_Config::PREFIX . 'settings',
30
+ plugin_dir_url( __FILE__ ) . '../css/settings.css'
31
+ );
32
+ wp_enqueue_script(
33
+ SCF_Config::PREFIX . 'settings',
34
+ plugin_dir_url( __FILE__ ) . '../js/settings.js',
35
+ array( 'jquery' ),
36
+ null,
37
+ true
38
+ );
39
+ wp_localize_script( SCF_Config::PREFIX . 'settings', 'smart_cf_settings', array(
40
+ 'duplicate_alert' => esc_html__( 'Same name exists!', 'smart-custom-fields' ),
41
+ ) );
42
+ wp_enqueue_script( 'jquery-ui-sortable' );
43
+ }
44
+ }
45
+
46
+ /**
47
+ * register_post_type
48
+ */
49
+ public function register_post_type() {
50
+ register_post_type(
51
+ SCF_Config::NAME,
52
+ array(
53
+ 'label' => 'Smart Custom Fields',
54
+ 'labels' => array(
55
+ ),
56
+ 'public' => false,
57
+ 'show_ui' => true,
58
+ 'capability_type' => 'page',
59
+ 'supports' => array( 'title' ),
60
+ 'menu_position' => 80,
61
+ )
62
+ );
63
+ }
64
+
65
+ /**
66
+ * add_meta_boxes
67
+ * 投稿画面にカスタムフィールドを表示
68
+ */
69
+ public function add_meta_boxes() {
70
+ add_meta_box(
71
+ SCF_Config::PREFIX . 'meta-box',
72
+ __( 'Custom Fields', 'smart-custom-fields' ),
73
+ array( $this, 'display_meta_box' ),
74
+ SCF_Config::NAME
75
+ );
76
+ add_meta_box(
77
+ SCF_Config::PREFIX . 'meta-box-condition',
78
+ __( 'Display conditions', 'smart-custom-fields' ),
79
+ array( $this, 'display_meta_box_condition' ),
80
+ SCF_Config::NAME,
81
+ 'side'
82
+ );
83
+ }
84
+
85
+ /**
86
+ * get
87
+ * @param string $key 取得したいデータのキー
88
+ * @param array $data データ配列
89
+ * @return mixed
90
+ */
91
+ private function get( $key, array $data ) {
92
+ if ( isset( $data[$key] ) ) {
93
+ return $data[$key];
94
+ }
95
+ }
96
+
97
+ /**
98
+ * add_hide_class
99
+ * @param string $key 値があれば hide を表示
100
+ */
101
+ private function add_hide_class( $key ) {
102
+ if ( !$key ) {
103
+ echo 'hide';
104
+ }
105
+ }
106
+
107
+ /**
108
+ * display_meta_box
109
+ */
110
+ public function display_meta_box() {
111
+ $default = array(
112
+ array(
113
+ 'group-name' => '',
114
+ 'fields' => array(),
115
+ ),
116
+ );
117
+ $settings = get_post_meta( get_the_ID(), SCF_Config::PREFIX . 'setting', true );
118
+ $settings = wp_parse_args( $settings, $default );
119
+ ?>
120
+ <div class="<?php echo esc_attr( SCF_Config::PREFIX . 'fields-wrapper' ); ?>">
121
+ <div class="<?php echo esc_attr( SCF_Config::PREFIX . 'groups' ); ?>">
122
+ <?php foreach ( $settings as $group_key => $group ) : ?>
123
+ <?php
124
+ $group_name = '';
125
+ if ( !is_numeric( $group['group-name'] ) ) {
126
+ $group_name = $group['group-name'];
127
+ }
128
+ array_unshift( $group['fields'], array() );
129
+ ?>
130
+ <div class="<?php echo esc_attr( SCF_Config::PREFIX . 'group' ); ?> <?php $this->add_hide_class( $group_key ); ?>">
131
+ <div class="btn-remove-group"><b>x</b></div>
132
+ <div class="<?php echo esc_attr( SCF_Config::PREFIX . 'group-repeat' ); ?>">
133
+ <label>
134
+ <input type="checkbox"
135
+ name="<?php echo esc_attr( SCF_Config::NAME . '[' . $group_key . '][repeat]' ); ?>"
136
+ value="true"
137
+ <?php checked( $this->get( 'repeat', $group ), true ); ?>
138
+ />
139
+ <?php esc_html_e( 'Repeat', 'smart-custom-fields' ); ?>
140
+ </label>
141
+ </div>
142
+ <table class="<?php echo esc_attr( SCF_Config::PREFIX . 'group-names' ); ?> <?php $this->add_hide_class( $this->get( 'repeat', $group ) ); ?>">
143
+ <tr>
144
+ <th><?php esc_html_e( 'Group name', 'smart-custom-fields' ); ?><span class="<?php echo esc_attr( SCF_Config::PREFIX . 'require' ); ?>">*</span></th>
145
+ <td>
146
+ <input type="text"
147
+ name="<?php echo esc_attr( SCF_Config::NAME . '[' . $group_key . '][group-name]' ); ?>"
148
+ size="30"
149
+ class="<?php echo esc_attr( SCF_Config::PREFIX . 'group-name' ); ?>"
150
+ value="<?php echo esc_attr( $group_name ); ?>"
151
+ />
152
+ </td>
153
+ </tr>
154
+ </table>
155
+
156
+ <div class="<?php echo esc_attr( SCF_Config::PREFIX . 'fields' ); ?>">
157
+ <?php foreach ( $group['fields'] as $field_key => $field ) : ?>
158
+ <div class="<?php echo esc_attr( SCF_Config::PREFIX . 'field' ); ?> <?php $this->add_hide_class( $field_key ); ?>">
159
+ <?php
160
+ $field_label = $this->get( 'label', $field );
161
+ if ( !$field_label ) {
162
+ $field_label = $this->get( 'name', $field );
163
+ }
164
+ ?>
165
+ <div class="btn-remove-field"><span><?php echo esc_html( $field_label ); ?></span><b>x</b></div>
166
+ <table class="<?php $this->add_hide_class( !$this->get( 'name', $field ) ); ?>">
167
+ <tr>
168
+ <th><?php esc_html_e( 'Name', 'smart-custom-fields' ); ?><span class="<?php echo esc_attr( SCF_Config::PREFIX . 'require' ); ?>">*</span></th>
169
+ <td>
170
+ <input type="text"
171
+ name="<?php echo esc_attr( SCF_Config::NAME . '[' . $group_key . '][fields][' . $field_key . '][name]' ); ?>"
172
+ size="30"
173
+ class="<?php echo esc_attr( SCF_Config::PREFIX . 'field-name' ); ?>"
174
+ value="<?php echo esc_attr( $this->get( 'name', $field ) ); ?>"
175
+ />
176
+ </td>
177
+ </tr>
178
+ <tr>
179
+ <th><?php esc_html_e( 'Label', 'smart-custom-fields' ); ?></th>
180
+ <td>
181
+ <input type="text"
182
+ name="<?php echo esc_attr( SCF_Config::NAME . '[' . $group_key . '][fields][' . $field_key . '][label]' ); ?>"
183
+ size="30"
184
+ class="<?php echo esc_attr( SCF_Config::PREFIX . 'field-label' ); ?>"
185
+ value="<?php echo esc_attr( $this->get( 'label', $field ) ); ?>"
186
+ />
187
+ </td>
188
+ </tr>
189
+ <tr>
190
+ <th><?php esc_html_e( 'Type', 'smart-custom-fields' ); ?><span class="<?php echo esc_attr( SCF_Config::PREFIX . 'require' ); ?>">*</span></th>
191
+ <td>
192
+ <select
193
+ name="<?php echo esc_attr( SCF_Config::NAME . '[' . $group_key . '][fields][' . $field_key . '][type]' ); ?>"
194
+ class="<?php echo esc_attr( SCF_Config::PREFIX . 'field-select' ); ?>" />
195
+ <?php
196
+ $optgroups = array(
197
+ 'basic-fields' => array(
198
+ 'label' => esc_attr__( 'Basic fields', 'smart-custom-fields' ),
199
+ 'options' => array(),
200
+ ),
201
+ 'select-fields' => array(
202
+ 'label' => esc_attr__( 'Select fields', 'smart-custom-fields' ),
203
+ 'options' => array(),
204
+ ),
205
+ 'content-fields' => array(
206
+ 'label' => esc_attr__( 'Content fields', 'smart-custom-fields' ),
207
+ 'options' => array(),
208
+ ),
209
+ 'other-fields' => array(
210
+ 'label' => esc_attr__( 'Other fields', 'smart-custom-fields' ),
211
+ 'options' => array(),
212
+ ),
213
+ );
214
+ foreach ( $optgroups as $optgroup_name => $optgroup_values ) {
215
+ $optgroup_fields = array();
216
+ $optgroup_values['options'] = apply_filters(
217
+ SCF_Config::PREFIX . 'field-select-' . $optgroup_name,
218
+ $optgroup_values['options']
219
+ );
220
+ foreach ( $optgroup_values['options'] as $option_key => $option ) {
221
+ $optgroup_fields[] = sprintf(
222
+ '<option value="%s" %s>%s</option>',
223
+ esc_attr( $option_key ),
224
+ selected( $this->get( 'type', $field ), $option_key, false ),
225
+ esc_html( $option )
226
+ );
227
+ }
228
+ printf(
229
+ '<optgroup label="%s">%s</optgroup>',
230
+ $optgroup_values['label'],
231
+ implode( '', $optgroup_fields )
232
+ );
233
+ }
234
+ ?>
235
+ </select>
236
+ </td>
237
+ </tr>
238
+ <?php do_action( SCF_Config::PREFIX . 'field-options', $group_key, $field_key, $field ); ?>
239
+ </table>
240
+ </div>
241
+ <?php endforeach; ?>
242
+ </div>
243
+ <div class="button btn-add-field <?php $this->add_hide_class( $this->get( 'repeat', $group ) ); ?>"><?php esc_html_e( 'Add Sub field', 'smart-custom-fields' ); ?></div>
244
+ </div>
245
+ <?php endforeach; ?>
246
+ </div>
247
+ <div class="button btn-add-group"><?php esc_html_e( 'Add Field', 'smart-custom-fields' ); ?></div>
248
+ </div>
249
+ <?php wp_nonce_field( SCF_Config::NAME . '-settings', SCF_Config::PREFIX . 'settings-nonce' ) ?>
250
+ <?php
251
+ }
252
+
253
+ /**
254
+ * display_meta_box_condition
255
+ * メタボックスの表示条件を設定するメタボックスを表示
256
+ */
257
+ public function display_meta_box_condition() {
258
+ $post_types = get_post_types( array(
259
+ 'show_ui' => true,
260
+ ), 'objects' );
261
+ unset( $post_types['attachment'] );
262
+ unset( $post_types[SCF_Config::NAME] );
263
+
264
+ $conditions = get_post_meta( get_the_ID(), SCF_Config::PREFIX . 'condition', true );
265
+ foreach ( $post_types as $post_type => $post_type_object ) {
266
+ $current = ( is_array( $conditions ) && in_array( $post_type, $conditions ) ) ? $post_type : false;
267
+ printf(
268
+ '<label><input type="checkbox" name="%s" value="%s" %s /> %s</label>',
269
+ esc_attr( SCF_Config::PREFIX . 'condition[]' ),
270
+ esc_attr( $post_type ),
271
+ checked( $current, $post_type, false ),
272
+ esc_attr( $post_type_object->labels->singular_name )
273
+ );
274
+ }
275
+ }
276
+
277
+ /**
278
+ * save_post
279
+ */
280
+ public function save_post( $post_id ) {
281
+ if ( !isset( $_POST[SCF_Config::PREFIX . 'settings-nonce'] ) ) {
282
+ return;
283
+ }
284
+ if ( !wp_verify_nonce( $_POST[SCF_Config::PREFIX . 'settings-nonce'], SCF_Config::NAME . '-settings' ) ) {
285
+ return;
286
+ }
287
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
288
+ return;
289
+ }
290
+ if ( get_post_type() !== SCF_Config::NAME ) {
291
+ return;
292
+ }
293
+ if ( !isset( $_POST[SCF_Config::NAME] ) ) {
294
+ return;
295
+ }
296
+
297
+ $data = array();
298
+ foreach ( $_POST[SCF_Config::NAME] as $group_key => $group_value ) {
299
+ if ( !empty( $group_value['fields'] ) && count( $group_value['fields'] ) > 1 ) {
300
+ $fields = array();
301
+ foreach ( $group_value['fields'] as $field_value ) {
302
+ if ( !empty( $field_value['name'] ) ) {
303
+ $fields[] = $field_value;
304
+ }
305
+ }
306
+ if ( !$fields )
307
+ continue;
308
+
309
+ if ( !empty( $group_value['repeat'] ) && $group_value['repeat'] === 'true' ) {
310
+ $group_value['repeat'] = true;
311
+ }
312
+
313
+ // repeat が true でないときは name を空に
314
+ // true のときで、name から空のときは index を代入
315
+ if ( !( isset( $group_value['repeat'] ) && $group_value['repeat'] === true && !empty( $group_value['group-name'] ) ) ) {
316
+ $group_value['group-name'] = $group_key;
317
+ }
318
+
319
+ $group_value['fields'] = $fields;
320
+ $data[] = $group_value;
321
+ }
322
+ }
323
+ update_post_meta( $post_id, SCF_Config::PREFIX . 'setting', $data );
324
+
325
+ if ( !isset( $_POST[SCF_Config::PREFIX . 'condition'] ) ) {
326
+ delete_post_meta( $post_id, SCF_Config::PREFIX . 'condition' );
327
+ } else {
328
+ update_post_meta( $post_id, SCF_Config::PREFIX . 'condition', $_POST[SCF_Config::PREFIX . 'condition'] );
329
+ }
330
+ }
331
+ }
classes/fields/class.field-check.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Check
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Check extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'check',
20
+ 'label' => __( 'Check', 'smart-custom-fields' ),
21
+ 'optgroup' => 'select-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+ $choices = $this->get_choices( $field['choices'] );
35
+
36
+ $form_field = sprintf(
37
+ '<input type="hidden" name="%s" value="" %s />',
38
+ esc_attr( $name ),
39
+ disabled( true, $disabled, false )
40
+ );
41
+ foreach ( $choices as $choice ) {
42
+ $choice = trim( $choice );
43
+ $checked = ( is_array( $value ) && in_array( $choice, $value ) ) ? 'checked="checked"' : '' ;
44
+ $form_field .= sprintf(
45
+ '<label><input type="checkbox" name="%s" value="%s" %s %s /> %s</label>',
46
+ esc_attr( $name . '[]' ),
47
+ esc_attr( $choice ),
48
+ $checked,
49
+ disabled( true, $disabled, false ),
50
+ esc_html( $choice )
51
+ );
52
+ }
53
+ return $form_field;
54
+ }
55
+
56
+ /**
57
+ * display_field_options
58
+ * @param int $group_key
59
+ * @param int $field_key
60
+ */
61
+ public function display_field_options( $group_key, $field_key ) {
62
+ ?>
63
+ <tr>
64
+ <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
65
+ <td>
66
+ <textarea
67
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'choices' ) ); ?>"
68
+ class="widefat"
69
+ rows="5" /><?php echo esc_textarea( "\n" . $this->get_field_value( 'choices' ) ); ?></textarea>
70
+ </td>
71
+ </tr>
72
+ <tr>
73
+ <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
74
+ <td>
75
+ <textarea
76
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'default' ) ); ?>"
77
+ class="widefat"
78
+ rows="5" /><?php echo esc_textarea( "\n" . $this->get_field_value( 'default' ) ); ?></textarea>
79
+ </td>
80
+ </tr>
81
+ <tr>
82
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
83
+ <td>
84
+ <input type="text"
85
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
86
+ class="widefat"
87
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
88
+ />
89
+ </td>
90
+ </tr>
91
+ <?php
92
+ }
93
+ }
classes/fields/class.field-file.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_File
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_File extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'file',
20
+ 'label' => __( 'File', 'smart-custom-fields' ),
21
+ 'optgroup' => 'content-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+
35
+ $btn_remove = sprintf(
36
+ '<span class="btn-remove-file hide">%s</span>',
37
+ esc_html__( 'Delete', 'smart-custom-fields' )
38
+ );
39
+
40
+ $hide_class = 'hide';
41
+ $image = $btn_remove;
42
+ if ( $value ) {
43
+ $image_src = wp_get_attachment_image_src( $value, 'thumbnail', true );
44
+ if ( is_array( $image_src ) && isset( $image_src[0] ) ) {
45
+ $image_src = $image_src[0];
46
+ $image = sprintf(
47
+ '<a href="%s" target="_blank"><img src="%s" alt="" /></a>%s',
48
+ wp_get_attachment_url( $value ),
49
+ esc_url( $image_src ),
50
+ $btn_remove
51
+ );
52
+ $hide_class = '';
53
+ }
54
+ }
55
+
56
+ return sprintf(
57
+ '<span class="button btn-add-file">%s</span><br />
58
+ <span class="%s %s">%s</span>
59
+ <input type="hidden" name="%s" value="%s" %s />',
60
+ esc_html__( 'File Select', 'smart-custom-fields' ),
61
+ esc_attr( SCF_Config::PREFIX . 'upload-file' ),
62
+ esc_attr( $hide_class ),
63
+ $image,
64
+ esc_attr( $name ),
65
+ esc_attr( $value ),
66
+ disabled( true, $disabled, false )
67
+ );
68
+ }
69
+
70
+ /**
71
+ * display_field_options
72
+ * @param int $group_key
73
+ * @param int $field_key
74
+ */
75
+ public function display_field_options( $group_key, $field_key ) {
76
+ ?>
77
+ <tr>
78
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
79
+ <td>
80
+ <input type="text"
81
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
82
+ class="widefat"
83
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
84
+ />
85
+ </td>
86
+ </tr>
87
+ <?php
88
+ }
89
+ }
classes/fields/class.field-image.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Image
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Image extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'image',
20
+ 'label' => __( 'Image', 'smart-custom-fields' ),
21
+ 'optgroup' => 'content-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+
35
+ $btn_remove = sprintf(
36
+ '<span class="btn-remove-image hide">%s</span>',
37
+ esc_html__( 'Delete', 'smart-custom-fields' )
38
+ );
39
+
40
+ $hide_class = 'hide';
41
+ $image = $btn_remove;
42
+ if ( $value ) {
43
+ $image_src = wp_get_attachment_image_src( $value, 'full' );
44
+ if ( is_array( $image_src ) && isset( $image_src[0] ) ) {
45
+ $image_src = $image_src[0];
46
+ $image = sprintf(
47
+ '<img src="%s" alt="" />%s',
48
+ esc_url( $image_src ),
49
+ $btn_remove
50
+ );
51
+ $hide_class = '';
52
+ }
53
+ }
54
+
55
+ return sprintf(
56
+ '<span class="button btn-add-image">%s</span><br />
57
+ <span class="%s %s">%s</span>
58
+ <input type="hidden" name="%s" value="%s" %s />',
59
+ esc_html__( 'Image Select', 'smart-custom-fields' ),
60
+ esc_attr( SCF_Config::PREFIX . 'upload-image' ),
61
+ esc_attr( $hide_class ),
62
+ $image,
63
+ esc_attr( $name ),
64
+ esc_attr( $value ),
65
+ disabled( true, $disabled, false )
66
+ );
67
+ }
68
+
69
+ /**
70
+ * display_field_options
71
+ * @param int $group_key
72
+ * @param int $field_key
73
+ */
74
+ public function display_field_options( $group_key, $field_key ) {
75
+ ?>
76
+ <tr>
77
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
78
+ <td>
79
+ <input type="text"
80
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
81
+ class="widefat"
82
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
83
+ />
84
+ </td>
85
+ </tr>
86
+ <?php
87
+ }
88
+ }
classes/fields/class.field-radio.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Radio
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Radio extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'radio',
20
+ 'label' => __( 'Radio', 'smart-custom-fields' ),
21
+ 'optgroup' => 'select-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+ $choices = $this->get_choices( $field['choices'] );
35
+
36
+ $form_field = sprintf(
37
+ '<input type="hidden" name="%s" value="" %s />',
38
+ esc_attr( $name ),
39
+ disabled( true, $disabled, false )
40
+ );
41
+ foreach ( $choices as $choice ) {
42
+ $choice = trim( $choice );
43
+ $form_field .= sprintf(
44
+ '<label><input type="radio" name="%s" value="%s" %s %s /> %s</label>',
45
+ esc_attr( $name ),
46
+ esc_attr( $choice ),
47
+ checked( $value, $choice, false ),
48
+ disabled( true, $disabled, false ),
49
+ esc_html( $choice )
50
+ );
51
+ }
52
+ return $form_field;
53
+ }
54
+
55
+ /**
56
+ * display_field_options
57
+ * @param int $group_key
58
+ * @param int $field_key
59
+ */
60
+ public function display_field_options( $group_key, $field_key ) {
61
+ ?>
62
+ <tr>
63
+ <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
64
+ <td>
65
+ <textarea
66
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'choices' ) ); ?>"
67
+ class="widefat"
68
+ rows="5" /><?php echo esc_textarea( "\n" . $this->get_field_value( 'choices' ) ); ?></textarea>
69
+ </td>
70
+ </tr>
71
+ <tr>
72
+ <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
73
+ <td>
74
+ <input type="text"
75
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'default' ) ); ?>"
76
+ class="widefat"
77
+ value="<?php echo esc_attr( $this->get_field_value( 'default' ) ); ?>" />
78
+ </td>
79
+ </tr>
80
+ <tr>
81
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
82
+ <td>
83
+ <input type="text"
84
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
85
+ class="widefat"
86
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
87
+ />
88
+ </td>
89
+ </tr>
90
+ <?php
91
+ }
92
+ }
classes/fields/class.field-relation.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Relation
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Relation extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'relation',
20
+ 'label' => __( 'Relation', 'smart-custom-fields' ),
21
+ 'optgroup' => 'other-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+ $post_type = $this->get( 'post-type', $field );
35
+ if ( !$post_type ) {
36
+ $post_type = array( 'post' );
37
+ }
38
+ $posts_per_page = get_option( 'posts_per_page' );
39
+
40
+ // 選択肢
41
+ $choices_posts = get_posts( array(
42
+ 'post_type' => $post_type,
43
+ 'order' => 'ASC',
44
+ 'orderby' => 'ID',
45
+ 'posts_per_page' => $posts_per_page,
46
+ ) );
47
+ $choices_li = array();
48
+ foreach ( $choices_posts as $_post ) {
49
+ $post_title = get_the_title( $_post->ID );
50
+ if ( empty( $post_title ) ) {
51
+ $post_title = '&nbsp;';
52
+ }
53
+ $choices_li[] = sprintf( '<li data-id="%d">%s</li>', $_post->ID, $post_title );
54
+ }
55
+
56
+ // 選択済
57
+ $selected_posts = array();
58
+ if ( !empty( $value ) && is_array( $value ) ) {
59
+ foreach ( $value as $post_id ) {
60
+ if ( get_post_status( $post_id ) !== 'publish' )
61
+ continue;
62
+ $post_title = get_the_title( $post_id );
63
+ if ( empty( $post_title ) ) {
64
+ $post_title = '&nbsp;';
65
+ }
66
+ $selected_posts[$post_id] = $post_title;
67
+ }
68
+ }
69
+ $selected_li = array();
70
+ $hidden = array();
71
+ foreach ( $selected_posts as $post_id => $post_title ) {
72
+ $selected_li[] = sprintf(
73
+ '<li data-id="%d"><span class="%s"></span>%s<span class="relation-remove">-</li></li>',
74
+ $post_id,
75
+ esc_attr( SCF_Config::PREFIX . 'icon-handle' ),
76
+ $post_title
77
+ );
78
+ $hidden[] = sprintf(
79
+ '<input type="hidden" name="%s" value="%d" %s />',
80
+ esc_attr( $name . '[]' ),
81
+ $post_id,
82
+ disabled( true, $disabled, false )
83
+ );
84
+ }
85
+
86
+ $hide_class = '';
87
+ if ( count( $choices_li ) < $posts_per_page ) {
88
+ $hide_class = 'hide';
89
+ }
90
+
91
+ return sprintf(
92
+ '<div class="%s">
93
+ <div class="%s">
94
+ <ul>%s</ul>
95
+ <p class="load-relation-posts %s" data-post-types="%s">%s</p>
96
+ <input type="hidden" name="%s" %s />
97
+ %s
98
+ </div>
99
+ </div>
100
+ <div class="%s"><ul>%s</ul></div>',
101
+ SCF_Config::PREFIX . 'relation-left',
102
+ SCF_Config::PREFIX . 'relation-children-select',
103
+ implode( '', $choices_li ),
104
+ $hide_class,
105
+ implode( ',', $post_type ),
106
+ esc_html__( 'Load more', 'smart-custom-fields' ),
107
+ esc_attr( $name ),
108
+ disabled( true, $disabled, false ),
109
+ implode( '', $hidden ),
110
+ SCF_Config::PREFIX . 'relation-right',
111
+ implode( '', $selected_li )
112
+ );
113
+ }
114
+
115
+ /**
116
+ * display_field_options
117
+ * @param int $group_key
118
+ * @param int $field_key
119
+ */
120
+ public function display_field_options( $group_key, $field_key ) {
121
+ ?>
122
+ <tr>
123
+ <th><?php esc_html_e( 'Post Types', 'smart-custom-fields' ); ?></th>
124
+ <td>
125
+ <?php
126
+ $post_types = get_post_types( array(
127
+ 'show_ui' => true,
128
+ ), 'objects' );
129
+ unset( $post_types['attachment'] );
130
+ unset( $post_types[SCF_Config::NAME] );
131
+ ?>
132
+ <?php foreach ( $post_types as $post_type => $post_type_object ) : ?>
133
+ <?php
134
+ $save_post_type = $this->get( 'post-type', $this->field );
135
+ $checked = ( is_array( $save_post_type ) && in_array( $post_type, $save_post_type ) ) ? 'checked="checked"' : ''; ?>
136
+ <input type="checkbox"
137
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'post-type' ) ); ?>[]"
138
+ value="<?php echo esc_attr( $post_type ); ?>"
139
+ <?php echo $checked; ?> /><?php echo esc_html( $post_type_object->labels->singular_name ); ?>
140
+ <?php endforeach; ?>
141
+ </td>
142
+ </tr>
143
+ <tr>
144
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
145
+ <td>
146
+ <input type="text"
147
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
148
+ class="widefat"
149
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
150
+ />
151
+ </td>
152
+ </tr>
153
+ <?php
154
+ }
155
+ }
classes/fields/class.field-select.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Select
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Select extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'select',
20
+ 'label' => __( 'Select', 'smart-custom-fields' ),
21
+ 'optgroup' => 'select-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+ $choices = $this->get_choices( $field['choices'] );
35
+
36
+ $form_field = '';
37
+ foreach ( $choices as $choice ) {
38
+ $choice = trim( $choice );
39
+ $form_field .= sprintf( '<option value="%1$s" %2$s>%1$s</option>',
40
+ esc_html( $choice ),
41
+ selected( $value, $choice, false )
42
+ );
43
+ }
44
+ return sprintf(
45
+ '<select name="%s" %s>%s</select>',
46
+ esc_attr( $name ),
47
+ disabled( true, $disabled, false ),
48
+ $form_field
49
+ );
50
+ }
51
+
52
+ /**
53
+ * display_field_options
54
+ * @param int $group_key
55
+ * @param int $field_key
56
+ */
57
+ public function display_field_options( $group_key, $field_key ) {
58
+ ?>
59
+ <tr>
60
+ <th><?php esc_html_e( 'Choices', 'smart-custom-fields' ); ?></th>
61
+ <td>
62
+ <textarea
63
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'choices' ) ); ?>"
64
+ class="widefat"
65
+ rows="5" /><?php echo esc_textarea( "\n" . $this->get_field_value( 'choices' ) ); ?></textarea>
66
+ </td>
67
+ </tr>
68
+ <tr>
69
+ <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
70
+ <td>
71
+ <input type="text"
72
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'default' ) ); ?>"
73
+ class="widefat"
74
+ value="<?php echo esc_attr( $this->get_field_value( 'default' ) ); ?>" />
75
+ </td>
76
+ </tr>
77
+ <tr>
78
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
79
+ <td>
80
+ <input type="text"
81
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
82
+ class="widefat"
83
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
84
+ />
85
+ </td>
86
+ </tr>
87
+ <?php
88
+ }
89
+ }
classes/fields/class.field-text.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Text
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Text extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'text',
20
+ 'label' => __( 'Text', 'smart-custom-fields' ),
21
+ 'optgroup' => 'basic-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+ return sprintf(
35
+ '<input type="text" name="%s" value="%s" class="widefat" %s />',
36
+ esc_attr( $name ),
37
+ esc_attr( $value ),
38
+ disabled( true, $disabled, false )
39
+ );
40
+ }
41
+
42
+ /**
43
+ * display_field_options
44
+ * @param int $group_key
45
+ * @param int $field_key
46
+ */
47
+ public function display_field_options( $group_key, $field_key ) {
48
+ ?>
49
+ <tr>
50
+ <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
51
+ <td>
52
+ <input type="text"
53
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'default' ) ); ?>"
54
+ class="widefat"
55
+ value="<?php echo esc_attr( $this->get_field_value( 'default' ) ); ?>" />
56
+ </td>
57
+ </tr>
58
+ <tr>
59
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
60
+ <td>
61
+ <input type="text"
62
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
63
+ class="widefat"
64
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
65
+ />
66
+ </td>
67
+ </tr>
68
+ <?php
69
+ }
70
+ }
classes/fields/class.field-textarea.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Textarea
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Textarea extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'textarea',
20
+ 'label' => __( 'Textarea', 'smart-custom-fields' ),
21
+ 'optgroup' => 'basic-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+ return sprintf(
35
+ '<textarea name="%s" rows="5" class="widefat" %s>%s</textarea>',
36
+ esc_attr( $name ),
37
+ disabled( true, $disabled, false ),
38
+ $value
39
+ );
40
+ }
41
+
42
+ /**
43
+ * display_field_options
44
+ * @param int $group_key
45
+ * @param int $field_key
46
+ */
47
+ public function display_field_options( $group_key, $field_key ) {
48
+ ?>
49
+ <tr>
50
+ <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
51
+ <td>
52
+ <textarea
53
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'default' ) ); ?>"
54
+ class="widefat"
55
+ rows="5"><?php echo esc_textarea( "\n" . $this->get_field_value( 'default' ) ); ?></textarea>
56
+ </td>
57
+ </tr>
58
+ <tr>
59
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
60
+ <td>
61
+ <input type="text"
62
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
63
+ class="widefat"
64
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
65
+ />
66
+ </td>
67
+ </tr>
68
+ <?php
69
+ }
70
+ }
classes/fields/class.field-wysiwyg.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Smart_Custom_Fields_Field_Wysiwyg
4
+ * Version : 1.0.0
5
+ * Author : Takashi Kitajima
6
+ * Created : October 7, 2014
7
+ * Modified :
8
+ * License : GPLv2
9
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+ */
11
+ class Smart_Custom_Fields_Field_Wysiwyg extends Smart_Custom_Fields_Field_Base {
12
+
13
+ /**
14
+ * init
15
+ * @return array ( name, label, optgroup )
16
+ */
17
+ protected function init() {
18
+ return array(
19
+ 'name' => 'wysiwyg',
20
+ 'label' => __( 'Wysiwyg', 'smart-custom-fields' ),
21
+ 'optgroup' => 'content-fields',
22
+ );
23
+ }
24
+
25
+ /**
26
+ * get_field
27
+ * @param array $field フィールドの情報
28
+ * @param int $index インデックス番号
29
+ * @param mixed $value 保存されている値(check のときだけ配列)
30
+ */
31
+ public function get_field( $field, $index, $value ) {
32
+ $name = $this->get_name_attribute( $field['name'], $index );
33
+ $disabled = $this->get_disable_attribute( $index );
34
+ return sprintf(
35
+ '<div class="wp-editor-wrap">
36
+ <div class="wp-media-buttons">%s</div>
37
+ <div class="wp-editor-container">
38
+ <textarea name="%s" rows="8" class="widefat smart-cf-wp-editor" %s>%s</textarea>
39
+ </div>
40
+ </div>',
41
+ $this->media_buttons(),
42
+ esc_attr( $name ),
43
+ disabled( true, $disabled, false ),
44
+ wp_richedit_pre( $value )
45
+ );
46
+ }
47
+
48
+ /**
49
+ * display_field_options
50
+ * @param int $group_key
51
+ * @param int $field_key
52
+ */
53
+ public function display_field_options( $group_key, $field_key ) {
54
+ ?>
55
+ <tr>
56
+ <th><?php esc_html_e( 'Default', 'smart-custom-fields' ); ?></th>
57
+ <td>
58
+ <textarea
59
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'default' ) ); ?>"
60
+ class="widefat"
61
+ rows="5"><?php echo esc_textarea( "\n" . $this->get_field_value( 'default' ) ); ?></textarea>
62
+ </td>
63
+ </tr>
64
+ <tr>
65
+ <th><?php esc_html_e( 'Notes', 'smart-custom-fields' ); ?></th>
66
+ <td>
67
+ <input type="text"
68
+ name="<?php echo esc_attr( $this->get_field_name( $group_key, $field_key, 'notes' ) ); ?>"
69
+ class="widefat"
70
+ value="<?php echo esc_attr( $this->get_field_value( 'notes' ) ); ?>"
71
+ />
72
+ </td>
73
+ </tr>
74
+ <?php
75
+ }
76
+
77
+ protected function media_buttons( $editor_id = 'content' ) {
78
+ $img = '<span class="wp-media-buttons-icon"></span> ';
79
+ return sprintf( '<a href="#" class="button insert-media add_media" data-editor="%s" title="%s">%s</a>',
80
+ esc_attr( $editor_id ),
81
+ esc_attr__( 'Add Media' ),
82
+ $img . __( 'Add Media' )
83
+ );
84
+ }
85
+ }
css/editor.css ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * editor.css
3
+ * Version : 1.0.0
4
+ * Author : Takashi Kitajima
5
+ * Created : September 23, 2014
6
+ * Modified :
7
+ * License : GPLv2
8
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ */
10
+
11
+ /** ==================================================
12
+ * #normal-sortables
13
+ */
14
+ .smart-cf-meta-box {
15
+ margin: 0 -12px;
16
+ }
17
+
18
+ /** ==================================================
19
+ * .smart-cf-meta-box-table
20
+ */
21
+ .smart-cf-meta-box-table {
22
+ background: #fff;
23
+ border-bottom: #eee solid 1px;
24
+ padding: 10px 12px;
25
+ }
26
+ .smart-cf-meta-box-table table {
27
+ width: 100%;
28
+ }
29
+ .smart-cf-meta-box-table th,
30
+ .smart-cf-meta-box-table td {
31
+ font-weight: normal;
32
+ text-align: left;
33
+ padding: 7px 5px;
34
+ vertical-align: top;
35
+ }
36
+ .smart-cf-meta-box-table th {
37
+ width: 25%;
38
+ }
39
+ .smart-cf-meta-box-table td label {
40
+ margin-right: 10px;
41
+ }
42
+ .smart-cf-meta-box-table .wp-editor-container {
43
+ clear: both;
44
+ }
45
+ .smart-cf-meta-box-table td .description {
46
+ font-size: 12px;
47
+ margin: 10px 0 0;
48
+ }
49
+
50
+ /** ==================================================
51
+ * .smart-cf-meta-box-repeat-tables
52
+ */
53
+ .smart-cf-meta-box-repeat-tables .smart-cf-meta-box-table > .smart-cf-icon-handle {
54
+ top: 5px;
55
+ }
56
+
57
+ /** ==================================================
58
+ * relation
59
+ */
60
+ .smart-cf-meta-box-table .smart-cf-relation-left,
61
+ .smart-cf-meta-box-table .smart-cf-relation-right {
62
+ border: #ddd solid 1px;
63
+ border-radius: 3px;
64
+ height: 160px;
65
+ overflow: auto;
66
+ }
67
+ .smart-cf-meta-box-table .smart-cf-relation-left ul,
68
+ .smart-cf-meta-box-table .smart-cf-relation-right ul {
69
+ list-style: none;
70
+ margin: 0;
71
+ padding: 0;
72
+ }
73
+ .smart-cf-meta-box-table .smart-cf-relation-left ul li,
74
+ .smart-cf-meta-box-table .smart-cf-relation-right ul li {
75
+ background: #fff;
76
+ border-bottom: #eee solid 1px;
77
+ color: #0074a2;
78
+ margin: 0;
79
+ padding: 5px 10px;
80
+ position: relative;
81
+ }
82
+ .smart-cf-meta-box-table .smart-cf-relation-left {
83
+ float: left;
84
+ width: 47%;
85
+ }
86
+ .smart-cf-meta-box-table .smart-cf-relation-left ul li {
87
+ cursor: pointer;
88
+ }
89
+ .smart-cf-meta-box-table .smart-cf-relation-left ul li:hover {
90
+ background: #e4f6fd;
91
+ }
92
+ .smart-cf-meta-box-table .smart-cf-relation-left .load-relation-posts {
93
+ background: #e4f6fd;
94
+ cursor: pointer;
95
+ margin: 0;
96
+ padding: 6px 10px;
97
+ text-align: center;
98
+ }
99
+ .smart-cf-meta-box-table .smart-cf-relation-left .load-relation-posts:hover {
100
+ background: #c1ebfc;
101
+ }
102
+ .smart-cf-meta-box-table .smart-cf-relation-right {
103
+ float: right;
104
+ width: 50%;
105
+ }
106
+ .smart-cf-meta-box-table .smart-cf-relation-right ul li .relation-remove {
107
+ cursor: pointer;
108
+ display: block;
109
+ padding: 2px 8px;
110
+ position: absolute;
111
+ top: 2px;
112
+ right: 6px;
113
+ }
114
+ .smart-cf-meta-box-table .smart-cf-relation-right ul li {
115
+ padding-right: 15px;
116
+ }
117
+
118
+ /** ==================================================
119
+ * .smart-cf-upload-image, .smart-cf-upload-file
120
+ */
121
+ .smart-cf-upload-image,
122
+ .smart-cf-upload-file {
123
+ display: inline-block;
124
+ position: relative;
125
+ }
126
+ .smart-cf-upload-image img,
127
+ .smart-cf-upload-file img {
128
+ margin-top: 5px;
129
+ max-width: 100%;
130
+ vertical-align: top;
131
+ }
132
+ .smart-cf-upload-image .btn-remove-image,
133
+ .smart-cf-upload-file .btn-remove-file {
134
+ background: red;
135
+ border-radius: 3px;
136
+ color: #fff;
137
+ cursor: pointer;
138
+ display: block;
139
+ font-size: 10px;
140
+ padding: 2px 6px;
141
+ position: absolute;
142
+ left: 5px;
143
+ bottom: 5px;
144
+ }
145
+
146
+ /** ==================================================
147
+ * .hide
148
+ */
149
+ .smart-cf-upload-image.hide,
150
+ .smart-cf-upload-file.hide,
151
+ .smart-cf-upload-image .btn-remove-image.hide,
152
+ .smart-cf-upload-file .btn-remove-file.hide,
153
+ .load-relation-posts.hide {
154
+ display: none;
155
+ }
156
+
157
+ /** ==================================================
158
+ * classes
159
+ */
160
+ .smart-cf-icon-handle {
161
+ background: url( ../images/handle.png ) no-repeat;
162
+ cursor: move;
163
+ display: inline-block;
164
+ margin-right: 10px;
165
+ height: 10px;
166
+ width: 10px;
167
+ overflow: hidden;
168
+ position: relative;
169
+ }
css/settings.css ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * settings.css
3
+ * Version : 1.0.0
4
+ * Author : Takashi Kitajima
5
+ * Created : September 23, 2014
6
+ * Modified :
7
+ * License : GPLv2
8
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ */
10
+
11
+ /** ==================================================
12
+ * #normal-sortables
13
+ */
14
+ #normal-sortables {
15
+ display: none;
16
+ }
17
+
18
+ /** ==================================================
19
+ * .btn-add-group
20
+ */
21
+ .smart-cf-fields-wrapper .btn-add-group {
22
+ margin-top: 10px;
23
+ }
24
+
25
+ /** ==================================================
26
+ * .smart-cf-group
27
+ */
28
+ .smart-cf-group {
29
+ background: #f5f5f5;
30
+ border: #ddd solid 1px;
31
+ margin: 10px 0 0;
32
+ padding: 10px;
33
+ position: relative;
34
+ }
35
+ .smart-cf-group .smart-cf-require {
36
+ color: #f60;
37
+ font-size: 90%;
38
+ margin-left: 3px;
39
+ }
40
+
41
+ /**
42
+ * .btn-remove-group
43
+ */
44
+ .smart-cf-group .btn-remove-group {
45
+ cursor: pointer;
46
+ position: absolute;
47
+ top: 12px;
48
+ right: 10px;
49
+ }
50
+
51
+ /**
52
+ * .btn-add-field
53
+ */
54
+ .smart-cf-group .btn-add-field {
55
+ margin-top: 5px;
56
+ }
57
+
58
+ /**
59
+ * .smart-cf-group-repeat
60
+ */
61
+ .smart-cf-group .smart-cf-group-repeat {
62
+ cursor: move;
63
+ margin: 0 0 5px;
64
+ }
65
+
66
+ /**
67
+ * .smart-cf-group-names
68
+ */
69
+ .smart-cf-group .smart-cf-group-names {
70
+ width: 100%;
71
+ }
72
+ .smart-cf-group .smart-cf-group-names th {
73
+ text-align: left;
74
+ width: 20%;
75
+ }
76
+
77
+ /**
78
+ * .smart-cf-alert
79
+ */
80
+ .smart-cf-alert {
81
+ color: #f60;
82
+ display: block;
83
+ font-size: 90%;
84
+ margin-top: 2px 0;
85
+ }
86
+
87
+ /** ==================================================
88
+ * .smart-cf-field
89
+ */
90
+ .smart-cf-group .smart-cf-field {
91
+ background: #fff;
92
+ border: #ddd solid 1px;
93
+ margin: 5px 0 0;
94
+ padding: 10px;
95
+ }
96
+ .smart-cf-group .smart-cf-field:first-child {
97
+ margin-top: 0;
98
+ }
99
+ .smart-cf-group .smart-cf-field table {
100
+ border-collapse: collapse;
101
+ width: 100%;
102
+ }
103
+ .smart-cf-group .smart-cf-field table th,
104
+ .smart-cf-group .smart-cf-field table td {
105
+ padding: 5px 0;
106
+ }
107
+ .smart-cf-group .smart-cf-field table th {
108
+ font-weight: normal;
109
+ padding-right: 15px;
110
+ text-align: left;
111
+ vertical-align: top;
112
+ width: 15%;
113
+ }
114
+ .smart-cf-group .smart-cf-field table table {
115
+ margin: -5px 0;
116
+ }
117
+
118
+ /**
119
+ * .btn-remove-field
120
+ */
121
+ .smart-cf-group .smart-cf-field .btn-remove-field {
122
+ cursor: move;
123
+ position: relative;
124
+ overflow: hidden;
125
+ *zoom: 1;
126
+ }
127
+ .smart-cf-group .smart-cf-field .btn-remove-field b {
128
+ float: right;
129
+ }
130
+
131
+ /** ==================================================
132
+ * #smart-cf-meta-box-condition
133
+ */
134
+ #smart-cf-meta-box-condition label {
135
+ display: block;
136
+ margin: 0 0 5px;
137
+ }
138
+
139
+ /** ==================================================
140
+ * .hide
141
+ */
142
+ .smart-cf-group .smart-cf-field table tr.hide,
143
+ .smart-cf-group.hide,
144
+ .smart-cf-group .btn-add-field.hide,
145
+ .smart-cf-group .smart-cf-group-names.hide,
146
+ .smart-cf-group .smart-cf-field.hide,
147
+ .smart-cf-group .smart-cf-field table.hide {
148
+ display: none;
149
+ }
images/handle.png ADDED
Binary file
js/editor-relation.js ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * editor.js
3
+ * Version : 1.0.0
4
+ * Author : Takashi Kitajima
5
+ * Created : September 30, 2014
6
+ * Modified :
7
+ * License : GPLv2
8
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ */
10
+ jQuery( function( $ ) {
11
+
12
+ var table_class = '.smart-cf-meta-box-table';
13
+
14
+ /**
15
+ * 読み込みボタン
16
+ */
17
+ $( '.smart-cf-meta-box .load-relation-posts' )
18
+ .data( 'click_count', 0 )
19
+ .click( function() {
20
+ var parent = $( this ).parents( '.smart-cf-meta-box-table' );
21
+ var click_count = $( this ).data( 'click_count' );
22
+ var post_types = $( this ).data( 'post-types' );
23
+ var btn_load = $( this );
24
+ click_count ++;
25
+ btn_load.data( 'click_count', click_count );
26
+ var btn_load_text = btn_load.text();
27
+ btn_load.text( 'Now loading...' );
28
+
29
+ $.post( smart_cf_relation.endpoint, {
30
+ action : smart_cf_relation.action,
31
+ nonce : smart_cf_relation.nonce,
32
+ click_count: click_count,
33
+ post_types : post_types
34
+ },
35
+ function( response ) {
36
+ btn_load.addClass( 'hide' );
37
+ $( response ).each( function( i, e ) {
38
+ parent.find( '.smart-cf-relation-children-select ul' ).append(
39
+ $( '<li />' )
40
+ .attr( 'data-id', this.ID )
41
+ .text( this.post_title )
42
+ );
43
+ } );
44
+ if ( response ) {
45
+ btn_load.text( btn_load_text );
46
+ btn_load.removeClass( 'hide' );
47
+ }
48
+ }
49
+ );
50
+ return false;
51
+ } );
52
+
53
+ /**
54
+ * 選択肢
55
+ */
56
+ var choices_li = '.smart-cf-relation-children-select li';
57
+ $( '.smart-cf-meta-box' ).on( 'click', choices_li, function() {
58
+ var id = $( this ).data( 'id' );
59
+ var parent = $( this ).parents( table_class );
60
+ if ( parent.find( '.smart-cf-relation-right li[data-id="' + id + '"]' ).length === 0 ) {
61
+ var clone = $( this ).clone();
62
+ clone
63
+ .prepend( $( '<span class="smart-cf-icon-handle"></span>' ) )
64
+ .append( $( '<span class="relation-remove">-</span>' ) );
65
+ parent.find( '.smart-cf-relation-right ul' ).append( clone );
66
+ update_relation_value( $( this ).parents( 'tr' ) );
67
+ }
68
+ } );
69
+
70
+ /**
71
+ * 選択済み項目の削除
72
+ */
73
+ var relation_remove = '.smart-cf-relation-right li .relation-remove';
74
+ $( '.smart-cf-meta-box' ).on( 'click', relation_remove, function() {
75
+ var tr = $( this ).parents( 'tr' );
76
+ $( this ).parent().remove();
77
+ update_relation_value( tr );
78
+ } );
79
+
80
+ /**
81
+ * update_relation_value
82
+ * @param dom tr
83
+ */
84
+ function update_relation_value( tr ) {
85
+ var hidden = tr.find( 'input[type="hidden"]' );
86
+ hidden.each( function( i, e ) {
87
+ if ( i !== 0 ) {
88
+ $( this ).remove();
89
+ }
90
+ } );
91
+ tr.find( '.smart-cf-relation-right li' ).each( function( i, e ) {
92
+ var hidden_box = $( this ).parents( table_class ).find( '.smart-cf-relation-children-select' );
93
+ var id = $( this ).data( 'id' );
94
+ var clone = hidden.first().clone();
95
+ var name = clone.attr( 'name' );
96
+ clone.attr( 'name', name + '[]' );
97
+ clone.val( id );
98
+ hidden_box.append( clone );
99
+ } );
100
+ }
101
+
102
+ /**
103
+ * sortable
104
+ */
105
+ $( '.smart-cf-meta-box .smart-cf-relation-right ul' ).sortable( {
106
+ handle: '.smart-cf-icon-handle',
107
+ update: function() {
108
+ update_relation_value( $( this ).parents( 'tr' ) );
109
+ }
110
+ } );
111
+ } );
js/editor-wysiwyg.js ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * editor-wysiwyg.js
3
+ * Version : 1.0.0
4
+ * Author : Takashi Kitajima
5
+ * Created : September 28, 2014
6
+ * Modified :
7
+ * License : GPLv2
8
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ */
10
+ jQuery( function( $ ) {
11
+
12
+ /**
13
+ * グループ追加ボタンを押したときに発火。
14
+ * wysiwyg エディター用のテキストエリアがあったら wysiwyg 化する。
15
+ */
16
+ $( document ).on( 'smart-cf-after-add-group', function( e, button ) {
17
+ var parent = $( button ).parents( '.smart-cf-meta-box-repeat-tables' );
18
+ parent.find( '.smart-cf-wp-editor' ).each( function( i, e ) {
19
+ if ( $( this ).css( 'display' ) !== 'none' ) {
20
+ var editor_id = $( this ).attr( 'id' );
21
+ if ( editor_id ) {
22
+ $( this ).parents( '.wp-editor-wrap' ).find( 'a.add_media' ).attr( 'data-editor', editor_id );
23
+ tinymce.execCommand( 'mceAddEditor', false, editor_id );
24
+ }
25
+ }
26
+ } );
27
+ } );
28
+
29
+ /**
30
+ * ドラッグしたときに発火。
31
+ * wysiwyg エディター用のテキストエリアをオフる。
32
+ */
33
+ $( document ).on( 'smart-cf-repeat-table-sortable-start', function( e, ui ) {
34
+ $( ui ).find( '.smart-cf-wp-editor' ).each( function( i, e ) {
35
+ var editor_id = $( this ).attr( 'id' );
36
+ if ( editor_id ) {
37
+ tinymce.execCommand( 'mceRemoveEditor', false, editor_id );
38
+ }
39
+ } );
40
+ } );
41
+
42
+ /**
43
+ * ドロップしたときに発火。
44
+ * wysiwyg エディター用のテキストエリアを wysiwyg 化する。
45
+ */
46
+ $( document ).on( 'smart-cf-repeat-table-sortable-stop', function( e, ui ) {
47
+ $( ui ).find( '.smart-cf-wp-editor' ).each( function( i, e ) {
48
+ var editor_id = $( this ).attr( 'id' );
49
+ if ( editor_id ) {
50
+ tinymce.execCommand( 'mceAddEditor', false, editor_id );
51
+ }
52
+ } );
53
+ } );
54
+
55
+ } );
js/editor.js ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * editor.js
3
+ * Version : 1.0.0
4
+ * Author : Takashi Kitajima
5
+ * Created : September 23, 2014
6
+ * Modified :
7
+ * License : GPLv2
8
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ */
10
+ jQuery( function( $ ) {
11
+
12
+ $( '.smart-cf-meta-box' ).each( function( i, e ) {
13
+ var wrapper = $( e );
14
+ var btn_add_repeat_group = wrapper.find( '.btn-add-repeat-group' );
15
+ var btn_remove_repeat_group = wrapper.find( '.btn-remove-repeat-group' );
16
+ var table_class = '.smart-cf-meta-box-table';
17
+ var cnt = wrapper.find( table_class ).length;
18
+
19
+ /**
20
+ * ロード時に wysiwyg エディター用のテキストエリアがあったら wysiwyg 化する。
21
+ */
22
+ wrapper.find( '.smart-cf-wp-editor' ).each( function( i, e ) {
23
+ if ( $( this ).parents( table_class ).css( 'display' ) !== 'none' ) {
24
+ $( this ).attr( 'id', 'smart-cf-wysiwyg-' + cnt + i );
25
+ var editor_id = $( this ).attr( 'id' );
26
+ $( this ).parents( '.wp-editor-wrap' ).find( 'a.add_media' ).attr( 'data-editor', editor_id );
27
+ tinymce.execCommand( 'mceAddEditor', false, editor_id );
28
+ }
29
+ } );
30
+
31
+ /**
32
+ * グループ追加ボタン
33
+ */
34
+ btn_add_repeat_group.click( function( e ) {
35
+ cnt ++;
36
+ var parent = $( this ).parents( '.smart-cf-meta-box-repeat-tables' );
37
+ add_repeat_group( $( this ) );
38
+ } );
39
+
40
+ /**
41
+ * グループ削除ボタン
42
+ */
43
+ btn_remove_repeat_group.click( function() {
44
+ var table = $( this ).parents( table_class );
45
+ table.fadeOut( 'fast', function() {
46
+ $( this ).remove();
47
+ } );
48
+ var tables = $( this ).parents( '.smart-cf-meta-box-repeat-tables' );
49
+ if ( tables.find( table_class ).length === 2 ) {
50
+ cnt ++;
51
+ add_repeat_group( $( this ) );
52
+ }
53
+ } );
54
+
55
+ function add_repeat_group( button ) {
56
+ var tables = button.parents( '.smart-cf-meta-box-repeat-tables' );
57
+ var table = tables.find( table_class ).first();
58
+ var clone = table.clone( true, true ).hide();
59
+
60
+ clone.find( 'input, select, textarea' ).each( function( i, e ) {
61
+ $( this ).attr( 'name',
62
+ $( this ).attr( 'name' ).replace(
63
+ /^(smart-custom-fields\[.+\])\[_\]/,
64
+ '$1[_' + cnt + ']'
65
+ )
66
+ );
67
+ $( this ).removeAttr( 'disabled' );
68
+ } );
69
+
70
+ clone.find( '.smart-cf-wp-editor' ).each( function( i, e ) {
71
+ $( this ).attr( 'id', 'smart-cf-wysiwyg-' + cnt + i );
72
+ } );
73
+
74
+ button.parent().after( clone.fadeIn( 'fast' ) );
75
+ button.trigger( 'smart-cf-after-add-group', button );
76
+ }
77
+
78
+ /**
79
+ * 画像アップローダー
80
+ */
81
+ wrapper.find( '.btn-add-image' ).click( function( e ) {
82
+ e.preventDefault();
83
+ var custom_uploader_image;
84
+ var upload_button = $( this );
85
+ if ( custom_uploader_image ) {
86
+ custom_uploader_image.open();
87
+ return;
88
+ }
89
+ custom_uploader_image = wp.media( {
90
+ title : smart_cf_uploader.image_uploader_title,
91
+ library: {
92
+ type: 'image'
93
+ },
94
+ button : {
95
+ text: smart_cf_uploader.image_uploader_title
96
+ },
97
+ multiple: false
98
+ } );
99
+
100
+ custom_uploader_image.on( 'select', function() {
101
+ var images = custom_uploader_image.state().get( 'selection' );
102
+ images.each( function( file ){
103
+ var image_area = upload_button.parent().find( '.smart-cf-upload-image' );
104
+ image_area.find( 'img' ).remove();
105
+ image_area.prepend(
106
+ '<img src="' + file.toJSON().url + '" />'
107
+ );
108
+ image_area.removeClass( 'hide' );
109
+ upload_button.parent().find( 'input[type="hidden"]' ).val( file.toJSON().id );
110
+ } );
111
+ } );
112
+
113
+ custom_uploader_image.open();
114
+ } );
115
+
116
+ /**
117
+ * 画像削除ボタン
118
+ */
119
+ wrapper.find( '.smart-cf-upload-image' ).hover( function() {
120
+ $( this ).find( '.btn-remove-image' ).fadeIn( 'fast', function() {
121
+ $( this ).removeClass( 'hide' );
122
+ } );
123
+ }, function() {
124
+ $( this ).find( '.btn-remove-image' ).fadeOut( 'fast', function() {
125
+ $( this ).addClass( 'hide' );
126
+ } );
127
+ } );
128
+ wrapper.find( '.btn-remove-image' ).click( function() {
129
+ $( this ).parent().find( 'img' ).remove();
130
+ $( this ).parent().siblings( 'input[type="hidden"]' ).val( '' );
131
+ $( this ).parent().addClass( 'hide' );
132
+ } );
133
+
134
+ /**
135
+ * ファイルアップローダー
136
+ */
137
+ wrapper.find( '.btn-add-file' ).click( function( e ) {
138
+ e.preventDefault();
139
+ var custom_uploader_file;
140
+ var upload_button = $( this );
141
+ if ( custom_uploader_file ) {
142
+ custom_uploader_file.open();
143
+ return;
144
+ }
145
+ custom_uploader_file = wp.media( {
146
+ title : smart_cf_uploader.file_uploader_title,
147
+ button: {
148
+ text: smart_cf_uploader.file_uploader_title
149
+ },
150
+ multiple: false
151
+ } );
152
+
153
+ custom_uploader_file.on( 'select', function() {
154
+ var images = custom_uploader_file.state().get( 'selection' );
155
+ images.each( function( file ){
156
+ var image_area = upload_button.parent().find( '.smart-cf-upload-file' );
157
+ image_area.find( 'img' ).remove();
158
+ image_area.prepend(
159
+ '<a href="' + file.toJSON().url + '" target="_blank"><img src="' + file.toJSON().icon + '" /></a>'
160
+ );
161
+ image_area.removeClass( 'hide' );
162
+ upload_button.parent().find( 'input[type="hidden"]' ).val( file.toJSON().id );
163
+ } );
164
+ } );
165
+
166
+ custom_uploader_file.open();
167
+ } );
168
+
169
+ /**
170
+ * ファイル削除ボタン
171
+ */
172
+ wrapper.find( '.smart-cf-upload-file' ).hover( function() {
173
+ $( this ).find( '.btn-remove-file' ).fadeIn( 'fast', function() {
174
+ $( this ).removeClass( 'hide' );
175
+ } );
176
+ }, function() {
177
+ $( this ).find( '.btn-remove-file' ).fadeOut( 'fast', function() {
178
+ $( this ).addClass( 'hide' );
179
+ } );
180
+ } );
181
+ wrapper.find( '.btn-remove-file' ).click( function() {
182
+ $( this ).parent().find( 'img' ).remove();
183
+ $( this ).parent().siblings( 'input[type="hidden"]' ).val( '' );
184
+ $( this ).parent().addClass( 'hide' );
185
+ } );
186
+
187
+ /**
188
+ * sortable
189
+ */
190
+ wrapper.find( '.smart-cf-meta-box-repeat-tables' ).sortable( {
191
+ handle: '.smart-cf-icon-handle',
192
+ items : '> .smart-cf-meta-box-table:not( :first-child )',
193
+ start : function( e, ui ) {
194
+ $( this ).trigger( 'smart-cf-repeat-table-sortable-start', ui.item );
195
+ },
196
+ stop : function( e, ui ) {
197
+ $( this ).trigger( 'smart-cf-repeat-table-sortable-stop', ui.item );
198
+ },
199
+ } );
200
+
201
+ } );
202
+ } );
js/settings.js ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * settings.js
3
+ * Version : 1.0.0
4
+ * Author : Takashi Kitajima
5
+ * Created : September 23, 2014
6
+ * Modified :
7
+ * License : GPLv2
8
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+ */
10
+ jQuery( function( $ ) {
11
+ $( '.smart-cf-fields-wrapper' ).each( function( i, e ) {
12
+ var wrapper = $( e );
13
+ var btn_add_group = wrapper.find( '.btn-add-group' );
14
+ var btn_remove_group = wrapper.find( '.btn-remove-group b' );
15
+ var btn_add_field = wrapper.find( '.btn-add-field' );
16
+ var btn_remove_field = wrapper.find( '.btn-remove-field b' );
17
+ var group_class = '.smart-cf-group';
18
+ var field_class = '.smart-cf-field';
19
+ var duplicate_alert_class = '.smart-cf-duplicate-alert';
20
+ var options = wrapper.find( '.smart-cf-field-options' );
21
+ var cnt = wrapper.find( field_class ).length;
22
+
23
+ /**
24
+ * 重複エラーメッセージ表示 & 重複時の更新不可
25
+ */
26
+ wrapper.find( 'input[class="smart-cf-group-name"], input[class="smart-cf-field-name"]' ).keyup( function() {
27
+ var val = $( this ).val();
28
+ var cnt = 0;
29
+ wrapper.find( 'input[class="smart-cf-group-name"], input[class="smart-cf-field-name"]' ).each( function( i, e ) {
30
+ if ( val === $( this ).val() && val !== '' ) {
31
+ cnt ++;
32
+ }
33
+ } );
34
+ if ( cnt > 1 ) {
35
+ if ( $( this ).siblings( duplicate_alert_class ).length < 1 ) {
36
+ $( this ).after(
37
+ $( '<div class="smart-cf-alert" />' )
38
+ .addClass( duplicate_alert_class.replace( '.', '' ) )
39
+ .text( smart_cf_settings.duplicate_alert )
40
+ );
41
+ }
42
+ cnt = 0;
43
+ } else {
44
+ $( this ).siblings( duplicate_alert_class ).remove();
45
+ }
46
+
47
+ if ( $( duplicate_alert_class ).length ) {
48
+ $( '#publish' ).attr( 'disabled', 'disabled' );
49
+ } else {
50
+ $( '#publish' ).removeAttr( 'disabled' );
51
+ }
52
+ } );
53
+
54
+ /**
55
+ * sortable
56
+ */
57
+ $( '.smart-cf-groups' ).sortable( {
58
+ cursor: 'move',
59
+ handle: '.smart-cf-group-repeat'
60
+ } );
61
+ $( '.smart-cf-fields' ).sortable( {
62
+ cursor: 'move',
63
+ handle: '.btn-remove-field'
64
+ } );
65
+
66
+ /**
67
+ * フィールドの開閉
68
+ */
69
+ $( '.btn-remove-field' ).click( function() {
70
+ var btn_remove_field_slide = $( this );
71
+ var table = $( this ).parents( field_class ).find( 'table' );
72
+ if ( table.hasClass( 'hide' ) ) {
73
+ btn_remove_field_slide.find( 'span' ).text( '' );
74
+ table.fadeIn( 'fast', function() {
75
+ $( this ).removeClass( 'hide' );
76
+ } );
77
+ } else {
78
+ var label = table.find( '.smart-cf-field-label' ).val();
79
+ if ( !label ) {
80
+ label = table.find( '.smart-cf-field-name' ).val();
81
+ }
82
+ table.fadeOut( 'fast', function() {
83
+ $( this ).addClass( 'hide' );
84
+ btn_remove_field_slide.find( 'span' ).text( label );
85
+ } );
86
+ }
87
+ } );
88
+
89
+ /**
90
+ * グループ追加ボタン
91
+ */
92
+ btn_add_group.click( function() {
93
+ cnt ++;
94
+ var group = wrapper.find( group_class );
95
+ var group_clone = group.first().clone( true, true );
96
+ group.last().after( group_clone.fadeIn( 'fast', function() {
97
+ $( this ).removeClass( 'hide' );
98
+ } ) );
99
+
100
+ var field = group_clone.find( field_class );
101
+ var field_clone = field.first().clone( true, true );
102
+ field.last().after( field_clone.removeClass( 'hide' ) );
103
+
104
+ group_clone.find( 'input, select, textarea' ).each( function( i, e ) {
105
+ $( this ).attr( 'name',
106
+ $( this ).attr( 'name' ).replace(
107
+ /^(smart-custom-fields)\[\d+\]/,
108
+ '$1[' + cnt + ']'
109
+ )
110
+ );
111
+ } );
112
+
113
+ field_clone.find( 'input, select, textarea' ).each( function( i, e ) {
114
+ $( this ).attr( 'name',
115
+ $( this ).attr( 'name' ).replace(
116
+ /^(smart-custom-fields)\[.+?\](\[fields\])\[\d+?\]/,
117
+ '$1[' + cnt + ']$2[' + cnt + ']'
118
+ )
119
+ );
120
+ } );
121
+ } );
122
+
123
+ /**
124
+ * グループ削除ボタン
125
+ */
126
+ btn_remove_group.click( function() {
127
+ $( this ).parents( group_class ).fadeOut( 'fast', function() {
128
+ $( this ).remove();
129
+ } );
130
+ } );
131
+
132
+ /**
133
+ * フィールド追加ボタン
134
+ */
135
+ btn_add_field.click( function() {
136
+ cnt ++;
137
+ var group = $( this ).parents( group_class );
138
+ var field = group.find( field_class );
139
+ var clone = field.first().clone( true, true );
140
+ field.last().after( clone.fadeIn( 'fast', function() {
141
+ $( this ).removeClass( 'hide' );
142
+ } ) );
143
+
144
+ clone.find( 'input, select, textarea' ).each( function( i, e ) {
145
+ $( this ).attr( 'name',
146
+ $( this ).attr( 'name' ).replace(
147
+ /^(smart-custom-fields\[.+?\]\[fields\])\[\d+?\]/,
148
+ '$1[' + cnt + ']'
149
+ )
150
+ );
151
+ } );
152
+ } );
153
+
154
+ /**
155
+ * フィールド削除ボタン
156
+ */
157
+ btn_remove_field.click( function() {
158
+ $( this ).parents( field_class ).fadeOut( 'fast', function() {
159
+ $( this ).remove();
160
+ } );
161
+ } );
162
+
163
+ /**
164
+ * 選択項目オプション
165
+ */
166
+ options.find( 'input, textarea, select' ).attr( 'disabled', 'disabled' );
167
+ wrapper.find( '.smart-cf-field-select' ).each( function( i, e ) {
168
+ var selected_type = $( this ).val();
169
+ $( this ).parents( field_class ).find( '.smart-cf-field-options-' + selected_type )
170
+ .removeClass( 'hide' )
171
+ .find( 'input, textarea, select' ).removeAttr( 'disabled' );
172
+ } );
173
+
174
+ wrapper.find( '.smart-cf-field-select' ).change( function() {
175
+ var field = $( this ).parents( field_class );
176
+ var val = $( this ).val();
177
+
178
+ var hide_options = field.find( '.smart-cf-field-options' );
179
+ hide_options.addClass( 'hide' );
180
+ hide_options.find( 'input, textarea, select' ).attr( 'disabled', 'disabled' );
181
+
182
+ var show_options = field.find( '.smart-cf-field-options-' + val );
183
+ show_options.find( 'input, textarea, select' ).removeAttr( 'disabled' );
184
+ show_options.removeClass( 'hide' );
185
+ } );
186
+
187
+ /**
188
+ * リピートボタンクリック時
189
+ */
190
+ wrapper.find( '.smart-cf-group-repeat input' ).click( function() {
191
+ var group = $( this ).parents( group_class );
192
+ var names = group.find( '.smart-cf-group-names' );
193
+ var btn_add_field = group.find( '.btn-add-field' );
194
+ if ( $( this ).prop( 'checked' ) ) {
195
+ names.removeClass( 'hide' );
196
+ btn_add_field.removeClass( 'hide' );
197
+ } else {
198
+ names.addClass( 'hide' );
199
+ btn_add_field.addClass( 'hide' );
200
+ }
201
+ } );
202
+
203
+ /**
204
+ * フィールド名入力ボックス
205
+ */
206
+ wrapper.find( '.smart-cf-field-label' ).focus( function() {
207
+ var field = $( this ).parents( '.smart-cf-field' );
208
+ var name_val = field.find( '.smart-cf-field-name' ).val();
209
+ var label_val = $( this ).val();
210
+ if ( name_val && !label_val ) {
211
+ $( this ).val( name_val );
212
+ }
213
+ } );
214
+ } );
215
+ } );
readme.txt ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Smart Custom Fields ===
2
+ Contributors: inc2734
3
+ Donate link: http://www.amazon.co.jp/registry/wishlist/39ANKRNSTNW40
4
+ Tags: plugin, custom field, custom, field, meta, meta field, repeat, repeatable
5
+ Requires at least: 3.9
6
+ Tested up to: 4.0
7
+ Stable tag: 1.0.0
8
+ License: GPLv2
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Smart Custom Fields is a simple plugin that management custom fields.
12
+
13
+ == Description ==
14
+
15
+ Smart Custom Fields is a simple plugin that management custom fields.
16
+
17
+ * This plugin has loop field function.
18
+ * Supported metadata revision.
19
+ * Supported metadata preview.
20
+
21
+ https://www.youtube.com/watch?v=WxPZurn0yvI
22
+
23
+ = Field Types =
24
+
25
+ * Text
26
+ * Textarea
27
+ * Radio
28
+ * Select
29
+ * Checkbox
30
+ * Wysiwyg editor
31
+ * Image
32
+ * File
33
+ * Relation
34
+
35
+ = How to get meta data ? =
36
+
37
+ * SCF::get( 'field-name' )
38
+ This method can get any meta data.
39
+
40
+ * SCF::get( 'group-name' )
41
+ This method can get meta data of any group.
42
+
43
+ * SCF::gets()
44
+ This method can get all meta data.
45
+
46
+ = GitHub =
47
+
48
+ https://github.com/inc2734/smart-custom-fields/
49
+
50
+ == Installation ==
51
+
52
+ 1. Upload `Smart Custom Fields` to the `/wp-content/plugins/` directory
53
+ 1. Activate the plugin through the 'Plugins' menu in WordPress
54
+ 1. You can setting custom fields in 'Smart Custom Fields' page.
55
+
56
+ == Screenshots ==
57
+
58
+ 1. Smart Custom Fields settings page.
59
+ 2. Post edit page.
60
+
61
+ == Changelog ==
62
+
63
+ = 1.0.0 =
64
+ * Initial release.
smart-custom-fields.php ADDED
@@ -0,0 +1,514 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin name: Smart Custom Fields
4
+ * Plugin URI: https://github.com/inc2734/smart-custom-fields/
5
+ * Description: Smart Custom Fields is a simple plugin that management custom fields.
6
+ * Version: 1.0.0
7
+ * Author: Takashi Kitajima
8
+ * Author URI: http://2inc.org
9
+ * Created: October 9, 2014
10
+ * Modified:
11
+ * Text Domain: smart-custom-fields
12
+ * Domain Path: /languages/
13
+ * License: GPLv2
14
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
15
+ */
16
+ class Smart_Custom_Fields {
17
+
18
+ /**
19
+ * post_custom 格納用
20
+ * 何度も関数呼び出ししなくて良いように保存
21
+ */
22
+ protected $post_custom = array();
23
+
24
+ /**
25
+ * repeat_multiple_data
26
+ * 何度も関数呼び出ししなくて良いように保存
27
+ */
28
+ protected $repeat_multiple_data = array();
29
+
30
+ /**
31
+ * fields
32
+ * 各フォーム部品のオブジェクトを格納する配列
33
+ */
34
+ protected $fields = array();
35
+
36
+ /**
37
+ * __construct
38
+ */
39
+ public function __construct() {
40
+ require_once plugin_dir_path( __FILE__ ) . 'classes/class.config.php';
41
+ add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
42
+ register_uninstall_hook( __FILE__, array( __CLASS__, 'uninstall' ) );
43
+ }
44
+
45
+ /**
46
+ * plugins_loaded
47
+ */
48
+ public function plugins_loaded() {
49
+ do_action( SCF_Config::PREFIX . 'load' );
50
+ require_once plugin_dir_path( __FILE__ ) . 'classes/class.field-base.php';
51
+ require_once plugin_dir_path( __FILE__ ) . 'classes/fields/class.field-text.php';
52
+ foreach ( glob( plugin_dir_path( __FILE__ ) . 'classes/fields/*.php' ) as $form_item ) {
53
+ include_once $form_item;
54
+ $basename = basename( $form_item, '.php' );
55
+ $classname = preg_replace( '/^class\.field\-(.+)$/', 'Smart_Custom_Fields_Field_$1', $basename );
56
+ if ( class_exists( $classname ) ) {
57
+ new $classname();
58
+ }
59
+ }
60
+ $this->fields = apply_filters( SCF_Config::PREFIX . 'add-fields', $this->fields );
61
+
62
+ require_once plugin_dir_path( __FILE__ ) . 'classes/class.settings.php';
63
+ require_once plugin_dir_path( __FILE__ ) . 'classes/class.revisions.php';
64
+ require_once plugin_dir_path( __FILE__ ) . 'classes/class.scf.php';
65
+ new Smart_Custom_Fields_Settings();
66
+ new Smart_Custom_Fields_Revisions();
67
+ new SCF();
68
+
69
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
70
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 );
71
+ add_action( 'save_post', array( $this, 'save_post' ) );
72
+ add_action( 'wp_ajax_smart-cf-relational-posts-search', array( $this, 'relational_posts_search' ) );
73
+ }
74
+
75
+ /**
76
+ * uninstall
77
+ */
78
+ public static function uninstall() {
79
+ $cf_posts = get_posts( array(
80
+ 'post_type' => SCF_Config::NAME,
81
+ 'posts_per_page' => -1,
82
+ 'post_status' => 'any',
83
+ ) );
84
+ foreach ( $cf_posts as $post ) {
85
+ wp_delete_post( $post->ID, true );
86
+ }
87
+ delete_post_meta_by_key( SCF_Config::PREFIX . 'repeat-multiple-data' );
88
+ }
89
+
90
+ /**
91
+ * admin_enqueue_scripts
92
+ * @param string $hook
93
+ */
94
+ public function admin_enqueue_scripts( $hook ) {
95
+ if ( in_array( $hook, array( 'post-new.php', 'post.php' ) ) ) {
96
+ $post_type = get_post_type();
97
+ $settings = SCF::get_settings( $post_type );
98
+
99
+ if ( empty( $settings ) )
100
+ return;
101
+
102
+ wp_enqueue_style(
103
+ SCF_Config::PREFIX . 'editor',
104
+ plugin_dir_url( __FILE__ ) . 'css/editor.css'
105
+ );
106
+ wp_enqueue_media();
107
+ wp_enqueue_script(
108
+ SCF_Config::PREFIX . 'editor',
109
+ plugin_dir_url( __FILE__ ) . 'js/editor.js',
110
+ array( 'jquery' ),
111
+ null,
112
+ true
113
+ );
114
+ wp_localize_script( SCF_Config::PREFIX . 'editor', 'smart_cf_uploader', array(
115
+ 'image_uploader_title' => esc_html__( 'Image setting', 'smart-custom-fields' ),
116
+ 'file_uploader_title' => esc_html__( 'File setting', 'smart-custom-fields' ),
117
+ ) );
118
+ add_action( 'after_wp_tiny_mce', array( $this, 'after_wp_tiny_mce' ) );
119
+
120
+ // relation field
121
+ wp_enqueue_script(
122
+ SCF_Config::PREFIX . 'editor-relation',
123
+ plugin_dir_url( __FILE__ ) . 'js/editor-relation.js',
124
+ array( 'jquery' ),
125
+ null,
126
+ true
127
+ );
128
+ wp_localize_script( SCF_Config::PREFIX . 'editor-relation', 'smart_cf_relation', array(
129
+ 'endpoint' => admin_url( 'admin-ajax.php' ),
130
+ 'action' => SCF_Config::PREFIX . 'relational-posts-search',
131
+ 'nonce' => wp_create_nonce( SCF_Config::NAME . '-relation' )
132
+ ) );
133
+ }
134
+ }
135
+
136
+ public function after_wp_tiny_mce() {
137
+ printf( '<script type="text/javascript" src="%s"></script>', plugin_dir_url( __FILE__ ) . 'js/editor-wysiwyg.js' );
138
+ }
139
+
140
+ /**
141
+ * add_meta_boxes
142
+ * 投稿画面にカスタムフィールドを表示
143
+ * @param stirng $post_type
144
+ * @param object $post
145
+ */
146
+ public function add_meta_boxes( $post_type, $post ) {
147
+ $cf_posts = SCF::get_settings_posts( $post_type );
148
+ foreach ( $cf_posts as $post ) {
149
+ setup_postdata( $post );
150
+ $settings = get_post_meta( $post->ID, SCF_Config::PREFIX . 'setting', true );
151
+ if ( !$settings )
152
+ continue;
153
+ add_meta_box(
154
+ SCF_Config::PREFIX . 'custom-field-' . $post->ID,
155
+ $post->post_title,
156
+ array( $this, 'display_meta_box' ),
157
+ $post_type,
158
+ 'normal',
159
+ 'default',
160
+ $settings
161
+ );
162
+ wp_reset_postdata();
163
+ }
164
+ }
165
+
166
+ /**
167
+ * display_meta_box
168
+ * @param object $post
169
+ * @param array $setings カスタムフィールドの設定情報
170
+ */
171
+ public function display_meta_box( $post, $settings ) {
172
+ $groups = $settings['args'];
173
+ $tables = $this->get_tables( $post->ID, $groups );
174
+
175
+ printf( '<div class="%s">', esc_attr( SCF_Config::PREFIX . 'meta-box' ) );
176
+ $index = 0;
177
+ foreach ( $tables as $group_key => $group ) {
178
+ $btn_repeat = '';
179
+ $is_repeat = ( isset( $group['repeat'] ) && $group['repeat'] === true ) ? true : false;
180
+ if ( $is_repeat ) {
181
+ if ( $index === 0 ) {
182
+ printf(
183
+ '<div class="%s">',
184
+ esc_attr( SCF_Config::PREFIX . 'meta-box-repeat-tables' )
185
+ );
186
+ $this->display_tr( $post->ID, $is_repeat, $group['fields'] );
187
+ }
188
+ }
189
+
190
+ $this->display_tr( $post->ID, $is_repeat, $group['fields'], $index );
191
+
192
+ // ループの場合は添字をカウントアップ
193
+ // ループを抜けたらカウントをもとに戻す
194
+ if ( $is_repeat &&
195
+ isset( $tables[$group_key + 1 ]['group-name'] ) &&
196
+ $tables[$group_key + 1 ]['group-name'] === $group['group-name'] ) {
197
+ $index ++;
198
+ } else {
199
+ $index = 0;
200
+ }
201
+ if ( $is_repeat && $index === 0 ) {
202
+ echo '</div>';
203
+ }
204
+ }
205
+ printf( '</div>' );
206
+ wp_nonce_field( SCF_Config::NAME . '-fields', SCF_Config::PREFIX . 'fields-nonce' );
207
+ }
208
+
209
+ /**
210
+ * save_post
211
+ * @param int $post_id
212
+ */
213
+ public function save_post( $post_id ) {
214
+ if ( !isset( $_POST[SCF_Config::PREFIX . 'fields-nonce'] ) ) {
215
+ return;
216
+ }
217
+ if ( !wp_verify_nonce( $_POST[SCF_Config::PREFIX . 'fields-nonce'], SCF_Config::NAME . '-fields' ) ) {
218
+ return;
219
+ }
220
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
221
+ return;
222
+ }
223
+ if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ){
224
+ return;
225
+ }
226
+ if ( !isset( $_POST[SCF_Config::NAME] ) ) {
227
+ return;
228
+ }
229
+
230
+ // 繰り返しフィールドのチェックボックスは、普通のチェックボックスと混ざって
231
+ // 判別できなくなるのでわかるように保存しておく
232
+ $repeat_multiple_data = array();
233
+
234
+ // チェックボックスが未入力のときは "" がくるので、それは保存しないように判別
235
+ $multiple_data_fields = array();
236
+
237
+ $post_type = get_post_type();
238
+ $settings = SCF::get_settings( $post_type );
239
+ foreach ( $settings as $setting ) {
240
+ foreach ( $setting as $group ) {
241
+ $is_repeat = ( isset( $group['repeat'] ) && $group['repeat'] === true ) ? true : false;
242
+ foreach ( $group['fields'] as $field ) {
243
+ delete_post_meta( $post_id, $field['name'] );
244
+
245
+ if ( in_array( $field['type'], array( 'check', 'relation' ) ) ) {
246
+ $multiple_data_fields[] = $field['name'];
247
+ }
248
+
249
+ if ( $is_repeat && in_array( $field['type'], array( 'check', 'relation' ) ) ) {
250
+ $repeat_multiple_data_fields = $_POST[SCF_Config::NAME][$field['name']];
251
+ foreach ( $repeat_multiple_data_fields as $values ) {
252
+ if ( is_array( $values ) ) {
253
+ $repeat_multiple_data[$field['name']][] = count( $values );
254
+ } else {
255
+ $repeat_multiple_data[$field['name']][] = 0;
256
+ }
257
+ }
258
+ }
259
+ }
260
+ }
261
+ }
262
+ delete_post_meta( $post_id, SCF_Config::PREFIX . 'repeat-multiple-data' );
263
+ if ( $repeat_multiple_data ) {
264
+ update_post_meta( $post_id, SCF_Config::PREFIX . 'repeat-multiple-data', $repeat_multiple_data );
265
+ }
266
+
267
+ foreach ( $_POST[SCF_Config::NAME] as $name => $values ) {
268
+ foreach ( $values as $value ) {
269
+ if ( in_array( $name, $multiple_data_fields ) && $value === '' )
270
+ continue;
271
+ if ( !is_array( $value ) ) {
272
+ add_post_meta( $post_id, $name, $value );
273
+ } else {
274
+ foreach ( $value as $val ) {
275
+ add_post_meta( $post_id, $name, $val );
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ /**
283
+ * get_post_custom
284
+ * @param int $post_id
285
+ * @return array
286
+ */
287
+ protected function get_post_custom( $post_id ) {
288
+ $post_custom = $this->post_custom;
289
+ if ( empty( $post_custom ) ) {
290
+ $post_custom = get_post_custom( $post_id );
291
+ if ( empty( $post_custom ) ) {
292
+ return array();
293
+ }
294
+ $this->post_custom = $post_custom;
295
+ }
296
+ return $this->post_custom;
297
+ }
298
+
299
+ /**
300
+ * get_repeat_multiple_data
301
+ * @param int $post_id
302
+ * @return array $this->repeat_multiple_data
303
+ */
304
+ protected function get_repeat_multiple_data( $post_id ) {
305
+ $repeat_multiple_data = $this->repeat_multiple_data;
306
+ if ( empty( $repeat_multiple_data ) ) {
307
+ $repeat_multiple_data = get_post_meta( $post_id, SCF_Config::PREFIX . 'repeat-multiple-data', true );
308
+ if ( empty( $repeat_multiple_data ) ) {
309
+ return array();
310
+ }
311
+ if ( is_serialized( $repeat_multiple_data ) ) {
312
+ $repeat_multiple_data = maybe_unserialize( $repeat_multiple_data );
313
+ }
314
+ $this->repeat_multiple_data = $repeat_multiple_data;
315
+ }
316
+ return $this->repeat_multiple_data;
317
+ }
318
+
319
+ /**
320
+ * get_tables
321
+ * カスタムフィールドを出力するための配列を生成
322
+ * @param array $groups カスタムフィールド設定ページで保存した設定
323
+ * @return array $tables カスタムフィールド表示用のテーブルを出力するための配列
324
+ */
325
+ protected function get_tables( $post_id, $groups ) {
326
+ $post_custom = $this->get_post_custom( $post_id );
327
+ $repeat_multiple_data = $this->get_repeat_multiple_data( $post_id );
328
+ $tables = array();
329
+ foreach ( $groups as $group ) {
330
+ // ループのときは、ループの分だけグループを追加する
331
+ // ループだけどループがないとき(新規登録時とか)は1つだけ入れる
332
+ if ( isset( $group['repeat'] ) && $group['repeat'] === true ) {
333
+ $loop_count = 1;
334
+ foreach ( $group['fields'] as $field ) {
335
+ if ( isset( $post_custom[$field['name']] ) && is_array( $post_custom[$field['name']] ) ) {
336
+ $post_meta = $post_custom[$field['name']];
337
+ $post_meta_count = count( $post_meta );
338
+ // 同名のカスタムフィールドが複数のとき(チェックボックス or ループ)
339
+ if ( $post_meta_count > 1 ) {
340
+ // チェックボックスの場合
341
+ if ( is_array( $repeat_multiple_data ) && array_key_exists( $field['name'], $repeat_multiple_data ) ) {
342
+ $repeat_multiple_data_count = count( $repeat_multiple_data[$field['name']] );
343
+ if ( $loop_count < $repeat_multiple_data_count )
344
+ $loop_count = $repeat_multiple_data_count;
345
+ }
346
+ // チェックボックス以外
347
+ else {
348
+ if ( $loop_count < $post_meta_count )
349
+ $loop_count = $post_meta_count;
350
+ }
351
+ }
352
+ }
353
+ }
354
+ if ( $loop_count >= 1 ) {
355
+ for ( $i = $loop_count; $i > 0; $i -- ) {
356
+ $tables[] = $group;
357
+ }
358
+ continue;
359
+ }
360
+ }
361
+ $tables[] = $group;
362
+ }
363
+ return $tables;
364
+ }
365
+
366
+ /**
367
+ * get_multiple_data_field_value
368
+ * @param int $post_id
369
+ * @param string $field_name
370
+ * @param int $index
371
+ * @return array or null
372
+ */
373
+ protected function get_multiple_data_field_value( $post_id, $field_name, $index ) {
374
+ $post_custom = $this->get_post_custom( $post_id );
375
+ $repeat_multiple_data = $this->get_repeat_multiple_data( $post_id );
376
+ $value = null;
377
+ if ( isset( $post_custom[$field_name] ) && is_array( $post_custom[$field_name] ) ) {
378
+ $value = $post_custom[$field_name];
379
+ // ループのとき
380
+ if ( is_array( $repeat_multiple_data ) && array_key_exists( $field_name, $repeat_multiple_data ) ) {
381
+ $now_num = 0;
382
+ if ( isset( $repeat_multiple_data[$field_name][$index] ) ) {
383
+ $now_num = $repeat_multiple_data[$field_name][$index];
384
+ }
385
+
386
+ // 自分($index)より前の個数の合計が指す index が start
387
+ $_temp = array_slice( $repeat_multiple_data[$field_name], 0, $index );
388
+ $sum = array_sum( $_temp );
389
+ $start = $sum;
390
+
391
+ $value = null;
392
+ if ( $now_num ) {
393
+ $value = array_slice( $post_custom[$field_name], $start, $now_num );
394
+ }
395
+ }
396
+ }
397
+ return $value;
398
+ }
399
+
400
+ /**
401
+ * get_single_data_field_value
402
+ * @param int $post_id
403
+ * @param string $field_name
404
+ * @param int $index
405
+ * @return string or null
406
+ */
407
+ protected function get_single_data_field_value( $post_id, $field_name, $index ) {
408
+ $post_custom = $this->get_post_custom( $post_id );
409
+ $value = null;
410
+ if ( isset( $post_custom[$field_name][$index] ) ) {
411
+ $value = $post_custom[$field_name][$index];
412
+ }
413
+ return $value;
414
+ }
415
+
416
+ /**
417
+ * display_tr
418
+ * @param int $post_id
419
+ * @param bool $is_repeat
420
+ * @param array $fields
421
+ * @param int, null $index
422
+ */
423
+ protected function display_tr( $post_id, $is_repeat, $fields, $index = null ) {
424
+ $btn_repeat = '';
425
+ if ( $is_repeat ) {
426
+ $btn_repeat = sprintf( '<span class="%s"></span>', esc_attr( SCF_Config::PREFIX . 'icon-handle' ) );
427
+ $btn_repeat .= '<span class="button btn-add-repeat-group">+</span>';
428
+ $btn_repeat .= ' <span class="button btn-remove-repeat-group">-</span>';
429
+ }
430
+
431
+ $style = '';
432
+ if ( is_null( $index ) ) {
433
+ $style = 'style="display: none;"';
434
+ }
435
+
436
+ printf(
437
+ '<div class="%s" %s>%s<table>',
438
+ esc_attr( SCF_Config::PREFIX . 'meta-box-table' ),
439
+ $style,
440
+ $btn_repeat
441
+ );
442
+
443
+ foreach ( $fields as $field ) {
444
+ $field_label = $field['label'];
445
+ if ( !$field_label ) {
446
+ $field_label = $field['name'];
447
+ }
448
+
449
+ // 複数値許可フィールドのとき
450
+ $post_status = get_post_status( $post_id );
451
+ if ( in_array( $field['type'], array( 'check', 'relation' ) ) ) {
452
+ $value = array();
453
+ if ( !SCF::is_empty( $field['default'] ) && ( $post_status === 'auto-draft' || is_null( $index ) ) ) {
454
+ $value = $this->fields[$field['type']]->get_choices( $field['default'] );
455
+ }
456
+ $_value = $this->get_multiple_data_field_value( $post_id, $field['name'], $index );
457
+ }
458
+ // 複数不値許可フィールドのとき
459
+ else {
460
+ $value = '';
461
+ if ( $post_status === 'auto-draft' || is_null( $index ) ) {
462
+ if ( !SCF::is_empty( $field['default'] ) ) {
463
+ $value = $field['default'];
464
+ }
465
+ }
466
+ $_value = $this->get_single_data_field_value( $post_id, $field['name'], $index );
467
+ }
468
+ if ( !is_null( $_value ) ) {
469
+ $value = $_value;
470
+ }
471
+
472
+ $notes = '';
473
+ if ( !empty( $field['notes'] ) ) {
474
+ $notes = sprintf(
475
+ '<p class="description">%s</p>',
476
+ esc_html( $field['notes'] )
477
+ );
478
+ }
479
+
480
+ $form_field = $this->fields[$field['type']]->get_field( $field, $index, $value );
481
+ printf(
482
+ '<tr><th>%s</th><td>%s%s</td></tr>',
483
+ esc_html( $field_label ),
484
+ $form_field,
485
+ $notes
486
+ );
487
+ }
488
+ echo '</table></div>';
489
+ }
490
+
491
+ /**
492
+ * relational_posts_search
493
+ */
494
+ public function relational_posts_search() {
495
+ check_ajax_referer( SCF_Config::NAME . '-relation', 'nonce' );
496
+ $_posts = array();
497
+ if ( isset( $_POST['post_types'], $_POST['click_count' ] ) ) {
498
+ $post_type = explode( ',', $_POST['post_types'] );
499
+ $posts_per_page = get_option( 'posts_per_page' );
500
+ $offset = $_POST['click_count'] * $posts_per_page;
501
+ $_posts = get_posts( array(
502
+ 'post_type' => $post_type,
503
+ 'offset' => $offset,
504
+ 'order' => 'ASC',
505
+ 'orderby' => 'ID',
506
+ 'posts_per_page' => $posts_per_page,
507
+ ) );
508
+ }
509
+ header( 'Content-Type: application/json; charset=utf-8' );
510
+ echo json_encode( $_posts );
511
+ die();
512
+ }
513
+ }
514
+ new Smart_Custom_Fields();