PluginProbe
Polylang / trunk
Polylang vtrunk
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 3.0.3 All 233 releases
polylang / src / frontend / frontend-filters-search.php

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

178 lines 5.3 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 remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 9999 );
99 add_action( 'admin_bar_menu', array( $this, 'admin_bar_search_menu' ), 9999 );
100 }
101
102 /**
103 * Rewrites the admin bar search form to pass our get_search_form filter. See #21342.
104 * Code last checked: WP 5.4.1.
105 *
106 * @since 0.9
107 *
108 * @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance, passed by reference.
109 * @return void
110 */
111 public function admin_bar_search_menu( $wp_admin_bar ) {
112 $form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
113 $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />';
114 $form .= '<label for="adminbar-search" class="screen-reader-text">' .
115 /* translators: Hidden accessibility text. */
116 esc_html__( 'Search', 'polylang' ) .
117 '</label>';
118 $form .= '<input type="submit" class="adminbar-button" value="' . esc_attr__( 'Search', 'polylang' ) . '" />';
119 $form .= '</form>';
120
121 $wp_admin_bar->add_node(
122 array(
123 'parent' => 'top-secondary',
124 'id' => 'search',
125 'title' => $this->get_search_form( $form ), // Pass the get_search_form filter.
126 'meta' => array(
127 'class' => 'admin-bar-search',
128 'tabindex' => -1,
129 ),
130 )
131 );
132 }
133
134 /**
135 * Allows modifying the search form if it does not pass get_search_form.
136 *
137 * @since 0.1
138 *
139 * @return void
140 */
141 public function wp_print_footer_scripts() {
142 /*
143 * Don't use directly e[0] just in case there is somewhere else an element named 's'
144 * Check before if the hidden input has not already been introduced by get_search_form ( FIXME: is there a way to improve this ) ?
145 * Thanks to AndyDeGroo for improving the code for compatibility with old browsers
146 * http://wordpress.org/support/topic/development-of-polylang-version-08?replies=6#post-2645559
147 */
148 $lang = esc_js( $this->curlang->slug );
149 $js = "e = document.getElementsByName( 's' );
150 for ( i = 0; i < e.length; i++ ) {
151 if ( e[i].tagName.toUpperCase() == 'INPUT' ) {
152 s = e[i].parentNode.parentNode.children;
153 l = 0;
154 for ( j = 0; j < s.length; j++ ) {
155 if ( s[j].name == 'lang' ) {
156 l = 1;
157 }
158 }
159 if ( l == 0 ) {
160 var ih = document.createElement( 'input' );
161 ih.type = 'hidden';
162 ih.name = 'lang';
163 ih.value = '{$lang}';
164 e[i].parentNode.appendChild( ih );
165 }
166 }
167 }";
168
169 $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : ' type="text/javascript"';
170
171 if ( $type_attr ) {
172 $js = "/* <![CDATA[ */\n{$js}\n/* ]]> */";
173 }
174
175 echo "<script{$type_attr}>\n{$js}\n</script>\n"; // phpcs:ignore WordPress.Security.EscapeOutput
176 }
177 }
178