1: <?php
2:
3: 4: 5:
6: final class Papi_Admin_Meta_Box {
7:
8: 9: 10: 11: 12:
13: private $default_options = [
14: 'capabilities' => [],
15: 'context' => 'normal',
16: 'priority' => 'default',
17: 'properties' => [],
18: 'sort_order' => null,
19: 'title' => '',
20:
21: '_id' => '',
22: '_post_type' => 'page',
23: '_required' => false,
24: '_tab_box' => false
25: ];
26:
27: 28: 29: 30: 31:
32: private $options;
33:
34: 35: 36: 37: 38:
39: private $properties = [];
40:
41: 42: 43: 44: 45: 46:
47: public function __construct( $options = [], $properties = [] ) {
48: if ( empty( $options ) ) {
49: return;
50: }
51:
52: $this->setup_options( $options );
53:
54:
55: if ( ! papi_current_user_is_allowed( $this->options->capabilities ) ) {
56: return;
57: }
58:
59: $this->populate_properties( $properties );
60:
61: $this->setup_actions();
62: }
63:
64: 65: 66: 67: 68:
69: public function add_property( $property ) {
70: $this->properties[] = $property;
71: }
72:
73: 74: 75: 76: 77: 78: 79:
80: private function get_meta_box_id( $slug ) {
81: return papi_f( papi_underscorify( papify( $slug ) ) );
82: }
83:
84: 85: 86: 87: 88: 89: 90:
91: public function meta_box_css_classes( $classes ) {
92: return array_merge( $classes, [
93: 'papi-box'
94: ] );
95: }
96:
97: 98: 99:
100: public function move_meta_box_after_title() {
101: global $post, $wp_meta_boxes;
102: do_meta_boxes( get_current_screen(), $this->options->context, $post );
103: unset( $wp_meta_boxes[get_post_type( $post )][$this->options->context] );
104: }
105:
106: 107: 108: 109: 110: 111: 112:
113: private function populate_post_type( $post_type ) {
114: $post_id = papi_get_post_id();
115:
116: if ( $post_id !== 0 ) {
117: return get_post_type( $post_id );
118: }
119:
120:
121: $post_type = array_filter( papi_to_array( $post_type ), function ( $post_type ) {
122:
123: if ( strpos( $post_type, '_papi' ) !== false ) {
124: return true;
125: }
126:
127: return ! empty( $post_type ) &&
128: strtolower( $post_type ) === strtolower(
129: papi_get_or_post( 'post_type' )
130: );
131: } );
132:
133: if ( ! empty( $post_type ) ) {
134: return $post_type[0];
135: }
136:
137: return 'page';
138: }
139:
140: 141: 142: 143: 144:
145: private function populate_properties( $properties ) {
146: $this->properties = papi_populate_properties( $properties );
147:
148: if ( ! empty( $this->properties ) ) {
149: $this->options->_tab_box = isset( $this->properties[0]->tab ) &&
150: $this->properties[0]->tab;
151: }
152: }
153:
154: 155: 156: 157: 158: 159:
160: public function render_meta_box( $post, $args ) {
161: if ( ! is_array( $args ) || ! isset( $args['args'] ) ) {
162: return;
163: }
164:
165:
166: papi_render_properties( $args['args'] );
167: }
168:
169: 170: 171:
172: private function setup_actions() {
173: if ( post_type_exists( $this->options->_post_type ) ) {
174: add_action( 'add_meta_boxes', [$this, 'setup_meta_box'] );
175:
176: if ( $this->options->context === 'after_title' ) {
177: add_action( 'edit_form_after_title', [$this, 'move_meta_box_after_title'] );
178: }
179: } else {
180: $this->setup_meta_box();
181: }
182:
183:
184:
185: add_action(
186: sprintf(
187: 'postbox_classes_%s_%s',
188: $this->options->_post_type,
189: $this->options->_id
190: ),
191: [$this, 'meta_box_css_classes']
192: );
193: }
194:
195: 196: 197:
198: public function setup_meta_box() {
199: $this->options->title = papi_remove_papi( $this->options->title );
200:
201: if ( $this->options->_required ) {
202: $this->options->title .= papi_required_html(
203: $this->properties[0],
204: true
205: );
206: }
207:
208: add_meta_box(
209: $this->options->_id,
210: $this->options->title,
211: [ $this, 'render_meta_box' ],
212: $this->options->_post_type,
213: $this->options->context,
214: $this->options->priority,
215: $this->properties
216: );
217: }
218:
219: 220: 221: 222: 223:
224: private function setup_options( $options ) {
225: $options = empty( $options ) ? [] : $options;
226: $options = array_merge( $this->default_options, $options );
227: $this->options = (object) $options;
228: $this->options->title = ucfirst( $this->options->title );
229: $this->options->slug = papi_slugify( $this->options->title );
230: $this->options->_id = $this->get_meta_box_id(
231: $this->options->slug
232: );
233: $this->options->_post_type = $this->populate_post_type(
234: $this->options->_post_type
235: );
236: }
237: }
238: