Passed
Push — master ( 65f2fd...a92f6e )
by Fernando
02:12
created

LSX_API_Manager::check_status()   C

Complexity

Conditions 8
Paths 28

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 16
nc 28
nop 1
dl 0
loc 24
rs 5.7377
c 0
b 0
f 0
1
<?php
2
/**
3
 * LSX API Manager Class
4
 *
5
 * @package   LSX API Manager
6
 * @author    LightSpeed
7
 * @license   GPL3
8
 * @link
9
 * @copyright 2016 LightSpeed
10
 */
11
class LSX_API_Manager {
12
13
	/**
14
	 * Holds the API Key
15
	 *
16
	 * @var      string
17
	 */
18
	public $api_key = false;
19
20
	/**
21
	 * Holds the mode (dev/live)
22
	 *
23
	 * @var      string
24
	 */
25
	public $dev_mode = false;
26
27
	/**
28
	 * Holds the Email address used to purchase the API key
29
	 *
30
	 * @var      string
31
	 */
32
	public $email = false;
33
34
	/**
35
	 * Holds the Products Title
36
	 *
37
	 * @var      string
38
	 */
39
	public $product_id = false;
40
41
	/**
42
	 * Holds the Products Slug
43
	 *
44
	 * @var      string
45
	 */
46
	public $product_slug = false;
47
48
	/**
49
	 * Holds the current version of the plugin
50
	 *
51
	 * @var      string
52
	 */
53
	public $version = false;
54
55
	/**
56
	 * Holds the unique password for this site.
57
	 *
58
	 * @var      string
59
	 */
60
	public $password = false;
61
62
	/**
63
	 * Holds any messages for the user.
64
	 *
65
	 * @var      string
66
	 */
67
	public $messages = false;
68
69
	/**
70
	 * Holds any path to the plugin file.
71
	 *
72
	 * @var      string
73
	 */
74
	public $file = false;
75
76
	/**
77
	 * Holds the activate / deactivate button.
78
	 *
79
	 * @var      string
80
	 */
81
	public $button = false;
82
83
	/**
84
	 * Holds the documentation slug button.
85
	 *
86
	 * @var      string
87
	 */
88
	public $documentation = false;
89
90
	/**
91
	 * Holds class instance
92
	 *
93
	 * @var      string
94
	 */
95
	protected static $instance = null;
96
97
	/**
98
	 * Initialize the plugin by setting localization, filters, and administration functions.
99
	 */
100
	public function __construct($api_array = array()) {
101
102
		if(isset($api_array['api_key'])){
103
			$api_array['api_key'] = trim($api_array['api_key']);
104
			if('dev-' === substr($api_array['api_key'], 0, 4)){
105
				$this->dev_mode = true;
0 ignored issues
show
Documentation Bug introduced by
The property $dev_mode was declared of type string, but true is of type boolean. 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...
106
				$api_array['api_key'] = preg_replace('/^(dev-)(.*)$/i', '${2}', $api_array['api_key']);
107
			}
108
			$this->api_key = $api_array['api_key'];
109
		}
110
		if(isset($api_array['email'])){
111
			$this->email = trim($api_array['email']);
112
		}
113
		if(isset($api_array['product_id'])){
114
			$this->product_id = $api_array['product_id'];
115
			$this->product_slug = sanitize_title($api_array['product_id']);
116
		}
117
		if(isset($api_array['version'])){
118
			$this->version = $api_array['version'];
119
		}
120
		if(isset($api_array['instance'])){
121
			$this->password = $api_array['instance'];
122
		}
123
		if(isset($api_array['file'])){
124
			$this->file = $api_array['file'];
125
		}
126
127
		if(isset($api_array['documentation'])){
128
			$this->documentation = $api_array['documentation'];
129
		}
130
131
		if ($this->dev_mode) {
132
			$this->api_url = 'https://dev.lsdev.biz/wc-api/product-key-api';
0 ignored issues
show
Bug introduced by
The property api_url does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
133
			$this->products_api_url = 'https://dev.lsdev.biz/';
0 ignored issues
show
Bug introduced by
The property products_api_url does not seem to exist. Did you mean api_url?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
134
			$this->license_check_url = 'https://dev.lsdev.biz/wc-api/license-status-check';
0 ignored issues
show
Bug introduced by
The property license_check_url does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
135
		} else {
136
			$this->api_url = 'https://www.lsdev.biz/wc-api/product-key-api';
137
			$this->products_api_url = 'https://www.lsdev.biz/';
0 ignored issues
show
Bug introduced by
The property products_api_url does not seem to exist. Did you mean api_url?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
138
			$this->license_check_url = 'https://www.lsdev.biz/wc-api/license-status-check';
139
		}
140
141
		add_filter( 'plugin_action_links_' . plugin_basename(str_replace('.php','',$this->file).'/'.$this->file), array($this,'add_action_links'));
142
		$this->status = get_option($this->product_slug.'_status',false);
0 ignored issues
show
Bug introduced by
The property status does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
143
144
		if(isset($_GET['page']) && in_array($_GET['page'],apply_filters('lsx_api_manager_options_pages',array(false)))){
145
146
			//Maybe activate the software, do this before the status checks.
147
			$this->activate_deactivate();
148
149
			if(false === $this->status){
150
				$this->status = $this->check_status();
151
				update_option($this->product_slug.'_status',$this->status);
152
			}
153
154
			$button_url = '<a data-product="'.$this->product_slug.'" style="margin-top:-5px;" href="';
155
			$button_label = '';
156
			$admin_url_base = function_exists( 'tour_operator' ) ? 'admin.php?page=lsx-to-settings' : 'themes.php?page=lsx-settings';
157
			if(false === $this->status || 'inactive' === $this->status){
158
				$button_url .= admin_url($admin_url_base.'&action=activate&product='.$this->product_slug);
159
				$button_label = 'Activate';
160
			}elseif('active' === $this->status){
161
				$button_url .= admin_url($admin_url_base.'&action=deactivate&product='.$this->product_slug);
162
				$button_label = 'Deactivate';
163
			}
164
			$button_url .= '" class="button-secondary activate">'.$button_label.'</a>';
165
			$this->button = $button_url;
166
		}
167
168
		add_filter('site_transient_update_plugins', array($this,'injectUpdate'));
169
		add_action( "in_plugin_update_message-".$this->file,array($this,'plugin_update_message'),10,2);
170
171
		if ( function_exists( 'tour_operator' ) ) {
172
			add_action( 'lsx_to_framework_api_tab_content', array( $this, 'dashboard_tabs' ), 1, 1 );
173
		} else {
174
			add_action( 'lsx_framework_api_tab_content', array( $this, 'dashboard_tabs' ), 1, 1 );
175
		}
176
177
		add_action('wp_ajax_wc_api_'.$this->product_slug,array($this,'activate_deactivate'));
178
		add_action('wp_ajax_nopriv_wc_api_'.$this->product_slug,array($this,'activate_deactivate'));
179
	}
180
181
	/**
182
	 * Return an instance of this class.
183
	 *
184
	 * @since 1.0.0
185
	 *
186
	 * @return    object    A single instance of this class.
187
	 */
188
	public static function get_instance() {
189
		// If the single instance hasn't been set, set it now.
190
		if ( null == self::$instance ) {
191
			self::$instance = new self;
0 ignored issues
show
Documentation Bug introduced by
It seems like new self() of type object<LSX_API_Manager> is incompatible with the declared type string of property $instance.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
192
		}
193
		return self::$instance;
194
	}
195
196
	/**
197
	 * Outputs the dashboard tab pages.
198
	 *
199
	 * @since 1.0.0
200
	 *
201
	 * @return    object A single instance of this class.
202
	 */
203
	public function dashboard_tabs($tab='general') {
204
		if('api' !== $tab){ return false;}
205
206
		if('active' === $this->status){
207
			$description = __( '<span style="color:#008000;">Your license is now active</span>', $this->product_slug );
0 ignored issues
show
Unused Code introduced by
$description is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
208
		}else{
209
			$description = __( 'You can find your key on your <a target="_blank" href="https://www.lsdev.biz/my-account/">My Account</a> page.', $this->product_slug );
0 ignored issues
show
Unused Code introduced by
$description is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
210
		}
211
212
		?>
213
		<tr class="form-field <?php echo $this->product_slug; ?>-wrap">
214
			<th class="<?php echo $this->product_slug; ?>_table_heading" style="padding-bottom:0px;" scope="row" colspan="2">
215
216
				<?php
217
				$colour = 'red';
218
				if('active' === $this->status){
219
					$colour = 'green';
220
				}
221
				?>
222
223
				<h4 style="margin-bottom:0px;">
224
					<span><?php echo $this->product_id; ?></span>
225
					- <span><?php echo $this->version; ?></span>
226
					- <span style="color:<?php echo $colour;?>;"><?php echo $this->status; ?></span>
227
					- <?php echo $this->button; ?>
228
				</h4>
229
230
				<?php if ( $this->dev_mode && is_array( $this->messages ) ) { ?><p><small class="messages" style="font-weight:normal;"><?php echo implode( '. ', $this->messages ); ?></small></p><?php }  ?>
231
232
			</th>
233
		</tr>
234
235
		<tr class="form-field <?php echo $this->product_slug; ?>-api-email-wrap">
236
			<th style="font-size:13px;" scope="row">
237
				<i class="dashicons-before dashicons-email-alt"></i> <?php esc_html_e( 'Registered Email', $this->product_slug ); ?>
238
			</th>
239
			<td>
240
				<input type="text" {{#if <?php echo $this->product_slug; ?>_email}} value="{{<?php echo $this->product_slug; ?>_email}}" {{/if}} name="<?php echo $this->product_slug; ?>_email" /><br />
241
			</td>
242
243
		</tr>
244
		<tr class="form-field <?php echo $this->product_slug; ?>-api-key-wrap">
245
			<th style="font-size:13px;" scope="row">
246
				<i class="dashicons-before dashicons-admin-network"></i> <?php esc_html_e( 'API Key', $this->product_slug ); ?>
247
			</th>
248
			<td>
249
				<input type="text" {{#if <?php echo $this->product_slug; ?>_api_key}} value="{{<?php echo $this->product_slug; ?>_api_key}}" {{/if}} name="<?php echo $this->product_slug; ?>_api_key" />
250
			</td>
251
		</tr>
252
253
		<?php
254
		$this->settings_page_scripts();
255
	}
256
257
	/**
258
	 * outputs the scripts for the dashboard settings pages.
259
	 */
260
	public function settings_page_scripts(){ ?>
261
		{{#script}}
262
		jQuery( function( $ ){
263
		$( '.<?php echo $this->product_slug; ?>-api-email-wrap input' ).on( 'change', function() {
264
		$('input[name="<?php echo $this->product_slug; ?>_api_action"]').remove();
265
266
		var action = 'activate';
267
		if('' == $(this).val() || undefined == $(this).val()){
268
		action = 'deactivate';
269
		}
270
		$('.<?php echo $this->product_slug; ?>-wrap').append('<input type="hidden" value="'+action+'" name="<?php echo $this->product_slug; ?>_api_action" />');
271
		});
272
273
		$( '.activate[data-product="<?php echo $this->product_slug; ?>"]' ).on( 'click', function() {
274
		event.preventDefault();
275
		console.log('hello');
276
		var url = $(this).attr('href');
277
		$( window ).on('uix.saved',function() {
278
		window.location.href = url;
279
		});
280
		$('button[data-save-object="true"]').click();
281
		});
282
		});
283
		{{/script}}
284
		<?php
285
	}
286
287
	/**
288
	 * Return an instance of this class.
289
	 */
290
	public function activate_deactivate(){
291
		if(isset($_GET['action']) && 'activate' === $_GET['action']
292
			&& isset($_GET['product']) && $this->product_slug === $_GET['product']
293
			&& false !== $this->api_key && '' !== $this->api_key
294
			&& false !== $this->email && '' !== $this->email){
295
296
297
			$response = $this->query('activation');
298
			if(is_object($response) && isset($response->activated) && true === $response->activated){
299
				update_option($this->product_slug.'_status','active');
300
				$this->status = 'active';
301
			}
302
		}
303
304
		if((isset($_GET['action']) && 'deactivate' === $_GET['action'] && isset($_GET['product']) && $this->product_slug === $_GET['product'])
305
			|| (false === $this->api_key || '' === $this->api_key || false === $this->email || '' === $this->email)){
306
307
			if('active' === $this->status) {
308
				$this->query('deactivation');
309
				update_option($this->product_slug.'_status','inactive');
310
				$this->status = 'inactive';
311
			}
312
		}
313
	}
314
315
	/**
316
	 * Generates the API URL
317
	 */
318
	public function create_software_api_url( $args ) {
319
320
		$endpoint = 'am-software-api';
321
		if('pluginupdatecheck' === $args['request']){
322
			$endpoint = 'upgrade-api';
323
		}
324
		$api_url = add_query_arg( 'wc-api', $endpoint, $this->products_api_url );
0 ignored issues
show
Bug introduced by
The property products_api_url does not seem to exist. Did you mean api_url?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
325
		return $api_url . '&' . http_build_query( $args );
326
	}
327
328
	/**
329
	 * Checks if the software is activated or deactivated
330
	 * @return string
331
	 */
332
	public function check_status($response = false) {
333
		if(false === $response){
334
			$response = $this->query('status');
335
		}
336
		if ( $this->dev_mode ) {
337
			$this->messages[] = print_r( $response, true );
338
		}
339
		$status = 'inactive';
340
		if(is_object($response)){
341
342
			if(isset($response->error)){
343
				$this->messages[] = $this->format_error_code($response->code);
344
			}elseif(isset($response->status_check)){
345
				$status = $response->status_check;
346
				if(isset($response->activations_remaining)){
347
					$this->messages[] = $response->activations_remaining;
348
				}
349
				if(isset($response->message)){
350
					$this->messages[] = $response->message;
351
				}
352
			}
353
		}
354
		return $status;
355
	}
356
357
	/**
358
	 * Does the actual contacting to the API.
359
	 * @param  string $action
360
	 * @return array
361
	 */
362
	public function query($action='status') {
363
		if ( 'status' === $action ) {
364
			$transient_status_id = 'lsx_addon_' . $this->product_id . '_status';
365
			$response =  get_transient( $transient_status_id );
366
		} else {
367
			$response = false;
368
		}
369
370
		if ( ! $response ) {
371
			$args = array(
372
				'request' 		=> $action,
373
				'email' 		=> $this->email,
374
				'licence_key'	=> $this->api_key,
375
				'product_id' 	=> $this->product_id,
376
				'platform' 		=> home_url(),
377
				'instance' 		=> $this->password
378
			);
379
			$target_url = esc_url_raw( $this->create_software_api_url( $args ) );
380
381
			$request = wp_remote_get( $target_url );
382
			if( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) {
383
				// Request failed
384
				return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by LSX_API_Manager::query of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
385
			}
386
			$response = wp_remote_retrieve_body( $request );
387
			if ( $this->dev_mode ) {
388
				$this->messages[] = print_r( $response, true );
389
			}
390
			set_transient( $transient_status_id, $response, MINUTE_IN_SECONDS );
0 ignored issues
show
Bug introduced by
The variable $transient_status_id 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...
391
		}
392
393
		return json_decode($response);
394
	}
395
396
	/**
397
	 * Formats the error code into a readable format.
398
	 * @param  array $args
0 ignored issues
show
Bug introduced by
There is no parameter named $args. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
399
	 * @return array
400
	 */
401
	public function format_error_code($code=false){
402
		switch ( $code ) {
403 View Code Duplication
			case '101' :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
404
				$error = array( 'error' => esc_html__( 'Invalid API License Key. Login to your My Account page to find a valid API License Key', $this->product_slug ), 'code' => '101' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
405
				break;
406 View Code Duplication
			case '102' :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
407
				$error = array( 'error' => esc_html__( 'Software has been deactivated', $this->product_slug ), 'code' => '102' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
408
				break;
409 View Code Duplication
			case '103' :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
410
				$error = array( 'error' => esc_html__( 'Exceeded maximum number of activations', $this->product_slug ), 'code' => '103' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
411
				break;
412 View Code Duplication
			case '104' :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
413
				$error = array( 'error' => esc_html__( 'Invalid Instance ID', $this->product_slug ), 'code' => '104' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
414
				break;
415 View Code Duplication
			case '105' :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
416
				$error = array( 'error' => esc_html__( 'Invalid API License Key', $this->product_slug ), 'code' => '105' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
417
				break;
418 View Code Duplication
			case '106' :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
419
				$error = array( 'error' => esc_html__( 'Subscription Is Not Active', $this->product_slug ), 'code' => '106' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
420
				break;
421
			default :
422
				$error = array( 'error' => esc_html__( 'Invalid Request', $this->product_slug ), 'code' => '100' );
0 ignored issues
show
Unused Code introduced by
$error is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
423
				break;
424
		}
425
	}
426
427
	public static function generatePassword($length = 20) {
428
		$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
429
		$count = mb_strlen($chars);
430
431
		for ($i = 0, $result = ''; $i < $length; $i++) {
432
			$index = rand(0, $count - 1);
433
			$result .= mb_substr($chars, $index, 1);
434
		}
435
436
		return $result;
437
	}
438
439
	public function set_update_status(){
440
		$this->status = $this->check_status();
441
		$this->upgrade_response = get_transient($this->product_slug.'_upgrade_response',false);
0 ignored issues
show
Bug introduced by
The property upgrade_response does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
442
443
		if(false !== $this->upgrade_response){
444
			$this->upgrade_response = maybe_unserialize($this->upgrade_response);
445
		}
446
447
		if(isset($this->status) && 'active' === $this->status && false === $this->upgrade_response){
448
			$args = array(
449
				'request' 			=> 'pluginupdatecheck',
450
				'plugin_name' 		=> $this->product_slug.'/'.$this->file,
451
				'version' 			=> $this->product_slug,
452
				'activation_email' 	=> $this->email,
453
				'api_key'			=> $this->api_key,
454
				'product_id' 		=> $this->product_id,
455
				'domain' 			=> home_url(),
456
				'instance' 			=> $this->password,
457
				'software_version'	=> $this->version,
458
			);
459
			$target_url = esc_url_raw( $this->create_software_api_url( $args ) );
460
			$request = wp_remote_get( $target_url );
461
			if( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) {
462
				// Request failed
463
				$this->upgrade_response=false;
464
			}
465
			$response = wp_remote_retrieve_body( $request );
466
			$this->upgrade_response = maybe_unserialize($response);
467
			set_transient($this->product_slug . '_upgrade_response', $response, 60 * 30);
468
		}
469
	}
470
471
	/**
472
	 * Insert the latest update (if any) into the update list maintained by WP.
473
	 *
474
	 * @param StdClass $updates Update list.
475
	 * @return StdClass Modified update list.
476
	 */
477
	public function injectUpdate($updates=false){
478
		$this->set_update_status();
479
		if(isset($this->status) && 'active' === $this->status && null !== $this->upgrade_response && is_object($this->upgrade_response) && isset($this->upgrade_response->new_version) && version_compare ( $this->upgrade_response->new_version , $this->version , '>' )){
480
481
			//setup the response if our plugin is the only one that needs updating.
482
			if ( !is_object($updates) ) {
483
				$updates = new StdClass();
484
				$updates->response = array();
485
			}
486
			$updates->response[$this->product_slug.'/'.$this->file] = $this->upgrade_response;
487
		}
488
		return $updates;
0 ignored issues
show
Bug Compatibility introduced by
The expression return $updates; of type false|stdClass is incompatible with the return type documented by LSX_API_Manager::injectUpdate of type stdClass as it can also be of type false which is not included in this return type.
Loading history...
489
	}
490
491
	/**
492
	 * Adds in the "settings" link for the plugins.php page
493
	 */
494
	public function add_action_links ( $links ) {
495
		$admin_url_base = function_exists( 'tour_operator' ) ? 'admin.php?page=lsx-to-settings' : 'themes.php?page=lsx-settings';
496
		$documentation = $this->product_slug;
497
		if(false !== $this->documentation){$documentation = $this->documentation; }
498
		$mylinks = array(
499
			'<a href="' . admin_url( $admin_url_base ) . '">'.esc_html__('Settings',$this->product_slug).'</a>',
500
			'<a href="https://www.lsdev.biz/documentation/'.$documentation.'/" target="_blank">'.esc_html__('Documentation',$this->product_slug).'</a>',
501
			'<a href="https://www.lsdev.biz/contact-us/" target="_blank">'.esc_html__('Support',$this->product_slug).'</a>',
502
		);
503
		return array_merge( $links, $mylinks );
504
	}
505
}
506