1: <?php
2:
3: 4: 5: 6:
7: class Papi_Property_Relationship extends Papi_Property {
8:
9: 10: 11: 12: 13:
14: public $convert_type = 'array';
15:
16: 17: 18: 19: 20:
21: public $default_value = [];
22:
23: 24: 25: 26: 27: 28: 29:
30: protected function convert_post_to_item( WP_Post $post ) {
31: return (object) [
32: 'id' => $post->ID,
33: 'title' => $post->post_title
34: ];
35: }
36:
37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
47: public function format_value( $values, $slug, $post_id ) {
48: if ( is_array( $values ) || is_object( $values ) ) {
49: $items = $this->get_settings()->items;
50: $result = [];
51:
52: foreach ( $values as $key => $id ) {
53:
54: $id = is_array( $id ) ? $id['id'] : $id;
55:
56: if ( empty( $id ) ) {
57: continue;
58: }
59:
60: if ( papi_is_empty( $items ) ) {
61: $post = get_post( $id );
62:
63: if ( empty( $post ) ) {
64: continue;
65: }
66:
67: $result[] = $post;
68: } else {
69: $item = array_filter( $items, function ( $item ) use ( $id ) {
70: return wp_list_pluck( [$item], 'id' )[0] === (int) $id;
71: } );
72:
73: $result[] = papi_maybe_convert_to_object( array_values( $item )[0] );
74: }
75: }
76:
77: return $this->sort_value( $result, $slug, $post_id );
78: }
79:
80: return $this->default_value;
81: }
82:
83: 84: 85: 86: 87:
88: public function get_default_settings() {
89: return [
90: 'items' => [],
91: 'limit' => -1,
92: 'only_once' => false,
93: 'post_type' => 'page',
94: 'title' => __( 'Post', 'papi' ),
95: 'query' => [],
96: 'show_sort_by' => true
97: ];
98: }
99:
100: 101: 102: 103: 104: 105: 106:
107: public function get_sort_option( $post_id ) {
108: $slug = $this->html_id( 'sort_option' );
109: $slug = str_replace( '][', '_', $slug );
110: $slug = str_replace( '[', '_', $slug );
111: $slug = str_replace( ']', '', $slug );
112:
113: return papi_get_property_meta_value( $post_id, $slug );
114: }
115:
116: 117: 118: 119: 120:
121: public static function get_sort_options() {
122: $sort_options = [];
123:
124: $sort_options[__( 'Select', 'papi' )] = null;
125:
126: $sort_options[__( 'Name (alphabetically)', 'papi' )] = function ( $a, $b ) {
127:
128: return strcmp(
129: strtolower( isset( $a->post_title ) ? $a->post_title : $a->title ),
130: strtolower( isset( $b->post_title ) ? $b->post_title : $b->title )
131: );
132: };
133:
134: $sort_options[__( 'Post created date (ascending)', 'papi' )] = function ( $a, $b ) {
135: return strtotime( $a->post_date ) > strtotime( $b->post_date );
136: };
137:
138: $sort_options[__( 'Post created date (descending)', 'papi' )] = function ( $a, $b ) {
139: return strtotime( $a->post_date ) < strtotime( $b->post_date );
140: };
141:
142: $sort_options[__( 'Post id (ascending)', 'papi' )] = function ( $a, $b ) {
143:
144: return isset( $a->ID ) ? $a->ID > $b->ID : $a->id > $b->id;
145: };
146:
147: $sort_options[__( 'Post id (descending)', 'papi' )] = function ( $a, $b ) {
148:
149: return isset( $a->ID ) ? $a->ID < $b->ID : $a->id < $b->id;
150: };
151:
152: $sort_options[__( 'Post order value (ascending)', 'papi' )] = function ( $a, $b ) {
153: return $a->menu_order > $b->menu_order;
154: };
155:
156: $sort_options[__( 'Post order value (descending)', 'papi' )] = function ( $a, $b ) {
157: return $a->menu_order < $b->menu_order;
158: };
159:
160: $sort_options[__( 'Post modified date (ascending)', 'papi' )] = function ( $a, $b ) {
161: return strtotime( $a->post_modified ) >
162: strtotime( $b->post_modified );
163: };
164:
165: $sort_options[__( 'Post modified date (descending)', 'papi' )] = function ( $a, $b ) {
166: return strtotime( $a->post_modified ) <
167: strtotime( $b->post_modified );
168: };
169:
170: return apply_filters(
171: 'papi/property/relationship/sort_options',
172: $sort_options
173: );
174: }
175:
176: 177: 178: 179: 180: 181: 182:
183: protected function get_items( $settings ) {
184: if ( is_array( $settings->items ) && ! empty( $settings->items ) ) {
185: $mapping = function ( $item ) {
186: return is_array( $item ) ?
187: isset( $item['id'] ) && isset( $item['title'] ) :
188: isset( $item->id ) && isset( $item->title );
189: };
190:
191: return array_map(
192: 'papi_maybe_convert_to_object',
193: array_filter( $settings->items, $mapping )
194: );
195: }
196:
197:
198: if ( ! isset( $settings->query['posts_per_page'] ) ) {
199: $settings->query['posts_per_page'] = -1;
200: }
201:
202:
203: $args = array_merge( $settings->query, [
204: 'post_type' => papi_to_array( $settings->post_type ),
205: 'no_found_rows' => true,
206: 'update_post_meta_cache' => false,
207: 'update_post_term_cache' => false
208: ] );
209:
210: $query = new WP_Query( $args );
211: $items = $query->get_posts();
212:
213: return array_map(
214: [$this, 'convert_post_to_item'],
215: papi_get_only_objects( $items )
216: );
217: }
218:
219: 220: 221:
222: public function html() {
223: $post_id = papi_get_post_id();
224: $slug = $this->html_name();
225: $settings = $this->get_settings();
226: $settings_json = [];
227: $sort_option = $this->get_sort_option( $post_id );
228: $sort_options = static::get_sort_options();
229: $values = papi_get_only_objects( $this->get_value() );
230: $items = $this->get_items( $settings );
231:
232: if ( papi_is_empty( $settings->items ) ) {
233: $values = array_map( [$this, 'convert_post_to_item'], $values );
234: } else {
235: foreach ( $sort_options as $key => $sort ) {
236: if ( strpos( $key, 'Post' ) === 0 ) {
237: unset( $sort_options[$key] );
238: }
239: }
240: }
241:
242:
243: foreach ( (array) $settings as $key => $val ) {
244: if ( ! is_string( $key ) || ! in_array( $key, ['only_once', 'limit'] ) ) {
245: continue;
246: }
247:
248: $settings_json[papi_camel_case( $key )] = $val;
249: }
250: ?>
251: <div class="papi-property-relationship" data-settings='<?php echo json_encode( $settings_json ); ?>'>
252: <input type="hidden" name="<?php echo $slug; ?>[]" data-papi-rule="<?php echo $slug; ?>" />
253: <div class="relationship-inner">
254: <div class="relationship-top-left">
255: <label for="<?php echo $this->html_id( 'search' ); ?>"><?php _e( 'Search', 'papi' ); ?></label>
256: <input id="<?php echo $this->html_id( 'search' ); ?>" type="search" />
257: </div>
258: <div class="relationship-top-right">
259: <?php if ( $settings->show_sort_by ): ?>
260: <label for="<?php echo $this->html_id( 'sort_option' ); ?>"><?php _e( 'Sort by', 'papi' ); ?></label>
261: <select id="<?php echo $this->html_id( 'sort_option' ); ?>" name="<?php echo $this->html_id( 'sort_option' ); ?>">
262: <?php foreach ( $sort_options as $key => $v ): ?>
263: <option value="<?php echo $key; ?>" <?php echo $key === $sort_option ? 'selected="selected"' : ''; ?>><?php echo $key; ?></option>
264: <?php endforeach; ?>
265: </select>
266: <?php endif; ?>
267: </div>
268: <div class="papi-clear"></div>
269: </div>
270: <div class="relationship-inner">
271: <div class="relationship-left">
272: <ul>
273: <?php
274: foreach ( $items as $item ):
275: if ( ! empty( $item->title ) ):
276: ?>
277: <li>
278: <input type="hidden"
279: data-name="<?php echo $slug; ?>[]"
280: value="<?php echo $item->id; ?>"/>
281: <a href="#"><?php echo $item->title; ?></a>
282: <span class="icon plus"></span>
283: </li>
284: <?php
285: endif;
286: endforeach;
287: ?>
288: </ul>
289: </div>
290: <div class="relationship-right">
291: <ul>
292: <?php foreach ( $values as $item ): ?>
293: <li>
294: <input type="hidden" name="<?php echo $slug; ?>[]"
295: value="<?php echo $item->id; ?>"/>
296: <a href="#"><?php echo $item->title; ?></a>
297: <span class="icon minus"></span>
298: </li>
299: <?php endforeach; ?>
300: </ul>
301: </div>
302: <div class="papi-clear"></div>
303: </div>
304: </div>
305: <?php
306: }
307:
308: 309: 310: 311: 312: 313: 314: 315: 316:
317: public function import_value( $value, $slug, $post_id ) {
318: if ( ! is_array( $value ) && ! is_object( $value ) && ! is_numeric( $value ) ) {
319: return;
320: }
321:
322: $values = [];
323:
324: foreach ( papi_to_array( $value ) as $index => $val ) {
325: if ( $val instanceof WP_Post ) {
326: $values[] = $val->ID;
327: }
328:
329: if ( is_object( $val ) && isset( $val->id ) ) {
330: $values[] = (int) $val->id;
331: }
332:
333: if ( is_numeric( $val ) ) {
334: $values[] = (int) $val;
335: }
336: }
337:
338: return $values;
339: }
340:
341: 342: 343: 344: 345: 346: 347: 348: 349:
350: public function load_value( $values, $slug, $post_id ) {
351: return (array) papi_maybe_json_decode( maybe_unserialize( $values ), true );
352: }
353:
354: 355: 356: 357: 358: 359: 360: 361: 362:
363: public function sort_value( $values, $slug, $post_id ) {
364: $sort_option = $this->get_sort_option( $post_id );
365: $sort_options = static::get_sort_options();
366:
367: if ( empty( $sort_option ) || ! isset( $sort_options[$sort_option] ) || is_null( $sort_options[$sort_option] ) ) {
368: return $values;
369: }
370:
371: usort( $values, $sort_options[$sort_option] );
372:
373: return $values;
374: }
375:
376: 377: 378: 379: 380: 381: 382: 383: 384:
385: public function update_value( $values, $slug, $post_id ) {
386: $values = $this->format_value( $values, $slug, $post_id );
387: $values = array_map( function ( $item ) {
388: if ( $item instanceof WP_Post ) {
389: $item = $this->convert_post_to_item( $item );
390: }
391:
392: if ( isset( $item->title ) ) {
393: unset( $item->title );
394: }
395:
396: return $item;
397: }, $values );
398:
399: return json_encode( $values );
400: }
401: }
402: