iThemes Sync - Version 2.0.13

Version Description

  • Enhancment: Updater improvements
Download this release

Release Info

Developer layotte
Plugin Icon 128x128 iThemes Sync
Version 2.0.13
Comparing to
See all releases

Code changes from version 2.0.12 to 2.0.13

admin.php CHANGED
@@ -57,21 +57,27 @@ class Ithemes_Sync_Admin {
57
  $show_sync = true;
58
  set_site_transient( "ithemes-sync-force-display-$user_id", true, 600 );
59
 
60
- add_action( 'all_admin_notices', array( $this, 'show_force_display_notice' ), 0 );
 
 
61
  } else {
62
  delete_site_transient( "ithemes-sync-force-display-$user_id" );
63
 
64
- add_action( 'all_admin_notices', array( $this, 'show_force_display_disable_notice' ), 0 );
 
 
65
  }
66
  } else if ( false !== get_site_transient( "ithemes-sync-force-display-$user_id" ) ) {
67
  $show_sync = true;
68
 
69
- add_action( 'all_admin_notices', array( $this, 'show_force_display_notice' ), 0 );
 
 
70
  }
71
  }
72
 
73
 
74
- if ( $show_sync ) {
75
  if ( ! is_multisite() || is_super_admin() ) {
76
  add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
77
  }
@@ -87,7 +93,9 @@ class Ithemes_Sync_Admin {
87
  wp_enqueue_style( 'ithemes-updater-admin-notice-style', "$path_url/css/admin-notice.css" );
88
  wp_enqueue_script( 'ithemes-updater-admin-notice-script', "$path_url/js/admin-notice.js", array( 'jquery' ) );
89
 
90
- add_action( 'all_admin_notices', array( $this, 'show_authenticate_notice' ), 0 );
 
 
91
 
92
  delete_site_transient( 'ithemes-sync-activated' );
93
  }
@@ -98,7 +106,9 @@ class Ithemes_Sync_Admin {
98
  wp_enqueue_style( 'ithemes-updater-admin-notice-style', "$path_url/css/admin-notice.css" );
99
  wp_enqueue_script( 'ithemes-updater-admin-notice-script', "$path_url/js/admin-notice.js", array( 'jquery' ) );
100
 
101
- add_action( 'all_admin_notices', array( $this, 'show_activate_notice' ), 0 );
 
 
102
 
103
  delete_site_transient( 'ithemes-sync-activated' );
104
  }
@@ -246,6 +256,18 @@ class Ithemes_Sync_Admin {
246
 
247
  wp_add_privacy_policy_content( 'iThemes Sync', wp_kses_post( wpautop( $content, false ) ) );
248
  }
 
 
 
 
 
 
 
 
 
 
 
 
249
  }
250
 
251
  new Ithemes_Sync_Admin();
57
  $show_sync = true;
58
  set_site_transient( "ithemes-sync-force-display-$user_id", true, 600 );
59
 
60
+ if ( false === $this->silent_mode_enabled() ) {
61
+ add_action( 'all_admin_notices', array( $this, 'show_force_display_notice' ), 0 );
62
+ }
63
  } else {
64
  delete_site_transient( "ithemes-sync-force-display-$user_id" );
65
 
66
+ if ( false === $this->silent_mode_enabled() ) {
67
+ add_action( 'all_admin_notices', array( $this, 'show_force_display_disable_notice' ), 0 );
68
+ }
69
  }
70
  } else if ( false !== get_site_transient( "ithemes-sync-force-display-$user_id" ) ) {
71
  $show_sync = true;
72
 
73
+ if ( false === $this->silent_mode_enabled() ) {
74
+ add_action( 'all_admin_notices', array( $this, 'show_force_display_notice' ), 0 );
75
+ }
76
  }
77
  }
78
 
79
 
80
+ if ( $show_sync && ( false === $this->silent_mode_enabled() ) ) {
81
  if ( ! is_multisite() || is_super_admin() ) {
82
  add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
83
  }
93
  wp_enqueue_style( 'ithemes-updater-admin-notice-style', "$path_url/css/admin-notice.css" );
94
  wp_enqueue_script( 'ithemes-updater-admin-notice-script', "$path_url/js/admin-notice.js", array( 'jquery' ) );
95
 
96
+ if ( false === $this->silent_mode_enabled() ) {
97
+ add_action( 'all_admin_notices', array( $this, 'show_authenticate_notice' ), 0 );
98
+ }
99
 
100
  delete_site_transient( 'ithemes-sync-activated' );
101
  }
106
  wp_enqueue_style( 'ithemes-updater-admin-notice-style', "$path_url/css/admin-notice.css" );
107
  wp_enqueue_script( 'ithemes-updater-admin-notice-script', "$path_url/js/admin-notice.js", array( 'jquery' ) );
108
 
109
+ if ( false === $this->silent_mode_enabled() ) {
110
+ add_action( 'all_admin_notices', array( $this, 'show_activate_notice' ), 0 );
111
+ }
112
 
113
  delete_site_transient( 'ithemes-sync-activated' );
114
  }
256
 
257
  wp_add_privacy_policy_content( 'iThemes Sync', wp_kses_post( wpautop( $content, false ) ) );
258
  }
259
+
260
+ /**
261
+ * Returns boolean depending on whether silent mode is enabled or not.
262
+ *
263
+ * Silent mode kills all sync admin notices as well as the menu item and admin page.
264
+ *
265
+ * @since 2.0.14
266
+ * @return boolean
267
+ */
268
+ function silent_mode_enabled() {
269
+ return apply_filters( 'ithemes-sync-silent-mode-enabled', false );
270
+ }
271
  }
272
 
273
  new Ithemes_Sync_Admin();
history.txt CHANGED
@@ -200,5 +200,14 @@
200
  Enhancement: Adding GDPR Policy Content Suggestions
201
  2.0.10 - 2018-08-13 - Lew Ayotte
202
  Enhancement: Updating ITSEC Notifications updates
203
- 2.0.11 - 2019-10-04 - Lew Ayotte
204
  Enhancement: Updating sync's whitelist IP
 
 
 
 
 
 
 
 
 
200
  Enhancement: Adding GDPR Policy Content Suggestions
201
  2.0.10 - 2018-08-13 - Lew Ayotte
202
  Enhancement: Updating ITSEC Notifications updates
203
+ 2.0.11 - 2018-10-04 - Lew Ayotte
204
  Enhancement: Updating sync's whitelist IP
205
+ 2.0.12
206
+ 2.0.13 - 2019-01-03 - Glenn Ansley
207
+ Enhancement - Updater improvements
208
+ 2.0.14 - 2019-02-12 - Glenn Ansley
209
+ Enhancement - Added Silent Mode hooks
210
+ 2.0.15 - 2019-02-25 - Lew Ayotte
211
+ Bug Fix: PHP7.1/7.2's implemention of serialize precision causes
212
+ json_encode to float version numbers like 5.1 as 5.0999999999996, which
213
+ disrupts our hashing algorithm.
init.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: iThemes Sync
4
  Plugin URI: http://ithemes.com/sync
5
  Description: Manage updates to your WordPress sites easily in one place.
6
  Author: iThemes
7
- Version: 2.0.12
8
  Author URI: http://ithemes.com/
9
  Domain Path: /lang/
10
  iThemes Package: ithemes-sync
4
  Plugin URI: http://ithemes.com/sync
5
  Description: Manage updates to your WordPress sites easily in one place.
6
  Author: iThemes
7
+ Version: 2.0.15
8
  Author URI: http://ithemes.com/
9
  Domain Path: /lang/
10
  iThemes Package: ithemes-sync
lang/ithemes-sync.pot CHANGED
@@ -1,11 +1,11 @@
1
- # Copyright (C) 2018 iThemes Sync
2
  # This file is distributed under the same license as the iThemes Sync package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: iThemes Sync 2.0.12\n"
6
  "Report-Msgid-Bugs-To: http://ithemes.com/support/\n"
7
- "POT-Creation-Date: 2018-10-24 19:39:21+00:00\n"
8
- "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
@@ -13,47 +13,47 @@ msgstr ""
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
 
16
- #: admin.php:119
17
  msgid ""
18
  "iThemes Sync is active. <a class=\"ithemes-sync-notice-button\" href=\"%s"
19
  "\">Manage Sync</a> <a class=\"ithemes-sync-notice-dismiss\" href=\"#\">×</a>"
20
  msgstr ""
21
 
22
- #: admin.php:133
23
  msgid ""
24
  "iThemes Sync is almost ready. <a class=\"ithemes-sync-notice-button\" href="
25
  "\"%s\">Set Up Sync</a> <a class=\"ithemes-sync-notice-hide\" href=\"#\">×</a>"
26
  msgstr ""
27
 
28
- #: admin.php:148
29
  msgid ""
30
  "iThemes Sync will show for your user for the next %1$s. Click <a href=\"%2$s"
31
  "\">here</a> to hide iThemes Sync again."
32
  msgstr ""
33
 
34
- #: admin.php:158
35
  msgid "iThemes Sync is now hidden from your user again."
36
  msgstr ""
37
 
38
- #. #-#-#-#-# ithemes-sync.pot (iThemes Sync 2.0.12) #-#-#-#-#
39
  #. Plugin Name of the plugin/theme
40
- #: admin.php:169 admin.php:175 settings-page.php:268
41
  msgid "iThemes Sync"
42
  msgstr ""
43
 
44
- #: admin.php:203 lib/updater/admin.php:181
45
  msgid "Manage iThemes product licenses to receive automatic upgrade support"
46
  msgstr ""
47
 
48
- #: admin.php:203 lib/updater/admin.php:181
49
  msgid "License"
50
  msgstr ""
51
 
52
- #: admin.php:244
53
  msgid "Where we send your data"
54
  msgstr ""
55
 
56
- #: admin.php:245
57
  msgid ""
58
  "%s%sSuggested text:%s This web site uses a third party service to manage "
59
  "administrative tasks. If you leave a comment, submit personal information "
@@ -84,79 +84,44 @@ msgid ""
84
  "to use."
85
  msgstr ""
86
 
87
- #: lib/updater/admin.php:140
88
  msgid ""
89
  "To receive automatic updates for %l, use the <a href=\"%s\">iThemes "
90
  "Licensing</a> page found in the Settings menu."
91
  msgstr ""
92
 
93
- #: lib/updater/admin.php:147 lib/updater/admin.php:153
94
- #: lib/updater/settings-page.php:302
95
  msgid "iThemes Licensing"
96
  msgstr ""
97
 
98
- #: lib/updater/api.php:41 lib/updater/api.php:59
99
- msgid ""
100
- "<p>Unable to get changelog data at this time.</p><p>Error <code>%1$s</code>: "
101
- "%2$s</p>"
102
- msgstr ""
103
-
104
  #: lib/updater/api.php:45
105
- msgid ""
106
- "<p>Unable to get changelog data at this time.</p><p>Error: Unrecognized "
107
- "response from <code>wp_remote_get</code>.</p>"
108
- msgstr ""
109
-
110
- #: lib/updater/api.php:49
111
- msgid ""
112
- "<p>Unable to get changelog data at this time.</p><p>Error code <code>%1$s</"
113
- "code>: %2$s</p>"
114
  msgstr ""
115
 
116
  #: lib/updater/api.php:61
117
- msgid ""
118
- "<p>Unable to get changelog data at this time.</p><p>Error: Unrecognized "
119
- "response from iThemes API server.</p>"
120
- msgstr ""
121
-
122
- #: lib/updater/server.php:78
123
- msgid ""
124
- "The server could not be contacted. Requests are delayed for %d minute to "
125
- "allow the server to recover."
126
- msgid_plural ""
127
- "The server could not be contacted. Requests are delayed for %d minutes to "
128
- "allow the server to recover."
129
- msgstr[0] ""
130
- msgstr[1] ""
131
-
132
- #: lib/updater/server.php:155
133
- msgid "The server was unable to be contacted."
134
- msgstr ""
135
-
136
- #: lib/updater/server.php:165
137
- msgid ""
138
- "An error occurred when communicating with the iThemes update server: %s (%s)"
139
  msgstr ""
140
 
141
- #: lib/updater/settings-page.php:77
142
  msgid ""
143
  "Incorrect password. Please make sure that you are supplying your iThemes "
144
  "membership username and password details."
145
  msgstr ""
146
 
147
- #: lib/updater/settings-page.php:81
148
  msgid ""
149
  "Invalid username. Please make sure that you are supplying your iThemes "
150
  "membership username and password details."
151
  msgstr ""
152
 
153
- #: lib/updater/settings-page.php:84
154
  msgid ""
155
  "The licensing server reports that the %1$s (%2$s) product is unknown. Please "
156
  "contact support for assistance."
157
  msgstr ""
158
 
159
- #: lib/updater/settings-page.php:87
160
  msgid ""
161
  "%1$s could not be licensed since the membership account is out of available "
162
  "licenses for this product. You can unlicense the product on other sites or "
@@ -164,123 +129,147 @@ msgid ""
164
  "increase the amount of available licenses."
165
  msgstr ""
166
 
167
- #: lib/updater/settings-page.php:90
168
  msgid ""
169
  "%s could not be licensed due to an internal error. Please try to license %s "
170
  "again at a later time. If this problem continues, please contact iThemes "
171
  "support."
172
  msgstr ""
173
 
174
- #: lib/updater/settings-page.php:96
175
  msgid ""
176
  "An unknown error relating to the %1$s product occurred. Please contact "
177
  "iThemes support. Error details: %2$s"
178
  msgstr ""
179
 
180
- #: lib/updater/settings-page.php:98
181
  msgid ""
182
  "An unknown error occurred. Please contact iThemes support. Error details: %s"
183
  msgstr ""
184
 
185
- #: lib/updater/settings-page.php:129 settings-page.php:239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  msgid "Settings saved"
187
  msgstr ""
188
 
189
- #: lib/updater/settings-page.php:136
190
  msgid ""
191
  "You must supply an iThemes membership username and password in order to "
192
  "license products."
193
  msgstr ""
194
 
195
- #: lib/updater/settings-page.php:138
196
  msgid ""
197
  "You must supply an iThemes membership username in order to license products."
198
  msgstr ""
199
 
200
- #: lib/updater/settings-page.php:140
201
  msgid ""
202
  "You must supply an iThemes membership password in order to license products."
203
  msgstr ""
204
 
205
- #: lib/updater/settings-page.php:142
206
  msgid ""
207
  "You must select at least one product to license. Ensure that you select the "
208
  "products that you wish to license in the listing below."
209
  msgstr ""
210
 
211
- #: lib/updater/settings-page.php:157
212
  msgid ""
213
  "An unknown server error occurred. Please try to license your products again "
214
  "at another time."
215
  msgstr ""
216
 
217
- #: lib/updater/settings-page.php:177
218
  msgid "Your product subscription has expired"
219
  msgstr ""
220
 
221
- #: lib/updater/settings-page.php:184
222
  msgid "Successfully licensed %l."
223
  msgstr ""
224
 
225
- #: lib/updater/settings-page.php:188 lib/updater/settings-page.php:193
226
  msgid "Unable to license %1$s. Reason: %2$s"
227
  msgstr ""
228
 
229
- #: lib/updater/settings-page.php:201
230
  msgid ""
231
  "You must supply an iThemes membership username and password in order to "
232
  "remove licenses."
233
  msgstr ""
234
 
235
- #: lib/updater/settings-page.php:203
236
  msgid ""
237
  "You must supply an iThemes membership username in order to remove licenses."
238
  msgstr ""
239
 
240
- #: lib/updater/settings-page.php:205
241
  msgid ""
242
  "You must supply an iThemes membership password in order to remove licenses."
243
  msgstr ""
244
 
245
- #: lib/updater/settings-page.php:207
246
  msgid ""
247
  "You must select at least one license to remove. Ensure that you select the "
248
  "licenses that you wish to remove in the listing below."
249
  msgstr ""
250
 
251
- #: lib/updater/settings-page.php:222
252
  msgid ""
253
  "An unknown server error occurred. Please try to remove licenses from your "
254
  "products again at another time."
255
  msgstr ""
256
 
257
- #: lib/updater/settings-page.php:243
258
  msgid "Unknown server error."
259
  msgstr ""
260
 
261
- #: lib/updater/settings-page.php:248
262
  msgid "Successfully removed license from %l."
263
  msgid_plural "Successfully removed licenses from %l."
264
  msgstr[0] ""
265
  msgstr[1] ""
266
 
267
- #: lib/updater/settings-page.php:252
268
  msgid "Unable to remove license from %1$s. Reason: %2$s"
269
  msgstr ""
270
 
271
- #: lib/updater/settings-page.php:324
272
  msgid "Settings"
273
  msgstr ""
274
 
275
- #: lib/updater/settings-page.php:330
276
  msgid "Quick Release Updates"
277
  msgstr ""
278
 
279
- #: lib/updater/settings-page.php:337
280
  msgid "Enable quick release updates"
281
  msgstr ""
282
 
283
- #: lib/updater/settings-page.php:340
284
  msgid ""
285
  "Some products have quick releases that are created to solve specific issues "
286
  "that some users experience. In order to avoid causing users to have updates "
@@ -292,139 +281,139 @@ msgid ""
292
  "confirming that the quick release solves the issue for you."
293
  msgstr ""
294
 
295
- #: lib/updater/settings-page.php:347
296
  msgid "Save Settings"
297
  msgstr ""
298
 
299
- #: lib/updater/settings-page.php:366 lib/updater/settings-page.php:397
300
- #: lib/updater/settings-page.php:521 lib/updater/settings-page.php:589
301
  msgid "Product"
302
  msgstr ""
303
 
304
- #: lib/updater/settings-page.php:367 lib/updater/settings-page.php:399
305
  msgid "Member"
306
  msgstr ""
307
 
308
- #: lib/updater/settings-page.php:368 lib/updater/settings-page.php:401
309
  msgid "Expiration"
310
  msgstr ""
311
 
312
- #: lib/updater/settings-page.php:369 lib/updater/settings-page.php:402
313
  msgid "Remaining Licenses"
314
  msgstr ""
315
 
316
- #: lib/updater/settings-page.php:385
317
  msgid "Licensed Products"
318
  msgstr ""
319
 
320
- #: lib/updater/settings-page.php:391 lib/updater/settings-page.php:515
321
  msgid "Select All"
322
  msgstr ""
323
 
324
- #: lib/updater/settings-page.php:400
325
  msgid "Product Status"
326
  msgstr ""
327
 
328
- #: lib/updater/settings-page.php:410
329
  msgid "unlimited"
330
  msgstr ""
331
 
332
- #: lib/updater/settings-page.php:451 lib/updater/settings-page.php:545
333
  msgid "Select %s"
334
  msgstr ""
335
 
336
- #: lib/updater/settings-page.php:471
337
  msgid "Remove Licenses"
338
  msgstr ""
339
 
340
- #: lib/updater/settings-page.php:505
341
  msgid "Unlicensed Products"
342
  msgstr ""
343
 
344
- #: lib/updater/settings-page.php:507
345
  msgid ""
346
  "The following products have not been licensed. Licensing a product gives you "
347
  "access to automatic updates from within WordPress."
348
  msgstr ""
349
 
350
- #: lib/updater/settings-page.php:508
351
  msgid ""
352
  "To license products, select the products you wish to license, enter your "
353
  "iThemes membership username and password, and press the License Products "
354
  "button."
355
  msgstr ""
356
 
357
- #: lib/updater/settings-page.php:509
358
  msgid "Need help? <a href=\"%s\">Click here for a quick video tutorial</a>."
359
  msgstr ""
360
 
361
- #: lib/updater/settings-page.php:561
362
  msgid "License Products"
363
  msgstr ""
364
 
365
- #: lib/updater/settings-page.php:581
366
  msgid "Unrecognized Products"
367
  msgstr ""
368
 
369
- #: lib/updater/settings-page.php:583
370
  msgid ""
371
  "The following products were not recognized by the licensing system. This can "
372
  "be due to a bug in the product code, a temporary server issue, or because "
373
  "the product is no longer supported."
374
  msgstr ""
375
 
376
- #: lib/updater/settings-page.php:584
377
  msgid ""
378
  "Please check this page again at a later time to see if the problem resolves "
379
  "itself. If the product remains, please contact <a href=\"%s\">iThemes "
380
  "support</a> and provide them with the details given below."
381
  msgstr ""
382
 
383
- #: lib/updater/settings-page.php:590
384
  msgid "Type"
385
  msgstr ""
386
 
387
- #: lib/updater/settings-page.php:591
388
  msgid "Package"
389
  msgstr ""
390
 
391
- #: lib/updater/settings-page.php:592
392
  msgid "Version"
393
  msgstr ""
394
 
395
- #: lib/updater/settings-page.php:593
396
  msgid "Server Response"
397
  msgstr ""
398
 
399
- #: lib/updater/settings-page.php:603
400
  msgid "Unknown Error"
401
  msgstr ""
402
 
403
- #: lib/updater/settings-page.php:642
404
  msgid "%d day"
405
  msgid_plural "%d days"
406
  msgstr[0] ""
407
  msgstr[1] ""
408
 
409
- #: lib/updater/settings-page.php:644
410
  msgid "%d hour"
411
  msgid_plural "%d hours"
412
  msgstr[0] ""
413
  msgstr[1] ""
414
 
415
- #: lib/updater/settings-page.php:646
416
  msgid "%d minute"
417
  msgid_plural "%d minutes"
418
  msgstr[0] ""
419
  msgstr[1] ""
420
 
421
- #: lib/updater/settings-page.php:648
422
  msgid "%d second"
423
  msgid_plural "%d seconds"
424
  msgstr[0] ""
425
  msgstr[1] ""
426
 
427
- #: lib/updater/settings-page.php:651
428
  msgid "%s ago"
429
  msgstr ""
430
 
1
+ # Copyright (C) 2019 iThemes Sync
2
  # This file is distributed under the same license as the iThemes Sync package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: iThemes Sync 2.0.15\n"
6
  "Report-Msgid-Bugs-To: http://ithemes.com/support/\n"
7
+ "POT-Creation-Date: 2019-02-25 15:38:37+00:00\n"
8
+ "PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
 
16
+ #: admin.php:129
17
  msgid ""
18
  "iThemes Sync is active. <a class=\"ithemes-sync-notice-button\" href=\"%s"
19
  "\">Manage Sync</a> <a class=\"ithemes-sync-notice-dismiss\" href=\"#\">×</a>"
20
  msgstr ""
21
 
22
+ #: admin.php:143
23
  msgid ""
24
  "iThemes Sync is almost ready. <a class=\"ithemes-sync-notice-button\" href="
25
  "\"%s\">Set Up Sync</a> <a class=\"ithemes-sync-notice-hide\" href=\"#\">×</a>"
26
  msgstr ""
27
 
28
+ #: admin.php:158
29
  msgid ""
30
  "iThemes Sync will show for your user for the next %1$s. Click <a href=\"%2$s"
31
  "\">here</a> to hide iThemes Sync again."
32
  msgstr ""
33
 
34
+ #: admin.php:168
35
  msgid "iThemes Sync is now hidden from your user again."
36
  msgstr ""
37
 
38
+ #. #-#-#-#-# ithemes-sync.pot (iThemes Sync 2.0.15) #-#-#-#-#
39
  #. Plugin Name of the plugin/theme
40
+ #: admin.php:179 admin.php:185 settings-page.php:268
41
  msgid "iThemes Sync"
42
  msgstr ""
43
 
44
+ #: admin.php:213 lib/updater/admin.php:218
45
  msgid "Manage iThemes product licenses to receive automatic upgrade support"
46
  msgstr ""
47
 
48
+ #: admin.php:213 lib/updater/admin.php:218
49
  msgid "License"
50
  msgstr ""
51
 
52
+ #: admin.php:254
53
  msgid "Where we send your data"
54
  msgstr ""
55
 
56
+ #: admin.php:255
57
  msgid ""
58
  "%s%sSuggested text:%s This web site uses a third party service to manage "
59
  "administrative tasks. If you leave a comment, submit personal information "
84
  "to use."
85
  msgstr ""
86
 
87
+ #: lib/updater/admin.php:177
88
  msgid ""
89
  "To receive automatic updates for %l, use the <a href=\"%s\">iThemes "
90
  "Licensing</a> page found in the Settings menu."
91
  msgstr ""
92
 
93
+ #: lib/updater/admin.php:184 lib/updater/admin.php:190
94
+ #: lib/updater/settings-page.php:268
95
  msgid "iThemes Licensing"
96
  msgstr ""
97
 
 
 
 
 
 
 
98
  #: lib/updater/api.php:45
99
+ msgid "Unrecognized response from <code>wp_remote_get</code>."
 
 
 
 
 
 
 
 
100
  msgstr ""
101
 
102
  #: lib/updater/api.php:61
103
+ msgid "Unrecognized response from iThemes API server."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  msgstr ""
105
 
106
+ #: lib/updater/api.php:309
107
  msgid ""
108
  "Incorrect password. Please make sure that you are supplying your iThemes "
109
  "membership username and password details."
110
  msgstr ""
111
 
112
+ #: lib/updater/api.php:313
113
  msgid ""
114
  "Invalid username. Please make sure that you are supplying your iThemes "
115
  "membership username and password details."
116
  msgstr ""
117
 
118
+ #: lib/updater/api.php:316
119
  msgid ""
120
  "The licensing server reports that the %1$s (%2$s) product is unknown. Please "
121
  "contact support for assistance."
122
  msgstr ""
123
 
124
+ #: lib/updater/api.php:319
125
  msgid ""
126
  "%1$s could not be licensed since the membership account is out of available "
127
  "licenses for this product. You can unlicense the product on other sites or "
129
  "increase the amount of available licenses."
130
  msgstr ""
131
 
132
+ #: lib/updater/api.php:322
133
  msgid ""
134
  "%s could not be licensed due to an internal error. Please try to license %s "
135
  "again at a later time. If this problem continues, please contact iThemes "
136
  "support."
137
  msgstr ""
138
 
139
+ #: lib/updater/api.php:328
140
  msgid ""
141
  "An unknown error relating to the %1$s product occurred. Please contact "
142
  "iThemes support. Error details: %2$s"
143
  msgstr ""
144
 
145
+ #: lib/updater/api.php:330
146
  msgid ""
