PluginProbe
Polylang / 2.8
Polylang v2.8
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.8, at include/license.php

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