forked from argoproject/Argo
-
-
Notifications
You must be signed in to change notification settings - Fork 83
/
metabox-api.php
181 lines (154 loc) · 5.78 KB
/
metabox-api.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
<?php
/**
* Contains function definitions for hooking fields and boxes into Largo
* Relies on the global variable $largo, which feels hack-ish but creates the most convenience
*/
/**
* First things first: check if $largo['meta'] exists
* If it does, then this file has already been included (likely by a child theme) and should stop.
* Otherwise we get function redeclarations.
* Since we're using include_once() this is unlikely, but possible and worth checking.
*/
if ( isset($largo) && array_key_exists('meta', $largo) ) return;
$largo['meta'] = array(
'boxes' => array(), // the metaboxes to generate, including callbacks for the content
'inputs' => array(), // input names to process with largo_meta_box_save()
);
/**
* Call this function to define a metabox container
*
* @since 0.2
*
* @param string $id Required. HTML 'id' attribute of edit screen section. Corresponds to first argument of add_meta_box()
* @param string $title Required. Title of the metabox, visible to user
* @param array|string $screens Optional. Name of post type(s) this box should appear on. Values correspond to $post_type argument of add_meta_box(). Defaults to 'post'
* @param string $context Optional. The context within the page where the boxes should show ('normal', 'advanced', 'side'). Defaults to 'advanced'
* @param string $priority Optional. The priority within the context where the boxes should show ('high', 'low', 'core', 'default'). Defaults to 'default'
*
*/
function largo_add_meta_box( $id, $title, $callbacks = array(), $post_types = 'post', $context = 'advanced', $priority = 'default' ) {
global $largo;
if ( is_string($post_types) ) $post_types = array($post_types);
if ( is_string($callbacks) ) $callbacks = array($callbacks);
if ( is_null($callbacks) ) $callbacks = array();
$largo['meta']['boxes'][$id] = array(
'title' => __( $title, 'largo'),
'callbacks' => $callbacks,
'screens' => $post_types,
'context' => $context,
'priority' => $priority
);
}
/**
* Call this function to add a field to an (existing) metabox container
*
* @since 0.2
*
* @param string $callback Required. Function that outputs the markup for this field
* @param string $box_id Required. HTML 'id' attribute of the box this field goes into
*
* TODO: Implement some sort of weighting protocol to control ordering of fields within a metabox (right now it's just FIFO)
*/
function largo_add_meta_content( $callback, $box_id ) {
global $largo;
// Create this metabox if one hasn't been defined... assumes just 'post'
if ( !array_key_exists( $box_id, $largo['meta']['boxes'] ) ){
largo_add_meta_box( $box_id, 'Meta Information' );
}
// Add this field to the array
$largo['meta']['boxes'][$box_id]['callbacks'][] = $callback;
}
/**
* Call this function from within a largo_add_meta_field callback to register an input as a post meta field
*
* @since 0.2
*
* @param string|array $input_names Name of a single input or array of input names to add as meta fields
*
* TODO: Include a validation parameter so meta fields can be validated easily.
*/
function largo_register_meta_input( $input_names, $presave_fn = NULL ) {
global $largo;
if ( is_string( $input_names ) ) {
$input_names = array( $input_names );
}
foreach( $input_names as $name ) {
$largo[ 'inputs' ][ $name ] = array( 'name' => $name, 'presave_fn' => $presave_fn );
}
}
/**
* Private function to actually generate the metaboxes
*/
function _largo_metaboxes_generate() {
global $largo;
foreach( $largo['meta']['boxes'] as $box_id => $settings ) {
foreach( $settings['screens'] as $screen ) {
add_meta_box(
$box_id,
$settings['title'],
'_largo_metaboxes_content',
$screen,
$settings['context'],
$settings['priority'],
$settings['callbacks']
);
}
}
}
add_action( 'add_meta_boxes', '_largo_metaboxes_generate', 12 ); // give everything time to do its thing before we run
/**
* Private function to generate fields/markup within largo metaboxes
*
*/
function _largo_metaboxes_content( $post, $callbacks = array() ) {
// loop thru the $callbacks array and execute each of them
// $callbacks is not actually just $settings['callbacks']
// instead it has array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $callback_args);
foreach( $callbacks['args'] as $callback ) {
$callback( $post );
}
}
/**
* Private function to handle saving inputs registered with largo_register_meta_input()
*
* TODO: Implement validation for inputs
*/
// Save our custom meta box values as custom fields
function _largo_meta_box_save( $post_id ) {
global $post, $largo;
// Bail if we're doing an auto save
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// if our nonce isn't there, or we can't verify it, bail
if ( ! isset( $_POST['meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['meta_box_nonce'], 'largo_meta_box_nonce' ) ) {
return;
}
// if our current user can't edit this post, bail
if ( ! current_user_can( 'edit_post' ) ) {
return;
}
// set up our array of data
$mydata = array();
foreach ( $largo['inputs'] as $input_name => $handlers ) {
if ( array_key_exists( $input_name, $_POST ) ) {
if ( function_exists( $handlers['presave_fn'] ) ) {
$mydata[ $input_name ] = call_user_func( $handlers['presave_fn'], $_POST[ $input_name ] );
} else {
$mydata[ $input_name ] = $_POST[ $input_name ];
}
}
}
// process our posts
foreach ( $mydata as $key => $value ) {
if ( get_post_meta( $post->ID, $key, FALSE ) ) {
update_post_meta( $post->ID, $key, $value ); //if the custom field already has a value, update it
} else {
add_post_meta( $post->ID, $key, $value );//if the custom field doesn't have a value, add the data
}
if ( ! $value ) {
delete_post_meta( $post->ID, $key ); //and delete if blank
}
}
}
add_action( 'save_post', '_largo_meta_box_save' );