147
  "An unknown error occurred. Please contact iThemes support. Error details: %s"
148
  msgstr ""
149
 
150
+ #. translators: 1. Error message, 2. Error code
151
+ #: lib/updater/information.php:42
152
+ msgid "<p>Unable to get changelog data at this time.</p><p>%1$s (%2$s)</p>"
153
+ msgstr ""
154
+
155
+ #: lib/updater/server.php:80
156
+ msgid ""
157
+ "The server could not be contacted. Requests are delayed for %d minute to "
158
+ "allow the server to recover."
159
+ msgid_plural ""
160
+ "The server could not be contacted. Requests are delayed for %d minutes to "
161
+ "allow the server to recover."
162
+ msgstr[0] ""
163
+ msgstr[1] ""
164
+
165
+ #: lib/updater/server.php:157
166
+ msgid "The server was unable to be contacted."
167
+ msgstr ""
168
+
169
+ #: lib/updater/server.php:167
170
+ msgid ""
171
+ "An error occurred when communicating with the iThemes update server: %s (%s)"
172
+ msgstr ""
173
+
174
+ #: lib/updater/settings-page.php:95 settings-page.php:239
175
  msgid "Settings saved"
176
  msgstr ""
177
 
178
+ #: lib/updater/settings-page.php:102
179
  msgid ""
180
  "You must supply an iThemes membership username and password in order to "
181
  "license products."
182
  msgstr ""
183
 
184
+ #: lib/updater/settings-page.php:104
185
  msgid ""
186
  "You must supply an iThemes membership username in order to license products."
187
  msgstr ""
188
 
189
+ #: lib/updater/settings-page.php:106
190
  msgid ""
191
  "You must supply an iThemes membership password in order to license products."
192
  msgstr ""
193
 
194
+ #: lib/updater/settings-page.php:108
195
  msgid ""
196
  "You must select at least one product to license. Ensure that you select the "
197
  "products that you wish to license in the listing below."
198
  msgstr ""
199
 
200
+ #: lib/updater/settings-page.php:123
201
  msgid ""
202
  "An unknown server error occurred. Please try to license your products again "
203
  "at another time."
204
  msgstr ""
205
 
206
+ #: lib/updater/settings-page.php:143
207
  msgid "Your product subscription has expired"
208
  msgstr ""
209
 
210
+ #: lib/updater/settings-page.php:150
211
  msgid "Successfully licensed %l."
212
  msgstr ""
213
 
214
+ #: lib/updater/settings-page.php:154 lib/updater/settings-page.php:159
215
  msgid "Unable to license %1$s. Reason: %2$s"
216
  msgstr ""
217
 
218
+ #: lib/updater/settings-page.php:167
219
  msgid ""
220
  "You must supply an iThemes membership username and password in order to "
221
  "remove licenses."
222
  msgstr ""
223
 
224
+ #: lib/updater/settings-page.php:169
225
  msgid ""
226
  "You must supply an iThemes membership username in order to remove licenses."
227
  msgstr ""
228
 
229
+ #: lib/updater/settings-page.php:171
230
  msgid ""
231
  "You must supply an iThemes membership password in order to remove licenses."
232
  msgstr ""
233
 
234
+ #: lib/updater/settings-page.php:173
235
  msgid ""
236
  "You must select at least one license to remove. Ensure that you select the "
237
  "licenses that you wish to remove in the listing below."
238
  msgstr ""
239
 
240
+ #: lib/updater/settings-page.php:188
241
  msgid ""
242
  "An unknown server error occurred. Please try to remove licenses from your "
243
  "products again at another time."
244
  msgstr ""
245
 
246
+ #: lib/updater/settings-page.php:209
247
  msgid "Unknown server error."
248
  msgstr ""
249
 
250
+ #: lib/updater/settings-page.php:214
251
  msgid "Successfully removed license from %l."
252
  msgid_plural "Successfully removed licenses from %l."
253
  msgstr[0] ""
254
  msgstr[1] ""
255
 
256
+ #: lib/updater/settings-page.php:218
257
  msgid "Unable to remove license from %1$s. Reason: %2$s"
258
  msgstr ""
259
 
260
+ #: lib/updater/settings-page.php:290
261
  msgid "Settings"
262
  msgstr ""
263
 
264
+ #: lib/updater/settings-page.php:296
265
  msgid "Quick Release Updates"
266
  msgstr ""
267
 
268
+ #: lib/updater/settings-page.php:303
269
  msgid "Enable quick release updates"
270
  msgstr ""
271
 
272
+ #: lib/updater/settings-page.php:306
273
  msgid ""
274
  "Some products have quick releases that are created to solve specific issues "
275
  "that some users experience. In order to avoid causing users to have updates "
281
  "confirming that the quick release solves the issue for you."
282
  msgstr ""
283
 
284
+ #: lib/updater/settings-page.php:313
285
  msgid "Save Settings"
286
  msgstr ""
287
 
288
+ #: lib/updater/settings-page.php:332 lib/updater/settings-page.php:363
289
+ #: lib/updater/settings-page.php:487 lib/updater/settings-page.php:555
290
  msgid "Product"
291
  msgstr ""
292
 
293
+ #: lib/updater/settings-page.php:333 lib/updater/settings-page.php:365
294
  msgid "Member"
295
  msgstr ""
296
 
297
+ #: lib/updater/settings-page.php:334 lib/updater/settings-page.php:367
298
  msgid "Expiration"
299
  msgstr ""
300
 
301
+ #: lib/updater/settings-page.php:335 lib/updater/settings-page.php:368
302
  msgid "Remaining Licenses"
303
  msgstr ""
304
 
305
+ #: lib/updater/settings-page.php:351
306
  msgid "Licensed Products"
307
  msgstr ""
308
 
309
+ #: lib/updater/settings-page.php:357 lib/updater/settings-page.php:481
310
  msgid "Select All"
311
  msgstr ""
312
 
313
+ #: lib/updater/settings-page.php:366
314
  msgid "Product Status"
315
  msgstr ""
316
 
317
+ #: lib/updater/settings-page.php:376
318
  msgid "unlimited"
319
  msgstr ""
320
 
321
+ #: lib/updater/settings-page.php:417 lib/updater/settings-page.php:511
322
  msgid "Select %s"
323
  msgstr ""
324
 
325
+ #: lib/updater/settings-page.php:437
326
  msgid "Remove Licenses"
327
  msgstr ""
328
 
329
+ #: lib/updater/settings-page.php:471
330
  msgid "Unlicensed Products"
331
  msgstr ""
332
 
333
+ #: lib/updater/settings-page.php:473
334
  msgid ""
335
  "The following products have not been licensed. Licensing a product gives you "
336
  "access to automatic updates from within WordPress."
337
  msgstr ""
338
 
339
+ #: lib/updater/settings-page.php:474
340
  msgid ""
341
  "To license products, select the products you wish to license, enter your "
342
  "iThemes membership username and password, and press the License Products "
343
  "button."
344
  msgstr ""
345
 
346
+ #: lib/updater/settings-page.php:475
347
  msgid "Need help? <a href=\"%s\">Click here for a quick video tutorial</a>."
348
  msgstr ""
349
 
350
+ #: lib/updater/settings-page.php:527
351
  msgid "License Products"
352
  msgstr ""
353
 
354
+ #: lib/updater/settings-page.php:547
355
  msgid "Unrecognized Products"
356
  msgstr ""
357
 
358
+ #: lib/updater/settings-page.php:549
359
  msgid ""
360
  "The following products were not recognized by the licensing system. This can "
361
  "be due to a bug in the product code, a temporary server issue, or because "
362
  "the product is no longer supported."
363
  msgstr ""
364
 
365
+ #: lib/updater/settings-page.php:550
366
  msgid ""
367
  "Please check this page again at a later time to see if the problem resolves "
368
  "itself. If the product remains, please contact <a href=\"%s\">iThemes "
369
  "support</a> and provide them with the details given below."
370
  msgstr ""
371
 
372
+ #: lib/updater/settings-page.php:556
373
  msgid "Type"
374
  msgstr ""
375
 
376
+ #: lib/updater/settings-page.php:557
377
  msgid "Package"
378
  msgstr ""
379
 
380
+ #: lib/updater/settings-page.php:558
381
  msgid "Version"
382
  msgstr ""
383
 
384
+ #: lib/updater/settings-page.php:559
385
  msgid "Server Response"
386
  msgstr ""
387
 
388
+ #: lib/updater/settings-page.php:569
389
  msgid "Unknown Error"
390
  msgstr ""
391
 
392
+ #: lib/updater/settings-page.php:608
393
  msgid "%d day"
394
  msgid_plural "%d days"
395
  msgstr[0] ""
396
  msgstr[1] ""
397
 
398
+ #: lib/updater/settings-page.php:610
399
  msgid "%d hour"
400
  msgid_plural "%d hours"
401
  msgstr[0] ""
402
  msgstr[1] ""
403
 
404
+ #: lib/updater/settings-page.php:612
405
  msgid "%d minute"
406
  msgid_plural "%d minutes"
407
  msgstr[0] ""
408
  msgstr[1] ""
409
 
410
+ #: lib/updater/settings-page.php:614
411
  msgid "%d second"
412
  msgid_plural "%d seconds"
413
  msgstr[0] ""
414
  msgstr[1] ""
415
 
416
+ #: lib/updater/settings-page.php:617
417
  msgid "%s ago"
418
  msgstr ""
419
 
lib/updater/admin.php CHANGED
@@ -22,180 +22,217 @@ Version History
22
 
23
  class Ithemes_Updater_Admin {
24
  private $page_name = 'ithemes-licensing';
25
-
26
  private $package_details = false;
27
  private $registration_link = false;
28
-
29
  private $page_ref;
30
-
31
-
32
  public function __construct() {
33
  require_once( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
34
-
35
  if ( ! is_multisite() || is_super_admin() ) {
36
  add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
37
  }
38
-
39
  add_action( 'network_admin_menu', array( $this, 'add_network_admin_pages' ) );
40
-
41
  add_action( 'admin_head-plugins.php', array( $this, 'show_activation_message' ) );
42
  add_action( 'admin_head-themes.php', array( $this, 'show_activation_message' ) );
43
  add_action( 'deactivated_plugin', array( $this, 'clear_activation_package' ) );
44
-
45
  add_filter( 'upgrader_pre_install', array( $this, 'filter_upgrader_pre_install' ) );
46
  add_filter( 'upgrader_post_install', array( $this, 'filter_upgrader_post_install' ), 10, 3 );
47
  add_filter( 'plugins_api', array( $this, 'filter_plugins_api' ), 10, 3 );
48
-
49
  if ( ! is_multisite() || is_super_admin() ) {
50
  add_filter( 'plugin_action_links', array( $this, 'filter_plugin_action_links' ), 10, 4 );
51
  add_filter( 'theme_action_links', array( $this, 'filter_theme_action_links' ), 10, 2 );
52
  }
53
-
54
  add_filter( 'network_admin_plugin_action_links', array( $this, 'filter_plugin_action_links' ), 10, 4 );
55
  add_filter( 'network_admin_theme_action_links', array( $this, 'filter_theme_action_links' ), 10, 2 );
56
  }
57
-
58
  public function filter_plugins_api( $value, $action, $args ) {
59
  $options = $GLOBALS['ithemes-updater-settings']->get_options();
60
-
61
  if ( ! isset( $args->slug ) ) {
62
  return $value;
63
  }
64
-
65
  foreach ( (array) $options['update_plugins'] as $path => $data ) {
66
  if ( $data->slug == $args->slug ) {
67
  require_once( $GLOBALS['ithemes_updater_path'] . '/information.php' );
68
  return Ithemes_Updater_Information::get_plugin_information( $path );
69
  }
70
  }
71
-
72
  foreach ( (array) $options['update_themes'] as $path => $data ) {
73
  if ( $path == $args->slug ) {
74
  require_once( $GLOBALS['ithemes_updater_path'] . '/information.php' );
75
  return Ithemes_Updater_Information::get_theme_information( $path );
76
  }
77
  }
78
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  return $value;
80
  }
81
-
82
  public function filter_upgrader_pre_install( $value ) {
83
  $this->set_package_details();
84
-
85
  return $value;
86
  }
87
-
88
  public function filter_upgrader_post_install( $value, $hook_extra, $result ) {
89
  $options = $GLOBALS['ithemes-updater-settings']->queue_flush();
90
-
91
  return $value;
92
  }
93
-
94
  public function clear_activation_package( $deactivated_path ) {
95
  $packages = $GLOBALS['ithemes-updater-settings']->get_packages();
96
  $options = $GLOBALS['ithemes-updater-settings']->get_options();
97
-
98
  $deactivated_path = WP_PLUGIN_DIR . "/$deactivated_path";
99
-
100
  foreach ( $packages as $package => $paths ) {
101
  if ( ! in_array( $deactivated_path, $paths ) || ( count( $paths ) > 1 ) ) {
102
  continue;
103
  }
104
-
105
  $index = array_search( $package, $options['packages'] );
106
-
107
  if ( false === $index ) {
108
  return;
109
  }
110
-
111
  unset( $options['packages'][$index] );
112
  $GLOBALS['ithemes-updater-settings']->update_options( $options );
113
-
114
  return;
115
  }
116
  }
117
-
118
  public function show_activation_message() {
119
  $new_packages = $GLOBALS['ithemes-updater-settings']->get_new_packages();
120
-
121
  if ( empty( $new_packages ) ) {
122
  return;
123
  }
124
-
125
-
126
  natcasesort( $new_packages );
127
  require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
128
  $names = array();
129
-
130
  foreach ( $new_packages as $package ) {
131
  $names = Ithemes_Updater_Functions::get_package_name( $package );
132
  }
133
-
134
  if ( is_multisite() && is_network_admin() ) {
135
  $url = network_admin_url( 'settings.php' ) . "?page={$this->page_name}";
136
  } else {
137
  $url = admin_url( 'options-general.php' ) . "?page={$this->page_name}";
138
  }
139
-
140
  echo '<div class="updated fade"><p>' . wp_sprintf( __( 'To receive automatic updates for %l, use the <a href="%s">iThemes Licensing</a> page found in the Settings menu.', 'it-l10n-ithemes-sync' ), $names, $url ) . '</p></div>';
141
-
142
-
143
  $GLOBALS['ithemes-updater-settings']->update_packages();
144
  }
145
-
146
  public function add_admin_pages() {
147
  $this->page_ref = add_options_page( __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), 'manage_options', $this->page_name, array( $this, 'settings_index' ) );
148
-
149
  add_action( "load-{$this->page_ref}", array( $this, 'load_settings_page' ) );
150
  }
151
-
152
  public function add_network_admin_pages() {
153
  $this->page_ref = add_submenu_page( 'settings.php', __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), 'manage_options', $this->page_name, array( $this, 'settings_index' ) );
154
-
155
  add_action( "load-{$this->page_ref}", array( $this, 'load_settings_page' ) );
156
  }
157
-
158
  public function load_settings_page() {
159
  require( $GLOBALS['ithemes_updater_path'] . '/settings-page.php' );
160
  }
161
-
162
  public function settings_index() {
163
  do_action( 'ithemes_updater_settings_page_index' );
164
  }
165
-
166
  private function set_package_details() {
167
  if ( false !== $this->package_details ) {
168
  return;
169
  }
170
-
171
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
172
  $this->package_details = Ithemes_Updater_Packages::get_local_details();
173
  }
174
-
175
  private function set_registration_link() {
176
  if ( false !== $this->registration_link ) {
177
  return;
178
  }
179
-
180
  $url = admin_url( 'options-general.php' ) . "?page={$this->page_name}";
181
  $this->registration_link = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $url, __( 'Manage iThemes product licenses to receive automatic upgrade support', 'it-l10n-ithemes-sync' ), __( 'License', 'it-l10n-ithemes-sync' ) );
182
  }
183
-
184
  public function filter_plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
185
  $this->set_package_details();
186
  $this->set_registration_link();
187
-
188
- if ( isset( $this->package_details[$plugin_file] ) ) {
189
  $actions[] = $this->registration_link;
190
  }
191
-
192
  return $actions;
193
  }
194
-
195
  public function filter_theme_action_links( $actions, $theme ) {
196
  $this->set_package_details();
197
  $this->set_registration_link();
198
-
199
  if ( is_object( $theme ) ) {
200
  $path = basename( $theme->get_stylesheet_directory() ) . '/style.css';
201
  } else if ( is_array( $theme ) && isset( $theme['Stylesheet Dir'] ) ) {
@@ -203,11 +240,11 @@ class Ithemes_Updater_Admin {
203
  } else {
204
  $path = '';
205
  }
206
-
207
- if ( isset( $this->package_details[$path] ) ) {
208
  $actions[] = $this->registration_link;
209
  }
210
-
211
  return $actions;
212
  }
213
  }
22
 
23
  class Ithemes_Updater_Admin {
24
  private $page_name = 'ithemes-licensing';
25
+
26
  private $package_details = false;
27
  private $registration_link = false;
28
+
29
  private $page_ref;
30
+
31
+
32
  public function __construct() {
33
  require_once( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
34
+
35
  if ( ! is_multisite() || is_super_admin() ) {
36
  add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
37
  }
38
+
39
  add_action( 'network_admin_menu', array( $this, 'add_network_admin_pages' ) );
40
+
41
  add_action( 'admin_head-plugins.php', array( $this, 'show_activation_message' ) );
42
  add_action( 'admin_head-themes.php', array( $this, 'show_activation_message' ) );
43
  add_action( 'deactivated_plugin', array( $this, 'clear_activation_package' ) );
44
+
45
  add_filter( 'upgrader_pre_install', array( $this, 'filter_upgrader_pre_install' ) );
46
  add_filter( 'upgrader_post_install', array( $this, 'filter_upgrader_post_install' ), 10, 3 );
47
  add_filter( 'plugins_api', array( $this, 'filter_plugins_api' ), 10, 3 );
48
+
49
  if ( ! is_multisite() || is_super_admin() ) {
50
  add_filter( 'plugin_action_links', array( $this, 'filter_plugin_action_links' ), 10, 4 );
51
  add_filter( 'theme_action_links', array( $this, 'filter_theme_action_links' ), 10, 2 );
52
  }
53
+
54
  add_filter( 'network_admin_plugin_action_links', array( $this, 'filter_plugin_action_links' ), 10, 4 );
55
  add_filter( 'network_admin_theme_action_links', array( $this, 'filter_theme_action_links' ), 10, 2 );
56
  }
57
+
58
  public function filter_plugins_api( $value, $action, $args ) {
59
  $options = $GLOBALS['ithemes-updater-settings']->get_options();
60
+
61
  if ( ! isset( $args->slug ) ) {
62
  return $value;
63
  }
64
+
65
  foreach ( (array) $options['update_plugins'] as $path => $data ) {
66
  if ( $data->slug == $args->slug ) {
67
  require_once( $GLOBALS['ithemes_updater_path'] . '/information.php' );
68
  return Ithemes_Updater_Information::get_plugin_information( $path );
69
  }
70
  }
71
+
72
  foreach ( (array) $options['update_themes'] as $path => $data ) {
73
  if ( $path == $args->slug ) {
74
  require_once( $GLOBALS['ithemes_updater_path'] . '/information.php' );
75
  return Ithemes_Updater_Information::get_theme_information( $path );
76
  }
77
  }
78
+
79
+
80
+ $dir = WP_PLUGIN_DIR . '/' . $args->slug;
81
+ $dh = @opendir( $dir );
82
+
83
+ if ( ! $dh ) {
84
+ return $value;
85
+ }
86
+
87
+ while ( false !== ( $file = readdir( $dh ) ) ) {
88
+ if ( ! is_file( "$dir/$file" ) ) {
89
+ continue;
90
+ }
91
+
92
+ if ( '.php' !== substr( $file, -4 ) ) {
93
+ continue;
94
+ }
95
+
96
+ $plugin_data = get_plugin_data( "$dir/$file", false, false );
97
+
98
+ if ( ! empty ( $plugin_data['Name'] ) ) {
99
+ $plugin_file = basename( $file );
100
+ }
101
+ }
102
+
103
+ closedir( $dh );
104
+
105
+ if ( empty( $plugin_file ) ) {
106
+ return $value;
107
+ }
108
+
109
+ require_once( $GLOBALS['ithemes_updater_path'] . '/information.php' );
110
+ $information = Ithemes_Updater_Information::get_plugin_information( "{$args->slug}/$plugin_file" );
111
+
112
+ if ( false !== $information ) {
113
+ return $information;
114
+ }
115
+
116
  return $value;
117
  }
118
+
119
  public function filter_upgrader_pre_install( $value ) {
120
  $this->set_package_details();
121
+
122
  return $value;
123
  }
124
+
125
  public function filter_upgrader_post_install( $value, $hook_extra, $result ) {
126
  $options = $GLOBALS['ithemes-updater-settings']->queue_flush();
127
+
128
  return $value;
129
  }
130
+
131
  public function clear_activation_package( $deactivated_path ) {
132
  $packages = $GLOBALS['ithemes-updater-settings']->get_packages();
133
  $options = $GLOBALS['ithemes-updater-settings']->get_options();
134
+
135
  $deactivated_path = WP_PLUGIN_DIR . "/$deactivated_path";
136
+
137
  foreach ( $packages as $package => $paths ) {
138
  if ( ! in_array( $deactivated_path, $paths ) || ( count( $paths ) > 1 ) ) {
139
  continue;
140
  }
141
+
142
  $index = array_search( $package, $options['packages'] );
143
+
144
  if ( false === $index ) {
145
  return;
146
  }
147
+
148
  unset( $options['packages'][$index] );
149
  $GLOBALS['ithemes-updater-settings']->update_options( $options );
150
+
151
  return;
152
  }
153
  }
154
+
155
  public function show_activation_message() {
156
  $new_packages = $GLOBALS['ithemes-updater-settings']->get_new_packages();
157
+
158
  if ( empty( $new_packages ) ) {
159
  return;
160
  }
161
+
162
+
163
  natcasesort( $new_packages );
164
  require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
165
  $names = array();
166
+
167
  foreach ( $new_packages as $package ) {
168
  $names = Ithemes_Updater_Functions::get_package_name( $package );
169
  }
170
+
171
  if ( is_multisite() && is_network_admin() ) {
172
  $url = network_admin_url( 'settings.php' ) . "?page={$this->page_name}";
173
  } else {
174
  $url = admin_url( 'options-general.php' ) . "?page={$this->page_name}";
175
  }
176
+
177
  echo '<div class="updated fade"><p>' . wp_sprintf( __( 'To receive automatic updates for %l, use the <a href="%s">iThemes Licensing</a> page found in the Settings menu.', 'it-l10n-ithemes-sync' ), $names, $url ) . '</p></div>';
178
+
179
+
180
  $GLOBALS['ithemes-updater-settings']->update_packages();
181
  }
182
+
183
  public function add_admin_pages() {
184
  $this->page_ref = add_options_page( __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), 'manage_options', $this->page_name, array( $this, 'settings_index' ) );
185
+
186
  add_action( "load-{$this->page_ref}", array( $this, 'load_settings_page' ) );
187
  }
188
+
189
  public function add_network_admin_pages() {
190
  $this->page_ref = add_submenu_page( 'settings.php', __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), __( 'iThemes Licensing', 'it-l10n-ithemes-sync' ), 'manage_options', $this->page_name, array( $this, 'settings_index' ) );
191
+
192
  add_action( "load-{$this->page_ref}", array( $this, 'load_settings_page' ) );
193
  }
194
+
195
  public function load_settings_page() {
196
  require( $GLOBALS['ithemes_updater_path'] . '/settings-page.php' );
197
  }
198
+
199
  public function settings_index() {
200
  do_action( 'ithemes_updater_settings_page_index' );
201
  }
202
+
203
  private function set_package_details() {
204
  if ( false !== $this->package_details ) {
205
  return;
206
  }
207
+
208
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
209
  $this->package_details = Ithemes_Updater_Packages::get_local_details();
210
  }
211
+
212
  private function set_registration_link() {
213
  if ( false !== $this->registration_link ) {
214
  return;
215
  }
216
+
217
  $url = admin_url( 'options-general.php' ) . "?page={$this->page_name}";
218
  $this->registration_link = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $url, __( 'Manage iThemes product licenses to receive automatic upgrade support', 'it-l10n-ithemes-sync' ), __( 'License', 'it-l10n-ithemes-sync' ) );
219
  }
220
+
221
  public function filter_plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
222
  $this->set_package_details();
223
  $this->set_registration_link();
224
+
225
+ if ( isset( $this->package_details[$plugin_file] ) && is_array( $actions ) ) {
226
  $actions[] = $this->registration_link;
227
  }
228
+
229
  return $actions;
230
  }
231
+
232
  public function filter_theme_action_links( $actions, $theme ) {
233
  $this->set_package_details();
234
  $this->set_registration_link();
235
+
236
  if ( is_object( $theme ) ) {
237
  $path = basename( $theme->get_stylesheet_directory() ) . '/style.css';
238
  } else if ( is_array( $theme ) && isset( $theme['Stylesheet Dir'] ) ) {
240
  } else {
241
  $path = '';
242
  }
243
+
244
+ if ( isset( $this->package_details[$path] ) && is_array( $actions ) ) {
245
  $actions[] = $this->registration_link;
246
  }
247
+
248
  return $actions;
249
  }
250
  }
