PluginProbe
Polylang / 2.7
Polylang v2.7
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / include / license.php

license.php in Polylang 2.7, at include/license.php

297 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * A class to easily manage licenses for Polylang Pro and addons
5 *
6 * @since 1.9
7 */
8 class PLL_License {
9 public $id, $name, $license_key, $license_data;
10 private $file, $version, $author;
11 private $api_url = 'https://polylang.pro';
12
13 /**
14 * Constructor
15 *
16 * @since 1.9
17 *
18 * @param string $file
19 * @param string $item_name
20 * @param string $version
21 * @param string $author
22 * @param string $api_url optional
23 */
24 public function __construct( $file, $item_name, $version, $author, $api_url = null ) {
25 $this->id = sanitize_title( $item_name );
26 $this->file = $file;
27 $this->name = $item_name;
28 $this->version = $version;
29 $this->author = $author;
30 $this->api_url = empty( $api_url ) ? $this->api_url : $api_url;
31
32 $licenses = get_option( 'polylang_licenses' );
33 $this->license_key = empty( $licenses[ $this->id ]['key'] ) ? '' : $licenses[ $this->id ]['key'];
34 if ( ! empty( $licenses[ $this->id ]['data'] ) ) {
35 $this->license_data = $licenses[ $this->id ]['data'];
36 }
37
38 // Updater
39 add_action( 'admin_init', array( $this, 'auto_updater' ), 0 );
40 add_action( 'cli_init', array( $this, 'auto_updater' ), 0 ); // For WP CLI.
41
42 // Register settings
43 add_filter( 'pll_settings_licenses', array( $this, 'settings' ) );
44
45 // Weekly schedule
46 if ( ! wp_next_scheduled( 'polylang_check_licenses' ) ) {
47 wp_schedule_event( time(), 'weekly', 'polylang_check_licenses' );
48 }
49
50 add_action( 'polylang_check_licenses', array( $this, 'check_license' ) );
51 }
52
53 /**
54 * Auto updater
55 *
56 * @since 1.9
57 */
58 public function auto_updater() {
59 $args = array(
60 'version' => $this->version,
61 'license' => $this->license_key,
62 'author' => $this->author,
63 'item_name' => $this->name,
64 );
65
66 // Setup the updater
67 new PLL_Plugin_Updater( $this->api_url, $this->file, $args );
68 }
69
70 /**
71 * Registers the licence in the Settings
72 *
73 * @since 1.9
74 *
75 * @param array $items
76 * @return array
77 */
78 public function settings( $items ) {
79 $items[ $this->id ] = $this;
80 return $items;
81 }
82
83 /**
84 * Activate the license key
85 *
86 * @since 1.9
87 *
88 * @param string $license_key activation key
89 * @return object updated $this
90 */
91 public function activate_license( $license_key ) {
92 $this->license_key = $license_key;
93 $this->api_request( 'activate_license' );
94
95 // Tell WordPress to look for updates
96 set_site_transient( 'update_plugins', null );
97 return $this;
98 }
99
100
101 /**
102 * Deactivate the license key
103 *
104 * @since 1.9
105 *
106 * @return object updated $this
107 */
108 public function deactivate_license() {
109 $this->api_request( 'deactivate_license' );
110 return $this;
111 }
112
113 /**
114 * Check if license key is valid
115 *
116 * @since 1.9
117 *
118 * @return object updated $this
119 */
120 public function check_license() {
121 $this->api_request( 'check_license' );
122 return $this;
123 }
124
125 /**
126 * Sends an api request to check, activate or deactivate the license
127 * Updates the licenses option according to the status
128 *
129 * @since 1.9
130 *
131 * @param string $request check_license | activate_license | deactivate_license
132 */
133 private function api_request( $request ) {
134 $licenses = get_option( 'polylang_licenses' );
135
136 if ( is_array( $licenses ) ) {
137 unset( $licenses[ $this->id ] );
138 } else {
139 $licenses = array();
140 }
141 unset( $this->license_data );
142
143 if ( ! empty( $this->license_key ) ) {
144 // Data to send in our API request
145 $api_params = array(
146 'edd_action' => $request,
147 'license' => $this->license_key,
148 'item_name' => urlencode( $this->name ),
149 'url' => home_url(),
150 );
151
152 // Call the API
153 $response = wp_remote_post(
154 $this->api_url,
155 array(
156 'timeout' => 3,
157 'sslverify' => false,
158 'body' => $api_params,
159 )
160 );
161
162 // Update the option only if we got a response
163 if ( is_wp_error( $response ) ) {
164 return;
165 }
166
167 // Save new license info
168 $licenses[ $this->id ] = array( 'key' => $this->license_key );
169 $data = json_decode( wp_remote_retrieve_body( $response ) );
170
171 if ( 'deactivated' !== $data->license ) {
172 $licenses[ $this->id ]['data'] = $this->license_data = $data;
173 }
174 }
175
176 update_option( 'polylang_licenses', $licenses ); // FIXME called multiple times when saving all licenses
177 }
178
179 /**
180 * Get the html form field in a table row (one per license key) for display
181 *
182 * @since 2.7
183 *
184 * @return string
185 */
186 public function get_form_field() {
187 if ( ! empty( $this->license_data ) ) {
188 $license = $this->license_data;
189 }
190
191 $class = 'license-null';
192
193 $out = sprintf(
194 '<td><label for="pll-licenses[%1$s]">%2$s</label></td>' .
195 '<td><input name="licenses[%1$s]" id="pll-licenses[%1$s]" type="text" value="%3$s" class="regular-text code" />',
196 esc_attr( $this->id ),
197 esc_attr( $this->name ),
198 esc_html( $this->license_key )
199 );
200
201 if ( ! empty( $license ) && is_object( $license ) ) {
202 $now = time();
203 $expiration = isset( $license->expires ) ? strtotime( $license->expires ) : false;
204
205 // Special case: the license expired after the last check
206 if ( $license->success && $expiration && $expiration < $now ) {
207 $license->success = false;
208 $license->error = 'expired';
209 }
210
211 if ( false === $license->success ) {
212 $class = 'notice-error notice-alt';
213
214 switch ( $license->error ) {
215 case 'expired':
216 $message = sprintf(
217 /* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
218 esc_html__( 'Your license key expired on %1$s. Please %2$srenew your license key%3$s.', 'polylang' ),
219 esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
220 sprintf( '<a href="%s" target="_blank">', esc_url( 'https://polylang.pro/checkout/?edd_license_key=' . $this->license_key ) ),
221 '</a>'
222 );
223 break;
224
225 case 'disabled':
226 case 'revoked':
227 $message = esc_html__( 'Your license key has been disabled.', 'polylang' );
228 break;
229
230 case 'missing':
231 $message = sprintf(
232 /* translators: %1$s is link start tag, %2$s is link end tag. */
233 esc_html__( 'Invalid license. Please %1$svisit your account page%2$s and verify it.', 'polylang' ),
234 sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
235 '</a>'
236 );
237 break;
238
239 case 'invalid':
240 case 'site_inactive':
241 $message = sprintf(
242 /* translators: %1$s is a product name, %2$s is link start tag, %3$s is link end tag. */
243 esc_html__( 'Your %1$s license key is not active for this URL. Please %2$svisit your account page%3$s to manage your license key URLs.', 'polylang' ),
244 esc_html( $this->name ),
245 sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
246 '</a>'
247 );
248 break;
249
250 case 'item_name_mismatch':
251 /* translators: %s is a product name */
252 $message = sprintf( esc_html__( 'This is not a %s license key.', 'polylang' ), esc_html( $this->name ) );
253 break;
254
255 case 'no_activations_left':
256 $message = sprintf(
257 /* translators: %1$s is link start tag, %2$s is link end tag */
258 esc_html__( 'Your license key has reached its activation limit. %1$sView possible upgrades%2$s now.', 'polylang' ),
259 sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
260 '</a>'
261 );
262 break;
263 }
264 } else {
265 $class = 'license-valid';
266
267 $out .= sprintf( '<button id="deactivate_%s" type="button" class="button button-secondary pll-deactivate-license">%s</button>', esc_attr( $this->id ), esc_html__( 'Deactivate', 'polylang' ) );
268
269 if ( 'lifetime' === $license->expires ) {
270 $message = esc_html__( 'The license key never expires.', 'polylang' );
271 } elseif ( $expiration > $now && $expiration - $now < ( DAY_IN_SECONDS * 30 ) ) {
272 $class = 'notice-warning notice-alt';
273 $message = sprintf(
274 /* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
275 esc_html__( 'Your license key will expire soon! Precisely, it will expire on %1$s. %2$sRenew your license key today!%3$s.', 'polylang' ),
276 esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
277 sprintf( '<a href="%s" target="_blank">', esc_url( 'https://polylang.pro/checkout/?edd_license_key=' . $this->license_key ) ),
278 '</a>'
279 );
280 } else {
281 $message = sprintf(
282 /* translators: %s is a date */
283 esc_html__( 'Your license key expires on %s.', 'polylang' ),
284 esc_html( date_i18n( get_option( 'date_format' ), $expiration ) )
285 );
286 }
287 }
288 }
289
290 if ( ! empty( $message ) ) {
291 $out .= '<p>' . $message . '</p>';
292 }
293
294 return sprintf( '<tr id="pll-license-%s" class="%s">%s</tr>', esc_attr( $this->id ), $class, $out );
295 }
296 }
297