iThemes Sync - Version 2.0.2

Version Description

Download this release

Release Info

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

Code changes from version 2.0.1 to 2.0.2

Files changed (110) hide show
  1. history.txt +2 -0
  2. init.php +1 -1
  3. lang/ithemes-sync.pot +3 -3
  4. readme.txt +129 -16
  5. trunk/admin.php +0 -233
  6. trunk/api.php +0 -274
  7. trunk/api.txt +0 -60
  8. trunk/ca/index.php +0 -1
  9. trunk/ca/roots.crt +0 -58
  10. trunk/class-ithemes-credentials.php +0 -143
  11. trunk/class-ithemes-sync-json.php +0 -64
  12. trunk/class-ithemes-sync-utf8-encoder.php +0 -343
  13. trunk/client-dashboard.php +0 -413
  14. trunk/css/admin-notice.css +0 -53
  15. trunk/css/client-dashboard.css +0 -147
  16. trunk/css/index.php +0 -1
  17. trunk/css/settings-page.css +0 -195
  18. trunk/css/social-metabox.css +0 -52
  19. trunk/duplicator.php +0 -127
  20. trunk/functions.php +0 -1011
  21. trunk/history.txt +0 -186
  22. trunk/images/index.php +0 -1
  23. trunk/index.php +0 -1
  24. trunk/init.php +0 -54
  25. trunk/js/admin-notice.js +0 -25
  26. trunk/js/index.php +0 -1
  27. trunk/js/settings-page.js +0 -10
  28. trunk/js/social-metabox.js +0 -49
  29. trunk/lang/index.php +0 -1
  30. trunk/lang/ithemes-sync.pot +0 -620
  31. trunk/lib/index.php +0 -1
  32. trunk/lib/updater/admin.php +0 -215
  33. trunk/lib/updater/api.php +0 -301
  34. trunk/lib/updater/api.txt +0 -40
  35. trunk/lib/updater/ca/index.php +0 -1
  36. trunk/lib/updater/ca/roots.crt +0 -58
  37. trunk/lib/updater/class-ithemes-credentials.php +0 -143
  38. trunk/lib/updater/css/index.php +0 -1
  39. trunk/lib/updater/css/settings-page.css +0 -67
  40. trunk/lib/updater/functions.php +0 -61
  41. trunk/lib/updater/history.txt +0 -38
  42. trunk/lib/updater/images/index.php +0 -1
  43. trunk/lib/updater/index.php +0 -1
  44. trunk/lib/updater/information.php +0 -56
  45. trunk/lib/updater/init.php +0 -54
  46. trunk/lib/updater/keys.php +0 -165
  47. trunk/lib/updater/load.php +0 -54
  48. trunk/lib/updater/packages.php +0 -223
  49. trunk/lib/updater/server.php +0 -217
  50. trunk/lib/updater/settings-page.php +0 -659
  51. trunk/lib/updater/settings.php +0 -336
  52. trunk/lib/updater/updates.php +0 -166
  53. trunk/load-translations.php +0 -21
  54. trunk/load.php +0 -188
  55. trunk/notice-handler.php +0 -106
  56. trunk/notices.php +0 -187
  57. trunk/readme.txt +0 -37
  58. trunk/request-handler.php +0 -459
  59. trunk/server.php +0 -239
  60. trunk/settings-page.php +0 -349
  61. trunk/settings.php +0 -211
  62. trunk/social.php +0 -167
  63. trunk/uninstall.php +0 -22
  64. trunk/upgrader-skin.php +0 -23
  65. trunk/verbs/db-optimization.php +0 -388
  66. trunk/verbs/deauthenticate-user.php +0 -36
  67. trunk/verbs/do-update.php +0 -326
  68. trunk/verbs/get-admin-bar-item-whitelist.php +0 -32
  69. trunk/verbs/get-admin-bar-items.php +0 -32
  70. trunk/verbs/get-admin-menu.php +0 -22
  71. trunk/verbs/get-authentication-token.php +0 -53
  72. trunk/verbs/get-comment-details.php +0 -173
  73. trunk/verbs/get-dashboard-widgets.php +0 -22
  74. trunk/verbs/get-gf-form-entries.php +0 -64
  75. trunk/verbs/get-gf-forms.php +0 -25
  76. trunk/verbs/get-notices.php +0 -40
  77. trunk/verbs/get-options.php +0 -73
  78. trunk/verbs/get-php-details.php +0 -30
  79. trunk/verbs/get-plugin-details.php +0 -30
  80. trunk/verbs/get-post-types.php +0 -29
  81. trunk/verbs/get-posts.php +0 -84
  82. trunk/verbs/get-role-details.php +0 -40
  83. trunk/verbs/get-server-details.php +0 -30
  84. trunk/verbs/get-status-elements.php +0 -28
  85. trunk/verbs/get-status.php +0 -79
  86. trunk/verbs/get-supported-verbs.php +0 -32
  87. trunk/verbs/get-sync-settings.php +0 -30
  88. trunk/verbs/get-theme-details.php +0 -30
  89. trunk/verbs/get-update-details.php +0 -30
  90. trunk/verbs/get-updates.php +0 -32
  91. trunk/verbs/get-user-details.php +0 -52
  92. trunk/verbs/get-wordpress-details.php +0 -30
  93. trunk/verbs/get-wordpress-settings.php +0 -248
  94. trunk/verbs/get-wordpress-users.php +0 -31
  95. trunk/verbs/get-yoast-seo-summary.php +0 -27
  96. trunk/verbs/index.php +0 -1
  97. trunk/verbs/manage-comments.php +0 -344
  98. trunk/verbs/manage-ithemes-licenses.php +0 -111
  99. trunk/verbs/manage-options.php +0 -75
  100. trunk/verbs/manage-plugins.php +0 -215
  101. trunk/verbs/manage-posts.php +0 -136
  102. trunk/verbs/manage-reports.php +0 -107
  103. trunk/verbs/manage-roles.php +0 -100
  104. trunk/verbs/manage-themes.php +0 -189
  105. trunk/verbs/manage-users.php +0 -120
  106. trunk/verbs/set-admin-bar-item-whitelist.php +0 -40
  107. trunk/verbs/update-google-site-verification-token.php +0 -23
  108. trunk/verbs/update-show-sync.php +0 -38
  109. trunk/verbs/verb.php +0 -30
  110. verbs/get-authentication-token.php +2 -1
history.txt CHANGED
@@ -182,3 +182,5 @@
182
  Enhancement: Add ability to read and set most options found Settings pages.
183
  2.0.0 - 2017-06-01 - Lew Ayotte
184
  Initial release to WordPress.org
 
 
182
  Enhancement: Add ability to read and set most options found Settings pages.
183
  2.0.0 - 2017-06-01 - Lew Ayotte
184
  Initial release to WordPress.org
185
+ 2.0.1 - 2017-06-21 - Lew Ayotte
186
+ Bug Fix: Adding code to get-authentication-token verb to set the scheme to https by default if it should be
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.0
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.1
8
  Author URI: http://ithemes.com/
9
  Domain Path: /lang/
10
  iThemes Package: ithemes-sync
lang/ithemes-sync.pot CHANGED
@@ -2,9 +2,9 @@
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.0\n"
6
  "Report-Msgid-Bugs-To: http://ithemes.com/support/\n"
7
- "POT-Creation-Date: 2017-06-01 20:02:57+00:00\n"
8
  "PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
@@ -35,7 +35,7 @@ msgstr ""
35
  msgid "iThemes Sync is now hidden from your user again."
36
  msgstr ""
37
 
38
- #. #-#-#-#-# ithemes-sync.pot (iThemes Sync 2.0.0) #-#-#-#-#
39
  #. Plugin Name of the plugin/theme
40
  #: admin.php:168 admin.php:174 settings-page.php:268
41
  msgid "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.1\n"
6
  "Report-Msgid-Bugs-To: http://ithemes.com/support/\n"
7
+ "POT-Creation-Date: 2017-06-21 12:49:59+00:00\n"
8
  "PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
35
  msgid "iThemes Sync is now hidden from your user again."
36
  msgstr ""
37
 
38
+ #. #-#-#-#-# ithemes-sync.pot (iThemes Sync 2.0.1) #-#-#-#-#
39
  #. Plugin Name of the plugin/theme
40
  #: admin.php:168 admin.php:174 settings-page.php:268
41
  msgid "iThemes Sync"
readme.txt CHANGED
@@ -1,34 +1,147 @@
1
  === iThemes Sync ===
2
- Contributors: ithemes, layotte, glennansley
3
- Tags: Manage Multiple Sites, Backup, Security, Migrate, SEO, Manage Updates, Administration, Update Manager, Reports, Reporting, Scheduled Reports, Sync, Google Analytics, Google Webmaster Tools, Optimize, Uptime, iThemes, Customize Dashboard, Client Sites, Maintenance, Management
4
  Requires at least: 4.5
5
- Tested up to: 4.7.3
6
- Stable tag: 2.0.0
7
- License: GPLv2 or later
8
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
- == License ==
11
- Released under the terms of the GNU General Public License.
12
 
