Issues (575)

classes/class-frontend.php (30 issues)

1
<?php
2
/**
3
 * LSX Currency Frontend Class
4
 *
5
 * @package   LSX Currencies
6
 * @author    LightSpeed
7
 * @license   GPL3
8
 * @link
9
 * @copyright 2019 LightSpeed
10
 */
11
12
namespace lsx\currencies\classes;
13
14
/**
15
 * The frontend classes
16
 */
17
class Frontend {
18
19
	/**
20
	 * Holds instance of the class
21
	 *
22
	 * @var object \lsx\currencies\classes\Admin()
23
	 */
24
	private static $instance;
25
26
	/**
27
	 * This will hold the rates with a base currency of USD.
28
	 *
29
	 * @var boolean
30
	 */
31
	public $rates = false;
32
33
	/**
34
	 * This will hold the rates error message.
35
	 *
36
	 * @var boolean
37
	 */
38
	public $rates_message = false;
39
40
	/**
41
	 * This is the current currency selected, default to the base currency.
42
	 *
43
	 * @var boolean
44
	 */
45
	public $current_currency = false;
46
47
	/**
48
	 * Constructor
49
	 */
50
	public function __construct() {
51
		if ( ! is_admin() ) {
0 ignored issues
show
Expected 0 spaces after opening bracket; 1 found
Loading history...
Expected 0 spaces before closing bracket; 1 found
Loading history...
52
			add_action( 'plugins_loaded', array( $this, 'set_defaults' ), 11, 1 );
53
			add_filter( 'lsx_to_custom_field_query', array( $this, 'price_filter' ), 20, 5 );
54
			add_action( 'wp_enqueue_scripts', array( $this, 'assets' ), 5 );
55
			add_filter( 'wp_nav_menu_items', array( $this, 'wp_nav_menu_items_filter' ), 10, 2 );
56
			add_filter( 'wp_kses_allowed_html', array( $this, 'wp_kses_allowed_html' ), 10, 2 );
57
			add_filter( 'get_post_metadata', array( $this, 'filter_post_meta' ), 100, 4 );
58
		}
59
	}
60
61
	/**
62
	 * Return an instance of this class.
63
	 *
64
	 * @return  object
65
	 */
66
	public static function init() {
67
		// If the single instance hasn't been set, set it now.
68
		if ( ! isset( self::$instance ) ) {
69
			self::$instance = new self();
70
		}
71
		return self::$instance;
72
	}
73
74
	/**
75
	 * Constructor
76
	 */
77
	public function set_defaults() {
78
		$this->rates_message = esc_html__( 'Error: API key isn\'t set.', 'lsx-currencies' );
0 ignored issues
show
Documentation Bug introduced by
The property $rates_message was declared of type boolean, but esc_html__('Error: API k...et.', 'lsx-currencies') is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
79
		$this->rates = get_transient( 'lsx_currencies_rates' );
80
		if ( false === $this->rates ) {
81
			$rates         = wp_remote_retrieve_body( wp_safe_remote_get( lsx_currencies()->api_url ) );
82
			$decoded_rates = json_decode( $rates );
83
84
			if ( is_wp_error( $rates ) ) {
85
				$this->rates_message = $rates->get_error_message();
86
			} elseif ( ! empty( $decoded_rates->error ) ) {
87
				$this->rates_message = $decoded_rates->description;
88
			} elseif ( empty( $rates ) ) {
89
				$this->rates_message = esc_html__( 'Error: API response is empty.', 'lsx-currencies' );
90
			} else {
91
				$this->rates_message = esc_html__( 'Success (new request).', 'lsx-currencies' );
92
				set_transient( 'lsx_currencies_rates', $decoded_rates->rates, 60 * 60 * 12 );
93
				do_action( 'lsx_currencies_rates_refreshed' );
94
				$this->rates = $decoded_rates->rates;
95
			}
96
		} else {
97
			$this->rates_message = esc_html__( 'Success (from cache).', 'lsx-currencies' );
98
		}
99
		$this->current_currency = isset( $_COOKIE['lsx_currencies_choice'] ) ? sanitize_key( $_COOKIE['lsx_currencies_choice'] ) : lsx_currencies()->base_currency;
100
		$this->current_currency = strtoupper( $this->current_currency );
101
	}
0 ignored issues
show
Expected 2 blank lines after function; 1 found
Loading history...
Expected 1 blank line before closing function brace; 0 found
Loading history...
102
103
	/**
104
	 * Enques the assets
105
	 */
106
	public function assets() {
107
		wp_enqueue_script( 'lsx-moneyjs', LSX_CURRENCIES_URL . 'assets/js/vendor/money.min.js', array( 'jquery' ), LSX_CURRENCIES_VER, true );
108
		wp_enqueue_script( 'lsx-accountingjs', LSX_CURRENCIES_URL . 'assets/js/vendor/accounting.min.js', array( 'jquery' ), LSX_CURRENCIES_VER, true );
109
		wp_enqueue_script( 'lsx-jquery-cookie', LSX_CURRENCIES_URL . 'assets/js/vendor/cookie.min.js', array( 'jquery' ), LSX_CURRENCIES_VER, true );
110
111
		$prefix = '.min';
112
		$src = '';
113
		$script_debug = false;
114
		if ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) {
115
			$prefix = '';
116
			$src = 'src/';
117
			$script_debug = true;
118
		}
119
		wp_enqueue_script( 'lsx-currencies', LSX_CURRENCIES_URL . 'assets/js/' . $src . 'lsx-currencies' . $prefix . '.js', array( 'jquery', 'lsx-moneyjs', 'lsx-accountingjs', 'lsx-jquery-cookie' ), LSX_CURRENCIES_VER, true );
120
121
		$base_currency = lsx_currencies()->base_currency;
122
		$current_currency = $this->current_currency;
123
		if ( true === lsx_currencies()->convert_to_single ) {
124
			$current_currency = $base_currency;
125
		}
126
127
		$params = apply_filters( 'lsx_currencies_js_params', array(
0 ignored issues
show
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
For multi-line function calls, each argument should be on a separate line.

For a function calls that spawns multiple lines, the coding style suggests to split arguments to separate lines like this:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
);
Loading history...
128
			'current_currency'  => $current_currency,
129
			'currency_symbols'  => $this->get_available_symbols(),
130
			'rates'             => $this->rates,
131
			'rates_message'     => $this->rates_message,
132
			'base'              => $base_currency,
133
			'flags'             => lsx_currencies()->display_flags,
134
			'convert_to_single' => lsx_currencies()->convert_to_single,
135
			'script_debug'      => $script_debug,
136
			'remove_decimals'   => lsx_currencies()->remove_decimals,
137
		));
