PluginProbe
Polylang / 3.8.10
Polylang v3.8.10
3.8.10 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 All 234 releases
polylang / src / frontend / frontend-filters-search.php

frontend-filters-search.php in Polylang 3.8.10, at src/frontend/frontend-filters-search.php

184 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 /**
7 * Filters search forms when using permalinks
8 *
9 * @since 1.2
10 */
11 class PLL_Frontend_Filters_Search {
12 /**
13 * Instance of a child class of PLL_Links_Model.
14 *
15 * @var PLL_Links_Model
16 */
17 public $links_model;
18
19 /**
20 * Current language.
21 *
22 * @var PLL_Language|null
23 */
24 public $curlang;
25
26 /**
27 * Constructor.
28 *
29 * @since 1.2
30 *
31 * @param object $polylang The Polylang object.
32 */
33 public function __construct( &$polylang ) {
34 $this->links_model = &$polylang->links_model;
35 $this->curlang = &$polylang->curlang;
36
37 // Adds the language information in the search form
38 // Low priority in case the search form is created using the same filter as described in http://codex.wordpress.org/Function_Reference/get_search_form
39 add_filter( 'get_search_form', array( $this, 'get_search_form' ), 99 );
40
41 // Adds the language information in the search block.
42 add_filter( 'render_block_core/search', array( $this, 'get_search_form' ) );
43
44 // Adds the language information in admin bar search form
45 add_action( 'add_admin_bar_menus', array( $this, 'add_admin_bar_menus' ) );
46
47
48 // Adds javascript at the end of the document
49 // Was used for WP < 3.6. kept just in case
50 if ( defined( 'PLL_SEARCH_FORM_JS' ) && PLL_SEARCH_FORM_JS ) {
51 add_action( 'wp_footer', array( $this, 'wp_print_footer_scripts' ) );
52 }
53 }
54
55 /**
56 * Adds the language information in the search form.
57 *
58 * Does not work if searchform.php ( prior to WP 3.6 ) is used or if the search form is hardcoded in another template file
59 *
60 * @since 0.1
61 *
62 * @param string $form The search form HTML.
63 * @return string Modified search form.
64 */
65 public function get_search_form( $form ) {
66 if ( empty( $form ) || empty( $this->curlang ) ) {
67 return $form;
68 }
69
70 if ( $this->links_model->using_permalinks ) {
71 // Take care to modify only the url in the <form> tag.
72 preg_match( '#<form.+?>#s', $form, $matches );
73 $old = reset( $matches );
74 if ( empty( $old ) ) {
75 return $form;
76 }
77 // Replace action attribute (a text with no space and no closing tag within double quotes or simple quotes or without quotes).
78 $new = preg_replace( '#\saction=("[^"\r\n]+"|\'[^\'\r\n]+\'|[^\'"][^>\s]+)#', ' action="' . esc_url( $this->curlang->get_search_url() ) . '"', $old );
79 if ( empty( $new ) ) {
80 return $form;
81 }
82 $form = str_replace( $old, $new, $form );
83 } else {
84 $form = str_replace( '</form>', '<input type="hidden" name="lang" value="' . esc_attr( $this->curlang->slug ) . '" /></form>', $form );
85 }
86
87 return $form;
88 }
89
90 /**
91 * Adds the language information in the admin bar search form.
92 *
93 * @since 1.2
94 *
95 * @return void
96 */
97 public function add_admin_bar_menus() {
98 // Backward compatibility with WP < 6.6. The priority was 4 before this version, 9999 since then.
99 $priority = has_action( 'admin_bar_menu', 'wp_admin_bar_search_menu' );
100 if ( ! is_int( $priority ) ) {
101 return;
102 }
103
104 remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', $priority );
105 add_action( 'admin_bar_menu', array( $this, 'admin_bar_search_menu' ), $priority );
106 }
107
108 /**
109 * Rewrites the admin bar search form to pass our get_search_form filter. See #21342.
110 * Code last checked: WP 5.4.1.
111 *
112 * @since 0.9
113 *
114 * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance, passed by reference.
115 * @return void
116 */
117 public function admin_bar_search_menu( $wp_admin_bar ) {
118 $form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
119 $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />';
120 $form .= '<label for="adminbar-search" class="screen-reader-text">' .
121 /* translators: Hidden accessibility text. */
122 esc_html__( 'Search', 'polylang' ) .
123 '</label>';
124 $form .= '<input type="submit" class="adminbar-button" value="' . esc_attr__( 'Search', 'polylang' ) . '" />';
125 $form .= '</form>';
126
127 $wp_admin_bar->add_node(
128 array(
129 'parent' => 'top-secondary',
130 'id' => 'search',
131 'title' => $this->get_search_form( $form ), // Pass the get_search_form filter.
132 'meta' => array(
133 'class' => 'admin-bar-search',
134 'tabindex' => -1,
135 ),
136 )
137 );
138 }
139
140 /**
141 * Allows modifying the search form if it does not pass get_search_form.
142 *
143 * @since 0.1
144 *
145 * @return void
146 */
147 public function wp_print_footer_scripts() {
148 /*
149 * Don't use directly e[0] just in case there is somewhere else an element named 's'
150 * Check before if the hidden input has not already been introduced by get_search_form ( FIXME: is there a way to improve this ) ?
151 * Thanks to AndyDeGroo for improving the code for compatibility with old browsers
152 * http://wordpress.org/support/topic/development-of-polylang-version-08?replies=6#post-2645559
153 */
154 $lang = esc_js( $this->curlang->slug );
155 $js = "e = document.getElementsByName( 's' );
156 for ( i = 0; i < e.length; i++ ) {
157 if ( e[i].tagName.toUpperCase() == 'INPUT' ) {
158 s = e[i].parentNode.parentNode.children;
159 l = 0;
160 for ( j = 0; j < s.length; j++ ) {
161 if ( s[j].name == 'lang' ) {
162 l = 1;
163 }
164 }
165 if ( l == 0 ) {
166 var ih = document.createElement( 'input' );
167 ih.type = 'hidden';
168 ih.name = 'lang';
169 ih.value = '{$lang}';
170 e[i].parentNode.appendChild( ih );
171 }
172 }
173 }";
174
175 $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : ' type="text/javascript"';
176
177 if ( $type_attr ) {
178 $js = "/* <![CDATA[ */\n{$js}\n/* ]]> */";
179 }
180
181 echo "<script{$type_attr}>\n{$js}\n</script>\n"; // phpcs:ignore WordPress.Security.EscapeOutput
182 }
183 }
184