Completed
Push — master ( 186893...053e09 )
by Sudar
02:09
created

AddonList::get_inactive_addons()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 11
rs 9.4285
1
<?php namespace EmailLog\Addon;
2
3
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
4
5
/**
6
 * Retrieve the list of add-ons and render them.
7
 *
8
 * @since 2.0.0
9
 */
10
class AddonList {
11
12
	const CACHE_EXPIRY_IN_HRS = 12;
13
	const CACHE_KEY = 'el_addon_list';
14
15
	/**
16
	 * Add-on list.
17
	 *
18
	 * @var Addon[]
19
	 */
20
	protected $addons;
21
22
	/**
23
	 * Store URL.
24
	 *
25
	 * @var string
26
	 */
27
	protected $store_url;
28
29
	/**
30
	 * Create a list of add-ons.
31
	 *
32
	 * @param Addon[]     $addons    List of Add-ons. If not passed, they will be automatically loaded.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $addons not be Addon[]|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
33
	 * @param null|string $store_url Store url.
34
	 */
35
	public function __construct( $addons = null, $store_url = null ) {
36
		if ( null === $store_url ) {
37
			$email_log = email_log();
38
			$store_url = $email_log->get_store_url();
39
		}
40
		$this->store_url = $store_url;
41
42
		if ( null === $addons ) {
43
			$addons = $this->get_addons();
44
		}
45
46
		$this->addons = $addons;
47
	}
48
49
	/**
50
	 * Get an add-on by slug.
51
	 *
52
	 * @param string $slug Add-on slug.
53
	 *
54
	 * @return bool|\EmailLog\Addon\Addon Add-on if found, False otherwise.
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Addon|false.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
55
	 */
56
	public function get_addon_by_slug( $slug ) {
57
		if ( array_key_exists( $slug, $this->addons ) ) {
58
			return $this->addons[ $slug ];
59
		}
60
61
		return false;
62
	}
63
64
	/**
65
	 * Get all add-ons that are not active (either not installed or not activated).
66
	 *
67
	 * @return \EmailLog\Addon\Addon[] List of inactive add-ons.
68
	 */
69
	public function get_inactive_addons() {
70
		$inactive_addons = array();
71
72
		foreach ( $this->addons as $addon ) {
73
			if ( ! $addon->is_active() ) {
74
				$inactive_addons[] = $addon;
75
			}
76
		}
77
78
		return $inactive_addons;
79
	}
80
81
	/**
82
	 * Setup page to render the list of add-ons.
83
	 */
84
	public function render() {
85
		?>
86
87
		<div class="el-container">
88
			<?php $this->render_addons(); ?>
89
			<div class="clear"></div>
90
		</div> <!-- .el-container -->
91
		<?php
92
	}
93
94
	/**
95
	 * Retrieve the list of add-ons by calling the store API.
96
	 *
97
	 * @return Addon[] List of add-ons, empty array if API call fails.
98
	 */
99
	protected function get_addons() {
100
		if ( false === ( $addons = get_transient( self::CACHE_KEY ) ) ) {
101
			$response = wp_remote_get( $this->get_api_url() );
102
103
			if ( is_wp_error( $response ) || ! is_array( $response ) ) {
104
				// TODO: Don't keep trying if the server is down.
105
				return array();
106
			}
107
108
			$addons = $this->parse_response( wp_remote_retrieve_body( $response ) );
109
110
			if ( ! empty( $addons ) ) {
111
				set_transient( self::CACHE_KEY, $addons, self::CACHE_EXPIRY_IN_HRS * HOUR_IN_SECONDS );
112
			}
113
		}
114
115
		return $addons;
116
	}
117
118
	/**
119
	 * Parse the response and get the list of add-on.
120
	 *
121
	 * @param string $response API Response.
122
	 *
123
	 * @return array List of Add-ons.
124
	 */
125
	protected function parse_response( $response ) {
126
		$json = json_decode( $response, true );
127
128
		if ( ! is_array( $json ) || ! array_key_exists( 'products', $json ) ) {
129
			return array();
130
		}
131
132
		return $this->build_addon_list( $json['products'] );
133
	}
134
135
	/**
136
	 * Build a list of Addon objects from products data array.
137
	 *
138
	 * @param array $products Products data array.
139
	 *
140
	 * @return Addon[] List of Addons.
141
	 */
142
	protected function build_addon_list( $products ) {
143
		$addons = array();
144
145
		foreach ( $products as $product ) {
146
			$addon = new Addon( $product );
147
			$addons[ $addon->slug ] = $addon;
148
		}
149
150
		return $addons;
151
	}
152
153
	/**
154
	 * Render the add-on list or display an error if the list can't be retrieved.
155
	 */
156
	protected function render_addons() {
157
		if ( empty( $this->addons ) ) {
158
			$this->render_empty_list();
159
		}
160
161
		foreach ( $this->addons as $addon ) {
162
			$addon->render();
163
		}
164
	}
165
166
	/**
167
	 * Display a notice if the list of add-on can't be retrieved.
168
	 */
169
	protected function render_empty_list() {
170
		?>
171
		<span class="el-addon-empty">
172
			<?php
173
				printf(
174
					__( 'We are not able to retrieve the add-on list now. Please visit the <a href="%s">add-on page</a> to view the add-ons.', 'email-log' ), // @codingStandardsIgnoreLine
175
					'https://wpemaillog.com/addons'
176
				);
177
			?>
178
		</span>
179
		<?php
180
	}
181
182
	/**
183
	 * Get API URL.
184
	 *
185
	 * @return string API URL.
186
	 */
187
	protected function get_api_url() {
188
		return $this->store_url . '/edd-api/products/?category=addon';
189
	}
190
}
191