138
139
		wp_localize_script( 'lsx-currencies', 'lsx_currencies_params', $params );
140
141
		wp_enqueue_style( 'lsx-currencies', LSX_CURRENCIES_URL . 'assets/css/lsx-currencies.css', array(), LSX_CURRENCIES_VER );
142
		wp_style_add_data( 'lsx-currencies', 'rtl', 'replace' );
143
	}
144
145
	/**
146
	 * Returns all of the available symbols.
147
	 *
148
	 * @return array
149
	 */
150
	public function get_available_symbols() {
151
		$symbols = array();
152
		if ( false !== lsx_currencies()->additional_currencies && ! empty( lsx_currencies()->additional_currencies ) ) {
153
			foreach ( lsx_currencies()->additional_currencies as $key => $currency ) {
154
				$symbols[ $key ] = lsx_currencies()->currency_symbols[ $key ];
155
			}
156
		}
157
		return $symbols;
158
	}
159
160
	/**
161
	 * Adds in the required currency conversion tags
162
	 */
163
	public function price_filter( $return_html, $meta_key, $value, $before, $after ) {
164
		if ( 'price' === $meta_key ) {
0 ignored issues
show
Expected 0 spaces after opening bracket; 1 found
Loading history...
Expected 0 spaces before closing bracket; 1 found
Loading history...
165
			$additional_html = '';
166
			$additional_prices = get_post_meta( get_the_ID(), 'additional_prices', false );
0 ignored issues
show
It seems like get_the_ID() can also be of type false; however, parameter $post_id of get_post_meta() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

166
			$additional_prices = get_post_meta( /** @scrutinizer ignore-type */ get_the_ID(), 'additional_prices', false );
Loading history...
167
			$prefix = '<span class="amount lsx-currencies" ';
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 12 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
168
169
			if ( true === lsx_currencies()->multi_prices && ! empty( $additional_prices ) ) {
170
				foreach ( $additional_prices as $a_price ) {
0 ignored issues
show
Expected 0 spaces after opening bracket; 1 found
Loading history...
Expected 0 spaces before closing bracket; 1 found
Loading history...
171
					$additional_html .= ' data-price-' . $a_price['currency'] . '="' . $a_price['amount'] . '"';
172
				}
173
			}
174
175
			$value = preg_replace( '/[^0-9.]+/', '', $value );
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
176
			$decimals = substr_count( $value, '.' );
177
178
			if ( false !== $decimals && $decimals > 1 ) {
0 ignored issues
show
Expected 0 spaces after opening bracket; 1 found
Loading history...
Expected 0 spaces before closing bracket; 1 found
Loading history...
179
				$decimals--;
180
				$decimals = (int) $decimals;
181
				$value = preg_replace( '/' . preg_quote( '.', '/' ) . '/', '', $value, $decimals );
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
182
			}
183
184
			$money_format = 2;
185
			if ( false !== lsx_currencies()->remove_decimals ) {
186
				$money_format = 0;
187
			}
188
189
			$prefix .= '>';
190
			$suffix = '</span>';
191
192
			setlocale( LC_MONETARY, 'en_US' );
193
194
			// Work out the other tags.
195
			$currency = '<span class="currency-icon ' . mb_strtolower( lsx_currencies()->base_currency ) . '">' . lsx_currencies()->base_currency . '</span>';
196
197
			$value = ltrim( rtrim( $value ) );
198
			
199
			$for_value = number_format( (float) $value, $money_format );
200
			$for_value = str_replace( array( '$', 'USD' ), '', $for_value );
201
			
202
			$amount = '<span class="value" data-price-' . lsx_currencies()->base_currency . '="' . trim( str_replace( array( '$', 'USD' ), '', $value ) ) . '" ' . $additional_html . '>' . str_replace( array( '$', 'USD' ), '', $for_value ) . '</span>';
203
204
			// Check for a price type and add that in.
205
			$price_type = get_post_meta( get_the_ID(), 'price_type', true );
206
207
			switch ( $price_type ) {
0 ignored issues
show
Expected 0 spaces after opening bracket; 1 found
Loading history...
Expected 0 spaces before closing bracket; 1 found
Loading history...
208
				case 'per_person_per_night':
209
				case 'per_person_sharing':
210
				case 'per_person_sharing_per_night':
211
					$amount = $currency . $amount . ' ' . ucwords( str_replace( '_', ' ', $price_type ) );
212
				    break;
213
214
				case 'total_percentage':
215
					$amount .= '% ' . esc_html__( 'Off', 'lsx-currencies' );
216
					$before = str_replace( 'from', '', $before );
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
217
				    break;
218
219
				case 'none':
220
				default:
221
					$amount = $currency . $amount;
222
				    break;
223
			}
224
225
			$return_html = $before . $prefix . $amount . $suffix . $after;
226
		}
227
228
		return $return_html;
229
	}
