Completed
Push — master ( c336cf...9cad87 )
by David
30:41
created

Wordlift_Deactivator_Feedback   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 160
Duplicated Lines 5.63 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 9
loc 160
rs 10
c 0
b 0
f 0
wmc 14
lcom 1
cbo 2

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A has_permission_to_show_popup() 0 21 3
A render_feedback_popup() 0 8 2
A enqueue_popup_scripts() 9 9 2
B wl_deactivation_feedback() 0 55 6

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Fired during plugin deactivate
4
 *
5
 * @link       https://wordlift.io
6
 * @since      3.19.0
7
 *
8
 * @package    Wordlift
9
 * @subpackage Wordlift/includes
10
 */
11
12
/**
13
 * Fired during plugin deactivate.
14
 *
15
 * This class defines all code necessary to run during the plugin's deactivate.
16
 *
17
 * @since      3.19.0
18
 * @package    Wordlift
19
 * @subpackage Wordlift/includes
20
 * @author     WordLift <[email protected]>
21
 */
22
class Wordlift_Deactivator_Feedback {
23
24
	/**
25
	 * A {@link Wordlift_Log_Service} instance.
26
	 *
27
	 * @since  3.19.0
28
	 * @access private
29
	 * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
30
	 */
31
	private $log;
32
33
	/**
34
	 * The {@link Wordlift_Configuration_Service} instance.
35
	 *
36
	 * @since  3.19.0
37
	 * @access private
38
	 * @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
39
	 */
40
	private $configuration_service;
41
42
	/**
43
	 * Wordlift_Deactivator_Feedback constructor.
44
	 *
45
	 * @since 3.19.0
46
	 *
47
	 * @param \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
48
	 */
49
	public function __construct( $configuration_service ) {
50
51
		$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Deactivator_Feedback' );
52
53
		$this->configuration_service = $configuration_service;
54
55
	}
56
	/**
57
	 * Checks whether we have permissions to show the popup.
58
	 *
59
	 * @version 3.19.0
60
	 *
61
	 * @return  bool `true` if we have permissions, false otherwise.
62
	 */
63
	private function has_permission_to_show_popup() {
64
		// Get the current page.
65
		global $pagenow;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
66
67
		// Bail if the user doesn't have permissions
68
		// or if it's not the plugins page.
69
		if ( 'plugins.php' !== $pagenow ) {
70
			return false;
71
		}
72
73
		// Get the user preferences. We shouldn't show the feedback popup
74
		// if we don't have permissions for that.
75
		$user_preferences = $this->configuration_service->get_diagnostic_preferences();
76
77
		// Bail. We don't have preferences to show the popup.
78
		if ( 'yes' !== $user_preferences ) {
79
			return false;
80
		}
81
82
		return true;
83
	}
84
85
	/**
86
	 * Render the feedback popup in the footer.
87
	 *
88
	 * @version 3.19.0
89
	 *
90
	 * @return  void
91
	 */
92
	public function render_feedback_popup() {
93
		// Bail if we don't have permissions to show the popup.
94
		if ( ! $this->has_permission_to_show_popup() ) {
95
			return;
96
		}
97
		// Include the partial.
98
		include plugin_dir_path( __FILE__ ) . '../admin/partials/wordlift-admin-deactivation-feedback-popup.php';
99
	}
100
101
	/**
102
	 * Enqueue required popup scripts and styles.
103
	 *
104
	 * @version 3.19.0
105
	 *
106
	 * @return  void
107
	 */
108 View Code Duplication
	public function enqueue_popup_scripts() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
109
		// Bail if we don't have permissions to show the popup.
110
		if ( ! $this->has_permission_to_show_popup() ) {
111
			return;
112
		}
113
114
		wp_enqueue_style( 'wordlift-admin-feedback-popup', plugin_dir_url( dirname( __FILE__ ) ) . 'admin/css/wordlift-admin-feedback-popup.css', array() );
115
		wp_enqueue_script( 'wordlift-admin-feedback-popup', plugin_dir_url( dirname( __FILE__ ) ) . 'admin/js/wordlift-admin-feedback-popup.js', array( 'jquery' ) );
116
	}
117
118
	/**
119
	 * Handle the deactivation ajax call
120
	 * and perform a request to external server.
121
	 *
122
	 * @version 3.19.0
123
	 *
124
	 * @return  void
125
	 */
126
	public function wl_deactivation_feedback() {
0 ignored issues
show
Coding Style introduced by
wl_deactivation_feedback uses the super-global variable $_POST 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...
127
		// Bail if the nonce is not valid.
128
		if (
129
			empty( $_POST['wl_deactivation_feedback_nonce'] ) || // The nonce doens't exists.
130
			! wp_verify_nonce( $_POST['wl_deactivation_feedback_nonce'], 'wl_deactivation_feedback_nonce' ) // The nonce is invalid.
131
		) {
132
			wp_send_json_error( __( 'Nonce Security Check Failed!', 'wordlift' ) );
133
		}
134
135
		// We allow user to deactivate without providing a reason
136
		// so bail and send success response.
137
		if ( empty( $_POST['code'] ) ) {
138
			wp_send_json_success();
139
		}
140
141
		$plugin_data = get_plugin_data( plugin_dir_path( dirname( __FILE__ ) ) . 'wordlift.php', false, false );
142
143
		// Prepare the options.
144
		$options = array(
145
			// The deactivation reason.
146
			'code'             => $_POST['code'],
147
			// Additional information if provided.
148
			'details'          => ( ! empty( $_POST['details'] ) ) ? $_POST['details'] : '',
149
			// The website url.
150
			'url'              => get_bloginfo( 'url' ),
151
			// WP version.
152
			'wordpressVersion' => get_bloginfo( 'version' ),
153
			// WL version.
154
			'wordliftVersion'  => $plugin_data['Version'],
155
			// The admin email.
156
			'email'            => get_bloginfo( 'admin_email' ),
157
		);
158
159
		$response = wp_remote_post(
160
			$this->configuration_service->get_deactivation_feedback_url(),
161
			array(
162
				'method'  => 'POST',
163
				'body'    => json_encode( $options ),
164
				'headers' => array( 'Content-Type' => 'application/json; charset=utf-8' ),
165
			)
166
		);
167
168
		$code    = wp_remote_retrieve_response_code( $response );
169
		$message = wp_remote_retrieve_response_message( $response );
170
171
		// Add message to the error log if the response code is not 200.
172
		if ( 201 !== $code ) {
173
			// Write the error in the logs.
174
			$this->log->error( 'An error occurred while requesting a feedback endpoint error_code: ' . $code . ' message: ' . $message );
175
		}
176
177
		// We should send success message even when the feedback is not
178
		// send, because otherwise the plugin cannot be deactivated.
179
		wp_send_json_success();
180
	}
181
}
182