13
  == Description ==
14
 
15
  = Manage Multiple WordPress Sites From One Dashboard =
16
 
17
- Manage updates (and much more!) for your WordPress websites all in one place. Save time logging in to multiple websites to perform WordPress admin tasks.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  == Installation ==
20
 
21
- 1. Upload the zip file to the `/wp-content/plugins/` directory
22
- 2. Unzip
23
- 3. Activate the plugin through the 'Plugins' menu in WordPress
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  DISCLAIMER: Under no circumstances do we release this plugin with any warranty, implied or otherwise. We cannot be held responsible for any damage that might arise from the use of this plugin.
26
 
27
  == Frequently Asked Questions ==
28
 
29
- https://ithemes.com/sync/#faq
30
 
31
- == Changelog ==
32
 
33
- = 2.0.0 =
34
- * Initial release to WordPress.org
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  === iThemes Sync ===
2
+ 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.8
6
+ Stable tag: 2.0.1
7
+ License: GPLv3 or later
8
+ License URI: http://www.gnu.org/licenses/quick-guide-gplv3.html
9
 
10
+ Manage multiple WordPress sites from one dashboard.
 
11
 
12
  == Description ==
13
 
14
  = Manage Multiple WordPress Sites From One Dashboard =
15
 
16
+ Manage updates (and much more!) for all your WordPress websites from one central dashboard. With iThemes Sync, there’s no more logging in to multiple websites to perform WordPress admin tasks. Let iThemes Sync be your personal WordPress website assistant with features for WordPress management productivity. See all [20+ ways iThemes Sync will save you time in your WordPress workflow](https://ithemes.com/2015/06/17/20-ways-ithemes-sync-will-save-you-time/).
17
+
18
+ = Maintained and Supported by iThemes =
19
+
20
+ iThemes has been building WordPress tools since 2008, including iThemes Security, our [WordPress security plugin](http://ithemes.com/security) and BackupBuddy, our [WordPress backup plugin](http://ithemes.com/purchase/backupbuddy)
21
+
22
+ = One Central Dashboard to Save You Loads of Time =
23
+ iThemes Sync allows you to manage and maintain multiple WordPress websites from one central dashboard. Instead of having to login to each individual website, iTheme Sync gives you one place to view important website data and perform remote WordPress admin actions. Easily switch to iThemes Sync’s individual site view to perform site-specific admin actions such as running WordPress plugin and theme updates, making remote WordPress backups and more.
24
+
25
+ * No More Logging In To Multiple WordPress Websites - Logging in to multiple websites is tedious and time-consuming. No more keeping up with multiple usernames and passwords. With Sync, you have one dashboard for all your WordPress websites.
26
+ * Perform WordPress Admin Actions Remotely - iThemes Sync allows you to perform a host of admin tasks remotely—like installing themes and plugins, managing comments, running updates, adding users and much more.
27
+ * Stay On Top of WordPress Updates - WordPress updates are important both for the security and efficiency of WordPress websites. iThemes Sync totally changes the way you update your WordPress sites—now you can update dozens of sites with click.
28
+ * Bulk Install Themes and Plugins From WordPress.org or Zip Upload - Search and install from WordPress.org and view your WordPress.org profile favorites. Upload theme or plugin zip files or install themes and plugins directly from your iThemes membership.
29
+ * WordPress User Manager - WordPress user management in iThemes Sync allows you view all users on a website, edit user profiles and delete users remotely. With Sync’s Client Dashboard, you can customize how certain users see the WordPress dashboard.
30
+ * WordPress Post & Page Manager - View a list of current posts and pages on your site, including the title, author, date last modified, focus keyword, SEO score and SEO readability.
31
+ * Duplicate Pages & Posts Remotely - Once clicked, you’ll be taken to a new, duplicate post or page on your website.
32
+ * Remotely Login to WordPress & Switch Between User Accounts - Quickly jump to the WordPress Admin dashboard of your WordPress site where you’ll be instantly logged in from iThemes Sync. You can also switch between any WordPress user account registered on the site without sharing password info.
33
+ * WordPress Comment Manager - View all comments (all, approved, pending, spam, trash) and unapprove, mark as spam, or move comments to trash.
34
+ * WordPress Database Optimizations (Pro) - Make sure your WordPress sites are running efficiently with WordPress optimizations. Sync handles actions like cleaning out post revisions, spam comments and more.
35
+ * WordPress Uptime Monitoring (Pro) - Sync Pro offers a way to monitor WordPress uptime, downtime & overall performance for all your WordPress websites. Get notification emails when sites go down and view a history of your overall WordPress performance.
36
+ * SEO Checker + Google Analytics & Google Search Console Reports (Pro) - Track key SEO metrics with Sync's [SEO Checker](https://ithemes.com/2016/11/09/yoast-seo-checker-ithemes-sync/) and Google Analytics & Google Search Console integration. Sync integrates with the Yoast SEO plugin to give you an overview of the health of your SEO efforts.
37
+ * Remote WordPress Backups & WordPress Security Actions - Run remote backups with Sync's integration with BackupBuddy, our WordPress backup plugin, and perform more WordPress security actions from Sync with iThemes Security, our WordPress security plugin.
38
+
39
+ = Features Designed for Freelancers and Agencies =
40
+ Sync Pro was made for anyone managing multiple WordPress sites. If you're building sites for clients, you'll love how Sync makes caring for client sites easier and more profitable.
41
+
42
+ * WordPress Maintenance Reports - Sync Pro includes in-depth WordPress maintenance reporting to show the work involved in maintaining WordPress websites. Email clients beautiful HTML email reports with a summary of update actions you took to keep their site running smoothly.
43
+ * Customize the WordPress dashboard for clients/users (Pro) - With Sync Pro, you get Client Dashboard, a WordPress role manager that controls which menu items your clients see in their WordPress dashboard. Don't want them have access to plugins, themes or settings? Simplify their dashboard so they only see what they need -- like posts and pages.
44
+ * Show/Hide Sync From the WP Dashboard - To keep your clients or other site users from messing with your Sync authentication or removing the plugin, you can choose to hide or show the plugin in the WordPress dashboard of each site you manage with Sync.
45
+ * Share Your Sync Dashboard with Another User - If you have other people on your team that you'd like to task with helping you maintain sites, this feature is a great way help you easily delegate your workload to other team members.
46
+ * Site Notes and Tags - Sync’s Notes feature is a handy way to keep notations about your Synced sites. For example, if you added customizations to theme or plugin files that could be lost with an update, add a reminder. Tag business sites, personal sites, client sites, live, non-live or however you want to be able identify your sites.
47
+
48
+ = WordPress Security & Monitoring =
49
+
50
+ * Two-factor Authentication - Add an extra layer of protection to your Sync dashboard login with two-factor authentication. Once enabled, Sync will require both a password AND an SMS code sent to your mobile device to log in to the Sync Dashboard.
51
+ * WordPress Uptime Monitoring - Monitor WordPress uptime and know immediately if one of your websites goes down with uptime notification emails. View uptime stats such as total uptime percentage, total downtime, and number of downtimes for WordPress performance monitoring.
52
+ * Whitelist Your IP Address (iThemes Security integration) - Temporarily whitelist your IP Address remotely so you don't get locked out of your website by the iThemes Security plugin's Bad Users feature.
53
+ * Release iThemes Security Lockouts (iThemes Security integration) - View and release any current iThemes Security lockouts.
54
+
55
+ = WordPress Updates =
56
+
57
+ * Daily Notification Emails - Get a daily summary of available WordPress updates as a helpful reminder to log in and run updates. Customize the delivery time your daily notification emails to fit your schedule.
58
+ * One-Click Update All - View a summary of all available updates for all your websites and then update them all with one click.
59
+ * View Plugin Changelogs - View update logs that include all updates made in Sync, including the date of the update, previous version number and new version number.
60
+ * View Updates by Site - The in-depth individual site view gives you a detailed view of the available updates for that site, with more WordPress site management action options.
61
+ * Sort Updates By Theme or Plugin - View a listing of individual theme and plugins you have installed on your websites along with available update information.
62
+ * Ignore Update Option - If you've made customizations to your themes and plugins, an update could overwrite your work. Choose to ignore updates for specific themes and plugins.
63
+
64
+ = WordPress Maintenance Reports for Clients (Pro) =
65
+ Make steady, reliable income for WordPress maintenance with iThemes Sync Pro’s WordPress Maintenance Reports.
66
+
67
+ * Show Clients the Value of What You Do - Detailed website reports are one of the best ways to show clients the value of a monthly [WordPress maintenance](https://ithemes.com/sync/wordpress-maintenance/) plan. Sync Pro's WordPress Maintenance Reports handle the hard work of compiling all the update actions you took, so you can justify the value of what you do.
68
+ * White-label Report Emails - Upload your own logo and set custom colors for the header, footer and button color of report emails to better match your company’s branding.
69
+ * Summarize Update Actions to WordPress Core, Themes & Plugins + More Website Stats - Reports include all update actions taken within a certain timeframe, both from the Sync dashboard and the WordPress dashboard. [See a full list of all of stats included in Sync's WordPress reports](https://ithemes.com/sync/wordpress-report-stats/).
70
+ * Schedule Reports to Automatically Run & Deliver Report Emails - Reports can run on a daily, weekly or monthly basis, and then automatically email reports to clients.
71
+ * Email Beautiful, Interactive HTML Reports to Clients - Reports are delivered as beautiful, interactive HTML reports so clients can get a visual summary of the WordPress maintenance you provide. Sync handles compiling and organizing update actions and key website stats. [See a WordPress maintenance report demo](https://ithemes.com/sync-pro/demo-report.html).
72
+ * SEO Reporting - Summarize key SEO Stats stats in an easy-to-digest format — showing how your client’s sites are doing in Google and where they can improve. [See a WordPress SEO report demo](https://ithemes.com/sync-pro/seo-demo-report.html).
73
+
74
+ = Integrations =
75
+
76
+ * WordPress.org - Search and install themes and plugins from WordPress.org remotely from Sync. View your WordPress.org profile favorites to save time.
77
+ * BackupBuddy - Run remote WordPress backups, download your latest backup file, view number of edits since your last BackupBuddy backup and download ImportBuddy remotely.
78
+ * BackupBuddy Stash - View, download and delete your BackupBuddy Stash backups, and view a graph of the total amount of Stash space you've used.
79
+ * iThemes Security - Temporarily Whitelist your IP Address remotely so you don't get locked out of the website. View and release any iThemes Security lockouts.
80
+ * Google Analytics - Track Google Analytics for multiple WordPress sites. View key metrics from Google Analytics such as traffic, landing pages, keywords, sessions and referrer URLS.
81
+ * Google Search Console - Get a quick summary of Google Search Console data, view search analytics, crawl errors and sitemaps info.
82
+ * Twitter - Automatically share posts and pages to Twitter. Once activated, adds a button to your WordPress post editor to tweet.
83
+ * Yoast SEO - Sync's SEO Checker feature integrates with the Yoast SEO Plugin so you can quickly see the SEO status of the content on your WordPress website.
84
+ * Gravity Forms - From Sync, you can view all the forms you’ve created in Gravity Forms for that site. You can also quickly see how many responses and views each form has received.
85
+ * WP101 Plugin - Easily add a complete series of WordPress onboarding tutorial videos to the WordPress dashboard of your client sites with Sync's WP101 plugin integration.
86
+
87
+ == Changelog ==
88
+
89
+ = 2.0.1 =
90
+ * Adding code to get-authentication-token verb to set the scheme to https by default if it should be
91
+
92
+ = 2.0.0 =
93
+ * Initial Release to wordpress.org
94
 
95
  == Installation ==
96
 
97
+ 1. Signup for your [free iThemes Sync 10 site plan](https://sync.ithemes.com/signup).
98
+ 2. Follow the normal WordPress plugin installation method to install the iThemes Sync plugin on your WordPress website.
99
+ 3. Follow the steps to add your first website to iThemes Sync.
100
+
101
+ For more detailed instructions, check out the [Sync Quick Setup Guide](https://ithemes.com/2013/11/11/how-to-set-up-ithemes-sync/).
102
+
103
+ == Screenshots ==
104
+
105
+ 1. iThemes Sync dashboard home screen with multiple WordPress websites
106
+ 2. Individual site view with remote WordPress admin actions
107
+ 3. Updates view with listing of themes/plugins and available site updates
108
+ 4. Bulk install themes and plugins across multiple sites via zip upload and WordPress.org search
109
+ 5. Uptime monitoring (Pro)
110
+ 6. Run remote backups and download backup files remotely with BackupBuddy integration
111
+ 7. Update sites on the go with mobile-optimized dashboard
112
+ 8. Activate Client Dashboard for certain users. Customize the WordPress dashboard and hide/display menu items (Pro)
113
+ 9. Send clients interactive WordPress maintenance reports that summarize update actions and other key site metrics (Pro)
114
+
115
+
116
+ == License ==
117
+
118
+ This file is part of iThemes Sync. This plugin is released under the terms of the GNU General Public License.
119
 
120
  DISCLAIMER: Under no circumstances do we release this plugin with any warranty, implied or otherwise. We cannot be held responsible for any damage that might arise from the use of this plugin.
121
 
122
  == Frequently Asked Questions ==
123
 
124
+ = Is iThemes Sync free? =
125
 
126
+ You can manage 10 sites totally free for iThemes Sync. If you need additional sites, you can [add more sites to your Sync plan](https://ithemes.com/sync). Some features including Client Dashboard and WordPress Maintenance Reports are Pro-only features and not included in the 10-site free plan.
127
 
128
+ = Do you offer support for free users? =
129
+
130
+ Yes. We handle support for free iThemes Sync users both from the WordPress.org forum and from the [iThemes Help Desk](https://ithemes.com/support). The iThemes Help Desk offers private, ticketed support to protect your privacy.
131
+
132
+ = Is iThemes Sync secure? =
133
+
134
+ Yes. We develop and maintain iThemes Sync according to strict WordPress security standards. We take security seriously; so much so, we have an in-house WordPress security team and have our own WordPress security plugin with over 1 million active installs.
135
+
136
+ To help keep access to iThemes Sync secure, we strongly suggest enabling two-factor authentication for your iTheme Sync account. Using two-factor authentication for your Sync login will help ensure that only you have access to the websites in Sync. Because iThemes Sync allows you to perform WordPress administrator tasks such as installing and uninstalling themes and plugins, adding WordPress user accounts, logging into the WordPress dashboard and more, securing your iThemes Sync account is as important as securing your WordPress administrator account login.
137
+
138
+ = Does iThemes Sync work with WordPress.com sites? =
139
+
140
+ No. iThemes Sync only works with self-hosted WordPress sites.
141
+
142
+ = Help! I’m having problems adding a site to Sync. =
143
+
144
+ iThemes Sync includes an automatic “Add Site" prompt when you first login to the Sync dashboard. If this authentication method fails, try manually installing the iThemes Sync plugin on your WordPress site. Make sure to [create an iThemes account here](https://sync.ithemes.com/signup) and then follow the prompt from the Sync plugin to add your credentials. If you still need help, please open a ticket at the [iThemes Help Desk](https://ithemes.com/support).
145
+
146
+
147
+ Got more questions? [Contact us!](https://ithemes.com/contact “iThemes Contact")
trunk/admin.php DELETED
@@ -1,233 +0,0 @@
1
- <?php
2
-
3
- /*
4
- Set up admin interface.
5
- Written by Chris Jean for iThemes.com
6
- Version 1.2.0
7
-
8
- Version History
9
- 1.0.0 - 2013-10-02 - Chris Jean
10
- Initial version
11
- 1.1.0 - 2013-11-19 - Chris Jean
12
- Added the ability for the show_sync option to control who sees the Sync interface and plugin.
13
- 1.2.0 - 2014-02-14 - Chris Jean
14
- Added support for ?ithemes-sync-force-display=1 in the admin page to force a hidden Sync plugin to display for that specific user.
15
- */
16
-
17
-
18
- require_once( $GLOBALS['ithemes_sync_path'] . '/load-translations.php' );
19
-
20
- class Ithemes_Sync_Admin {
21
- private $page_name = 'ithemes-sync';
22
-
23
- private $page_ref;
24
-
25
-
26
- public function __construct() {
27
- add_action( 'init', array( $this, 'init' ) );
28
- add_action( 'wp_ajax_ithemes_sync_hide_notice', array( $this, 'hide_authenticate_notice' ) );
29
- }
30
-
31
- public function modify_plugins_page() {
32
- add_filter( 'all_plugins', array( $this, 'remove_sync_plugin' ) );
33
- }
34
-
35
- public function remove_sync_plugin( $plugins ) {
36
- unset( $plugins[basename( $GLOBALS['ithemes_sync_path'] ) . '/init.php'] );
37
-
38
- return $plugins;
39
- }
40
-
41
- public function init() {
42
- require_once( $GLOBALS['ithemes_sync_path'] . '/settings.php' );
43
-
44
-
45
- $show_sync = $GLOBALS['ithemes-sync-settings']->get_option( 'show_sync' );
46
-
47
- if ( is_array( $show_sync ) ) {
48
- $show_sync = in_array( get_current_user_id(), $show_sync );
49
- }
50
-
51
- if ( ! $show_sync && current_user_can( 'manage_options' ) ) {
52
- $user_id = get_current_user_id();
53
-
54
- if ( isset( $_GET['ithemes-sync-force-display'] ) ) {
55
- if ( ! empty( $_GET['ithemes-sync-force-display'] ) ) {
56
- $show_sync = true;
57
- set_site_transient( "ithemes-sync-force-display-$user_id", true, 600 );
58
-
59
- add_action( 'all_admin_notices', array( $this, 'show_force_display_notice' ), 0 );
60
- } else {
61
- delete_site_transient( "ithemes-sync-force-display-$user_id" );
62
-
63
- add_action( 'all_admin_notices', array( $this, 'show_force_display_disable_notice' ), 0 );
64
- }
65
- } else if ( false !== get_site_transient( "ithemes-sync-force-display-$user_id" ) ) {
66
- $show_sync = true;
67
-
68
- add_action( 'all_admin_notices', array( $this, 'show_force_display_notice' ), 0 );
69
- }
70
- }
71
-
72
-
73
- if ( $show_sync ) {
74
- if ( ! is_multisite() || is_super_admin() ) {
75
- add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
76
- }
77
-
78
- add_action( 'network_admin_menu', array( $this, 'add_network_admin_pages' ) );
79
-
80
-
81
- if ( current_user_can( 'manage_options' ) ) {
82
- if ( ! get_site_option( 'ithemes-sync-authenticated' ) && ( empty( $_GET['page'] ) || ( $this->page_name != $_GET['page'] ) ) && ! get_site_option( 'ithemes_sync_hide_authenticate_notice' ) ) {
83
- require_once( $GLOBALS['ithemes_sync_path'] . '/functions.php' );
84
-
85
- $path_url = Ithemes_Sync_Functions::get_url( $GLOBALS['ithemes_sync_path'] );
86
- wp_enqueue_style( 'ithemes-updater-admin-notice-style', "$path_url/css/admin-notice.css" );
87
- wp_enqueue_script( 'ithemes-updater-admin-notice-script', "$path_url/js/admin-notice.js", array( 'jquery' ) );
88
-
89
- add_action( 'all_admin_notices', array( $this, 'show_authenticate_notice' ), 0 );
90
-
91
- delete_site_transient( 'ithemes-sync-activated' );
92
- }
93
- else if ( ! empty( $_GET['activate'] ) && get_site_transient( 'ithemes-sync-activated' ) ) {
94
- require_once( $GLOBALS['ithemes_sync_path'] . '/functions.php' );
95
-
96
- $path_url = Ithemes_Sync_Functions::get_url( $GLOBALS['ithemes_sync_path'] );
97
- wp_enqueue_style( 'ithemes-updater-admin-notice-style', "$path_url/css/admin-notice.css" );
98
- wp_enqueue_script( 'ithemes-updater-admin-notice-script', "$path_url/js/admin-notice.js", array( 'jquery' ) );
99
-
100
- add_action( 'all_admin_notices', array( $this, 'show_activate_notice' ), 0 );
101
-
102
- delete_site_transient( 'ithemes-sync-activated' );
103
- }
104
- }
105
- } else {
106
- add_action( 'load-plugins.php', array( $this, 'modify_plugins_page' ) );
107
- }
108
- }
109
-
110
- public function show_activate_notice() {
111
- if ( is_multisite() && is_network_admin() )
112
- $url = network_admin_url( 'settings.php' ) . "?page={$this->page_name}";
113
- else
114
- $url = admin_url( 'options-general.php' ) . "?page={$this->page_name}";
115
-
116
- ?>
117
- <div class="updated" id="ithemes-sync-notice">
118
- <?php printf( __( 'iThemes Sync is active. <a class="ithemes-sync-notice-button" href="%s">Manage Sync</a> <a class="ithemes-sync-notice-dismiss" href="#">×</a>', 'it-l10n-ithemes-sync' ), $url ); ?>
119
- </div>
120
- <?php
121
-
122
- }
123
-
124
- public function show_authenticate_notice() {
125
- if ( is_multisite() && is_network_admin() )
126
- $url = network_admin_url( 'settings.php' ) . "?page={$this->page_name}";
127
- else
128
- $url = admin_url( 'options-general.php' ) . "?page={$this->page_name}";
129
-
130
- ?>
131
- <div class="updated" id="ithemes-sync-notice">
132
- <?php printf( __( 'iThemes Sync is almost ready. <a class="ithemes-sync-notice-button" href="%s">Set Up Sync</a> <a class="ithemes-sync-notice-hide" href="#">×</a>', 'it-l10n-ithemes-sync' ), $url ); ?>
133
- </div>
134
- <?php
135
-
136
- }
137
-
138
- public function show_force_display_notice() {
139
- $user_id = get_current_user_id();
140
- $time = get_site_option( "_site_transient_timeout_ithemes-sync-force-display-$user_id" );
141
- $time_diff = human_time_diff( time(), $time );
142
-
143
- $url = admin_url( 'index.php?ithemes-sync-force-display=0' );
144
-
145
- ?>
146
- <div class="updated">
147
- <p><?php printf( __( 'iThemes Sync will show for your user for the next %1$s. Click <a href="%2$s">here</a> to hide iThemes Sync again.', 'it-l10n-ithemes-sync' ), $time_diff, $url ); ?></p>
148
- </div>
149
- <?php
150
-
151
- }
152
-
153
- public function show_force_display_disable_notice() {
154
-
155
- ?>
156
- <div class="updated">
157
- <p><?php _e( 'iThemes Sync is now hidden from your user again.', 'it-l10n-ithemes-sync' ); ?></p>
158
- </div>
159
- <?php
160
-
161
- }
162
-
163
- public function hide_authenticate_notice() {
164
- update_site_option( 'ithemes_sync_hide_authenticate_notice', true );
165
- }
166
-
167
- public function add_admin_pages() {
168
- $this->page_ref = add_options_page( __( 'iThemes Sync', 'it-l10n-ithemes-sync' ), __( 'iThemes Sync', 'it-l10n-ithemes-sync' ), 'manage_options', $this->page_name, array( $this, 'settings_index' ) );
169
-
170
- add_action( "load-{$this->page_ref}", array( $this, 'load_settings_page' ) );
171
- }
172
-
173
- public function add_network_admin_pages() {
174
- $this->page_ref = add_submenu_page( 'settings.php', __( 'iThemes Sync', 'it-l10n-ithemes-sync' ), __( 'iThemes Sync', 'it-l10n-ithemes-sync' ), 'manage_options', $this->page_name, array( $this, 'settings_index' ) );
175
-
176
- add_action( "load-{$this->page_ref}", array( $this, 'load_settings_page' ) );
177
- }
178
-
179
- public function load_settings_page() {
180
- require_once( $GLOBALS['ithemes_sync_path'] . '/settings.php' );
181
-
182
- require( $GLOBALS['ithemes_sync_path'] . '/settings-page.php' );
183
- }
184
-
185
- public function settings_index() {
186
- do_action( 'ithemes_sync_settings_page_index' );
187
- }
188
-
189
- private function set_package_details() {
190
- if ( false !== $this->package_details )
191
- return;
192
-
193
- require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
194
- $this->package_details = Ithemes_Updater_Packages::get_local_details();
195
- }
196
-
197
- private function set_registration_link() {
198
- if ( false !== $this->registration_link )
199
- return;
200
-
201
- $url = admin_url( 'options-general.php' ) . "?page={$this->page_name}";
202
- $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' ) );
203
- }
204
-
205
- public function filter_plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
206
- $this->set_package_details();
207
- $this->set_registration_link();
208
-
209
- if ( isset( $this->package_details[$plugin_file] ) )
210
- $actions[] = $this->registration_link;
211
-
212
- return $actions;
213
- }
214
-
215
- public function filter_theme_action_links( $actions, $theme ) {
216
- $this->set_package_details();
217
- $this->set_registration_link();
218
-
219
- if ( is_object( $theme ) )
220
- $path = basename( $theme->get_stylesheet_directory() ) . '/style.css';
221
- else if ( is_array( $theme ) && isset( $theme['Stylesheet Dir'] ) )
222
- $path = $theme['Stylesheet Dir'] . '/style.css';
223
- else
224
- $path = '';
225
-
226
- if ( isset( $this->package_details[$path] ) )
227
- $actions[] = $this->registration_link;
228
-
229
- return $actions;
230
- }
231
- }
232
-
233
- new Ithemes_Sync_Admin();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trunk/api.php DELETED
@@ -1,274 +0,0 @@
1
- <?php
2
-
3
- /*
4
- Simple API for managing verbs for Sync.
5
- Written by Chris Jean for iThemes.com
6
- Version 1.4.1
7
-
8
- Version History
9
- 1.0.0 - 2013-10-01 - Chris Jean
10
- Initial version
11
- 1.1.0 - 2013-11-18 - Chris Jean
12
- Updated default verbs.
13
- 1.2.0 - 2014-01-20 - Chris Jean
14
- Added: get-status-elements, manage-plugins, and manage-themes.
15
- Added: is_default_status_element(), get_default_status_elements().
16
- 1.2.1 - 2014-02-07 - Chris Jean
17
- When including a verb's file, errors are no longer hidden. This allows for easier detection of verbs with problems.
18
- Better handling of invalid verbs.
19
- 1.3.0 - 2014-03-25 - Chris Jean
20
- Added: get-notices.
21
- 1.4.0 - 2014-07-01 - Chris Jean
22
- Added: get-comment-details, get-options, get-role-details, get-user-details, manage-commments, manage-roles, manage-users.
23
- register() now returns true when a Verb has been successfully registered.
24
- 1.4.1 - 2014-11-10 - Chris Jean
25
- Changed init hook priority to 11 in order to avoid issues with some plugin updates not appearing.
26
- */
27
-
28
-
29
- class Ithemes_Sync_API {
30
- private $verbs = array();
31
-
32
- private $default_verbs = array(
33
- 'db-optimization' => 'Ithemes_Sync_Verb_DB_Optimization',
34
- 'deauthenticate-user' => 'Ithemes_Sync_Verb_Deauthenticate_User',
35
- 'do-update' => 'Ithemes_Sync_Verb_Do_Update',
36
- 'get-admin-bar-item-whitelist' => 'Ithemes_Sync_Verb_Get_Admin_Bar_Item_Whitelist',
37
- 'get-admin-bar-items' => 'Ithemes_Sync_Verb_Get_Admin_Bar_Items',
38
- 'get-admin-menu' => 'Ithemes_Sync_Verb_Get_Admin_Menu',
39
- 'get-authentication-token' => 'Ithemes_Sync_Verb_Get_Authentication_Token',
40
- 'get-comment-details' => 'Ithemes_Sync_Verb_Get_Comment_Details',
41
- 'get-dashboard-widgets' => 'Ithemes_Sync_Verb_Get_Dashboard_Widgets',
42
- 'get-options' => 'Ithemes_Sync_Verb_Get_Options',
43
- 'get-php-details' => 'Ithemes_Sync_Verb_Get_PHP_Details',
44
- 'get-plugin-details' => 'Ithemes_Sync_Verb_Get_Plugin_Details',
45
- 'get-posts' => 'Ithemes_Sync_Verb_Get_Posts',
46
- 'get-post-types' => 'Ithemes_Sync_Verb_Get_Post_Types',
47
- 'get-notices' => 'Ithemes_Sync_Verb_Get_Notices',
48
- 'get-role-details' => 'Ithemes_Sync_Verb_Get_Role_Details',
49
- 'get-server-details' => 'Ithemes_Sync_Verb_Get_Server_Details',
50
- 'get-status' => 'Ithemes_Sync_Verb_Get_Status',
51
- 'get-status-elements' => 'Ithemes_Sync_Verb_Get_Status_Elements',
52
- 'get-supported-verbs' => 'Ithemes_Sync_Verb_Get_Supported_Verbs',
53
- 'get-sync-settings' => 'Ithemes_Sync_Verb_Get_Sync_Settings',
54
- 'get-theme-details' => 'Ithemes_Sync_Verb_Get_Theme_Details',
55
- 'get-update-details' => 'Ithemes_Sync_Verb_Get_Update_Details',
56
- 'get-updates' => 'Ithemes_Sync_Verb_Get_Updates',
57
- 'get-user-details' => 'Ithemes_Sync_Verb_Get_User_Details',
58
- 'get-wordpress-details' => 'Ithemes_Sync_Verb_Get_Wordpress_Details',
59
- 'get-wordpress-settings' => 'Ithemes_Sync_Verb_Get_Wordpress_Settings',
60
- 'get-wordpress-users' => 'Ithemes_Sync_Verb_Get_Wordpress_Users',
61
- 'manage-posts' => 'Ithemes_Sync_Verb_Manage_Posts',
62
- 'manage-comments' => 'Ithemes_Sync_Verb_Manage_Comments',
63
- 'manage-ithemes-licenses' => 'Ithemes_Sync_Verb_Manage_Ithemes_Licenses',
64
- 'manage-options' => 'Ithemes_Sync_Verb_Manage_Options',
65
- 'manage-plugins' => 'Ithemes_Sync_Verb_Manage_Plugins',
66
- 'manage-reports' => 'Ithemes_Sync_Verb_Manage_Reports',
67
- 'manage-roles' => 'Ithemes_Sync_Verb_Manage_Roles',
68
- 'manage-themes' => 'Ithemes_Sync_Verb_Manage_Themes',
69
- 'manage-users' => 'Ithemes_Sync_Verb_Manage_Users',
70
- 'set-admin-bar-item-whitelist' => 'Ithemes_Sync_Verb_Set_Admin_Bar_Item_Whitelist',
71
- 'update-show-sync' => 'Ithemes_Sync_Verb_Update_Show_Sync',
72
- 'update-google-site-verification-token' => 'Ithemes_Sync_Verb_Update_Google_Site_Verification_Token',
73
- );
74
-
75
- public function __construct() {
76
- $GLOBALS['ithemes-sync-api'] = $this;
77
-
78
- require_once( $GLOBALS['ithemes_sync_path'] . '/functions.php' );
79
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
80
-
81
- // Gravity Forms Verbs
82
- if ( class_exists( 'GFForms' ) ) {
83
- $this->default_verbs['get-gf-forms'] = 'Ithemes_Sync_Verb_Get_GF_Forms';
84
- $this->default_verbs['get-gf-form-entries'] = 'Ithemes_Sync_Verb_Get_GF_Form_Entries';
85
- }
86
-
87
- // Yoast SEO Verbs
88
- if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) ) {
89
- $this->default_verbs['get-yoast-seo-summary'] = 'Ithemes_Sync_Verb_Get_Yoast_SEO_Summary';
90
- }
91
-
92
- add_action( 'init', array( $this, 'init' ), 11 );
93
- }
94
-
95
- public function init() {
96
- require_once( $GLOBALS['ithemes_sync_path'] . "/verbs/verb.php" );
97
-
98
- foreach ( $this->default_verbs as $name => $class ) {
99
- $this->register( $name, $class, $GLOBALS['ithemes_sync_path'] . "/verbs/$name.php" );
100
- }
101
-
102
- do_action( 'ithemes_sync_register_verbs', $this );
103
-
104
- do_action( 'ithemes_sync_verbs_registered' );
105
- }
106
-
107
- public function register( $name, $class, $file = '' ) {
108
- if ( isset( $this->verbs[$name] ) ) {
109
- do_action( 'ithemes-sync-add-log', 'Tried to add a verb name that already exists.', compact( 'name', 'class', 'file' ) );
110
- return false;
111
- }
112
-
113
- $this->verbs[$name] = compact( 'name', 'class', 'file' );
114
-
115
- return true;
116
- }
117
-
118
- public function get_names() {
119
- return array_keys( $this->verbs );
120
- }
121
-
122
- public function get_description( $name ) {
123
- $class = $this->get_class( $name );
124
-
125
- if ( false === $class )
126
- return '';
127
-
128
-
129
- $vars = get_class_vars( $class );
130
-
131
- if ( isset( $vars['description'] ) )
132
- return $vars['description'];
133
-
134
- return '';
135
- }
136
-
137
- public function get_descriptions() {
138
- $names = $this->get_names();
139
- $descriptions = array();
140
-
141
- foreach ( $names as $name )
142
- $descriptions[$name] = $this->get_description( $name );
143
-
144
- return $descriptions;
145
- }
146
-
147
- public function get_status_element( $name ) {
148
- $class = $this->get_class( $name );
149
-
150
- if ( false === $class ) {
151
- return false;
152
- }
153
-
154
-
155
- $vars = get_class_vars( $class );
156
-
157
- if ( ! empty( $vars['status_element_name'] ) ) {
158
- return $vars['status_element_name'];
159
- }
160
-
161
- return false;
162
- }
163
-
164
- public function get_status_elements() {
165
- $names = $this->get_names();
166
- $status_elements = array();
167
-
168
- foreach ( $names as $name ) {
169
- $status_element = $this->get_status_element( $name );
170
-
171
- if ( false !== $status_element ) {
172
- $status_elements[$status_element] = $name;
173
- }
174
- }
175
-
176
- return $status_elements;
177
- }
178
-
179
- public function is_default_status_element( $name ) {
180
- $class = $this->get_class( $name );
181
-
182
- if ( false === $class ) {
183
- return false;
184
- }
185
-
186
-
187
- $vars = get_class_vars( $class );
188
-
189
- if ( ! empty( $vars['show_in_status_by_default'] ) ) {
190
- return $vars['show_in_status_by_default'];
191
- }
192
-
193
- return false;
194
- }
195
-
196
- public function get_default_status_elements() {
197
- $names = $this->get_names();
198
- $default_status_elements = array();
199
-
200
- foreach ( $names as $name ) {
201
- if ( $this->is_default_status_element( $name ) ) {
202
- $default_status_elements[] = $this->get_status_element( $name );
203
- }
204
- }
205
-
206
- return $default_status_elements;
207
- }
208
-
209
- public function run( $name, $arguments = array() ) {
210
- $object = $this->get_object( $name );
211
-
212
- if ( false == $object ) {
213
- return new WP_Error( 'invalid-verb-object', "Unable to find a valid object for the requested verb: $name" );
214
- }
215
-
216
- return $object->run( $arguments );
217
- }
218
-
219
- private function get_class( $name ) {
220
- if ( ! isset( $this->verbs[$name] ) ) {
221
- do_action( 'ithemes-sync-add-log', 'Unable to find requested verb.', array( 'name' => $name ) );
222
- return false;
223
- }
224
-
225
- if ( ! class_exists( $this->verbs[$name]['class'] ) ) {
226
- if ( empty( $this->verbs[$name]['file'] ) ) {
227
- do_action( 'ithemes-sync-add-log', 'Unable to find requested verb\'s class.', $this->verbs[$name] );
228
- return false;
229
- }
230
- else if ( ! is_file( $this->verbs[$name]['file'] ) ) {
231
- do_action( 'ithemes-sync-add-log', 'Unable to find requested verb\'s file.', $this->verbs[$name] );
232
- return false;
233
- }
234
- else {
235
- include_once( $this->verbs[$name]['file'] );
236
-
237
- if ( ! class_exists( $this->verbs[$name]['class'] ) ) {
238
- do_action( 'ithemes-sync-add-log', 'Unable to find requested verb\'s class even after loading its file.', $this->verbs[$name] );
239
- return false;
240
- }
241
-
242
- if ( ! is_subclass_of( $this->verbs[$name]['class'], 'Ithemes_Sync_Verb' ) ) {
243
- do_action( 'ithemes-sync-add-log', 'Verb added without being a subclass of Ithemes_Sync_Verb', $this->verbs[$name] );
244
- return false;
245
- }
246
- }
247
- }
248
-
249
- return $this->verbs[$name]['class'];
250
- }
251
-
252
- private function get_object( $name ) {
253
- if ( ! isset( $this->verbs[$name] ) ) {
254
- do_action( 'ithemes-sync-add-log', 'Unable to find requested verb.', array( 'name' => $name ) );
255
- return false;
256
- }
257
-
258
- if ( ! isset( $this->verbs[$name]['object'] ) ) {
259
- $class = $this->get_class( $name );
260
-
261
- if ( false === $class ) {
262
- return false;
263
- }
264
-
265
- $object = new $class();
266
-
267
- $this->verbs[$name]['object'] = $object;
268
- }
269
-
270
- return $this->verbs[$name]['object'];
271
- }
272
- }
273
-
274
- new Ithemes_Sync_API();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trunk/api.txt DELETED
@@ -1,60 +0,0 @@
1
- #### Notices ####
2
-
3
- Sync can receive notifications from other projects. These notifications are of two kinds: normal and urgent.
4
-
5
-
6
- ## Normal Notices ##
7
-
8
- Normal notices are for providing information that is not urgent but should be made note of when an admin is maintaining the site. They are sent to the server when the server makes status requests or when specifically requesting notices from the site.
9
-
10
- Example:
11
-
12
- function backup_plugin_add_notices( $arguments ) {
13
- $data = array(
14
- 'last_backup' => 1394859600,
15
- 'last_backup_diff_from_now' => 988402,
16
- );
17
-
18
- // The verbose argument can be checked for in order to provide additional information that may not always be necessary.
19
- if ( ! empty( $arguments['verbose'] ) ) {
20
- $data['last_backup_type'] = 'full';
21
- }
22
-
23
- ithemes_sync_add_notice( 'backup_plugin', 'no_recent_backups', 'No recent backups', 'It has been more than a week since the last backup.', $data );
24
-
25
-
26
- // Plugin-specific arguments could be provided to enable additional notices that would be disabled by default.
27
- if ( ! empty( $arguments['backup_plugin_show_extra_notices'] ) ) {
28
- ithemes_sync_add_notice( 'backup_plugin', 'superfluous_notice', 'Superfluous notice', 'I ran out of good ideas, so this is merely an example.' );
29
- // Note how the $data argument is optional in the call above.
30
- }
31
- }
32
- add_action( 'ithemes_sync_add_notices', 'backup_plugin_add_notices' );
33
-
34
- Details about the ithemes_sync_add_notice function:
35
- * @param string $source Uniquely identifies the project that is sending the notice.
36
- * @param string $id Identifies the type of notice. This is to allow the server to differentiate different kinds of notices without having to parse the message.
37
- * @param string $subject A brief subject description of the notice that is fit for presentation to Sync users.
38
- * @param string $message A message that is fit for presentation to Sync users.
39
- * @param array $data Optional. Data that is relevant to the notice. For notices that may be best presented in a graphical manner, this field could be used to send data used to construct the graphic.
40
- * @return bool True. Currently, it always returns true.
41
-
42
-
43
- ## Urgent Notices ##
44
-
45
- Urgent notices are sent immediately to the server so that the administator can be notified directly. These notices are to be used when something important happens on the site that requires immediate attention.
46
-
47
- Example:
48
-
49
- function security_plugin_send_urgent_notice() {
50
- $result = ithemes_sync_send_urgent_notice( 'security_plugin', 'intruder_detected', 'Intruder detected', 'An intruder has been detected on the site.' );
51
- }
52
- add_action( 'init', 'security_plugin_send_urgent_notice' );
53
-
54
- Details about the ithemes_sync_send_urgent_notice function:
55
- * @param string $source Uniquely identifies the project that is sending the notice.
56
- * @param string $id Identifies the type of notice. This is to allow the server to differentiate different kinds of notices without having to parse the message.
57
- * @param string $subject A brief subject description of the notice that is fit for presentation to Sync users.
58
- * @param string $message A message that is fit for presentation to Sync users.
59
- * @param array $data Optional. Data that is relevant to the notice. For notices that may be best presented in a graphical manner, this field could be used to send data used to construct the graphic.
60
- * @return bool|WP_Error True on successful receipt by the server. WP_Error object otherwise. In the event of an error, the notice is queued for sending to the server when it makes a status or notice request.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trunk/ca/index.php DELETED
@@ -1 +0,0 @@
1
- <?php // Silence is golden.
 
trunk/ca/roots.crt DELETED
@@ -1,58 +0,0 @@
1
- ##
2
- ## CA Root Certificate for api.ithemes.com and s3.amazonaws.com
3
- ##
4
- ## Certificate data from Mozilla as of: Sat Dec 29 20:03:40 2012
5
- ##
6
-
7
- # @(#) $RCSfile: certdata.txt,v $ $Revision: 1.87 $ $Date: 2012/12/29 16:32:45 $
8
-
9
- Go Daddy Class 2 CA
10
- ===================
11
- -----BEGIN CERTIFICATE-----
12
- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
13
- VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
14
- ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
15
- A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
16
- RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
17
- ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
18
- 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
19
- qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
20
- YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
21
- vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
22
- BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
23
- atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
24
- MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
25
- A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
26
- PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
27
- I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
28
- HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
29
- Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
30
- vZ8=
31
- -----END CERTIFICATE-----
32
-
33
- VeriSign Class 3 Public Primary Certification Authority - G5
34
- ============================================================
35
- -----BEGIN CERTIFICATE-----
36
- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
37
- BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
38
- ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
39
- IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
40
- ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
41
- yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
42
- biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
43
- dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
44
- YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
45
- ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
46
- j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
47
- Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
48
- Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
49
- fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
50
- BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
51
- Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
52
- aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
53
- SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
54
- X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
55
- KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
56
- Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
57
- ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
58
- -----END CERTIFICATE-----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trunk/class-ithemes-credentials.php DELETED
@@ -1,143 +0,0 @@
1
- <?php
2
-
3
- //-----------------------------------------------------------------------------
4
-
5
- class iThemes_Credentials
6
- {
7
-
8
- //-----------------------------------------------------------------------------
9
-
10
- protected $hash = 'sha256';
11
-
12
- protected $salt_padding = 'wdHVwU&HcYcWnllo%kTUUnxpScy4%ICM29';
13
-
14
- protected $iteration_count = 131072;
15
-
16
- protected $key_length = 64;
17
-
18
- protected $password;
19
-
20
- //-----------------------------------------------------------------------------
21
-
22
- public function __construct($username, $password, $options = array())
23
- {
24
-
25
- $this->username = $username;
26
-
27
- $this->password = $password;
28
-
29
-
30
- if(!empty($options['hash']))
31
- $this->hash = strtolower(trim($options['hash']));
32
-
33
- if(!empty($options['iterations']))
34
- $this->iteration_count = intval($options['iterations']);
35
-
36
- if(!empty($options['salt']))
37
- $this->salt_padding = $options['salt'];
38
-
39
- if(!empty($options['key_length']))
40
- $this->key_length = intval($options['key_length']);
41
-
42
- }
43
-
44
- //-----------------------------------------------------------------------------
45
-
46
- public static function get_password_hash($username, $password, $options = array())
47
- {
48
-
49
- $hasher = new iThemes_Credentials($username, $password, $options);
50
-
51
- return $hasher->get_pbkdf2();
52
-
53
- }
54
-
55
- //-----------------------------------------------------------------------------
56
-
57
- public function get_salt()
58
- {
59
-
60
- return strtolower(trim($this->username)) . $this->salt_padding;
61
-
62
- }
63
-
64
- //-----------------------------------------------------------------------------
65
-
66
- public function get_pbkdf2()
67
- {
68
-
69
- return $this->pbkdf2($this->hash,
70
- $this->password,
71
- $this->get_salt(),
72
- $this->iteration_count,
73
- $this->key_length / 2,
74
- false);
75
-
76
- }
77
-
78
- //-----------------------------------------------------------------------------
79
-
80
- /*
81
- * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
82
- * $algorithm - The hash algorithm to use. Recommended: SHA256
83
- * $password - The password.
84
- * $salt - A salt that is unique to the password.
85
- * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
86
- * $key_length - The length of the derived key in bytes.
87
- * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
88
- * Returns: A $key_length-byte key derived from the password and salt.
89
- *
90
- * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
91
- *
92
- * This implementation of PBKDF2 was originally created by https://defuse.ca
93
- * With improvements by http://www.variations-of-shadow.com
94
- */
95
- private function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
96
- {
97
-
98
- $algorithm = strtolower($algorithm);
99
-
100
- if(!in_array($algorithm, hash_algos(), true))
101
- trigger_error('PBKDF2 ERROR: Invalid hash algorithm.', E_USER_ERROR);
102
-
103
- if($count <= 0 || $key_length <= 0)
104
- trigger_error('PBKDF2 ERROR: Invalid parameters.', E_USER_ERROR);
105
-
106
-
107
- $hash_length = strlen(hash($algorithm, '', true));
108
- $block_count = ceil($key_length / $hash_length);
109
-
110
- $output = '';
111
-
112
- for($i = 1; $i <= $block_count; $i++)
113
- {
114
-
115
- // $i encoded as 4 bytes, big endian.
116
- $last = $salt . pack("N", $i);
117
-
118
- // first iteration
119
- $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
120
-
121
- // perform the other $count - 1 iterations
122
- for ($j = 1; $j < $count; $j++)
123
- {
124
- $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
125
- }
126
-
127
- $output .= $xorsum;
128
-
129
- }
130
-
131
- if($raw_output)
132
- return substr($output, 0, $key_length);
133
- else
134
- return bin2hex(substr($output, 0, $key_length));
135
-
136
- }
137
-
138
- //-----------------------------------------------------------------------------
139
-
140
- }
141
-
142
- //-----------------------------------------------------------------------------
143
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trunk/class-ithemes-sync-json.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
-
3
- final class Ithemes_Sync_JSON {
4
- public static function encode( $data ) {
5
- $json = json_encode( $data );
6
-
7
- if ( false !== $json ) {
8
- return $json;
9
- }
10
-
11
- $data = self::get_fixed_data( $data );
12
- $json = json_encode( $data );
13
-
14
- if ( false !== $json ) {
15
- return $json;
16
- }
17
-
18
- return json_encode( 'Encoding error. Unable to JSON encode the data due to an unknown error.' );
19
- }
20
-
21
- private static function get_fixed_data( $data ) {
22
- if ( false !== json_encode( $data ) ) {
23
- return $data;
24
- }
25
-
26
- if ( is_string( $data ) ) {
27
- require_once( $GLOBALS['ithemes_sync_path'] . '/class-ithemes-sync-utf8-encoder.php' );
28
- $data = Ithemes_Sync_UTF8_Encoder::toUTF8( $data );
29
-
30
- if ( false === json_encode( $data ) ) {
31
- return 'INVALID STRING DATA';
32
- }
33
-
34
- return $data;
35
- }
36
-
37
- if ( is_array( $data ) ) {
38
- foreach ( $data as $key => $value ) {
39
- if ( false === json_encode( $key ) ) {
40
- unset( $data[$key] );
41
- $key = self::get_fixed_data( $key );
42
- $data[$key] = $value;
43
- }
44
-
45
- if ( false === json_encode( $value ) ) {
46
- $value = self::get_fixed_data( $value );
47
- $data[$key] = $value;
48
- }
49
- }
50
-
51
- if ( false === json_encode( $data ) ) {
52
- return 'INVALID ARRAY DATA';
53
- }
54
-
55
- return $data;
56
- }
57
-
58
- if ( is_object( $data ) ) {
59
- return 'INVALID CLASS ' . get_class( $data ) . ' DATA';
60
- }
61
-
62
- return 'INVALID DATA (' . gettype( $data ) . ')';
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
trunk/class-ithemes-sync-utf8-encoder.php DELETED
@@ -1,343 +0,0 @@
1
- <?php
2
- /*
3
- Copyright (c) 2008 Sebastián Grignoli
4
- All rights reserved.
5
-
6
- Redistribution and use in source and binary forms, with or without
7
- modification, are permitted provided that the following conditions
8
- are met:
9
- 1. Redistributions of source code must retain the above copyright
10
- notice, this list of conditions and the following disclaimer.
11
- 2. Redistributions in binary form must reproduce the above copyright
12
- notice, this list of conditions and the following disclaimer in the
13
- documentation and/or other materials provided with the distribution.
14
- 3. Neither the name of copyright holders nor the names of its
15
- contributors may be used to endorse or promote products derived
16
- from this software without specific prior written permission.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
22
- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
- POSSIBILITY OF SUCH DAMAGE.
29
- */
30
-
31
- /**
32
- * @author "Sebastián Grignoli" <grignoli@gmail.com>
33
- * @package Encoding
34
- * @version 2.0
35
- * @link https://github.com/neitanod/forceutf8
36
- * @example https://github.com/neitanod/forceutf8
37
- * @license Revised BSD
38
- */
39
-
40
- // Modified by Chris Jean of iThemes.com to add backcompat support for PHP 5.2.4.
41
-
42
- class Ithemes_Sync_UTF8_Encoder {
43
-
44
- protected static $win1252ToUtf8 = array(
45
- 128 => "\xe2\x82\xac",
46
-
47
- 130 => "\xe2\x80\x9a",
48
- 131 => "\xc6\x92",
49
- 132 => "\xe2\x80\x9e",
50
- 133 => "\xe2\x80\xa6",
51
- 134 => "\xe2\x80\xa0",
52
- 135 => "\xe2\x80\xa1",
53
- 136 => "\xcb\x86",
54
- 137 => "\xe2\x80\xb0",
55
- 138 => "\xc5\xa0",
56
- 139 => "\xe2\x80\xb9",
57
- 140 => "\xc5\x92",
58
-
59
- 142 => "\xc5\xbd",
60
-
61
-
62
- 145 => "\xe2\x80\x98",
63
- 146 => "\xe2\x80\x99",
64
- 147 => "\xe2\x80\x9c",
65
- 148 => "\xe2\x80\x9d",
66
- 149 => "\xe2\x80\xa2",
67
- 150 => "\xe2\x80\x93",
68
- 151 => "\xe2\x80\x94",
69
- 152 => "\xcb\x9c",
70
- 153 => "\xe2\x84\xa2",
71
- 154 => "\xc5\xa1",
72
- 155 => "\xe2\x80\xba",
73
- 156 => "\xc5\x93",
74
-
75
- 158 => "\xc5\xbe",
76
- 159 => "\xc5\xb8"
77
- );
78
-
79
- protected static $brokenUtf8ToUtf8 = array(
80
- "\xc2\x80" => "\xe2\x82\xac",
81
-
82
- "\xc2\x82" => "\xe2\x80\x9a",
83
- "\xc2\x83" => "\xc6\x92",
84
- "\xc2\x84" => "\xe2\x80\x9e",
85
- "\xc2\x85" => "\xe2\x80\xa6",
86
- "\xc2\x86" => "\xe2\x80\xa0",
87
- "\xc2\x87" => "\xe2\x80\xa1",
88
- "\xc2\x88" => "\xcb\x86",
89
- "\xc2\x89" => "\xe2\x80\xb0",
90
- "\xc2\x8a" => "\xc5\xa0",
91
- "\xc2\x8b" => "\xe2\x80\xb9",
92
- "\xc2\x8c" => "\xc5\x92",
93
-
94
- "\xc2\x8e" => "\xc5\xbd",
95
-
96
-
97
- "\xc2\x91" => "\xe2\x80\x98",
98
- "\xc2\x92" => "\xe2\x80\x99",
99
- "\xc2\x93" => "\xe2\x80\x9c",
100
- "\xc2\x94" => "\xe2\x80\x9d",
101
- "\xc2\x95" => "\xe2\x80\xa2",
102
- "\xc2\x96" => "\xe2\x80\x93",
103
- "\xc2\x97" => "\xe2\x80\x94",
104
- "\xc2\x98" => "\xcb\x9c",
105
- "\xc2\x99" => "\xe2\x84\xa2",
106
- "\xc2\x9a" => "\xc5\xa1",
107
- "\xc2\x9b" => "\xe2\x80\xba",
108
- "\xc2\x9c" => "\xc5\x93",
109
-
110
- "\xc2\x9e" => "\xc5\xbe",
111
- "\xc2\x9f" => "\xc5\xb8"
112
- );
113
-
114
- protected static $utf8ToWin1252 = array(
115
- "\xe2\x82\xac" => "\x80",
116
-
117
- "\xe2\x80\x9a" => "\x82",
118
- "\xc6\x92" => "\x83",
119
- "\xe2\x80\x9e" => "\x84",
120
- "\xe2\x80\xa6" => "\x85",
121
- "\xe2\x80\xa0" => "\x86",
122
- "\xe2\x80\xa1" => "\x87",
123
- "\xcb\x86" => "\x88",
124
- "\xe2\x80\xb0" => "\x89",
125
- "\xc5\xa0" => "\x8a",
126
- "\xe2\x80\xb9" => "\x8b",
127
- "\xc5\x92" => "\x8c",
128
-
129
- "\xc5\xbd" => "\x8e",
130
-
131
-
132
- "\xe2\x80\x98" => "\x91",
133
- "\xe2\x80\x99" => "\x92",
134
- "\xe2\x80\x9c" => "\x93",
135
- "\xe2\x80\x9d" => "\x94",
136
- "\xe2\x80\xa2" => "\x95",
137
- "\xe2\x80\x93" => "\x96",
138
- "\xe2\x80\x94" => "\x97",
139
- "\xcb\x9c" => "\x98",
140
- "\xe2\x84\xa2" => "\x99",
141
- "\xc5\xa1" => "\x9a",
142
- "\xe2\x80\xba" => "\x9b",
143
- "\xc5\x93" => "\x9c",
144
-
145
- "\xc5\xbe" => "\x9e",
146
- "\xc5\xb8" => "\x9f"
147
- );
148
-
149
- static function toUTF8($text){
150
- /**
151
- * Function \ForceUTF8\Encoding::toUTF8
152
- *
153
- * This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8.
154
- *
155
- * It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1.
156
- *
157
- * It may fail to convert characters to UTF-8 if they fall into one of these scenarios:
158
- *
159
- * 1) when any of these characters: ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
160
- * are followed by any of these: ("group B")
161
- * ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶•¸¹º»¼½¾¿
162
- * For example: %ABREPRESENT%C9%BB. «REPRESENTÉ»
163
- * The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB)
164
- * is also a valid unicode character, and will be left unchanged.
165
- *
166
- * 2) when any of these: àáâãäåæçèéêëìíîï are followed by TWO chars from group B,
167
- * 3) when any of these: ðñòó are followed by THREE chars from group B.
168
- *
169
- * @name toUTF8
170
- * @param string $text Any string.
171
- * @return string The same string, UTF8 encoded
172
- *
173
- */
174
-
175
- if(is_array($text))
176
- {
177
- foreach($text as $k => $v)
178
- {
179
- $text[$k] = self::toUTF8($v);
180
- }
181
- return $text;
182
- }
183
-
184
- if(!is_string($text)) {
185
- return $text;
186
- }
187
-
188
- $max = self::strlen($text);
189
-
190
- $buf = "";
191
- for($i = 0; $i < $max; $i++){
192
- $c1 = $text{$i};
193
- if($c1>="\xc0"){ //Should be converted to UTF8, if it's not UTF8 already
194
- $c2 = $i+1 >= $max? "\x00" : $text{$i+1};
195
- $c3 = $i+2 >= $max? "\x00" : $text{$i+2};
196
- $c4 = $i+3 >= $max? "\x00" : $text{$i+3};
197
- if($c1 >= "\xc0" & $c1 <= "\xdf"){ //looks like 2 bytes UTF8
198
- if($c2 >= "\x80" && $c2 <= "\xbf"){ //yeah, almost sure it's UTF8 already
199
- $buf .= $c1 . $c2;
200
- $i++;
201
- } else { //not valid UTF8. Convert it.
202
- $cc1 = (chr(ord($c1) / 64) | "\xc0");
203
- $cc2 = ($c1 & "\x3f") | "\x80";
204
- $buf .= $cc1 . $cc2;
205
- }
206
- } elseif($c1 >= "\xe0" & $c1 <= "\xef"){ //looks like 3 bytes UTF8
207
- if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf"){ //yeah, almost sure it's UTF8 already
208
- $buf .= $c1 . $c2 . $c3;
209
- $i = $i + 2;
210
- } else { //not valid UTF8. Convert it.
211
- $cc1 = (chr(ord($c1) / 64) | "\xc0");
212
- $cc2 = ($c1 & "\x3f") | "\x80";
213
- $buf .= $cc1 . $cc2;
214
- }
215
- } elseif($c1 >= "\xf0" & $c1 <= "\xf7"){ //looks like 4 bytes UTF8
216
- if($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf"){ //yeah, almost sure it's UTF8 already
217
- $buf .= $c1 . $c2 . $c3 . $c4;
218
- $i = $i + 3;
219
- } else { //not valid UTF8. Convert it.
220
- $cc1 = (chr(ord($c1) / 64) | "\xc0");
221
- $cc2 = ($c1 & "\x3f") | "\x80";
222
- $buf .= $cc1 . $cc2;
223
- }
224
- } else { //doesn't look like UTF8, but should be converted
225
- $cc1 = (chr(ord($c1) / 64) | "\xc0");
226
- $cc2 = (($c1 & "\x3f") | "\x80");
227
- $buf .= $cc1 . $cc2;
228
- }
229
- } elseif(($c1 & "\xc0") == "\x80"){ // needs conversion
230
- if(isset(self::$win1252ToUtf8[ord($c1)])) { //found in Windows-1252 special cases
231
- $buf .= self::$win1252ToUtf8[ord($c1)];
232
- } else {
233
- $cc1 = (chr(ord($c1) / 64) | "\xc0");
234
- $cc2 = (($c1 & "\x3f") | "\x80");
235
- $buf .= $cc1 . $cc2;
236
- }
237
- } else { // it doesn't need conversion
238
- $buf .= $c1;
239
- }
240
- }
241
- return $buf;
242
- }
243
-
244
- static function toWin1252($text, $option = '') {
245
- if(is_array($text)) {
246
- foreach($text as $k => $v) {
247
- $text[$k] = self::toWin1252($v, $option);
248
- }
249
- return $text;
250
- } elseif(is_string($text)) {
251
- return static::utf8_decode($text, $option);
252
- } else {
253
- return $text;
254
- }
255
- }
256
-
257
- static function toISO8859($text) {
258
- return self::toWin1252($text);
259
- }
260
-
261
- static function toLatin1($text) {
262
- return self::toWin1252($text);
263
- }
264
-
265
- static function fixUTF8($text, $option = ''){
266
- if(is_array($text)) {
267
- foreach($text as $k => $v) {
268
- $text[$k] = self::fixUTF8($v, $option);
269
- }
270
- return $text;
271
- }
272
-
273
- $last = "";
274
- while($last <> $text){
275
- $last = $text;
276
- $text = self::toUTF8(static::utf8_decode($text, $option));
277
- }
278
- $text = self::toUTF8(static::utf8_decode($text, $option));
279
- return $text;
280
- }
281
-
282
- static function UTF8FixWin1252Chars($text){
283
- // If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1
284
- // (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
285
- // See: http://en.wikipedia.org/wiki/Windows-1252
286
-
287
- return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text);
288
- }
289
-
290
- static function removeBOM($str=""){
291
- if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
292
- $str=substr($str, 3);
293
- }
294
- return $str;
295
- }
296
-
297
- protected static function strlen($text){
298
- return (function_exists('mb_strlen') && ((int) ini_get('mbstring.func_overload')) & 2) ?
299
- mb_strlen($text,'8bit') : strlen($text);
300
- }
301
-
302
- public static function normalizeEncoding($encodingLabel)
303
- {
304
- $encoding = strtoupper($encodingLabel);
305
- $encoding = preg_replace('/[^a-zA-Z0-9\s]/', '', $encoding);
306
- $equivalences = array(
307
- 'ISO88591' => 'ISO-8859-1',
308
- 'ISO8859' => 'ISO-8859-1',
309
- 'ISO' => 'ISO-8859-1',
310
- 'LATIN1' => 'ISO-8859-1',
311
- 'LATIN' => 'ISO-8859-1',
312
- 'UTF8' => 'UTF-8',
313
- 'UTF' => 'UTF-8',
314
- 'WIN1252' => 'ISO-8859-1',
315
- 'WINDOWS1252' => 'ISO-8859-1'
316
- );
317
-
318
- if(empty($equivalences[$encoding])){
319
- return 'UTF-8';
320
- }
321
-
322
- return $equivalences[$encoding];
323
- }
324
-
325
- public static function encode($encodingLabel, $text)
326
- {
327
- $encodingLabel = self::normalizeEncoding($encodingLabel);
328
- if($encodingLabel == 'ISO-8859-1') return self::toLatin1($text);
329
- return self::toUTF8($text);
330
- }
331
-
332
- protected static function utf8_decode($text, $option)
333
- {
334
- if ($option == '' || !function_exists('iconv')) {
335
- $o = utf8_decode(
336
- str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text))
337
- );
338
- } else {
339
- $o = iconv("UTF-8", "Windows-1252" . ($option == 'TRANSLIT' ? '//TRANSLIT' : ($option == 'IGNORE' ? '//IGNORE' : '')), $text);
340
- }
341
- return $o;
342
- }
343
- }