0 ignored issues
show
Expected 2 blank lines after function; 1 found
Loading history...
Expected 1 blank line before closing function brace; 0 found
Loading history...
230
231
	/**
232
	 * Filter on the 'wp_nav_menu_items' hook, that potentially adds a currency switcher to the item of some menus.
233
	 *
234
	 * @param $items string
235
	 * @param $args object
236
	 *
237
	 * @return string
238
	 */
239
	public function wp_nav_menu_items_filter( $items, $args ) {
240
		if ( '' !== lsx_currencies()->menus && lsx_currencies()->menus === $args->theme_location ) {
241
			if ( 'top-menu' === $args->theme_location ) {
0 ignored issues
show
Expected 0 spaces after opening bracket; 1 found
Loading history...
Expected 0 spaces before closing bracket; 1 found
Loading history...
242
				$items = $this->get_menu_html( $args ) . $items;
243
			} else {
244
				$items = $items . $this->get_menu_html( $args );
245
			}
246
		}
247
		return $items;
248
	}
249
250
	/**
251
	 * Returns the HTML string of the language switcher for a given menu.
252
	 *
253
	 * @param $args object
254
	 *
255
	 * @return string
256
	 */
257
	private function get_menu_html( $args ) {
258
		if ( empty( lsx_currencies()->additional_currencies ) ) {
259
			return '';
260
		}
261
262
		$items = '';
263
		$items .= '<li class="menu-item menu-item-currency menu-item-currency-current menu-item-has-children dropdown">';
264
		$items .= isset( $args->before ) ? $args->before : '';
265
		$items .= '<a class="current symbol-' . lsx_currencies()->switcher_symbol_position . '" href="#' . strtolower( $this->current_currency ) . '">';
266
		$items .= isset( $args->link_before ) ? $args->link_before : '';
267
268
		if ( ! empty( lsx_currencies()->display_flags ) && 'left' === lsx_currencies()->flag_position ) {
269
			$items .= lsx_currencies()->get_currency_flag( $this->current_currency );
270
		}
271
272
		if ( 'left' === lsx_currencies()->switcher_symbol_position ) {
273
			$items .= '<span class="currency-icon ' . strtolower( $this->current_currency ) . '"></span>';
274
		}
275
276
		$items .= $this->current_currency;
277
278
		if ( 'right' === lsx_currencies()->switcher_symbol_position ) {
279
			$items .= '<span class="currency-icon ' . strtolower( $this->current_currency ) . '"></span>';
280
		}
281
282
		if ( ! empty( lsx_currencies()->display_flags ) && 'right' === lsx_currencies()->flag_position ) {
283
			$items .= lsx_currencies()->get_currency_flag( $this->current_currency );
284
		}
285
286
		$items .= isset( $args->link_after ) ? $args->link_after : '';
287
		$items .= '<span class="caret"></span></a>';
288
		$items .= isset( $args->after ) ? $args->after : '';
289
		$items .= $this->render_sub_items();
290
		$items .= '</li>';
291
		return $items;
292
	}
