Completed
Push — develop ( 0165dc...849df1 )
by David
04:14 queued 01:46
created

Wordlift_Autocomplete_Adapter   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 76
rs 10
c 0
b 0
f 0
wmc 8
lcom 1
cbo 1

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
C wl_autocomplete() 0 47 7
1
<?php
2
/**
3
 * Wordlift_Autocomplete_Adapter class.
4
 *
5
 * The {@link Wordlift_Autocomplete_Adapter} class create requests to external API's.
6
 *
7
 * @link       https://wordlift.io
8
 *
9
 * @package    Wordlift
10
 * @since      3.15.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Create autocomplete request to external API's and return the result if there is such.
19
 *
20
 * @since 3.15.0
21
 */
22
class Wordlift_Autocomplete_Adapter {
23
24
	/**
25
	 * The {@link Wordlift_Autocomplete_Service} instance.
26
	 *
27
	 * @since  3.15.0
28
	 * @access private
29
	 * @var \Wordlift_Autocomplete_Service $configuration_service The {@link Wordlift_Autocomplete_Service} instance.
30
	 */
31
	private $autocomplete_service;
32
33
34
	/**
35
	 * Wordlift_Autocomplete_Adapter constructor.
36
	 *
37
	 * @since 3.14.2
38
	 *
39
	 * @param \Wordlift_Autocomplete_Service $autocomplete_service The {@link Wordlift_Autocomplete_Service} instance.
40
	 */
41
	public function __construct( $autocomplete_service ) {
42
		$this->autocomplete_service = $autocomplete_service;
43
	}
44
45
	/**
46
	 * Handle the autocomplete ajax request.
47
	 *
48
	 * @since 3.15.0
49
	 */
50
	public function wl_autocomplete() {
0 ignored issues
show
Coding Style introduced by
wl_autocomplete uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
51
		if (
52
			! isset( $_REQUEST['_wpnonce'] ) || // Input var okay.
53
			! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'wordlift_autocomplete' ) // Input var okay.
54
		) {
55
			wp_send_json_error( array(
56
				'message' => __( 'Nonce field doens\'t match.', 'wordlift' ),
57
			) );
58
		}
59
60
		// Return error if the query param is empty.
61
		if ( ! empty( $_REQUEST['query'] ) ) { // Input var okay.
62
			$query = sanitize_text_field( wp_unslash( $_REQUEST['query'] ) ); // Input var okay.
63
		} else {
64
			wp_send_json_error( array(
65
				'message' => __( 'The query param is empty.', 'wordlift' ),
66
			) );
67
		}
68
69
		// Make request.
70
		$response = $this->autocomplete_service->make_request( $query );
0 ignored issues
show
Bug introduced by
The variable $query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
71
72
		// Clear any buffer.
73
		ob_clean();
74
75
		// If the response is valid, then send the suggestions.
76
		if ( ! is_wp_error( $response ) && 200 === (int) $response['response']['code'] ) {
77
			// Echo the response.
78
			wp_send_json_success( array(
79
				json_decode( wp_remote_retrieve_body( $response ), true ),
80
			) );
81
		} else {
82
			// Default error message.
83
			$error_message = 'Something went wrong.';
84
85
			// Get the real error message if there is WP_Error.
86
			if ( is_wp_error( $response ) ) {
87
				$error_message = $response->get_error_message();
0 ignored issues
show
Bug introduced by
The method get_error_message cannot be called on $response (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
88
			}
89
90
			// There is an error, so send error message.
91
			wp_send_json_error( array(
92
				/* translators: Placeholders: %s - the error message that will be returned. */
93
				'message' => sprintf( esc_html__( 'Error: %s', 'wordlift' ), $error_message ),
94
			) );
95
		}
96
	}
97
}
98