Completed
Push — master ( 49679a...617b2a )
by Sudar
02:03
created

AddonList::parse_response()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 1
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php namespace EmailLog\Addon;
2
3
use EmailLog\Addon\Addon;
4
5
defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
6
7
/**
8
 * Retrieve the list of add-ons and render them.
9
 *
10
 * @since 2.0.0
11
 */
12
class AddonList {
13
14
	const API_URL = 'https://wpemaillog.com/edd-api/products/?category=addon';
15
	const CACHE_EXPIRY_IN_HRS = 12;
16
	const CACHE_KEY = 'el_addon_list';
17
18
	/**
19
	 * Add-on list.
20
	 *
21
	 * @var Addon[]
22
	 */
23
	protected $addons;
24
25
	/**
26
	 * Create a list of add-ons.
27
	 *
28
	 * @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...
29
	 */
30
	public function __construct( $addons = null ) {
31
		if ( null === $addons ) {
32
			$addons = $this->get_addons();
33
		}
34
35
		$this->addons = $addons;
36
	}
37
38
	/**
39
	 * Setup page to render the list of add-ons.
40
	 */
41
	public function render() {
42
		?>
43
44
		<div class="el-container">
45
			<?php $this->render_addons(); ?>
46
			<div class="clear"></div>
47
		</div> <!-- .el-container -->
48
		<?php
49
	}
50
51
	/**
52
	 * Retrieve the list of add-ons by calling the store API.
53
	 *
54
	 * @return Addon[] List of add-ons, empty array if API call fails.
55
	 */
56
	protected function get_addons() {
57
		if ( false === ( $addons = get_transient( self::CACHE_KEY ) ) ) {
58
			$response = wp_remote_get( self::API_URL );
59
60
			if ( is_wp_error( $response ) || ! is_array( $response ) ) {
61
				// TODO: Don't keep trying if the server is down.
62
				return array();
63
			}
64
65
			$addons = $this->parse_response( wp_remote_retrieve_body( $response ) );
66
67
			if ( ! empty( $addons ) ) {
68
				set_transient( self::CACHE_KEY, $addons, self::CACHE_EXPIRY_IN_HRS * HOUR_IN_SECONDS );
69
			}
70
		}
71
72
		return $addons;
73
	}
74
75
	/**
76
	 * Parse the response and get the list of add-on.
77
	 *
78
	 * @param string $response API Response.
79
	 *
80
	 * @return array List of Add-ons.
81
	 */
82
	protected function parse_response( $response ) {
83
		$json = json_decode( $response, true );
84
85
		if ( ! is_array( $json ) || ! array_key_exists( 'products', $json ) ) {
86
			return array();
87
		}
88
89
		return $this->build_addon_list( $json['products'] );
90
	}
91
92
	/**
93
	 * Build a list of Addon objects from products data array.
94
	 *
95
	 * @param array $products Products data array.
96
	 *
97
	 * @return Addon[] List of Addons.
98
	 */
99
	protected function build_addon_list( $products ) {
100
		$addons = array();
101
102
		foreach ( $products as $product ) {
103
			$addon = new Addon( $product );
104
			$addons[ $addon->slug ] = $addon;
0 ignored issues
show
Documentation introduced by
The property $slug is declared private in EmailLog\Addon\Addon. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
105
		}
106
107
		return $addons;
108
	}
109
110
	/**
111
	 * Render the add-on list or display an error if the list can't be retrieved.
112
	 */
113
	protected function render_addons() {
114
		if ( empty( $this->addons ) ) {
115
			$this->render_empty_list();
116
		}
117
118
		foreach ( $this->addons as $addon ) {
119
			$addon->render();
120
		}
121
	}
122
123
	/**
124
	 * Display a notice if the list of add-on can't be retrieved.
125
	 */
126
	protected function render_empty_list() {
127
		?>
128
		<span class="el-addon-empty">
129
			<?php
130
				printf(
131
					__( '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
132
					'https://wpemaillog.com/addons'
133
				);
134
			?>
135
		</span>
136
		<?php
137
	}
138
139
	/**
140
	 * Get an add-on by slug.
141
	 *
142
	 * @param string $slug Add-on slug.
143
	 *
144
	 * @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...
145
	 */
146
	public function get_addon_by_slug( $slug ) {
147
		if ( array_key_exists( $slug, $this->addons ) ) {
148
			return $this->addons[ $slug ];
149
		}
150
151
		return false;
152
	}
153
}
154