Complex classes like GravityView_Widget_Search often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use GravityView_Widget_Search, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 16 | class GravityView_Widget_Search extends \GV\Widget { |
||
| 17 | |||
| 18 | public static $file; |
||
| 19 | public static $instance; |
||
| 20 | |||
| 21 | private $search_filters = array(); |
||
| 22 | |||
| 23 | /** |
||
| 24 | * whether search method is GET or POST ( default: GET ) |
||
| 25 | * @since 1.16.4 |
||
| 26 | * @var string |
||
| 27 | */ |
||
| 28 | private $search_method = 'get'; |
||
| 29 | |||
| 30 | 36 | public function __construct() { |
|
| 103 | |||
| 104 | /** |
||
| 105 | * @return GravityView_Widget_Search |
||
| 106 | */ |
||
| 107 | 5 | public static function getInstance() { |
|
| 113 | |||
| 114 | /** |
||
| 115 | * Sets the search method to GET (default) or POST |
||
| 116 | * @since 1.16.4 |
||
| 117 | */ |
||
| 118 | 36 | private function set_search_method() { |
|
| 131 | |||
| 132 | /** |
||
| 133 | * Returns the search method |
||
| 134 | * @since 1.16.4 |
||
| 135 | * @return string |
||
| 136 | */ |
||
| 137 | 5 | public function get_search_method() { |
|
| 140 | |||
| 141 | /** |
||
| 142 | * Get the input types available for different field types |
||
| 143 | * |
||
| 144 | * @since 1.17.5 |
||
| 145 | * |
||
| 146 | * @return array [field type name] => (array|string) search bar input types |
||
| 147 | */ |
||
| 148 | public static function get_input_types_by_field_type() { |
||
| 177 | |||
| 178 | /** |
||
| 179 | * Get labels for different types of search bar inputs |
||
| 180 | * |
||
| 181 | * @since 1.17.5 |
||
| 182 | * |
||
| 183 | * @return array [input type] => input type label |
||
| 184 | */ |
||
| 185 | public static function get_search_input_labels() { |
||
| 211 | |||
| 212 | public static function get_search_input_label( $input_type ) { |
||
| 217 | |||
| 218 | /** |
||
| 219 | * Add script to Views edit screen (admin) |
||
| 220 | * @param mixed $hook |
||
| 221 | */ |
||
| 222 | public function add_scripts_and_styles( $hook ) { |
||
| 248 | |||
| 249 | /** |
||
| 250 | * Add admin script to the no-conflict scripts whitelist |
||
| 251 | * @param array $allowed Scripts allowed in no-conflict mode |
||
| 252 | * @return array Scripts allowed in no-conflict mode, plus the search widget script |
||
| 253 | */ |
||
| 254 | public function register_no_conflict( $allowed ) { |
||
| 258 | |||
| 259 | /** |
||
| 260 | * Ajax |
||
| 261 | * Returns the form fields ( only the searchable ones ) |
||
| 262 | * |
||
| 263 | * @access public |
||
| 264 | * @return void |
||
| 265 | */ |
||
| 266 | public static function get_searchable_fields() { |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Generates html for the available Search Fields dropdown |
||
| 297 | * @param int $form_id |
||
| 298 | * @param string $current (for future use) |
||
| 299 | * @return string |
||
| 300 | */ |
||
| 301 | public static function render_searchable_fields( $form_id = null, $current = '' ) { |
||
| 379 | |||
| 380 | /** |
||
| 381 | * Assign an input type according to the form field type |
||
| 382 | * |
||
| 383 | * @see admin-search-widget.js |
||
| 384 | * |
||
| 385 | * @param string|int|float $field_id Gravity Forms field ID |
||
| 386 | * @param string $field_type Gravity Forms field type (also the `name` parameter of GravityView_Field classes) |
||
| 387 | * |
||
| 388 | * @return string GV field search input type ('multi', 'boolean', 'select', 'date', 'text') |
||
| 389 | */ |
||
| 390 | public static function get_search_input_types( $field_id = '', $field_type = null ) { |
||
| 421 | |||
| 422 | /** |
||
| 423 | * Display hidden fields to add support for sites using Default permalink structure |
||
| 424 | * |
||
| 425 | * @since 1.8 |
||
| 426 | * @return array Search fields, modified if not using permalinks |
||
| 427 | */ |
||
| 428 | 4 | public function add_no_permalink_fields( $search_fields, $object, $widget_args = array() ) { |
|
| 461 | |||
| 462 | /** |
||
| 463 | * Get the fields that are searchable for a View |
||
| 464 | * |
||
| 465 | * @since 2.0 |
||
| 466 | * @since 2.0.9 Added $with_full_field parameter |
||
| 467 | * |
||
| 468 | * @param \GV\View|null $view |
||
| 469 | * @param bool $with_full_field Return full field array, or just field ID? Default: false (just field ID) |
||
| 470 | * |
||
| 471 | * TODO: Move to \GV\View, perhaps? And return a Field_Collection |
||
| 472 | * TODO: Use in gravityview()->request->is_search() to calculate whether a valid search |
||
| 473 | * |
||
| 474 | * @return array If no View, returns empty array. Otherwise, returns array of fields configured in widgets and Search Bar for a View |
||
| 475 | */ |
||
| 476 | 33 | private function get_view_searchable_fields( $view, $with_full_field = false ) { |
|
| 518 | |||
| 519 | /** --- Frontend --- */ |
||
| 520 | |||
| 521 | /** |
||
| 522 | * Calculate the search criteria to filter entries |
||
| 523 | * @param array $search_criteria The search criteria |
||
| 524 | * @param int $form_id The form ID |
||
| 525 | * @param array $args Some args |
||
| 526 | * |
||
| 527 | * @param bool $force_search_criteria Whether to suppress GF_Query filter, internally used in self::gf_query_filter |
||
| 528 | * |
||
| 529 | * @return array |
||
| 530 | */ |
||
| 531 | 78 | public function filter_entries( $search_criteria, $form_id = null, $args = array(), $force_search_criteria = false ) { |
|
| 728 | |||
| 729 | /** |
||
| 730 | * Filters the \GF_Query with advanced logic. |
||
| 731 | * |
||
| 732 | * Dropin for the legacy flat filters when \GF_Query is available. |
||
| 733 | * |
||
| 734 | * @param \GF_Query $query The current query object reference |
||
| 735 | * @param \GV\View $this The current view object |
||
| 736 | * @param \GV\Request $request The request object |
||
| 737 | */ |
||
| 738 | 58 | public function gf_query_filter( &$query, $view, $request ) { |
|
| 739 | /** |
||
| 740 | * This is a shortcut to get all the needed search criteria. |
||
| 741 | * We feed these into an new GF_Query and tack them onto the current object. |
||
| 742 | */ |
||
| 743 | 58 | $search_criteria = $this->filter_entries( array(), null, array( 'id' => $view->ID ), true /** force search_criteria */ ); |
|
| 744 | |||
| 745 | /** |
||
| 746 | * Call any userland filters that they might have. |
||
| 747 | */ |
||
| 748 | 58 | remove_filter( 'gravityview_fe_search_criteria', array( $this, 'filter_entries' ), 10, 3 ); |
|
| 749 | 58 | $search_criteria = apply_filters( 'gravityview_fe_search_criteria', $search_criteria, $view->form->ID, $view->settings->as_atts() ); |
|
| 750 | 58 | add_filter( 'gravityview_fe_search_criteria', array( $this, 'filter_entries' ), 10, 3 ); |
|
| 751 | |||
| 752 | 58 | $query_class = $view->get_query_class(); |
|
| 753 | |||
| 754 | 58 | if ( empty( $search_criteria['field_filters'] ) ) { |
|
| 755 | 53 | return; |
|
| 756 | } |
||
| 757 | |||
| 758 | 15 | $widgets = $view->widgets->by_id( $this->widget_id ); |
|
| 759 | 15 | if ( $widgets->count() ) { |
|
| 760 | 12 | $widgets = $widgets->all(); |
|
| 761 | 12 | $widget = $widgets[0]; |
|
| 762 | |||
| 763 | 12 | $search_fields = json_decode( $widget->configuration->get( 'search_fields' ), true ); |
|
| 764 | |||
| 765 | 12 | foreach ( (array) $search_fields as $search_field ) { |
|
| 766 | 12 | if ( 'created_by' === $search_field['field'] && 'input_text' === $search_field['input'] ) { |
|
| 767 | 1 | $created_by_text_mode = true; |
|
| 768 | } |
||
| 769 | } |
||
| 770 | } |
||
| 771 | |||
| 772 | 15 | $extra_conditions = array(); |
|
| 773 | 15 | $mode = 'any'; |
|
| 774 | |||
| 775 | 15 | foreach ( $search_criteria['field_filters'] as &$filter ) { |
|
| 776 | 15 | if ( ! is_array( $filter ) ) { |
|
| 777 | 15 | if ( in_array( strtolower( $filter ), array( 'any', 'all' ) ) ) { |
|
| 778 | 15 | $mode = $filter; |
|
| 779 | } |
||
| 780 | 15 | continue; |
|
| 781 | } |
||
| 782 | |||
| 783 | // Construct a manual query for unapproved statuses |
||
| 784 | 11 | if ( 'is_approved' === $filter['key'] && in_array( \GravityView_Entry_Approval_Status::UNAPPROVED, (array) $filter['value'] ) ) { |
|
| 785 | 2 | $_tmp_query = new $query_class( $view->form->ID, array( |
|
| 786 | 2 | 'field_filters' => array( |
|
| 787 | array( |
||
| 788 | 2 | 'operator' => 'in', |
|
| 789 | 2 | 'key' => 'is_approved', |
|
| 790 | 2 | 'value' => (array) $filter['value'], |
|
| 791 | ), |
||
| 792 | array( |
||
| 793 | 'operator' => 'is', |
||
| 794 | 'key' => 'is_approved', |
||
| 795 | 'value' => '', |
||
| 796 | ), |
||
| 797 | 2 | 'mode' => 'any' |
|
| 798 | ), |
||
| 799 | ) ); |
||
| 800 | 2 | $_tmp_query_parts = $_tmp_query->_introspect(); |
|
| 801 | |||
| 802 | 2 | $extra_conditions[] = $_tmp_query_parts['where']; |
|
| 803 | |||
| 804 | 2 | $filter = false; |
|
| 805 | 2 | continue; |
|
| 806 | } |
||
| 807 | |||
| 808 | // Construct manual query for text mode creator search |
||
| 809 | 11 | if ( 'created_by' === $filter['key'] && ! empty( $created_by_text_mode ) ) { |
|
| 810 | 1 | $extra_conditions[] = new GravityView_Widget_Search_Author_GF_Query_Condition( $filter, $view ); |
|
| 811 | 1 | $filter = false; |
|
| 812 | 1 | continue; |
|
| 813 | } |
||
| 814 | |||
| 815 | // By default, we want searches to be wildcard for each field. |
||
| 816 | 10 | $filter['operator'] = empty( $filter['operator'] ) ? 'contains' : $filter['operator']; |
|
| 817 | |||
| 818 | // For multichoice, let's have an in (OR) search. |
||
| 819 | 10 | if ( is_array( $filter['value'] ) ) { |
|
| 820 | 3 | $filter['operator'] = 'in'; // @todo what about in contains (OR LIKE chains)? |
|
| 821 | } |
||
| 822 | |||
| 823 | // Default form with joins functionality |
||
| 824 | 10 | if ( empty( $filter['form_id'] ) ) { |
|
| 825 | 3 | $filter['form_id'] = $view->form ? $view->form->ID : 0; |
|
| 826 | } |
||
| 827 | |||
| 828 | /** |
||
| 829 | * @filter `gravityview_search_operator` Modify the search operator for the field (contains, is, isnot, etc) |
||
| 830 | * @param string $operator Existing search operator |
||
| 831 | * @param array $filter array with `key`, `value`, `operator`, `type` keys |
||
| 832 | * @since develop |
||
| 833 | * @param \GV\View $view The View we're operating on. |
||
| 834 | */ |
||
| 835 | 10 | $filter['operator'] = apply_filters( 'gravityview_search_operator', $filter['operator'], $filter, $view ); |
|
| 836 | } |
||
| 837 | |||
| 838 | 15 | if ( ! empty( $search_criteria['start_date'] ) || ! empty( $search_criteria['end_date'] ) ) { |
|
| 839 | 1 | $date_criteria = array(); |
|
| 840 | |||
| 841 | 1 | if ( isset( $search_criteria['start_date'] ) ) { |
|
| 842 | 1 | $date_criteria['start_date'] = $search_criteria['start_date']; |
|
| 843 | } |
||
| 844 | |||
| 845 | 1 | if ( isset( $search_criteria['end_date'] ) ) { |
|
| 846 | 1 | $date_criteria['end_date'] = $search_criteria['end_date']; |
|
| 847 | } |
||
| 848 | |||
| 849 | 1 | $_tmp_query = new $query_class( $view->form->ID, $date_criteria ); |
|
| 850 | 1 | $_tmp_query_parts = $_tmp_query->_introspect(); |
|
| 851 | 1 | $extra_conditions[] = $_tmp_query_parts['where']; |
|
| 852 | } |
||
| 853 | |||
| 854 | 15 | $search_conditions = array(); |
|
| 855 | |||
| 856 | 15 | if ( $filters = array_filter( $search_criteria['field_filters'] ) ) { |
|
| 857 | |||
| 858 | 15 | foreach ( $filters as $filter ) { |
|
| 859 | 15 | if ( ! is_array( $filter ) ) { |
|
| 860 | 8 | continue; |
|
| 861 | } |
||
| 862 | |||
| 863 | /** |
||
| 864 | * Parse the filter criteria to generate the needed |
||
| 865 | * WHERE condition. This is a trick to not write our own generation |
||
| 866 | * code by reusing what's inside GF_Query already as they |
||
| 867 | * take care of many small things like forcing numeric, etc. |
||
| 868 | */ |
||
| 869 | 10 | $_tmp_query = new $query_class( $filter['form_id'], array( 'mode' => 'any', 'field_filters' => array( $filter ) ) ); |
|
| 870 | 10 | $_tmp_query_parts = $_tmp_query->_introspect(); |
|
| 871 | 10 | $search_condition = $_tmp_query_parts['where']; |
|
| 872 | |||
| 873 | 10 | if ( empty( $filter['key'] ) && $search_condition->expressions ) { |
|
| 874 | 1 | $search_conditions[] = $search_condition; // new GravityView_Widget_Search_All_GF_Query_Condition( $search_condition, $view ); |
|
| 875 | } else { |
||
| 876 | 9 | $left = $search_condition->left; |
|
| 877 | 9 | $alias = $query->_alias( $left->field_id, $left->source, $left->is_entry_column() ? 't' : 'm' ); |
|
| 878 | |||
| 879 | 9 | if ( $view->joins && $left->field_id == GF_Query_Column::META ) { |
|
| 880 | $search_conditions[] = new GravityView_Widget_Search_All_GF_Query_Condition( $search_condition, $view ); |
||
| 881 | } else { |
||
| 882 | 9 | $search_conditions[] = new GF_Query_Condition( |
|
| 883 | 9 | new GF_Query_Column( $left->field_id, $left->source, $alias ), |
|
| 884 | 9 | $search_condition->operator, |
|
| 885 | 9 | $search_condition->right |
|
| 886 | ); |
||
| 887 | } |
||
| 888 | } |
||
| 889 | } |
||
| 890 | |||
| 891 | 15 | if ( $search_conditions ) { |
|
| 892 | 10 | $search_conditions = array( call_user_func_array( '\GF_Query_Condition::' . ( $mode == 'all' ? '_and' : '_or' ), $search_conditions ) ); |
|
| 893 | } |
||
| 894 | } |
||
| 895 | |||
| 896 | /** |
||
| 897 | * Grab the current clauses. We'll be combining them shortly. |
||
| 898 | */ |
||
| 899 | 15 | $query_parts = $query->_introspect(); |
|
| 900 | |||
| 901 | /** |
||
| 902 | * Combine the parts as a new WHERE clause. |
||
| 903 | */ |
||
| 904 | 15 | $where = call_user_func_array( '\GF_Query_Condition::_and', array_merge( array( $query_parts['where'] ), $search_conditions, $extra_conditions ) ); |
|
| 905 | 15 | $query->where( $where ); |
|
| 906 | 15 | } |
|
| 907 | |||
| 908 | /** |
||
| 909 | * Convert $_GET/$_POST key to the field/meta ID |
||
| 910 | * |
||
| 911 | * Examples: |
||
| 912 | * - `filter_is_starred` => `is_starred` |
||
| 913 | * - `filter_1_2` => `1.2` |
||
| 914 | * - `filter_5` => `5` |
||
| 915 | * |
||
| 916 | * @since 2.0 |
||
| 917 | * |
||
| 918 | * @param string $key $_GET/_$_POST search key |
||
| 919 | * |
||
| 920 | * @return string |
||
| 921 | */ |
||
| 922 | 16 | private function convert_request_key_to_filter_key( $key ) { |
|
| 923 | |||
| 924 | 16 | $field_id = str_replace( 'filter_', '', $key ); |
|
| 925 | |||
| 926 | // calculates field_id, removing 'filter_' and for '_' for advanced fields ( like name or checkbox ) |
||
| 927 | 16 | if ( preg_match('/^[0-9_]+$/ism', $field_id ) ) { |
|
| 928 | 14 | $field_id = str_replace( '_', '.', $field_id ); |
|
| 929 | } |
||
| 930 | |||
| 931 | 16 | return $field_id; |
|
| 932 | } |
||
| 933 | |||
| 934 | /** |
||
| 935 | * Prepare the field filters to GFAPI |
||
| 936 | * |
||
| 937 | * The type post_category, multiselect and checkbox support multi-select search - each value needs to be separated in an independent filter so we could apply the ANY search mode. |
||
| 938 | * |
||
| 939 | * Format searched values |
||
| 940 | * |
||
| 941 | * @param string $filter_key ID of the field, or entry meta key |
||
| 942 | * @param string $value $_GET/$_POST search value |
||
| 943 | * @param \GV\View $view The view we're looking at |
||
| 944 | * @param array[] $searchable_fields The searchable fields as configured by the widget. |
||
| 945 | * @param string[] $get The $_GET/$_POST array. |
||
| 946 | * |
||
| 947 | * @since develop Added 5th $get parameter for operator overrides. |
||
| 948 | * @todo Set function as private. |
||
| 949 | * |
||
| 950 | * @return array|false 1 or 2 deph levels, false if not allowed |
||
| 951 | */ |
||
| 952 | 16 | public function prepare_field_filter( $filter_key, $value, $view, $searchable_fields, $get = array() ) { |
|
| 953 | 16 | $key = $filter_key; |
|
| 954 | 16 | $filter_key = explode( ':', $filter_key ); // field_id, form_id |
|
| 955 | |||
| 956 | 16 | $form = null; |
|
| 957 | |||
| 958 | 16 | if ( count( $filter_key ) > 1 ) { |
|
| 959 | // form is specified |
||
| 960 | 1 | list( $field_id, $form_id ) = $filter_key; |
|
| 961 | |||
| 962 | 1 | if ( $forms = \GV\View::get_joined_forms( $view->ID ) ) { |
|
| 963 | 1 | if ( ! $form = \GV\GF_Form::by_id( $form_id ) ) { |
|
| 964 | return false; |
||
| 965 | } |
||
| 966 | } |
||
| 967 | |||
| 968 | // form is allowed |
||
| 969 | 1 | $found = false; |
|
| 970 | 1 | foreach ( $forms as $form ) { |
|
| 971 | 1 | if ( $form->ID == $form_id ) { |
|
| 972 | 1 | $found = true; |
|
| 973 | 1 | break; |
|
| 974 | } |
||
| 975 | } |
||
| 976 | |||
| 977 | 1 | if ( ! $found ) { |
|
| 978 | return false; |
||
| 979 | } |
||
| 980 | |||
| 981 | // form is in searchable fields |
||
| 982 | 1 | $found = false; |
|
| 983 | 1 | foreach ( $searchable_fields as $field ) { |
|
| 984 | 1 | if ( $field_id == $field['field'] && $form->ID == $field['form_id'] ) { |
|
| 985 | 1 | $found = true; |
|
| 986 | 1 | break; |
|
| 987 | } |
||
| 988 | } |
||
| 989 | |||
| 990 | 1 | if ( ! $found ) { |
|
| 991 | 1 | return false; |
|
| 992 | } |
||
| 993 | } else { |
||
| 994 | 16 | $field_id = reset( $filter_key ); |
|
| 995 | 16 | $searchable_fields = wp_list_pluck( $searchable_fields, 'field' ); |
|
| 996 | 16 | if ( ! in_array( 'search_all', $searchable_fields ) && ! in_array( $field_id, $searchable_fields ) ) { |
|
| 997 | 1 | return false; |
|
| 998 | } |
||
| 999 | } |
||
| 1000 | |||
| 1001 | 15 | if ( ! $form ) { |
|
| 1002 | // fallback |
||
| 1003 | 15 | $form = $view->form; |
|
| 1004 | } |
||
| 1005 | |||
| 1006 | // get form field array |
||
| 1007 | 15 | $form_field = is_numeric( $field_id ) ? \GV\GF_Field::by_id( $form, $field_id ) : \GV\Internal_Field::by_id( $field_id ); |
|
| 1008 | |||
| 1009 | // default filter array |
||
| 1010 | $filter = array( |
||
| 1011 | 15 | 'key' => $field_id, |
|
| 1012 | 15 | 'value' => $value, |
|
| 1013 | 15 | 'form_id' => $form->ID, |
|
| 1014 | ); |
||
| 1015 | |||
| 1016 | 15 | switch ( $form_field->type ) { |
|
| 1017 | |||
| 1018 | 15 | case 'select': |
|
| 1019 | 15 | case 'radio': |
|
| 1020 | 1 | $filter['operator'] = $this->get_operator( $get, $key, array( 'is' ), 'is' ); |
|
| 1021 | 1 | break; |
|
| 1022 | |||
| 1023 | 14 | case 'post_category': |
|
| 1024 | |||
| 1025 | if ( ! is_array( $value ) ) { |
||
| 1026 | $value = array( $value ); |
||
| 1027 | } |
||
| 1028 | |||
| 1029 | // Reset filter variable |
||
| 1030 | $filter = array(); |
||
| 1031 | |||
| 1032 | foreach ( $value as $val ) { |
||
| 1033 | $cat = get_term( $val, 'category' ); |
||
| 1034 | $filter[] = array( |
||
| 1035 | 'key' => $field_id, |
||
| 1036 | 'value' => esc_attr( $cat->name ) . ':' . $val, |
||
| 1037 | 'operator' => $this->get_operator( $get, $key, array( 'is' ), 'is' ), |
||
| 1038 | ); |
||
| 1039 | } |
||
| 1040 | |||
| 1041 | break; |
||
| 1042 | |||
| 1043 | 14 | case 'multiselect': |
|
| 1044 | |||
| 1045 | if ( ! is_array( $value ) ) { |
||
| 1046 | break; |
||
| 1047 | } |
||
| 1048 | |||
| 1049 | // Reset filter variable |
||
| 1050 | $filter = array(); |
||
| 1051 | |||
| 1052 | foreach ( $value as $val ) { |
||
| 1053 | $filter[] = array( 'key' => $field_id, 'value' => $val ); |
||
| 1054 | } |
||
| 1055 | |||
| 1056 | break; |
||
| 1057 | |||
| 1058 | 14 | case 'checkbox': |
|
| 1059 | // convert checkbox on/off into the correct search filter |
||
| 1060 | if ( false !== strpos( $field_id, '.' ) && ! empty( $form_field->inputs ) && ! empty( $form_field->choices ) ) { |
||
| 1061 | foreach ( $form_field->inputs as $k => $input ) { |
||
| 1062 | if ( $input['id'] == $field_id ) { |
||
| 1063 | $filter['value'] = $form_field->choices[ $k ]['value']; |
||
| 1064 | $filter['operator'] = $this->get_operator( $get, $key, array( 'is' ), 'is' ); |
||
| 1065 | break; |
||
| 1066 | } |
||
| 1067 | } |
||
| 1068 | } elseif ( is_array( $value ) ) { |
||
| 1069 | |||
| 1070 | // Reset filter variable |
||
| 1071 | $filter = array(); |
||
| 1072 | |||
| 1073 | foreach ( $value as $val ) { |
||
| 1074 | $filter[] = array( |
||
| 1075 | 'key' => $field_id, |
||
| 1076 | 'value' => $val, |
||
| 1077 | 'operator' => $this->get_operator( $get, $key, array( 'is' ), 'is' ), |
||
| 1078 | ); |
||
| 1079 | } |
||
| 1080 | } |
||
| 1081 | |||
| 1082 | break; |
||
| 1083 | |||
| 1084 | 14 | case 'name': |
|
| 1085 | 14 | case 'address': |
|
| 1086 | |||
| 1087 | if ( false === strpos( $field_id, '.' ) ) { |
||
| 1088 | |||
| 1089 | $words = explode( ' ', $value ); |
||
| 1090 | |||
| 1091 | $filters = array(); |
||
| 1092 | foreach ( $words as $word ) { |
||
| 1093 | if ( ! empty( $word ) && strlen( $word ) > 1 ) { |
||
| 1094 | // Keep the same key for each filter |
||
| 1095 | $filter['value'] = $word; |
||
| 1096 | // Add a search for the value |
||
| 1097 | $filters[] = $filter; |
||
| 1098 | } |
||
| 1099 | } |
||
| 1100 | |||
| 1101 | $filter = $filters; |
||
| 1102 | } |
||
| 1103 | |||
| 1104 | // State/Province should be exact matches |
||
| 1105 | if ( 'address' === $form_field->field->type ) { |
||
| 1106 | |||
| 1107 | $searchable_fields = $this->get_view_searchable_fields( $view, true ); |
||
| 1108 | |||
| 1109 | foreach ( $searchable_fields as $searchable_field ) { |
||
| 1110 | |||
| 1111 | if( $form_field->ID !== $searchable_field['field'] ) { |
||
| 1112 | continue; |
||
| 1113 | } |
||
| 1114 | |||
| 1115 | // Only exact-match dropdowns, not text search |
||
| 1116 | if( in_array( $searchable_field['input'], array( 'text', 'search' ), true ) ) { |
||
| 1117 | continue; |
||
| 1118 | } |
||
| 1119 | |||
| 1120 | $input_id = gravityview_get_input_id_from_id( $form_field->ID ); |
||
| 1121 | |||
| 1122 | if ( 4 === $input_id ) { |
||
| 1123 | $filter['operator'] = $this->get_operator( $get, $key, array( 'is' ), 'is' ); |
||
| 1124 | }; |
||
| 1125 | } |
||
| 1126 | } |
||
| 1127 | |||
| 1128 | break; |
||
| 1129 | |||
| 1130 | 14 | case 'date': |
|
| 1131 | |||
| 1132 | 8 | $date_format = $this->get_datepicker_format( true ); |
|
| 1133 | |||
| 1134 | 8 | if ( is_array( $value ) ) { |
|
| 1135 | |||
| 1136 | // Reset filter variable |
||
| 1137 | $filter = array(); |
||
| 1138 | |||
| 1139 | foreach ( $value as $k => $date ) { |
||
| 1140 | if ( empty( $date ) ) { |
||
| 1141 | continue; |
||
| 1142 | } |
||
| 1143 | $operator = 'start' === $k ? '>=' : '<='; |
||
| 1144 | |||
| 1145 | /** |
||
| 1146 | * @hack |
||
| 1147 | * @since 1.16.3 |
||
| 1148 | * Safeguard until GF implements '<=' operator |
||
| 1149 | */ |
||
| 1150 | if( !GFFormsModel::is_valid_operator( $operator ) && $operator === '<=' ) { |
||
| 1151 | $operator = '<'; |
||
| 1152 | $date = date( 'Y-m-d', strtotime( self::get_formatted_date( $date, 'Y-m-d', $date_format ) . ' +1 day' ) ); |
||
| 1153 | } |
||
| 1154 | |||
| 1155 | $filter[] = array( |
||
| 1156 | 'key' => $field_id, |
||
| 1157 | 'value' => self::get_formatted_date( $date, 'Y-m-d', $date_format ), |
||
| 1158 | 'operator' => $this->get_operator( $get, $key, array( $operator ), $operator ), |
||
| 1159 | ); |
||
| 1160 | } |
||
| 1161 | } else { |
||
| 1162 | 8 | $date = $value; |
|
| 1163 | 8 | $filter['value'] = self::get_formatted_date( $date, 'Y-m-d', $date_format ); |
|
| 1164 | 8 | $filter['operator'] = $this->get_operator( $get, $key, array( 'is' ), 'is' ); |
|
| 1165 | } |
||
| 1166 | |||
| 1167 | 8 | break; |
|
| 1168 | |||
| 1169 | |||
| 1170 | } // switch field type |
||
| 1171 | |||
| 1172 | 15 | return $filter; |
|
| 1173 | } |
||
| 1174 | |||
| 1175 | /** |
||
| 1176 | * Get the Field Format form GravityForms |
||
| 1177 | * |
||
| 1178 | * @param GF_Field_Date $field The field object |
||
| 1179 | * @since 1.10 |
||
| 1180 | * |
||
| 1181 | * @return string Format of the date in the database |
||
| 1182 | */ |
||
| 1183 | public static function get_date_field_format( GF_Field_Date $field ) { |
||
| 1184 | $format = 'm/d/Y'; |
||
| 1185 | $datepicker = array( |
||
| 1186 | 'mdy' => 'm/d/Y', |
||
| 1187 | 'dmy' => 'd/m/Y', |
||
| 1188 | 'dmy_dash' => 'd-m-Y', |
||
| 1189 | 'dmy_dot' => 'd.m.Y', |
||
| 1190 | 'ymd_slash' => 'Y/m/d', |
||
| 1191 | 'ymd_dash' => 'Y-m-d', |
||
| 1192 | 'ymd_dot' => 'Y.m.d', |
||
| 1193 | ); |
||
| 1194 | |||
| 1195 | if ( ! empty( $field->dateFormat ) && isset( $datepicker[ $field->dateFormat ] ) ){ |
||
| 1196 | $format = $datepicker[ $field->dateFormat ]; |
||
| 1197 | } |
||
| 1198 | |||
| 1199 | return $format; |
||
| 1200 | } |
||
| 1201 | |||
| 1202 | /** |
||
| 1203 | * Format a date value |
||
| 1204 | * |
||
| 1205 | * @param string $value Date value input |
||
| 1206 | * @param string $format Wanted formatted date |
||
| 1207 | * |
||
| 1208 | * @since 2.1.2 |
||
| 1209 | * @param string $value_format The value format. Default: Y-m-d |
||
| 1210 | * |
||
| 1211 | * @return string |
||
| 1212 | */ |
||
| 1213 | 8 | public static function get_formatted_date( $value = '', $format = 'Y-m-d', $value_format = 'Y-m-d' ) { |
|
| 1214 | |||
| 1215 | 8 | $date = date_create_from_format( $value_format, $value ); |
|
| 1216 | |||
| 1217 | 8 | if ( empty( $date ) ) { |
|
| 1218 | gravityview()->log->debug( 'Date format not valid: {value}', array( 'value' => $value ) ); |
||
| 1219 | return ''; |
||
| 1220 | } |
||
| 1221 | 8 | return $date->format( $format ); |
|
| 1222 | } |
||
| 1223 | |||
| 1224 | |||
| 1225 | /** |
||
| 1226 | * Include this extension templates path |
||
| 1227 | * @param array $file_paths List of template paths ordered |
||
| 1228 | */ |
||
| 1229 | 1 | public function add_template_path( $file_paths ) { |
|
| 1230 | |||
| 1231 | // Index 100 is the default GravityView template path. |
||
| 1232 | 1 | $file_paths[102] = self::$file . 'templates/'; |
|
| 1233 | |||
| 1234 | 1 | return $file_paths; |
|
| 1235 | } |
||
| 1236 | |||
| 1237 | /** |
||
| 1238 | * Check whether the configured search fields have a date field |
||
| 1239 | * |
||
| 1240 | * @since 1.17.5 |
||
| 1241 | * |
||
| 1242 | * @param array $search_fields |
||
| 1243 | * |
||
| 1244 | * @return bool True: has a `date` or `date_range` field |
||
| 1245 | */ |
||
| 1246 | 4 | private function has_date_field( $search_fields ) { |
|
| 1247 | |||
| 1248 | 4 | $has_date = false; |
|
| 1249 | |||
| 1250 | 4 | foreach ( $search_fields as $k => $field ) { |
|
| 1251 | 4 | if ( in_array( $field['input'], array( 'date', 'date_range', 'entry_date' ) ) ) { |
|
| 1252 | $has_date = true; |
||
| 1253 | break; |
||
| 1254 | } |
||
| 1255 | } |
||
| 1256 | |||
| 1257 | 4 | return $has_date; |
|
| 1258 | } |
||
| 1259 | |||
| 1260 | /** |
||
| 1261 | * Renders the Search Widget |
||
| 1262 | * @param array $widget_args |
||
| 1263 | * @param string $content |
||
| 1264 | * @param string $context |
||
| 1265 | * |
||
| 1266 | * @return void |
||
| 1267 | */ |
||
| 1268 | 4 | public function render_frontend( $widget_args, $content = '', $context = '' ) { |
|
| 1269 | /** @var GravityView_View $gravityview_view */ |
||
| 1270 | 4 | $gravityview_view = GravityView_View::getInstance(); |
|
| 1271 | |||
| 1272 | 4 | if ( empty( $gravityview_view ) ) { |
|
| 1273 | gravityview()->log->debug( '$gravityview_view not instantiated yet.' ); |
||
| 1274 | return; |
||
| 1275 | } |
||
| 1276 | |||
| 1277 | // get configured search fields |
||
| 1278 | 4 | $search_fields = ! empty( $widget_args['search_fields'] ) ? json_decode( $widget_args['search_fields'], true ) : ''; |
|
| 1279 | |||
| 1280 | 4 | if ( empty( $search_fields ) || ! is_array( $search_fields ) ) { |
|
| 1281 | gravityview()->log->debug( 'No search fields configured for widget:', array( 'data' => $widget_args ) ); |
||
| 1282 | return; |
||
| 1283 | } |
||
| 1284 | |||
| 1285 | 4 | $view = \GV\View::by_id( $gravityview_view->view_id ); |
|
| 1286 | |||
| 1287 | // prepare fields |
||
| 1288 | 4 | foreach ( $search_fields as $k => $field ) { |
|
| 1289 | |||
| 1290 | 4 | $updated_field = $field; |
|
| 1291 | |||
| 1292 | 4 | $updated_field = $this->get_search_filter_details( $updated_field ); |
|
| 1293 | |||
| 1294 | 4 | switch ( $field['field'] ) { |
|
| 1295 | |||
| 1296 | 4 | case 'search_all': |
|
| 1297 | 4 | $updated_field['key'] = 'search_all'; |
|
| 1298 | 4 | $updated_field['input'] = 'search_all'; |
|
| 1299 | 4 | $updated_field['value'] = $this->rgget_or_rgpost( 'gv_search' ); |
|
| 1300 | 4 | break; |
|
| 1301 | |||
| 1302 | case 'entry_date': |
||
| 1303 | $updated_field['key'] = 'entry_date'; |
||
| 1304 | $updated_field['input'] = 'entry_date'; |
||
| 1305 | $updated_field['value'] = array( |
||
| 1306 | 'start' => $this->rgget_or_rgpost( 'gv_start' ), |
||
| 1307 | 'end' => $this->rgget_or_rgpost( 'gv_end' ), |
||
| 1308 | ); |
||
| 1309 | break; |
||
| 1310 | |||
| 1311 | case 'entry_id': |
||
| 1312 | $updated_field['key'] = 'entry_id'; |
||
| 1313 | $updated_field['input'] = 'entry_id'; |
||
| 1314 | $updated_field['value'] = $this->rgget_or_rgpost( 'gv_id' ); |
||
| 1315 | break; |
||
| 1316 | |||
| 1317 | case 'created_by': |
||
| 1318 | $updated_field['key'] = 'created_by'; |
||
| 1319 | $updated_field['name'] = 'gv_by'; |
||
| 1320 | $updated_field['value'] = $this->rgget_or_rgpost( 'gv_by' ); |
||
| 1321 | $updated_field['choices'] = self::get_created_by_choices( $view ); |
||
| 1322 | break; |
||
| 1323 | |||
| 1324 | case 'is_approved': |
||
| 1325 | $updated_field['key'] = 'is_approved'; |
||
| 1326 | $updated_field['value'] = $this->rgget_or_rgpost( 'filter_is_approved' ); |
||
| 1327 | $updated_field['choices'] = self::get_is_approved_choices(); |
||
| 1328 | break; |
||
| 1329 | } |
||
| 1330 | |||
| 1331 | 4 | $search_fields[ $k ] = $updated_field; |
|
| 1332 | } |
||
| 1333 | |||
| 1334 | 4 | gravityview()->log->debug( 'Calculated Search Fields: ', array( 'data' => $search_fields ) ); |
|
| 1335 | |||
| 1336 | /** |
||
| 1337 | * @filter `gravityview_widget_search_filters` Modify what fields are shown. The order of the fields in the $search_filters array controls the order as displayed in the search bar widget. |
||
| 1338 | * @param array $search_fields Array of search filters with `key`, `label`, `value`, `type`, `choices` keys |
||
| 1339 | * @param GravityView_Widget_Search $this Current widget object |
||
| 1340 | * @param array $widget_args Args passed to this method. {@since 1.8} |
||
| 1341 | * @param \GV\Template_Context $context {@since 2.0} |
||
| 1342 | * @var array |
||
| 1343 | */ |
||
| 1344 | 4 | $gravityview_view->search_fields = apply_filters( 'gravityview_widget_search_filters', $search_fields, $this, $widget_args, $context ); |
|
| 1345 | |||
| 1346 | 4 | $gravityview_view->search_layout = ! empty( $widget_args['search_layout'] ) ? $widget_args['search_layout'] : 'horizontal'; |
|
| 1347 | |||
| 1348 | /** @since 1.14 */ |
||
| 1349 | 4 | $gravityview_view->search_mode = ! empty( $widget_args['search_mode'] ) ? $widget_args['search_mode'] : 'any'; |
|
| 1350 | |||
| 1351 | 4 | $custom_class = ! empty( $widget_args['custom_class'] ) ? $widget_args['custom_class'] : ''; |
|
| 1352 | |||
| 1353 | 4 | $gravityview_view->search_class = self::get_search_class( $custom_class ); |
|
| 1354 | |||
| 1355 | 4 | $gravityview_view->search_clear = ! empty( $widget_args['search_clear'] ) ? $widget_args['search_clear'] : false; |
|
| 1356 | |||
| 1357 | 4 | if ( $this->has_date_field( $search_fields ) ) { |
|
| 1358 | // enqueue datepicker stuff only if needed! |
||
| 1359 | $this->enqueue_datepicker(); |
||
| 1360 | } |
||
| 1361 | |||
| 1362 | 4 | $this->maybe_enqueue_flexibility(); |
|
| 1363 | |||
| 1364 | 4 | $gravityview_view->render( 'widget', 'search', false ); |
|
| 1365 | 4 | } |
|
| 1366 | |||
| 1367 | /** |
||
| 1368 | * Get the search class for a search form |
||
| 1369 | * |
||
| 1370 | * @since 1.5.4 |
||
| 1371 | * |
||
| 1372 | * @return string Sanitized CSS class for the search form |
||
| 1373 | */ |
||
| 1374 | 4 | public static function get_search_class( $custom_class = '' ) { |
|
| 1375 | 4 | $gravityview_view = GravityView_View::getInstance(); |
|
| 1376 | |||
| 1377 | 4 | $search_class = 'gv-search-'.$gravityview_view->search_layout; |
|
| 1378 | |||
| 1379 | 4 | if ( ! empty( $custom_class ) ) { |
|
| 1380 | $search_class .= ' '.$custom_class; |
||
| 1381 | } |
||
| 1382 | |||
| 1383 | /** |
||
| 1384 | * @filter `gravityview_search_class` Modify the CSS class for the search form |
||
| 1385 | * @param string $search_class The CSS class for the search form |
||
| 1386 | */ |
||
| 1387 | 4 | $search_class = apply_filters( 'gravityview_search_class', $search_class ); |
|
| 1388 | |||
| 1389 | // Is there an active search being performed? Used by fe-views.js |
||
| 1390 | 4 | $search_class .= GravityView_frontend::getInstance()->isSearch() ? ' gv-is-search' : ''; |
|
| 1391 | |||
| 1392 | 4 | return gravityview_sanitize_html_class( $search_class ); |
|
| 1393 | } |
||
| 1394 | |||
| 1395 | |||
| 1396 | /** |
||
| 1397 | * Calculate the search form action |
||
| 1398 | * @since 1.6 |
||
| 1399 | * |
||
| 1400 | * @return string |
||
| 1401 | */ |
||
| 1402 | 4 | public static function get_search_form_action() { |
|
| 1403 | 4 | $gravityview_view = GravityView_View::getInstance(); |
|
| 1404 | |||
| 1405 | 4 | $post_id = $gravityview_view->getPostId() ? $gravityview_view->getPostId() : $gravityview_view->getViewId(); |
|
| 1406 | |||
| 1407 | 4 | $url = add_query_arg( array(), get_permalink( $post_id ) ); |
|
| 1408 | |||
| 1409 | 4 | return esc_url( $url ); |
|
| 1410 | } |
||
| 1411 | |||
| 1412 | /** |
||
| 1413 | * Get the label for a search form field |
||
| 1414 | * @param array $field Field setting as sent by the GV configuration - has `field`, `input` (input type), and `label` keys |
||
| 1415 | * @param array $form_field Form field data, as fetched by `gravityview_get_field()` |
||
| 1416 | * @return string Label for the search form |
||
| 1417 | */ |
||
| 1418 | 4 | private static function get_field_label( $field, $form_field = array() ) { |
|
| 1419 | |||
| 1420 | 4 | $label = \GV\Utils::_GET( 'label', \GV\Utils::get( $field, 'label' ) ); |
|
| 1421 | |||
| 1422 | 4 | if ( ! $label ) { |
|
| 1423 | |||
| 1424 | 4 | $label = isset( $form_field['label'] ) ? $form_field['label'] : ''; |
|
| 1425 | |||
| 1426 | 4 | switch( $field['field'] ) { |
|
| 1427 | 4 | case 'search_all': |
|
| 1428 | 4 | $label = __( 'Search Entries:', 'gravityview' ); |
|
| 1429 | 4 | break; |
|
| 1430 | case 'entry_date': |
||
| 1431 | $label = __( 'Filter by date:', 'gravityview' ); |
||
| 1432 | break; |
||
| 1433 | case 'entry_id': |
||
| 1434 | $label = __( 'Entry ID:', 'gravityview' ); |
||
| 1435 | break; |
||
| 1436 | default: |
||
| 1437 | // If this is a field input, not a field |
||
| 1438 | if ( strpos( $field['field'], '.' ) > 0 && ! empty( $form_field['inputs'] ) ) { |
||
| 1439 | |||
| 1440 | // Get the label for the field in question, which returns an array |
||
| 1441 | $items = wp_list_filter( $form_field['inputs'], array( 'id' => $field['field'] ) ); |
||
| 1442 | |||
| 1443 | // Get the item with the `label` key |
||
| 1444 | $values = wp_list_pluck( $items, 'label' ); |
||
| 1445 | |||
| 1446 | // There will only one item in the array, but this is easier |
||
| 1447 | foreach ( $values as $value ) { |
||
| 1448 | $label = $value; |
||
| 1449 | break; |
||
| 1450 | } |
||
| 1451 | } |
||
| 1452 | } |
||
| 1453 | } |
||
| 1454 | |||
| 1455 | /** |
||
| 1456 | * @filter `gravityview_search_field_label` Modify the label for a search field. Supports returning HTML |
||
| 1457 | * @since 1.17.3 Added $field parameter |
||
| 1458 | * @param[in,out] string $label Existing label text, sanitized. |
||
| 1459 | * @param[in] array $form_field Gravity Forms field array, as returned by `GFFormsModel::get_field()` |
||
| 1460 | * @param[in] array $field Field setting as sent by the GV configuration - has `field`, `input` (input type), and `label` keys |
||
| 1461 | */ |
||
| 1462 | 4 | $label = apply_filters( 'gravityview_search_field_label', esc_attr( $label ), $form_field, $field ); |
|
| 1463 | |||
| 1464 | 4 | return $label; |
|
| 1465 | } |
||
| 1466 | |||
| 1467 | /** |
||
| 1468 | * Prepare search fields to frontend render with other details (label, field type, searched values) |
||
| 1469 | * |
||
| 1470 | * @param array $field |
||
| 1471 | * @return array |
||
| 1472 | */ |
||
| 1473 | 4 | private function get_search_filter_details( $field ) { |
|
| 1511 | |||
| 1512 | /** |
||
| 1513 | * Calculate the search choices for the users |
||
| 1514 | * |
||
| 1515 | * @param \GV\View $view The view |
||
| 1516 | * @since develop |
||
| 1517 | * |
||
| 1518 | * @since 1.8 |
||
| 1519 | * |
||
| 1520 | * @return array Array of user choices (value = ID, text = display name) |
||
| 1521 | */ |
||
| 1522 | private static function get_created_by_choices( $view ) { |
||
| 1523 | |||
| 1524 | /** |
||
| 1525 | * filter gravityview/get_users/search_widget |
||
| 1526 | * @see \GVCommon::get_users |
||
| 1527 | */ |
||
| 1528 | $users = GVCommon::get_users( 'search_widget', array( 'fields' => array( 'ID', 'display_name' ) ) ); |
||
| 1529 | |||
| 1530 | $choices = array(); |
||
| 1531 | foreach ( $users as $user ) { |
||
| 1532 | /** |
||
| 1533 | * @filter `gravityview/search/created_by/text` Filter the display text in created by search choices |
||
| 1534 | * @since develop |
||
| 1535 | * @param string[in,out] The text. Default: $user->display_name |
||
| 1536 | * @param \WP_User $user The user. |
||
| 1537 | * @param \GV\View $view The view. |
||
| 1538 | */ |
||
| 1539 | $text = apply_filters( 'gravityview/search/created_by/text', $user->display_name, $user, $view ); |
||
| 1540 | $choices[] = array( |
||
| 1541 | 'value' => $user->ID, |
||
| 1542 | 'text' => $text, |
||
| 1543 | ); |
||
| 1544 | } |
||
| 1545 | |||
| 1546 | return $choices; |
||
| 1547 | } |
||
| 1548 | |||
| 1549 | /** |
||
| 1550 | * Calculate the search checkbox choices for approval status |
||
| 1551 | * |
||
| 1552 | * @since develop |
||
| 1553 | * |
||
| 1554 | * @return array Array of approval status choices (value = status, text = display name) |
||
| 1555 | */ |
||
| 1556 | private static function get_is_approved_choices() { |
||
| 1557 | |||
| 1558 | $choices = array(); |
||
| 1559 | foreach ( GravityView_Entry_Approval_Status::get_all() as $status ) { |
||
| 1560 | $choices[] = array( |
||
| 1561 | 'value' => $status['value'], |
||
| 1562 | 'text' => $status['label'], |
||
| 1563 | ); |
||
| 1564 | } |
||
| 1565 | |||
| 1566 | return $choices; |
||
| 1567 | } |
||
| 1568 | |||
| 1569 | /** |
||
| 1570 | * Output the Clear Search Results button |
||
| 1571 | * @since 1.5.4 |
||
| 1572 | */ |
||
| 1573 | 4 | public static function the_clear_search_button() { |
|
| 1574 | 4 | $gravityview_view = GravityView_View::getInstance(); |
|
| 1575 | |||
| 1576 | 4 | if ( $gravityview_view->search_clear ) { |
|
| 1577 | |||
| 1578 | $url = strtok( add_query_arg( array() ), '?' ); |
||
| 1579 | |||
| 1580 | echo gravityview_get_link( $url, esc_html__( 'Clear', 'gravityview' ), 'class=button gv-search-clear' ); |
||
| 1581 | |||
| 1582 | } |
||
| 1583 | 4 | } |
|
| 1584 | |||
| 1585 | /** |
||
| 1586 | * Based on the search method, fetch the value for a specific key |
||
| 1587 | * |
||
| 1588 | * @since 1.16.4 |
||
| 1589 | * |
||
| 1590 | * @param string $name Name of the request key to fetch the value for |
||
| 1591 | * |
||
| 1592 | * @return mixed|string Value of request at $name key. Empty string if empty. |
||
| 1593 | */ |
||
| 1594 | 4 | private function rgget_or_rgpost( $name ) { |
|
| 1595 | 4 | $value = \GV\Utils::_REQUEST( $name ); |
|
| 1596 | |||
| 1597 | 4 | $value = stripslashes_deep( $value ); |
|
| 1598 | |||
| 1599 | 4 | $value = gv_map_deep( $value, 'rawurldecode' ); |
|
| 1600 | |||
| 1601 | 4 | $value = gv_map_deep( $value, '_wp_specialchars' ); |
|
| 1602 | |||
| 1603 | 4 | return $value; |
|
| 1604 | } |
||
| 1605 | |||
| 1606 | |||
| 1607 | /** |
||
| 1608 | * Require the datepicker script for the frontend GV script |
||
| 1609 | * @param array $js_dependencies Array of existing required scripts for the fe-views.js script |
||
| 1610 | * @return array Array required scripts, with `jquery-ui-datepicker` added |
||
| 1611 | */ |
||
| 1612 | public function add_datepicker_js_dependency( $js_dependencies ) { |
||
| 1613 | |||
| 1614 | $js_dependencies[] = 'jquery-ui-datepicker'; |
||
| 1615 | |||
| 1616 | return $js_dependencies; |
||
| 1617 | } |
||
| 1618 | |||
| 1619 | /** |
||
| 1620 | * Modify the array passed to wp_localize_script() |
||
| 1621 | * |
||
| 1622 | * @param array $js_localization The data padded to the Javascript file |
||
| 1623 | * @param array $view_data View data array with View settings |
||
| 1624 | * |
||
| 1625 | * @return array |
||
| 1626 | */ |
||
| 1627 | public function add_datepicker_localization( $localizations = array(), $view_data = array() ) { |
||
| 1663 | |||
| 1664 | /** |
||
| 1665 | * Register search widget scripts, including Flexibility |
||
| 1666 | * |
||
| 1667 | * @see https://github.com/10up/flexibility |
||
| 1668 | * |
||
| 1669 | * @since 1.17 |
||
| 1670 | * |
||
| 1671 | * @return void |
||
| 1672 | */ |
||
| 1673 | public function register_scripts() { |
||
| 1674 | wp_register_script( 'gv-flexibility', plugins_url( 'assets/lib/flexibility/flexibility.js', GRAVITYVIEW_FILE ), array(), \GV\Plugin::$version, true ); |
||
| 1675 | } |
||
| 1676 | |||
| 1677 | /** |
||
| 1678 | * If the current visitor is running IE 8 or 9, enqueue Flexibility |
||
| 1679 | * |
||
| 1680 | * @since 1.17 |
||
| 1681 | * |
||
| 1682 | * @return void |
||
| 1683 | */ |
||
| 1684 | 4 | private function maybe_enqueue_flexibility() { |
|
| 1689 | |||
| 1690 | /** |
||
| 1691 | * Enqueue the datepicker script |
||
| 1692 | * |
||
| 1693 | * It sets the $gravityview->datepicker_class parameter |
||
| 1694 | * |
||
| 1695 | * @todo Use own datepicker javascript instead of GF datepicker.js - that way, we can localize the settings and not require the changeMonth and changeYear pickers. |
||
| 1696 | * @return void |
||
| 1697 | */ |
||
| 1698 | public function enqueue_datepicker() { |
||
| 1726 | |||
| 1727 | /** |
||
| 1728 | * Retrieve the datepicker format. |
||
| 1729 | * |
||
| 1730 | * @param bool $date_format Whether to return the PHP date format or the datpicker class name. Default: false. |
||
| 1731 | * |
||
| 1732 | * @see https://docs.gravityview.co/article/115-changing-the-format-of-the-search-widgets-date-picker |
||
| 1733 | * |
||
| 1734 | * @return string The datepicker format placeholder, or the PHP date format. |
||
| 1735 | */ |
||
| 1736 | 19 | private function get_datepicker_format( $date_format = false ) { |
|
| 1775 | |||
| 1776 | /** |
||
| 1777 | * If previewing a View or page with embedded Views, make the search work properly by adding hidden fields with query vars |
||
| 1778 | * |
||
| 1779 | * @since 2.2.1 |
||
| 1780 | * |
||
| 1781 | * @return void |
||
| 1782 | */ |
||
| 1783 | 4 | public function add_preview_inputs() { |
|
| 1796 | |||
| 1797 | /** |
||
| 1798 | * Get an operator URL override. |
||
| 1799 | * |
||
| 1800 | * @param array $get Where to look for the operator. |
||
| 1801 | * @param string $key The filter key to look for. |
||
| 1802 | * @param array $allowed The allowed operators (whitelist). |
||
| 1803 | * @param string $default The default operator. |
||
| 1804 | * |
||
| 1805 | * @return string The operator. |
||
| 1806 | */ |
||
| 1807 | 18 | private function get_operator( $get, $key, $allowed, $default ) { |
|
| 1823 | |||
| 1824 | |||
| 1825 | } // end class |
||
| 1826 | |||
| 1912 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.