293
	/**
294
	 * Returns the HTML string of the language switcher for a given menu.
295
	 *
296
	 * @param object $args
297
	 *
298
	 * @return string
299
	 */
300
	private function render_sub_items() {
301
		$sub_items = '';
302
		foreach ( lsx_currencies()->additional_currencies as $key => $currency ) {
303
			$hidden = '';
304
			$class = '';
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
305
306
			if ( $this->current_currency === $key ) {
0 ignored issues
show
Expected 0 spaces before closing bracket; 1 found
Loading history...
Expected 0 spaces after opening bracket; 1 found
Loading history...
307
				$hidden = 'style="display:none";';
308
				$class = 'hidden';
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
309
			}
310
311
			$sub_items .= '<li ' . $hidden . ' class="' . $class . ' menu-item menu-item-currency ' . lsx_currencies()->switcher_symbol_position . '">';
312
			$sub_items .= '<a class=" symbol-' . lsx_currencies()->switcher_symbol_position . '" href="#' . strtolower( $key ) . '">';
313
314
			if ( ! empty( lsx_currencies()->display_flags ) && 'left' === lsx_currencies()->flag_position ) {
315
				$sub_items .= lsx_currencies()->get_currency_flag( $key );
316
			}
317
318
			if ( 'left' === lsx_currencies()->switcher_symbol_position ) {
319
				$sub_items .= '<span class="currency-icon ' . strtolower( $key ) . '"></span>';
320
			}
321
322
			$sub_items .= ucwords( $key );
323
324
			if ( 'right' === lsx_currencies()->switcher_symbol_position ) {
325
				$sub_items .= '<span class="currency-icon ' . strtolower( $key ) . '"></span>';
326
			}
327
328
			if ( ! empty( lsx_currencies()->display_flags ) && 'right' === lsx_currencies()->flag_position ) {
329
				$sub_items .= lsx_currencies()->get_currency_flag( $key );
330
			}
331
332
			$sub_items .= '</a></li>';
333
		}
334
335
		$sub_items = '<ul class="sub-menu submenu-currency dropdown-menu">' . $sub_items . '</ul>';
336
		return $sub_items;
337
	}