lib/updater/api.php CHANGED
@@ -23,52 +23,52 @@ class Ithemes_Updater_API {
23
  public static function activate_package( $username, $password, $packages ) {
24
  return self::get_response( 'activate_package', compact( 'username', 'password', 'packages' ), false );
25
  }
26
-
27
  public static function deactivate_package( $username, $password, $packages ) {
28
  return self::get_response( 'deactivate_package', compact( 'username', 'password', 'packages' ), false );
29
  }
30
-
31
  public static function get_package_details( $cache = true ) {
32
  $packages = array();
33
-
34
  return self::get_response( 'get_package_details', compact( 'packages' ), $cache );
35
  }
36
-
37
  public static function get_package_changelog( $package, $cur_version = false ) {
38
  $response = wp_remote_get( 'http://api.ithemes.com/product/changelog?package=' . urlencode( $package ) );
39
-
40
  if ( is_wp_error( $response ) ) {
41
- return sprintf( __( '<p>Unable to get changelog data at this time.</p><p>Error <code>%1$s</code>: %2$s</p>', 'it-l10n-ithemes-sync' ), $response->get_error_code(), $response->get_error_message() );
42
  }
43
-
44
- if ( ! is_array( $response ) || ! isset( $response['body'] ) ) {
45
- return __( '<p>Unable to get changelog data at this time.</p><p>Error: Unrecognized response from <code>wp_remote_get</code>.</p>', 'it-l10n-ithemes-sync' );
46
  }
47
-
48
  if ( isset( $response['response']['code'] ) && ( '200' != $response['response']['code'] ) ) {
49
- return sprintf( __( '<p>Unable to get changelog data at this time.</p><p>Error code <code>%1$s</code>: %2$s</p>', 'it-l10n-ithemes-sync' ), $response['response']['code'], $response['response']['message'] );
50
  }
51
-
52
-
53
  $body = $response['body'];
54
-
55
  if ( '{' === substr( $body, 0, 1 ) ) {
56
  $error = json_decode( $body, true );
57
-
58
  if ( is_array( $error ) && isset( $error['error'] ) && is_array( $error['error'] ) && isset( $error['error']['type'] ) && isset( $error['error']['message'] ) ) {
59
- return sprintf( __( '<p>Unable to get changelog data at this time.</p><p>Error <code>%1$s</code>: %2$s</p>', 'it-l10n-ithemes-sync' ), $error['error']['type'], $error['error']['message'] );
60
  } else {
61
- return __( '<p>Unable to get changelog data at this time.</p><p>Error: Unrecognized response from iThemes API server.</p>', 'it-l10n-ithemes-sync' );
62
  }
63
  }
64
-
65
-
66
  $versions = array();
67
  $version = false;
68
  $depth = 0;
69
-
70
  $lines = preg_split( '/[\n\r]+/', $body );
71
-
72
  foreach ( $lines as $line ) {
73
  if ( preg_match( '/^\d/', $line ) ) {
74
  if ( ! empty( $version ) && ( $depth > 0 ) ) {
@@ -76,19 +76,19 @@ class Ithemes_Updater_API {
76
  $versions[$version] .= "</ul>\n";
77
  }
78
  }
79
-
80
  $depth = 0;
81
-
82
  $parts = preg_split( '/\s+-\s+/', $line );
83
  $version = $parts[0];
84
-
85
  if ( version_compare( $version, $cur_version, '<=' ) ) {
86
  $version = '';
87
  continue;
88
  }
89
-
90
  $versions[$version] = '';
91
-
92
  continue;
93
  } else if ( preg_match( '/^\S/', $line ) ) {
94
  $version = '';
@@ -96,17 +96,17 @@ class Ithemes_Updater_API {
96
  } else if ( empty( $version ) ) {
97
  continue;
98
  }
99
-
100
  $line = str_replace( ' ', "\t", $line );
101
  $line = str_replace( "\t", '', $line, $count );
102
  $line = preg_replace( '/^\s+/', '', $line );
103
-
104
  if ( empty( $line ) ) {
105
  continue;
106
  }
107
-
108
  $details = '';
109
-
110
  if ( $count > $depth ) {
111
  $details .= "<ul>\n";
112
  $depth++;
@@ -114,55 +114,55 @@ class Ithemes_Updater_API {
114
  $details .= "</ul>\n";
115
  $depth--;
116
  }
117
-
118
  $details .= "<li>$line</li>\n";
119
-
120
-
121
  $versions[$version] .= $details;
122
  }
123
-
124
  if ( ! empty( $version ) && ( $depth > 0 ) ) {
125
  while ( $depth-- > 0 ) {
126
  $versions[$version] .= "</ul>\n";
127
  }
128
  }
129
-
130
-
131
  uksort( $versions, 'version_compare' );
132
  $versions = array_reverse( $versions );
133
-
134
-
135
  $changelog = '';
136
-
137
  foreach ( $versions as $version => $details ) {
138
  $changelog .= "<h4>$version</h4>\n$details\n";
139
  }
140
-
141
  $changelog = preg_replace( '/\s+$/', '', $changelog );
142
-
143
-
144
  return $changelog;
145
  }
146
-
147
  public static function get_response( $action, $args, $cache ) {
148
  require_once( $GLOBALS['ithemes_updater_path'] . '/server.php' );
149
  require_once( $GLOBALS['ithemes_updater_path'] . '/updates.php' );
150
-
151
-
152
  if ( isset( $args['packages'] ) ) {
153
  $args['packages'] = self::get_request_package_details( $args['packages'] );
154
  }
155
-
156
-
157
  $response = false;
158
  $source = '';
159
  $cached = true;
160
-
161
  $md5 = substr( md5( serialize( $args ) ), 0, 5 );
162
  $time = time();
163
  $cache_var = "it-updater-$action-$md5";
164
-
165
-
166
  if ( $cache ) {
167
  if ( isset( $GLOBALS[$cache_var] ) ) {
168
  $response = $GLOBALS[$cache_var];
@@ -172,104 +172,104 @@ class Ithemes_Updater_API {
172
  $source = 'transient';
173
  }
174
  }
175
-
176
-
177
  if ( false === $response ) {
178
  $response = call_user_func_array( array( 'Ithemes_Updater_Server', $action ), $args );
179
  $source = 'server';
180
-
181
  if ( is_wp_error( $response ) ) {
182
  return $response;
183
  }
184
-
185
  $cache_length = 86400 * $GLOBALS['ithemes-updater-settings']->get_option( 'timeout-multiplier' );
186
-
187
  set_site_transient( $cache_var, $response, $cache_length );
188
-
189
  $cached = false;
190
  }
191
-
192
-
193
  Ithemes_Updater_Updates::process_server_response( $response, $cached );
194
-
195
  $GLOBALS[$cache_var] = $response;
196
-
197
  return $response;
198
  }
199
-
200
  private static function get_request_package_details( $desired_packages = array() ) {
201
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
202
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
203
-
204
-
205
  $all_packages = Ithemes_Updater_Packages::get_local_details();
206
  reset( $desired_packages );
207
-
208
  if ( empty( $desired_packages ) ) {
209
  $desired_packages = $all_packages;
210
  } else if ( is_numeric( key( $desired_packages ) ) ) {
211
  $new_desired_packages = array();
212
-
213
  foreach ( $all_packages as $path => $details ) {
214
  foreach ( $desired_packages as $package ) {
215
  if ( $package != $details['package'] ) {
216
  continue;
217
  }
218
-
219
  $new_desired_packages[$path] = $details;
220
-
221
  break;
222
  }
223
  }
224
-
225
  $desired_packages = $new_desired_packages;
226
  }
227
-
228
-
229
  $packages = array();
230
  $keys = Ithemes_Updater_Keys::get();
231
-
232
-
233
  $package_slugs = array();
234
-
235
  foreach ( $desired_packages as $data ) {
236
  $package_slugs[] = $data['package'];
237
  }
238
-
239
  $legacy_keys = Ithemes_Updater_Keys::get_legacy( $package_slugs );
240
-
241
-
242
  $active_themes = array(
243
  'stylesheet' => get_stylesheet_directory(),
244
  'template' => get_template_directory(),
245
  );
246
  $active_themes = array_unique( $active_themes );
247
-
248
  foreach ( $active_themes as $index => $path ) {
249
  $active_themes[$index] = basename( $path );
250
  }
251
-
252
-
253
  foreach ( $desired_packages as $path => $data ) {
254
  $key = ( isset( $keys[$data['package']] ) ) ? $keys[$data['package']] : '';
255
-
256
  $package = array(
257
  'ver' => $data['installed'],
258
  'key' => $key,
259
  );
260
-
261
  if ( ! empty( $legacy_keys[$data['package']] ) ) {
262
  $package['old-key'] = $legacy_keys[$data['package']];
263
  }
264
-
265
-
266
  if ( 'plugins' == $data['type'] ) {
267
  $package['active'] = (int) is_plugin_active( $path );
268
  } else {
269
  $dir = dirname( $path );
270
-
271
  $package['active'] = (int) in_array( $dir, $active_themes );
272
-
273
  if ( $package['active'] && ( count( $active_themes ) > 1 ) ) {
274
  if ( $dir == $active_themes['stylesheet'] ) {
275
  $package['child-theme'] = 1;
@@ -278,24 +278,58 @@ class Ithemes_Updater_API {
278
  }
279
  }
280
  }
281
-
282
-
283
  $package_key = $data['package'];
284
  $counter = 0;
285
-
286
  while ( isset( $packages[$package_key] ) ) {
287
  $package_key = "{$data['package']} ||| " . ++$counter;
288
  }
289
-
290
  $packages[$package_key] = $package;
291
  }
292
-
293
-
294
  if ( ! empty( $legacy_keys ) ) {
295
  Ithemes_Updater_Keys::delete_legacy( array_keys( $legacy_keys ) );
296
  }
297
-
298
-
299
  return $packages;
300
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  }
23
  public static function activate_package( $username, $password, $packages ) {
24
  return self::get_response( 'activate_package', compact( 'username', 'password', 'packages' ), false );
25
  }
26
+
27
  public static function deactivate_package( $username, $password, $packages ) {
28
  return self::get_response( 'deactivate_package', compact( 'username', 'password', 'packages' ), false );
29
  }
30
+
31
  public static function get_package_details( $cache = true ) {
32
  $packages = array();
33
+
34
  return self::get_response( 'get_package_details', compact( 'packages' ), $cache );
35
  }
36
+
37
  public static function get_package_changelog( $package, $cur_version = false ) {
38
  $response = wp_remote_get( 'http://api.ithemes.com/product/changelog?package=' . urlencode( $package ) );
39
+
40
  if ( is_wp_error( $response ) ) {
41
+ return $response;
42
  }
43
+
44
+ if ( ! isset( $response['body'] ) ) {
45
+ return new WP_Error( 'ithemes-updater-changelog-bad-wp-remote-get-response', __( 'Unrecognized response from <code>wp_remote_get</code>.', 'it-l10n-ithemes-sync' ) );
46
  }
47
+
48
  if ( isset( $response['response']['code'] ) && ( '200' != $response['response']['code'] ) ) {
49
+ return new WP_Error( 'ithemes-updater-wp-remote-get-error-' . $response['response']['code'], $response['response']['message'] );
50
  }
51
+
52
+
53
  $body = $response['body'];
54
+
55
  if ( '{' === substr( $body, 0, 1 ) ) {
56
  $error = json_decode( $body, true );
57
+
58
  if ( is_array( $error ) && isset( $error['error'] ) && is_array( $error['error'] ) && isset( $error['error']['type'] ) && isset( $error['error']['message'] ) ) {
59
+ return new WP_Error( 'ithemes-updater-json-decode-error-' . $error['error']['type'], $error['error']['message'] );
60
  } else {
61
+ return new WP_Error( 'ithemes-updater-changelog-bad-json-decode-result', __( 'Unrecognized response from iThemes API server.', 'it-l10n-ithemes-sync' ) );
62
  }
63
  }
64
+
65
+
66
  $versions = array();
67
  $version = false;
68
  $depth = 0;
69
+
70
  $lines = preg_split( '/[\n\r]+/', $body );
71
+
72
  foreach ( $lines as $line ) {
73
  if ( preg_match( '/^\d/', $line ) ) {
74
  if ( ! empty( $version ) && ( $depth > 0 ) ) {
76
  $versions[$version] .= "</ul>\n";
77
  }
78
  }
79
+
80
  $depth = 0;
81
+
82
  $parts = preg_split( '/\s+-\s+/', $line );
83
  $version = $parts[0];
84
+
85
  if ( version_compare( $version, $cur_version, '<=' ) ) {
86
  $version = '';
87
  continue;
88
  }
89
+
90
  $versions[$version] = '';
91
+
92
  continue;
93
  } else if ( preg_match( '/^\S/', $line ) ) {
94
  $version = '';
96
  } else if ( empty( $version ) ) {
97
  continue;
98
  }
99
+
100
  $line = str_replace( ' ', "\t", $line );
101
  $line = str_replace( "\t", '', $line, $count );
102
  $line = preg_replace( '/^\s+/', '', $line );
103
+
104
  if ( empty( $line ) ) {
105
  continue;
106
  }
107
+
108
  $details = '';
109
+
110
  if ( $count > $depth ) {
111
  $details .= "<ul>\n";
112
  $depth++;
114
  $details .= "</ul>\n";
115
  $depth--;
116
  }
117
+
118
  $details .= "<li>$line</li>\n";
119
+
120
+
121
  $versions[$version] .= $details;
122
  }
123
+
124
  if ( ! empty( $version ) && ( $depth > 0 ) ) {
125
  while ( $depth-- > 0 ) {
126
  $versions[$version] .= "</ul>\n";
127
  }
128
  }
129
+
130
+
131
  uksort( $versions, 'version_compare' );
132
  $versions = array_reverse( $versions );
133
+
134
+
135
  $changelog = '';
136
+
137
  foreach ( $versions as $version => $details ) {
138
  $changelog .= "<h4>$version</h4>\n$details\n";
139
  }
140
+
141
  $changelog = preg_replace( '/\s+$/', '', $changelog );
142
+
143
+
144
  return $changelog;
145
  }
146
+
147
  public static function get_response( $action, $args, $cache ) {
148
  require_once( $GLOBALS['ithemes_updater_path'] . '/server.php' );
149
  require_once( $GLOBALS['ithemes_updater_path'] . '/updates.php' );
150
+
151
+
152
  if ( isset( $args['packages'] ) ) {
153
  $args['packages'] = self::get_request_package_details( $args['packages'] );
154
  }
155
+
156
+
157
  $response = false;
158
  $source = '';
159
  $cached = true;
160
+
161
  $md5 = substr( md5( serialize( $args ) ), 0, 5 );
162
  $time = time();
163
  $cache_var = "it-updater-$action-$md5";
164
+
165
+
166
  if ( $cache ) {
167
  if ( isset( $GLOBALS[$cache_var] ) ) {
168
  $response = $GLOBALS[$cache_var];
172
  $source = 'transient';
173
  }
174
  }
175
+
176
+
177
  if ( false === $response ) {
178
  $response = call_user_func_array( array( 'Ithemes_Updater_Server', $action ), $args );
179
  $source = 'server';
180
+
181
  if ( is_wp_error( $response ) ) {
182
  return $response;
183
  }
184
+
185
  $cache_length = 86400 * $GLOBALS['ithemes-updater-settings']->get_option( 'timeout-multiplier' );
186
+
187
  set_site_transient( $cache_var, $response, $cache_length );
188
+
189
  $cached = false;
190
  }
191
+
192
+
193
  Ithemes_Updater_Updates::process_server_response( $response, $cached );
194
+
195
  $GLOBALS[$cache_var] = $response;
196
+
197
  return $response;
198
  }
199
+
200
  private static function get_request_package_details( $desired_packages = array() ) {
201
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
202
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
203
+
204
+
205
  $all_packages = Ithemes_Updater_Packages::get_local_details();
206
  reset( $desired_packages );
207
+
208
  if ( empty( $desired_packages ) ) {
209
  $desired_packages = $all_packages;
210
  } else if ( is_numeric( key( $desired_packages ) ) ) {
211
  $new_desired_packages = array();
212
+
213
  foreach ( $all_packages as $path => $details ) {
214
  foreach ( $desired_packages as $package ) {
215
  if ( $package != $details['package'] ) {
216
  continue;
217
  }
218
+
219
  $new_desired_packages[$path] = $details;
220
+
221
  break;
222
  }
223
  }
224
+
225
  $desired_packages = $new_desired_packages;
226
  }
227
+
228
+
229
  $packages = array();
230
  $keys = Ithemes_Updater_Keys::get();
231
+
232
+
233
  $package_slugs = array();
234
+
235
  foreach ( $desired_packages as $data ) {
236
  $package_slugs[] = $data['package'];
237
  }
238
+
239
  $legacy_keys = Ithemes_Updater_Keys::get_legacy( $package_slugs );
240
+
241
+
242
  $active_themes = array(
243
  'stylesheet' => get_stylesheet_directory(),
244
  'template' => get_template_directory(),
245
  );
246
  $active_themes = array_unique( $active_themes );
247
+
248
  foreach ( $active_themes as $index => $path ) {
249
  $active_themes[$index] = basename( $path );
250
  }
251
+
252
+
253
  foreach ( $desired_packages as $path => $data ) {
254
  $key = ( isset( $keys[$data['package']] ) ) ? $keys[$data['package']] : '';
255
+
256
  $package = array(
257
  'ver' => $data['installed'],
258
  'key' => $key,
259
  );
260
+
261
  if ( ! empty( $legacy_keys[$data['package']] ) ) {
262
  $package['old-key'] = $legacy_keys[$data['package']];
263
  }
264
+
265
+
266
  if ( 'plugins' == $data['type'] ) {
267
  $package['active'] = (int) is_plugin_active( $path );
268
  } else {
269
  $dir = dirname( $path );
270
+
271
  $package['active'] = (int) in_array( $dir, $active_themes );
272
+
273
  if ( $package['active'] && ( count( $active_themes ) > 1 ) ) {
274
  if ( $dir == $active_themes['stylesheet'] ) {
275
  $package['child-theme'] = 1;
278
  }
279
  }
280
  }
281
+
282
+
283
  $package_key = $data['package'];
284
  $counter = 0;
285
+
286
  while ( isset( $packages[$package_key] ) ) {
287
  $package_key = "{$data['package']} ||| " . ++$counter;
288
  }
289
+
290
  $packages[$package_key] = $package;
291
  }
292
+
293
+
294
  if ( ! empty( $legacy_keys ) ) {
295
  Ithemes_Updater_Keys::delete_legacy( array_keys( $legacy_keys ) );
296
  }
297
+
298
+
299
  return $packages;
300
  }
301
+
302
+ public static function get_error_explanation( $error, $package = '' ) {
303
+ $code = $error->get_error_code();
304
+ $package_name = Ithemes_Updater_Functions::get_package_name( $package );
305
+ $message = '';
306
+
307
+ switch( $code ) {
308
+ case 'ITXAPI_Updater_Bad_Login':
309
+ $message = __( 'Incorrect password. Please make sure that you are supplying your iThemes membership username and password details.', 'it-l10n-ithemes-sync' );
310
+ break;
311
+ case 'ITXAPI_Updater_Username_Unknown':
312
+ case 'ITXAPI_Updater_Username_Invalid':
313
+ $message = __( 'Invalid username. Please make sure that you are supplying your iThemes membership username and password details.', 'it-l10n-ithemes-sync' );
314
+ break;
315
+ case 'ITXAPI_Product_Package_Unknown':
316
+ $message = sprintf( __( 'The licensing server reports that the %1$s (%2$s) product is unknown. Please contact support for assistance.', 'it-l10n-ithemes-sync' ), $package_name, $package );
317
+ break;
318
+ case 'ITXAPI_Updater_Too_Many_Sites':
319
+ $message = sprintf( __( '%1$s could not be licensed since the membership account is out of available licenses for this product. You can unlicense the product on other sites or upgrade your membership to one with a higher number of licenses in order to increase the amount of available licenses.', 'it-l10n-ithemes-sync' ), $package_name );
320
+ break;
321
+ case 'ITXAPI_License_Key_Generate_Failed':
322
+ $message = sprintf( __( '%s could not be licensed due to an internal error. Please try to license %s again at a later time. If this problem continues, please contact iThemes support.', 'it-l10n-ithemes-sync' ), $package_name );
323
+ break;
324
+ }
325
+
326
+ if ( empty( $message ) ) {
327
+ if ( ! empty( $package ) )
328
+ $message = sprintf( __( 'An unknown error relating to the %1$s product occurred. Please contact iThemes support. Error details: %2$s', 'it-l10n-ithemes-sync' ), $package_name, $error->get_error_message() . " ($code)" );
329
+ else
330
+ $message = sprintf( __( 'An unknown error occurred. Please contact iThemes support. Error details: %s', 'it-l10n-ithemes-sync' ), $error->get_error_message() . " ($code)" );
331
+ }
332
+
333
+ return $message;
334
+ }
335
  }
lib/updater/functions.php CHANGED
@@ -15,37 +15,37 @@ class Ithemes_Updater_Functions {
15
  public static function get_url( $path ) {
16
  $path = str_replace( '\\', '/', $path );
17
  $wp_content_dir = str_replace( '\\', '/', WP_CONTENT_DIR );
18
-
19
  if ( 0 === strpos( $path, $wp_content_dir ) )
20
  return content_url( str_replace( $wp_content_dir, '', $path ) );
21
-
22
  $abspath = str_replace( '\\', '/', ABSPATH );
23
-
24
  if ( 0 === strpos( $path, $abspath ) )
25
  return site_url( str_replace( $abspath, '', $path ) );
26
-
27
  $wp_plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR );
28
  $wpmu_plugin_dir = str_replace( '\\', '/', WPMU_PLUGIN_DIR );
29
-
30
  if ( 0 === strpos( $path, $wp_plugin_dir ) || 0 === strpos( $path, $wpmu_plugin_dir ) )
31
  return plugins_url( basename( $path ), $path );
32
-
33
  return false;
34
  }
35
-
36
  public static function get_package_name( $package ) {
37
  $name = str_replace( 'builderchild', 'Builder Child', $package );
38
  $name = str_replace( '-', ' ', $name );
39
  $name = ucwords( $name );
40
  $name = str_replace( 'buddy', 'Buddy', $name );
41
  $name = str_replace( 'Ithemes', 'iThemes', $name );
42
-
43
  return $name;
44
  }
45
-
46
  public static function get_post_data( $vars, $fill_missing = false ) {
47
  $data = array();
48
-
49
  foreach ( $vars as $var ) {
50
  if ( isset( $_POST[$var] ) ) {
51
  $clean_var = preg_replace( '/^it-updater-/', '', $var );
@@ -55,7 +55,53 @@ class Ithemes_Updater_Functions {
55
  $data[$var] = '';
56
  }
57
  }
58
-
59
  return stripslashes_deep( $data );
60
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
15
  public static function get_url( $path ) {
16
  $path = str_replace( '\\', '/', $path );
17
  $wp_content_dir = str_replace( '\\', '/', WP_CONTENT_DIR );
18
+
19
  if ( 0 === strpos( $path, $wp_content_dir ) )
20
  return content_url( str_replace( $wp_content_dir, '', $path ) );
21
+
22
  $abspath = str_replace( '\\', '/', ABSPATH );
23
+
24
  if ( 0 === strpos( $path, $abspath ) )
25
  return site_url( str_replace( $abspath, '', $path ) );
26
+
27
  $wp_plugin_dir = str_replace( '\\', '/', WP_PLUGIN_DIR );
28
  $wpmu_plugin_dir = str_replace( '\\', '/', WPMU_PLUGIN_DIR );
29
+
30
  if ( 0 === strpos( $path, $wp_plugin_dir ) || 0 === strpos( $path, $wpmu_plugin_dir ) )
31
  return plugins_url( basename( $path ), $path );
32
+
33
  return false;
34
  }
35
+
36
  public static function get_package_name( $package ) {
37
  $name = str_replace( 'builderchild', 'Builder Child', $package );
38
  $name = str_replace( '-', ' ', $name );
39
  $name = ucwords( $name );
40
  $name = str_replace( 'buddy', 'Buddy', $name );
41
  $name = str_replace( 'Ithemes', 'iThemes', $name );
42
+
43
  return $name;
44
  }
45
+
46
  public static function get_post_data( $vars, $fill_missing = false ) {
47
  $data = array();
48
+
49
  foreach ( $vars as $var ) {
50
  if ( isset( $_POST[$var] ) ) {
51
  $clean_var = preg_replace( '/^it-updater-/', '', $var );
55
  $data[$var] = '';
56
  }
57
  }
58
+
59
  return stripslashes_deep( $data );
60
  }
61
+
62
+ public static function get_site_option( $option ) {
63
+ global $wpdb;
64
+
65
+ $options = get_site_option( $option, false );
66
+
67
+ if ( is_array( $options ) ) {
68
+ return $options;
69
+ }
70
+
71
+ // Attempt to get the stored option manually to ensure that the failure wasn't due to a DB or other glitch.
72
+
73
+ if ( is_multisite() ) {
74
+ $network_id = get_current_network_id();
75
+ $query = $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d LIMIT 1", $option, $network_id );
76
+ $index = 'meta_value';
77
+ } else {
78
+ $query = $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option );
79
+ $index = 'option_value';
80
+ }
81
+
82
+ $result = $wpdb->query( $query );
83
+
84
+ if ( false === $result ) {
85
+ // Something went wrong with the DB.
86
+ return false;
87
+ }
88
+
89
+ if ( empty( $wpdb->last_result[0] ) || empty( $wpdb->last_result[0]->$index ) ) {
90
+ // The value has not been set yet, return the default value.
91
+ return null;
92
+ }
93
+
94
+ $value = $wpdb->last_result[0]->$index;
95
+
96
+ $options = @unserialize( $value );
97
+
98
+ if ( is_array( $options ) ) {
99
+ return $options;
100
+ }
101
+
102
+ // Seems that we have some bad data.
103
+ // TODO: Attempt data restoration.
104
+
105
+ return null;
106
+ }
107
  }
lib/updater/history.txt CHANGED
@@ -36,3 +36,11 @@
36
  Compatibility Fix: Updated plugin and theme update data format to match changes in WordPress 4.2.
37
  1.4.2 - 2015-07-14 - Chris Jean
38
  Enhancement: Updated link to iThemes support.
 
 
 
 
 
 
 
 
36
  Compatibility Fix: Updated plugin and theme update data format to match changes in WordPress 4.2.
37
  1.4.2 - 2015-07-14 - Chris Jean
38
  Enhancement: Updated link to iThemes support.
39
+ 1.5.0 - 2018-05-02 - Chris Jean
40
+ Bug Fix: Fixed the "View details" link failing to work properly after updating.
41
+ Bug Fix: Fixed an issue that could cause data changes to not save properly on specific background page requests.
42
+ Bug Fix: Added a compatibility fix to avoid conflicts with plugins that change the plugin_action_links filter value from an array to a string.
43
+ Compatibility Fix: Updated handing of wp_remote_get() response due to changes documented in https://core.trac.wordpress.org/ticket/33055.
44
+ Enhancement: Added ability to manage licensing from WP-CLI.
45
+ 1.5.1 - 2018-05-03 - Chris Jean
46
+ Bug Fix: Fixed fatal error that could occur when clicking the "View details" link for an available plugin update.
lib/updater/information.php CHANGED
@@ -21,36 +21,41 @@ class Ithemes_Updater_Information {
21
  public static function get_theme_information( $path ) {
22
  return self::get_plugin_information( "$path/style.css" );
23
  }
24
-
25
  public static function get_plugin_information( $path ) {
26
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
27
  $details = Ithemes_Updater_Packages::get_full_details();
28
-
29
  if ( ! isset( $details['packages'][$path] ) )
30
  return false;
31
-
32
-
33
  $package = $details['packages'][$path];
34
-
35
  require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
36
  require_once( $GLOBALS['ithemes_updater_path'] . '/information.php' );
37
-
38
  $changelog = Ithemes_Updater_API::get_package_changelog( $package['package'], $details['packages'][$path]['installed'] );
39
-
40
-
 
 
 
 
 
41
  $info = array(
42
  'name' => Ithemes_Updater_Functions::get_package_name( $package['package'] ),
43
  'slug' => dirname( $path ),
44
  'version' => $package['available'],
45
  'author' => '<a href="http://ithemes.com/">iThemes</a>',
46
  'download_link' => $package['package-url'],
47
-
48
  'sections' => array(
49
  'changelog' => $changelog,
50
  ),
51
  );
52
-
53
-
54
  return (object) $info;
55
  }
56
  }
21
  public static function get_theme_information( $path ) {
22
  return self::get_plugin_information( "$path/style.css" );
23
  }
24
+
25
  public static function get_plugin_information( $path ) {
26
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
27
  $details = Ithemes_Updater_Packages::get_full_details();
28
+
29
  if ( ! isset( $details['packages'][$path] ) )
30
  return false;
31
+
32
+
33
  $package = $details['packages'][$path];
34
+
35
  require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
36
  require_once( $GLOBALS['ithemes_updater_path'] . '/information.php' );
37
+
38
  $changelog = Ithemes_Updater_API::get_package_changelog( $package['package'], $details['packages'][$path]['installed'] );
39
+
40
+ if ( is_wp_error( $changelog ) ) {
41
+ /* translators: 1. Error message, 2. Error code */
42
+ $changelog = sprintf( __( '<p>Unable to get changelog data at this time.</p><p>%1$s (%2$s)</p>', 'it-l10n-ithemes-sync' ), $response->get_error_message(), $response->get_error_code() );
43
+ }
44
+
45
+
46
  $info = array(
47
  'name' => Ithemes_Updater_Functions::get_package_name( $package['package'] ),
48
  'slug' => dirname( $path ),
49
  'version' => $package['available'],
50
  'author' => '<a href="http://ithemes.com/">iThemes</a>',
51
  'download_link' => $package['package-url'],
52
+
53
  'sections' => array(
54
  'changelog' => $changelog,
55
  ),
56
  );
57
+
58
+
59
  return (object) $info;
60
  }
61
  }
lib/updater/init.php CHANGED
@@ -19,6 +19,12 @@ Version History
19
  */
20
 
21
 
 
 
 
 
 
 
22
  if ( defined( 'ITHEMES_UPDATER_DISABLE' ) && ITHEMES_UPDATER_DISABLE ) {
23
  return;
24
  }
@@ -36,7 +42,7 @@ function ithemes_updater_filter_update_plugins( $update_plugins ) {
36
  if ( ! class_exists( 'Ithemes_Updater_Settings' ) ) {
37
  require( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
38
  }
39
-
40
  return $GLOBALS['ithemes-updater-settings']->filter_update_plugins( $update_plugins );
41
  }
42
  add_filter( 'site_transient_update_plugins', 'ithemes_updater_filter_update_plugins' );
@@ -47,7 +53,7 @@ function ithemes_updater_filter_update_themes( $update_themes ) {
47
  if ( ! class_exists( 'Ithemes_Updater_Settings' ) ) {
48
  require( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
49
  }
50
-
51
  return $GLOBALS['ithemes-updater-settings']->filter_update_themes( $update_themes );
52
  }
53
  add_filter( 'site_transient_update_themes', 'ithemes_updater_filter_update_themes' );
19
  */
20
 
21
 
22
+ if ( defined( 'WP_CLI' ) && WP_CLI && class_exists( 'WP_CLI_Command' ) && ! class_exists( 'Ithemes_Updater_WP_CLI_Ithemes_Licensing' ) ) {
23
+ require( dirname( __FILE__ ) . '/wp-cli.php' );
24
+ WP_CLI::add_command( 'ithemes-licensing', 'Ithemes_Updater_WP_CLI_Ithemes_Licensing' );
25
+ }
26
+
27
+
28
  if ( defined( 'ITHEMES_UPDATER_DISABLE' ) && ITHEMES_UPDATER_DISABLE ) {
29
  return;
30
  }
42
  if ( ! class_exists( 'Ithemes_Updater_Settings' ) ) {
43
  require( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
44
  }
45
+
46
  return $GLOBALS['ithemes-updater-settings']->filter_update_plugins( $update_plugins );
47
  }
48
  add_filter( 'site_transient_update_plugins', 'ithemes_updater_filter_update_plugins' );
53
  if ( ! class_exists( 'Ithemes_Updater_Settings' ) ) {
54
  require( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
55
  }
56
+
57
  return $GLOBALS['ithemes-updater-settings']->filter_update_themes( $update_themes );
58
  }
59
  add_filter( 'site_transient_update_themes', 'ithemes_updater_filter_update_themes' );
lib/updater/keys.php CHANGED
@@ -17,40 +17,50 @@ Version History
17
 
18
  class Ithemes_Updater_Keys {
19
  private static $option_name = 'ithemes-updater-keys';
20
-
21
-
22
  public static function get( $packages = array() ) {
23
- $all_keys = get_site_option( self::$option_name, array() );
24
-
 
 
 
 
 
 
 
 
 
 
25
  if ( '__all__' == $packages ) {
26
  return $all_keys;
27
  }
28
-
29
  if ( empty( $packages ) ) {
30
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
31
  $packages = array_unique( array_values( Ithemes_Updater_Packages::get_all() ) );
32
  }
33
-
34
-
35
  $keys = array();
36
-
37
  foreach ( (array) $packages as $package ) {
38
  if ( ! empty( $all_keys[$package] ) ) {
39
  $keys[$package] = $all_keys[$package];
40
  }
41
  }
42
-
43
-
44
  if ( ! is_array( $packages ) ) {
45
  return $keys[$packages];
46
  }
47
-
48
  return $keys;
49
  }
50
-
51
  public static function set( $new_keys, $key = false ) {
52
  $keys = self::get( '__all__' );
53
-
54
  if ( false === $key ) {
55
  foreach ( $new_keys as $package => $key ) {
56
  $keys[$package] = $key;
@@ -58,88 +68,90 @@ class Ithemes_Updater_Keys {
58
  } else {
59
  $keys[$new_keys] = $key;
60
  }
61
-
62
- update_site_option( self::$option_name, $keys );
 
 
63
  }
64
-
65
  private static function get_legacy_slug( $raw_slug ) {
66
  $slug = str_replace( '_', '-', $raw_slug );
67
  $slug = preg_replace( '/^(pluginbuddy|ithemes|it)-/', '', $slug );
68
-
69
  if ( 'boom-bar' == $slug ) {
70
  $slug = 'boombar';
71
  }
72
-
73
  return $slug;
74
  }
75
-
76
  public static function delete_legacy( $packages = array() ) {
77
  if ( ! is_array( $packages ) ) {
78
  $packages = array( $packages );
79
  }
80
-
81
  $data = get_site_option( 'pluginbuddy_plugins', false );
82
-
83
-
84
  $remaining_count = 0;
85
-
86
  foreach ( $data as $index => $entry ) {
87
  if ( ! is_object( $entry ) || empty( $entry->slug ) ) {
88
  continue;
89
  }
90
-
91
  $slug = self::get_legacy_slug( $entry->slug );
92
-
93
  if ( in_array( $slug, $packages ) ) {
94
  unset( $data[$index] );
95
  } else {
96
  $remaining_count++;
97
  }
98
  }
99
-
100
  if ( 0 == $remaining_count ) {
101
  $data = false;
102
  }
103
-
104
-
105
  update_site_option( 'pluginbuddy_plugins', $data );
106
  }
107
-
108
  public static function get_legacy( $packages = array() ) {
109
  $data = get_site_option( 'pluginbuddy_plugins', false );
110
-
111
  if ( empty( $data ) || ! is_array( $data ) ) {
112
  return array();
113
  }
114
-
115
-
116
  $keys = array();
117
-
118
  foreach ( $data as $index => $entry ) {
119
  if ( ! is_object( $entry ) || empty( $entry->slug ) || ! isset( $entry->key ) ) {
120
  continue;
121
  }
122
-
123
  $slug = self::get_legacy_slug( $entry->slug );
124
  $keys[$slug] = $entry->key;
125
  }
126
-
127
-
128
  foreach ( array_keys( $keys ) as $slug ) {
129
  if ( ! isset( $data[$slug] ) ) {
130
  continue;
131
  }
132
-
133
  $entry = $data[$slug];
134
-
135
  if ( ! is_object( $entry ) || empty( $entry->slug ) || empty( $entry->key ) ) {
136
  continue;
137
  }
138
-
139
  $keys[$slug] = $entry->key;
140
  }
141
-
142
-
143
  if ( empty( $packages ) ) {
144
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
145
  $packages = array_unique( array_values( Ithemes_Updater_Packages::get_all() ) );
@@ -147,19 +159,19 @@ class Ithemes_Updater_Keys {
147
  if ( ! empty( $keys[$packages] ) ) {
148
  return $keys[$packages];
149
  }
150
-
151
  return false;
152
  }
153
-
154
-
155
  $package_keys = array();
156
-
157
  foreach ( $packages as $package ) {
158
  if ( ! empty( $keys[$package] ) ) {
159
  $package_keys[$package] = $keys[$package];
160
  }
161
  }
162
-
163
  return $package_keys;
164
  }
165
  }
17
 
18
  class Ithemes_Updater_Keys {
19
  private static $option_name = 'ithemes-updater-keys';
20
+
21
+
22
  public static function get( $packages = array() ) {
23
+ require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
24
+ $all_keys = Ithemes_Updater_Functions::get_site_option( self::$option_name );
25
+
26
+ if ( false === $all_keys ) {
27
+ $GLOBALS['ithemes-updater-keys-db-failure'] = true;
28
+ } else {
29
+ $GLOBALS['ithemes-updater-keys-db-failure'] = false;
30
+ }
31
+ if ( ! is_array( $all_keys ) ) {
32
+ $all_keys = array();
33
+ }
34
+
35
  if ( '__all__' == $packages ) {
36
  return $all_keys;
37
  }
38
+
39
  if ( empty( $packages ) ) {
40
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
41
  $packages = array_unique( array_values( Ithemes_Updater_Packages::get_all() ) );
42
  }
43
+
44
+
45
  $keys = array();
46
+
47
  foreach ( (array) $packages as $package ) {
48
  if ( ! empty( $all_keys[$package] ) ) {
49
  $keys[$package] = $all_keys[$package];
50
  }
51
  }
52
+
53
+
54
  if ( ! is_array( $packages ) ) {
55
  return $keys[$packages];
56
  }
57
+
58
  return $keys;
59
  }
60
+
61
  public static function set( $new_keys, $key = false ) {
62
  $keys = self::get( '__all__' );
63
+
64
  if ( false === $key ) {
65
  foreach ( $new_keys as $package => $key ) {
66
  $keys[$package] = $key;
68
  } else {
69
  $keys[$new_keys] = $key;
70
  }
71
+
72
+ if ( ! isset( $GLOBALS['ithemes-updater-keys-db-failure'] ) || false === $GLOBALS['ithemes-updater-keys-db-failure'] ) {
73
+ update_site_option( self::$option_name, $keys );
74
+ }
75
  }
76
+
77
  private static function get_legacy_slug( $raw_slug ) {
78
  $slug = str_replace( '_', '-', $raw_slug );
79
  $slug = preg_replace( '/^(pluginbuddy|ithemes|it)-/', '', $slug );
80
+
81
  if ( 'boom-bar' == $slug ) {
82
  $slug = 'boombar';
83
  }
84
+
85
  return $slug;
86
  }
87
+
88
  public static function delete_legacy( $packages = array() ) {
89
  if ( ! is_array( $packages ) ) {
90
  $packages = array( $packages );
91
  }
92
+
93
  $data = get_site_option( 'pluginbuddy_plugins', false );
94
+
95
+
96
  $remaining_count = 0;
97
+
98
  foreach ( $data as $index => $entry ) {
99
  if ( ! is_object( $entry ) || empty( $entry->slug ) ) {
100
  continue;
101
  }
102
+
103
  $slug = self::get_legacy_slug( $entry->slug );
104
+
105
  if ( in_array( $slug, $packages ) ) {
106
  unset( $data[$index] );
107
  } else {
108
  $remaining_count++;
109
  }
110
  }
111
+
112
  if ( 0 == $remaining_count ) {
113
  $data = false;
114
  }
115
+
116
+
117
  update_site_option( 'pluginbuddy_plugins', $data );
118
  }
119
+
120
  public static function get_legacy( $packages = array() ) {
121
  $data = get_site_option( 'pluginbuddy_plugins', false );
122
+
123
  if ( empty( $data ) || ! is_array( $data ) ) {
124
  return array();
125
  }
126
+
127
+
128
  $keys = array();
129
+
130
  foreach ( $data as $index => $entry ) {
131
  if ( ! is_object( $entry ) || empty( $entry->slug ) || ! isset( $entry->key ) ) {
132
  continue;
133
  }
134
+
135
  $slug = self::get_legacy_slug( $entry->slug );
136
  $keys[$slug] = $entry->key;
137
  }
138
+
139
+
140
  foreach ( array_keys( $keys ) as $slug ) {
141
  if ( ! isset( $data[$slug] ) ) {
142
  continue;
143
  }
144
+
145
  $entry = $data[$slug];
146
+
147
  if ( ! is_object( $entry ) || empty( $entry->slug ) || empty( $entry->key ) ) {
148
  continue;
149
  }
150
+
151
  $keys[$slug] = $entry->key;
152
  }
153
+
154
+
155
  if ( empty( $packages ) ) {
156
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
157
  $packages = array_unique( array_values( Ithemes_Updater_Packages::get_all() ) );
159
  if ( ! empty( $keys[$packages] ) ) {
160
  return $keys[$packages];
161
  }
162
+
163
  return false;
164
  }
165
+
166
+
167
  $package_keys = array();
168
+
169
  foreach ( $packages as $package ) {
170
  if ( ! empty( $keys[$package] ) ) {
171
  $package_keys[$package] = $keys[$package];
172
  }
173
  }
174
+
175
  return $package_keys;
176
  }
177
  }
lib/updater/load.php CHANGED
@@ -5,7 +5,7 @@ Written by Chris Jean for iThemes.com
5
  */
6
 
7
 
8
- $it_registration_list_version = '1.4.2';
9
  $it_registration_list_library = 'updater';
10
  $it_registration_list_init_file = dirname( __FILE__ ) . '/init.php';
11
 
@@ -18,35 +18,35 @@ if ( ! function_exists( 'it_registration_list_init' ) ) {
18
  global $wp_locale;
19
  if ( ! isset( $wp_locale ) )
20
  return;
21
-
22
-
23
  $init_files = array();
24
-
25
  foreach ( (array) $GLOBALS['it_classes_registration_list'] as $library => $versions ) {
26
  $max_version = '-10000';
27
  $init_file = '';
28
-
29
  foreach ( (array) $versions as $version => $file ) {
30
  if ( version_compare( $version, $max_version, '>' ) ) {
31
  $max_version = $version;
32
  $init_file = $file;
33
  }
34
  }
35
-
36
  if ( ! empty( $init_file ) )
37
  $init_files[] = $init_file;
38
  }
39
-
40
  unset( $GLOBALS['it_classes_registration_list'] );
41
-
42
  foreach ( (array) $init_files as $init_file )
43
  require_once( $init_file );
44
-
45
  do_action( 'it_libraries_loaded' );
46
  }
47
-
48
  global $wp_version;
49
-
50
  if ( version_compare( $wp_version, '2.9.7', '>' ) )
51
  add_action( 'after_setup_theme', 'it_registration_list_init' );
52
  else
5
  */
6
 
7
 
8
+ $it_registration_list_version = '1.5.1';
9
  $it_registration_list_library = 'updater';
10
  $it_registration_list_init_file = dirname( __FILE__ ) . '/init.php';
11
 
18
  global $wp_locale;
19
  if ( ! isset( $wp_locale ) )
20
  return;
21
+
22
+
23
  $init_files = array();
24
+
25
  foreach ( (array) $GLOBALS['it_classes_registration_list'] as $library => $versions ) {
26
  $max_version = '-10000';
27
  $init_file = '';
28
+
29
  foreach ( (array) $versions as $version => $file ) {
30
  if ( version_compare( $version, $max_version, '>' ) ) {
31
  $max_version = $version;
32
  $init_file = $file;
33
  }
34
  }
35
+
36
  if ( ! empty( $init_file ) )
37
  $init_files[] = $init_file;
38
  }
39
+
40
  unset( $GLOBALS['it_classes_registration_list'] );
41
+
42
  foreach ( (array) $init_files as $init_file )
43
  require_once( $init_file );
44
+
45
  do_action( 'it_libraries_loaded' );
46
  }
47
+
48
  global $wp_version;
49
+
50
  if ( version_compare( $wp_version, '2.9.7', '>' ) )
51
  add_action( 'after_setup_theme', 'it_registration_list_init' );
52
  else
lib/updater/packages.php CHANGED
@@ -20,22 +20,22 @@ class Ithemes_Updater_Packages {
20
  public static function flush() {
21
  unset( $GLOBALS['ithemes-updater-packages-all'] );
22
  }
23
-
24
  public static function get_full_details( $response = false ) {
25
  if ( false === $response ) {
26
  require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
27
  $response = Ithemes_Updater_API::get_package_details();
28
  }
29
-
30
  $packages = self::get_local_details();
31
-
32
-
33
  if ( is_wp_error( $response ) ) {
34
  $expiration = time() + 600;
35
-
36
  foreach ( $packages as $path => $data ) {
37
  $packages[$path]['status'] = 'error';
38
-
39
  $packages[$path]['error'] = array(
40
  'code' => 'unknown',
41
  'type' => $response->get_error_code(),
@@ -44,14 +44,14 @@ class Ithemes_Updater_Packages {
44
  }
45
  } else {
46
  $expiration = time() + ( 12 * 3600 );
47
-
48
  foreach ( $packages as $path => $data ) {
49
  if ( empty( $response['packages'][$data['package']] ) ) {
50
  continue;
51
  }
52
-
53
  $package = $response['packages'][$data['package']];
54
-
55
  if ( ! empty( $package['error'] ) ) {
56
  if ( in_array( $package['error']['type'], array( 'ITXAPI_License_Key_Unknown', 'ITXAPI_Updater_Missing_Legacy_Key' ) ) ) {
57
  $packages[$path]['status'] = 'unlicensed';
@@ -59,11 +59,11 @@ class Ithemes_Updater_Packages {
59
  $packages[$path]['status'] = 'error';
60
  $packages[$path]['error'] = $package['error'];
61
  }
62
-
63
  continue;
64
  }
65
-
66
-
67
  $key_map = array(
68
  'status' => 'status',
69
  'link' => 'package-url',
@@ -74,7 +74,7 @@ class Ithemes_Updater_Packages {
74
  'sub_expire' => 'expiration',
75
  'upgrade' => 'upgrade',
76
  );
77
-
78
  foreach ( $key_map as $old => $new ) {
79
  if ( isset( $package[$old] ) ) {
80
  $packages[$path][$new] = $package[$old];
@@ -82,48 +82,48 @@ class Ithemes_Updater_Packages {
82
  $packages[$path][$new] = null;
83
  }
84
  }
85
-
86
  if ( isset( $package['link_expire'] ) ) {
87
  $expiration = min( $expiration, $package['link_expire'] );
88
  }
89
  }
90
  }
91
-
92
-
93
  $details = compact( 'packages', 'expiration' );
94
-
95
  return $details;
96
  }
97
-
98
  public static function get_local_details() {
99
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
100
-
101
-
102
  $all_packages = self::get_all();
103
  $keys = Ithemes_Updater_Keys::get();
104
-
105
  $packages = array();
106
-
107
  foreach ( $all_packages as $file => $slug ) {
108
  $packages[$slug][] = $file;
109
  }
110
-
111
  foreach ( $packages as $slug => $paths ) {
112
  $packages[$slug] = array_unique( $paths );
113
  }
114
-
115
-
116
  $details = array();
117
-
118
-
119
  foreach ( $packages as $package => $paths ) {
120
  foreach ( $paths as $path ) {
121
  $plugin_path = preg_replace( '/^' . preg_quote( WP_PLUGIN_DIR, '/' ) . '/', '', $path );
122
-
123
  if ( $plugin_path != $path ) {
124
  $type = 'plugin';
125
  $rel_path = preg_replace( '|^[/\\\\]|', '', $plugin_path );
126
-
127
  $plugin_data = get_plugin_data( $path, false, false );
128
  $version = $plugin_data['Version'];
129
  $info_url = $plugin_data['PluginURI'];
@@ -131,21 +131,21 @@ class Ithemes_Updater_Packages {
131
  $type = 'theme';
132
  $dir = basename( dirname( $path ) );
133
  $rel_path = "$dir/" . basename( $path );
134
-
135
  if ( function_exists( 'wp_get_theme' ) ) {
136
  $theme_data = wp_get_theme( $dir );
137
-
138
  $version = $theme_data->get( 'Version' );
139
  $info_url = $theme_data->get( 'ThemeURI' );
140
  } else {
141
  $theme_data = get_theme( $dir );
142
-
143
  $version = $theme_data['Version'];
144
  $info_url = '';
145
  }
146
  }
147
-
148
-
149
  $details[$rel_path] = array(
150
  'type' => $type,
151
  'package' => $package,
@@ -155,69 +155,69 @@ class Ithemes_Updater_Packages {
155
  );
156
  }
157
  }
158
-
159
-
160
  return $details;
161
  }
162
-
163
  public static function get_all() {
164
  if ( isset( $GLOBALS['ithemes-updater-packages-all'] ) ) {
165
  return $GLOBALS['ithemes-updater-packages-all'];
166
  }
167
-
168
-
169
  $packages = array();
170
-
171
-
172
  // Compatibility fix for WP < 3.1 as the global var is empty by default
173
  if ( empty( $GLOBALS['wp_theme_directories'] ) ) {
174
  get_themes();
175
  }
176
-
177
  $themes = search_theme_directories();
178
-
179
  if ( is_array( $themes ) ) {
180
  foreach ( $themes as $slug => $data ) {
181
  if ( ! file_exists( "{$data['theme_root']}/{$data['theme_file']}" ) ) {
182
  continue;
183
  }
184
-
185
  $headers = get_file_data( "{$data['theme_root']}/{$data['theme_file']}", array( 'package' => 'iThemes Package' ), 'theme' );
186
-
187
  if ( empty( $headers['package'] ) ) {
188
  continue;
189
  }
190
-
191
  $packages["{$data['theme_root']}/{$data['theme_file']}"] = $headers['package'];
192
  }
193
  }
194
-
195
-
196
  require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
197
  $plugins = get_plugins();
198
-
199
  foreach ( $plugins as $file => $data ) {
200
  if ( ! file_exists( WP_PLUGIN_DIR . "/$file" ) ) {
201
  continue;
202
  }
203
-
204
  $headers = get_file_data( WP_PLUGIN_DIR . "/$file", array( 'package' => 'iThemes Package' ), 'plugin' );
205
-
206
  if ( empty( $headers['package'] ) ) {
207
  continue;
208
  }
209
-
210
  $packages[WP_PLUGIN_DIR . "/$file"] = $headers['package'];
211
  }
212
-
213
-
214
  foreach ( $packages as $path => $package ) {
215
  $packages[$path] = strtolower( $package );
216
  }
217
-
218
-
219
  $GLOBALS['ithemes-updater-packages-all'] = $packages;
220
-
221
  return $packages;
222
  }
223
  }
20
  public static function flush() {
21
  unset( $GLOBALS['ithemes-updater-packages-all'] );
22
  }
23
+
24
  public static function get_full_details( $response = false ) {
25
  if ( false === $response ) {
26
  require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
27
  $response = Ithemes_Updater_API::get_package_details();
28
  }
29
+
30
  $packages = self::get_local_details();
31
+
32
+
33
  if ( is_wp_error( $response ) ) {
34
  $expiration = time() + 600;
35
+
36
  foreach ( $packages as $path => $data ) {
37
  $packages[$path]['status'] = 'error';
38
+
39
  $packages[$path]['error'] = array(
40
  'code' => 'unknown',
41
  'type' => $response->get_error_code(),
44
  }
45
  } else {
46
  $expiration = time() + ( 12 * 3600 );
47
+
48
  foreach ( $packages as $path => $data ) {
49
  if ( empty( $response['packages'][$data['package']] ) ) {
50
  continue;
51
  }
52
+
53
  $package = $response['packages'][$data['package']];
54
+
55
  if ( ! empty( $package['error'] ) ) {
56
  if ( in_array( $package['error']['type'], array( 'ITXAPI_License_Key_Unknown', 'ITXAPI_Updater_Missing_Legacy_Key' ) ) ) {
57
  $packages[$path]['status'] = 'unlicensed';
59
  $packages[$path]['status'] = 'error';
60
  $packages[$path]['error'] = $package['error'];
61
  }
62
+
63
  continue;
64
  }
65
+
66
+
67
  $key_map = array(
68
  'status' => 'status',
69
  'link' => 'package-url',
74
  'sub_expire' => 'expiration',
75
  'upgrade' => 'upgrade',
76
  );
77
+
78
  foreach ( $key_map as $old => $new ) {
79
  if ( isset( $package[$old] ) ) {
80
  $packages[$path][$new] = $package[$old];
82
  $packages[$path][$new] = null;
83
  }
84
  }
85
+
86
  if ( isset( $package['link_expire'] ) ) {
87
  $expiration = min( $expiration, $package['link_expire'] );
88
  }
89
  }
90
  }
91
+
92
+
93
  $details = compact( 'packages', 'expiration' );
94
+
95
  return $details;
96
  }
97
+
98
  public static function get_local_details() {
99
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
100
+
101
+
102
  $all_packages = self::get_all();
103
  $keys = Ithemes_Updater_Keys::get();
104
+
105
  $packages = array();
106
+
107
  foreach ( $all_packages as $file => $slug ) {
108
  $packages[$slug][] = $file;
109
  }
110
+
111
  foreach ( $packages as $slug => $paths ) {
112
  $packages[$slug] = array_unique( $paths );
113
  }
114
+
115
+
116
  $details = array();
117
+
118
+
119
  foreach ( $packages as $package => $paths ) {
120
  foreach ( $paths as $path ) {
121
  $plugin_path = preg_replace( '/^' . preg_quote( WP_PLUGIN_DIR, '/' ) . '/', '', $path );
122
+
123
  if ( $plugin_path != $path ) {
124
  $type = 'plugin';
125
  $rel_path = preg_replace( '|^[/\\\\]|', '', $plugin_path );
126
+
127
  $plugin_data = get_plugin_data( $path, false, false );
128
  $version = $plugin_data['Version'];
129
  $info_url = $plugin_data['PluginURI'];
131
  $type = 'theme';
132
  $dir = basename( dirname( $path ) );
133
  $rel_path = "$dir/" . basename( $path );
134
+
135
  if ( function_exists( 'wp_get_theme' ) ) {
136
  $theme_data = wp_get_theme( $dir );
137
+
138
  $version = $theme_data->get( 'Version' );
139
  $info_url = $theme_data->get( 'ThemeURI' );
140
  } else {
141
  $theme_data = get_theme( $dir );
142
+
143
  $version = $theme_data['Version'];
144
  $info_url = '';
145
  }
146
  }
147
+
148
+
149
  $details[$rel_path] = array(
150
  'type' => $type,
151
  'package' => $package,
155
  );
156
  }
157
  }
158
+
159
+
160
  return $details;
161
  }
162
+
163
  public static function get_all() {
164
  if ( isset( $GLOBALS['ithemes-updater-packages-all'] ) ) {
165
  return $GLOBALS['ithemes-updater-packages-all'];
166
  }
167
+
168
+
169
  $packages = array();
170
+
171
+
172
  // Compatibility fix for WP < 3.1 as the global var is empty by default
173
  if ( empty( $GLOBALS['wp_theme_directories'] ) ) {
174
  get_themes();
175
  }
176
+
177
  $themes = search_theme_directories();
178
+
179
  if ( is_array( $themes ) ) {
180
  foreach ( $themes as $slug => $data ) {
181
  if ( ! file_exists( "{$data['theme_root']}/{$data['theme_file']}" ) ) {
182
  continue;
183
  }
184
+
185
  $headers = get_file_data( "{$data['theme_root']}/{$data['theme_file']}", array( 'package' => 'iThemes Package' ), 'theme' );
186
+
187
  if ( empty( $headers['package'] ) ) {
188
  continue;
189
  }
190
+
191
  $packages["{$data['theme_root']}/{$data['theme_file']}"] = $headers['package'];
192
  }
193
  }
194
+
195
+
196
  require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
197
  $plugins = get_plugins();
198
+
199
  foreach ( $plugins as $file => $data ) {
200
  if ( ! file_exists( WP_PLUGIN_DIR . "/$file" ) ) {
201
  continue;
202
  }
203
+
204
  $headers = get_file_data( WP_PLUGIN_DIR . "/$file", array( 'package' => 'iThemes Package' ), 'plugin' );
205
+
206
  if ( empty( $headers['package'] ) ) {
207
  continue;
208
  }
209
+
210
  $packages[WP_PLUGIN_DIR . "/$file"] = $headers['package'];
211
  }
212
+
213
+
214
  foreach ( $packages as $path => $package ) {
215
  $packages[$path] = strtolower( $package );
216
  }
217
+
218
+
219
  $GLOBALS['ithemes-updater-packages-all'] = $packages;
220
+
221
  return $packages;
222
  }
223
  }
lib/updater/server.php CHANGED
@@ -26,192 +26,194 @@ Version History
26
  class Ithemes_Updater_Server {
27
  private static $secure_server_url = 'https://api.ithemes.com/updater';
28
  private static $insecure_server_url = 'http://api.ithemes.com/updater';
29
-
30
  private static $password_iterations = 8;
31
-
32
-
33
  public static function activate_package( $username, $password, $packages ) {
34
  $query = array(
35
  'user' => $username
36
  );
37
-
38
  $data = array(
39
  'auth_token' => self::get_password_hash( $username, $password ),
40
  'packages' => $packages,
41
  );
42
-
43
  return Ithemes_Updater_Server::request( 'package-activate', $query, $data );
44
  }
45
-
46
  public static function deactivate_package( $username, $password, $packages ) {
47
  $query = array(
48
  'user' => $username
49
  );
50
-
51
  $data = array(
52
  'auth_token' => self::get_password_hash( $username, $password ),
53
  'packages' => $packages,
54
  );
55
-
56
  return Ithemes_Updater_Server::request( 'package-deactivate', $query, $data );
57
  }
58
-
59
  public static function get_package_details( $packages ) {
60
  $query = array();
61
-
62
  $data = array(
63
  'packages' => $packages
64
  );
65
-
66
  return Ithemes_Updater_Server::request( 'package-details', $query, $data );
67
  }
68
-
69
  public static function request( $action, $query = array(), $data = array() ) {
 
 
70
  if ( false !== ( $timeout_start = get_site_option( 'ithemes-updater-server-timed-out' ) ) ) {
71
  // Hold off updates for 30 minutes.
72
  $time_remaining = 1800 - ( time() - $timeout_start );
73
  $minutes_remaining = ceil( $time_remaining / 60 );
74
-
75
  if ( $time_remaining < 0 ) {
76
  delete_site_option( 'ithemes-updater-server-timed-out' );
77
  } else {
78
  return new WP_Error( 'ithemes-updater-timed-out-server', sprintf( _n( 'The server could not be contacted. Requests are delayed for %d minute to allow the server to recover.', 'The server could not be contacted. Requests are delayed for %d minutes to allow the server to recover.', $minutes_remaining, 'it-l10n-ithemes-sync' ), $minutes_remaining ) );
79
  }
80
  }
81
-
82
-
83
  if ( isset( $data['auth_token'] ) ) {
84
  $data['iterations'] = self::$password_iterations;
85
  }
86
-
87
-
88
  $site_url = self::get_site_url();
89
-
90
-
91
  $default_query = array(
92
  'wp' => $GLOBALS['wp_version'],
93
  'site' => $site_url,
94
  'timestamp' => time(),
95
  'auth_version' => '2',
96
  );
97
-
98
  if ( is_multisite() ) {
99
  $default_query['ms'] = 1;
100
  }
101
-
102
  $query = array_merge( $default_query, $query );
103
  $request = "/$action/?" . http_build_query( $query, '', '&' );
104
-
105
  $post_data = array(
106
  'request' => json_encode( $data ),
107
  );
108
-
109
  $remote_post_args = array(
110
  'timeout' => 10,
111
  'body' => $post_data,
112
  );
113
-
114
-
115
  $options = array(
116
  'use_ca_patch' => false,
117
  'use_ssl' => true,
118
  );
119
-
120
  $patch_enabled = $GLOBALS['ithemes-updater-settings']->get_option( 'use_ca_patch' );
121
-
122
  if ( $patch_enabled ) {
123
  self::disable_ssl_ca_patch();
124
  }
125
-
126
-
127
  $response = wp_remote_post( self::$secure_server_url . $request, $remote_post_args );
128
-
129
  if ( is_wp_error( $response ) && ( 'connect() timed out!' != $response->get_error_message() ) ) {
130
  self::enable_ssl_ca_patch();
131
  $response = wp_remote_post( self::$secure_server_url . $request, $remote_post_args );
132
-
133
  if ( ! is_wp_error( $response ) ) {
134
  $options['use_ca_patch'] = true;
135
  }
136
  }
137
-
138
  if ( is_wp_error( $response ) && ( 'connect() timed out!' != $response->get_error_message() ) ) {
139
  $response = wp_remote_post( self::$insecure_server_url . $request, $remote_post_args );
140
-
141
  $options['use_ssl'] = false;
142
  }
143
-
144
  if ( ! $options['use_ca_patch'] ) {
145
  self::disable_ssl_ca_patch();
146
  }
147
-
148
  $GLOBALS['ithemes-updater-settings']->update_options( $options );
149
-
150
  if ( is_wp_error( $response ) ) {
151
  if ( 'connect() timed out!' == $response->get_error_message() ) {
152
  // Set option to delay server checks for a period of time.
153
  update_site_option( 'ithemes-updater-server-timed-out', time() );
154
-
155
  return new WP_Error( 'http_request_failed', __( 'The server was unable to be contacted.', 'it-l10n-ithemes-sync' ) );
156
  }
157
-
158
  return $response;
159
  }
160
-
161
-
162
  $body = json_decode( $response['body'], true );
163
-
164
  if ( ! empty( $body['error'] ) ) {
165
  return new WP_Error( $body['error']['type'], sprintf( __( 'An error occurred when communicating with the iThemes update server: %s (%s)', 'it-l10n-ithemes-sync' ), $body['error']['message'], $body['error']['code'] ) );
166
  }
167
-
168
-
169
  return $body;
170
  }
171
-
172
  private static function get_site_url() {
173
  if ( is_callable( 'network_home_url' ) ) {
174
  $site_url = network_home_url();
175
  } else {
176
  $site_url = get_bloginfo( 'url' );
177
  }
178
-
179
  $site_url = preg_replace( '/^https/', 'http', $site_url );
180
  $site_url = preg_replace( '|/$|', '', $site_url );
181
-
182
  return $site_url;
183
  }
184
-
185
  private static function get_password_hash( $username, $password ) {
186
- require_once( ABSPATH . 'wp-includes/class-phpass.php' );
187
  require_once( dirname( __FILE__ ) . '/class-ithemes-credentials.php' );
188
-
189
  $password = iThemes_Credentials::get_password_hash( $username, $password );
190
-
191
  $salted_password = $password . $username . self::get_site_url() . $GLOBALS['wp_version'];
192
  $salted_password = substr( $salted_password, 0, max( strlen( $password ), 512 ) );
193
-
194
  $hasher = new PasswordHash( self::$password_iterations, true );
195
  $auth_token = $hasher->HashPassword( $salted_password );
196
-
197
  return $auth_token;
198
  }
199
-
200
  public static function enable_ssl_ca_patch() {
201
  add_action( 'http_api_curl', array( __CLASS__, 'add_ca_patch_to_curl_opts' ) );
202
  }
203
-
204
  public static function disable_ssl_ca_patch() {
205
  remove_action( 'http_api_curl', array( __CLASS__, 'add_ca_patch_to_curl_opts' ) );
206
  }
207
-
208
  public static function add_ca_patch_to_curl_opts( $handle ) {
209
  $url = curl_getinfo( $handle, CURLINFO_EFFECTIVE_URL );
210
-
211
  if ( ! preg_match( '{^https://(api|downloads)\.ithemes\.com}', $url ) ) {
212
  return;
213
  }
214
-
215
  curl_setopt( $handle, CURLOPT_CAINFO, $GLOBALS['ithemes_updater_path'] . '/ca/roots.crt' );
216
  }
217
  }
26
  class Ithemes_Updater_Server {
27
  private static $secure_server_url = 'https://api.ithemes.com/updater';
28
  private static $insecure_server_url = 'http://api.ithemes.com/updater';
29
+
30
  private static $password_iterations = 8;
31
+
32
+
33
  public static function activate_package( $username, $password, $packages ) {
34
  $query = array(
35
  'user' => $username
36
  );
37
+
38
  $data = array(
39
  'auth_token' => self::get_password_hash( $username, $password ),
40
  'packages' => $packages,
41
  );
42
+
43
  return Ithemes_Updater_Server::request( 'package-activate', $query, $data );
44
  }
45
+
46
  public static function deactivate_package( $username, $password, $packages ) {
47
  $query = array(
48
  'user' => $username
49
  );
50
+
51
  $data = array(
52
  'auth_token' => self::get_password_hash( $username, $password ),
53
  'packages' => $packages,
54
  );
55
+
56
  return Ithemes_Updater_Server::request( 'package-deactivate', $query, $data );
57
  }
58
+
59
  public static function get_package_details( $packages ) {
60
  $query = array();
61
+
62
  $data = array(
63
  'packages' => $packages
64
  );
65
+
66
  return Ithemes_Updater_Server::request( 'package-details', $query, $data );
67
  }
68
+
69
  public static function request( $action, $query = array(), $data = array() ) {
70
+ require_once( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
71
+
72
  if ( false !== ( $timeout_start = get_site_option( 'ithemes-updater-server-timed-out' ) ) ) {
73
  // Hold off updates for 30 minutes.
74
  $time_remaining = 1800 - ( time() - $timeout_start );
75
  $minutes_remaining = ceil( $time_remaining / 60 );
76
+
77
  if ( $time_remaining < 0 ) {
78
  delete_site_option( 'ithemes-updater-server-timed-out' );
79
  } else {
80
  return new WP_Error( 'ithemes-updater-timed-out-server', sprintf( _n( 'The server could not be contacted. Requests are delayed for %d minute to allow the server to recover.', 'The server could not be contacted. Requests are delayed for %d minutes to allow the server to recover.', $minutes_remaining, 'it-l10n-ithemes-sync' ), $minutes_remaining ) );
81
  }
82
  }
83
+
84
+
85
  if ( isset( $data['auth_token'] ) ) {
86
  $data['iterations'] = self::$password_iterations;
87
  }
88
+
89
+
90
  $site_url = self::get_site_url();
91
+
92
+
93
  $default_query = array(
94
  'wp' => $GLOBALS['wp_version'],
95
  'site' => $site_url,
96
  'timestamp' => time(),
97
  'auth_version' => '2',
98
  );
99
+
100
  if ( is_multisite() ) {
101
  $default_query['ms'] = 1;
102
  }
103
+
104
  $query = array_merge( $default_query, $query );
105
  $request = "/$action/?" . http_build_query( $query, '', '&' );
106
+
107
  $post_data = array(
108
  'request' => json_encode( $data ),
109
  );
110
+
111
  $remote_post_args = array(
112
  'timeout' => 10,
113
  'body' => $post_data,
114
  );
115
+
116
+
117
  $options = array(
118
  'use_ca_patch' => false,
119
  'use_ssl' => true,
120
  );
121
+
122
  $patch_enabled = $GLOBALS['ithemes-updater-settings']->get_option( 'use_ca_patch' );
123
+
124
  if ( $patch_enabled ) {
125
  self::disable_ssl_ca_patch();
126
  }
127
+
128
+
129
  $response = wp_remote_post( self::$secure_server_url . $request, $remote_post_args );
130
+
131
  if ( is_wp_error( $response ) && ( 'connect() timed out!' != $response->get_error_message() ) ) {
132
  self::enable_ssl_ca_patch();
133
  $response = wp_remote_post( self::$secure_server_url . $request, $remote_post_args );
134
+
135
  if ( ! is_wp_error( $response ) ) {
136
  $options['use_ca_patch'] = true;
137
  }
138
  }
139
+
140
  if ( is_wp_error( $response ) && ( 'connect() timed out!' != $response->get_error_message() ) ) {
141
  $response = wp_remote_post( self::$insecure_server_url . $request, $remote_post_args );
142
+
143
  $options['use_ssl'] = false;
144
  }
145
+
146
  if ( ! $options['use_ca_patch'] ) {
147
  self::disable_ssl_ca_patch();
148
  }
149
+
150
  $GLOBALS['ithemes-updater-settings']->update_options( $options );
151
+
152
  if ( is_wp_error( $response ) ) {
153
  if ( 'connect() timed out!' == $response->get_error_message() ) {
154
  // Set option to delay server checks for a period of time.
155
  update_site_option( 'ithemes-updater-server-timed-out', time() );
156
+
157
  return new WP_Error( 'http_request_failed', __( 'The server was unable to be contacted.', 'it-l10n-ithemes-sync' ) );
158
  }
159
+
160
  return $response;
161
  }
162
+
163
+
164
  $body = json_decode( $response['body'], true );
165
+
166
  if ( ! empty( $body['error'] ) ) {
167
  return new WP_Error( $body['error']['type'], sprintf( __( 'An error occurred when communicating with the iThemes update server: %s (%s)', 'it-l10n-ithemes-sync' ), $body['error']['message'], $body['error']['code'] ) );
168
  }
169
+
170
+
171
  return $body;
172
  }
173
+
174
  private static function get_site_url() {
175
  if ( is_callable( 'network_home_url' ) ) {
176
  $site_url = network_home_url();
177
  } else {
178
  $site_url = get_bloginfo( 'url' );
179
  }
180
+
181
  $site_url = preg_replace( '/^https/', 'http', $site_url );
182
  $site_url = preg_replace( '|/$|', '', $site_url );
183
+
184
  return $site_url;
185
  }
186
+
187
  private static function get_password_hash( $username, $password ) {
188
+ require_once( ABSPATH . WPINC . '/class-phpass.php' );
189
  require_once( dirname( __FILE__ ) . '/class-ithemes-credentials.php' );
190
+
191
  $password = iThemes_Credentials::get_password_hash( $username, $password );
192
+
193
  $salted_password = $password . $username . self::get_site_url() . $GLOBALS['wp_version'];
194
  $salted_password = substr( $salted_password, 0, max( strlen( $password ), 512 ) );
195
+
196
  $hasher = new PasswordHash( self::$password_iterations, true );
197
  $auth_token = $hasher->HashPassword( $salted_password );
198
+
199
  return $auth_token;
200
  }
201
+
202
  public static function enable_ssl_ca_patch() {
203
  add_action( 'http_api_curl', array( __CLASS__, 'add_ca_patch_to_curl_opts' ) );
204
  }
205
+
206
  public static function disable_ssl_ca_patch() {
207
  remove_action( 'http_api_curl', array( __CLASS__, 'add_ca_patch_to_curl_opts' ) );
208
  }
209
+
210
  public static function add_ca_patch_to_curl_opts( $handle ) {
211
  $url = curl_getinfo( $handle, CURLINFO_EFFECTIVE_URL );
212
+
213
  if ( ! preg_match( '{^https://(api|downloads)\.ithemes\.com}', $url ) ) {
214
  return;
215
  }
216
+
217
  curl_setopt( $handle, CURLOPT_CAINFO, $GLOBALS['ithemes_updater_path'] . '/ca/roots.crt' );
218
  }
219
  }
lib/updater/settings-page.php CHANGED
@@ -19,119 +19,85 @@ Version History
19
 
20
  class Ithemes_Updater_Settings_Page {
21
  private $page_name = 'ithemes-licensing';
22
-
23
  private $path_url = '';
24
  private $self_url = '';
25
  private $messages = array();
26
  private $message_strings = array();
27
  private $errors = array();
28
  private $soft_errors = array();
29
-
30
-
31
  public function __construct() {
32
  require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
33
  require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
34
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
35
-
36
-
37
  $this->path_url = Ithemes_Updater_Functions::get_url( $GLOBALS['ithemes_updater_path'] );
38
-
39
  list( $this->self_url ) = explode( '?', $_SERVER['REQUEST_URI'] );
40
  $this->self_url .= '?page=' . $this->page_name;
41
-
42
-
43
  add_action( 'ithemes_updater_settings_page_index', array( $this, 'index' ) );
44
  add_action( 'admin_print_styles', array( $this, 'add_styles' ) );
45
  }
46
-
47
  public function add_styles() {
48
  wp_enqueue_style( 'ithemes-updater-settings-page-style', "{$this->path_url}/css/settings-page.css" );
49
  }
50
-
51
  public function index() {
52
  $post_data = Ithemes_Updater_Functions::get_post_data( array( 'it-updater-username', 'it-updater-password', 'packages', 'action' ), true );
53
-
54
  if ( empty( $post_data['packages'] ) )
55
  $post_data['packages'] = array();
56
-
57
-
58
  $action = $post_data['action'];
59
-
60
  if ( 'license_packages' == $action )
61
  $this->license_packages( $post_data );
62
  else if ( 'unlicense_packages' == $action )
63
  $this->unlicense_packages( $post_data );
64
  else if ( 'save_settings' == $action )
65
  $this->save_settings();
66
-
67
  $this->list_packages( $action, $post_data );
68
  }
69
-
70
- private function get_error_explanation( $error, $package = '' ) {
71
- $code = $error->get_error_code();
72
- $package_name = Ithemes_Updater_Functions::get_package_name( $package );
73
- $message = '';
74
-
75
- switch( $code ) {
76
- case 'ITXAPI_Updater_Bad_Login':
77
- $message = __( 'Incorrect password. Please make sure that you are supplying your iThemes membership username and password details.', 'it-l10n-ithemes-sync' );
78
- break;
79
- case 'ITXAPI_Updater_Username_Unknown':
80
- case 'ITXAPI_Updater_Username_Invalid':
81
- $message = __( 'Invalid username. Please make sure that you are supplying your iThemes membership username and password details.', 'it-l10n-ithemes-sync' );
82
- break;
83
- case 'ITXAPI_Product_Package_Unknown':
84
- $message = sprintf( __( 'The licensing server reports that the %1$s (%2$s) product is unknown. Please contact support for assistance.', 'it-l10n-ithemes-sync' ), $package_name, $package );
85
- break;
86
- case 'ITXAPI_Updater_Too_Many_Sites':
87
- $message = sprintf( __( '%1$s could not be licensed since the membership account is out of available licenses for this product. You can unlicense the product on other sites or upgrade your membership to one with a higher number of licenses in order to increase the amount of available licenses.', 'it-l10n-ithemes-sync' ), $package_name );
88
- break;
89
- case 'ITXAPI_License_Key_Generate_Failed':
90
- $message = sprintf( __( '%s could not be licensed due to an internal error. Please try to license %s again at a later time. If this problem continues, please contact iThemes support.', 'it-l10n-ithemes-sync' ), $package_name );
91
- break;
92
- }
93
-
94
- if ( empty( $message ) ) {
95
- if ( ! empty( $package ) )
96
- $message = sprintf( __( 'An unknown error relating to the %1$s product occurred. Please contact iThemes support. Error details: %2$s', 'it-l10n-ithemes-sync' ), $package_name, $error->get_error_message() . " ($code)" );
97
- else
98
- $message = sprintf( __( 'An unknown error occurred. Please contact iThemes support. Error details: %s', 'it-l10n-ithemes-sync' ), $error->get_error_message() . " ($code)" );
99
- }
100
-
101
- return $message;
102
- }
103
-
104
  private function save_settings() {
105
  check_admin_referer( 'save_settings', 'ithemes_updater_nonce' );
106
-
107
-
108
  $settings_defaults = array(
109
  'quick_releases' => false,
110
  );
111
-
112
  $settings = array();
113
-
114
  foreach ( $settings_defaults as $var => $val ) {
115
  if ( isset( $_POST[$var] ) )
116
  $settings[$var] = $_POST[$var];
117
  else
118
  $settings[$var] = $val;
119
  }
120
-
121
  if ( $settings['quick_releases'] )
122
  $settings['quick_releases'] = true;
123
-
124
  $GLOBALS['ithemes-updater-settings']->update_options( $settings );
125
-
126
  $GLOBALS['ithemes-updater-settings']->flush( 'settings saved' );
127
-
128
-
129
  $this->messages[] = __( 'Settings saved', 'it-l10n-ithemes-sync' );
130
  }
131
-
132
  private function license_packages( $data ) {
133
  check_admin_referer( 'license_packages', 'ithemes_updater_nonce' );
134
-
135
  if ( empty( $data['username'] ) && empty( $data['password'] ) )
136
  $this->errors[] = __( 'You must supply an iThemes membership username and password in order to license products.', 'it-l10n-ithemes-sync' );
137
  else if ( empty( $data['username'] ) )
@@ -140,37 +106,37 @@ class Ithemes_Updater_Settings_Page {
140
  $this->errors[] = __( 'You must supply an iThemes membership password in order to license products.', 'it-l10n-ithemes-sync' );
141
  else if ( empty( $data['packages'] ) )
142
  $this->errors[] = __( 'You must select at least one product to license. Ensure that you select the products that you wish to license in the listing below.', 'it-l10n-ithemes-sync' );
143
-
144
  if ( ! empty( $this->errors ) )
145
  return;
146
-
147
-
148
  $response = Ithemes_Updater_API::activate_package( $data['username'], $data['password'], $data['packages'] );
149
-
150
  if ( is_wp_error( $response ) ) {
151
- $this->errors[] = $this->get_error_explanation( $response );
152
-
153
  return;
154
  }
155
-
156
  if ( empty( $response['packages'] ) ) {
157
  $this->errors[] = __( 'An unknown server error occurred. Please try to license your products again at another time.', 'it-l10n-ithemes-sync' );
158
  return;
159
  }
160
-
161
-
162
  uksort( $response['packages'], 'strnatcasecmp' );
163
-
164
  $success = array();
165
  $warn = array();
166
  $fail = array();
167
-
168
  foreach ( $response['packages'] as $package => $data ) {
169
  if ( preg_match( '/ \|\|\| \d+$/', $package ) )
170
  continue;
171
-
172
  $name = Ithemes_Updater_Functions::get_package_name( $package );
173
-
174
  if ( ! empty( $data['key'] ) )
175
  $success[] = $name;
176
  else if ( ! empty( $data['status'] ) && ( 'expired' == $data['status'] ) )
@@ -178,25 +144,25 @@ class Ithemes_Updater_Settings_Page {
178
  else
179
  $fail[$name] = $data['error']['message'];
180
  }
181
-
182
-
183
  if ( ! empty( $success ) )
184
  $this->messages[] = wp_sprintf( __( 'Successfully licensed %l.', 'it-l10n-ithemes-sync' ), $success );
185
-
186
  if ( ! empty( $fail ) ) {
187
  foreach ( $fail as $name => $reason )
188
  $this->errors[] = sprintf( __( 'Unable to license %1$s. Reason: %2$s', 'it-l10n-ithemes-sync' ), $name, $reason );
189
  }
190
-
191
  if ( ! empty( $warn ) ) {
192
  foreach ( $warn as $name => $reason )
193
  $this->soft_errors[] = sprintf( __( 'Unable to license %1$s. Reason: %2$s', 'it-l10n-ithemes-sync' ), $name, $reason );
194
  }
195
  }
196
-
197
  private function unlicense_packages( $data ) {
198
  check_admin_referer( 'unlicense_packages', 'ithemes_updater_nonce' );
199
-
200
  if ( empty( $data['username'] ) && empty( $data['password'] ) )
201
  $this->errors[] = __( 'You must supply an iThemes membership username and password in order to remove licenses.', 'it-l10n-ithemes-sync' );
202
  else if ( empty( $data['username'] ) )
@@ -205,36 +171,36 @@ class Ithemes_Updater_Settings_Page {
205
  $this->errors[] = __( 'You must supply an iThemes membership password in order to remove licenses.', 'it-l10n-ithemes-sync' );
206
  else if ( empty( $data['packages'] ) )
207
  $this->errors[] = __( 'You must select at least one license to remove. Ensure that you select the licenses that you wish to remove in the listing below.', 'it-l10n-ithemes-sync' );
208
-
209
  if ( ! empty( $this->errors ) )
210
  return;
211
-
212
-
213
  $response = Ithemes_Updater_API::deactivate_package( $data['username'], $data['password'], $data['packages'] );
214
-
215
  if ( is_wp_error( $response ) ) {
216
- $this->errors[] = $this->get_error_explanation( $response );
217
-
218
  return;
219
  }
220
-
221
  if ( empty( $response['packages'] ) ) {
222
  $this->errors[] = __( 'An unknown server error occurred. Please try to remove licenses from your products again at another time.', 'it-l10n-ithemes-sync' );
223
  return;
224
  }
225
-
226
-
227
  uksort( $response['packages'], 'strnatcasecmp' );
228
-
229
  $success = array();
230
  $fail = array();
231
-
232
  foreach ( $response['packages'] as $package => $data ) {
233
  if ( preg_match( '/ \|\|\| \d+$/', $package ) )
234
  continue;
235
-
236
  $name = Ithemes_Updater_Functions::get_package_name( $package );
237
-
238
  if ( isset( $data['status'] ) && ( 'inactive' == $data['status'] ) )
239
  $success[] = $name;
240
  else if ( isset( $data['error'] ) && isset( $data['error']['message'] ) )
@@ -242,30 +208,30 @@ class Ithemes_Updater_Settings_Page {
242
  else
243
  $fail[$name] = __( 'Unknown server error.', 'it-l10n-ithemes-sync' );
244
  }
245
-
246
-
247
  if ( ! empty( $success ) )
248
  $this->messages[] = wp_sprintf( _n( 'Successfully removed license from %l.', 'Successfully removed licenses from %l.', count( $success ), 'it-l10n-ithemes-sync' ), $success );
249
-
250
  if ( ! empty( $fail ) ) {
251
  foreach ( $fail as $name => $reason )
252
  $this->errors[] = sprintf( __( 'Unable to remove license from %1$s. Reason: %2$s', 'it-l10n-ithemes-sync' ), $name, $reason );
253
  }
254
  }
255
-
256
  public function list_packages( $action, $post_data ) {
257
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
258
  $details = Ithemes_Updater_Packages::get_full_details();
259
  $packages = $details['packages'];
260
-
261
  $licensed = array();
262
  $unlicensed = array();
263
  $unrecognized = array();
264
-
265
  foreach ( $packages as $path => $data ) {
266
  $name = Ithemes_Updater_Functions::get_package_name( $data['package'] );
267
  $data['path'] = $path;
268
-
269
  if ( 'unlicensed' == $data['status'] )
270
  $unlicensed[$name] = $data;
271
  else if ( in_array( $data['status'], array( 'active', 'expired' ) ) )
@@ -273,24 +239,24 @@ class Ithemes_Updater_Settings_Page {
273
  else
274
  $unrecognized[$name] = $data;
275
  }
276
-
277
-
278
  if ( ! empty( $this->messages ) ) {
279
  foreach ( $this->messages as $message )
280
  echo "<div class=\"updated fade\"><p><strong>$message</strong></p></div>\n";
281
  }
282
-
283
  if ( ! empty( $this->errors ) ) {
284
  foreach ( $this->errors as $error )
285
  echo "<div class=\"error\"><p><strong>$error</strong></p></div>\n";
286
  }
287
-
288
  if ( ! empty( $this->soft_errors ) ) {
289
  foreach ( $this->soft_errors as $error )
290
  echo "<div class=\"error\"><p><strong>$error</strong></p></div>\n";
291
  }
292
-
293
-
294
  ?>
295
  <div class="wrap">
296
  <?php
@@ -298,31 +264,31 @@ class Ithemes_Updater_Settings_Page {
298
  screen_icon();
299
  }
300
  ?>
301
-
302
  <h2><?php _e( 'iThemes Licensing', 'it-l10n-ithemes-sync' ); ?></h2>
303
-
304
  <?php $this->list_licensed_products( $licensed, $post_data, $action ); ?>
305
-
306
  <?php $this->list_unlicensed_products( $unlicensed, $post_data, $action ); ?>
307
-
308
  <?php $this->list_unrecognized_products( $unrecognized ); ?>
309
-
310
  <?php $this->show_settings(); ?>
311
  </div>
312
  <?php
313
-
314
  }
315
-
316
  private function show_settings() {
317
  $quick_releases = $GLOBALS['ithemes-updater-settings']->get_option( 'quick_releases' );
318
-
319
  ?>
320
  <form id="posts-filter" enctype="multipart/form-data" method="post" action="<?php echo $this->self_url; ?>">
321
  <?php wp_nonce_field( 'save_settings', 'ithemes_updater_nonce' ); ?>
322
-
323
  <div id="ithemes-updater-settings">
324
  <h3 class="subtitle"><?php _e( 'Settings', 'it-l10n-ithemes-sync' ); ?></h3>
325
-
326
  <table class="form-table">
327
  <tbody>
328
  <tr valign="top">
@@ -331,18 +297,18 @@ class Ithemes_Updater_Settings_Page {
331
  </th>
332
  <td>
333
  <?php $checked = ( $quick_releases ) ? ' checked="checked"' : ''; ?>
334
-
335
  <label>
336
  <input id="quick_releases" type="checkbox" name="quick_releases" value="1" <?php echo $checked; ?>/>
337
  <?php _e( 'Enable quick release updates', 'it-l10n-ithemes-sync' ); ?>
338
  </label>
339
-
340
  <p class="description"><?php _e( 'Some products have quick releases that are created to solve specific issues that some users experience. In order to avoid causing users to have updates show up too frequently, automatic updates to these quick releases are disabled by default. Enabling this feature allows quick releases to be available to the automatic update system. Using this option is only recommended if support has requested that you enable it in order to receive a quick release. You should disable this option at a later time after confirming that the quick release solves the issue for you.', 'it-l10n-ithemes-sync' ); ?></p>
341
  </td>
342
  </tr>
343
  </tbody>
344
  </table>
345
-
346
  <p class="submit">
347
  <input id="save_settings" class="button button-primary" type="submit" value="<?php _e( 'Save Settings', 'it-l10n-ithemes-sync' ); ?>" />
348
  <input type="hidden" name="action" value="save_settings" />
@@ -350,25 +316,25 @@ class Ithemes_Updater_Settings_Page {
350
  </div>
351
  </form>
352
  <?php
353
-
354
  }
355
-
356
-
357
  private function list_licensed_products( $products, $post_data, $action ) {
358
  if ( empty( $products ) )
359
  return;
360
-
361
  uksort( $products, 'strnatcasecmp' );
362
-
363
  $time = time();
364
-
365
  $headings = array(
366
  __( 'Product', 'it-l10n-ithemes-sync' ),
367
  __( 'Member', 'it-l10n-ithemes-sync' ),
368
  __( 'Expiration', 'it-l10n-ithemes-sync' ),
369
  __( 'Remaining Licenses', 'it-l10n-ithemes-sync' ),
370
  );
371
-
372
  if ( ( 'unlicense_packages' != $action ) || empty( $this->errors ) ) {
373
  $post_data = array(
374
  'username' => '',
@@ -376,14 +342,14 @@ class Ithemes_Updater_Settings_Page {
376
  'packages' => array(),
377
  );
378
  }
379
-
380
  ?>
381
  <form id="posts-filter" enctype="multipart/form-data" method="post" action="<?php echo $this->self_url; ?>" autocomplete="off">
382
  <?php wp_nonce_field( 'unlicense_packages', 'ithemes_updater_nonce' ); ?>
383
-
384
  <div class="ithemes-updater-products" id="ithemes-updater-licensed">
385
  <h3 class="subtitle"><?php _e( 'Licensed Products', 'it-l10n-ithemes-sync' ); ?></h3>
386
-
387
  <table class="ithemes-updater-listing widefat">
388
  <thead>
389
  <tr>
@@ -410,40 +376,40 @@ class Ithemes_Updater_Settings_Page {
410
  $remaining = __( 'unlimited', 'it-l10n-ithemes-sync' );
411
  else
412
  $remaining = $data['total'] - $data['used'];
413
-
414
  // if ( 0 == $remaining )
415
  // $remaining .= ' <a class="button-secondary upgrade">' . __( 'Upgrade', 'it-l10n-ithemes-sync' ) . '</a>';
416
-
417
-
418
  $expiration = $this->get_expiration_string( $data['expiration'] );
419
  $expiration = '<time datetime="' . date( 'Y-m-d\TH:i:s\Z', $data['expiration'] ) . '">' . $expiration . '</time>';
420
-
421
-
422
  $time_left = $data['expiration'] - $time;
423
  $class = 'expiring';
424
-
425
  if ( $time_left > ( 86400 * 30 ) )
426
  $class = 'active';
427
  else if ( $time_left <= 0 )
428
  $class = 'expired';
429
-
430
  if ( 'expired' == $data['status'] ) {
431
  $class = 'expired';
432
  $remaining = '&nbsp;';
433
  }
434
-
435
-
436
  $status = ucfirst( $class );
437
-
438
-
439
  if ( ++$count % 2 ) {
440
  $class .= ' alt';
441
  }
442
-
443
-
444
  $check_id = "cb-select-{$data['package']}";
445
-
446
-
447
  $checked = ( in_array( $data['package'], $post_data['packages'] ) ) ? ' checked' : '';
448
  ?>
449
  <tr class="<?php echo $class; ?>">
@@ -477,37 +443,37 @@ class Ithemes_Updater_Settings_Page {
477
  </div>
478
  </form>
479
  <?php
480
-
481
  }
482
-
483
  private function list_unlicensed_products( $products, $post_data, $action ) {
484
  if ( empty( $products ) )
485
  return;
486
-
487
  uksort( $products, 'strnatcasecmp' );
488
-
489
  if ( ( 'license_packages' != $action ) || empty( $this->errors ) ) {
490
  $post_data = array(
491
  'username' => '',
492
  'password' => '',
493
  'packages' => array(),
494
  );
495
-
496
  foreach ( $products as $name => $data )
497
  $post_data['packages'][] = $data['package'];
498
  }
499
-
500
  ?>
501
  <form id="posts-filter" enctype="multipart/form-data" method="post" action="<?php echo $this->self_url; ?>" autocomplete="off">
502
  <?php wp_nonce_field( 'license_packages', 'ithemes_updater_nonce' ); ?>
503
-
504
  <div class="ithemes-updater-products" id="ithemes-updater-unlicensed">
505
  <h3 class="subtitle"><?php _e( 'Unlicensed Products', 'it-l10n-ithemes-sync' ); ?></h3>
506
-
507
  <p><?php _e( 'The following products have not been licensed. Licensing a product gives you access to automatic updates from within WordPress.', 'it-l10n-ithemes-sync' ); ?></p>
508
  <p><?php _e( 'To license products, select the products you wish to license, enter your iThemes membership username and password, and press the License Products button.', 'it-l10n-ithemes-sync' ); ?></p>
509
  <p><?php printf( __( 'Need help? <a href="%s">Click here for a quick video tutorial</a>.', 'it-l10n-ithemes-sync' ), 'http://ithemes.com/2013/04/11/introducing-the-new-and-improved-ithemes-licensing-system/' ); ?></p>
510
-
511
  <table class="ithemes-updater-listing widefat">
512
  <thead>
513
  <tr>
@@ -527,18 +493,18 @@ class Ithemes_Updater_Settings_Page {
527
  <?php foreach ( $products as $name => $data ) : ?>
528
  <?php
529
  $check_id = "cb-select-{$data['package']}";
530
-
531
  if ( 'license_packages' == $action )
532
  $checked = ( in_array( $data['package'], $post_data['packages'] ) ) ? ' checked' : '';
533
  else
534
  $checked = ' checked';
535
-
536
  if ( ++$count % 2 ) {
537
  $class = 'alt';
538
  } else {
539
  $class = '';
540
  }
541
-
542
  ?>
543
  <tr class="<?php echo $class; ?>">
544
  <th class="check-column" scope="row">
@@ -567,22 +533,22 @@ class Ithemes_Updater_Settings_Page {
567
  </div>
568
  </form>
569
  <?php
570
-
571
  }
572
-
573
  private function list_unrecognized_products( $products ) {
574
  if ( empty( $products ) )
575
  return;
576
-
577
  uksort( $products, 'strnatcasecmp' );
578
-
579
  ?>
580
  <div class="ithemes-updater-products" id="ithemes-updater-unrecognized">
581
  <h3 class="subtitle"><?php _e( 'Unrecognized Products', 'it-l10n-ithemes-sync' ); ?></h3>
582
-
583
  <p><?php _e( 'The following products were not recognized by the licensing system. This can be due to a bug in the product code, a temporary server issue, or because the product is no longer supported.', 'it-l10n-ithemes-sync' ); ?></p>
584
  <p><?php printf( __( 'Please check this page again at a later time to see if the problem resolves itself. If the product remains, please contact <a href="%s">iThemes support</a> and provide them with the details given below.', 'it-l10n-ithemes-sync' ), 'http://ithemes.com/support/' ); ?></p>
585
-
586
  <table class="ithemes-updater-listing widefat">
587
  <thead>
588
  <tr>
@@ -601,7 +567,7 @@ class Ithemes_Updater_Settings_Page {
601
  $response = "{$data['error']['message']} ({$data['error']['code']})";
602
  else
603
  $response = __( 'Unknown Error', 'it-l10n-ithemes-sync' );
604
-
605
  if ( ++$count % 2 ) {
606
  $class = 'alt';
607
  } else {
@@ -620,21 +586,21 @@ class Ithemes_Updater_Settings_Page {
620
  </table>
621
  </div>
622
  <?php
623
-
624
  }
625
-
626
  private function get_expiration_string( $expiration_timestamp ) {
627
  $time = time();
628
-
629
  $time_left = $expiration_timestamp - $time;
630
-
631
  $expired = false;
632
-
633
  if ( $time_left < 0 ) {
634
  $expired = true;
635
  $time_left = abs( $time_left );
636
  }
637
-
638
  if ( $time_left > ( 86400 * 30 ) )
639
  $expiration = date( 'Y-m-d', $expiration_timestamp );
640
  else {
@@ -646,11 +612,11 @@ class Ithemes_Updater_Settings_Page {
646
  $expiration = sprintf( _n( '%d minute', '%d minutes', intval( $time_left / 60 ), 'it-l10n-ithemes-sync' ), intval( $time_left / 60 ) );
647
  else
648
  $expiration = sprintf( _n( '%d second', '%d seconds', $time_left, 'it-l10n-ithemes-sync' ), intval( $time_left / 60 ) );
649
-
650
  if ( $expired )
651
  $expiration = sprintf( __( '%s ago', 'it-l10n-ithemes-sync' ), $expiration );
652
  }
653
-
654
  return $expiration;
655
  }
656
  }
19
 
20
  class Ithemes_Updater_Settings_Page {
21
  private $page_name = 'ithemes-licensing';
22
+
23
  private $path_url = '';
24
  private $self_url = '';
25
  private $messages = array();
26
  private $message_strings = array();
27
  private $errors = array();
28
  private $soft_errors = array();
29
+
30
+
31
  public function __construct() {
32
  require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
33
  require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
34
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
35
+
36
+
37
  $this->path_url = Ithemes_Updater_Functions::get_url( $GLOBALS['ithemes_updater_path'] );
38
+
39
  list( $this->self_url ) = explode( '?', $_SERVER['REQUEST_URI'] );
40
  $this->self_url .= '?page=' . $this->page_name;
41
+
42
+
43
  add_action( 'ithemes_updater_settings_page_index', array( $this, 'index' ) );
44
  add_action( 'admin_print_styles', array( $this, 'add_styles' ) );
45
  }
46
+
47
  public function add_styles() {
48
  wp_enqueue_style( 'ithemes-updater-settings-page-style', "{$this->path_url}/css/settings-page.css" );
49
  }
50
+
51
  public function index() {
52
  $post_data = Ithemes_Updater_Functions::get_post_data( array( 'it-updater-username', 'it-updater-password', 'packages', 'action' ), true );
53
+
54
  if ( empty( $post_data['packages'] ) )
55
  $post_data['packages'] = array();
56
+
57
+
58
  $action = $post_data['action'];
59
+
60
  if ( 'license_packages' == $action )
61
  $this->license_packages( $post_data );
62
  else if ( 'unlicense_packages' == $action )
63
  $this->unlicense_packages( $post_data );
64
  else if ( 'save_settings' == $action )
65
  $this->save_settings();
66
+
67
  $this->list_packages( $action, $post_data );
68
  }
69
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  private function save_settings() {
71
  check_admin_referer( 'save_settings', 'ithemes_updater_nonce' );
72
+
73
+
74
  $settings_defaults = array(
75
  'quick_releases' => false,
76
  );
77
+
78
  $settings = array();
79
+
80
  foreach ( $settings_defaults as $var => $val ) {
81
  if ( isset( $_POST[$var] ) )
82
  $settings[$var] = $_POST[$var];
83
  else
84
  $settings[$var] = $val;
85
  }
86
+
87
  if ( $settings['quick_releases'] )
88
  $settings['quick_releases'] = true;
89
+
90
  $GLOBALS['ithemes-updater-settings']->update_options( $settings );
91
+
92
  $GLOBALS['ithemes-updater-settings']->flush( 'settings saved' );
93
+
94
+
95
  $this->messages[] = __( 'Settings saved', 'it-l10n-ithemes-sync' );
96
  }
97
+
98
  private function license_packages( $data ) {
99
  check_admin_referer( 'license_packages', 'ithemes_updater_nonce' );
100
+
101
  if ( empty( $data['username'] ) && empty( $data['password'] ) )
102
  $this->errors[] = __( 'You must supply an iThemes membership username and password in order to license products.', 'it-l10n-ithemes-sync' );
103
  else if ( empty( $data['username'] ) )
106
  $this->errors[] = __( 'You must supply an iThemes membership password in order to license products.', 'it-l10n-ithemes-sync' );
107
  else if ( empty( $data['packages'] ) )
108
  $this->errors[] = __( 'You must select at least one product to license. Ensure that you select the products that you wish to license in the listing below.', 'it-l10n-ithemes-sync' );
109
+
110
  if ( ! empty( $this->errors ) )
111
  return;
112
+
113
+
114
  $response = Ithemes_Updater_API::activate_package( $data['username'], $data['password'], $data['packages'] );
115
+
116
  if ( is_wp_error( $response ) ) {
117
+ $this->errors[] = Ithemes_Updater_API::get_error_explanation( $response );
118
+
119
  return;
120
  }
121
+
122
  if ( empty( $response['packages'] ) ) {
123
  $this->errors[] = __( 'An unknown server error occurred. Please try to license your products again at another time.', 'it-l10n-ithemes-sync' );
124
  return;
125
  }
126
+
127
+
128
  uksort( $response['packages'], 'strnatcasecmp' );
129
+
130
  $success = array();
131
  $warn = array();
132
  $fail = array();
133
+
134
  foreach ( $response['packages'] as $package => $data ) {
135
  if ( preg_match( '/ \|\|\| \d+$/', $package ) )
136
  continue;
137
+
138
  $name = Ithemes_Updater_Functions::get_package_name( $package );
139
+
140
  if ( ! empty( $data['key'] ) )
141
  $success[] = $name;
142
  else if ( ! empty( $data['status'] ) && ( 'expired' == $data['status'] ) )
144
  else
145
  $fail[$name] = $data['error']['message'];
146
  }
147
+
148
+
149
  if ( ! empty( $success ) )
150
  $this->messages[] = wp_sprintf( __( 'Successfully licensed %l.', 'it-l10n-ithemes-sync' ), $success );
151
+
152
  if ( ! empty( $fail ) ) {
153
  foreach ( $fail as $name => $reason )
154
  $this->errors[] = sprintf( __( 'Unable to license %1$s. Reason: %2$s', 'it-l10n-ithemes-sync' ), $name, $reason );
155
  }
156
+
157
  if ( ! empty( $warn ) ) {
158
  foreach ( $warn as $name => $reason )
159
  $this->soft_errors[] = sprintf( __( 'Unable to license %1$s. Reason: %2$s', 'it-l10n-ithemes-sync' ), $name, $reason );
160
  }
161
  }
162
+
163
  private function unlicense_packages( $data ) {
164
  check_admin_referer( 'unlicense_packages', 'ithemes_updater_nonce' );
165
+
166
  if ( empty( $data['username'] ) && empty( $data['password'] ) )
167
  $this->errors[] = __( 'You must supply an iThemes membership username and password in order to remove licenses.', 'it-l10n-ithemes-sync' );
168
  else if ( empty( $data['username'] ) )
171
  $this->errors[] = __( 'You must supply an iThemes membership password in order to remove licenses.', 'it-l10n-ithemes-sync' );
172
  else if ( empty( $data['packages'] ) )
173
  $this->errors[] = __( 'You must select at least one license to remove. Ensure that you select the licenses that you wish to remove in the listing below.', 'it-l10n-ithemes-sync' );
174
+
175
  if ( ! empty( $this->errors ) )
176
  return;
177
+
178
+
179
  $response = Ithemes_Updater_API::deactivate_package( $data['username'], $data['password'], $data['packages'] );
180
+
181
  if ( is_wp_error( $response ) ) {
182
+ $this->errors[] = Ithemes_Updater_API::get_error_explanation( $response );
183
+
184
  return;
185
  }
186
+
187
  if ( empty( $response['packages'] ) ) {
188
  $this->errors[] = __( 'An unknown server error occurred. Please try to remove licenses from your products again at another time.', 'it-l10n-ithemes-sync' );
189
  return;
190
  }
191
+
192
+
193
  uksort( $response['packages'], 'strnatcasecmp' );
194
+
195
  $success = array();
196
  $fail = array();
197
+
198
  foreach ( $response['packages'] as $package => $data ) {
199
  if ( preg_match( '/ \|\|\| \d+$/', $package ) )
200
  continue;
201
+
202
  $name = Ithemes_Updater_Functions::get_package_name( $package );
203
+
204
  if ( isset( $data['status'] ) && ( 'inactive' == $data['status'] ) )
205
  $success[] = $name;
206
  else if ( isset( $data['error'] ) && isset( $data['error']['message'] ) )
208
  else
209
  $fail[$name] = __( 'Unknown server error.', 'it-l10n-ithemes-sync' );
210
  }
211
+
212
+
213
  if ( ! empty( $success ) )
214
  $this->messages[] = wp_sprintf( _n( 'Successfully removed license from %l.', 'Successfully removed licenses from %l.', count( $success ), 'it-l10n-ithemes-sync' ), $success );
215
+
216
  if ( ! empty( $fail ) ) {
217
  foreach ( $fail as $name => $reason )
218
  $this->errors[] = sprintf( __( 'Unable to remove license from %1$s. Reason: %2$s', 'it-l10n-ithemes-sync' ), $name, $reason );
219
  }
220
  }
221
+
222
  public function list_packages( $action, $post_data ) {
223
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
224
  $details = Ithemes_Updater_Packages::get_full_details();
225
  $packages = $details['packages'];
226
+
227
  $licensed = array();
228
  $unlicensed = array();
229
  $unrecognized = array();
230
+
231
  foreach ( $packages as $path => $data ) {
232
  $name = Ithemes_Updater_Functions::get_package_name( $data['package'] );
233
  $data['path'] = $path;
234
+
235
  if ( 'unlicensed' == $data['status'] )
236
  $unlicensed[$name] = $data;
237
  else if ( in_array( $data['status'], array( 'active', 'expired' ) ) )
239
  else
240
  $unrecognized[$name] = $data;
241
  }
242
+
243
+
244
  if ( ! empty( $this->messages ) ) {
245
  foreach ( $this->messages as $message )
246
  echo "<div class=\"updated fade\"><p><strong>$message</strong></p></div>\n";
247
  }
248
+
249
  if ( ! empty( $this->errors ) ) {
250
  foreach ( $this->errors as $error )
251
  echo "<div class=\"error\"><p><strong>$error</strong></p></div>\n";
252
  }
253
+
254
  if ( ! empty( $this->soft_errors ) ) {
255
  foreach ( $this->soft_errors as $error )
256
  echo "<div class=\"error\"><p><strong>$error</strong></p></div>\n";
257
  }
258
+
259
+
260
  ?>
261
  <div class="wrap">
262
  <?php
264
  screen_icon();
265
  }
266
  ?>
267
+
268
  <h2><?php _e( 'iThemes Licensing', 'it-l10n-ithemes-sync' ); ?></h2>
269
+
270
  <?php $this->list_licensed_products( $licensed, $post_data, $action ); ?>
271
+
272
  <?php $this->list_unlicensed_products( $unlicensed, $post_data, $action ); ?>
273
+
274
  <?php $this->list_unrecognized_products( $unrecognized ); ?>
275
+
276
  <?php $this->show_settings(); ?>
277
  </div>
278
  <?php
279
+
280
  }
281
+
282
  private function show_settings() {
283
  $quick_releases = $GLOBALS['ithemes-updater-settings']->get_option( 'quick_releases' );
284
+
285
  ?>
286
  <form id="posts-filter" enctype="multipart/form-data" method="post" action="<?php echo $this->self_url; ?>">
287
  <?php wp_nonce_field( 'save_settings', 'ithemes_updater_nonce' ); ?>
288
+
289
  <div id="ithemes-updater-settings">
290
  <h3 class="subtitle"><?php _e( 'Settings', 'it-l10n-ithemes-sync' ); ?></h3>
291
+
292
  <table class="form-table">
293
  <tbody>
294
  <tr valign="top">
297
  </th>
298
  <td>
299
  <?php $checked = ( $quick_releases ) ? ' checked="checked"' : ''; ?>
300
+
301
  <label>
302
  <input id="quick_releases" type="checkbox" name="quick_releases" value="1" <?php echo $checked; ?>/>
303
  <?php _e( 'Enable quick release updates', 'it-l10n-ithemes-sync' ); ?>
304
  </label>
305
+
306
  <p class="description"><?php _e( 'Some products have quick releases that are created to solve specific issues that some users experience. In order to avoid causing users to have updates show up too frequently, automatic updates to these quick releases are disabled by default. Enabling this feature allows quick releases to be available to the automatic update system. Using this option is only recommended if support has requested that you enable it in order to receive a quick release. You should disable this option at a later time after confirming that the quick release solves the issue for you.', 'it-l10n-ithemes-sync' ); ?></p>
307
  </td>
308
  </tr>
309
  </tbody>
310
  </table>
311
+
312
  <p class="submit">
313
  <input id="save_settings" class="button button-primary" type="submit" value="<?php _e( 'Save Settings', 'it-l10n-ithemes-sync' ); ?>" />
314
  <input type="hidden" name="action" value="save_settings" />
316
  </div>
317
  </form>
318
  <?php
319
+
320
  }
321
+
322
+
323
  private function list_licensed_products( $products, $post_data, $action ) {
324
  if ( empty( $products ) )
325
  return;
326
+
327
  uksort( $products, 'strnatcasecmp' );
328
+
329
  $time = time();
330
+
331
  $headings = array(
332
  __( 'Product', 'it-l10n-ithemes-sync' ),
333
  __( 'Member', 'it-l10n-ithemes-sync' ),
334
  __( 'Expiration', 'it-l10n-ithemes-sync' ),
335
  __( 'Remaining Licenses', 'it-l10n-ithemes-sync' ),
336
  );
337
+
338
  if ( ( 'unlicense_packages' != $action ) || empty( $this->errors ) ) {
339
  $post_data = array(
340
  'username' => '',
342
  'packages' => array(),
343
  );
344
  }
345
+
346
  ?>
347
  <form id="posts-filter" enctype="multipart/form-data" method="post" action="<?php echo $this->self_url; ?>" autocomplete="off">
348
  <?php wp_nonce_field( 'unlicense_packages', 'ithemes_updater_nonce' ); ?>
349
+
350
  <div class="ithemes-updater-products" id="ithemes-updater-licensed">
351
  <h3 class="subtitle"><?php _e( 'Licensed Products', 'it-l10n-ithemes-sync' ); ?></h3>
352
+
353
  <table class="ithemes-updater-listing widefat">
354
  <thead>
355
  <tr>
376
  $remaining = __( 'unlimited', 'it-l10n-ithemes-sync' );
377
  else
378
  $remaining = $data['total'] - $data['used'];
379
+
380
  // if ( 0 == $remaining )
381
  // $remaining .= ' <a class="button-secondary upgrade">' . __( 'Upgrade', 'it-l10n-ithemes-sync' ) . '</a>';
382
+
383
+
384
  $expiration = $this->get_expiration_string( $data['expiration'] );
385
  $expiration = '<time datetime="' . date( 'Y-m-d\TH:i:s\Z', $data['expiration'] ) . '">' . $expiration . '</time>';
386
+
387
+
388
  $time_left = $data['expiration'] - $time;
389
  $class = 'expiring';
390
+
391
  if ( $time_left > ( 86400 * 30 ) )
392
  $class = 'active';
393
  else if ( $time_left <= 0 )
394
  $class = 'expired';
395
+
396
  if ( 'expired' == $data['status'] ) {
397
  $class = 'expired';
398
  $remaining = '&nbsp;';
399
  }
400
+
401
+
402
  $status = ucfirst( $class );
403
+
404
+
405
  if ( ++$count % 2 ) {
406
  $class .= ' alt';
407
  }
408
+
409
+
410
  $check_id = "cb-select-{$data['package']}";
411
+
412
+
413
  $checked = ( in_array( $data['package'], $post_data['packages'] ) ) ? ' checked' : '';
414
  ?>
415
  <tr class="<?php echo $class; ?>">
443
  </div>
444
  </form>
445
  <?php
446
+
447
  }
448
+
449
  private function list_unlicensed_products( $products, $post_data, $action ) {
450
  if ( empty( $products ) )
451
  return;
452
+
453
  uksort( $products, 'strnatcasecmp' );
454
+
455
  if ( ( 'license_packages' != $action ) || empty( $this->errors ) ) {
456
  $post_data = array(
457
  'username' => '',
458
  'password' => '',
459
  'packages' => array(),
460
  );
461
+
462
  foreach ( $products as $name => $data )
463
  $post_data['packages'][] = $data['package'];
464
  }
465
+
466
  ?>
467
  <form id="posts-filter" enctype="multipart/form-data" method="post" action="<?php echo $this->self_url; ?>" autocomplete="off">
468
  <?php wp_nonce_field( 'license_packages', 'ithemes_updater_nonce' ); ?>
469
+
470
  <div class="ithemes-updater-products" id="ithemes-updater-unlicensed">
471
  <h3 class="subtitle"><?php _e( 'Unlicensed Products', 'it-l10n-ithemes-sync' ); ?></h3>
472
+
473
  <p><?php _e( 'The following products have not been licensed. Licensing a product gives you access to automatic updates from within WordPress.', 'it-l10n-ithemes-sync' ); ?></p>
474
  <p><?php _e( 'To license products, select the products you wish to license, enter your iThemes membership username and password, and press the License Products button.', 'it-l10n-ithemes-sync' ); ?></p>
475
  <p><?php printf( __( 'Need help? <a href="%s">Click here for a quick video tutorial</a>.', 'it-l10n-ithemes-sync' ), 'http://ithemes.com/2013/04/11/introducing-the-new-and-improved-ithemes-licensing-system/' ); ?></p>
476
+
477
  <table class="ithemes-updater-listing widefat">
478
  <thead>
479
  <tr>
493
  <?php foreach ( $products as $name => $data ) : ?>
494
  <?php
495
  $check_id = "cb-select-{$data['package']}";
496
+
497
  if ( 'license_packages' == $action )
498
  $checked = ( in_array( $data['package'], $post_data['packages'] ) ) ? ' checked' : '';
499
  else
500
  $checked = ' checked';
501
+
502
  if ( ++$count % 2 ) {
503
  $class = 'alt';
504
  } else {
505
  $class = '';
506
  }
507
+
508
  ?>
509
  <tr class="<?php echo $class; ?>">
510
  <th class="check-column" scope="row">
533
  </div>
534
  </form>
535
  <?php
536
+
537
  }
538
+
539
  private function list_unrecognized_products( $products ) {
540
  if ( empty( $products ) )
541
  return;
542
+
543
  uksort( $products, 'strnatcasecmp' );
544
+
545
  ?>
546
  <div class="ithemes-updater-products" id="ithemes-updater-unrecognized">
547
  <h3 class="subtitle"><?php _e( 'Unrecognized Products', 'it-l10n-ithemes-sync' ); ?></h3>
548
+
549
  <p><?php _e( 'The following products were not recognized by the licensing system. This can be due to a bug in the product code, a temporary server issue, or because the product is no longer supported.', 'it-l10n-ithemes-sync' ); ?></p>
550
  <p><?php printf( __( 'Please check this page again at a later time to see if the problem resolves itself. If the product remains, please contact <a href="%s">iThemes support</a> and provide them with the details given below.', 'it-l10n-ithemes-sync' ), 'http://ithemes.com/support/' ); ?></p>
551
+
552
  <table class="ithemes-updater-listing widefat">
553
  <thead>
554
  <tr>
567
  $response = "{$data['error']['message']} ({$data['error']['code']})";
568
  else
569
  $response = __( 'Unknown Error', 'it-l10n-ithemes-sync' );
570
+
571
  if ( ++$count % 2 ) {
572
  $class = 'alt';
573
  } else {
586
  </table>
587
  </div>
588
  <?php
589
+
590
  }
591
+
592
  private function get_expiration_string( $expiration_timestamp ) {
593
  $time = time();
594
+
595
  $time_left = $expiration_timestamp - $time;
596
+
597
  $expired = false;
598
+
599
  if ( $time_left < 0 ) {
600
  $expired = true;
601
  $time_left = abs( $time_left );
602
  }
603
+
604
  if ( $time_left > ( 86400 * 30 ) )
605
  $expiration = date( 'Y-m-d', $expiration_timestamp );
606
  else {
612
  $expiration = sprintf( _n( '%d minute', '%d minutes', intval( $time_left / 60 ), 'it-l10n-ithemes-sync' ), intval( $time_left / 60 ) );
613
  else
614
  $expiration = sprintf( _n( '%d second', '%d seconds', $time_left, 'it-l10n-ithemes-sync' ), intval( $time_left / 60 ) );
615
+
616
  if ( $expired )
617
  $expiration = sprintf( __( '%s ago', 'it-l10n-ithemes-sync' ), $expiration );
618
  }
619
+
620
  return $expiration;
621
  }
622
  }
lib/updater/settings.php CHANGED
@@ -30,7 +30,7 @@ Version History
30
 
31
  class Ithemes_Updater_Settings {
32
  private $option_name = 'ithemes-updater-cache';
33
-
34
  private $packages = array();
35
  private $new_packages = array();
36
  private $options = false;
@@ -39,7 +39,8 @@ class Ithemes_Updater_Settings {
39
  private $initialized = false;
40
  private $plugins_cleaned = false;
41
  private $themes_cleaned = false;
42
-
 
43
  private $default_options = array(
44
  'timeout-multiplier' => 1,
45
  'expiration' => 0,
@@ -51,52 +52,52 @@ class Ithemes_Updater_Settings {
51
  'use_ssl' => true,
52
  'quick_releases' => false,
53
  );
54
-
55
-
56
  public function __construct() {
57
  $GLOBALS['ithemes-updater-settings'] = $this;
58
-
59
  add_action( 'init', array( $this, 'init' ) );
60
- add_action( 'shutdown', array( $this, 'shutdown' ) );
61
  }
62
-
63
  public function init() {
64
  if ( $this->initialized ) {
65
  return;
66
  }
67
-
68
  $this->initialized = true;
69
-
70
  if ( ! isset( $GLOBALS['ithemes_updater_path'] ) ) {
71
  $GLOBALS['ithemes_updater_path'] = dirname( __FILE__ );
72
  }
73
-
74
  $this->load();
75
-
76
  do_action( 'ithemes_updater_register', $this );
77
-
78
  $this->new_packages = array_diff( array_keys( $this->packages ), $this->options['packages'] );
79
-
80
-
81
  if ( isset( $_GET['ithemes-updater-force-quick-release-update'] ) && ! isset( $_GET['ithemes-updater-force-minor-update'] ) ) {
82
  $_GET['ithemes-updater-force-minor-update'] = $_GET['ithemes-updater-force-quick-release-update'];
83
  }
84
-
85
-
86
  $flushed = false;
87
-
88
-
89
  if ( isset( $_GET['ithemes-updater-force-minor-update'] ) && current_user_can( 'manage_options' ) ) {
90
  if ( $_GET['ithemes-updater-force-minor-update'] ) {
91
  $this->options['force_minor_version_update'] = time() + 3600;
92
  $this->update_options( $this->options );
93
-
94
  $this->flush( 'forced minor version update' );
95
  $flushed = true;
96
  } else {
97
  unset( $this->options['force_minor_version_update'] );
98
  $this->update_options( $this->options );
99
-
100
  $this->flush( 'unset forced minor version update' );
101
  $flushed = true;
102
  }
@@ -104,8 +105,8 @@ class Ithemes_Updater_Settings {
104
  unset( $this->options['force_minor_version_update'] );
105
  $this->update_options( $this->options );
106
  }
107
-
108
-
109
  if ( ! $flushed ) {
110
  if ( ! empty( $_GET['ithemes-updater-force-refresh'] ) && current_user_can( 'manage_options' ) ) {
111
  $this->flush( 'forced' );
@@ -118,192 +119,201 @@ class Ithemes_Updater_Settings {
118
  }
119
  }
120
  }
121
-
122
  public function load() {
123
  if ( false !== $this->options ) {
124
  return;
125
  }
126
-
127
- $this->options = get_site_option( $this->option_name, false );
128
-
129
- if ( ( false === $this->options ) || ! is_array( $this->options ) ) {
 
 
 
 
130
  $this->options = array();
131
  }
132
-
133
  $this->options = array_merge( $this->default_options, $this->options );
134
-
135
  if ( 0 == $this->options['timestamp'] ) {
136
  $this->update();
137
  }
138
  }
139
-
140
  public function shutdown() {
141
  $this->flush();
142
-
143
- if ( $this->options_modified ) {
144
  update_site_option( $this->option_name, $this->options );
145
  }
146
  }
147
-
148
  public function queue_flush() {
149
  $this->do_flush = true;
150
  }
151
-
152
  public function flush( $reason = '' ) {
153
  if ( empty( $reason ) && ! $this->do_flush ) {
154
  return;
155
  }
156
-
157
  $this->do_flush = false;
158
-
159
  $this->update();
160
  }
161
-
162
  public function update() {
163
  $this->init();
164
-
165
  require_once( $GLOBALS['ithemes_updater_path'] . '/updates.php' );
166
-
167
  Ithemes_Updater_Updates::run_update();
168
  }
169
-
170
  public function get_options() {
171
  $this->init();
172
-
173
  return $this->options;
174
  }
175
-
176
  public function get_option( $var ) {
177
  $this->init();
178
-
179
  if ( isset( $this->options[$var] ) ) {
180
  return $this->options[$var];
181
  }
182
-
183
  return null;
184
  }
185
-
186
  public function update_options( $updates ) {
187
  $this->init();
188
-
189
  $this->options = array_merge( $this->options, $updates );
190
  $this->options_modified = true;
191
  }
192
-
193
  public function update_packages() {
194
  $this->update_options( array( 'packages' => array_keys( $this->packages ) ) );
195
  }
196
-
197
  public function get_packages() {
198
  return $this->packages;
199
  }
200
-
201
  public function get_new_packages() {
202
  return $this->new_packages;
203
  }
204
-
205
  public function filter_update_plugins( $update_plugins ) {
206
  if ( ! is_object( $update_plugins ) ) {
207
  return $update_plugins;
208
  }
209
-
210
  if ( ! isset( $update_plugins->response ) || ! is_array( $update_plugins->response ) ) {
211
  $update_plugins->response = array();
212
  }
213
-
214
  $this->flush();
215
-
216
  if ( ! is_array( $this->options ) || ! isset( $this->options['update_plugins'] ) ) {
217
  $this->load();
218
  }
219
-
220
  if ( isset( $this->options['update_plugins'] ) && is_array( $this->options['update_plugins'] ) ) {
221
  if ( ! $this->plugins_cleaned ) {
222
  @include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
223
-
224
  if ( is_callable( 'get_plugin_data' ) ) {
225
  foreach ( $this->options['update_plugins'] as $plugin => $update_data ) {
 
 
 
 
226
  $plugin_data = get_plugin_data( WP_PLUGIN_DIR . "/$plugin", false, false );
227
-
228
  if ( $plugin_data['Version'] == $update_data->new_version ) {
229
  unset( $this->options['update_plugins'][$plugin] );
230
  $this->plugins_cleaned = true;
231
  }
232
  }
233
  }
234
-
235
  if ( $this->plugins_cleaned ) {
236
  $this->options_modified = true;
237
  }
238
-
239
  $this->plugins_cleaned = true;
240
  }
241
-
242
  $update_plugins->response = array_merge( $update_plugins->response, $this->options['update_plugins'] );
243
  }
244
-
245
  return $update_plugins;
246
  }
247
-
248
  public function filter_update_themes( $update_themes ) {
249
  if ( ! is_object( $update_themes ) ) {
250
  return $update_themes;
251
  }
252
-
253
  if ( ! isset( $update_themes->response ) || ! is_array( $update_themes->response ) ) {
254
  $update_themes->response = array();
255
  }
256
-
257
  $this->flush();
258
-
259
  if ( ! is_array( $this->options ) || ! isset( $this->options['update_themes'] ) ) {
260
  $this->load();
261
  }
262
-
263
  if ( isset( $this->options['update_themes'] ) && is_array( $this->options['update_themes'] ) ) {
264
  if ( ! $this->themes_cleaned ) {
265
  foreach ( $this->options['update_themes'] as $theme => $update_data ) {
266
  $theme_data = wp_get_theme( $theme );
267
-
268
- if ( $theme_data->get( 'Version' ) == $update_data['new_version'] ) {
269
  unset( $this->options['update_themes'][$theme] );
 
270
  $this->themes_cleaned = true;
271
  }
272
  }
273
-
274
  if ( $this->themes_cleaned ) {
275
  $this->options_modified = true;
276
  }
277
-
278
  $this->themes_cleaned = true;
279
  }
280
-
281
  $update_themes->response = array_merge( $update_themes->response, $this->options['update_themes'] );
282
  }
283
-
284
  return $update_themes;
285
  }
286
-
287
  public function register( $slug, $file ) {
288
  $this->packages[$slug][] = $file;
289
  }
290
-
291
  private function is_expired( $timestamp ) {
292
  $multiplier = $this->get_option( 'timeout-multiplier' );
293
-
294
  if ( $multiplier < 1 ) {
295
  $multiplier = 1;
296
  } else if ( $multiplier > 10 ) {
297
  $multiplier = 10;
298
  }
299
-
300
-
301
  if ( current_user_can( 'update_themes' ) || current_user_can( 'update_plugins' ) ) {
302
  if ( ! empty( $_POST['action'] ) && ( 'heartbeat' == $_POST['action'] ) ) {
303
  $timeout = 43200;
304
  } else {
305
  $page = empty( $_GET['page'] ) ? $GLOBALS['pagenow'] : $_GET['page'];
306
-
307
  switch ( $page ) {
308
  case 'update.php' :
309
  case 'update-core.php' :
@@ -321,14 +331,14 @@ class Ithemes_Updater_Settings {
321
  } else {
322
  $timeout = 7200;
323
  }
324
-
325
  $timeout *= $multiplier;
326
-
327
-
328
  if ( $timestamp <= ( time() - $timeout ) ) {
329
  return true;
330
  }
331
-
332
  return false;
333
  }
334
  }
30
 
31
  class Ithemes_Updater_Settings {
32
  private $option_name = 'ithemes-updater-cache';
33
+
34
  private $packages = array();
35
  private $new_packages = array();
36
  private $options = false;
39
  private $initialized = false;
40
  private $plugins_cleaned = false;
41
  private $themes_cleaned = false;
42
+ private $db_failure = false;
43
+
44
  private $default_options = array(
45
  'timeout-multiplier' => 1,
46
  'expiration' => 0,
52
  'use_ssl' => true,
53
  'quick_releases' => false,
54
  );
55
+
56
+
57
  public function __construct() {
58
  $GLOBALS['ithemes-updater-settings'] = $this;
59
+
60
  add_action( 'init', array( $this, 'init' ) );
61
+ add_action( 'shutdown', array( $this, 'shutdown' ), -10 );
62
  }
63
+
64
  public function init() {
65
  if ( $this->initialized ) {
66
  return;
67
  }
68
+
69
  $this->initialized = true;
70
+
71
  if ( ! isset( $GLOBALS['ithemes_updater_path'] ) ) {
72
  $GLOBALS['ithemes_updater_path'] = dirname( __FILE__ );
73
  }
74
+
75
  $this->load();
76
+
77
  do_action( 'ithemes_updater_register', $this );
78
+
79
  $this->new_packages = array_diff( array_keys( $this->packages ), $this->options['packages'] );
80
+
81
+
82
  if ( isset( $_GET['ithemes-updater-force-quick-release-update'] ) && ! isset( $_GET['ithemes-updater-force-minor-update'] ) ) {
83
  $_GET['ithemes-updater-force-minor-update'] = $_GET['ithemes-updater-force-quick-release-update'];
84
  }
85
+
86
+
87
  $flushed = false;
88
+
89
+
90
  if ( isset( $_GET['ithemes-updater-force-minor-update'] ) && current_user_can( 'manage_options' ) ) {
91
  if ( $_GET['ithemes-updater-force-minor-update'] ) {
92
  $this->options['force_minor_version_update'] = time() + 3600;
93
  $this->update_options( $this->options );
94
+
95
  $this->flush( 'forced minor version update' );
96
  $flushed = true;
97
  } else {
98
  unset( $this->options['force_minor_version_update'] );
99
  $this->update_options( $this->options );
100
+
101
  $this->flush( 'unset forced minor version update' );
102
  $flushed = true;
103
  }
105
  unset( $this->options['force_minor_version_update'] );
106
  $this->update_options( $this->options );
107
  }
108
+
109
+
110
  if ( ! $flushed ) {
111
  if ( ! empty( $_GET['ithemes-updater-force-refresh'] ) && current_user_can( 'manage_options' ) ) {
112
  $this->flush( 'forced' );
119
  }
120
  }
121
  }
122
+
123
  public function load() {
124
  if ( false !== $this->options ) {
125
  return;
126
  }
127
+
128
+ require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
129
+ $this->options = Ithemes_Updater_Functions::get_site_option( $this->option_name );
130
+
131
+ if ( false === $this->options ) {
132
+ $this->db_failure = true;
133
+ }
134
+ if ( ! is_array( $this->options ) ) {
135
  $this->options = array();
136
  }
137
+
138
  $this->options = array_merge( $this->default_options, $this->options );
139
+
140
  if ( 0 == $this->options['timestamp'] ) {
141
  $this->update();
142
  }
143
  }
144
+
145
  public function shutdown() {
146
  $this->flush();
147
+
148
+ if ( $this->options_modified && false === $this->db_failure ) {
149
  update_site_option( $this->option_name, $this->options );
150
  }
151
  }
152
+
153
  public function queue_flush() {
154
  $this->do_flush = true;
155
  }
156
+
157
  public function flush( $reason = '' ) {
158
  if ( empty( $reason ) && ! $this->do_flush ) {
159
  return;
160
  }
161
+
162
  $this->do_flush = false;
163
+
164
  $this->update();
165
  }
166
+
167
  public function update() {
168
  $this->init();
169
+
170
  require_once( $GLOBALS['ithemes_updater_path'] . '/updates.php' );
171
+
172
  Ithemes_Updater_Updates::run_update();
173
  }
174
+
175
  public function get_options() {
176
  $this->init();
177
+
178
  return $this->options;
179
  }
180
+
181
  public function get_option( $var ) {
182
  $this->init();
183
+
184
  if ( isset( $this->options[$var] ) ) {
185
  return $this->options[$var];
186
  }
187
+
188
  return null;
189
  }
190
+
191
  public function update_options( $updates ) {
192
  $this->init();
193
+
194
  $this->options = array_merge( $this->options, $updates );
195
  $this->options_modified = true;
196
  }
197
+
198
  public function update_packages() {
199
  $this->update_options( array( 'packages' => array_keys( $this->packages ) ) );
200
  }
201
+
202
  public function get_packages() {
203
  return $this->packages;
204
  }
205
+
206
  public function get_new_packages() {
207
  return $this->new_packages;
208
  }
209
+
210
  public function filter_update_plugins( $update_plugins ) {
211
  if ( ! is_object( $update_plugins ) ) {
212
  return $update_plugins;
213
  }
214
+
215
  if ( ! isset( $update_plugins->response ) || ! is_array( $update_plugins->response ) ) {
216
  $update_plugins->response = array();
217
  }
218
+
219
  $this->flush();
220
+
221
  if ( ! is_array( $this->options ) || ! isset( $this->options['update_plugins'] ) ) {
222
  $this->load();
223
  }
224
+
225
  if ( isset( $this->options['update_plugins'] ) && is_array( $this->options['update_plugins'] ) ) {
226
  if ( ! $this->plugins_cleaned ) {
227
  @include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
228
+
229
  if ( is_callable( 'get_plugin_data' ) ) {
230
  foreach ( $this->options['update_plugins'] as $plugin => $update_data ) {
231
+ if ( ! is_file( WP_PLUGIN_DIR . "/$plugin" ) ) {
232
+ continue;
233
+ }
234
+
235
  $plugin_data = get_plugin_data( WP_PLUGIN_DIR . "/$plugin", false, false );
236
+
237
  if ( $plugin_data['Version'] == $update_data->new_version ) {
238
  unset( $this->options['update_plugins'][$plugin] );
239
  $this->plugins_cleaned = true;
240
  }
241
  }
242
  }
243
+
244
  if ( $this->plugins_cleaned ) {
245
  $this->options_modified = true;
246
  }
247
+
248
  $this->plugins_cleaned = true;
249
  }
250
+
251
  $update_plugins->response = array_merge( $update_plugins->response, $this->options['update_plugins'] );
252
  }
253
+
254
  return $update_plugins;
255
  }
256
+
257
  public function filter_update_themes( $update_themes ) {
258
  if ( ! is_object( $update_themes ) ) {
259
  return $update_themes;
260
  }
261
+
262
  if ( ! isset( $update_themes->response ) || ! is_array( $update_themes->response ) ) {
263
  $update_themes->response = array();
264
  }
265
+
266
  $this->flush();
267
+
268
  if ( ! is_array( $this->options ) || ! isset( $this->options['update_themes'] ) ) {
269
  $this->load();
270
  }
271
+
272
  if ( isset( $this->options['update_themes'] ) && is_array( $this->options['update_themes'] ) ) {
273
  if ( ! $this->themes_cleaned ) {
274
  foreach ( $this->options['update_themes'] as $theme => $update_data ) {
275
  $theme_data = wp_get_theme( $theme );
276
+
277
+ if ( $theme_data->get( 'Version' ) === $update_data['new_version'] ) {
278
  unset( $this->options['update_themes'][$theme] );
279
+
280
  $this->themes_cleaned = true;
281
  }
282
  }
283
+
284
  if ( $this->themes_cleaned ) {
285
  $this->options_modified = true;
286
  }
287
+
288
  $this->themes_cleaned = true;
289
  }
290
+
291
  $update_themes->response = array_merge( $update_themes->response, $this->options['update_themes'] );
292
  }
293
+
294
  return $update_themes;
295
  }
296
+
297
  public function register( $slug, $file ) {
298
  $this->packages[$slug][] = $file;
299
  }
300
+
301
  private function is_expired( $timestamp ) {
302
  $multiplier = $this->get_option( 'timeout-multiplier' );
303
+
304
  if ( $multiplier < 1 ) {
305
  $multiplier = 1;
306
  } else if ( $multiplier > 10 ) {
307
  $multiplier = 10;
308
  }
309
+
310
+
311
  if ( current_user_can( 'update_themes' ) || current_user_can( 'update_plugins' ) ) {
312
  if ( ! empty( $_POST['action'] ) && ( 'heartbeat' == $_POST['action'] ) ) {
313
  $timeout = 43200;
314
  } else {
315
  $page = empty( $_GET['page'] ) ? $GLOBALS['pagenow'] : $_GET['page'];
316
+
317
  switch ( $page ) {
318
  case 'update.php' :
319
  case 'update-core.php' :
331
  } else {
332
  $timeout = 7200;
333
  }
334
+
335
  $timeout *= $multiplier;
336
+
337
+
338
  if ( $timestamp <= ( time() - $timeout ) ) {
339
  return true;
340
  }
341
+
342
  return false;
343
  }
344
  }
lib/updater/updates.php CHANGED
@@ -37,35 +37,36 @@ class Ithemes_Updater_Updates {
37
  if ( ! isset( $GLOBALS['ithemes_updater_path'] ) ) {
38
  return;
39
  }
40
-
41
  require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
42
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
43
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
44
-
45
-
46
  $keys = Ithemes_Updater_Keys::get();
47
  $legacy_keys = Ithemes_Updater_Keys::get_legacy();
48
-
49
  if ( empty( $keys ) && empty( $legacy_keys ) ) {
50
  return;
51
  }
52
-
53
-
54
  Ithemes_Updater_API::get_package_details( false );
55
  }
56
-
57
  public static function process_server_response( $response, $cached = false ) {
58
  if ( empty( $response['packages'] ) ) {
59
  return;
60
  }
61
-
62
-
63
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
64
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
65
-
66
-
 
67
  $keys = array();
68
-
69
  foreach ( $response['packages'] as $package => $data ) {
70
  if ( isset( $data['key'] ) ) {
71
  $keys[$package] = $data['key'];
@@ -73,53 +74,53 @@ class Ithemes_Updater_Updates {
73
  $keys[$package] = '';
74
  }
75
  }
76
-
77
  Ithemes_Updater_Keys::set( $keys );
78
-
79
-
80
  $details = Ithemes_Updater_Packages::get_full_details( $response );
81
-
82
  $updates = array(
83
  'update_themes' => array(),
84
  'update_plugins' => array(),
85
  'expiration' => $details['expiration'],
86
  );
87
-
88
  if ( ! $cached ) {
89
  $updates['timestamp'] = time();
90
  }
91
-
92
-
93
  if ( isset( $response['timeout_multiplier'] ) ) {
94
  $updates['timeout-multiplier'] = $response['timeout_multiplier'];
95
  }
96
-
97
  if ( ! isset( $updates['timeout-multiplier'] ) || ( $updates['timeout-multiplier'] < 1 ) ) {
98
  $updates['timeout-mulitplier'] = 1;
99
  } else if ( $updates['timeout-multiplier'] > 10 ) {
100
  $updates['timeout-mulitplier'] = 10;
101
  }
102
-
103
  $use_ssl = $GLOBALS['ithemes-updater-settings']->get_option( 'use_ssl' );
104
-
105
-
106
  foreach ( $details['packages'] as $path => $data ) {
107
  if ( empty( $data['package-url'] ) || version_compare( $data['installed'], $data['available'], '>=' ) ) {
108
  continue;
109
  }
110
-
111
-
112
  $force_minor_version_update = $GLOBALS['ithemes-updater-settings']->get_option( 'force_minor_version_update' );
113
  $quick_releases = $GLOBALS['ithemes-updater-settings']->get_option( 'quick_releases' );
114
-
115
  if ( ( isset( $data['upgrade'] ) && ! $data['upgrade'] ) && ! $force_minor_version_update && ! $quick_releases ) {
116
  continue;
117
  }
118
-
119
  if ( ! $use_ssl ) {
120
  $data['package-url'] = preg_replace( '/^https/', 'http', $data['package-url'] );
121
  }
122
-
123
  if ( 'plugin' == $data['type'] ) {
124
  $update = array(
125
  'id' => 0,
@@ -129,14 +130,14 @@ class Ithemes_Updater_Updates {
129
  'url' => $data['info-url'],
130
  'package' => $data['package-url'],
131
  );
132
-
133
  if ( isset( $data['autoupdate'] ) ) {
134
  $update['autoupdate'] = $data['autoupdate'];
135
  }
136
  if ( isset( $data['upgrade_notice'] ) ) {
137
  $update['upgrade_notice'] = $data['upgrade_notice'];
138
  }
139
-
140
  $update = (object) $update;
141
  }
142
  else {
@@ -146,21 +147,21 @@ class Ithemes_Updater_Updates {
146
  'url' => self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . dirname( $path ) . '&section=changelog&TB_iframe=true&width=600&height=800' ),
147
  'package' => $data['package-url'],
148
  );
149
-
150
  if ( isset( $data['autoupdate'] ) ) {
151
  $update['autoupdate'] = $data['autoupdate'];
152
  }
153
  if ( isset( $data['upgrade_notice'] ) ) {
154
  $update['upgrade_notice'] = $data['upgrade_notice'];
155
  }
156
-
157
  $path = dirname( $path );
158
  }
159
-
160
  $updates["update_{$data['type']}s"][$path] = $update;
161
  }
162
-
163
-
164
  $GLOBALS['ithemes-updater-settings']->update_options( $updates );
165
  }
166
  }
37
  if ( ! isset( $GLOBALS['ithemes_updater_path'] ) ) {
38
  return;
39
  }
40
+
41
  require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
42
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
43
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
44
+
45
+
46
  $keys = Ithemes_Updater_Keys::get();
47
  $legacy_keys = Ithemes_Updater_Keys::get_legacy();
48
+
49
  if ( empty( $keys ) && empty( $legacy_keys ) ) {
50
  return;
51
  }
52
+
53
+
54
  Ithemes_Updater_API::get_package_details( false );
55
  }
56
+
57
  public static function process_server_response( $response, $cached = false ) {
58
  if ( empty( $response['packages'] ) ) {
59
  return;
60
  }
61
+
62
+
63
  require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
64
  require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
65
+ require_once( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
66
+
67
+
68
  $keys = array();
69
+
70
  foreach ( $response['packages'] as $package => $data ) {
71
  if ( isset( $data['key'] ) ) {
72
  $keys[$package] = $data['key'];
74
  $keys[$package] = '';
75
  }
76
  }
77
+
78
  Ithemes_Updater_Keys::set( $keys );
79
+
80
+
81
  $details = Ithemes_Updater_Packages::get_full_details( $response );
82
+
83
  $updates = array(
84
  'update_themes' => array(),
85
  'update_plugins' => array(),
86
  'expiration' => $details['expiration'],
87
  );
88
+
89
  if ( ! $cached ) {
90
  $updates['timestamp'] = time();
91
  }
92
+
93
+
94
  if ( isset( $response['timeout_multiplier'] ) ) {
95
  $updates['timeout-multiplier'] = $response['timeout_multiplier'];
96
  }
97
+
98
  if ( ! isset( $updates['timeout-multiplier'] ) || ( $updates['timeout-multiplier'] < 1 ) ) {
99
  $updates['timeout-mulitplier'] = 1;
100
  } else if ( $updates['timeout-multiplier'] > 10 ) {
101
  $updates['timeout-mulitplier'] = 10;
102
  }
103
+
104
  $use_ssl = $GLOBALS['ithemes-updater-settings']->get_option( 'use_ssl' );
105
+
106
+
107
  foreach ( $details['packages'] as $path => $data ) {
108
  if ( empty( $data['package-url'] ) || version_compare( $data['installed'], $data['available'], '>=' ) ) {
109
  continue;
110
  }
111
+
112
+
113
  $force_minor_version_update = $GLOBALS['ithemes-updater-settings']->get_option( 'force_minor_version_update' );
114
  $quick_releases = $GLOBALS['ithemes-updater-settings']->get_option( 'quick_releases' );
115
+
116
  if ( ( isset( $data['upgrade'] ) && ! $data['upgrade'] ) && ! $force_minor_version_update && ! $quick_releases ) {
117
  continue;
118
  }
119
+
120
  if ( ! $use_ssl ) {
121
  $data['package-url'] = preg_replace( '/^https/', 'http', $data['package-url'] );
122
  }
123
+
124
  if ( 'plugin' == $data['type'] ) {
125
  $update = array(
126
  'id' => 0,
130
  'url' => $data['info-url'],
131
  'package' => $data['package-url'],
132
  );
133
+
134
  if ( isset( $data['autoupdate'] ) ) {
135
  $update['autoupdate'] = $data['autoupdate'];
136
  }
137
  if ( isset( $data['upgrade_notice'] ) ) {
138
  $update['upgrade_notice'] = $data['upgrade_notice'];
139
  }
140
+
141
  $update = (object) $update;
142
  }
143
  else {
147
  'url' => self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . dirname( $path ) . '&section=changelog&TB_iframe=true&width=600&height=800' ),
148
  'package' => $data['package-url'],
149
  );
150
+
151
  if ( isset( $data['autoupdate'] ) ) {
152
  $update['autoupdate'] = $data['autoupdate'];
153
  }
154
  if ( isset( $data['upgrade_notice'] ) ) {
155
  $update['upgrade_notice'] = $data['upgrade_notice'];
156
  }
157
+
158
  $path = dirname( $path );
159
  }
160
+
161
  $updates["update_{$data['type']}s"][$path] = $update;
162
  }
163
+
164
+
165
  $GLOBALS['ithemes-updater-settings']->update_options( $updates );
166
  }
167
  }
lib/updater/wp-cli.php ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Manage licensing of iThemes plugins and themes.
5
+ */
6
+ final class Ithemes_Updater_WP_CLI_Ithemes_Licensing extends WP_CLI_Command {
7
+ /**
8
+ * Show iThemes plugins and themes on the site and the licensing status for each.
9
+ *
10
+ * ## OPTIONS
11
+ *
12
+ * [<product>]
13
+ * : Only show the status for the supplied product.
14
+ *
15
+ * [--verbose]
16
+ * : Show increased detail about each product.
17
+ *
18
+ * [--status=<status>]
19
+ * : Limit the list to products with a specific licensing status.
20
+ * ---
21
+ * default: all
22
+ * options:
23
+ * - all
24
+ * - active
25
+ * - inactive
26
+ *
27
+ * [--format=<format>]
28
+ * : Output formatting
29
+ * ---
30
+ * default: table
31
+ * options:
32
+ * - table
33
+ * - json
34
+ * - csv
35
+ * - yaml
36
+ * - count
37
+ *
38
+ * @param array $args
39
+ * @param array $assoc_args
40
+ */
41
+ public function show( $args, $assoc_args ) {
42
+ $this->verify_updater_is_present();
43
+
44
+ require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
45
+
46
+ if ( ! empty( $args ) ) {
47
+ list( $product ) = $args;
48
+ } else {
49
+ $product = null;
50
+ }
51
+
52
+ $default_args = array(
53
+ 'verbose' => false,
54
+ 'status' => 'all',
55
+ 'format' => 'table',
56
+ );
57
+
58
+ $assoc_args = wp_parse_args( $assoc_args, $default_args );
59
+ $package_details = Ithemes_Updater_API::get_package_details();
60
+
61
+ if ( is_wp_error( $package_details ) ) {
62
+ WP_CLI::error( sprintf( 'Unable to retrieve product details: %1$s (%2$s)', $package_details->get_error_message(), $package_details->get_error_code() ) );
63
+ return;
64
+ }
65
+
66
+ ksort( $package_details['packages'] );
67
+ $packages = array();
68
+
69
+ foreach ( $package_details['packages'] as $name => $details ) {
70
+ if ( ! is_null( $product ) && $name !== $product ) {
71
+ continue;
72
+ }
73
+
74
+ if ( ! isset( $details['status'] ) ) {
75
+ $details['status'] = 'inactive';
76
+ }
77
+
78
+ if ( 'all' !== $assoc_args['status'] && $details['status'] !== $assoc_args['status'] ) {
79
+ continue;
80
+ }
81
+
82
+ $package = array(
83
+ 'name' => $name,
84
+ 'status' => isset( $details['status'] ) ? $details['status'] : 'inactive',
85
+ );
86
+
87
+ if ( $assoc_args['verbose'] ) {
88
+ $package = array_merge( $package, $details );
89
+ }
90
+
91
+ $packages[] = $package;
92
+ }
93
+
94
+ if ( ! empty( $packages ) ) {
95
+ if ( $assoc_args['verbose'] ) {
96
+ $columns = array(
97
+ 'name',
98
+ 'status',
99
+ 'used',
100
+ 'total',
101
+ 'ver',
102
+ 'user',
103
+ 'sub_expire',
104
+ 'release_timestamp',
105
+ 'upgrade',
106
+ 'link_expire',
107
+ 'link',
108
+ 'key',
109
+ 'error',
110
+ );
111
+ } else {
112
+ $columns = array(
113
+ 'name',
114
+ 'status',
115
+ );
116
+ }
117
+
118
+ foreach ( $packages as &$package ) {
119
+ foreach ( $columns as $column ) {
120
+ if ( ! isset( $package[$column] ) ) {
121
+ $package[$column] = '';
122
+ }
123
+ }
124
+ }
125
+
126
+ WP_CLI\Utils\format_items( $assoc_args['format'], $packages, $columns );
127
+ } else if ( $assoc_args['verbose'] ) {
128
+ WP_CLI::error( 'No iThemes products were found matching the current criteria.' );
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Activate licensing for one or more products
134
+ *
135
+ * ## OPTIONS
136
+ *
137
+ * Specificy the iThemes account username and password using the environment variables ITHEMES_USER and ITHEMES_PASS
138
+ *
139
+ * [<product>...]
140
+ * : Product to activate licensing for.
141
+ *
142
+ * [--ithemes-user=<user>]
143
+ * : iThemes member username. This value can also be supplied by an ITHEMES_USER environment variable.
144
+ *
145
+ * [--ithemes-pass=<pass>]
146
+ * : iThemes member password. This value can also be supplied by an ITHEMES_PASS environment variable.
147
+ *
148
+ * [--all]
149
+ * : Activate licensing for all currently installed, inactive products.
150
+ *
151
+ * ## EXAMPLES
152
+ *
153
+ * # Activate licensing for the ithemes-security-pro plugin.
154
+ * $ wp ithemes-licensing activate ithemes-security-pro --ithemes-user=example --ithemes-pass=example
155
+ *
156
+ * # Activate licensing for all installed iThemes products using environment variables for member details.
157
+ * $ ITHEMES_USER=example ITHEMES_PASS=example wp ithemes-licensing activate --all
158
+ *
159
+ * @param array $args
160
+ * @param array $assoc_args
161
+ */
162
+ public function activate( $args, $assoc_args ) {
163
+ $this->handle_request( 'activate', $args, $assoc_args );
164
+ }
165
+
166
+ /**
167
+ * Deactivate licensing for one or more products
168
+ *
169
+ * ## OPTIONS
170
+ *
171
+ * Specificy the iThemes account username and password using the environment variables ITHEMES_USER and ITHEMES_PASS
172
+ *
173
+ * [<product>...]
174
+ * : Product to deactivate licensing for.
175
+ *
176
+ * [--ithemes-user=<user>]
177
+ * : iThemes member username. This value can also be supplied by an ITHEMES_USER environment variable.
178
+ *
179
+ * [--ithemes-pass=<pass>]
180
+ * : iThemes member password. This value can also be supplied by an ITHEMES_PASS environment variable.
181
+ *
182
+ * [--all]
183
+ * : Deactivate licensing for all currently installed, active products.
184
+ *
185
+ * ## EXAMPLES
186
+ *
187
+ * # Deactivate licensing for the ithemes-security-pro plugin.
188
+ * $ wp ithemes-licensing deactivate ithemes-security-pro --ithemes-user=example --ithemes-pass=example
189
+ *
190
+ * # Deactivate licensing for all installed iThemes products using environment variables for member details.
191
+ * $ ITHEMES_USER=example ITHEMES_PASS=example wp ithemes-licensing deactivate --all
192
+ *
193
+ * @param array $args
194
+ * @param array $assoc_args
195
+ */
196
+ public function deactivate( $args, $assoc_args ) {
197
+ $this->handle_request( 'deactivate', $args, $assoc_args );
198
+ }
199
+
200
+ private function handle_request( $verb, $args, $assoc_args ) {
201
+ $this->verify_updater_is_present();
202
+
203
+ require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
204
+ require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
205
+
206
+ $products = $args;
207
+
208
+ $default_args = array(
209
+ 'all' => false,
210
+ );
211
+
212
+ $assoc_args = wp_parse_args( $assoc_args, $default_args );
213
+ $user = getenv( 'ITHEMES_USER' );
214
+ $pass = getenv( 'ITHEMES_PASS' );
215
+
216
+ if ( isset( $assoc_args['ithemes-user'] ) ) {
217
+ $user = $assoc_args['ithemes-user'];
218
+ }
219
+ if ( isset( $assoc_args['ithemes-pass'] ) ) {
220
+ $pass = $assoc_args['ithemes-pass'];
221
+ }
222
+
223
+ if ( empty( $user ) ) {
224
+ WP_CLI::error( 'You must supply the iThemes member username.' );
225
+ return;
226
+ }
227
+ if ( empty( $pass ) ) {
228
+ WP_CLI::error( 'You must supply the iThemes member password.' );
229
+ return;
230
+ }
231
+
232
+ if ( empty( $products ) && ! $assoc_args['all'] ) {
233
+ WP_CLI::error( "You must supply one or more products or use the --all flag." );
234
+ return;
235
+ } else if ( ! empty( $products ) && $assoc_args['all'] ) {
236
+ WP_CLI::error( 'You must supply one or more products or use the --all flag, but not both.' );
237
+ return;
238
+ }
239
+
240
+
241
+ $package_details = Ithemes_Updater_API::get_package_details();
242
+
243
+ if ( $assoc_args['all'] ) {
244
+ if ( is_wp_error( $package_details ) ) {
245
+ WP_CLI::error( sprintf( 'Unable to retrieve product details: %1$s (%2$s)', $package_details->get_error_message(), $package_details->get_error_code() ) );
246
+ return;
247
+ }
248
+
249
+ $products = array();
250
+
251
+ foreach ( $package_details['packages'] as $name => $details ) {
252
+ if ( 'activate' === $verb xor ( isset( $details['status'] ) && 'active' === $details['status'] ) ) {
253
+ $products[] = $name;
254
+ }
255
+ }
256
+
257
+ if ( empty( $products ) ) {
258
+ if ( 'activate' === $verb ) {
259
+ WP_CLI::success( 'No products with inactive licensing were found.' );
260
+ } else {
261
+ WP_CLI::success( 'No products with active licensing were found.' );
262
+ }
263
+
264
+ return;
265
+ }
266
+ } else {
267
+ foreach ( $products as $index => $product ) {
268
+ if ( ! isset( $package_details['packages'][$product] ) ) {
269
+ WP_CLI::error( "$product is not a valid iThemes product. Licensing for it cannot be {$verb}d." );
270
+ unset( $products[$index] );
271
+ }
272
+ }
273
+
274
+ if ( empty( $products ) ) {
275
+ return;
276
+ }
277
+ }
278
+
279
+ if ( 'activate' === $verb ) {
280
+ $response = Ithemes_Updater_API::activate_package( $user, $pass, $products );
281
+ } else {
282
+ $response = Ithemes_Updater_API::deactivate_package( $user, $pass, $products );
283
+ }
284
+
285
+ if ( is_wp_error( $response ) ) {
286
+ WP_CLI::error( Ithemes_Updater_API::get_error_explanation( $response ) );
287
+ return;
288
+ }
289
+
290
+ if ( empty( $response['packages'] ) ) {
291
+ if ( 1 === count( $products ) ) {
292
+ WP_CLI::error( "An unknown server error occurred. Please try to $verb your product license again at another time." );
293
+ } else {
294
+ WP_CLI::error( "An unknown server error occurred. Please try to $verb your product licenses again at another time." );
295
+ }
296
+
297
+ return;
298
+ }
299
+
300
+
301
+ uksort( $response['packages'], 'strnatcasecmp' );
302
+
303
+ foreach ( $response['packages'] as $package => $data ) {
304
+ if ( preg_match( '/ \|\|\| \d+$/', $package ) ) {
305
+ continue;
306
+ }
307
+
308
+ if ( 'activate' === $verb ) {
309
+ if ( ! empty( $data['key'] ) ) {
310
+ WP_CLI::success( "Activated the product license for $package." );
311
+ } else if ( ! empty( $data['status'] ) && ( 'expired' === $data['status'] ) ) {
312
+ WP_CLI::warning( "Unable to activate the product license for $package. Your product subscription has expired." );
313
+ } else {
314
+ WP_CLI::error( "Unable to activate the product license for $package. {$data['error']['message']}" );
315
+ }
316
+ } else {
317
+ if ( isset( $data['status'] ) && ( 'inactive' == $data['status'] ) ) {
318
+ WP_CLI::success( "Deactivated the product license for $package." );
319
+ } else if ( isset( $data['error'] ) && isset( $data['error']['message'] ) ) {
320
+ WP_CLI::error( "Unable to deactivate the product license for $package. {$data['error']['message']}" );
321
+ } else {
322
+ WP_CLI::error( "Unable to deactivate the product license for $package. Unknown server error." );
323
+ }
324
+ }
325
+ }
326
+ }
327
+
328
+ private function verify_updater_is_present() {
329
+ if ( empty( $GLOBALS['ithemes_updater_path'] ) ) {
330
+ if ( defined( 'ITHEMES_UPDATER_DISABLE' ) && ITHEMES_UPDATER_DISABLE ) {
331
+ WP_CLI::error( 'The iThemes updater library is disabled on this site due to the ITHEMES_UPDATER_DISABLE define being set to a truthy value. Licensing for this site cannot be managed.' );
332
+ } else {
333
+ WP_CLI::error( 'The $GLOBALS[\'ithemes_updater_path\'] variable is empty or not set. This indicates that the updater was not loaded although the cause for this is not known.' );
334
+ }
335
+
336
+ exit;
337
+ }
338
+ }
339
+ }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: ithemes, layotte, blepoxp
3
  Tags: manage multiple Sites, backup, security, migrate, SEO, manage updates, administration, update manager, reports, sync, google analytics, optimize, uptime, ithemes, customize dashboard, client sites, maintenance, management, google webmaster tools, reporting
4
  Requires at least: 4.5
5
  Tested up to: 4.10
6
- Stable tag: 2.0.12
7
  License: GPLv3 or later
8
  License URI: http://www.gnu.org/licenses/quick-guide-gplv3.html
9
 
@@ -86,6 +86,15 @@ Make steady, reliable income for WordPress maintenance with iThemes Sync Pro’s
86
 
87
  == Changelog ==
88
 
 
 
 
 
 
 
 
 
 
89
  = 2.0.12 =
90
  * Enhancement: Add check for Yoast SEO Premium plugin for Yoast SEO functionality
91
 
3
  Tags: manage multiple Sites, backup, security, migrate, SEO, manage updates, administration, update manager, reports, sync, google analytics, optimize, uptime, ithemes, customize dashboard, client sites, maintenance, management, google webmaster tools, reporting
4
  Requires at least: 4.5
5
  Tested up to: 4.10
6
+ Stable tag: 2.0.15
7
  License: GPLv3 or later
8
  License URI: http://www.gnu.org/licenses/quick-guide-gplv3.html
9
 
86
 
87
  == Changelog ==
88
 
89
+ = 2.0.15 =
90
+ * Bug Fix: PHP7.1/7.2's implemention of serialize precision causes json_encode to float version numbers like 5.1 as 5.0999999999996, which disrupts our hashing algorithm.
91
+
92
+ = 2.0.14 =
93
+ * Enhancemet: Added silent mode hooks
94
+
95
+ = 2.0.13 =
96
+ * Enhancment: Updater improvements
97
+
98
  = 2.0.12 =
99
  * Enhancement: Add check for Yoast SEO Premium plugin for Yoast SEO functionality
100
 
request-handler.php CHANGED
@@ -450,15 +450,22 @@ class Ithemes_Sync_Request_Handler {
450
  }
451
 
452
  private function json_encode( $data ) {
453
- $json = json_encode( $data );
454
 
455
- if ( false !== $json ) {
456
- return $json;
 
457
  }
 
 
458
 
459
- require_once( $GLOBALS['ithemes_sync_path'] . '/class-ithemes-sync-json.php' );
 
 
 
460
 
461
- return Ithemes_Sync_JSON::encode( $data );
 
 
462
  }
463
  }
464
 
450
  }
451
 
452
  private function json_encode( $data ) {
 
453
 
454
+ $serialize_precision = ini_get( 'serialize_precision' );
455
+ if ( version_compare( phpversion(), '7.1', '>=' ) ) {
456
+ ini_set( 'serialize_precision', -1 );
457
  }
458
+
459
+ $json = json_encode( $data );
460
 
461
+ if ( false === $json ) {
462
+ require_once( $GLOBALS['ithemes_sync_path'] . '/class-ithemes-sync-json.php' );
463
+ $json = Ithemes_Sync_JSON::encode( $data );
464
+ }
465
 
466
+ ini_set( 'serialize_precision', $serialize_precision );
467
+
468
+ return $json;
469
  }
470
  }
471