acf_field_relationship

The Advanced Custom Fields acf field relationship class.

Defined (1)

The class is defined in the following location(s).

/core/fields/relationship.php  
  1. class acf_field_relationship extends acf_field 
  2. /** 
  3. * __construct 
  4. * Set name / label needed for actions / filters 
  5. * @since 3.6 
  6. * @date 23/01/13 
  7. */ 
  8.  
  9. function __construct() 
  10. // vars 
  11. $this->name = 'relationship'; 
  12. $this->label = __("Relationship", 'acf'); 
  13. $this->category = __("Relational", 'acf'); 
  14. $this->defaults = array( 
  15. 'post_type' => array('all'),  
  16. 'max' => '',  
  17. 'taxonomy' => array('all'),  
  18. 'filters' => array('search'),  
  19. 'result_elements' => array('post_title', 'post_type'),  
  20. 'return_format' => 'object' 
  21. ); 
  22. $this->l10n = array( 
  23. 'max' => __("Maximum values reached ( {max} values )", 'acf'),  
  24. 'tmpl_li' => ' 
  25. <li> 
  26. <a href="#" data-post_id="<%= post_id %>"><%= title %><span class="acf-button-remove"></span></a> 
  27. <input type="hidden" name="<%= name %>[]" value="<%= post_id %>" /> 
  28. </li> 
  29. ); 
  30.  
  31.  
  32. // do not delete! 
  33. parent::__construct(); 
  34.  
  35.  
  36. // extra 
  37. add_action('wp_ajax_acf/fields/relationship/query_posts', array($this, 'query_posts')); 
  38. add_action('wp_ajax_nopriv_acf/fields/relationship/query_posts', array($this, 'query_posts')); 
  39.  
  40.  
  41. /** 
  42. * load_field() 
  43. *  
  44. * This filter is appied to the $field after it is loaded from the database 
  45. *  
  46. * @type filter 
  47. * @since 3.6 
  48. * @date 23/01/13 
  49. *  
  50. * @param $field - the field array holding all the field options 
  51. *  
  52. * @return $field - the field array holding all the field options 
  53. */ 
  54.  
  55. function load_field( $field ) 
  56. // validate post_type 
  57. if( !$field['post_type'] || !is_array($field['post_type']) || in_array('', $field['post_type']) ) 
  58. $field['post_type'] = array( 'all' ); 
  59.  
  60.  
  61. // validate taxonomy 
  62. if( !$field['taxonomy'] || !is_array($field['taxonomy']) || in_array('', $field['taxonomy']) ) 
  63. $field['taxonomy'] = array( 'all' ); 
  64.  
  65.  
  66. // validate result_elements 
  67. if( !is_array( $field['result_elements'] ) ) 
  68. $field['result_elements'] = array(); 
  69.  
  70. if( !in_array('post_title', $field['result_elements']) ) 
  71. $field['result_elements'][] = 'post_title'; 
  72.  
  73.  
  74. // filters 
  75. if( !is_array( $field['filters'] ) ) 
  76. $field['filters'] = array(); 
  77.  
  78.  
  79. // return 
  80. return $field; 
  81.  
  82.  
  83. /** 
  84. * get_result 
  85. * description 
  86. * @type function 
  87. * @date 5/02/2015 
  88. * @since 5.1.5 
  89. * @param $post_id (int) 
  90. * @return $post_id (int) 
  91. */ 
  92.  
  93. function get_result( $post, $field, $the_post, $options = array() ) { 
  94.  
  95. // right aligned info 
  96. $title = '<span class="relationship-item-info">'; 
  97.  
  98. if( in_array('post_type', $field['result_elements']) ) { 
  99.  
  100. $post_type_object = get_post_type_object( $post->post_type ); 
  101. $title .= $post_type_object->labels->singular_name; 
  102.  
  103.  
  104.  
  105. // WPML 
  106. if( !empty($options['lang']) ) { 
  107.  
  108. $title .= ' (' . $options['lang'] . ')'; 
  109.  
  110. } elseif( defined('ICL_LANGUAGE_CODE') ) { 
  111.  
  112. $title .= ' (' . ICL_LANGUAGE_CODE . ')'; 
  113.  
  114.  
  115. $title .= '</span>'; 
  116.  
  117.  
  118. // featured_image 
  119. if( in_array('featured_image', $field['result_elements']) ) { 
  120.  
  121. $image = ''; 
  122.  
  123. if( $post->post_type == 'attachment' ) { 
  124.  
  125. $image = wp_get_attachment_image( $post->ID, array(21, 21) ); 
  126.  
  127. } else { 
  128.  
  129. $image = get_the_post_thumbnail( $post->ID, array(21, 21) ); 
  130.  
  131.  
  132. $title .= '<div class="result-thumbnail">' . $image . '</div>'; 
  133.  
  134.  
  135.  
  136. // title 
  137. $post_title = get_the_title( $post->ID ); 
  138.  
  139.  
  140. // empty 
  141. if( $post_title === '' ) { 
  142.  
  143. $post_title = __('(no title)', 'acf'); 
  144.  
  145.  
  146.  
  147. $title .= $post_title; 
  148.  
  149.  
  150. // status 
  151. if( get_post_status( $post->ID ) != "publish" ) { 
  152.  
  153. $title .= ' (' . get_post_status( $post->ID ) . ')'; 
  154.  
  155.  
  156.  
  157. // filters 
  158. $title = apply_filters('acf/fields/relationship/result', $title, $post, $field, $the_post); 
  159. $title = apply_filters('acf/fields/relationship/result/name=' . $field['_name'] , $title, $post, $field, $the_post); 
  160. $title = apply_filters('acf/fields/relationship/result/key=' . $field['key'], $title, $post, $field, $the_post); 
  161.  
  162.  
  163. // return 
  164. return $title; 
  165.  
  166.  
  167.  
  168. /** 
  169. * query_posts 
  170. * @description:  
  171. * @since: 3.6 
  172. * @created: 27/01/13 
  173. */ 
  174.  
  175. function query_posts() 
  176. // vars 
  177. $r = array( 
  178. 'next_page_exists' => 1,  
  179. 'html' => '' 
  180. ); 
  181.  
  182.  
  183. // options 
  184. $options = array( 
  185. 'post_type' => 'all',  
  186. 'taxonomy' => 'all',  
  187. 'posts_per_page' => 10,  
  188. 'paged' => 1,  
  189. 'orderby' => 'title',  
  190. 'order' => 'ASC',  
  191. 'post_status' => 'any',  
  192. 'suppress_filters' => false,  
  193. 's' => '',  
  194. 'lang' => false,  
  195. 'update_post_meta_cache' => false,  
  196. 'field_key' => '',  
  197. 'nonce' => '',  
  198. 'ancestor' => false,  
  199. ); 
  200.  
  201. $options = array_merge( $options, $_POST ); 
  202.  
  203.  
  204. // validate 
  205. if( ! wp_verify_nonce($options['nonce'], 'acf_nonce') ) 
  206. die(); 
  207.  
  208.  
  209. // WPML 
  210. if( $options['lang'] ) 
  211. global $sitepress; 
  212.  
  213. if( !empty($sitepress) ) 
  214. $sitepress->switch_lang( $options['lang'] ); 
  215.  
  216.  
  217. // convert types 
  218. $options['post_type'] = explode(', ', $options['post_type']); 
  219. $options['taxonomy'] = explode(', ', $options['taxonomy']); 
  220.  
  221.  
  222. // load all post types by default 
  223. if( in_array('all', $options['post_type']) ) 
  224. $options['post_type'] = apply_filters('acf/get_post_types', array()); 
  225.  
  226.  
  227. // attachment doesn't work if it is the only item in an array??? 
  228. if( is_array($options['post_type']) && count($options['post_type']) == 1 ) 
  229. $options['post_type'] = $options['post_type'][0]; 
  230.  
  231.  
  232. // create tax queries 
  233. if( ! in_array('all', $options['taxonomy']) ) 
  234. // vars 
  235. $taxonomies = array(); 
  236. $options['tax_query'] = array(); 
  237.  
  238. foreach( $options['taxonomy'] as $v ) 
  239.  
  240. // find term (find taxonomy!) 
  241. // $term = array( 0 => $taxonomy, 1 => $term_id ) 
  242. $term = explode(':', $v);  
  243.  
  244.  
  245. // validate 
  246. if( !is_array($term) || !isset($term[1]) ) 
  247. continue; 
  248.  
  249.  
  250. // add to tax array 
  251. $taxonomies[ $term[0] ][] = $term[1]; 
  252.  
  253.  
  254.  
  255. // now create the tax queries 
  256. foreach( $taxonomies as $k => $v ) 
  257. $options['tax_query'][] = array( 
  258. 'taxonomy' => $k,  
  259. 'field' => 'id',  
  260. 'terms' => $v,  
  261. ); 
  262.  
  263. unset( $options['taxonomy'] ); 
  264.  
  265.  
  266. // load field 
  267. $field = array(); 
  268. if( $options['ancestor'] ) 
  269. $ancestor = apply_filters('acf/load_field', array(), $options['ancestor'] ); 
  270. $field = acf_get_child_field_from_parent_field( $options['field_key'], $ancestor ); 
  271. else 
  272. $field = apply_filters('acf/load_field', array(), $options['field_key'] ); 
  273.  
  274.  
  275. // get the post from which this field is rendered on 
  276. $the_post = get_post( $options['post_id'] ); 
  277.  
  278.  
  279. // filters 
  280. $options = apply_filters('acf/fields/relationship/query', $options, $field, $the_post); 
  281. $options = apply_filters('acf/fields/relationship/query/name=' . $field['_name'], $options, $field, $the_post ); 
  282. $options = apply_filters('acf/fields/relationship/query/key=' . $field['key'], $options, $field, $the_post ); 
  283.  
  284.  
  285. // query 
  286. $wp_query = new WP_Query( $options ); 
  287.  
  288.  
  289. // global 
  290. global $post; 
  291.  
  292.  
  293. // loop 
  294. while( $wp_query->have_posts() ) { 
  295.  
  296. $wp_query->the_post(); 
  297.  
  298.  
  299. // get title 
  300. $title = $this->get_result($post, $field, $the_post, $options); 
  301.  
  302.  
  303. // update html 
  304. $r['html'] .= '<li><a href="' . get_permalink($post->ID) . '" data-post_id="' . $post->ID . '">' . $title . '<span class="acf-button-add"></span></a></li>'; 
  305.  
  306.  
  307.  
  308. // next page 
  309. if( (int)$options['paged'] >= $wp_query->max_num_pages ) { 
  310.  
  311. $r['next_page_exists'] = 0; 
  312.  
  313.  
  314.  
  315. // reset 
  316. wp_reset_postdata(); 
  317.  
  318.  
  319. // return JSON 
  320. echo json_encode( $r ); 
  321.  
  322. die(); 
  323.  
  324.  
  325.  
  326. /** 
  327. * create_field() 
  328. * Create the HTML interface for your field 
  329. * @param $field - an array holding all the field's data 
  330. * @type action 
  331. * @since 3.6 
  332. * @date 23/01/13 
  333. */ 
  334.  
  335. function create_field( $field ) 
  336. // global 
  337. global $post; 
  338.  
  339.  
  340. // no row limit? 
  341. if( !$field['max'] || $field['max'] < 1 ) 
  342. $field['max'] = 9999; 
  343.  
  344.  
  345. // class 
  346. $class = ''; 
  347. if( $field['filters'] ) 
  348. foreach( $field['filters'] as $filter ) 
  349. $class .= ' has-' . $filter; 
  350.  
  351. $attributes = array( 
  352. 'max' => $field['max'],  
  353. 's' => '',  
  354. 'paged' => 1,  
  355. 'post_type' => implode(', ', $field['post_type']),  
  356. 'taxonomy' => implode(', ', $field['taxonomy']),  
  357. 'field_key' => $field['key'] 
  358. ); 
  359.  
  360.  
  361. // Lang 
  362. if( defined('ICL_LANGUAGE_CODE') ) 
  363. $attributes['lang'] = ICL_LANGUAGE_CODE; 
  364.  
  365.  
  366. // parent 
  367. preg_match('/\[(field_.*?)\]/', $field['name'], $ancestor); 
  368. if( isset($ancestor[1]) && $ancestor[1] != $field['key']) 
  369. $attributes['ancestor'] = $ancestor[1]; 
  370.  
  371. ?> 
  372. <div class="acf_relationship<?php echo $class; ?>"<?php foreach( $attributes as $k => $v ): ?> data-<?php echo $k; ?>="<?php echo $v; ?>"<?php endforeach; ?>> 
  373.  
  374.  
  375. <!-- Hidden Blank default value --> 
  376. <input type="hidden" name="<?php echo $field['name']; ?>" value="" /> 
  377.  
  378.  
  379. <!-- Left List --> 
  380. <div class="relationship_left"> 
  381. <table class="widefat"> 
  382. <thead> 
  383. <?php if(in_array( 'search', $field['filters']) ): ?> 
  384. <tr> 
  385. <th> 
  386. <input class="relationship_search" placeholder="<?php _e("Search...", 'acf'); ?>" type="text" id="relationship_<?php echo $field['name']; ?>" /> 
  387. </th> 
  388. </tr> 
  389. <?php endif; ?> 
  390. <?php if(in_array( 'post_type', $field['filters']) ): ?> 
  391. <tr> 
  392. <th> 
  393. <?php  
  394.  
  395. // vars 
  396. $choices = array( 
  397. 'all' => __("Filter by post type", 'acf') 
  398. ); 
  399.  
  400.  
  401. if( in_array('all', $field['post_type']) ) 
  402. $post_types = apply_filters( 'acf/get_post_types', array() ); 
  403. $choices = array_merge( $choices, $post_types); 
  404. else 
  405. foreach( $field['post_type'] as $post_type ) 
  406. $choices[ $post_type ] = $post_type; 
  407.  
  408.  
  409. // create field 
  410. do_action('acf/create_field', array( 
  411. 'type' => 'select',  
  412. 'name' => '',  
  413. 'class' => 'select-post_type',  
  414. 'value' => '',  
  415. 'choices' => $choices,  
  416. )); 
  417.  
  418. ?> 
  419. </th> 
  420. </tr> 
  421. <?php endif; ?> 
  422. </thead> 
  423. </table> 
  424. <ul class="bl relationship_list"> 
  425. <li class="load-more"> 
  426. <div class="acf-loading"></div> 
  427. </li> 
  428. </ul> 
  429. </div> 
  430. <!-- /Left List --> 
  431.  
  432. <!-- Right List --> 
  433. <div class="relationship_right"> 
  434. <ul class="bl relationship_list"> 
  435. <?php 
  436.  
  437. if( $field['value'] ) 
  438. foreach( $field['value'] as $p ) 
  439. $title = $this->get_result($p, $field, $post); 
  440.  
  441.  
  442. echo '<li> 
  443. <a href="' . get_permalink($p->ID) . '" class="" data-post_id="' . $p->ID . '">' . $title . '<span class="acf-button-remove"></span></a> 
  444. <input type="hidden" name="' . $field['name'] . '[]" value="' . $p->ID . '" /> 
  445. </li>'; 
  446.  
  447.  
  448.  
  449. ?> 
  450. </ul> 
  451. </div> 
  452. <!-- / Right List --> 
  453.  
  454. </div> 
  455. <?php 
  456.  
  457.  
  458.  
  459. /** 
  460. * create_options() 
  461. * Create extra options for your field. This is rendered when editing a field. 
  462. * The value of $field['name'] can be used (like bellow) to save extra data to the $field 
  463. * @type action 
  464. * @since 3.6 
  465. * @date 23/01/13 
  466. * @param $field - an array holding all the field's data 
  467. */ 
  468.  
  469. function create_options( $field ) 
  470. // vars 
  471. $key = $field['name']; 
  472.  
  473. ?> 
  474. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  475. <td class="label"> 
  476. <label><?php _e("Return Format", 'acf'); ?></label> 
  477. <p><?php _e("Specify the returned value on front end", 'acf') ?></p> 
  478. </td> 
  479. <td> 
  480. <?php 
  481. do_action('acf/create_field', array( 
  482. 'type' => 'radio',  
  483. 'name' => 'fields['.$key.'][return_format]',  
  484. 'value' => $field['return_format'],  
  485. 'layout' => 'horizontal',  
  486. 'choices' => array( 
  487. 'object' => __("Post Objects", 'acf'),  
  488. 'id' => __("Post IDs", 'acf') 
  489. )); 
  490. ?> 
  491. </td> 
  492. </tr> 
  493. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  494. <td class="label"> 
  495. <label for=""><?php _e("Post Type", 'acf'); ?></label> 
  496. </td> 
  497. <td> 
  498. <?php  
  499.  
  500. $choices = array( 
  501. 'all' => __("All", 'acf') 
  502. ); 
  503. $choices = apply_filters('acf/get_post_types', $choices); 
  504.  
  505.  
  506. do_action('acf/create_field', array( 
  507. 'type' => 'select',  
  508. 'name' => 'fields['.$key.'][post_type]',  
  509. 'value' => $field['post_type'],  
  510. 'choices' => $choices,  
  511. 'multiple' => 1,  
  512. )); 
  513.  
  514. ?> 
  515. </td> 
  516. </tr> 
  517. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  518. <td class="label"> 
  519. <label><?php _e("Filter from Taxonomy", 'acf'); ?></label> 
  520. </td> 
  521. <td> 
  522. <?php  
  523. $choices = array( 
  524. '' => array( 
  525. 'all' => __("All", 'acf') 
  526. ); 
  527. $simple_value = false; 
  528. $choices = apply_filters('acf/get_taxonomies_for_select', $choices, $simple_value); 
  529.  
  530.  
  531. do_action('acf/create_field', array( 
  532. 'type' => 'select',  
  533. 'name' => 'fields['.$key.'][taxonomy]',  
  534. 'value' => $field['taxonomy'],  
  535. 'choices' => $choices,  
  536. 'multiple' => 1,  
  537. )); 
  538. ?> 
  539. </td> 
  540. </tr> 
  541. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  542. <td class="label"> 
  543. <label><?php _e("Filters", 'acf'); ?></label> 
  544. </td> 
  545. <td> 
  546. <?php  
  547. do_action('acf/create_field', array( 
  548. 'type' => 'checkbox',  
  549. 'name' => 'fields['.$key.'][filters]',  
  550. 'value' => $field['filters'],  
  551. 'choices' => array( 
  552. 'search' => __("Search", 'acf'),  
  553. 'post_type' => __("Post Type Select", 'acf'),  
  554. )); 
  555. ?> 
  556. </td> 
  557. </tr> 
  558. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  559. <td class="label"> 
  560. <label><?php _e("Elements", 'acf'); ?></label> 
  561. <p><?php _e("Selected elements will be displayed in each result", 'acf') ?></p> 
  562. </td> 
  563. <td> 
  564. <?php  
  565. do_action('acf/create_field', array( 
  566. 'type' => 'checkbox',  
  567. 'name' => 'fields['.$key.'][result_elements]',  
  568. 'value' => $field['result_elements'],  
  569. 'choices' => array( 
  570. 'featured_image' => __("Featured Image", 'acf'),  
  571. 'post_title' => __("Post Title", 'acf'),  
  572. 'post_type' => __("Post Type", 'acf'),  
  573. ),  
  574. 'disabled' => array( 
  575. 'post_title' 
  576. )); 
  577. ?> 
  578. </td> 
  579. </tr> 
  580. <tr class="field_option field_option_<?php echo $this->name; ?>"> 
  581. <td class="label"> 
  582. <label><?php _e("Maximum posts", 'acf'); ?></label> 
  583. </td> 
  584. <td> 
  585. <?php  
  586. do_action('acf/create_field', array( 
  587. 'type' => 'number',  
  588. 'name' => 'fields['.$key.'][max]',  
  589. 'value' => $field['max'],  
  590. )); 
  591. ?> 
  592. </td> 
  593. </tr> 
  594. <?php 
  595.  
  596.  
  597.  
  598. /** 
  599. * format_value() 
  600. * This filter is appied to the $value after it is loaded from the db and before it is passed to the create_field action 
  601. * @type filter 
  602. * @since 3.6 
  603. * @date 23/01/13 
  604. * @param $value - the value which was loaded from the database 
  605. * @param $post_id - the $post_id from which the value was loaded 
  606. * @param $field - the field array holding all the field options 
  607. * @return $value - the modified value 
  608. */ 
  609.  
  610. function format_value( $value, $post_id, $field ) 
  611. // empty? 
  612. if( !empty($value) ) 
  613. // Pre 3.3.3, the value is a string coma seperated 
  614. if( is_string($value) ) 
  615. $value = explode(', ', $value); 
  616.  
  617.  
  618. // convert to integers 
  619. if( is_array($value) ) 
  620. $value = array_map('intval', $value); 
  621.  
  622. // convert into post objects 
  623. $value = $this->get_posts( $value ); 
  624.  
  625.  
  626.  
  627. // return value 
  628. return $value;  
  629.  
  630.  
  631. /** 
  632. * format_value_for_api() 
  633. * This filter is appied to the $value after it is loaded from the db and before it is passed back to the api functions such as the_field 
  634. * @type filter 
  635. * @since 3.6 
  636. * @date 23/01/13 
  637. * @param $value - the value which was loaded from the database 
  638. * @param $post_id - the $post_id from which the value was loaded 
  639. * @param $field - the field array holding all the field options 
  640. * @return $value - the modified value 
  641. */ 
  642.  
  643. function format_value_for_api( $value, $post_id, $field ) 
  644. // empty? 
  645. if( !$value ) 
  646. return $value; 
  647.  
  648.  
  649. // Pre 3.3.3, the value is a string coma seperated 
  650. if( is_string($value) ) 
  651. $value = explode(', ', $value); 
  652.  
  653.  
  654. // empty? 
  655. if( !is_array($value) || empty($value) ) 
  656. return $value; 
  657.  
  658.  
  659. // convert to integers 
  660. $value = array_map('intval', $value); 
  661.  
  662.  
  663. // return format 
  664. if( $field['return_format'] == 'object' ) 
  665. $value = $this->get_posts( $value );  
  666.  
  667.  
  668. // return 
  669. return $value; 
  670.  
  671.  
  672.  
  673. /** 
  674. * get_posts 
  675. * This function will take an array of post_id's ($value) and return an array of post_objects 
  676. * @type function 
  677. * @date 7/08/13 
  678. * @param $post_ids (array) the array of post ID's 
  679. * @return (array) an array of post objects 
  680. */ 
  681.  
  682. function get_posts( $post_ids ) 
  683. // validate 
  684. if( empty($post_ids) ) 
  685. return $post_ids; 
  686.  
  687.  
  688. // vars 
  689. $r = array(); 
  690.  
  691.  
  692. // find posts (DISTINCT POSTS) 
  693. $posts = get_posts(array( 
  694. 'numberposts' => -1,  
  695. 'post__in' => $post_ids,  
  696. 'post_type' => apply_filters('acf/get_post_types', array()),  
  697. 'post_status' => 'any',  
  698. )); 
  699.  
  700.  
  701. $ordered_posts = array(); 
  702. foreach( $posts as $p ) 
  703. // create array to hold value data 
  704. $ordered_posts[ $p->ID ] = $p; 
  705.  
  706.  
  707. // override value array with attachments 
  708. foreach( $post_ids as $k => $v) 
  709. // check that post exists (my have been trashed) 
  710. if( isset($ordered_posts[ $v ]) ) 
  711. $r[] = $ordered_posts[ $v ]; 
  712.  
  713.  
  714. // return 
  715. return $r; 
  716.  
  717.  
  718. /** 
  719. * update_value() 
  720. * This filter is appied to the $value before it is updated in the db 
  721. * @type filter 
  722. * @since 3.6 
  723. * @date 23/01/13 
  724. * @param $value - the value which will be saved in the database 
  725. * @param $post_id - the $post_id of which the value will be saved 
  726. * @param $field - the field array holding all the field options 
  727. * @return $value - the modified value 
  728. */ 
  729.  
  730. function update_value( $value, $post_id, $field ) 
  731. // validate 
  732. if( empty($value) ) 
  733. return $value; 
  734.  
  735.  
  736. if( is_string($value) ) 
  737. // string 
  738. $value = explode(', ', $value); 
  739.  
  740. elseif( is_object($value) && isset($value->ID) ) 
  741. // object 
  742. $value = array( $value->ID ); 
  743.  
  744. elseif( is_array($value) ) 
  745. // array 
  746. foreach( $value as $k => $v ) { 
  747.  
  748. // object? 
  749. if( is_object($v) && isset($v->ID) ) 
  750. $value[ $k ] = $v->ID; 
  751.  
  752.  
  753.  
  754. // save value as strings, so we can clearly search for them in SQL LIKE statements 
  755. $value = array_map('strval', $value); 
  756.  
  757.  
  758. return $value; 
  759.