338
339
	/**
340
	 * Allow data params for Slick slider addon.
341
	 */
342
	public function wp_kses_allowed_html( $allowedtags, $context ) {
343
		if ( ! isset( $allowedtags['span'] ) ) {
0 ignored issues
show
Expected 0 spaces after opening bracket; 1 found
Loading history...
Expected 0 spaces before closing bracket; 1 found
Loading history...
344
			$allowedtags['span'] = array();
345
		}
346
347
		$allowedtags['span']['data-price-AUD'] = true;
348
		$allowedtags['span']['data-price-BRL'] = true;
349
		$allowedtags['span']['data-price-GBP'] = true;
350
		$allowedtags['span']['data-price-BWP'] = true;
351
		$allowedtags['span']['data-price-CAD'] = true;
352
		$allowedtags['span']['data-price-CNY'] = true;
353
		$allowedtags['span']['data-price-EUR'] = true;
354
		$allowedtags['span']['data-price-HKD'] = true;
355
		$allowedtags['span']['data-price-INR'] = true;
356
		$allowedtags['span']['data-price-IDR'] = true;
357
		$allowedtags['span']['data-price-ILS'] = true;
358
		$allowedtags['span']['data-price-JPY'] = true;
359
		$allowedtags['span']['data-price-KES'] = true;
360
		$allowedtags['span']['data-price-LAK'] = true;
361
		$allowedtags['span']['data-price-MWK'] = true;
362
		$allowedtags['span']['data-price-MYR'] = true;
363
		$allowedtags['span']['data-price-MZN'] = true;
364
		$allowedtags['span']['data-price-NAD'] = true;
365
		$allowedtags['span']['data-price-NZD'] = true;
366
		$allowedtags['span']['data-price-NOK'] = true;
367
		$allowedtags['span']['data-price-RUB'] = true;
368
		$allowedtags['span']['data-price-SGD'] = true;
369
		$allowedtags['span']['data-price-ZAR'] = true;
370
		$allowedtags['span']['data-price-SEK'] = true;
371
		$allowedtags['span']['data-price-CHF'] = true;
372
		$allowedtags['span']['data-price-TZS'] = true;
373
		$allowedtags['span']['data-price-USD'] = true;
374
		$allowedtags['span']['data-price-AED'] = true;
375
		$allowedtags['span']['data-price-ZMW'] = true;
376
		$allowedtags['span']['data-price-ZWL'] = true;
377
378
		return $allowedtags;
379
	}
380
381
	/**
382
	 * Allow empty prices if the convert to single currency is active.
383
	 *
384
	 * @param null $metadata
385
	 * @param string $object_id
386
	 * @param string $meta_key
387
	 * @param boolean $single
388
	 * @return void
389
	 */
390
	public function filter_post_meta( $metadata = null, $object_id, $meta_key, $single ) {
391
		if ( true === lsx_currencies()->convert_to_single && 'price' === $meta_key ) {
392
			$meta_cache = wp_cache_get( $object_id, 'post_meta' );
393
394
			if ( ! isset( $meta_cache[ $meta_key ] ) || '' === $meta_cache[ $meta_key ] ) {
395
				$metadata = '0';
396
			}
397
		}
398
		return $metadata;
399
	}
400
}
401