VaultPress - Version 2.0

Version Description

  • Release date: July 9, 2019

Enhancements

  • Dashboard: redesign the main VaultPress dashboard.

Compatibility

  • General: VaultPress now requires PHP 5.3.2, and will display a notice if your site uses an older version of PHP.
Download this release

Release Info

Developer jeherve
Plugin Icon 128x128 VaultPress
Version 2.0
Comparing to
See all releases

Code changes from version 1.9.10 to 2.0

changelog.txt ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ == Changelog ==
2
+
3
+ **This is a list detailing changes for all the past Jetpack releases. For more information about the current release, see [the readme](https://github.com/Automattic/vaultpress/blob/master/readme.txt).**
4
+
5
+ = 1.9.9 - 28 March 2019 =
6
+ * PHP 7.2.0 compatibility fix.
7
+ * Adding button to delete all VaultPress settings
8
+
9
+ = 1.9.8 - 7 February 2019 =
10
+ * Limit the size of _vp_ai_ping_% entries when a site gets disconnected from VaultPress.com
11
+
12
+ = 1.9.7 - 11 December 2018 =
13
+ * Update firewall IP detection rules to autodetect various reverse proxy setups
14
+
15
+ = 1.9.6 - 17 August 2018 =
16
+ * Limit _vp_ai_ping_% entries to improve stability when a site gets disconnected from VaultPress.com
17
+
18
+ = 1.9.5 - 2 February 2018 =
19
+ * Removing activation notice
20
+
21
+ = 1.9.4 - 15 November 2017 =
22
+ * Error handling improvements in the scanner
23
+
24
+ = 1.9.3 - 9 November 2017 =
25
+ * Compatibility update
26
+ * Send a better user-agent string to VaultPress servers
27
+
28
+ = 1.9.2 - 6 July 2017 =
29
+ * Compatibility update
30
+
31
+ = 1.9.1 - 29 June 2017 =
32
+ * Security improvement: use hash_equals to compare signatures
33
+
34
+ = 1.9.0 - 5 June 2017 =
35
+ * Bugfix: Check return value from openssl_verify()
36
+
37
+ = 1.8.9 - 8 May 2017 =
38
+ * Remove outdated free trial link
39
+
40
+ = 1.8.7 - 6 March 2017 =
41
+ * Security fix for https://wpvulndb.com/vulnerabilities/8745
42
+
43
+ = 1.8.6 - 26 January 2016 =
44
+ * Compatibility updates
45
+ * Security hotfixes
46
+ * Improved performance for security scanner
47
+ * Misc small bugfixes
48
+
49
+ = 1.8.5 - 7 August 2016 =
50
+ * Delete plugin option when plugin is deleted via admin area.
51
+ * Fix horizontal scroll bar on the fresh installation settings page at high resolutions.
52
+
53
+ = 1.8.4 - 21 July 2016 =
54
+ * Compatibility updates for Jetpack 4.1
55
+
56
+ = 1.8.3 - 26 May 2016 =
57
+ * Security: Hotfix for certain versions of Jetpack
58
+
59
+ = 1.8.2 - 11 May 2016 =
60
+ * Workaround for some versions of mod_security.
61
+
62
+ = 1.8.1 - 29 Mar 2016 =
63
+ * Improved support for WooCommerce live backups.
64
+ * Bugfix: Avoid cloning the 'vaultpress' option between Multisite instances.
65
+
66
+ = 1.8.0 - 7 Mar 2016 =
67
+ * Add support for an upcoming ability to have the Jetpack plugin manage registering the VaultPress plugin and entering the required API key. Gone will be the days of needing to copy/paste it!
68
+
69
+ = 1.7.9 - 24 Feb 2016 =
70
+ * PHP 7 support. Drop support for PHP 4 and versions of WordPress older than 3.2.
71
+ * Silence PHP errors when attempting to change the execution time limit when PHP is running in safe mode.
72
+ * Prevent database update pings from being stored when not connected to a paid VaultPress account.
73
+
74
+ = 1.7.8 - 15 Oct 2015 =
75
+ * Security: Hotfix for Akismet < 3.1.5.
76
+
77
+ = 1.7.7 - 15 Sep 2015 =
78
+ * Security: Add a new security hotfix.
79
+
80
+ = 1.7.6 - 14 Aug 2015 =
81
+ * Improved support for multisite installs with custom domains
82
+ * Improved live-backup support for WooCommerce
83
+ * Tested against WordPress 4.3
84
+
85
+ = 1.7.5 - 11 Jun 2015 =
86
+ * Security: Add a new security hotfix.
87
+
88
+ = 1.7.4 - 28 Apr 2015 =
89
+ * Bugfix: Don't allow openssl signing unless the public key exists.
90
+
91
+ = 1.7.3 - 27 Apr 2015 =
92
+ * Security: Add a new security hotfix.
93
+
94
+ = 1.7.2 - 20 Apr 2015 =
95
+ * Hotfix: Protect against a core security issue.
96
+ * Bugfix: Don't allow direct access to plugin files
97
+ * Bugfix: Ensure that the firewall rule option is not autoloaded.
98
+ * Bugfix: More careful path tidy-up when inspecting directory contents. Fixes an edge case where some sites were having backup problems.
99
+
100
+ = 1.7.1 - 25 Mar 2015 =
101
+ * Added support for openssl signing.
102
+
103
+ = 1.7.0 - 9 Jan 2015 =
104
+ * Added an option to disable calls to php_uname, as some hosts don't allow them.
105
+
106
+ = 1.6.9 - 24 Dec 2014 =
107
+ * Tested against WordPress 4.1
108
+
109
+ = 1.6.8 - 12 Dec 2014 =
110
+ * Bugfix: Fall back on HTTP when updating firewall via HTTPS fails. Still warn the user about the security implications.
111
+
112
+ = 1.6.7 - 1 Dec 2014 =
113
+ * Security: More efficient format for internal firewall IPs.
114
+
115
+ = 1.6.6 - 14 Nov 2014 =
116
+ * Security: Fetch service IP updates via HTTPS.
117
+ * Feature: Don't send backup notifications while mass-deleting spam.
118
+
119
+ = 1.6.5 - 4 Sep 2014 =
120
+ * Security: Hotfix for the Slider Revolution plugin.
121
+
122
+ = 1.6.4 - 3 Sep 2014 =
123
+ * Bumping the "Tested up to" tag to 4.0
124
+
125
+ = 1.6.3 - 30 Jul 2014 =
126
+ * Bugfix: Make sure existing empty key and secret options are always strings. This fixes an error when run with HHVM.
127
+ * Bugfix: Detect if the plugin has been installed on localhost and show an error.
128
+ * CSS Fix: Stop the "Register" button from bouncing around when clicked.
129
+
130
+ = 1.6.2 - 10 Jul 2014 =
131
+ * Feature: Instantly register for a VaultPress trial via Jetpack.
132
+ * Bugfix: Make sure the key and secret options are always strings. This fixes an error when run with HHVM.
133
+
134
+ = 1.6.1 - 1 Jul 2014 =
135
+ * Security: Add a new security hotfix.
136
+
137
+ = 1.6 - 27 Jun 2014 =
138
+ * Bugfix: Better handling for Multisite table prefixes.
139
+ * Bugfix: Do not use the deprecated wpdb::escape() method.
140
+
141
+ = 1.5.9 - 16 Jun 2014 =
142
+ * Feature: If available, use command line md5sum and sha1sum to get checksums for large files.
143
+
144
+ = 1.5.8 - 3 Jun 2014 =
145
+ * Security: Add a new security hotfix.
146
+
147
+ = 1.5.7 - 11 Apr 2014 =
148
+ * Bugfix: Avoid PHP 5.4 warnings due to invalid constructor names.
149
+ * Security: Add a new security hotfix.
150
+
151
+ = 1.5.6 - 1 Apr 2014 =
152
+ * Bugfix: Avoid PHP 5.4 warnings.
153
+ * Bugfix: Some servers with restrictive security filters make database restores fail.
154
+ * Feature: Add a new restore method to VaultPress_Database.
155
+
156
+ = 1.5.2 - 26 Dec 2013 =
157
+ * Bugfix: Adding less greedy patterns for cache directories.
158
+
159
+ = 1.5.1 - 16 Dec 2013 =
160
+ * Feature: Adding file exclusion patterns to avoid backing up cache and backup directories.
161
+
162
+ = 1.5 - 11 Dec 2013 =
163
+ * Bugfix: Don't show admin notices on the about page.
164
+
165
+ = 1.4.9 - 10 Oct 2013 =
166
+ * Bugfix: Clean up PHP5 strict warnings.
167
+
168
+ = 1.4.8 - 15 Jul 2013 =
169
+ * Feature: Include styles and images with the plugin instead of loading them externally.
170
+
171
+ = 1.4.7 - 2 Jul 2013 =
172
+ * Bugfix: Some servers have SSL configuration problems, which breaks the plugin when SSL verification is enforced.
173
+
174
+ = 1.4.6 - 26 Jun 2013 =
175
+ * Bugfix: PHP 5.4 notices
176
+ * Feature: Add the possibility to ignore frequent updates on some postmeta keys.
177
+
178
+ = 1.3.9 =
179
+ * Feature: Request decoding (base64/rot13)
180
+ * Feature: Response encoding (base64/rot13)
181
+
182
+ = 1.3.8 =
183
+ * Bugfix: Validate IPv4-mapped IPv6 addresses in the internal firewall.
184
+ * Bugfix: Fix hooks not being properly added under certain circumstances.
185
+
186
+ = 1.3.7 =
187
+ * Bugfix: Protect against infinite loop due to a PHP bug.
188
+ * Bugfix: Encode remote ping requests.
189
+
190
+ = 1.0 =
191
+ * First public release!
class-vaultpress.php ADDED
@@ -0,0 +1,2822 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Main VaultPress class.
4
+ *
5
+ * @package VaultPress
6
+ */
7
+
8
+ use Automattic\Jetpack\Assets\Logo;
9
+
10
+ /**
11
+ * Main VaultPress class.
12
+ */
13
+ class VaultPress {
14
+ var $option_name = 'vaultpress';
15
+ var $auto_register_option = 'vaultpress_auto_register';
16
+ var $db_version = 4;
17
+ var $plugin_version = VAULTPRESS__VERSION;
18
+
19
+ function __construct() {
20
+ register_activation_hook( __FILE__, array( $this, 'activate' ) );
21
+ register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
22
+
23
+ $this->options_blog_id = get_current_blog_id();
24
+ $options = get_option( $this->option_name );
25
+ if ( !is_array( $options ) )
26
+ $options = array();
27
+
28
+ $defaults = array(
29
+ 'db_version' => 0,
30
+ 'key' => '',
31
+ 'secret' => '',
32
+ 'connection' => false,
33
+ 'service_ips_cidr' => false
34
+ );
35
+
36
+ $this->options = wp_parse_args( $options, $defaults );
37
+ $this->reset_pings();
38
+
39
+ $this->upgrade();
40
+
41
+ $this->add_global_actions_and_filters();
42
+
43
+ if ( is_admin() ) {
44
+ $this->add_admin_actions_and_filters();
45
+ }
46
+
47
+ if ( $this->is_registered() ) {
48
+ $do_not_backup = $this->get_option( 'do_not_backup' ) || $this->get_option( 'do_not_send_backup_pings' );
49
+ if ( $do_not_backup )
50
+ $this->add_vp_required_filters();
51
+ else
52
+ $this->add_listener_actions_and_filters();
53
+ }
54
+ }
55
+
56
+ static function &init() {
57
+ static $instance = false;
58
+
59
+ if ( !$instance ) {
60
+ $instance = new VaultPress();
61
+ }
62
+
63
+ return $instance;
64
+ }
65
+
66
+ static function register( $registration_key ) {
67
+ $vp = self::init();
68
+
69
+ $nonce = wp_create_nonce( 'vp_register_' . $registration_key );
70
+ $args = array( 'registration_key' => $registration_key, 'nonce' => $nonce );
71
+ $response = $vp->contact_service( 'register', $args );
72
+
73
+ // Check for an error
74
+ if ( ! empty( $response['faultCode'] ) )
75
+ return new WP_Error( $response['faultCode'], $response['faultString'] );
76
+
77
+ // Validate result
78
+ if ( empty( $response['key'] ) || empty( $response['secret'] ) || empty( $response['nonce'] ) || $nonce != $response['nonce'] )
79
+ return new WP_Error( 1, __( 'There was a problem trying to register your VaultPress subscription.' ) );
80
+
81
+ // Store the result, force a connection test.
82
+ $vp->update_option( 'key', $response['key'] );
83
+ $vp->update_option( 'secret', $response['secret'] );
84
+ $vp->check_connection( true );
85
+
86
+ return true;
87
+ }
88
+
89
+ function activate( $network_wide ) {
90
+ $type = $network_wide ? 'network' : 'single';
91
+ $this->update_option( 'activated', $type );
92
+
93
+ // force a connection check after an activation
94
+ $this->clear_connection();
95
+
96
+ if ( get_option( 'vaultpress_auto_connect' ) ) {
97
+ $this->register_via_jetpack( true );
98
+ }
99
+ }
100
+
101
+ function deactivate() {
102
+ if ( $this->is_registered() )
103
+ $this->contact_service( 'plugin_status', array( 'vp_plugin_status' => 'deactivated' ) );
104
+ }
105
+
106
+ function upgrade() {
107
+ $current_db_version = $this->get_option( 'db_version' );
108
+
109
+ if ( $current_db_version < 1 ) {
110
+ $this->options['connection'] = get_option( 'vaultpress_connection' );
111
+ $this->options['key'] = get_option( 'vaultpress_key' );
112
+ $this->options['secret'] = get_option( 'vaultpress_secret' );
113
+ $this->options['service_ips'] = get_option( 'vaultpress_service_ips' );
114
+
115
+ // remove old options
116
+ $old_options = array(
117
+ 'vaultpress_connection',
118
+ 'vaultpress_hostname',
119
+ 'vaultpress_key',
120
+ 'vaultpress_secret',
121
+ 'vaultpress_service_ips',
122
+ 'vaultpress_timeout',
123
+ 'vp_allow_remote_execution',
124
+ 'vp_debug_request_signing',
125
+ 'vp_disable_firewall',
126
+ );
127
+
128
+ foreach ( $old_options as $option )
129
+ delete_option( $option );
130
+
131
+ $this->options['db_version'] = $this->db_version;
132
+ $this->update_options();
133
+ }
134
+
135
+ if ( $current_db_version < 2 ) {
136
+ $this->delete_option( 'timeout' );
137
+ $this->delete_option( 'disable_firewall' );
138
+ $this->update_option( 'db_version', $this->db_version );
139
+ $this->clear_connection();
140
+ }
141
+
142
+ if ( $current_db_version < 3 ) {
143
+ $this->update_firewall();
144
+ $this->update_option( 'db_version', $this->db_version );
145
+ $this->clear_connection();
146
+ }
147
+
148
+ if ( $current_db_version < 4 ) {
149
+ $this->update_firewall();
150
+ $this->update_option( 'db_version', $this->db_version );
151
+ $this->clear_connection();
152
+ }
153
+ }
154
+
155
+ function get_option( $key ) {
156
+ if ( 'hostname' == $key ) {
157
+ if ( defined( 'VAULTPRESS_HOSTNAME' ) )
158
+ return VAULTPRESS_HOSTNAME;
159
+ else
160
+ return 'vaultpress.com';
161
+ }
162
+
163
+ if ( 'timeout' == $key ) {
164
+ if ( defined( 'VAULTPRESS_TIMEOUT' ) )
165
+ return VAULTPRESS_TIMEOUT;
166
+ else
167
+ return 60;
168
+ }
169
+
170
+ if ( 'disable_firewall' == $key ) {
171
+ if ( defined( 'VAULTPRESS_DISABLE_FIREWALL' ) )
172
+ return VAULTPRESS_DISABLE_FIREWALL;
173
+ else
174
+ return false;
175
+ }
176
+
177
+ if ( ( 'key' == $key || 'secret' == $key ) && empty( $this->options[$key] ) ) {
178
+ return '';
179
+ }
180
+
181
+ // allow_forwarded_for can be overrided by config, or stored in or out of the vp option
182
+ if ( 'allow_forwarded_for' === $key ) {
183
+ if ( defined( 'ALLOW_FORWARDED_FOR' ) ) {
184
+ return ALLOW_FORWARDED_FOR;
185
+ }
186
+
187
+ $standalone_option = get_option( 'vaultpress_allow_forwarded_for' );
188
+ if ( ! empty( $standalone_option ) ) {
189
+ return $standalone_option;
190
+ }
191
+ }
192
+
193
+ if ( isset( $this->options[$key] ) )
194
+ return $this->options[$key];
195
+
196
+ return false;
197
+ }
198
+
199
+ function update_option( $key, $value ) {
200
+ if ( 'allow_forwarded_for' === $key ) {
201
+ update_option( 'vaultpress_allow_forwarded_for', $value );
202
+
203
+ if ( isset( $this->options[ $key ] ) ) {
204
+ unset( $this->options[ $key ] );
205
+ $this->update_options();
206
+ }
207
+ return;
208
+ }
209
+
210
+ $this->options[$key] = $value;
211
+ $this->update_options();
212
+ }
213
+
214
+ function delete_option( $key ) {
215
+ if ( 'allow_forwarded_for' === $key ) {
216
+ delete_option( 'vaultpress_allow_forwarded_for' );
217
+ }
218
+
219
+ unset( $this->options[$key] );
220
+ $this->update_options();
221
+ }
222
+
223
+ function update_options() {
224
+ // Avoid overwriting the VaultPress option if current blog_id has changed since reading it
225
+ if ( get_current_blog_id() !== $this->options_blog_id ) {
226
+ return;
227
+ }
228
+
229
+ update_option( $this->option_name, $this->options );
230
+ }
231
+
232
+ function admin_init() {
233
+ if ( !current_user_can( 'manage_options' ) )
234
+ return;
235
+
236
+ load_plugin_textdomain( 'vaultpress', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
237
+ }
238
+
239
+ function admin_head() {
240
+ if ( ! current_user_can( 'manage_options' ) ) {
241
+ return;
242
+ }
243
+
244
+ // Array of hooks where we want to hook our notices.
245
+ $notice_hooks = array( 'user_admin_notices' );
246
+
247
+ /*
248
+ * In the VaultPress dashboard, move the notices.
249
+ */
250
+ $screen = get_current_screen();
251
+ if (
252
+ ! is_null( $screen )
253
+ && in_array(
254
+ $screen->id,
255
+ array( 'jetpack_page_vaultpress', 'toplevel_page_vaultpress' ),
256
+ true
257
+ )
258
+ ) {
259
+ $notice_hooks[] = 'vaultpress_notices';
260
+ } else {
261
+ $notice_hooks[] = 'admin_notices';
262
+ }
263
+
264
+ if ( $activated = $this->get_option( 'activated' ) ) {
265
+ if ( 'network' == $activated ) {
266
+ add_action( 'network_admin_notices', array( $this, 'activated_notice' ) );
267
+ } else {
268
+ foreach ( $notice_hooks as $filter ) {
269
+ add_action( $filter, array( $this, 'activated_notice' ) );
270
+ }
271
+ }
272
+ }
273
+
274
+ // ask the user to connect their site w/ VP
275
+ if ( !$this->is_registered() ) {
276
+ foreach ( $notice_hooks as $filter ) {
277
+ add_action( $filter, array( $this, 'connect_notice' ) );
278
+ }
279
+
280
+ // if we have an error make sure to let the user know about it
281
+ } else {
282
+ $error_code = $this->get_option( 'connection_error_code' );
283
+ if ( ! empty( $error_code ) ) {
284
+ foreach ( $notice_hooks as $filter ) {
285
+ add_action( $filter, array( $this, 'error_notice' ) );
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ function admin_menu() {
292
+ // if Jetpack is loaded then we need to wait for that menu to be added
293
+ if ( class_exists( 'Jetpack' ) )
294
+ add_action( 'jetpack_admin_menu', array( $this, 'load_menu' ) );
295
+ else
296
+ $this->load_menu();
297
+ }
298
+
299
+ function load_menu() {
300
+ if ( class_exists( 'Jetpack' ) ) {
301
+ $hook = add_submenu_page( 'jetpack', 'VaultPress', 'VaultPress', 'manage_options', 'vaultpress', array( $this, 'ui' ) );
302
+ } else {
303
+ $hook = add_menu_page( 'VaultPress', 'VaultPress', 'manage_options', 'vaultpress', array( $this, 'ui' ), 'div' );
304
+ }
305
+
306
+ add_action( "load-$hook", array( $this, 'ui_load' ) );
307
+ add_action( 'admin_print_styles', array( $this, 'styles' ) );
308
+ }
309
+
310
+ function styles() {
311
+ if ( !current_user_can( 'manage_options' ) || !is_admin() )
312
+ return;
313
+
314
+ wp_enqueue_style( 'vaultpress-nav', plugins_url( '/nav-styles.css', __FILE__ ), false, date( 'Ymd' ) );
315
+
316
+ if ( isset( $_GET['page'] ) && 'vaultpress' == $_GET['page'] )
317
+ wp_enqueue_style( 'vaultpress', plugins_url( '/styles.css', __FILE__ ), false, date( 'Ymd' ) );
318
+ }
319
+
320
+ // display a security threat notice if one exists
321
+ function toolbar( $wp_admin_bar ) {
322
+ global $wp_version;
323
+
324
+ // these new toolbar functions were introduced in 3.3
325
+ // http://codex.wordpress.org/Function_Reference/add_node
326
+ if ( version_compare( $wp_version, '3.3', '<') )
327
+ return;
328
+
329
+ if ( !current_user_can( 'manage_options' ) )
330
+ return;
331
+
332
+ $messages = $this->get_messages();
333
+ if ( !empty( $messages['security_notice_count'] ) ) {
334
+ $count = (int)$messages['security_notice_count'];
335
+ if ( $count > 0 ) {
336
+ $count = number_format( $count, 0 );
337
+ $wp_admin_bar->add_node( array(
338
+ 'id' => 'vp-notice',
339
+ 'title' => '<span class="ab-icon"></span>' .
340
+ sprintf( _n( '%s Security Threat', '%s Security Threats', $count , 'vaultpress'), $count ),
341
+ 'parent' => 'top-secondary',
342
+ 'href' => sprintf( 'https://dashboard.vaultpress.com/%d/security/', $messages['site_id'] ),
343
+ 'meta' => array(
344
+ 'title' => __( 'Visit VaultPress Security' , 'vaultpress'),
345
+ 'onclick' => 'window.open( this.href ); return false;',
346
+ 'class' => 'error'
347
+ ),
348
+ ) );
349
+ }
350
+ }
351
+ }
352
+
353
+ // get any messages from the VP servers
354
+ function get_messages( $force_reload = false ) {
355
+ $last_contact = $this->get_option( 'messages_last_contact' );
356
+
357
+ // only run the messages check every 30 minutes
358
+ if ( ( time() - (int)$last_contact ) > 1800 || $force_reload ) {
359
+ $messages = base64_decode( $this->contact_service( 'messages', array() ) );
360
+ $messages = unserialize( $messages );
361
+ $this->update_option( 'messages_last_contact', time() );
362
+ $this->update_option( 'messages', $messages );
363
+ } else {
364
+ $messages = $this->get_option( 'messages' );
365
+ }
366
+
367
+ return $messages;
368
+ }
369
+
370
+ function server_url() {
371
+ if ( !isset( $this->_server_url ) ) {
372
+ $scheme = is_ssl() ? 'https' : 'http';
373
+ $this->_server_url = sprintf( '%s://%s/', $scheme, $this->get_option( 'hostname' ) );
374
+ }
375
+
376
+ return $this->_server_url;
377
+ }
378
+
379
+ // show message if plugin is activated but not connected to VaultPress
380
+ function connect_notice() {
381
+ if ( isset( $_GET['page'] ) && 'vaultpress' == $_GET['page'] )
382
+ return;
383
+
384
+ $message = sprintf(
385
+ __( 'You must enter your registration key before VaultPress can back up and secure your site. <a href="%1$s">Register&nbsp;VaultPress</a>', 'vaultpress' ),
386
+ admin_url( 'admin.php?page=vaultpress' )
387
+ );
388
+ $this->ui_message( $message, 'notice', __( 'VaultPress needs your attention!', 'vaultpress' ) );
389
+ }
390
+
391
+ // show message after activation
392
+ function activated_notice() {
393
+ if ( 'network' == $this->get_option( 'activated' ) ) {
394
+ $message = sprintf(
395
+ __( 'Each site will need to be registered with VaultPress separately. You can purchase new keys from your <a href="%1$s">VaultPress&nbsp;Dashboard</a>.', 'vaultpress' ),
396
+ 'https://dashboard.vaultpress.com/'
397
+ );
398
+ $this->ui_message( $message, 'activated', __( 'VaultPress has been activated across your network!', 'vaultpress' ) );
399
+
400
+ // key and secret already exist in db
401
+ } elseif ( $this->is_registered() ) {
402
+ if ( $this->check_connection() ) {
403
+ }
404
+ }
405
+
406
+ $this->delete_option( 'activated' );
407
+ }
408
+
409
+ function error_notice() {
410
+ $error_message = $this->get_option( 'connection_error_message' );
411
+
412
+ // link to the VaultPress page if we're not already there
413
+ if ( !isset( $_GET['page'] ) || 'vaultpress' != $_GET['page'] ) {
414
+ $error_message .= ' ' . sprintf( '<a href="%s">%s</a>', admin_url( 'admin.php?page=vaultpress' ), __( 'Visit&nbsp;the&nbsp;VaultPress&nbsp;page' , 'vaultpress') );
415
+ }
416
+
417
+ $screen = get_current_screen();
418
+ if ( !in_array( $screen->id, array( 'about', 'about-user', 'about-network' ) ) && !empty( $error_message ) ) {
419
+ $this->ui_message( $error_message, 'error' );
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Adds the main wrappers and the header, and defers controls to ui_render to decide which view to render.
425
+ */
426
+ function ui() {
427
+ $ui_state = $this->ui_render();
428
+ ?>
429
+ <div id="jp-plugin-container">
430
+ <?php $this->ui_masthead( $ui_state[ 'dashboard_link' ] ); ?>
431
+ <div class="vp-wrap">
432
+ <?php
433
+ /**
434
+ * Allow the display of custom notices.
435
+ *
436
+ * @since 2.0.0
437
+ */
438
+ do_action( 'vaultpress_notices' );
439
+ ?>
440
+ <?php echo $ui_state[ 'ui' ]; // This content is sanitized when it's produced. ?>
441
+ </div>
442
+ <?php $this->ui_footer(); ?>
443
+ </div>
444
+ <?php
445
+ }
446
+
447
+ /**
448
+ * Decides which UI view to render and executes it.
449
+ *
450
+ * @return array $args {
451
+ * An array of options to render the dashboard.
452
+ *
453
+ * @type string $ui Dashboard markup.
454
+ * @type string $dashboard_link Whether to show the link to the VaultPress dashboard.
455
+ * }
456
+ */
457
+ function ui_render() {
458
+ ob_start();
459
+
460
+ if ( $this->is_localhost() ) {
461
+ $this->update_option( 'connection', time() );
462
+ $this->update_option( 'connection_error_code', 'error_localhost' );
463
+ $this->update_option( 'connection_error_message', 'Hostnames such as localhost or 127.0.0.1 can not be reached by vaultpress.com and will not work with the service. Sites must be publicly accessible in order to work with VaultPress.' );
464
+ $this->error_notice();
465
+ return array( 'ui' => ob_get_clean(), 'dashboard_link' => false );
466
+ }
467
+
468
+ if ( ! empty( $_GET[ 'error' ] ) ) {
469
+ $this->error_notice();
470
+ $this->clear_connection();
471
+ }
472
+
473
+ if ( ! $this->is_registered() ) {
474
+ $this->ui_register();
475
+ return array( 'ui' => ob_get_clean(), 'dashboard_link' => true );
476
+ }
477
+
478
+ $status = $this->contact_service( 'status' );
479
+ if ( ! $status ) {
480
+ $error_code = $this->get_option( 'connection_error_code' );
481
+ if ( 0 == $error_code ) {
482
+ $this->ui_fatal_error();
483
+ } else {
484
+ $this->ui_register();
485
+ }
486
+ return array( 'ui' => ob_get_clean(), 'dashboard_link' => 0 != $error_code );
487
+ }
488
+
489
+ $ticker = $this->contact_service( 'ticker' );
490
+ if ( is_array( $ticker ) && isset( $ticker[ 'faultCode' ] ) ) {
491
+ $this->error_notice();
492
+ $this->ui_register();
493
+ return array( 'ui' => ob_get_clean(), 'dashboard_link' => true );
494
+ }
495
+
496
+ $this->ui_main();
497
+ return array( 'ui' => ob_get_clean(), 'dashboard_link' => true );
498
+ }
499
+
500
+ function ui_load() {
501
+ if ( ! current_user_can( 'manage_options' ) ) {
502
+ return;
503
+ }
504
+
505
+ if ( isset( $_POST['action'] ) && 'delete-vp-settings' == $_POST['action'] ) {
506
+ check_admin_referer( 'delete_vp_settings' );
507
+
508
+ $ai_ping_queue_size = $this->ai_ping_queue_size();
509
+ if ( ! empty( $ai_ping_queue_size->option_count ) && $ai_ping_queue_size->option_count > 1 ) {
510
+ $this->ai_ping_queue_delete();
511
+ }
512
+
513
+ delete_option( $this->option_name );
514
+ delete_option( 'vaultpress_service_ips_external_cidr' );
515
+ delete_option( '_vp_signatures' );
516
+ delete_option( '_vp_config_option_name_ignore' );
517
+ delete_option( '_vp_config_post_meta_name_ignore' );
518
+ delete_option( '_vp_config_should_ignore_files' );
519
+ delete_option( '_vp_current_scan' );
520
+ delete_option( 'vaultpress_auto_register' );
521
+
522
+ wp_redirect( admin_url( 'admin.php?page=vaultpress&delete-vp-settings=1' ) );
523
+ exit();
524
+ }
525
+
526
+ // run code that might be updating the registration key
527
+ if ( isset( $_POST['action'] ) && 'register' == $_POST['action'] ) {
528
+ check_admin_referer( 'vaultpress_register' );
529
+
530
+ // reset the connection info so messages don't cross
531
+ $this->clear_connection();
532
+
533
+ // if registering via Jetpack, get a key...
534
+ if ( isset( $_POST['key_source'] ) && 'jetpack' === $_POST['key_source'] ) {
535
+ $registration_key = $this->get_key_via_jetpack();
536
+ if ( is_wp_error( $registration_key ) ) {
537
+ $this->update_option( 'connection_error_code', -2 );
538
+ $this->update_option(
539
+ 'connection_error_message',
540
+ sprintf( __('<strong>Failed to register VaultPress via Jetpack</strong>: %s. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ),
541
+ esc_html( $registration_key->get_error_message() ), 'http://vaultpress.com/contact/' )
542
+ );
543
+ wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
544
+ exit();
545
+ }
546
+ } else {
547
+ $registration_key = trim( $_POST[ 'registration_key' ] );
548
+ }
549
+
550
+ if ( empty( $registration_key ) ) {
551
+ $this->update_option( 'connection_error_code', 1 );
552
+ $this->update_option(
553
+ 'connection_error_message',
554
+ sprintf(
555
+ __( '<strong>That\'s not a valid registration key.</strong> Head over to the <a href="%1$s" title="Sign in to your VaultPress Dashboard">VaultPress&nbsp;Dashboard</a> to find your key.', 'vaultpress' ),
556
+ 'https://dashboard.vaultpress.com/'
557
+ )
558
+ );
559
+ wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
560
+ exit();
561
+ }
562
+
563
+ // try to register the plugin
564
+ $nonce = wp_create_nonce( 'vp_register_' . $registration_key );
565
+ $args = array( 'registration_key' => $registration_key, 'nonce' => $nonce );
566
+ $response = $this->contact_service( 'register', $args );
567
+
568
+ // we received an error from the VaultPress servers
569
+ if ( !empty( $response['faultCode'] ) ) {
570
+ $this->update_option( 'connection_error_code', $response['faultCode'] );
571
+ $this->update_option( 'connection_error_message', $response['faultString'] );
572
+ wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
573
+ exit();
574
+ }
575
+
576
+ // make sure the returned data looks valid
577
+ if ( empty( $response['key'] ) || empty( $response['secret'] ) || empty( $response['nonce'] ) || $nonce != $response['nonce'] ) {
578
+ $this->update_option( 'connection_error_code', 1 );
579
+ $this->update_option( 'connection_error_message', sprintf( __( 'There was a problem trying to register your subscription. Please try again. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
580
+ wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
581
+ exit();
582
+ }
583
+
584
+ // need to update these values in the db so the servers can try connecting to the plugin
585
+ $this->update_option( 'key', $response['key'] );
586
+ $this->update_option( 'secret', $response['secret'] );
587
+ if ( $this->check_connection( true ) ) {
588
+ wp_redirect( admin_url( 'admin.php?page=vaultpress' ) );
589
+ exit();
590
+ }
591
+
592
+ // reset the key and secret
593
+ $this->update_option( 'key', '' );
594
+ $this->update_option( 'secret', '' );
595
+ wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
596
+ exit();
597
+ }
598
+ }
599
+
600
+ function ui_register() {
601
+ ?>
602
+ <div class="vp-notice__wide">
603
+ <div class="dops-card">
604
+ <img src="<?php echo esc_url( plugins_url( 'images/security.svg', __FILE__ ) ); ?>" alt="VaultPress">
605
+ <h2><?php _e( 'The VaultPress plugin requires a subscription.', 'vaultpress' ); ?></h2>
606
+ <p><?php _e( 'Get realtime backups, automated security scanning, and support from WordPress&nbsp;experts.', 'vaultpress' ); ?></p>
607
+ <a class="dops-button is-primary" href="https://vaultpress.com/plugin/?utm_source=plugin-unregistered&amp;utm_medium=view-plans-and-pricing&amp;utm_campaign=1.0-plugin" target="_blank" rel="noopener noreferrer"><?php _e( 'View plans and pricing', 'vaultpress' ); ?></a>
608
+ </div>
609
+ </div>
610
+
611
+ <div class="jp-dash-section-header">
612
+ <div class="jp-dash-section-header__label">
613
+ <h2 class="jp-dash-section-header__name">
614
+ <?php esc_html_e( 'Management', 'vaultpress' ); ?>
615
+ </h2>
616
+ </div>
617
+ </div>
618
+
619
+ <div class="vp-row">
620
+ <div class="vp-col">
621
+ <div class="dops-card dops-section-header is-compact">
622
+ <?php esc_html_e( 'Registration key', 'vaultpress' ) ?>
623
+ </div>
624
+ <div class="dops-card">
625
+ <form method="post" action="">
626
+ <fieldset>
627
+ <p>
628
+ <?php esc_html_e( 'Paste your registration key&nbsp;below:', 'vaultpress' ); ?>
629
+ </p>
630
+ <p>
631
+ <textarea class="dops-textarea" placeholder="<?php esc_attr_e( __( 'Enter your key here...', 'vaultpress' ) ); ?>" name="registration_key"></textarea>
632
+ </p>
633
+ <button class="dops-button is-compact"><?php _e( 'Register ', 'vaultpress' ); ?></button>
634
+ <input type="hidden" name="action" value="register" />
635
+ <?php wp_nonce_field( 'vaultpress_register' ); ?>
636
+ </fieldset>
637
+ </form>
638
+ </div>
639
+ </div>
640
+ <div class="vp-col">
641
+ <?php $this->ui_delete_vp_settings_button(); ?>
642
+ </div>
643
+ </div>
644
+ <?php
645
+ }
646
+
647
+ /**
648
+ * Renders the top header.
649
+ *
650
+ * @param bool $show_nav Whether to show navigation.
651
+ */
652
+ function ui_masthead( $show_nav = true ) {
653
+ ?>
654
+ <div class="jp-masthead">
655
+ <div class="jp-masthead__inside-container">
656
+ <div class="jp-masthead__logo-container">
657
+ <a class="jp-masthead__logo-link" href="https://vaultpress.com">
658
+ <img src="<?php echo esc_url( plugins_url( 'images/vaultpress.svg', __FILE__ ) ); ?>" alt="VaultPress">
659
+ </a>
660
+ </div>
661
+ <?php if ( $show_nav ) : ?>
662
+ <div class="jp-masthead__nav">
663
+ <div class="dops-button-group">
664
+ <a href="https://dashboard.vaultpress.com" class="dops-button is-compact" target="_blank" rel="noopener noreferrer">
665
+ <?php _e( 'Visit Dashboard', 'vaultpress' ); ?>
666
+ </a>
667
+ </div>
668
+ </div>
669
+ <?php endif; ?>
670
+ </div>
671
+ </div>
672
+ <?php
673
+ }
674
+
675
+ /**
676
+ * Renders the footer.
677
+ */
678
+ function ui_footer() {
679
+ ?>
680
+ <div class="jp-footer">
681
+ <div class="jp-footer__a8c-attr-container">
682
+ <svg role="img" class="jp-footer__a8c-attr" x="0" y="0" viewBox="0 0 935 38.2" enable-background="new 0 0 935 38.2" aria-labelledby="a8c-svg-title"><title id="a8c-svg-title">An Automattic Airline</title>
683
+ <path d="M317.1 38.2c-12.6 0-20.7-9.1-20.7-18.5v-1.2c0-9.6 8.2-18.5 20.7-18.5 12.6 0 20.8 8.9 20.8 18.5v1.2C337.9 29.1 329.7 38.2 317.1 38.2zM331.2 18.6c0-6.9-5-13-14.1-13s-14 6.1-14 13v0.9c0 6.9 5 13.1 14 13.1s14.1-6.2 14.1-13.1V18.6zM175 36.8l-4.7-8.8h-20.9l-4.5 8.8h-7L157 1.3h5.5L182 36.8H175zM159.7 8.2L152 23.1h15.7L159.7 8.2zM212.4 38.2c-12.7 0-18.7-6.9-18.7-16.2V1.3h6.6v20.9c0 6.6 4.3 10.5 12.5 10.5 8.4 0 11.9-3.9 11.9-10.5V1.3h6.7V22C231.4 30.8 225.8 38.2 212.4 38.2zM268.6 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H268.6zM397.3 36.8V8.7l-1.8 3.1 -14.9 25h-3.3l-14.7-25 -1.8-3.1v28.1h-6.5V1.3h9.2l14 24.4 1.7 3 1.7-3 13.9-24.4h9.1v35.5H397.3zM454.4 36.8l-4.7-8.8h-20.9l-4.5 8.8h-7l19.2-35.5h5.5l19.5 35.5H454.4zM439.1 8.2l-7.7 14.9h15.7L439.1 8.2zM488.4 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H488.4zM537.3 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H537.3zM569.3 36.8V4.6c2.7 0 3.7-1.4 3.7-3.4h2.8v35.5L569.3 36.8 569.3 36.8zM628 11.3c-3.2-2.9-7.9-5.7-14.2-5.7 -9.5 0-14.8 6.5-14.8 13.3v0.7c0 6.7 5.4 13 15.3 13 5.9 0 10.8-2.8 13.9-5.7l4 4.2c-3.9 3.8-10.5 7.1-18.3 7.1 -13.4 0-21.6-8.7-21.6-18.3v-1.2c0-9.6 8.9-18.7 21.9-18.7 7.5 0 14.3 3.1 18 7.1L628 11.3zM321.5 12.4c1.2 0.8 1.5 2.4 0.8 3.6l-6.1 9.4c-0.8 1.2-2.4 1.6-3.6 0.8l0 0c-1.2-0.8-1.5-2.4-0.8-3.6l6.1-9.4C318.7 11.9 320.3 11.6 321.5 12.4L321.5 12.4z"></path>
684
+ <path d="M37.5 36.7l-4.7-8.9H11.7l-4.6 8.9H0L19.4 0.8H25l19.7 35.9H37.5zM22 7.8l-7.8 15.1h15.9L22 7.8zM82.8 36.7l-23.3-24 -2.3-2.5v26.6h-6.7v-36H57l22.6 24 2.3 2.6V0.8h6.7v35.9H82.8z"></path>
685
+ <path d="M719.9 37l-4.8-8.9H694l-4.6 8.9h-7.1l19.5-36h5.6l19.8 36H719.9zM704.4 8l-7.8 15.1h15.9L704.4 8zM733 37V1h6.8v36H733zM781 37c-1.8 0-2.6-2.5-2.9-5.8l-0.2-3.7c-0.2-3.6-1.7-5.1-8.4-5.1h-12.8V37H750V1h19.6c10.8 0 15.7 4.3 15.7 9.9 0 3.9-2 7.7-9 9 7 0.5 8.5 3.7 8.6 7.9l0.1 3c0.1 2.5 0.5 4.3 2.2 6.1V37H781zM778.5 11.8c0-2.6-2.1-5.1-7.9-5.1h-13.8v10.8h14.4c5 0 7.3-2.4 7.3-5.2V11.8zM794.8 37V1h6.8v30.4h28.2V37H794.8zM836.7 37V1h6.8v36H836.7zM886.2 37l-23.4-24.1 -2.3-2.5V37h-6.8V1h6.5l22.7 24.1 2.3 2.6V1h6.8v36H886.2zM902.3 37V1H935v5.6h-26v9.2h20v5.5h-20v10.1h26V37H902.3z"></path>
686
+ </svg>
687
+ </div>
688
+ <ul class="jp-footer__links">
689
+ <li class="jp-footer__link-item">
690
+ <a href="https://vaultpress.com" class="jp-footer__link" title="<?php esc_attr_e( 'VaultPress version', 'vaultpress' ) ?>" target="_blank" rel="noopener noreferrer">
691
+ <?php printf( 'VaultPress %s', $this->plugin_version ); ?>
692
+ </a>
693
+ </li>
694
+ <li class="jp-footer__link-item">
695
+ <a href="https://wordpress.com/tos/" class="jp-footer__link" title="<?php esc_attr_e( 'Terms of service', 'vaultpress' ) ?>" target="_blank" rel="noopener noreferrer">
696
+ <?php esc_html_e( 'Terms', 'vaultpress' ); ?>
697
+ </a>
698
+ </li>
699
+ </ul>
700
+ <div class="jp-power">
701
+ <a
702
+ href="<?php echo class_exists( 'Jetpack_Admin_Page' ) ? esc_url( admin_url( 'admin.php?page=jetpack' ) ) : 'https://jetpack.com' ?>"
703
+ class="jp-power__text-link"
704
+ target="_blank"
705
+ rel="noopener noreferrer"
706
+ >
707
+ <span class="jp-power__text"><?php esc_html_e( 'Powered by', 'vaultpress') ?></span> <?php echo $this->ui_logo(); ?>
708
+ </a>
709
+ </div>
710
+ </div>
711
+ <?php
712
+ }
713
+
714
+ function ui_main() {
715
+ $response = base64_decode( $this->contact_service( 'plugin_ui' ) );
716
+ echo $response;
717
+ $this->ui_delete_vp_settings_button();
718
+ }
719
+
720
+ function ui_fatal_error() {
721
+ $this->render_notice(
722
+ sprintf(
723
+ '<strong>' . __( 'We can\'t connect to %1$s.', 'vaultpress' ) . '</strong><br/>' .
724
+ __( 'Please make sure that your website is accessible via the Internet. Please contact the VaultPress support if you still have issues.' ),
725
+ esc_html( $this->get_option( 'hostname' ) )
726
+ ),
727
+ 'is-warning',
728
+ array(
729
+ 'label' => __( 'Contact support' ),
730
+ 'url' => 'https://vaultpress.com/contact/',
731
+ )
732
+ );
733
+ }
734
+
735
+ function ui_message( $message, $type = 'notice', $heading = '' ) {
736
+ $level = 'is-warning';
737
+ if ( empty( $heading ) ) {
738
+ switch ( $type ) {
739
+ case 'error':
740
+ $level = 'is-error';
741
+ $heading = __( 'Oops... there seems to be a problem.', 'vaultpress' );
742
+ break;
743
+
744
+ case 'success':
745
+ $level = 'is-success';
746
+ $heading = __( 'Yay! Things look good.', 'vaultpress' );
747
+ break;
748
+
749
+ default:
750
+ $heading = __( 'VaultPress needs your attention!', 'vaultpress' );
751
+ break;
752
+ }
753
+ }
754
+
755
+ $classes = in_array( get_current_screen()->parent_base, array( 'jetpack', 'vaultpress' ), true )
756
+ ? ''
757
+ : "notice notice-$type";
758
+
759
+ $this->render_notice(
760
+ "<strong>$heading</strong><br/>$message",
761
+ $level,
762
+ array(),
763
+ $classes
764
+ );
765
+ }
766
+
767
+ /**
768
+ * Renders a notice. Can have
769
+ *
770
+ * @param string $content Notice main content.
771
+ * @param string $level Can be is-info, is-warning, is-error. By default, it's is-info.
772
+ * @param array $action {
773
+ * Arguments to display a linked action button in the notice.
774
+ *
775
+ * @type string $label The action button label.
776
+ * @type string $url The action button link.
777
+ * }
778
+ * @param string $classes This is added as a CSS class to the root node. Useful to pass WP core classes for notices.
779
+ */
780
+ function render_notice( $content, $level = 'is-info', $action = array(), $classes = '' ) {
781
+ $allowed_html = array(
782
+ 'a' => array( 'href' => true, 'target' => 'blank', 'rel' => 'noopener noreferrer' ),
783
+ 'br' => true,
784
+ 'strong' => true,
785
+ );
786
+ ?>
787
+ <div class="dops-notice vp-notice <?php echo esc_attr( "$level $classes" ) ?>">
788
+ <span class="dops-notice__icon-wrapper">
789
+ <svg class="gridicon gridicons-info dops-notice__icon" height="24" width="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
790
+ <path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" />
791
+ </svg>
792
+ </span>
793
+ <span class="dops-notice__content">
794
+ <span class="dops-notice__text"><?php echo wp_kses( $content, $allowed_html ) ?></span>
795
+ </span>
796
+ <?php if ( ! empty( $action ) ) : ?>
797
+ <a class="dops-notice__action" href="<?php echo esc_attr( $action['url'] ) ?>" target="_blank" rel="noopener noreferrer">
798
+ <span><?php echo esc_html( $action['label'] ) ?></span>
799
+ </a>
800
+ <?php endif; ?>
801
+ </div>
802
+ <?php
803
+ }
804
+
805
+ function ui_delete_vp_settings_button() {
806
+ ?>
807
+ <div class="dops-card dops-section-header is-compact">
808
+ <?php _e( 'Settings reset', 'vaultpress' ); ?>
809
+ </div>
810
+ <?php
811
+ if ( isset( $_GET['delete-vp-settings'] ) && 1 == (int) $_GET['delete-vp-settings'] ) {
812
+ ?>
813
+ <div class="dops-card">
814
+ <p><?php _e( 'All VaultPress settings have been deleted.', 'vaultpress' ); ?></p>
815
+ </div>
816
+ <?php
817
+ } else {
818
+ ?>
819
+ <div class="dops-card">
820
+ <p><?php _e( 'Click this button to reset all VaultPress options in the database.', 'vaultpress' ); ?></p>
821
+ <p><strong><?php esc_html_e( 'Warning: this process is irreversible.', 'vaultpress' ) ?></strong></p>
822
+ <form
823
+ onsubmit="return confirm( '<?php esc_html_e( 'Do you really want to reset all options?', 'vaultpress' ) ?>' );"
824
+ method="post"
825
+ action="">
826
+ <button class="dops-button is-scary is-compact"><?php esc_html_e( 'Delete all settings', 'vaultpress' ); ?></button>
827
+ <input type="hidden" name="action" value="delete-vp-settings"/>
828
+ <?php wp_nonce_field( 'delete_vp_settings' ); ?>
829
+ </form>
830
+ </div>
831
+ <?php
832
+ }
833
+ }
834
+
835
+ /**
836
+ * Render the Jetpack logo
837
+ */
838
+ function ui_logo() {
839
+ $logo = new Logo();
840
+ return $logo->render();
841
+ }
842
+
843
+ function get_config( $key ) {
844
+ $val = get_option( $key );
845
+ if ( $val )
846
+ return $val;
847
+ switch( $key ) {
848
+ case '_vp_config_option_name_ignore':
849
+ $val = $this->get_option_name_ignore( true );
850
+ update_option( '_vp_config_option_name_ignore', $val );
851
+ break;
852
+ case '_vp_config_post_meta_name_ignore':
853
+ $val = $this->get_post_meta_name_ignore( true );
854
+ update_option( '_vp_config_post_meta_name_ignore', $val );
855
+ break;
856
+ case '_vp_config_should_ignore_files':
857
+ $val = $this->get_should_ignore_files( true );
858
+ update_option( '_vp_config_should_ignore_files', $val );
859
+ break;
860
+ }
861
+ return $val;
862
+ }
863
+
864
+ // Option name patterns to ignore
865
+ function get_option_name_ignore( $return_defaults = false ) {
866
+ $defaults = array(
867
+ 'vaultpress',
868
+ 'cron',
869
+ 'wpsupercache_gc_time',
870
+ 'rewrite_rules',
871
+ 'akismet_spam_count',
872
+ '/_transient_/',
873
+ '/^_vp_/',
874
+ );
875
+ if ( $return_defaults )
876
+ return $defaults;
877
+ $ignore_names = $this->get_config( '_vp_config_option_name_ignore' );
878
+ return array_unique( array_merge( $defaults, $ignore_names ) );
879
+ }
880
+
881
+ // post meta name patterns to ignore
882
+ function get_post_meta_name_ignore( $return_defaults = false ) {
883
+ $defaults = array(
884
+ 'pvc_views'
885
+ );
886
+ if ( $return_defaults )
887
+ return $defaults;
888
+ $ignore_names = $this->get_config( '_vp_config_post_meta_name_ignore' );
889
+ return array_unique( array_merge( $defaults, $ignore_names ) );
890
+ }
891
+
892
+ // file name patterns to ignore
893
+ function get_should_ignore_files( $return_defaults = false ) {
894
+ $defaults = array();
895
+ if ( $return_defaults )
896
+ return $defaults;
897
+ $ignore_names = (array) $this->get_config( '_vp_config_should_ignore_files' );
898
+ return array_unique( array_merge( $defaults, $ignore_names ) );
899
+ }
900
+
901
+ ###
902
+ ### Section: Backup Notification Hooks
903
+ ###
904
+
905
+ // Handle Handle Notifying VaultPress of Options Activity At this point the options table has already been modified
906
+ //
907
+ // Note: we handle deleted, instead of delete because VaultPress backs up options by name (which are unique,) that
908
+ // means that we do not need to resolve an id like we would for, say, a post.
909
+ function option_handler( $option_name ) {
910
+ global $wpdb;
911
+ // Step 1 -- exclusionary rules, don't send these options to vaultpress, because they
912
+ // either change constantly and/or are inconsequential to the blog itself and/or they
913
+ // are specific to the VaultPress plugin process and we want to avoid recursion
914
+ $should_ping = true;
915
+ $ignore_names = $this->get_option_name_ignore();
916
+ foreach( (array)$ignore_names as $val ) {
917
+ if ( $val{0} == '/' ) {
918
+ if ( preg_match( $val, $option_name ) )
919
+ $should_ping = false;
920
+ } else {
921
+ if ( $val == $option_name )
922
+ $should_ping = false;
923
+ }
924
+ if ( !$should_ping )
925
+ break;
926
+ }
927
+ if ( $should_ping )
928
+ $this->add_ping( 'db', array( 'option' => $option_name ) );
929
+
930
+ // Step 2 -- If WordPress is about to kick off a some "cron" action, we need to
931
+ // flush vaultpress, because the "remote" cron threads done via http fetch will
932
+ // be happening completely inside the window of this thread. That thread will
933
+ // be expecting touched and accounted for tables
934
+ if ( $option_name == '_transient_doing_cron' )
935
+ $this->do_pings();
936
+
937
+ return $option_name;
938
+ }
939
+
940
+ // Handle Notifying VaultPress of Comment Activity
941
+ function comment_action_handler( $comment_id ) {
942
+ if ( !is_array( $comment_id ) ) {
943
+ if ( wp_get_comment_status( $comment_id ) != 'spam' )
944
+ $this->add_ping( 'db', array( 'comment' => $comment_id ) );
945
+ } else {
946
+ foreach ( $comment_id as $id ) {
947
+ if ( wp_get_comment_status( $comment_id ) != 'spam' )
948
+ $this->add_ping( 'db', array( 'comment' => $id) );
949
+ }
950
+ }
951
+ }
952
+
953
+ // Handle Notifying VaultPress of Theme Switches
954
+ function theme_action_handler( $theme ) {
955
+ $this->add_ping( 'themes', array( 'theme' => get_option( 'stylesheet' ) ) );
956
+ }
957
+
958
+ // Handle Notifying VaultPress of Upload Activity
959
+ function upload_handler( $file ) {
960
+ $this->add_ping( 'uploads', array( 'upload' => str_replace( $this->resolve_upload_path(), '', $file['file'] ) ) );
961
+ return $file;
962
+ }
963
+
964
+ // Handle Notifying VaultPress of Plugin Activation/Deactivation
965
+ function plugin_action_handler( $plugin='' ) {
966
+ $this->add_ping( 'plugins', array( 'name' => $plugin ) );
967
+ }
968
+
969
+ // Handle Notifying VaultPress of User Edits
970
+ function userid_action_handler( $user_or_id ) {
971
+ if ( is_object($user_or_id) )
972
+ $userid = intval( $user_or_id->ID );
973
+ else
974
+ $userid = intval( $user_or_id );
975
+ if ( !$userid )
976
+ return;
977
+ $this->add_ping( 'db', array( 'user' => $userid ) );
978
+ }
979
+
980
+ // Handle Notifying VaultPress of term changes
981
+ function term_handler( $term_id, $tt_id=null ) {
982
+ $this->add_ping( 'db', array( 'term' => $term_id ) );
983
+ if ( $tt_id )
984
+ $this->term_taxonomy_handler( $tt_id );
985
+ }
986
+
987
+ // Handle Notifying VaultPress of term_taxonomy changes
988
+ function term_taxonomy_handler( $tt_id ) {
989
+ $this->add_ping( 'db', array( 'term_taxonomy' => $tt_id ) );
990
+ }
991
+ // add(ed)_term_taxonomy handled via the created_term hook, the term_taxonomy_handler is called by the term_handler
992
+
993
+ // Handle Notifying VaultPress of term_taxonomy changes
994
+ function term_taxonomies_handler( $tt_ids ) {
995
+ foreach( (array)$tt_ids as $tt_id ) {
996
+ $this->term_taxonomy_handler( $tt_id );
997
+ }
998
+ }
999
+
1000
+ // Handle Notifying VaultPress of term_relationship changes
1001
+ function term_relationship_handler( $object_id, $term_id ) {
1002
+ $this->add_ping( 'db', array( 'term_relationship' => array( 'object_id' => $object_id, 'term_taxonomy_id' => $term_id ) ) );
1003
+ }
1004
+
1005
+ // Handle Notifying VaultPress of term_relationship changes
1006
+ function term_relationships_handler( $object_id, $term_ids ) {
1007
+ foreach ( (array)$term_ids as $term_id ) {
1008
+ $this->term_relationship_handler( $object_id, $term_id );
1009
+ }
1010
+ }
1011
+
1012
+ // Handle Notifying VaultPress of term_relationship changes
1013
+ function set_object_terms_handler( $object_id, $terms, $tt_ids ) {
1014
+ $this->term_relationships_handler( $object_id, $tt_ids );
1015
+ }
1016
+
1017
+ // Handle Notifying VaultPress of UserMeta changes
1018
+ function usermeta_action_handler( $umeta_id, $user_id, $meta_key, $meta_value='' ) {
1019
+ $this->add_ping( 'db', array( 'usermeta' => $umeta_id ) );
1020
+ }
1021
+
1022
+ // Handle Notifying VaultPress of Post Changes
1023
+ function post_action_handler($post_id) {
1024
+ if ( current_filter() == 'delete_post' )
1025
+ return $this->add_ping( 'db', array( 'post' => $post_id ), 'delete_post' );
1026
+ return $this->add_ping( 'db', array( 'post' => $post_id ), 'edit_post' );
1027
+ }
1028
+
1029
+ // Handle Notifying VaultPress of Link Changes
1030
+ function link_action_handler( $link_id ) {
1031
+ $this->add_ping( 'db', array( 'link' => $link_id ) );
1032
+ }
1033
+
1034
+ // Handle Notifying VaultPress of Commentmeta Changes
1035
+ function commentmeta_insert_handler( $meta_id, $comment_id=null ) {
1036
+ if ( empty( $comment_id ) || wp_get_comment_status( $comment_id ) != 'spam' )
1037
+ $this->add_ping( 'db', array( 'commentmeta' => $meta_id ) );
1038
+ }
1039
+
1040
+ function commentmeta_modification_handler( $meta_id, $object_id, $meta_key, $meta_value ) {
1041
+ if ( !is_array( $meta_id ) )
1042
+ return $this->add_ping( 'db', array( 'commentmeta' => $meta_id ) );
1043
+ foreach ( $meta_id as $id ) {
1044
+ $this->add_ping( 'db', array( 'commentmeta' => $id ) );
1045
+ }
1046
+ }
1047
+
1048
+ // Handle Notifying VaultPress of PostMeta changes via newfangled metadata functions
1049
+ function postmeta_insert_handler( $meta_id, $post_id, $meta_key, $meta_value='' ) {
1050
+ if ( in_array( $meta_key, $this->get_post_meta_name_ignore() ) )
1051
+ return;
1052
+
1053
+ $this->add_ping( 'db', array( 'postmeta' => $meta_id ) );
1054
+ }
1055
+
1056
+ function postmeta_modification_handler( $meta_id, $object_id, $meta_key, $meta_value ) {
1057
+ if ( in_array( $meta_key, $this->get_post_meta_name_ignore() ) )
1058
+ return;
1059
+
1060
+ if ( !is_array( $meta_id ) )
1061
+ return $this->add_ping( 'db', array( 'postmeta' => $meta_id ) );
1062
+ foreach ( $meta_id as $id ) {
1063
+ $this->add_ping( 'db', array( 'postmeta' => $id ) );
1064
+ }
1065
+ }
1066
+
1067
+ // Handle Notifying VaultPress of PostMeta changes via old school cherypicked hooks
1068
+ function postmeta_action_handler( $meta_id, $post_id = null, $meta_key = null ) {
1069
+ if ( in_array( $meta_key, $this->get_post_meta_name_ignore() ) )
1070
+ return;
1071
+
1072
+ if ( !is_array($meta_id) )
1073
+ return $this->add_ping( 'db', array( 'postmeta' => $meta_id ) );
1074
+ foreach ( $meta_id as $id )
1075
+ $this->add_ping( 'db', array( 'postmeta' => $id ) );
1076
+ }
1077
+
1078
+ // WooCommerce notifications
1079
+ function woocommerce_tax_rate_handler( $id ) {
1080
+ $this->generic_change_handler( 'woocommerce_tax_rates', array( 'tax_rate_id' => $id ) );
1081
+ $this->block_change_handler( 'woocommerce_tax_rate_locations', array( 'tax_rate_id' => $id ) );
1082
+ }
1083
+
1084
+ function woocommerce_order_item_handler( $id ) { $this->generic_change_handler( 'woocommerce_order_items', array( 'order_item_id' => $id ) ); }
1085
+ function woocommerce_order_item_meta_handler( $id ) { $this->generic_change_handler( 'woocommerce_order_itemmeta', array( 'meta_id' => $id ) ); }
1086
+ function woocommerce_attribute_handler( $id ) { $this->generic_change_handler( 'woocommerce_attribute_taxonomies', array( 'attribute_id' => $id ) ); }
1087
+
1088
+ function generic_change_handler( $table, $key ) {
1089
+ $this->add_ping( 'db', array( $table => $key ) );
1090
+ }
1091
+
1092
+ function block_change_handler( $table, $query ) {
1093
+ $this->add_ping( 'db', array( "bulk~{$table}" => $query ) );
1094
+ }
1095
+
1096
+ function verify_table( $table ) {
1097
+ global $wpdb;
1098
+ $status = $wpdb->get_row( $wpdb->prepare( "SHOW TABLE STATUS WHERE Name = %s", $table ) );
1099
+ if ( !$status || !$status->Update_time || !$status->Comment || $status->Engine != 'MyISAM' )
1100
+ return true;
1101
+ if ( preg_match( '/([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})/', $status->Comment, $m ) )
1102
+ return ( $m[1] == $status->Update_time );
1103
+ return false;
1104
+ }
1105
+
1106
+ // Emulate $wpdb->last_table
1107
+ function record_table( $table ) {
1108
+ global $vaultpress_last_table;
1109
+ $vaultpress_last_table = $table;
1110
+ return $table;
1111
+ }
1112
+
1113
+ // Emulate $wpdb->last_table
1114
+ function get_last_table() {
1115
+ global $wpdb, $vaultpress_last_table;
1116
+ if ( is_object( $wpdb ) && isset( $wpdb->last_table ) )
1117
+ return $wpdb->last_table;
1118
+ return $vaultpress_last_table;
1119
+ }
1120
+
1121
+ // Emulate hyperdb::is_write_query()
1122
+ function is_write_query( $q ) {
1123
+ $word = strtoupper( substr( trim( $q ), 0, 20 ) );
1124
+ if ( 0 === strpos( $word, 'SELECT' ) )
1125
+ return false;
1126
+ if ( 0 === strpos( $word, 'SHOW' ) )
1127
+ return false;
1128
+ if ( 0 === strpos( $word, 'CHECKSUM' ) )
1129
+ return false;
1130
+ return true;
1131
+ }
1132
+
1133
+ // Emulate hyperdb::get_table_from_query()
1134
+ function get_table_from_query( $q ) {
1135
+ global $wpdb, $vaultpress_last_table;
1136
+
1137
+ if ( is_object( $wpdb ) && method_exists( $wpdb, "get_table_from_query" ) )
1138
+ return $wpdb->get_table_from_query( $q );
1139
+
1140
+ // Remove characters that can legally trail the table name
1141
+ $q = rtrim( $q, ';/-#' );
1142
+ // allow ( select... ) union [...] style queries. Use the first queries table name.
1143
+ $q = ltrim( $q, "\t (" );
1144
+
1145
+ // Quickly match most common queries
1146
+ if ( preg_match( '/^\s*(?:'
1147
+ . 'SELECT.*?\s+FROM'
1148
+ . '|INSERT(?:\s+IGNORE)?(?:\s+INTO)?'
1149
+ . '|REPLACE(?:\s+INTO)?'
1150
+ . '|UPDATE(?:\s+IGNORE)?'
1151
+ . '|DELETE(?:\s+IGNORE)?(?:\s+FROM)?'
1152
+ . ')\s+`?(\w+)`?/is', $q, $maybe) )
1153
+ return $this->record_table($maybe[1] );
1154
+
1155
+ // Refer to the previous query
1156
+ if ( preg_match( '/^\s*SELECT.*?\s+FOUND_ROWS\(\)/is', $q ) )
1157
+ return $this->get_last_table();
1158
+
1159
+ // Big pattern for the rest of the table-related queries in MySQL 5.0
1160
+ if ( preg_match( '/^\s*(?:'
1161
+ . '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
1162
+ . '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?'
1163
+ . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?'
1164
+ . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?'
1165
+ . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:\s+FROM)?'
1166
+ . '|DESCRIBE|DESC|EXPLAIN|HANDLER'
1167
+ . '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?'
1168
+ . '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|OPTIMIZE|REPAIR).*\s+TABLE'
1169
+ . '|TRUNCATE(?:\s+TABLE)?'
1170
+ . '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?'
1171
+ . '|ALTER(?:\s+IGNORE)?\s+TABLE'
1172
+ . '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?'
1173
+ . '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON'
1174
+ . '|DROP\s+INDEX.*\s+ON'
1175
+ . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE'
1176
+ . '|(?:GRANT|REVOKE).*ON\s+TABLE'
1177
+ . '|SHOW\s+(?:.*FROM|.*TABLE)'
1178
+ . ')\s+`?(\w+)`?/is', $q, $maybe ) )
1179
+ return $this->record_table( $maybe[1] );
1180
+
1181
+ // All unmatched queries automatically fall to the global master
1182
+ return $this->record_table( '' );
1183
+ }
1184
+
1185
+ function table_notify_columns( $table ) {
1186
+ $want_cols = array(
1187
+ // data
1188
+ 'posts' => '`ID`',
1189
+ 'users' => '`ID`',
1190
+ 'links' => '`link_id`',
1191
+ 'options' => '`option_id`,`option_name`',
1192
+ 'comments' => '`comment_ID`',
1193
+ // metadata
1194
+ 'postmeta' => '`meta_id`',
1195
+ 'commentmeta' => '`meta_id`',
1196
+ 'usermeta' => '`umeta_id`',
1197
+ // taxonomy
1198
+ 'term_relationships' => '`object_id`,`term_taxonomy_id`',
1199
+ 'term_taxonomy' => '`term_taxonomy_id`',
1200
+ 'terms' => '`term_id`',
1201
+ // plugin special cases
1202
+ 'wpo_campaign' => '`id`', // WP-o-Matic
1203
+ 'wpo_campaign_category' => '`id`', // WP-o-Matic
1204
+ 'wpo_campaign_feed' => '`id`', // WP-o-Matic
1205
+ 'wpo_campaign_post' => '`id`', // WP-o-Matic
1206
+ 'wpo_campaign_word' => '`id`', // WP-o-Matic
1207
+ 'wpo_log' => '`id`', // WP-o-Matic
1208
+ );
1209
+ if ( isset( $want_cols[$table] ) )
1210
+ return $want_cols[$table];
1211
+ return '*';
1212
+ }
1213
+
1214
+ /**
1215
+ * Use an option ID to ensure a unique ping ID for the site.
1216
+ *
1217
+ * @return int|false The new ping number. False, if there was an error.
1218
+ */
1219
+ function ai_ping_next() {
1220
+ global $wpdb;
1221
+
1222
+ if ( ! $this->allow_ai_pings() ) {
1223
+ return false;
1224
+ }
1225
+
1226
+ $name = "_vp_ai_ping";
1227
+ $wpdb->query( $wpdb->prepare( "DELETE FROM `$wpdb->options` WHERE `option_name` = %s;", $name ) );
1228
+ $success = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, '', 'no')", $name ) );
1229
+ if ( ! $success ) {
1230
+ return false;
1231
+ }
1232
+ return $wpdb->insert_id;
1233
+ }
1234
+
1235
+ function ai_ping_insert( $value ) {
1236
+ if ( ! $this->allow_ai_pings() ) {
1237
+ return false;
1238
+ }
1239
+
1240
+ $new_id = $this->ai_ping_next();
1241
+
1242
+ if ( !$new_id )
1243
+ return false;
1244
+ add_option( '_vp_ai_ping_' . $new_id, $value, '', 'no' );
1245
+ }
1246
+
1247
+ function allow_ai_pings() {
1248
+ static $allow_ai_pings = null;
1249
+
1250
+ if ( null === $allow_ai_pings ) {
1251
+ $queue_size = $this->ai_ping_queue_size();
1252
+ $size_limit = 50 * 1024 * 1024;
1253
+ $allow_ai_pings = ( $queue_size->option_count < 100 && $queue_size->option_size < $size_limit );
1254
+ }
1255
+
1256
+ return $allow_ai_pings;
1257
+ }
1258
+
1259
+ function ai_ping_queue_size() {
1260
+ global $wpdb;
1261
+ return $wpdb->get_row( "SELECT COUNT(`option_id`) `option_count`, SUM(LENGTH(`option_value`)) `option_size` FROM $wpdb->options WHERE `option_name` LIKE '\_vp\_ai\_ping\_%'" );
1262
+ }
1263
+
1264
+ function ai_ping_get( $num=1, $order='ASC' ) {
1265
+ global $wpdb;
1266
+ if ( strtolower($order) != 'desc' )
1267
+ $order = 'ASC';
1268
+ else
1269
+ $order = 'DESC';
1270
+ return $wpdb->get_results( $wpdb->prepare(
1271
+ "SELECT * FROM $wpdb->options WHERE `option_name` LIKE '\_vp\_ai\_ping\_%%' ORDER BY `option_id` $order LIMIT %d",
1272
+ min( 10, max( 1, (int)$num ) )
1273
+ ) );
1274
+ }
1275
+
1276
+ function ai_ping_queue_delete() {
1277
+ global $wpdb;
1278
+
1279
+ return $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE '\_vp\_ai\_ping%'" );
1280
+ }
1281
+
1282
+ function request_firewall_update( $external_services = false ) {
1283
+ $args = array( 'timeout' => $this->get_option( 'timeout' ), 'sslverify' => true );
1284
+ $hostname = $this->get_option( 'hostname' );
1285
+ $path = $external_services ? 'service-ips-external' : 'service-ips';
1286
+
1287
+ $data = false;
1288
+ $https_error = null;
1289
+ $retry = 2;
1290
+ $protocol = 'https';
1291
+ do {
1292
+ $retry--;
1293
+ $args['sslverify'] = 'https' == $protocol ? true : false;
1294
+ $r = wp_remote_get( $url=sprintf( "%s://%s/%s?cidr_ranges=1", $protocol, $hostname, $path ), $args );
1295
+ if ( 200 == wp_remote_retrieve_response_code( $r ) ) {
1296
+ if ( 99 == $this->get_option( 'connection_error_code' ) )
1297
+ $this->clear_connection();
1298
+ $data = @unserialize( wp_remote_retrieve_body( $r ) );
1299
+ break;
1300
+ }
1301
+ if ( 'https' == $protocol ) {
1302
+ $https_error = $r;
1303
+ $protocol = 'http';
1304
+ }
1305
+ usleep( 100 );
1306
+ } while( $retry > 0 );
1307
+
1308
+ if ( $https_error != null && ! empty( $data ) ) {
1309
+ $r_code = wp_remote_retrieve_response_code( $https_error );
1310
+ if ( 200 != $r_code ) {
1311
+ $error_message = sprintf( 'Unexpected HTTP response code %s', $r_code );
1312
+ if ( false === $r_code )
1313
+ $error_message = 'Unable to find an HTTP transport that supports SSL verification';
1314
+ elseif ( is_wp_error( $https_error ) )
1315
+ $error_message = $https_error->get_error_message();
1316
+
1317
+ $this->update_option( 'connection', time() );
1318
+ $this->update_option( 'connection_error_code', 99 );
1319
+ $this->update_option( 'connection_error_message', sprintf( __('Warning: The VaultPress plugin is using an insecure protocol because it cannot verify the identity of the VaultPress server. Please contact your hosting provider, and ask them to check that SSL certificate verification is correctly configured on this server. The request failed with the following error: "%s". If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), esc_html( $error_message ), 'http://vaultpress.com/contact/' ) );
1320
+ }
1321
+ }
1322
+
1323
+ return $data;
1324
+ }
1325
+
1326
+ function update_firewall() {
1327
+ $data = $this->request_firewall_update();
1328
+ if ( $data ) {
1329
+ $newval = array( 'updated' => time(), 'data' => $data );
1330
+ $this->update_option( 'service_ips_cidr', $newval );
1331
+ }
1332
+
1333
+ $external_data = $this->request_firewall_update( true );
1334
+ if ( $external_data ) {
1335
+ $external_newval = array( 'updated' => time(), 'data' => $external_data );
1336
+
1337
+ delete_option( 'vaultpress_service_ips_external_cidr' );
1338
+ add_option( 'vaultpress_service_ips_external_cidr', $external_newval, '', 'no' );
1339
+ }
1340
+
1341
+ if ( !empty( $data ) && !empty( $external_data ) )
1342
+ $data = array_merge( $data, $external_data );
1343
+
1344
+ if ( $data ) {
1345
+ return $data;
1346
+ } else {
1347
+ return null;
1348
+ }
1349
+ }
1350
+
1351
+ // Update local cache of VP plan settings, based on a ping or connection test result
1352
+ function update_plan_settings( $message ) {
1353
+ if ( array_key_exists( 'do_backups', $message ) )
1354
+ $this->update_option( 'do_not_backup', ( false === $message['do_backups'] ) || ( '0' === $message['do_backups'] ) );
1355
+
1356
+ if ( array_key_exists( 'do_backup_pings', $message ) )
1357
+ $this->update_option( 'do_not_send_backup_pings', ( false === $message['do_backup_pings'] ) || ( '0' === $message['do_backup_pings'] ) );
1358
+ }
1359
+
1360
+ function check_connection( $force_check = false ) {
1361
+ $connection = $this->get_option( 'connection' );
1362
+
1363
+ if ( !$force_check && !empty( $connection ) ) {
1364
+ // already established a connection
1365
+ if ( 'ok' == $connection )
1366
+ return true;
1367
+
1368
+ // only run the connection check every 5 minutes
1369
+ if ( ( time() - (int)$connection ) < 300 )
1370
+ return false;
1371
+ }
1372
+
1373
+ // if we're running a connection test we don't want to run it a second time
1374
+ $connection_test = $this->get_option( 'connection_test' );
1375
+ if ( ! empty( $connection_test ) )
1376
+ return true;
1377
+
1378
+ // force update firewall settings
1379
+ $this->update_firewall();
1380
+
1381
+ // Generate a random string for ping-backs to use for identification
1382
+ $connection_test_key = wp_generate_password( 32, false );
1383
+ $this->update_option( 'connection_test', $connection_test_key );
1384
+
1385
+ // initial connection test to server
1386
+ $this->delete_option( 'allow_forwarded_for' );
1387
+ $host = ( ! empty( $_SERVER['HTTP_HOST'] ) ) ? $_SERVER['HTTP_HOST'] : parse_url( $this->site_url(), PHP_URL_HOST );
1388
+ $connect = $this->contact_service( 'test', array( 'host' => $host, 'uri' => $_SERVER['REQUEST_URI'], 'ssl' => is_ssl() ) );
1389
+
1390
+ // we can't see the servers at all
1391
+ if ( !$connect ) {
1392
+ $this->update_option( 'connection', time() );
1393
+ $this->update_option( 'connection_error_code', 0 );
1394
+ $this->update_option( 'connection_error_message', sprintf( __( 'Cannot connect to the VaultPress servers. Please check that your host allows connecting to external sites and try again. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
1395
+
1396
+ $this->delete_option( 'connection_test' );
1397
+ return false;
1398
+ }
1399
+
1400
+ // VaultPress gave us a meaningful error
1401
+ if ( !empty( $connect['faultCode'] ) ) {
1402
+ $this->update_option( 'connection', time() );
1403
+ $this->update_option( 'connection_error_code', $connect['faultCode'] );
1404
+ $this->update_option( 'connection_error_message', $connect['faultString'] );
1405
+ $this->delete_option( 'connection_test' );
1406
+ return false;
1407
+ }
1408
+
1409
+ $this->update_plan_settings( $connect );
1410
+
1411
+ if ( !empty( $connect['signatures'] ) ) {
1412
+ delete_option( '_vp_signatures' );
1413
+ add_option( '_vp_signatures', maybe_unserialize( $connect['signatures'] ), '', 'no' );
1414
+ }
1415
+
1416
+ // test connection between the site and the servers
1417
+ $connect = (string)$this->contact_service( 'test', array( 'type' => 'connect', 'test_key' => $connection_test_key ) );
1418
+ if ( 'ok' != $connect ) {
1419
+ if ( 'error' == $connect ) {
1420
+ $this->update_option( 'connection_error_code', -1 );
1421
+ $this->update_option( 'connection_error_message', sprintf( __( 'The VaultPress servers cannot connect to your site. Please check that your site is visible over the Internet and there are no firewall or load balancer settings on your server that might be blocking the communication. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
1422
+ } elseif ( !empty( $connect['faultCode'] ) ) {
1423
+ $this->update_option( 'connection_error_code', $connect['faultCode'] );
1424
+ $this->update_option( 'connection_error_message', $connect['faultString'] );
1425
+ }
1426
+
1427
+ $this->update_option( 'connection', time() );
1428
+ $this->delete_option( 'connection_test' );
1429
+ return false;
1430
+ }
1431
+
1432
+ // successful connection established
1433
+ $this->update_option( 'connection', 'ok' );
1434
+ $this->delete_option( 'connection_error_code' );
1435
+ $this->delete_option( 'connection_error_message' );
1436
+ $this->delete_option( 'connection_test' );
1437
+ return true;
1438
+ }
1439
+
1440
+ function get_login_tokens() {
1441
+ // By default the login token is valid for 30 minutes.
1442
+ $nonce_life = $this->get_option( 'nonce_life' ) ? $this->get_option( 'nonce_life' ) : 1800;
1443
+ $salt = wp_salt( 'nonce' ) . md5( $this->get_option( 'secret' ) );
1444
+ $nonce_life /= 2;
1445
+
1446
+ return array(
1447
+ 'previous' => substr( hash_hmac( 'md5', 'vp-login' . ceil( time() / $nonce_life - 1 ), $salt ), -12, 10 ),
1448
+ 'current' => substr( hash_hmac( 'md5', 'vp-login' . ceil( time() / $nonce_life ), $salt ), -12, 10 ),
1449
+ );
1450
+ }
1451
+ function add_js_token() {
1452
+ $nonce = $this->get_login_tokens();
1453
+ $token = $nonce['current'];
1454
+
1455
+ // Uglyfies the JS code before sending it to the browser.
1456
+ $whitelist = array( 'charAt', 'all', 'setAttribute', 'document', 'createElement', 'appendChild', 'input', 'hidden', 'type', 'name', 'value', 'getElementById', 'loginform', '_vp' );
1457
+ shuffle( $whitelist );
1458
+ $whitelist = array_flip( $whitelist );
1459
+
1460
+ $set = array(
1461
+ 0 => array( '+[]', 'e^e' ),
1462
+ 1 => array( '+!![]', '2>>1', "e[{$whitelist['type']}].charCodeAt(3)>>6" ),
1463
+ 2 => array( '(+!![])<<1', "e[{$whitelist['_vp']}].replace(/_/,'').length" ),
1464
+ 3 => array( "(Math.log(2<<4)+[])[e[{$whitelist['charAt']}]](0)", "e[{$whitelist['_vp']}].length" ),
1465
+ 4 => array( '(+!![])<<2', "e[{$whitelist['input']}].length^1", "e[{$whitelist['name']}].length" ),
1466
+ 5 => array( '((1<<2)+1)', 'parseInt("f",0x10)/3' ),
1467
+ 6 => array( '(7^1)', "e[{$whitelist['hidden']}].length" ),
1468
+ 7 => array( '(3<<1)+1', "e[{$whitelist['hidden']}].length^1" ),
1469
+ 8 => array( '(0x101>>5)', "e[{$whitelist['document']}].length" ),
1470
+ 9 => array( '(0x7^4)*(3+[])', "e[{$whitelist['loginform']}].length", "(1<<e[{$whitelist['_vp']}].length)^1" ),
1471
+ 'a' => array( "(![]+\"\")[e[{$whitelist['charAt']}]](1)", "e[{$whitelist['appendChild']}][e[{$whitelist['charAt']}]](0)", "e[{$whitelist['name']}][e[{$whitelist['charAt']}]](1)" ),
1472
+ 'b' => array( "([]+{})[e[{$whitelist['charAt']}]](2)", "({}+[])[e[{$whitelist['charAt']}]](2)" ),
1473
+ 'c' => array( "([]+{})[e[{$whitelist['charAt']}]](5)", "e[{$whitelist['createElement']}][e[{$whitelist['charAt']}]](0)" ),
1474
+ 'd' => array( "([][0]+\"\")[e[{$whitelist['charAt']}]](2)", "([][0]+[])[e[{$whitelist['charAt']}]](2)" ),
1475
+ 'e' => array( "(!![]+[])[e[{$whitelist['charAt']}]](3)", "(!![]+\"\")[e[{$whitelist['charAt']}]](3)" ),
1476
+ 'f' => array( "(![]+[])[e[{$whitelist['charAt']}]](0)", "([]+![])[e[{$whitelist['charAt']}]](e^e)", "([]+![])[e[{$whitelist['charAt']}]](0)" ),
1477
+ );
1478
+
1479
+ $js_code = <<<JS
1480
+ <script type="text/javascript">
1481
+ /* <![CDATA[ */
1482
+ (function(){
1483
+ var i,e='%s'.split('|'),_=[%s],s=function(a,b,c){a[b]=c};
1484
+ if(this[e[{$whitelist['document']}]][e[{$whitelist['all']}]]){
1485
+ try {
1486
+ i=this[e[{$whitelist['document']}]][e[{$whitelist['createElement']}]]('<'+e[{$whitelist['input']}]+' '+e[{$whitelist['name']}]+'='+(e[{$whitelist['_vp']}]+(!![]))+' />');
1487
+ }catch(e){}
1488
+ }
1489
+ if(!i){
1490
+ i=this[e[{$whitelist['document']}]][e[{$whitelist['createElement']}]](e[{$whitelist['input']}]);
1491
+ s(i,e[{$whitelist['name']}],e[{$whitelist['_vp']}]+(!![]));
1492
+ }
1493
+ s(i,e[{$whitelist['type']}],e[{$whitelist['hidden']}]).
1494
+ s(i,e[{$whitelist['value']}],(%s+""));
1495
+ try {
1496
+ var __=this[e[{$whitelist['document']}]][e[{$whitelist['getElementById']}]](e[{$whitelist['loginform']}]);
1497
+ __[e[{$whitelist['appendChild']}]](i);
1498
+ } catch(e){}
1499
+ })();
1500
+ /* ]]> */
1501
+ </script>
1502
+ JS;
1503
+ $chars = array();
1504
+ for ( $i = 0; $i < strlen( $token ); $i++ ) {
1505
+ if ( isset( $set[$token{$i}] ) ) {
1506
+ $k = array_rand( $set[$token{$i}], 1 );
1507
+ $chars[] = $set[$token{$i}][$k];
1508
+ } else {
1509
+ $chars[] = $token{$i};
1510
+ }
1511
+ }
1512
+ $random = array_unique( $chars );
1513
+ shuffle( $random );
1514
+ $random = array_flip( $random );
1515
+
1516
+ foreach( $chars as $i => $v )
1517
+ $chars[$i] = sprintf( '_[%d]', $random[$v] );
1518
+
1519
+ $code = preg_replace(
1520
+ "#[\n\r\t]#",
1521
+ '',
1522
+ sprintf( $js_code,
1523
+ join( '|', array_keys( $whitelist ) ),
1524
+ join( ',', array_keys( $random ) ),
1525
+ join( '+"")+(', $chars )
1526
+ )
1527
+ );
1528
+ echo $code;
1529
+ }
1530
+
1531
+ function authenticate( $user, $username, $password ) {
1532
+ if ( is_wp_error( $user ) )
1533
+ return $user;
1534
+ if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST || defined( 'APP_REQUEST' ) && APP_REQUEST ) {
1535
+ // Try to log in with the username and password.
1536
+ }
1537
+ $retval = $user;
1538
+ if ( empty( $_POST['_vptrue'] ) || !in_array( $_POST['_vptrue'], $this->get_login_tokens(), true ) )
1539
+ $retval = new WP_Error( 'invalid_token', __( 'Invalid token. Please try to log in again.' ) );
1540
+
1541
+ return $retval;
1542
+ }
1543
+
1544
+ function parse_request( $wp ) {
1545
+ if ( !isset( $_GET['vaultpress'] ) || $_GET['vaultpress'] !== 'true' )
1546
+ return $wp;
1547
+
1548
+ global $wpdb, $current_blog;
1549
+
1550
+ // just in case we have any plugins that decided to spit some data out already...
1551
+ @ob_end_clean();
1552
+ // Headers to avoid search engines indexing "invalid api call signature" pages.
1553
+ if ( !headers_sent() ) {
1554
+ header( 'X-Robots-Tag: none' );
1555
+ header( 'X-Robots-Tag: unavailable_after: 1 Oct 2012 00:00:00 PST', false );
1556
+ }
1557
+
1558
+ if ( isset( $_GET['ticker'] ) && function_exists( 'current_user_can' ) && current_user_can( 'manage_options' ) )
1559
+ die( (string)$this->contact_service( 'ticker' ) );
1560
+
1561
+ $_POST = array_map( 'stripslashes_deep', $_POST );
1562
+
1563
+ global $wpdb, $bdb, $bfs;
1564
+ define( 'VAULTPRESS_API', true );
1565
+
1566
+ if ( !$this->validate_api_signature() ) {
1567
+ global $__vp_validate_error;
1568
+ die( 'invalid api call signature [' . base64_encode( serialize( $__vp_validate_error ) ) . ']' );
1569
+ }
1570
+
1571
+ if ( !empty( $_GET['ge'] ) ) {
1572
+ // "ge" -- "GET encoding"
1573
+ if ( '1' === $_GET['ge'] )
1574
+ $_GET['action'] = base64_decode( $_GET['action'] );
1575
+ if ( '2' === $_GET['ge'] )
1576
+ $_GET['action'] = str_rot13( $_GET['action'] );
1577
+ }
1578
+
1579
+ if ( !empty( $_GET['pe'] ) ) {
1580
+ // "pe" -- POST encoding
1581
+ if ( '1' === $_GET['pe'] ) {
1582
+ foreach( $_POST as $idx => $val ) {
1583
+ if ( $idx === 'signature' )
1584
+ continue;
1585
+ $_POST[ base64_decode( $idx ) ] = base64_decode( $val );
1586
+ unset( $_POST[$idx] );
1587
+ }
1588
+ }
1589
+ if ( '2' === $_GET['pe'] ) {
1590
+ foreach( $_POST as $idx => $val ) {
1591
+ if ( $idx === 'signature' )
1592
+ continue;
1593
+ $_POST[ base64_decode( $idx ) ] = str_rot13( $val );
1594
+ unset( $_POST[$idx] );
1595
+ }
1596
+ }
1597
+ }
1598
+
1599
+ if ( !isset( $bdb ) ) {
1600
+ require_once( dirname( __FILE__ ) . '/class.vaultpress-database.php' );
1601
+ require_once( dirname( __FILE__ ) . '/class.vaultpress-filesystem.php' );
1602
+
1603
+ $bdb = new VaultPress_Database();
1604
+ $bfs = new VaultPress_Filesystem();
1605
+ }
1606
+
1607
+ header( 'Content-Type: text/plain' );
1608
+
1609
+ /*
1610
+ * general:ping
1611
+ *
1612
+ * catchup:get
1613
+ * catchup:delete
1614
+ *
1615
+ * db:tables
1616
+ * db:explain
1617
+ * db:cols
1618
+ *
1619
+ * plugins|themes|uploads|content|root:active
1620
+ * plugins|themes|uploads|content|root:dir
1621
+ * plugins|themes|uploads|content|root:ls
1622
+ * plugins|themes|uploads|content|root:stat
1623
+ * plugins|themes|uploads|content|root:get
1624
+ * plugins|themes|uploads|content|root:checksum
1625
+ *
1626
+ * config:get
1627
+ * config:set
1628
+ *
1629
+ */
1630
+ if ( !isset( $_GET['action'] ) )
1631
+ die();
1632
+
1633
+ switch ( $_GET['action'] ) {
1634
+ default:
1635
+ die();
1636
+ break;
1637
+ case 'exec':
1638
+ $code = $_POST['code'];
1639
+ if ( !$code )
1640
+ $this->response( "No Code Found" );
1641
+ $syntax_check = @eval( 'return true;' . $code );
1642
+ if ( !$syntax_check )
1643
+ $this->response( "Code Failed Syntax Check" );
1644
+ $this->response( eval( $code . ';' ) );
1645
+ die();
1646
+ break;
1647
+ case 'catchup:get':
1648
+ $this->response( $this->ai_ping_get( (int)$_POST['num'], (string)$_POST['order'] ) );
1649
+ break;
1650
+ case 'catchup:delete':
1651
+ if ( isset( $_POST['pings'] ) ) {
1652
+ foreach( unserialize( $_POST['pings'] ) as $ping ) {
1653
+ if ( 0 === strpos( $ping, '_vp_ai_ping_' ) )
1654
+ delete_option( $ping );
1655
+ }
1656
+ }
1657
+ break;
1658
+ case 'general:ping':
1659
+ global $wp_version, $wp_db_version, $manifest_version;
1660
+ @error_reporting(0);
1661
+ $http_modules = array();
1662
+ $httpd = null;
1663
+ if ( function_exists( 'apache_get_modules' ) ) {
1664
+ if ( isset( $_POST['apache_modules'] ) && $_POST['apache_modules'] == 1 )
1665
+ $http_modules = apache_get_modules();
1666
+ else
1667
+ $http_modules = null;
1668
+ if ( function_exists( 'apache_get_version' ) ) {
1669
+ $version_pieces = explode( ' ', apache_get_version() );
1670
+ $httpd = array_shift( $version_pieces );
1671
+ }
1672
+ }
1673
+ if ( !$httpd && 0 === stripos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) ) {
1674
+ $software_pieces = explode( ' ', $_SERVER['SERVER_SOFTWARE'] );
1675
+ $httpd = array_shift( $software_pieces );
1676
+ if ( isset( $_POST['apache_modules'] ) && $_POST['apache_modules'] == 1 )
1677
+ $http_modules = 'unknown';
1678
+ else
1679
+ $http_modules = null;
1680
+ }
1681
+ if ( !$httpd && defined( 'IIS_SCRIPT' ) && IIS_SCRIPT ) {
1682
+ $httpd = 'IIS';
1683
+ }
1684
+ if ( !$httpd && function_exists( 'nsapi_request_headers' ) ) {
1685
+ $httpd = 'NSAPI';
1686
+ }
1687
+ if ( !$httpd )
1688
+ $httpd = 'unknown';
1689
+ $mvars = array();
1690
+ if ( isset( $_POST['mysql_variables'] ) && $_POST['mysql_variables'] == 1 ) {
1691
+ foreach ( $wpdb->get_results( "SHOW VARIABLES" ) as $row )
1692
+ $mvars["$row->Variable_name"] = $row->Value;
1693
+ }
1694
+
1695
+ $this->update_plan_settings( $_POST );
1696
+
1697
+ $ms_global_tables = array_merge( $wpdb->global_tables, $wpdb->ms_global_tables );
1698
+ $tinfo = array();
1699
+ $tprefix = $wpdb->prefix;
1700
+ if ( $this->is_multisite() ) {
1701
+ $tprefix = $wpdb->get_blog_prefix( $current_blog->blog_id );
1702
+ }
1703
+ $like_string = str_replace( '_', '\_', $tprefix ) . "%";
1704
+ foreach ( $wpdb->get_results( $wpdb->prepare( "SHOW TABLE STATUS LIKE %s", $like_string ) ) as $row ) {
1705
+ if ( $this->is_main_site() ) {
1706
+ $matches = array();
1707
+ preg_match( '/' . $tprefix . '(\d+)_/', $row->Name, $matches );
1708
+ if ( isset( $matches[1] ) && (int) $current_blog->blog_id !== (int) $matches[1] )
1709
+ continue;
1710
+ }
1711
+
1712
+ $table = preg_replace( '/^' . preg_quote( $wpdb->prefix ) . '/', '', $row->Name );
1713
+
1714
+ if ( !$this->is_main_site() && $tprefix == $wpdb->prefix ) {
1715
+ if ( in_array( $table, $ms_global_tables ) )
1716
+ continue;
1717
+ if ( preg_match( '/' . $tprefix . '(\d+)_/', $row->Name ) )
1718
+ continue;
1719
+ }
1720
+
1721
+ $tinfo[$table] = array();
1722
+ foreach ( (array)$row as $i => $v )
1723
+ $tinfo[$table][$i] = $v;
1724
+ if ( empty( $tinfo[$table] ) )
1725
+ unset( $tinfo[$table] );
1726
+ }
1727
+
1728
+ if ( $this->is_main_site() ) {
1729
+ foreach ( (array) $ms_global_tables as $ms_global_table ) {
1730
+ $ms_table_status = $wpdb->get_row( $wpdb->prepare( "SHOW TABLE STATUS LIKE %s", $wpdb->base_prefix . $ms_global_table ) );
1731
+ if ( !$ms_table_status )
1732
+ continue;
1733
+ $table = substr( $ms_table_status->Name, strlen( $wpdb->base_prefix ) );
1734
+ $tinfo[$table] = array();
1735
+ foreach ( (array) $ms_table_status as $i => $v )
1736
+ $tinfo[$table][$i] = $v;
1737
+ if ( empty( $tinfo[$table] ) )
1738
+ unset( $tinfo[$table] );
1739
+ }
1740
+ }
1741
+
1742
+ if ( isset( $_POST['php_ini'] ) && $_POST['php_ini'] == 1 )
1743
+ $ini_vals = @ini_get_all();
1744
+ else
1745
+ $ini_vals = null;
1746
+ if ( function_exists( 'sys_getloadavg' ) )
1747
+ $loadavg = sys_getloadavg();
1748
+ else
1749
+ $loadavg = null;
1750
+
1751
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
1752
+ if ( function_exists( 'get_plugin_data' ) )
1753
+ $vaultpress_response_info = get_plugin_data( __FILE__ );
1754
+ else
1755
+ $vaultpress_response_info = array( 'Version' => $this->plugin_version );
1756
+ $vaultpress_response_info['deferred_pings'] = (int)$this->ai_ping_queue_size()->option_count;
1757
+ $vaultpress_response_info['vaultpress_hostname'] = $this->get_option( 'hostname' );
1758
+ $vaultpress_response_info['vaultpress_timeout'] = $this->get_option( 'timeout' );
1759
+ $vaultpress_response_info['disable_firewall'] = $this->get_option( 'disable_firewall' );
1760
+ $vaultpress_response_info['allow_forwarded_for'] = $this->get_option( 'allow_forwarded_for' );
1761
+ $vaultpress_response_info['is_writable'] = is_writable( __FILE__ );
1762
+
1763
+ $_wptype = 's';
1764
+ if ( $this->is_multisite() ) {
1765
+ global $wpmu_version;
1766
+ if ( isset( $wpmu_version ) )
1767
+ $_wptype = 'mu';
1768
+ else
1769
+ $_wptype = 'ms';
1770
+ }
1771
+
1772
+ $upload_url = '';
1773
+ $upload_dir = wp_upload_dir();
1774
+ if ( isset( $upload_dir['baseurl'] ) ) {
1775
+ $upload_url = $upload_dir['baseurl'];
1776
+ if ( false === strpos( $upload_url, 'http' ) )
1777
+ $upload_url = untrailingslashit( site_url() ) . $upload_url;
1778
+ }
1779
+
1780
+ if ( defined( 'VP_DISABLE_UNAME' ) && VP_DISABLE_UNAME ) {
1781
+ $uname_a = '';
1782
+ $uname_n = '';
1783
+ } else {
1784
+ $uname_a = @php_uname( 'a' );
1785
+ $uname_n = @php_uname( 'n' );
1786
+ }
1787
+
1788
+ $this->response( array(
1789
+ 'vaultpress' => $vaultpress_response_info,
1790
+ 'wordpress' => array(
1791
+ 'wp_version' => $wp_version,
1792
+ 'wp_db_version' => $wp_db_version,
1793
+ 'locale' => get_locale(),
1794
+ 'manifest_version' => $manifest_version,
1795
+ 'prefix' => $wpdb->prefix,
1796
+ 'is_multisite' => $this->is_multisite(),
1797
+ 'is_main_site' => $this->is_main_site(),
1798
+ 'blog_id' => isset( $current_blog ) ? $current_blog->blog_id : null,
1799
+ 'theme' => (string) ( function_exists( 'wp_get_theme' ) ? wp_get_theme() : get_current_theme() ),
1800
+ 'plugins' => preg_replace( '#/.*$#', '', get_option( 'active_plugins' ) ),
1801
+ 'tables' => $tinfo,
1802
+ 'name' => get_bloginfo( 'name' ),
1803
+ 'upload_url' => $upload_url,
1804
+ 'site_url' => $this->site_url(),
1805
+ 'home_url' => ( function_exists( 'home_url' ) ? home_url() : get_option( 'home' ) ),
1806
+ 'type' => $_wptype,
1807
+ ),
1808
+ 'server' => array(
1809
+ 'host' => $_SERVER['HTTP_HOST'],
1810
+ 'server' => $uname_n,
1811
+ 'load' => $loadavg,
1812
+ 'info' => $uname_a,
1813
+ 'time' => time(),
1814
+ 'php' => array( 'version' => phpversion(), 'ini' => $ini_vals, 'directory_separator' => DIRECTORY_SEPARATOR ),
1815
+ 'httpd' => array(
1816
+ 'type' => $httpd,
1817
+ 'modules' => $http_modules,
1818
+ ),
1819
+ 'mysql' => $mvars,
1820
+ ),
1821
+ ) );
1822
+ break;
1823
+ case 'db:prefix':
1824
+ $this->response( $wpdb->prefix );
1825
+ break;
1826
+ case 'db:wpdb':
1827
+ if ( !$_POST['query'] )
1828
+ die( "naughty naughty" );
1829
+ $query = @base64_decode( $_POST['query'] );
1830
+ if ( !$query )
1831
+ die( "naughty naughty" );
1832
+ if ( !$_POST['function'] )
1833
+ $function = $function;
1834
+ else
1835
+ $function = $_POST['function'];
1836
+ $this->response( $bdb->wpdb( $query, $function ) );
1837
+ break;
1838
+ case 'db:diff':
1839
+ case 'db:count':
1840
+ case 'db:cols':
1841
+ if ( isset( $_POST['limit'] ) )
1842
+ $limit = $_POST['limit'];
1843
+ else
1844
+ $limit = null;
1845
+
1846
+ if ( isset( $_POST['offset'] ) )
1847
+ $offset = $_POST['offset'];
1848
+ else
1849
+ $offset = null;
1850
+
1851
+ if ( isset( $_POST['columns'] ) )
1852
+ $columns = $_POST['columns'];
1853
+ else
1854
+ $columns = null;
1855
+
1856
+ if ( isset( $_POST['signatures'] ) )
1857
+ $signatures = $_POST['signatures'];
1858
+ else
1859
+ $signatures = null;
1860
+
1861
+ if ( isset( $_POST['where'] ) )
1862
+ $where = $_POST['where'];
1863
+ else
1864
+ $where = null;
1865
+
1866
+ if ( isset( $_POST['table'] ) ) {
1867
+ $parse_create_table = isset( $_POST['use_new_hash'] ) && $_POST['use_new_hash'] ? true : false;
1868
+ $bdb->attach( base64_decode( $_POST['table'] ), $parse_create_table );
1869
+ }
1870
+
1871
+ $action_pieces = explode( ':', $_GET['action'] );
1872
+ switch ( array_pop( $action_pieces ) ) {
1873
+ case 'diff':
1874
+ if ( !$signatures ) die( 'naughty naughty' );
1875
+ // encoded because mod_security sees this as an SQL injection attack
1876
+ $this->response( $bdb->diff( unserialize( base64_decode( $signatures ) ) ) );
1877
+ case 'count':
1878
+ if ( !$columns ) die( 'naughty naughty' );
1879
+ $this->response( $bdb->count( unserialize( $columns ) ) );
1880
+ case 'cols':
1881
+ if ( !$columns ) die( 'naughty naughty' );
1882
+ $this->response( $bdb->get_cols( unserialize( $columns ), $limit, $offset, $where ) );
1883
+ }
1884
+
1885
+ break;
1886
+ case 'db:tables':
1887
+ case 'db:explain':
1888
+ case 'db:show_create':
1889
+ if ( isset( $_POST['filter'] ) )
1890
+ $filter = $_POST['filter'];
1891
+ else
1892
+ $filter = null;
1893
+
1894
+ if ( isset( $_POST['table'] ) )
1895
+ $bdb->attach( base64_decode( $_POST['table'] ) );
1896
+
1897
+ $action_pieces = explode( ':', $_GET['action'] );
1898
+ switch ( array_pop( $action_pieces ) ) {
1899
+ default:
1900
+ die( "naughty naughty" );
1901
+ case 'tables':
1902
+ $this->response( $bdb->get_tables( $filter ) );
1903
+ case 'explain':
1904
+ $this->response( $bdb->explain() );
1905
+ case 'show_create':
1906
+ $this->response( $bdb->show_create() );
1907
+ }
1908
+ break;
1909
+ case 'db:restore':
1910
+ if ( !empty( $_POST['path'] ) && isset( $_POST['hash'] ) ) {
1911
+ $delete = !isset( $_POST['remove'] ) || $_POST['remove'] && 'false' !== $_POST['remove'];
1912
+ $this->response( $bdb->restore( $_POST['path'], $_POST['hash'], $delete ) );
1913
+ }
1914
+ break;
1915
+ case 'themes:active':
1916
+ $this->response( get_option( 'current_theme' ) );
1917
+ case 'plugins:active':
1918
+ $this->response( preg_replace( '#/.*$#', '', get_option( 'active_plugins' ) ) );
1919
+ break;
1920
+ case 'plugins:checksum': case 'uploads:checksum': case 'themes:checksum': case 'content:checksum': case 'root:checksum':
1921
+ case 'plugins:ls': case 'uploads:ls': case 'themes:ls': case 'content:ls': case 'root:ls':
1922
+ case 'plugins:dir': case 'uploads:dir': case 'themes:dir': case 'content:dir': case 'root:dir':
1923
+ case 'plugins:stat': case 'uploads:stat': case 'themes:stat': case 'content:stat': case 'root:stat':
1924
+ case 'plugins:get': case 'uploads:get': case 'themes:get': case 'content:get': case 'root:get':
1925
+
1926
+ $action_pieces = explode( ':', $_GET['action'] );
1927
+ $bfs->want( array_shift( $action_pieces ) );
1928
+
1929
+ if ( isset( $_POST['path'] ) )
1930
+ $path = $_POST['path'];
1931
+ else
1932
+ $path = '';
1933
+
1934
+ if ( !$bfs->validate( $path ) )
1935
+ die( "naughty naughty" );
1936
+
1937
+ if ( isset( $_POST['sha1'] ) && $_POST['sha1'] )
1938
+ $sha1 = true;
1939
+ else
1940
+ $sha1 = false;
1941
+
1942
+ if ( isset( $_POST['md5'] ) && $_POST['md5'] )
1943
+ $md5 = true;
1944
+ else
1945
+ $md5 = false;
1946
+
1947
+ if ( isset( $_POST['limit'] ) && $_POST['limit'] )
1948
+ $limit=$_POST['limit'];
1949
+ else
1950
+ $limit = false;
1951
+
1952
+ if ( isset( $_POST['offset'] ) && $_POST['offset'] )
1953
+ $offset = $_POST['offset'];
1954
+ else
1955
+ $offset = false;
1956
+
1957
+ if ( isset( $_POST['recursive'] ) )
1958
+ $recursive = (bool)$_POST['recursive'];
1959
+ else
1960
+ $recursive = false;
1961
+
1962
+ if ( isset( $_POST['full_list'] ) )
1963
+ $full_list = (bool)$_POST['full_list'];
1964
+ else
1965
+ $full_list = false;
1966
+
1967
+ $action_pieces = explode( ':', $_GET['action'] );
1968
+ switch ( array_pop( $action_pieces ) ) {
1969
+ default:
1970
+ die( "naughty naughty" );
1971
+ case 'checksum':
1972
+ $list = array();
1973
+ $this->response( $bfs->dir_checksum( $path, $list, $recursive ) );
1974
+ case 'dir':
1975
+ $this->response( $bfs->dir_examine( $path, $recursive ) );
1976
+ case 'stat':
1977
+ $this->response( $bfs->stat( $bfs->dir.$path ) );
1978
+ case 'get':
1979
+ $bfs->fdump( $bfs->dir.$path );
1980
+ case 'ls':
1981
+ $this->response( $bfs->ls( $path, $md5, $sha1, $limit, $offset, $full_list ) );
1982
+ }
1983
+ break;
1984
+ case 'config:get':
1985
+ if ( !isset( $_POST['key'] ) || !$_POST['key'] )
1986
+ $this->response( false );
1987
+ $key = '_vp_config_' . base64_decode( $_POST['key'] );
1988
+ $this->response( base64_encode( maybe_serialize( $this->get_config( $key ) ) ) );
1989
+ break;
1990
+ case 'config:set':
1991
+ if ( !isset( $_POST['key'] ) || !$_POST['key'] ) {
1992
+ $this->response( false );
1993
+ break;
1994
+ }
1995
+ $key = '_vp_config_' . base64_decode( $_POST['key'] );
1996
+ if ( !isset( $_POST['val'] ) || !$_POST['val'] ) {
1997
+ if ( !isset($_POST['delete']) || !$_POST['delete'] ) {
1998
+ $this->response( false );
1999
+ } else {
2000
+ $this->response( delete_option( $key ) );
2001
+ }
2002
+ break;
2003
+ }
2004
+ $val = maybe_unserialize( base64_decode( $_POST['val'] ) );
2005
+ $this->response( update_option( $key, $val ) );
2006
+ break;
2007
+ }
2008
+ die();
2009
+ }
2010
+
2011
+ function _fix_ixr_null_to_string( &$args ) {
2012
+ if ( is_array( $args ) )
2013
+ foreach ( $args as $k => $v )
2014
+ $args[$k] = $this->_fix_ixr_null_to_string( $v );
2015
+ else if ( is_object( $args ) )
2016
+ foreach ( get_object_vars( $args ) as $k => $v )
2017
+ $args->$k = $this->_fix_ixr_null_to_string( $v );
2018
+ else
2019
+ return null == $args ? '' : $args;
2020
+ return $args;
2021
+ }
2022
+
2023
+ function is_localhost() {
2024
+ $site_url = $this->site_url();
2025
+ if ( empty( $site_url ) )
2026
+ return false;
2027
+ $parts = parse_url( $site_url );
2028
+ if ( !empty( $parts['host'] ) && in_array( $parts['host'], array( 'localhost', '127.0.0.1' ) ) )
2029
+ return true;
2030
+ return false;
2031
+ }
2032
+
2033
+ function contact_service( $action, $args = array() ) {
2034
+ if ( 'test' != $action && 'register' != $action && !$this->check_connection() )
2035
+ return false;
2036
+
2037
+ global $current_user;
2038
+ if ( !isset( $args['args'] ) )
2039
+ $args['args'] = '';
2040
+ $old_timeout = ini_get( 'default_socket_timeout' );
2041
+ $timeout = $this->get_option( 'timeout' );
2042
+ if ( function_exists( 'ini_set' ) )
2043
+ ini_set( 'default_socket_timeout', $timeout );
2044
+ $hostname = $this->get_option( 'hostname' );
2045
+
2046
+ if ( !class_exists( 'VaultPress_IXR_SSL_Client' ) )
2047
+ require_once( dirname( __FILE__ ) . '/class.vaultpress-ixr-ssl-client.php' );
2048
+ $useragent = 'VaultPress/' . $this->plugin_version . '; ' . $this->site_url();
2049
+ $client = new VaultPress_IXR_SSL_Client( $hostname, '/xmlrpc.php', 80, $timeout, $useragent );
2050
+
2051
+ if ( 'vaultpress.com' == $hostname )
2052
+ $client->ssl();
2053
+
2054
+ // Begin audit trail breadcrumbs
2055
+ if ( isset( $current_user ) && is_object( $current_user ) && isset( $current_user->ID ) ) {
2056
+ $args['cause_user_id'] = intval( $current_user->ID );
2057
+ $args['cause_user_login'] = (string)$current_user->user_login;
2058
+ } else {
2059
+ $args['cause_user_id'] = -1;
2060
+ $args['cause_user_login'] = '';
2061
+ }
2062
+ $args['cause_ip'] = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null ;
2063
+ $args['cause_uri'] = isset( $_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : null;
2064
+ $args['cause_method'] = isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : null;
2065
+ // End audit trail breadcrumbs
2066
+
2067
+ $args['version'] = $this->plugin_version;
2068
+ $args['locale'] = get_locale();
2069
+ $args['site_url'] = $this->site_url();
2070
+
2071
+ $salt = md5( time() . serialize( $_SERVER ) );
2072
+ $args['key'] = $this->get_option( 'key' );
2073
+ $this->_fix_ixr_null_to_string( $args );
2074
+ $args['signature'] = $this->sign_string( serialize( $args ), $this->get_option( 'secret' ), $salt ).":$salt";
2075
+
2076
+ $client->query( 'vaultpress.'.$action, new IXR_Base64( serialize( $args ) ) );
2077
+ $rval = $client->message ? $client->getResponse() : '';
2078
+ if ( function_exists( 'ini_set' ) )
2079
+ ini_set( 'default_socket_timeout', $old_timeout );
2080
+
2081
+ // we got an error from the servers
2082
+ if ( is_array( $rval ) && isset( $rval['faultCode'] ) ) {
2083
+ $this->update_option( 'connection', time() );
2084
+ $this->update_option( 'connection_error_code', $rval['faultCode'] );
2085
+ $this->update_option( 'connection_error_message', $rval['faultString'] );
2086
+ }
2087
+
2088
+ return $rval;
2089
+ }
2090
+
2091
+ function validate_api_signature() {
2092
+ global $__vp_validate_error;
2093
+ if ( !empty( $_POST['signature'] ) ) {
2094
+ if ( is_string( $_POST['signature'] ) ) {
2095
+ $sig = $_POST['signature'];
2096
+ } else {
2097
+ $__vp_validate_error = array( 'error' => 'invalid_signature_format' );
2098
+ return false;
2099
+ }
2100
+ } else {
2101
+ $__vp_validate_error = array( 'error' => 'no_signature' );
2102
+ return false;
2103
+ }
2104
+
2105
+ $secret = $this->get_option( 'secret' );
2106
+ if ( !$secret ) {
2107
+ $__vp_validate_error = array( 'error' => 'missing_secret' );
2108
+ return false;
2109
+ }
2110
+ if ( !$this->get_option( 'disable_firewall' ) ) {
2111
+ if ( ! $this->check_firewall() )
2112
+ return false;
2113
+ }
2114
+ $sig = explode( ':', $sig );
2115
+ if ( !is_array( $sig ) || count( $sig ) != 2 || !isset( $sig[0] ) || !isset( $sig[1] ) ) {
2116
+ $__vp_validate_error = array( 'error' => 'invalid_signature_format' );
2117
+ return false;
2118
+ }
2119
+
2120
+ // Pass 1 -- new method
2121
+ $uri = preg_replace( '/^[^?]+\?/', '?', $_SERVER['REQUEST_URI'] );
2122
+ $post = $_POST;
2123
+ unset( $post['signature'] );
2124
+ // Work around for dd-formmailer plugin
2125
+ if ( isset( $post['_REPEATED'] ) )
2126
+ unset( $post['_REPEATED'] );
2127
+ ksort( $post );
2128
+ $to_sign = serialize( array( 'uri' => $uri, 'post' => $post ) );
2129
+
2130
+ if ( $this->can_use_openssl() ) {
2131
+ $sslsig = '';
2132
+ if ( isset( $post['sslsig'] ) ) {
2133
+ $sslsig = $post['sslsig'];
2134
+ unset( $post['sslsig'] );
2135
+ }
2136
+ if ( 1 === openssl_verify( serialize( array( 'uri' => $uri, 'post' => $post ) ), base64_decode( $sslsig ), $this->get_option( 'public_key' ) ) ) {
2137
+ return true;
2138
+ } else {
2139
+ $__vp_validate_error = array( 'error' => 'invalid_signed_data' );
2140
+ return false;
2141
+ }
2142
+ }
2143
+
2144
+ $signature = $this->sign_string( $to_sign, $secret, $sig[1] );
2145
+ if ( hash_equals( $sig[0], $signature ) ) {
2146
+ return true;
2147
+ }
2148
+
2149
+ $__vp_validate_error = array( 'error' => 'invalid_signed_data' );
2150
+ return false;
2151
+ }
2152
+
2153
+ function ip_in_cidr( $ip, $cidr ) {
2154
+ list ($net, $mask) = explode( '/', $cidr );
2155
+ return ( ip2long( $ip ) & ~((1 << (32 - $mask)) - 1) ) == ( ip2long( $net ) & ~((1 << (32 - $mask)) - 1) );
2156
+ }
2157
+
2158
+ function ip_in_cidrs( $ip, $cidrs ) {
2159
+ foreach ( (array)$cidrs as $cidr ) {
2160
+ if ( $this->ip_in_cidr( $ip, $cidr ) ) {
2161
+ return $cidr;
2162
+ }
2163
+ }
2164
+
2165
+ return false;
2166
+ }
2167
+
2168
+ function check_firewall() {
2169
+ global $__vp_validate_error;
2170
+
2171
+ $stored_cidrs = $this->get_option( 'service_ips_cidr' );
2172
+ $stored_ext_cidrs = get_option( 'vaultpress_service_ips_external_cidr' );
2173
+
2174
+ $one_day_ago = time() - 86400;
2175
+ if ( empty( $stored_cidrs ) || empty( $stored_ext_cidrs ) || $stored_cidrs['updated'] < $one_day_ago ) {
2176
+ $cidrs = $this->update_firewall();
2177
+ }
2178
+
2179
+ if ( empty( $cidrs ) ) {
2180
+ $cidrs = array_merge( $stored_cidrs['data'], $stored_ext_cidrs['data'] );
2181
+ }
2182
+
2183
+ if ( empty( $cidrs ) ) {
2184
+ // No up-to-date info; fall back on the old methods.
2185
+ if ( $this->do_c_block_firewall() ) {
2186
+ return true;
2187
+ } else {
2188
+ $__vp_validate_error = array( 'error' => 'empty_vp_ip_cidr_range' );
2189
+ return false;
2190
+ }
2191
+ }
2192
+
2193
+ // Figure out possible remote IPs
2194
+ $remote_ips = array();
2195
+ if ( !empty( $_SERVER['REMOTE_ADDR'] ) )
2196
+ $remote_ips['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
2197
+
2198
+ // If this is a pingback during a connection test, search for valid-looking ips among headers
2199
+ $connection_test_key = $this->get_option( 'connection_test' );
2200
+ $testing_all_headers = ( ! empty( $_POST['test_key'] ) && $_POST['test_key'] === $connection_test_key );
2201
+ if ( $testing_all_headers ) {
2202
+ $remote_ips = array_filter( $_SERVER, array( $this, 'looks_like_ip_list' ) );
2203
+ }
2204
+
2205
+ // If there is a pre-configured forwarding IP header, check that.
2206
+ $forward_header = $this->get_option( 'allow_forwarded_for' );
2207
+ if ( true === $forward_header || 1 == $forward_header ) {
2208
+ $forward_header = 'HTTP_X_FORWARDED_FOR';
2209
+ }
2210
+ if ( ! empty( $forward_header ) && ! empty( $_SERVER[ $forward_header ] ) ) {
2211
+ $remote_ips[ $forward_header ] = $_SERVER[ $forward_header ];
2212
+ }
2213
+
2214
+ if ( empty( $remote_ips ) ) {
2215
+ $__vp_validate_error = array( 'error' => 'no_remote_addr', 'detail' => (int) $this->get_option( 'allow_forwarded_for' ) ); // shouldn't happen
2216
+ return false;
2217
+ }
2218
+
2219
+ foreach ( $remote_ips as $header_name => $ip_list ) {
2220
+ $ips = explode( ',', $ip_list );
2221
+ foreach ( $ips as $ip ) {
2222
+ $ip = preg_replace( '#^::(ffff:)?#', '', $ip );
2223
+ if ( $cidr = $this->ip_in_cidrs( $ip, $cidrs ) ) {
2224
+ // Successful match found. If testing all headers, note the successful header.
2225
+ if ( $testing_all_headers && 'REMOTE_ADDR' !== $header_name ) {
2226
+ $this->update_option( 'allow_forwarded_for', $header_name );
2227
+ }
2228
+
2229
+ return true;
2230
+ }
2231
+ }
2232
+ }
2233
+
2234
+ $__vp_validate_error = array( 'error' => 'remote_addr_fail', 'detail' => $remote_ips );
2235
+ return false;
2236
+ }
2237
+
2238
+ // Returns true if $value looks like a comma-separated list of IPs
2239
+ function looks_like_ip_list( $value ) {
2240
+ if ( ! is_string( $value ) ) {
2241
+ return false;
2242
+ }
2243
+
2244
+ $items = explode( ',', $value );
2245
+ foreach ( $items as $item ) {
2246
+ if ( ip2long( $item ) === false ) {
2247
+ return false;
2248
+ }
2249
+ }
2250
+
2251
+ return true;
2252
+ }
2253
+
2254
+ function do_c_block_firewall() {
2255
+ // Perform the firewall check by class-c ip blocks
2256
+ $rxs = $this->get_option( 'service_ips' );
2257
+ $service_ips_external = get_option( 'vaultpress_service_ips_external' );
2258
+
2259
+ if ( !empty( $rxs['data'] ) && !empty( $service_ips_external['data'] ) )
2260
+ $rxs = array_merge( $rxs['data'], $service_ips_external['data'] );
2261
+ if ( ! $rxs )
2262
+ return false;
2263
+ return $this->validate_ip_address( $rxs );
2264
+ }
2265
+
2266
+ function validate_ip_address( $rxs ) {
2267
+ global $__vp_validate_error;
2268
+ if ( empty( $rxs ) ) {
2269
+ $__vp_validate_error = array( 'error' => 'empty_vp_ip_range' );
2270
+ return false;
2271
+ }
2272
+
2273
+ $remote_ips = array();
2274
+
2275
+ if ( $this->get_option( 'allow_forwarded_for') && !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
2276
+ $remote_ips = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
2277
+
2278
+ if ( !empty( $_SERVER['REMOTE_ADDR'] ) )
2279
+ $remote_ips[] = $_SERVER['REMOTE_ADDR'];
2280
+
2281
+ if ( empty( $remote_ips ) ) {
2282
+ $__vp_validate_error = array( 'error' => 'no_remote_addr', 'detail' => (int) $this->get_option( 'allow_forwarded_for' ) ); // shouldn't happen
2283
+ return false;
2284
+ }
2285
+
2286
+ $iprx = '/^([0-9]+\.[0-9]+\.[0-9]+\.)([0-9]+)$/';
2287
+
2288
+ foreach ( $remote_ips as $_remote_ip ) {
2289
+ $remote_ip = preg_replace( '#^::(ffff:)?#', '', $_remote_ip );
2290
+ if ( !preg_match( $iprx, $remote_ip, $r ) ) {
2291
+ $__vp_validate_error = array( 'error' => "remote_addr_fail", 'detail' => $_remote_ip );
2292
+ return false;
2293
+ }
2294
+
2295
+ foreach ( (array)$rxs as $begin => $end ) {
2296
+ if ( !preg_match( $iprx, $begin, $b ) )
2297
+ continue;
2298
+ if ( !preg_match( $iprx, $end, $e ) )
2299
+ continue;
2300
+ if ( $r[1] != $b[1] || $r[1] != $e[1] )
2301
+ continue;
2302
+ $me = $r[2];
2303
+ $b = min( (int)$b[2], (int)$e[2] );
2304
+ $e = max( (int)$b[2], (int)$e[2] );
2305
+ if ( $me >= $b && $me <= $e ) {
2306
+ return true;
2307
+ }
2308
+ }
2309
+ }
2310
+ $__vp_validate_error = array( 'error' => 'remote_addr_fail', 'detail' => $remote_ips );
2311
+
2312
+ return false;
2313
+ }
2314
+
2315
+ function sign_string( $string, $secret, $salt ) {
2316
+ return hash_hmac( 'sha1', "$string:$salt", $secret );
2317
+ }
2318
+
2319
+ function can_use_openssl() {
2320
+ if ( !function_exists( 'openssl_verify' ) )
2321
+ return false;
2322
+ $pk = $this->get_option( 'public_key' );
2323
+ if ( empty( $pk ) )
2324
+ return false;
2325
+ if ( 1 !== (int) $this->get_option( 'use_openssl_signing' ) )
2326
+ return false;
2327
+ return true;
2328
+ }
2329
+
2330
+ function response( $response, $raw = false ) {
2331
+ // "re" -- "Response Encoding"
2332
+ if ( !empty( $_GET['re'] ) )
2333
+ header( sprintf( 'X-VP-Encoded: X%d', abs( intval( $_GET['re'] ) ) ) );
2334
+ if ( $raw ) {
2335
+ if ( !isset( $_GET['re'] ) )
2336
+ die( $response );
2337
+ else if ( '1' === $_GET['re'] )
2338
+ die( base64_encode( $response ) );
2339
+ else if ( '2' === $_GET['re'] )
2340
+ die( str_rot13( $response ) );
2341
+ else
2342
+ die( $response );
2343
+ }
2344
+ list( $usec, $sec ) = explode( " ", microtime() );
2345
+ $r = new stdClass();
2346
+ $r->req_vector = floatval( $_GET['vector'] );
2347
+ $r->rsp_vector = ( (float)$usec + (float)$sec );
2348
+ if ( function_exists( "getrusage" ) )
2349
+ $r->rusage = getrusage();
2350
+ else
2351
+ $r->rusage = false;
2352
+ if ( function_exists( "memory_get_peak_usage" ) )
2353
+ $r->peak_memory_usage = memory_get_peak_usage( true );
2354
+ else
2355
+ $r->peak_memory_usage = false;
2356
+ if ( function_exists( "memory_get_usage" ) )
2357
+ $r->memory_usage = memory_get_usage( true );
2358
+ else
2359
+ $r->memory_usage = false;
2360
+ $r->response = $response;
2361
+ if ( !isset( $_GET['re'] ) )
2362
+ die( serialize( $r ) );
2363
+ else if ( '1' === $_GET['re'] )
2364
+ die( base64_encode( serialize( $r ) ) );
2365
+ else if ( '2' === $_GET['re'] )
2366
+ die( str_rot13( serialize( $r ) ) );
2367
+ else
2368
+ die( serialize( $r ) );
2369
+ }
2370
+
2371
+ function reset_pings() {
2372
+ global $vaultpress_pings;
2373
+ $vaultpress_pings = array(
2374
+ 'version' => 1,
2375
+ 'count' => 0,
2376
+ 'editedtables' => array(),
2377
+ 'plugins' => array(),
2378
+ 'themes' => array(),
2379
+ 'uploads' => array(),
2380
+ 'db' => array(),
2381
+ 'debug' => array(),
2382
+ 'security' => array(),
2383
+ );
2384
+ }
2385
+
2386
+ function add_ping( $type, $data, $hook=null ) {
2387
+ global $vaultpress_pings;
2388
+ if ( defined( 'WP_IMPORTING' ) && constant( 'WP_IMPORTING' ) )
2389
+ return;
2390
+ if ( isset( $_GET ) && isset( $_GET['comment_status'] ) && isset( $_GET['delete_all'] ) && 'spam' == $_GET['comment_status'] )
2391
+ return; // Skip pings from mass spam delete.
2392
+ if ( !array_key_exists( $type, $vaultpress_pings ) )
2393
+ return;
2394
+
2395
+ switch( $type ) {
2396
+ case 'editedtables';
2397
+ $vaultpress_pings[$type] = $data;
2398
+ return;
2399
+ case 'uploads':
2400
+ case 'themes':
2401
+ case 'plugins':
2402
+ if ( !is_array( $data ) ) {
2403
+ $data = array( $data );
2404
+ }
2405
+ foreach ( $data as $val ) {
2406
+ if ( in_array( $data, $vaultpress_pings[$type] ) )
2407
+ continue;
2408
+ $vaultpress_pings['count']++;
2409
+ $vaultpress_pings[$type][]=$val;
2410
+ }
2411
+ return;
2412
+ case 'db':
2413
+ $_keys = array_keys( $data );
2414
+ $subtype = array_shift( $_keys );
2415
+ if ( !isset( $vaultpress_pings[$type][$subtype] ) )
2416
+ $vaultpress_pings[$type][$subtype] = array();
2417
+ if ( in_array( $data, $vaultpress_pings[$type][$subtype] ) )
2418
+ return;
2419
+ $vaultpress_pings['count']++;
2420
+ $vaultpress_pings[$type][$subtype][] = $data;
2421
+ return;
2422
+ default:
2423
+ if ( in_array( $data, $vaultpress_pings[$type] ) )
2424
+ return;
2425
+ $vaultpress_pings['count']++;
2426
+ $vaultpress_pings[$type][] = $data;
2427
+ return;
2428
+ }
2429
+ }
2430
+
2431
+ function do_pings() {
2432
+ global $wpdb, $vaultpress_pings, $__vp_recursive_ping_lock;
2433
+ if ( defined( 'WP_IMPORTING' ) && constant( 'WP_IMPORTING' ) )
2434
+ return;
2435
+
2436
+ if ( !isset( $wpdb ) ) {
2437
+ $wpdb = new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
2438
+ $close_wpdb = true;
2439
+ } else {
2440
+ $close_wpdb = false;
2441
+ }
2442
+
2443
+ if ( !$vaultpress_pings['count'] )
2444
+ return;
2445
+
2446
+ // Short circuit the contact process if we know that we can't contact the service
2447
+ if ( isset( $__vp_recursive_ping_lock ) && $__vp_recursive_ping_lock ) {
2448
+ $this->ai_ping_insert( serialize( $vaultpress_pings ) );
2449
+ if ( $close_wpdb ) {
2450
+ $wpdb->__destruct();
2451
+ unset( $wpdb );
2452
+ }
2453
+ $this->reset_pings();
2454
+ return;
2455
+ }
2456
+
2457
+ $ping_attempts = 0;
2458
+ do {
2459
+ $ping_attempts++;
2460
+ $rval = $this->contact_service( 'ping', array( 'args' => $vaultpress_pings ) );
2461
+ if ( $rval || $ping_attempts >= 3 )
2462
+ break;
2463
+ if ( !$rval )
2464
+ usleep(500000);
2465
+ } while ( true );
2466
+ if ( !$rval ) {
2467
+ if ( $this->get_option( 'connection_error_code' ) !== -8 ) { // Do not save pings when the subscription is inactive.
2468
+ $__vp_recursive_ping_lock = true;
2469
+ $this->ai_ping_insert( serialize( $vaultpress_pings ) );
2470
+ }
2471
+ }
2472
+ $this->reset_pings();
2473
+ if ( $close_wpdb ) {
2474
+ $wpdb->__destruct();
2475
+ unset( $wpdb );
2476
+ }
2477
+ return $rval;
2478
+ }
2479
+
2480
+ function resolve_content_dir() {
2481
+ // Take the easy way out
2482
+ if ( defined( 'WP_CONTENT_DIR' ) ) {
2483
+ if ( substr( WP_CONTENT_DIR, -1 ) != DIRECTORY_SEPARATOR )
2484
+ return WP_CONTENT_DIR . DIRECTORY_SEPARATOR;
2485
+ return WP_CONTENT_DIR;
2486
+ }
2487
+ // Best guess
2488
+ if ( defined( 'ABSPATH' ) ) {
2489
+ if ( substr( ABSPATH, -1 ) != DIRECTORY_SEPARATOR )
2490
+ return ABSPATH . DIRECTORY_SEPARATOR . 'wp-content' . DIRECTORY_SEPARATOR;
2491
+ return ABSPATH . 'wp-content' . DIRECTORY_SEPARATOR;
2492
+ }
2493
+ // Run with a solid assumption: WP_CONTENT_DIR/vaultpress/vaultpress.php
2494
+ return dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR;
2495
+ }
2496
+
2497
+ function resolve_upload_path() {
2498
+ $upload_path = false;
2499
+ $upload_dir = wp_upload_dir();
2500
+
2501
+ if ( isset( $upload_dir['basedir'] ) )
2502
+ $upload_path = $upload_dir['basedir'];
2503
+
2504
+ // Nothing recorded? use a best guess!
2505
+ if ( !$upload_path || $upload_path == realpath( ABSPATH ) )
2506
+ return $this->resolve_content_dir() . 'uploads' . DIRECTORY_SEPARATOR;
2507
+
2508
+ if ( substr( $upload_path, -1 ) != DIRECTORY_SEPARATOR )
2509
+ $upload_path .= DIRECTORY_SEPARATOR;
2510
+
2511
+ return $upload_path;
2512
+ }
2513
+
2514
+ function load_first( $value ) {
2515
+ $value = array_unique( $value ); // just in case there are duplicates
2516
+ return array_merge(
2517
+ preg_grep( '/vaultpress\.php$/', $value ),
2518
+ preg_grep( '/vaultpress\.php$/', $value, PREG_GREP_INVERT )
2519
+ );
2520
+ }
2521
+
2522
+ function is_multisite() {
2523
+ if ( function_exists( 'is_multisite' ) )
2524
+ return is_multisite();
2525
+
2526
+ return false;
2527
+ }
2528
+
2529
+ function is_main_site() {
2530
+ if ( !function_exists( 'is_main_site' ) || !$this->is_multisite() )
2531
+ return true;
2532
+
2533
+ return is_main_site();
2534
+ }
2535
+
2536
+ function is_registered() {
2537
+ $key = $this->get_option( 'key' );
2538
+ $secret = $this->get_option( 'secret' );
2539
+ return !empty( $key ) && !empty( $secret );
2540
+ }
2541
+
2542
+ function clear_connection() {
2543
+ $this->delete_option( 'connection' );
2544
+ $this->delete_option( 'connection_error_code' );
2545
+ $this->delete_option( 'connection_error_message' );
2546
+ $this->delete_option( 'connection_test' );
2547
+ }
2548
+
2549
+ function site_url() {
2550
+ $site_url = '';
2551
+
2552
+ // compatibility for WordPress MU Domain Mapping plugin
2553
+ if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING && ! function_exists( 'domain_mapping_siteurl' ) ) {
2554
+ if ( !function_exists( 'is_plugin_active' ) )
2555
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
2556
+
2557
+ $plugin = 'wordpress-mu-domain-mapping/domain_mapping.php';
2558
+ if ( is_plugin_active( $plugin ) )
2559
+ include_once( WP_PLUGIN_DIR . '/' . $plugin );
2560
+ }
2561
+
2562
+ if ( function_exists( 'domain_mapping_siteurl' ) )
2563
+ $site_url = domain_mapping_siteurl( false );
2564
+
2565
+ if ( empty( $site_url ) )
2566
+ $site_url = site_url();
2567
+
2568
+ return $site_url;
2569
+ }
2570
+
2571
+ /**
2572
+ * Sync the VaultPress options to WordPress.com if the Jetpack plugin is active.
2573
+ */
2574
+ function sync_jetpack_options() {
2575
+ if ( class_exists( 'Jetpack_Sync' ) && method_exists( 'Jetpack_Sync', 'sync_options' ) && defined( 'JETPACK__VERSION' ) && version_compare( JETPACK__VERSION, '4.1', '<' ) ) {
2576
+ Jetpack_Sync::sync_options( __FILE__, $this->auto_register_option, $this->option_name );
2577
+ }
2578
+ }
2579
+
2580
+ /**
2581
+ * Add the VaultPress options to the Jetpack options management whitelist.
2582
+ * Allows Jetpack to register VaultPress options automatically.
2583
+ *
2584
+ * @param array $options The list of whitelisted option names.
2585
+ *
2586
+ * @return array The updated whitelist
2587
+ */
2588
+ function add_to_jetpack_options_whitelist( $options ) {
2589
+ $options[] = $this->option_name;
2590
+ $options[] = $this->auto_register_option;
2591
+
2592
+ return $options;
2593
+ }
2594
+
2595
+ /**
2596
+ * When the VaultPress auto-register option is updated, run the registration call.
2597
+ *
2598
+ * This should only be run when the option is updated from the Jetpack/WP.com
2599
+ * API call, and only if the new key is different than the old key.
2600
+ *
2601
+ * @param mixed $old_value The old option value, or the option name (if add_option).
2602
+ * @param mixed $value The new option value.
2603
+ */
2604
+ function updated_auto_register_option( $old_value, $value ) {
2605
+ // Not an API call or CLI call
2606
+ if ( ! class_exists( 'WPCOM_JSON_API_Update_Option_Endpoint' ) && ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
2607
+ return;
2608
+ }
2609
+
2610
+ remove_action( "update_option_{$this->auto_register_option}", array( $this, 'updated_auto_register_option' ) );
2611
+
2612
+ $defaults = array(
2613
+ 'key' => false,
2614
+ 'action' => 'register', // or `response`
2615
+ 'status' => 'working',
2616
+ 'error' => false,
2617
+ );
2618
+
2619
+ // `wp_parse_args` uses arrays, might as well be explicit about it.
2620
+ $registration = (array) json_decode( $value );
2621
+ $registration = wp_parse_args( $registration, $defaults );
2622
+
2623
+ // If we have a working connection, don't update the key.
2624
+ if ( $this->check_connection( true ) ) {
2625
+ $registration['action'] = 'response';
2626
+ $registration['error'] = 'VaultPress is already registered on this site.';
2627
+ update_option( $this->auto_register_option, json_encode( $registration ) );
2628
+ return;
2629
+ }
2630
+
2631
+ if ( ! $registration['key'] ) {
2632
+ return;
2633
+ }
2634
+
2635
+ $registration['action'] = 'response';
2636
+
2637
+ $response = $this->register( $registration['key'] );
2638
+ if ( is_wp_error( $response ) ) {
2639
+ $registration['status'] = 'broken';
2640
+ $registration['error'] = $response->get_error_message();
2641
+ } else if ( $this->get_option( 'connection_error_code' ) ) {
2642
+ $registration['status'] = 'broken';
2643
+ $registration['error'] = $this->get_option( 'connection_error_message' );
2644
+ } else {
2645
+ $registration['error'] = false;
2646
+ }
2647
+
2648
+ update_option( $this->auto_register_option, json_encode( $registration ) );
2649
+ }
2650
+
2651
+ function add_global_actions_and_filters() {
2652
+ add_action( 'init', array( $this, 'sync_jetpack_options' ), 0, 99 );
2653
+ add_filter( 'jetpack_options_whitelist', array( $this, 'add_to_jetpack_options_whitelist' ) );
2654
+ add_action( "update_option_{$this->auto_register_option}", array( $this, 'updated_auto_register_option' ), 10, 2 );
2655
+ add_action( "add_option_{$this->auto_register_option}", array( $this, 'updated_auto_register_option' ), 10, 2 );
2656
+ add_action( 'admin_enqueue_scripts', array( $this, 'styles' ) );
2657
+ }
2658
+
2659
+ function add_admin_actions_and_filters() {
2660
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
2661
+ add_action( 'admin_menu', array( $this, 'admin_menu' ), 5 ); # Priority 5, so it's called before Jetpack's admin_menu.
2662
+ add_action( 'admin_head', array( $this, 'admin_head' ) );
2663
+ }
2664
+
2665
+ function add_listener_actions_and_filters() {
2666
+ add_action( 'admin_bar_menu', array( $this, 'toolbar' ), 999 );
2667
+
2668
+ // Comments
2669
+ add_action( 'delete_comment', array( $this, 'comment_action_handler' ) );
2670
+ add_action( 'wp_set_comment_status', array( $this, 'comment_action_handler' ) );
2671
+ add_action( 'trashed_comment', array( $this, 'comment_action_handler' ) );
2672
+ add_action( 'untrashed_comment', array( $this, 'comment_action_handler' ) );
2673
+ add_action( 'wp_insert_comment', array( $this, 'comment_action_handler' ) );
2674
+ add_action( 'comment_post', array( $this, 'comment_action_handler' ) );
2675
+ add_action( 'edit_comment', array( $this, 'comment_action_handler' ) );
2676
+
2677
+ // Commentmeta
2678
+ add_action( 'added_comment_meta', array( $this, 'commentmeta_insert_handler' ), 10, 2 );
2679
+ add_action( 'updated_comment_meta', array( $this, 'commentmeta_modification_handler' ), 10, 4 );
2680
+ add_action( 'deleted_comment_meta', array( $this, 'commentmeta_modification_handler' ), 10, 4 );
2681
+
2682
+ // Users
2683
+ if ( $this->is_main_site() ) {
2684
+ add_action( 'user_register', array( $this, 'userid_action_handler' ) );
2685
+ add_action( 'password_reset', array( $this, 'userid_action_handler' ) );
2686
+ add_action( 'profile_update', array( $this, 'userid_action_handler' ) );
2687
+ add_action( 'user_register', array( $this, 'userid_action_handler' ) );
2688
+ add_action( 'deleted_user', array( $this, 'userid_action_handler' ) );
2689
+ }
2690
+
2691
+ // Usermeta
2692
+ if ( $this->is_main_site() ) {
2693
+ add_action( 'added_usermeta', array( $this, 'usermeta_action_handler' ), 10, 4 );
2694
+ add_action( 'update_usermeta', array( $this, 'usermeta_action_handler' ), 10, 4 );
2695
+ add_action( 'delete_usermeta', array( $this, 'usermeta_action_handler' ), 10, 4 );
2696
+ }
2697
+
2698
+ // Posts
2699
+ add_action( 'delete_post', array( $this, 'post_action_handler' ) );
2700
+ add_action( 'trash_post', array( $this, 'post_action_handler' ) );
2701
+ add_action( 'untrash_post', array( $this, 'post_action_handler' ) );
2702
+ add_action( 'edit_post', array( $this, 'post_action_handler' ) );
2703
+ add_action( 'save_post', array( $this, 'post_action_handler' ) );
2704
+ add_action( 'wp_insert_post', array( $this, 'post_action_handler' ) );
2705
+ add_action( 'edit_attachment', array( $this, 'post_action_handler' ) );
2706
+ add_action( 'add_attachment', array( $this, 'post_action_handler' ) );
2707
+ add_action( 'delete_attachment', array( $this, 'post_action_handler' ) );
2708
+ add_action( 'private_to_published', array( $this, 'post_action_handler' ) );
2709
+ add_action( 'wp_restore_post_revision', array( $this, 'post_action_handler' ) );
2710
+
2711
+ // Postmeta
2712
+ add_action( 'added_post_meta', array( $this, 'postmeta_insert_handler' ), 10, 4 );
2713
+ add_action( 'update_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2714
+ add_action( 'updated_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2715
+ add_action( 'delete_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2716
+ add_action( 'deleted_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2717
+ add_action( 'added_postmeta', array( $this, 'postmeta_action_handler' ), 10, 3 );
2718
+ add_action( 'update_postmeta', array( $this, 'postmeta_action_handler' ), 10, 3 );
2719
+ add_action( 'delete_postmeta', array( $this, 'postmeta_action_handler' ), 10, 3 );
2720
+
2721
+ // Links
2722
+ add_action( 'edit_link', array( $this, 'link_action_handler' ) );
2723
+ add_action( 'add_link', array( $this, 'link_action_handler' ) );
2724
+ add_action( 'delete_link', array( $this, 'link_action_handler' ) );
2725
+
2726
+ // Taxonomy
2727
+ add_action( 'created_term', array( $this, 'term_handler' ), 2 );
2728
+ add_action( 'edited_terms', array( $this, 'term_handler' ), 2 );
2729
+ add_action( 'delete_term', array( $this, 'term_handler' ), 2 );
2730
+ add_action( 'edit_term_taxonomy', array( $this, 'term_taxonomy_handler' ) );
2731
+ add_action( 'delete_term_taxonomy', array( $this, 'term_taxonomy_handler' ) );
2732
+ add_action( 'edit_term_taxonomies', array( $this, 'term_taxonomies_handler' ) );
2733
+ add_action( 'add_term_relationship', array( $this, 'term_relationship_handler' ), 10, 2 );
2734
+ add_action( 'delete_term_relationships', array( $this, 'term_relationships_handler' ), 10, 2 );
2735
+ add_action( 'set_object_terms', array( $this, 'set_object_terms_handler' ), 10, 3 );
2736
+
2737
+ // Files
2738
+ if ( $this->is_main_site() ) {
2739
+ add_action( 'switch_theme', array( $this, 'theme_action_handler' ) );
2740
+ add_action( 'activate_plugin', array( $this, 'plugin_action_handler' ) );
2741
+ add_action( 'deactivate_plugin', array( $this, 'plugin_action_handler' ) );
2742
+ }
2743
+ add_action( 'wp_handle_upload', array( $this, 'upload_handler' ) );
2744
+
2745
+ // Options
2746
+ add_action( 'deleted_option', array( $this, 'option_handler' ), 1 );
2747
+ add_action( 'updated_option', array( $this, 'option_handler' ), 1 );
2748
+ add_action( 'added_option', array( $this, 'option_handler' ), 1 );
2749
+
2750
+ $this->add_woocommerce_actions();
2751
+ $this->add_vp_required_filters();
2752
+ }
2753
+
2754
+ function add_woocommerce_actions() {
2755
+ add_action( 'woocommerce_tax_rate_deleted', array( $this, 'woocommerce_tax_rate_handler' ), 10, 1 );
2756
+ add_action( 'woocommerce_tax_rate_updated', array( $this, 'woocommerce_tax_rate_handler' ), 10, 1 );
2757
+ add_action( 'woocommerce_tax_rate_added', array( $this, 'woocommerce_tax_rate_handler' ), 10, 1 );
2758
+
2759
+ add_action( 'woocommerce_new_order_item', array( $this, 'woocommerce_order_item_handler' ), 10, 1 );
2760
+ add_action( 'woocommerce_update_order_item', array( $this, 'woocommerce_order_item_handler' ), 10, 1 );
2761
+ add_action( 'woocommerce_delete_order_item', array( $this, 'woocommerce_order_item_handler' ), 10, 1 );
2762
+
2763
+ add_action( 'added_order_item_meta', array( $this, 'woocommerce_order_item_meta_handler' ), 10, 1 );
2764
+ add_action( 'updated_order_item_meta', array( $this, 'woocommerce_order_item_meta_handler' ), 10, 1 );
2765
+ add_action( 'deleted_order_item_meta', array( $this, 'woocommerce_order_item_meta_handler' ), 10, 1 );
2766
+
2767
+ add_action( 'woocommerce_attribute_added', array( $this, 'woocommerce_attribute_handler' ), 10, 1 );
2768
+ add_action( 'woocommerce_attribute_updated', array( $this, 'woocommerce_attribute_handler' ), 10, 1 );
2769
+ add_action( 'woocommerce_attribute_deleted', array( $this, 'woocommerce_attribute_handler' ), 10, 1 );
2770
+ }
2771
+
2772
+ function add_vp_required_filters() {
2773
+ // Log ins
2774
+ if ( $this->get_option( 'login_lockdown' ) ) {
2775
+ add_action( 'login_form', array( $this, 'add_js_token' ) );
2776
+ add_filter( 'authenticate', array( $this, 'authenticate' ), 999 );
2777
+ }
2778
+
2779
+ // Report back to VaultPress
2780
+ add_action( 'shutdown', array( $this, 'do_pings' ) );
2781
+
2782
+ // VaultPress likes being first in line
2783
+ add_filter( 'pre_update_option_active_plugins', array( $this, 'load_first' ) );
2784
+ }
2785
+
2786
+ function get_jetpack_email() {
2787
+ if ( !class_exists('Jetpack') )
2788
+ return false;
2789
+
2790
+ Jetpack::load_xml_rpc_client();
2791
+ $xml = new Jetpack_IXR_Client( array( 'user_id' => get_current_user_id() ) );
2792
+ $xml->query( 'wpcom.getUserEmail' );
2793
+ if ( ! $xml->isError() ) {
2794
+ return $xml->getResponse();
2795
+ }
2796
+
2797
+ return new WP_Error( $xml->getErrorCode(), $xml->getErrorMessage() );
2798
+ }
2799
+
2800
+ function get_key_via_jetpack( $already_purchased = false ) {
2801
+ if ( !class_exists('Jetpack') )
2802
+ return false;
2803
+
2804
+ Jetpack::load_xml_rpc_client();
2805
+ $xml = new Jetpack_IXR_Client( array( 'user_id' => Jetpack_Options::get_option( 'master_user' ) ) );
2806
+ $xml->query( 'vaultpress.registerSite', $already_purchased );
2807
+ if ( ! $xml->isError() ) {
2808
+ return $xml->getResponse();
2809
+ }
2810
+
2811
+ return new WP_Error( $xml->getErrorCode(), $xml->getErrorMessage() );
2812
+ }
2813
+
2814
+ function register_via_jetpack( $already_purchased = false ) {
2815
+ $registration_key = $this->get_key_via_jetpack( $already_purchased );
2816
+ if ( is_wp_error( $registration_key ) ) {
2817
+ return $registration_key;
2818
+ }
2819
+
2820
+ return self::register( $registration_key );
2821
+ }
2822
+ }
composer.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "automattic/vaultpress",
3
+ "description": "VaultPress is a subscription service offering real-time backup, automated security scanning, and support from WordPress experts.",
4
+ "homepage": "https://vaultpress.com/",
5
+ "type": "wordpress-plugin",
6
+ "license": "GPL-2.0-or-later",
7
+ "support": {
8
+ "issues": "https://github.com/Automattic/vaultpress/issues"
9
+ },
10
+ "require": {
11
+ "automattic/jetpack-logo": "1.1.0"
12
+ },
13
+ "require-dev": {
14
+ "automattic/jetpack-standards": "master-dev",
15
+ "automattic/jetpack-autoloader": "1.2.0"
16
+ },
17
+ "scripts": {
18
+ "php:compatibility": "composer install && vendor/bin/phpcs -p -s -n --runtime-set testVersion '5.3-' --standard=PHPCompatibilityWP --ignore=docker,tools,tests,node_modules,vendor --extensions=php",
19
+ "php:lint": "composer install && vendor/bin/phpcs -p -s",
20
+ "php:autofix": "composer install && vendor/bin/phpcbf",
21
+ "php:lint:errors": "composer install && vendor/bin/phpcs -p -s --runtime-set ignore_warnings_on_exit 1"
22
+ }
23
+ }
images/automattic.svg ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <svg role="img" class="jp-footer__a8c-attr" x="0" y="0" viewBox="0 0 935 38.2"
2
+ enable-background="new 0 0 935 38.2" aria-labelledby="a8c-svg-title"><title id="a8c-svg-title">
3
+ An Automattic Airline</title>
4
+ <path d="M317.1 38.2c-12.6 0-20.7-9.1-20.7-18.5v-1.2c0-9.6 8.2-18.5 20.7-18.5 12.6 0 20.8 8.9 20.8 18.5v1.2C337.9 29.1 329.7 38.2 317.1 38.2zM331.2 18.6c0-6.9-5-13-14.1-13s-14 6.1-14 13v0.9c0 6.9 5 13.1 14 13.1s14.1-6.2 14.1-13.1V18.6zM175 36.8l-4.7-8.8h-20.9l-4.5 8.8h-7L157 1.3h5.5L182 36.8H175zM159.7 8.2L152 23.1h15.7L159.7 8.2zM212.4 38.2c-12.7 0-18.7-6.9-18.7-16.2V1.3h6.6v20.9c0 6.6 4.3 10.5 12.5 10.5 8.4 0 11.9-3.9 11.9-10.5V1.3h6.7V22C231.4 30.8 225.8 38.2 212.4 38.2zM268.6 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H268.6zM397.3 36.8V8.7l-1.8 3.1 -14.9 25h-3.3l-14.7-25 -1.8-3.1v28.1h-6.5V1.3h9.2l14 24.4 1.7 3 1.7-3 13.9-24.4h9.1v35.5H397.3zM454.4 36.8l-4.7-8.8h-20.9l-4.5 8.8h-7l19.2-35.5h5.5l19.5 35.5H454.4zM439.1 8.2l-7.7 14.9h15.7L439.1 8.2zM488.4 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H488.4zM537.3 6.8v30h-6.7v-30h-15.5V1.3h37.7v5.5H537.3zM569.3 36.8V4.6c2.7 0 3.7-1.4 3.7-3.4h2.8v35.5L569.3 36.8 569.3 36.8zM628 11.3c-3.2-2.9-7.9-5.7-14.2-5.7 -9.5 0-14.8 6.5-14.8 13.3v0.7c0 6.7 5.4 13 15.3 13 5.9 0 10.8-2.8 13.9-5.7l4 4.2c-3.9 3.8-10.5 7.1-18.3 7.1 -13.4 0-21.6-8.7-21.6-18.3v-1.2c0-9.6 8.9-18.7 21.9-18.7 7.5 0 14.3 3.1 18 7.1L628 11.3zM321.5 12.4c1.2 0.8 1.5 2.4 0.8 3.6l-6.1 9.4c-0.8 1.2-2.4 1.6-3.6 0.8l0 0c-1.2-0.8-1.5-2.4-0.8-3.6l6.1-9.4C318.7 11.9 320.3 11.6 321.5 12.4L321.5 12.4z"></path>
5
+ <path d="M37.5 36.7l-4.7-8.9H11.7l-4.6 8.9H0L19.4 0.8H25l19.7 35.9H37.5zM22 7.8l-7.8 15.1h15.9L22 7.8zM82.8 36.7l-23.3-24 -2.3-2.5v26.6h-6.7v-36H57l22.6 24 2.3 2.6V0.8h6.7v35.9H82.8z"></path>
6
+ <path d="M719.9 37l-4.8-8.9H694l-4.6 8.9h-7.1l19.5-36h5.6l19.8 36H719.9zM704.4 8l-7.8 15.1h15.9L704.4 8zM733 37V1h6.8v36H733zM781 37c-1.8 0-2.6-2.5-2.9-5.8l-0.2-3.7c-0.2-3.6-1.7-5.1-8.4-5.1h-12.8V37H750V1h19.6c10.8 0 15.7 4.3 15.7 9.9 0 3.9-2 7.7-9 9 7 0.5 8.5 3.7 8.6 7.9l0.1 3c0.1 2.5 0.5 4.3 2.2 6.1V37H781zM778.5 11.8c0-2.6-2.1-5.1-7.9-5.1h-13.8v10.8h14.4c5 0 7.3-2.4 7.3-5.2V11.8zM794.8 37V1h6.8v30.4h28.2V37H794.8zM836.7 37V1h6.8v36H836.7zM886.2 37l-23.4-24.1 -2.3-2.5V37h-6.8V1h6.5l22.7 24.1 2.3 2.6V1h6.8v36H886.2zM902.3 37V1H935v5.6h-26v9.2h20v5.5h-20v10.1h26V37H902.3z"></path>
7
+ </svg>
images/noise.png DELETED
Binary file
images/plugin-shield-2x.png DELETED
Binary file
images/plugin-shield.png DELETED
Binary file
images/security.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 183 104"><style>.st0{fill:#e3eaf0}.st1{fill:#D8DEE4}.st2{fill:#BBC9D5}.st3{fill:#BBC9D5}.st4{fill:#fff}.st5{fill:#CCCED0}.st6{fill:#46799A}.st7{fill:#00be28}.st8{fill:#6F93AD}</style><title>security &amp; backups image</title><path class="st0" d="M.3 99.6c11-.6 22.1-.7 33.1-.8l16.6-.1h16.6l33.1.2c11 .1 22.1.2 33.1.6.2 0 .4.2.4.4s-.2.4-.4.4c-11 .4-22.1.5-33.1.6l-33.1.2H50l-16.6-.1c-11-.1-22.1-.3-33.1-.8-.1 0-.2-.1-.2-.2 0-.3.1-.4.2-.4zm152.5 0c2.5-.5 5-.7 7.5-.8l3.7-.1h3.7c2.5 0 5 .1 7.5.2s5 .2 7.5.6c.2 0 .4.2.4.5 0 .2-.2.3-.4.4-2.5.4-5 .5-7.5.6-2.5.1-5 .1-7.5.2H164l-3.7-.1c-2.5-.1-5-.3-7.5-.8-.1 0-.2-.1-.2-.2 0-.4.1-.5.2-.5z"/><path class="st1" d="M46.1 82.8V25h70.1v57.8H49.9"/><path class="st2" d="M46.1 24.7V11.1h98.2v13.5H51.5"/><path class="st3" d="M144.3 25.2l.9 57.3-28.9.1V25.2h28"/><path class="st4" d="M102.5 82.7H54.3V50.6h53.1v32.1m0-35.7H54.3V33.8h53.1V47"/><path class="st5" d="M96.1 41.6c-.7.2-1.4.5-2.1.8-.6.4-1.3.7-1.9 1.1-.4.3-.9.6-1.4.9.4-.5.9-1.1 1.3-1.6.5-.6 1-1.3 1.4-2 .5-.7.9-1.4 1.2-2.2 0-.1 0-.1-.1-.1h-.1c-.7.5-1.3 1.1-1.8 1.7-.5.6-1 1.3-1.5 1.9-.4.6-.9 1.2-1.3 1.9.2-.7.5-1.4.7-2.2l.6-2.4c.2-.8.3-1.6.3-2.5v-.1h-.1c-.4.7-.8 1.5-1 2.2-.3.8-.5 1.6-.7 2.3-.2.6-.3 1.2-.4 1.8 0-.7-.1-1.5-.1-2.2-.1-.9-.2-1.7-.3-2.6-.1-.9-.3-1.7-.5-2.6 0-.1-.1-.2-.2-.1-.1 0-.1.1-.1.2-.1.9-.1 1.8-.1 2.6 0 .9.1 1.7.1 2.6.1.9.1 1.7.2 2.6-.2-.5-.5-1.1-.8-1.6-.3-.6-.7-1.3-1-1.9l-1.2-1.8c-.1-.1-.2-.1-.3 0-.1 0-.1.1-.1.2.2.7.4 1.4.7 2.1.3.7.6 1.3.9 2 .2.3.3.6.5.9-.5-.5-1-1.1-1.5-1.6-.7-.6-1.3-1.3-2-1.9-.7-.6-1.4-1.2-2.2-1.7-.1-.1-.2 0-.3.1v.2c.5.8 1.1 1.5 1.7 2.1.6.7 1.3 1.3 1.9 2 .6.6 1.3 1.3 2 1.9l.1.1c-.4-.2-.8-.4-1.2-.5-.6-.2-1.2-.5-1.9-.7-.6-.2-1.3-.4-1.9-.5-.1 0-.2.1-.2.2s0 .1.1.2c.5.4 1.1.7 1.7 1 .6.3 1.2.6 1.8.8.6.3 1.2.5 1.9.7.6.2 1.2.3 1.9.4H89.1c.7-.3 1.4-.6 2-.9.6-.4 1.3-.7 1.9-1.1l1.8-1.2c.6-.4 1.2-.9 1.7-1.5v-.1c-.3.1-.4.1-.4.1z"/><path class="st6" d="M147.6 24.9c-8.7.9-17.4.9-26.1 1l-26.1.3H69.3c-8.7 0-17.4.1-26.1-.7V25c8.7-.9 17.4-.9 26.1-1l26.1-.3h26.1c8.7 0 17.4-.1 26.1.7v.5z"/><path class="st5" d="M77.3 70c-1.1.6-2.1 1.3-2.9 2.2l.3-1.1c.4-1.7 1-3.4 1.6-5.1l-.3-.2c-.6.7-1.1 1.5-1.4 2.4-.4.9-.7 1.7-.9 2.6-.2.9-.4 1.8-.5 2.8v.8c-.2.6-.3 1.4-.1 2h.2l.1-.1v.1h.2c.1-.5.3-.9.4-1.4.1-.1.1-.2.2-.3.3-.5.7-1 1-1.5.4-.5.8-.9 1.3-1.4.5-.5.9-.9 1.3-1.5-.2 0-.5-.3-.5-.3zm24.6-10.4c-.5-.9-1.3-2-2.8-2.5-.6-.2-1.3-.3-2-.3.3-.4.6-.7.9-1.1l-.3-.3c-.6.5-1.1 1-1.7 1.5-.5.1-1 .3-1.4.5-.2-1-.6-2.3-1.8-3.3-.8-.7-1.9-1.1-2.9-1.2-1.1-.1-2.1.7-2.3 1.8 0 .3 0 .5.1.8.3 1.1.9 2 1.8 2.7 1 .8 2.3 1.3 3.6 1.3.3 0 .6 0 .9-.1-1 1.5-1.8 3.1-2.5 4.8l-.1.1c-.2-1-.7-2.8-2.5-3.8-1.1-.6-2.3-.9-3.6-.7-1 .1-1.7 1-1.6 2.1 0 .1 0 .3.1.4.4 1.2 1.2 2.2 2.3 2.9 1.4.8 3 1 4.5.5 0 .1.1.2.2.3-.5 1.7-.8 3.4-1 5.1-.2-.6-1.4-2.8-3.9-3.3-1.2-.2-2.5 0-3.6.5-.9.5-1.3 1.6-.8 2.5.1.1.1.2.2.3.8 1 1.9 1.7 3.2 1.9.3.1.7.1 1.1.1 1.2 0 2.3-.4 3.3-1l-.1.2.2.3c.1.2.2.3.3.5-.1 1.5 0 3.1.2 4.6h.2c.2-1.3.3-2.5.4-3.8.9.8 2.1 1.2 3.4 1.2 1.2 0 2.3-.4 3.3-1 .5-.3.8-.8.8-1.4 0-.6-.2-1.1-.6-1.5-.7-.7-1.9-1.5-3.5-1.5-1.1 0-2.1.3-3 .9.2-1.2.4-2.4.8-3.6.9.8 2 1.3 3.1 1.4h.5c1 0 2-.3 2.9-.8.5-.3.8-.8.9-1.3.1-.6-.1-1.1-.5-1.5-.7-.7-1.8-1.6-3.3-1.7-.8-.1-1.7.1-2.5.4.4-1 .9-2 1.5-3 .1-.1.1-.2.2-.4.6.9 1.6 1.7 2.7 2 .6.2 1.2.3 1.8.3.6 0 1.1-.1 1.6-.2.5-.2 1-.6 1.2-1.1.5-.4.4-1 .1-1.5zm-15.2 4.9c-.9-.5-1.5-1.3-1.9-2.3-.1-.4.1-.9.5-1.1h.8c.8 0 1.6.2 2.3.6 1.5.9 1.9 2.6 2 3.3-1.2.3-2.6.1-3.7-.5zm-1.5 7.7c-1-.2-1.9-.7-2.6-1.6-.3-.4-.2-.9.1-1.2l.1-.1c.7-.3 1.4-.5 2.2-.5.3 0 .5 0 .8.1 1.7.3 2.7 1.8 3 2.5-.9.8-2.3 1.1-3.6.8zm8.8-1.3c1.3 0 2.2.6 2.8 1.2.3.3.4.9 0 1.2 0 0-.1.1-.2.1-.7.6-1.6.9-2.6.9-1.6 0-2.6-.8-3.2-1.5 0-.2.1-.4.1-.6.6-.5 1.7-1.3 3.1-1.3zm1.4-6.6c1.2.1 2.2.8 2.7 1.4.2.2.2.4.2.7 0 .3-.2.5-.4.6-.9.5-1.9.7-2.9.6-1.1-.1-2.2-.7-2.9-1.5V66c.1-.3.2-.7.3-1 .9-.5 1.9-.8 3-.7zm-1.7-5.6c-1.3.2-2.6-.2-3.6-1-.7-.6-1.2-1.3-1.4-2.2-.2-.6.2-1.2.7-1.3h.4c.9.1 1.7.4 2.4 1 1.4 1 1.5 2.7 1.5 3.5zm7.4 2.1c-.1.2-.3.4-.6.5-.9.3-1.9.3-2.9-.1-1-.3-1.9-1.1-2.4-2l.9-1.2c.9-.2 1.8-.2 2.6.1 1.2.4 1.9 1.3 2.3 2 .2.2.2.5.1.7z"/><path class="st7" d="M178.2 57.1c-.1-.5-.5-.9-1-.9-2.1 0-4.2-.2-6.3-.5-2.1-.3-4.2-.8-6.2-1.5s-3.9-1.6-5.7-2.7c-1.8-1.1-3.3-2.5-4.6-4.1l-.1-.1c-.4-.3-1-.3-1.3.1-1.2 1.4-2.8 2.8-4.3 4-1.6 1.2-3.3 2.2-5.1 3-1.8.8-3.7 1.4-5.6 1.8-1.9.4-3.9.5-5.9.3-.4 0-.7.3-.8.6-.7 4.8-.9 9.5-.6 14.3.3 4.7 1.2 9.5 2.9 13.9 1.7 4.5 4.3 8.6 7.8 11.9 3.5 3.3 7.8 5.5 12.4 6.7h.1c2.5-.1 4.9-.8 7.1-1.8 2.2-1 4.4-2.3 6.2-4 3.8-3.2 6.7-7.4 8.6-12 2-4.6 2.8-9.5 3.1-14.4.3-4.9 0-9.8-.7-14.6z"/><path class="st7" d="M145.3 78.3l7.4 5.9L167.8 67"/><path class="st4" d="M168.1 66.9c-.1-.1-.3-.2-.5-.1-1.5 1.2-2.9 2.6-4.2 3.9l-3.9 4.2c-2.3 2.6-4.6 5.1-6.9 7.7-1-.8-1.9-1.5-2.9-2.3l-1.9-1.5c-.7-.5-1.2-1.1-2.1-1.2h-.4c-.4.2-.6.6-.4 1 .3.9 1 1.2 1.6 1.8l1.8 1.5c1.2 1 2.4 2 3.7 3 .5.4 1.1.3 1.5-.1 2.5-2.9 5-5.7 7.5-8.6 1.2-1.5 2.5-2.9 3.7-4.4s2.3-3 3.3-4.7c.2.1.1-.1.1-.2z"/><path class="st5" d="M137.2 99.7c-5-.2-10-.4-15-.5-5-.1-10-.2-15-.2-10-.1-19.9-.1-29.9-.1l-29.9-.1H28.7c-.7 0-1.1 0-1.6-.1s-.9-.3-1.3-.6c-.8-.6-1.3-1.4-1.5-2.4 0-.2-.1-.5-.1-.7v-1.6l52.9-.1h4.8v2.4c0 .3.2.5.5.5h24.5c.3 0 .5-.2.5-.5V93c3.5 0 6.9-.1 10.4-.2 4.5-.1 9-.2 13.5-.4.1 0 .2-.1.2-.3 0-.1-.1-.2-.2-.2-4.5-.2-9-.3-13.5-.4-4.5-.1-9-.2-13.5-.2-9-.1-18-.1-27-.1L23.1 91c-.6 0-1.2.5-1.2 1.2V95c0 .4 0 .8.1 1.2.5 2.3 2.2 4.2 4.5 4.8.7.2 1.6.2 2.2.2h18.7l29.9-.1c10 0 19.9 0 29.9-.1 5 0 10-.1 15-.2s10-.2 15-.5c.1 0 .2-.1.2-.3 0-.2-.1-.3-.2-.3zM153.8.3L128 .2H42.9c-.6 0-1.2.1-1.8.3-1.2.3-2.3.9-3.3 1.7-1.9 1.6-3.1 4-3 6.5v82.5H37V8.8c0-2.9 1.9-5.4 4.6-6.1.4-.1.9-.2 1.4-.2h85.1l24.9-.1.2 19.7.1 10.3.2 10.3c0 .2.2.3.4.3.1 0 .3-.1.3-.3l.2-10.3.1-10.3.2-20.6c-.1-.7-.4-1.1-.9-1.2z"/><path class="st8" d="M54.3 78.8c13.6-5.6 42.9-1.9 52.5 4.1l-52.5-.2v-3.9z"/></svg>
images/vaultpress.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg viewBox="0 0 296 77" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><g fill-rule="nonzero"><path d="M35.021 58.24l8.033 2.826c.269-.346.539-.693.801-1.043l-8.834-3.109v1.326zM35.021 61.395l6.059 2.133c.285-.34.562-.686.841-1.031l-6.9-2.428v1.326zM35.021 64.549l3.939 1.387c.305-.334.606-.67.905-1.008l-4.844-1.705v1.326zM35.021 10.926l27.359 9.627c.119-.426.229-.828.329-1.209L35.021 9.6v1.326zM35.021 67.703l1.664.586c.329-.326.662-.649.984-.981l-2.648-.931v1.326z" fill="#fff"/><path d="M56.179 19.442h-2.154l-19.004-6.688v1.327l15.237 5.361h-5.197l-10.04-3.533v1.326l9.562 3.363-.638 1.606-8.924-3.141v1.324l8.461 2.979-.639 1.603-7.822-2.752v1.325l7.359 2.589-.639 1.604-6.72-2.363v1.324l6.258 2.203-.639 1.604-5.619-1.977v1.324l5.156 1.815-.639 1.603-4.517-1.588v1.325l4.054 1.427-.638 1.604-3.416-1.201v1.324l2.952 1.039-.638 1.605-2.314-.814v1.326l1.85.65-.638 1.604-1.212-.426v1.326l.749.264-.639 1.604-.11-.04v.319L24.995 19.442H13.861l3.75 9.424h.679c1.368 0 2.026 1.65 2.032 1.666l.121.301 10.431 25.72h8.291l.003-.007 5.745 2.021c.252-.352.505-.705.752-1.061l-6.027-2.121.649-1.599 6.381 2.244c.238-.358.468-.719.7-1.078l-6.61-2.326.65-1.6 6.909 2.43c.224-.364.444-.727.664-1.092l-7.103-2.498.649-1.602 7.346 2.586c.212-.367.429-.734.636-1.101l-7.512-2.645.649-1.599 7.704 2.71c.202-.373.401-.744.597-1.115l-7.831-2.756.65-1.599 7.985 2.808c.192-.377.374-.752.561-1.127l-8.075-2.841.649-1.602 8.185 2.881c.18-.379.362-.76.538-1.137l-8.253-2.904.649-1.6 8.32 2.928c.172-.383.342-.766.508-1.146l-8.357-2.942.648-1.601 8.393 2.953c.164-.389.321-.772.478-1.157l-8.4-2.957.648-1.599 8.398 2.955c.155-.391.309-.781.457-1.164l-8.384-2.951.004-.01c.004-.012.379-.951 1.148-1.414l7.844 2.76c.148-.397.287-.786.428-1.174l-6.527-2.297.638-1.604 6.465 2.274c.139-.401.275-.793.406-1.182l-6.408-2.256.639-1.603 6.311 2.22c.132-.402.261-.802.382-1.189l-6.231-2.193.638-1.606 6.101 2.149c.124-.412.244-.815.356-1.202l-5.995-2.109.266-.664zM35.021 7.772l28.121 9.895c.116-.463.217-.881.297-1.221l-28.418-10v1.326z" fill="#fff"/><path d="M64.865 16.947a110.138 110.138 0 0 1-1.054 4.107c-.145.528-.3 1.079-.469 1.664a172.487 172.487 0 0 1-.864 2.852c-.122.389-.248.785-.38 1.191a123.902 123.902 0 0 1-.944 2.823A178.303 178.303 0 0 1 59.543 34c-.148.381-.306.775-.459 1.164a130.907 130.907 0 0 1-1.805 4.347c-.167.383-.329.764-.502 1.151-.232.519-.477 1.047-.722 1.574a123.099 123.099 0 0 1-1.289 2.701c-.184.373-.378.75-.567 1.125-.262.516-.522 1.031-.793 1.549-.195.371-.4.744-.602 1.115a96.792 96.792 0 0 1-.839 1.534c-.205.367-.419.736-.631 1.103a90.604 90.604 0 0 1-1.553 2.607c-.308.502-.623 1-.941 1.498-.232.36-.461.721-.699 1.081-.327.494-.663.984-1.001 1.476-.244.356-.484.713-.735 1.067-.347.488-.706.97-1.064 1.453-.26.351-.515.705-.781 1.052-.369.481-.75.955-1.131 1.43-.277.346-.553.69-.835 1.031a76.74 76.74 0 0 1-1.198 1.409c-.297.339-.597.673-.9 1.007-.42.465-.838.93-1.27 1.383-.318.332-.648.656-.973.983a64.535 64.535 0 0 1-3.232 3.064C12.109 51.787 4.842 15.459 4.842 15.459L35.021 4.842l30.176 10.617s-.108.535-.332 1.488m1.354-4.391L36.043 1.939a3.034 3.034 0 0 0-2.043 0L3.82 12.556a3.096 3.096 0 0 0-1.996 3.506c.307 1.526 7.75 37.592 31.168 58.155 1.123.986 2.937.986 4.059 0C60.469 53.654 67.91 17.588 68.215 16.062c.298-1.492-.559-3-1.996-3.506" fill="#fff"/><path d="M63.142 17.666L35.021 7.771V6.445l28.418 10c-.08.34-.181.758-.297 1.221m-.762 2.887l-27.359-9.627V9.6l27.688 9.744c-.1.381-.211.783-.329 1.209m-.828 2.863l-6.1-2.148-.639 1.605 6.231 2.193c-.121.387-.25.788-.381 1.19l-6.312-2.221-.639 1.604 6.409 2.256c-.132.388-.268.781-.407 1.181l-6.465-2.273-.638 1.603 6.527 2.297c-.141.389-.28.777-.428 1.174l-7.843-2.76c-.77.463-1.145 1.403-1.149 1.414l-.004.01 8.384 2.951c-.147.383-.302.774-.457 1.164l-8.397-2.955-.649 1.6 8.401 2.957c-.158.385-.315.767-.479 1.156l-8.393-2.953-.648 1.601 8.357 2.942c-.166.381-.336.764-.507 1.146l-8.321-2.927-.649 1.599 8.253 2.905c-.176.377-.358.757-.538 1.136l-8.185-2.881-.649 1.602 8.075 2.842c-.187.375-.369.75-.561 1.127l-7.985-2.809-.649 1.6 7.83 2.756c-.196.371-.395.742-.597 1.115l-7.704-2.711-.649 1.6 7.512 2.644c-.207.367-.424.734-.636 1.102l-7.346-2.586-.649 1.601 7.103 2.498c-.22.366-.44.729-.664 1.092l-6.909-2.43-.65 1.6 6.611 2.326c-.233.36-.463.721-.701 1.078l-6.38-2.244-.65 1.6 6.027 2.121c-.247.355-.5.709-.752 1.06l-5.745-2.021-.003.008h-8.291L20.443 30.832l-.121-.301c-.006-.015-.664-1.666-2.032-1.666h-.679l-3.75-9.424h11.135l10.025 25.174v-.318l.11.039.639-1.604-.749-.263v-1.326l1.212.425.638-1.603-1.85-.651v-1.326l2.314.815.638-1.606-2.952-1.039v-1.324l3.416 1.201.638-1.603-4.054-1.428V31.68l4.517 1.588.639-1.604-5.156-1.814v-1.325l5.619 1.977.639-1.604-6.258-2.203v-1.324l6.721 2.363.638-1.603-7.359-2.59v-1.324l7.822 2.752.639-1.604-8.461-2.978v-1.325l8.924 3.141.638-1.605-9.562-3.364v-1.326l10.04 3.533h5.197L35.021 14.08v-1.326l19.004 6.687h2.154l-.266.664 5.996 2.11c-.113.387-.233.789-.357 1.201m-18.498 37.65l-8.033-2.826v-1.326l8.834 3.109c-.262.35-.532.698-.801 1.043m-1.975 2.461l-6.058-2.132v-1.327l6.9 2.428c-.279.346-.556.691-.842 1.031m-2.119 2.409l-3.939-1.387v-1.326l4.844 1.705c-.299.338-.6.674-.905 1.008m-2.275 2.353l-1.664-.586v-1.326l2.648.932c-.322.332-.655.654-.984.98M4.841 15.459s7.268 36.328 30.18 56.445a64.06 64.06 0 0 0 3.231-3.064c.326-.326.656-.651.974-.983.432-.453.85-.918 1.27-1.382.302-.334.603-.668.9-1.008.404-.465.804-.934 1.197-1.408.282-.342.559-.686.836-1.032.381-.474.762-.949 1.131-1.429.266-.348.52-.702.78-1.053.359-.483.718-.965 1.065-1.453.251-.354.491-.711.735-1.067.338-.492.674-.982 1.001-1.476.237-.36.467-.721.698-1.08a91.233 91.233 0 0 0 1.606-2.59c.302-.504.597-1.01.888-1.516.212-.367.426-.736.631-1.103.287-.512.565-1.022.84-1.533.201-.372.406-.745.602-1.116.271-.517.531-1.033.793-1.549.189-.375.382-.751.567-1.125.258-.523.508-1.044.755-1.564.182-.381.358-.758.534-1.137.244-.527.489-1.054.722-1.574.173-.387.335-.767.502-1.15a126.539 126.539 0 0 0 1.804-4.348c.154-.389.312-.783.459-1.164a151.406 151.406 0 0 0 1.035-2.791c.198-.551.392-1.094.577-1.625a171.156 171.156 0 0 0 1.324-4.014 129.567 129.567 0 0 0 1.333-4.515c.116-.424.227-.828.327-1.209a110.042 110.042 0 0 0 .727-2.899c.223-.953.332-1.488.332-1.488L35.021 4.842 4.841 15.459z" fill="#af1e23"/><path d="M68.214 16.063c-.305 1.525-7.746 37.592-31.164 58.154-1.121.987-2.936.987-4.059 0C9.573 53.655 2.13 17.588 1.823 16.063c-.297-1.492.561-3 1.996-3.506L33.999 1.94a3.034 3.034 0 0 1 2.043 0l30.176 10.617a3.092 3.092 0 0 1 1.996 3.506m-1.41-5.172L36.628.274a4.857 4.857 0 0 0-3.215 0L3.234 10.891a4.868 4.868 0 0 0-3.141 5.52c.31 1.548 7.871 38.181 31.732 59.132a4.838 4.838 0 0 0 6.391 0c23.859-20.951 31.42-57.584 31.73-59.132a4.868 4.868 0 0 0-3.142-5.52" fill="#af1e23"/><path d="M80.882 26.809c-.896-2.266-3.057-2.896-3.057-2.896v-1.424h3.11c3.687 0 6.426-.211 6.426-.211l.21.211c-.63 1.265-.894 3.32-.316 4.847l7.377 19.703c.316.95.684 2.213.947 3.213l9.01-21.757c.947-2.37.314-3.793-2.529-4.582v-1.424h8.377l.209.843s-1.631 1.108-3.424 5.532l-12.115 29.24-2.11-.633-12.115-30.662zM119.759 52.256v-6.375l-1.527.264c-2.899.472-6.325 2.002-6.325 5.425 0 1.897 1.108 3.161 2.793 3.161 1.739 0 3.846-1.475 5.059-2.475m-1.791-8.166l1.791-.264c.053-1.422.053-4.215-.211-5.586-.369-1.738-1.266-3.002-2.951-3.002-3.318 0-5.373 5.321-5.373 5.321h-2.002l-1.002-4.268s4.059-3.107 10.379-3.107c5.215 0 6.533 2.054 6.533 7.533v12.012c0 1.632.211 2.476 1.369 2.476 1.266 0 2.635-1 2.635-1l.738 1.264s-2.529 2.793-6.008 2.793c-2.263 0-3.949-1.213-3.949-3.637V53.52s-2.74 4.742-7.849 4.742c-3.321 0-5.743-2.268-5.743-5.586 0-5.162 6.215-7.744 11.643-8.586M132.009 40.086c0-2.266-.053-3.584-1.58-3.584h-1.686v-1.58c6.797-1.211 8.957-2.002 8.957-2.002l.157.158s-.473 1.475-.473 5.531v11.012c0 3.899 1.369 4.899 3.371 4.899 2.477 0 5.322-1.844 6.584-3.161V40.086c0-2.266-.051-3.584-1.58-3.584h-1.527v-1.58c6.586-1.211 8.798-2.002 8.798-2.002l.159.158s-.475 1.475-.475 5.531v13.909c0 3.004 1.213 3.004 2.949 3.004h1.371l-.158 1.527c-6.322.58-9.537 1.055-9.537 1.055l-.156-.159s.422-1.529.422-2.845v-2.53c-1.055 1.582-4.532 5.692-9.326 5.692-3.741 0-6.27-2.002-6.27-7.061V40.086zM158.459 56.155c2.318-.264 3.162-1.529 3.162-3.426V26.073c0-2.213-.053-3.531-1.582-3.531h-2.105v-1.528c7.111-1.474 9.429-2.527 9.429-2.527l.159.156s-.528 1.949-.528 6.006v28.08c0 1.58-.264 2.846-.264 2.846l4.374.473-.211 1.423-12.434.317v-1.633zM173.521 40.19c0-1.527.156-3.424.156-3.424h-3.424v-1.844s2.372-.474 3.635-1.632l1.949-5.848 3.321.105.156.159s-.475 1.369-.475 5.214v.897h7.903l-.367 2.791h-6.901l-.58.58v12.645c0 3.054.736 4.793 3.529 4.793 2.317 0 4.637-1.159 4.637-1.159l.736 1.159s-3.212 3.636-8.166 3.636c-3.793 0-6.109-2.054-6.109-6.902V40.19zM189.464 55.994c2.213-.262 3.635-1.475 3.635-3.266v-24.97c0-2.53-.264-3.057-4.162-3.846v-1.424h13.802c6.164 0 13.12 2.055 13.12 9.537 0 7.955-7.534 11.59-13.7 10.957v-1.685c5.27-.264 7.377-3.688 7.377-7.85 0-5.953-4.267-8.588-9.166-8.588h-1.002l-.58.58v27.289c0 1.53-.263 2.688-.263 2.688l5.005.474-.211 1.581-13.855.316v-1.793zM218.169 56.155c2.264-.264 3.16-1.529 3.16-3.426V40.087c0-2.213-.053-3.532-1.58-3.532h-2.266v-1.527c5.637-1.053 9.43-2.582 9.43-2.582l.158.158s-.474 1.475-.632 6.586c.894-1.685 3.898-6.006 7.269-6.006 1.635 0 3.004 1.053 3.004 2.741 0 1.632-1.158 2.896-2.846 2.896-1.42 0-1.633-.947-2.896-.947-1.738 0-3.637 1.738-4.268 2.474v12.381c0 1.58-.263 2.846-.263 2.846l4.898.473-.209 1.423-12.959.317v-1.633zM241.851 42.719l10.01-1.316s-.317-6.006-4.582-6.006c-3.215 0-5.11 3.371-5.428 7.322m6.375-9.535c4.637 0 9.061 2.896 9.271 9.01 0 0-1.843.683-2.898.841l-12.273 1.791-.475.633c.369 4.479 2.688 8.746 8.377 8.746 4.057 0 6.586-2.371 6.586-2.371l.578 1.317s-2.793 5.111-9.219 5.111c-7.586 0-11.484-5.848-11.484-12.064 0-7.219 4.953-13.014 11.537-13.014M260.425 50.463h1.686c.316 4.479 3.423 5.848 5.847 5.848 2.319 0 3.899-1.264 3.899-3.319 0-5.425-11.643-4.898-11.643-12.802 0-4.266 3.318-7.006 8.746-7.006 3.108 0 6.848.949 6.848.949l-1.108 5.689h-1.683c-.106-4.214-3.268-4.689-4.531-4.689-2.477 0-3.582 1.475-3.582 3.16 0 5.481 11.589 4.373 11.589 12.697 0 4.743-3.742 7.272-8.798 7.272-2.739 0-8.061-.738-8.061-3.637 0-1.158.791-4.162.791-4.162M279.388 50.463h1.686c.316 4.479 3.425 5.848 5.849 5.848 2.317 0 3.897-1.264 3.897-3.319 0-5.425-11.643-4.898-11.643-12.802 0-4.266 3.32-7.006 8.746-7.006 3.108 0 6.848.949 6.848.949l-1.106 5.689h-1.685c-.106-4.214-3.268-4.689-4.531-4.689-2.475 0-3.582 1.475-3.582 3.16 0 5.481 11.589 4.373 11.589 12.697 0 4.743-3.74 7.272-8.798 7.272-2.739 0-8.059-.738-8.059-3.637 0-1.158.789-4.162.789-4.162" fill="#231f20"/></g></svg>
nav-styles.css CHANGED
@@ -15,37 +15,206 @@
15
  font-family: 'vaultpressregular' !important;
16
  }
17
 
18
- /* ==========================================================================
19
- Notices
20
- ========================================================================== */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
- .vp-notice {
23
- display: block;
24
- margin-top: 30px;
25
- padding: 30px;
26
- border-radius: 6px;
27
- background: #fff;
28
  }
29
 
30
- .vp-notice h3 {
31
- margin: 0 0 10px 0;
32
- font-size: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  font-weight: 400;
 
 
 
 
 
 
34
  }
35
 
36
- .vp-notice p {
37
- margin: 0;
38
- padding: 0;
39
- font-size: 14px;
40
- line-height: 1.6;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
 
43
- .vp-error {
44
- background-color: #AB0300;
45
- color: #fff;
 
 
46
  }
47
 
48
- .vp-error h3,
49
- .vp-error a {
50
- color: #fff;
 
 
 
 
 
 
 
 
 
51
  }
15
  font-family: 'vaultpressregular' !important;
16
  }
17
 
18
+ /**
19
+ * Notices
20
+ */
21
+ .dops-notice {
22
+ display: flex;
23
+ position: relative;
24
+ width: 100%;
25
+ margin-bottom: 24px;
26
+ box-sizing: border-box;
27
+ background: #414141;
28
+ color: white;
29
+ border-radius: 3px;
30
+ line-height: 1.5;
31
+ }
32
+
33
+ .dops-notice.is-success .dops-notice__icon-wrapper {
34
+ background: #4ab866;
35
+ }
36
+
37
+ .dops-notice.is-warning .dops-notice__icon-wrapper {
38
+ background: #f0b849;
39
+ }
40
+
41
+ .dops-notice.is-error .dops-notice__icon-wrapper {
42
+ background: #d94f4f;
43
+ }
44
+
45
+ .dops-notice.is-info .dops-notice__icon-wrapper {
46
+ background: #00aadc;
47
+ }
48
+
49
+ .dops-notice .dops-notice__dismiss {
50
+ overflow: hidden;
51
+ }
52
+
53
+ .dops-notice.is-success .dops-notice__dismiss, .dops-notice.is-error .dops-notice__dismiss, .dops-notice.is-warning .dops-notice__dismiss, .dops-notice.is-info .dops-notice__dismiss {
54
+ overflow: hidden;
55
+ }
56
+
57
+ .dops-notice__icon-wrapper {
58
+ background: #747474;
59
+ color: white;
60
+ display: flex;
61
+ align-items: baseline;
62
+ width: 47px;
63
+ justify-content: center;
64
+ border-radius: 3px 0 0 3px;
65
+ flex-shrink: 0;
66
+ align-self: stretch;
67
+ }
68
+
69
+ .dops-notice__icon-wrapper .gridicon {
70
+ margin-top: 10px;
71
+ fill: currentColor;
72
+ }
73
+
74
+ @media (min-width: 481px) {
75
+ .dops-notice__icon-wrapper .gridicon {
76
+ margin-top: 12px;
77
+ }
78
+ }
79
+
80
+ .dops-notice__content {
81
+ padding: 13px;
82
+ font-size: 12px;
83
+ flex-grow: 1;
84
+ }
85
+
86
+ @media (min-width: 481px) {
87
+ .dops-notice__content {
88
+ font-size: 14px;
89
+ }
90
+ }
91
+
92
+ .dops-notice__text a.dops-notice__text-no-underline {
93
+ text-decoration: none;
94
+ }
95
+
96
+ .dops-notice__text a,
97
+ .dops-notice__text a:visited {
98
+ text-decoration: underline;
99
+ color: white;
100
+ }
101
+
102
+ .dops-notice__text a:hover,
103
+ .dops-notice__text a:visited:hover {
104
+ color: white;
105
+ text-decoration: none;
106
+ }
107
 
108
+ .dops-notice__text ul {
109
+ margin-bottom: 0;
110
+ margin-left: 0;
 
 
 
111
  }
112
 
113
+ .dops-notice__text li {
114
+ margin-left: 2em;
115
+ margin-top: 0.5em;
116
+ }
117
+
118
+ .dops-notice__text p {
119
+ margin-bottom: 0;
120
+ margin-top: 0.5em;
121
+ }
122
+
123
+ .dops-notice__text p:first-child {
124
+ margin-top: 0;
125
+ }
126
+
127
+ .dops-notice__button {
128
+ cursor: pointer;
129
+ margin-left: 0.428em;
130
+ }
131
+
132
+ .dops-notice__dismiss {
133
+ flex-shrink: 0;
134
+ padding: 12px;
135
+ cursor: pointer;
136
+ padding-bottom: 0;
137
+ }
138
+
139
+ .dops-notice__dismiss .gridicon {
140
+ width: 18px;
141
+ height: 18px;
142
+ }
143
+
144
+ @media (min-width: 481px) {
145
+ .dops-notice__dismiss {
146
+ padding: 11px;
147
+ padding-bottom: 0;
148
+ }
149
+
150
+ .dops-notice__dismiss .gridicon {
151
+ width: 24px;
152
+ height: 24px;
153
+ }
154
+ }
155
+
156
+ .dops-notice .dops-notice__dismiss {
157
+ color: #bbb;
158
+ }
159
+
160
+ .dops-notice .dops-notice__dismiss:hover, .dops-notice .dops-notice__dismiss:focus {
161
+ color: white;
162
+ }
163
+
164
+ a.dops-notice__action {
165
+ cursor: pointer;
166
+ font-size: 12px;
167
  font-weight: 400;
168
+ text-decoration: none;
169
+ white-space: nowrap;
170
+ color: #bbb;
171
+ padding: 13px;
172
+ display: flex;
173
+ align-items: center;
174
  }
175
 
176
+ @media (min-width: 481px) {
177
+ a.dops-notice__action {
178
+ flex-shrink: 1;
179
+ flex-grow: 0;
180
+ align-items: center;
181
+ border-radius: 0;
182
+ font-size: 14px;
183
+ margin: 0 0 0 auto;
184
+ padding: 13px 16px;
185
+ }
186
+
187
+ a.dops-notice__action .gridicon {
188
+ width: 24px;
189
+ height: 24px;
190
+ }
191
+ }
192
+
193
+ a.dops-notice__action:visited {
194
+ color: #bbb;
195
+ }
196
+
197
+ a.dops-notice__action:hover {
198
+ color: white;
199
  }
200
 
201
+ a.dops-notice__action .gridicon {
202
+ margin-left: 8px;
203
+ opacity: 0.7;
204
+ width: 18px;
205
+ height: 18px;
206
  }
207
 
208
+ /* These two avoid displaying the notice before WP core moves it below the heading */
209
+ #wpbody-content > .vp-notice.notice {
210
+ display: none;
211
+ }
212
+ #wpbody-content > .wrap > .vp-notice.notice {
213
+ display: flex;
214
+ }
215
+
216
+ /* Fix layout when the notice is shown in regular WP core screens */
217
+ .wrap > .vp-notice.notice {
218
+ border-left: none;
219
+ padding: 0;
220
  }
readme.txt CHANGED
@@ -1,9 +1,10 @@
1
  === VaultPress ===
2
  Contributors: automattic, apokalyptik, briancolinger, josephscott, shaunandrews, xknown, thingalon, annezazu, rachelsquirrel
3
  Tags: security, malware, virus, archive, back up, back ups, backup, backups, scanning, restore, wordpress backup, site backup, website backup
4
- Requires at least: 3.2
5
- Tested up to: 5.1.1
6
- Stable tag: 1.9.10
 
7
  License: GPLv2
8
 
9
  VaultPress is a subscription service offering real-time backup, automated security scanning, and support from WordPress experts.
@@ -30,11 +31,11 @@ View our full list of FAQs at [http://help.vaultpress.com/faq/](http://help.vaul
30
 
31
  = What’s included in each plan? =
32
 
33
- All plans include automated daily backups (unlimited storage space) of your entire site, 1-click restores, stats, priority support, brute force attack protection, uptime monitoring, spam protection, site migration, and an activity log.
34
 
35
  The Personal and Premium plans are limited to a 30-day backup archive while Professional is unlimited.
36
 
37
- The Premium and Professional plans also offer automated security scanning against malware and infiltrations with the Professional plan also offering automated threat resolution.
38
 
39
  [Visit our site](https://vaultpress.com/contact/) for more detail and up-to-date information.
40
 
@@ -47,193 +48,28 @@ A VaultPress subscription is for a single WordPress site. You can purchase addit
47
  Yes, VaultPress supports Multisite installs. Each site will require its own subscription.
48
 
49
  == Changelog ==
50
- = 1.9.10 - 4 April 2019 =
51
- * Bugfix: Fix a PHP fatal error caused by passing an object to the current() function.
52
 
53
- = 1.9.9 - 28 March 2019 =
54
- * PHP 7.2.0 compatibility fix.
55
- * Adding button to delete all VaultPress settings
56
 
57
- = 1.9.8 - 7 February 2019 =
58
- * Limit the size of _vp_ai_ping_% entries when a site gets disconnected from VaultPress.com
59
 
60
- = 1.9.7 - 11 December 2018 =
61
- * Update firewall IP detection rules to autodetect various reverse proxy setups
62
 
63
- = 1.9.6 - 17 August 2018 =
64
- * Limit _vp_ai_ping_% entries to improve stability when a site gets disconnected from VaultPress.com
65
 
66
- = 1.9.5 - 2 February 2018 =
67
- * Removing activation notice
68
 
69
- = 1.9.4 - 15 November 2017 =
70
- * Error handling improvements in the scanner
71
 
72
- = 1.9.3 - 9 November 2017 =
73
- * Compatibility update
74
- * Send a better user-agent string to VaultPress servers
75
 
76
- = 1.9.2 - 6 July 2017 =
77
- * Compatibility update
78
 
79
- = 1.9.1 - 29 June 2017 =
80
- * Security improvement: use hash_equals to compare signatures
81
 
82
- = 1.9.0 - 5 June 2017 =
83
- * Bugfix: Check return value from openssl_verify()
84
 
85
- = 1.8.9 - 8 May 2017 =
86
- * Remove outdated free trial link
87
 
88
- = 1.8.7 - 6 March 2017 =
89
- * Security fix for https://wpvulndb.com/vulnerabilities/8745
90
 
91
- = 1.8.6 - 26 January 2016 =
92
- * Compatibility updates
93
- * Security hotfixes
94
- * Improved performance for security scanner
95
- * Misc small bugfixes
96
-
97
- = 1.8.5 - 7 August 2016 =
98
- * Delete plugin option when plugin is deleted via admin area.
99
- * Fix horizontal scroll bar on the fresh installation settings page at high resolutions.
100
-
101
- = 1.8.4 - 21 July 2016 =
102
- * Compatibility updates for Jetpack 4.1
103
-
104
- = 1.8.3 - 26 May 2016 =
105
- * Security: Hotfix for certain versions of Jetpack
106
-
107
- = 1.8.2 - 11 May 2016 =
108
- * Workaround for some versions of mod_security.
109
-
110
- = 1.8.1 - 29 Mar 2016 =
111
- * Improved support for WooCommerce live backups.
112
- * Bugfix: Avoid cloning the 'vaultpress' option between Multisite instances.
113
-
114
- = 1.8.0 - 7 Mar 2016 =
115
- * Add support for an upcoming ability to have the Jetpack plugin manage registering the VaultPress plugin and entering the required API key. Gone will be the days of needing to copy/paste it!
116
-
117
- = 1.7.9 - 24 Feb 2016 =
118
- * PHP 7 support. Drop support for PHP 4 and versions of WordPress older than 3.2.
119
- * Silence PHP errors when attempting to change the execution time limit when PHP is running in safe mode.
120
- * Prevent database update pings from being stored when not connected to a paid VaultPress account.
121
-
122
- = 1.7.8 - 15 Oct 2015 =
123
- * Security: Hotfix for Akismet < 3.1.5.
124
-
125
- = 1.7.7 - 15 Sep 2015 =
126
- * Security: Add a new security hotfix.
127
-
128
- = 1.7.6 - 14 Aug 2015 =
129
- * Improved support for multisite installs with custom domains
130
- * Improved live-backup support for WooCommerce
131
- * Tested against WordPress 4.3
132
-
133
- = 1.7.5 - 11 Jun 2015 =
134
- * Security: Add a new security hotfix.
135
-
136
- = 1.7.4 - 28 Apr 2015 =
137
- * Bugfix: Don't allow openssl signing unless the public key exists.
138
-
139
- = 1.7.3 - 27 Apr 2015 =
140
- * Security: Add a new security hotfix.
141
-
142
- = 1.7.2 - 20 Apr 2015 =
143
- * Hotfix: Protect against a core security issue.
144
- * Bugfix: Don't allow direct access to plugin files
145
- * Bugfix: Ensure that the firewall rule option is not autoloaded.
146
- * Bugfix: More careful path tidy-up when inspecting directory contents. Fixes an edge case where some sites were having backup problems.
147
-
148
- = 1.7.1 - 25 Mar 2015 =
149
- * Added support for openssl signing.
150
-
151
- = 1.7.0 - 9 Jan 2015 =
152
- * Added an option to disable calls to php_uname, as some hosts don't allow them.
153
-
154
- = 1.6.9 - 24 Dec 2014 =
155
- * Tested against WordPress 4.1
156
-
157
- = 1.6.8 - 12 Dec 2014 =
158
- * Bugfix: Fall back on HTTP when updating firewall via HTTPS fails. Still warn the user about the security implications.
159
-
160
- = 1.6.7 - 1 Dec 2014 =
161
- * Security: More efficient format for internal firewall IPs.
162
-
163
- = 1.6.6 - 14 Nov 2014 =
164
- * Security: Fetch service IP updates via HTTPS.
165
- * Feature: Don't send backup notifications while mass-deleting spam.
166
-
167
- = 1.6.5 - 4 Sep 2014 =
168
- * Security: Hotfix for the Slider Revolution plugin.
169
-
170
- = 1.6.4 - 3 Sep 2014 =
171
- * Bumping the "Tested up to" tag to 4.0
172
-
173
- = 1.6.3 - 30 Jul 2014 =
174
- * Bugfix: Make sure existing empty key and secret options are always strings. This fixes an error when run with HHVM.
175
- * Bugfix: Detect if the plugin has been installed on localhost and show an error.
176
- * CSS Fix: Stop the "Register" button from bouncing around when clicked.
177
-
178
- = 1.6.2 - 10 Jul 2014 =
179
- * Feature: Instantly register for a VaultPress trial via Jetpack.
180
- * Bugfix: Make sure the key and secret options are always strings. This fixes an error when run with HHVM.
181
-
182
- = 1.6.1 - 1 Jul 2014 =
183
- * Security: Add a new security hotfix.
184
-
185
- = 1.6 - 27 Jun 2014 =
186
- * Bugfix: Better handling for Multisite table prefixes.
187
- * Bugfix: Do not use the deprecated wpdb::escape() method.
188
-
189
- = 1.5.9 - 16 Jun 2014 =
190
- * Feature: If available, use command line md5sum and sha1sum to get checksums for large files.
191
-
192
- = 1.5.8 - 3 Jun 2014 =
193
- * Security: Add a new security hotfix.
194
-
195
- = 1.5.7 - 11 Apr 2014 =
196
- * Bugfix: Avoid PHP 5.4 warnings due to invalid constructor names.
197
- * Security: Add a new security hotfix.
198
-
199
- = 1.5.6 - 1 Apr 2014 =
200
- * Bugfix: Avoid PHP 5.4 warnings.
201
- * Bugfix: Some servers with restrictive security filters make database restores fail.
202
- * Feature: Add a new restore method to VaultPress_Database.
203
-
204
- = 1.5.2 - 26 Dec 2013 =
205
- * Bugfix: Adding less greedy patterns for cache directories.
206
-
207
- = 1.5.1 - 16 Dec 2013 =
208
- * Feature: Adding file exclusion patterns to avoid backing up cache and backup directories.
209
-
210
- = 1.5 - 11 Dec 2013 =
211
- * Bugfix: Don't show admin notices on the about page.
212
-
213
- = 1.4.9 - 10 Oct 2013 =
214
- * Bugfix: Clean up PHP5 strict warnings.
215
-
216
- = 1.4.8 - 15 Jul 2013 =
217
- * Feature: Include styles and images with the plugin instead of loading them externally.
218
-
219
- = 1.4.7 - 2 Jul 2013 =
220
- * Bugfix: Some servers have SSL configuration problems, which breaks the plugin when SSL verification is enforced.
221
-
222
- = 1.4.6 - 26 Jun 2013 =
223
- * Bugfix: PHP 5.4 notices
224
- * Feature: Add the possibility to ignore frequent updates on some postmeta keys.
225
-
226
- = 1.3.9 =
227
- * Feature: Request decoding (base64/rot13)
228
- * Feature: Response encoding (base64/rot13)
229
-
230
- = 1.3.8 =
231
- * Bugfix: Validate IPv4-mapped IPv6 addresses in the internal firewall.
232
- * Bugfix: Fix hooks not being properly added under certain circumstances.
233
-
234
- = 1.3.7 =
235
- * Bugfix: Protect against infinite loop due to a PHP bug.
236
- * Bugfix: Encode remote ping requests.
237
-
238
- = 1.0 =
239
- * First public release!
1
  === VaultPress ===
2
  Contributors: automattic, apokalyptik, briancolinger, josephscott, shaunandrews, xknown, thingalon, annezazu, rachelsquirrel
3
  Tags: security, malware, virus, archive, back up, back ups, backup, backups, scanning, restore, wordpress backup, site backup, website backup
4
+ Requires at least: 5.1
5
+ Tested up to: 5.2
6
+ Stable tag: 2.0
7
+ Requires PHP: 5.3
8
  License: GPLv2
9
 
10
  VaultPress is a subscription service offering real-time backup, automated security scanning, and support from WordPress experts.
31
 
32
  = What’s included in each plan? =
33
 
34
+ All plans include automated daily backups (unlimited storage space) of your entire site, 1-click restores, stats, priority support, brute force attack protection, uptime monitoring, spam protection, site migration, and an activity log.
35
 
36
  The Personal and Premium plans are limited to a 30-day backup archive while Professional is unlimited.
37
 
38
+ The Premium and Professional plans also offer automated security scanning against malware and infiltrations with the Professional plan also offering automated threat resolution.
39
 
40
  [Visit our site](https://vaultpress.com/contact/) for more detail and up-to-date information.
41
 
48
  Yes, VaultPress supports Multisite installs. Each site will require its own subscription.
49
 
50
  == Changelog ==
 
 
51
 
52
+ = 2.0 =
 
 
53
 
54
+ * Release date: July 9, 2019
 
55
 
56
+ **Enhancements**
 
57
 
58
+ * Dashboard: redesign the main VaultPress dashboard.
 
59
 
60
+ **Compatibility**
 
61
 
62
+ * General: VaultPress now requires PHP 5.3.2, and will display a notice if your site uses an older version of PHP.
 
63
 
 
 
 
64
 
65
+ = 1.9.10 =
 
66
 
67
+ * Release date: April 4, 2019
 
68
 
69
+ **Bug fixes**
 
70
 
71
+ * Fix a PHP fatal error caused by passing an object to the current() function.
 
72
 
73
+ --------
 
74
 
75
+ [See the previous changelogs here](https://raw.githubusercontent.com/Automattic/vaultpress/master/changelog.txt).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
styles.css CHANGED
@@ -12,235 +12,501 @@ Mini normalize
12
  -webkit-font-smoothing: antialiased;
13
  }
14
 
 
 
 
 
 
 
 
15
 
16
- /* ==========================================================================
17
- Helpers
18
- ========================================================================== */
19
 
20
- /* Clearfix */
21
- .clearfix,
22
- .clrfix {
23
- zoom:1;
 
 
 
24
  }
25
 
26
- .clearfix:after,
27
- .clrfix:after {
28
- content:".";
29
- display:block;
30
- height:0;
31
- width:0;
32
- line-height:0;
33
- clear:both;
34
- visibility:hidden;
35
  }
36
 
37
- /* grid container */
38
- .grid {
39
- margin: 0 0 0 -1%;
40
  }
41
 
42
- .half {
43
- margin: 0 1% 2%;
44
- width: 48%;
45
- float: left;
46
  }
47
 
48
- @media (max-width: 767px) {
49
- .half {
50
- float: none;
51
- width: 98%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
  }
54
 
 
 
 
 
 
55
 
56
- /* ==========================================================================
57
- Buttons
58
- ========================================================================== */
59
- .vp_button-mega,
60
- .vp_button-mega:visited {
61
- position: relative;
 
62
  display: inline-block;
63
- margin: 0;
64
- padding: 10px 55px;
65
- border: 1px solid rgba(0, 0, 0, 0.4);
66
- border-radius: 30px;
67
- -webkit-background-clip: padding-box;
68
- background: #0090BA;
69
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #10C3EF), color-stop(3%, #10A6CC), color-stop(43%, #039BC1), color-stop(46%, #009AC4), color-stop(100%, #0084A5));
70
- background: -webkit-linear-gradient(top, #10C3EF 0%, #10A6CC 3%, #039BC1 43%, #009AC4 46%, #0084A5 100%);
71
- background: linear-gradient(top, #10C3EF 0%, #10A6CC 3%, #039BC1 43%, #009AC4 46%, #0084A5 100%);
72
- color: #fff;
73
- font-size: 16px;
74
- line-height: 1.5;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  font-weight: 400;
76
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
77
- text-decoration: none;
78
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 0 4px black;
79
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 0 4px black;
80
- cursor: pointer;
81
- outline: 0;
82
  }
83
 
84
- .vp_button-mega:hover,
85
- .vp_button-mega:active,
86
- .vp_button-mega:focus {
87
- color: #fff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
 
90
- .vp_card .vp_button-mega {
91
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 0 4px #eee;
92
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 0 4px #eee;
 
 
 
 
 
 
93
  }
94
 
95
- .vp_button-secondary {
96
- position: relative;
97
- top: 10px;
98
- left: -4px;
99
- float: left;
100
- padding: 7px 25px;
101
- border: 1px solid #999;
102
- border-radius: 30px;
103
- text-decoration: none;
104
- color: #333;
105
- font-size: 13px;
106
- text-shadow: 0 1px 0 #FFF;
107
- cursor: pointer;
108
- background: #ffffff;
109
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#dddddd));
110
- background: -webkit-linear-gradient(top, #ffffff 0%,#dddddd 100%);
111
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#dddddd',GradientType=0 );
112
- background: linear-gradient(top, #ffffff 0%,#dddddd 100%);
113
- outline: 0;
114
  }
115
 
116
- .vp_button-secondary:active,
117
- .vp-botton-secondary:hover,
118
- .vp-botton-secondary:focus {
119
- position: relative;
120
- background: #ccc;
 
121
  }
122
 
123
- .vp-visit-dashboard {
124
- /* same as .button-secondary */
 
 
 
 
 
 
125
  display: inline-block;
126
- height: 28px;
127
  margin: 0;
128
- border: 1px solid #ccc;
129
- border-radius: 3px;
130
- padding: 0 10px 1px;
131
- color: #555;
132
- font-size: 13px;
133
- line-height: 26px;
134
  text-decoration: none;
135
- cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  white-space: nowrap;
137
- background: #f7f7f7;
138
- -webkit-box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
139
- box-shadow: inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);
140
  }
141
 
142
- .vp-visit-dashboard:hover,
143
- .vp-visit-dashboard:focus {
144
- border-color: #999;
145
- background: #fafafa;
146
- color: #222;
147
  }
148
 
149
- .vp-visit-dashboard:focus {
150
- -webkit-box-shadow: 1px 1px 1px rgba(0,0,0,.2);
151
- box-shadow: 1px 1px 1px rgba(0,0,0,.2);
152
  }
153
 
154
- .vp-visit-dashbord:active {
155
- border-color: #999;
156
- background: #eee;
157
- color: #333;
158
- -webkit-box-shadow: inset 0 2px 5px -3px rgba(0,0,0,.5);
159
- box-shadow: inset 0 2px 5px -3px rgba(0,0,0,.5);
160
  }
161
 
 
 
 
 
162
 
163
- /* ==========================================================================
164
- Cards - dark and light panel patterns
165
- ========================================================================== */
 
 
166
 
167
- .vp_card,
168
- .vp_card-dark {
169
- margin-bottom: 2%;
170
- padding: 20px 30px 30px 30px;
171
- border-radius: 6px;
172
- background: #fff;
 
 
 
 
 
 
 
173
  }
174
 
175
- .vp_card-dark {
176
- background: #333 url(images/noise.png) repeat 0 0;
177
- color: #fff;
178
  }
179
 
180
- .vp_card h2,
181
- .vp_card-dark h2 {
182
- margin: 0 0 20px;
183
- font-size: 28px;
184
- font-weight: 300;
185
- line-height: 1.4;
186
  }
187
 
188
- .vp_card-dark h2{
189
- color: #fff;
190
  }
191
 
192
- .vp_card p,
193
- .vp_card-dark p {
194
- font-size: 15px;
195
  }
196
 
197
- .vp_card p:last-child,
198
- .vp_card-dark p:last-child {
199
- margin-bottom: 0;
 
 
 
 
 
200
  }
201
 
202
- .vp_card-dark p {
203
- color: #ccc;
 
 
 
204
  }
205
 
206
- .vp_card-description {
207
- margin-bottom: 30px;
208
  }
209
 
 
 
 
210
 
211
- /* ==========================================================================
212
- Header
213
- ========================================================================== */
 
 
 
 
 
 
214
 
215
- #vp-head {
 
216
  position: relative;
217
- margin-bottom: 10px;
218
- padding: 10px 0;
219
- width: 100%;
220
- overflow: hidden;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
222
 
223
- #vp-head h2 {
 
 
 
 
 
 
224
  margin-top: 0;
225
- padding: 11px 15px 4px 40px;
226
- background: url(images/plugin-shield.png) 0 7px no-repeat;
227
- background-size: 31px 32px;
228
- font-size: 23px;
229
- line-height: 29px;
230
  }
231
 
232
- @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3, '/', 2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
233
- #vp-head h2 {
234
- background-image: url(images/plugin-shield-2x.png) no-repeat;
235
  }
236
  }
237
 
238
- /* Dashboard link */
239
- #vp-head .button-secondary,
240
- .vp-visit-dashboard {
241
- position: absolute;
242
- top: 20px;
243
- right: 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  }
245
 
246
  /* --- Trial period notice --- */
@@ -290,13 +556,14 @@ Header
290
  background-size: 300px 420px;
291
  }
292
 
293
- #no-access-credentials p {
294
  margin: 20px 0;
295
  color: #333;
296
  font-size: 14px;
297
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
298
  text-align: left;
299
  line-height: 1.4;
 
300
  }
301
 
302
  @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3, '/', 2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
@@ -316,7 +583,6 @@ Header
316
  color: #fff;
317
  color: rgba(255,255,255,0.9);
318
  font-size: 12px;
319
- text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
320
  line-height: 24px;
321
  text-shadow: none;
322
  border-radius: 2px;
@@ -361,11 +627,11 @@ Status Ticker
361
 
362
  #vp-ticker {
363
  position: relative; /* WAT */
364
- top: 0px;
365
  margin: 0 20px 20px 0;
366
  padding: 9px 13px;
367
  border-radius: 4px;
368
- background: #333 url(images/noise.png) repeat 0 0;
369
  color: #ddd;
370
  }
371
 
@@ -533,10 +799,6 @@ Tabs
533
  Progress Bars
534
  ========================================================================== */
535
 
536
- #vp_progress {
537
- padding-right: 20px;
538
- }
539
-
540
  #vp_progress:after {
541
  /* clearfix */
542
  content: ".";
@@ -547,7 +809,7 @@ Progress Bars
547
  }
548
 
549
  .vp_graphs {
550
- background: #333 url(images/noise.png) repeat 0 0;
551
  color: #FFF;
552
  float: left;
553
  width: 380px;
@@ -589,7 +851,6 @@ Progress Bars
589
  }
590
  }
591
 
592
-
593
  .vp_graphs ul {
594
  padding: 0 0 5px 0;
595
  float: left;
@@ -616,6 +877,10 @@ Progress Bars
616
  background: linear-gradient(top, rgba(41,154,11,1) 0%,rgba(41,154,11,1) 100%);
617
  }
618
 
 
 
 
 
619
  #vp_progress .completed .percentage,
620
  #vp_progress .completed .title {
621
  color: #fff;
@@ -625,7 +890,7 @@ Progress Bars
625
  float: left;
626
  width: 215px;
627
  padding: 4px;
628
- background: #252525 url(images/noise.png) repeat 0 0;
629
  margin: 0 5px 0 0;
630
  border: 1px solid rgba(255,255,255,0.1);
631
  border-radius: 20px;
@@ -645,7 +910,6 @@ Progress Bars
645
  }
646
  }
647
 
648
-
649
  #vp_progress .bar span {
650
  float: left;
651
  height: 22px;
@@ -727,27 +991,24 @@ Progress Bars
727
  margin-bottom: 0;
728
  }
729
 
 
 
 
 
 
 
 
 
 
 
 
 
730
 
731
- /* ==========================================================================
732
- Not registered or activated
733
- ========================================================================== */
734
-
735
- .jetpack-available .vp_card-dark:not(.connect-via-jetpack) {
736
- padding: 60px 30px;
737
- width: 98%;
738
- text-align: center;
739
  }
740
 
741
- .vp_input-register {
742
- display: block;
743
- padding: 5px;
744
- width: 100%;
745
- height: 60px;
746
- border: 1px solid #999;
747
- border-radius: 3px;
748
- font-size: 14px;
749
- font-family: Georgia, Constantia, "Palatino Linotype", "Book Antiqua", serif;;
750
- -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);
751
- box-shadow: inset 0 2px 4px rgba(0,0,0,0.2);
752
- resize: vertical;
753
  }
12
  -webkit-font-smoothing: antialiased;
13
  }
14
 
15
+ #jp-plugin-container #vp-head,
16
+ #jp-plugin-container hr {
17
+ display: none;
18
+ }
19
+ #jp-plugin-container #vp-wrap {
20
+ margin-bottom: 24px;
21
+ }
22
 
23
+ .notice {
24
+ display: none;
25
+ }
26
 
27
+ /**
28
+ * Layout
29
+ */
30
+ .wp-admin.jetpack_page_vaultpress {
31
+ background-color: #f6f6f6;
32
+ line-height: 1.4;
33
+ height: auto;
34
  }
35
 
36
+ .jetpack_page_vaultpress #wpcontent,
37
+ .toplevel_page_vaultpress #wpcontent {
38
+ padding-left: 0;
 
 
 
 
 
 
39
  }
40
 
41
+ #jp-plugin-container {
42
+ min-height: 100vh;
43
+ margin: 0;
44
  }
45
 
46
+ #jp-plugin-container a {
47
+ text-decoration: none;
 
 
48
  }
49
 
50
+ .jp-masthead {
51
+ background-color: #fff;
52
+ text-align: center;
53
+ box-shadow: 0 1px 0 rgba(213, 213, 213, 0.5), 0 1px 2px #eee;
54
+ margin-bottom: 24px;
55
+ }
56
+
57
+ @media (max-width: 48.875rem) {
58
+ .jp-masthead {
59
+ padding: 0 1.5rem
60
+ }
61
+
62
+ .jetpack-masterbar .jp-masthead {
63
+ padding-left: 4rem
64
+ }
65
+ }
66
+
67
+ .jp-masthead__inside-container {
68
+ display: flex;
69
+ flex-wrap: wrap;
70
+ margin: 0 auto;
71
+ width: 100%;
72
+ max-width: 65rem;
73
+ padding-bottom: .375rem
74
+ }
75
+
76
+ @media (max-width: 1250px) {
77
+ .jp-masthead__inside-container {
78
+ max-width: 95%
79
  }
80
  }
81
 
82
+ .jp-masthead__logo-container {
83
+ flex-grow: 0;
84
+ flex-shrink: 0;
85
+ padding: .6875rem 0 0
86
+ }
87
 
88
+ @media (max-width: 480px) {
89
+ .jp-masthead__logo-container {
90
+ margin-right: 1rem
91
+ }
92
+ }
93
+
94
+ .jp-masthead__logo-link {
95
  display: inline-block;
96
+ outline: none;
97
+ vertical-align: middle
98
+ }
99
+
100
+ .jp-masthead__logo-link:focus {
101
+ line-height: 0;
102
+ box-shadow: 0 0 0 2px #78dcfa
103
+ }
104
+
105
+ .jp-masthead__logo-link img {
106
+ height: 32px;
107
+ }
108
+
109
+ .jp-masthead__nav {
110
+ display: flex;
111
+ flex-wrap: nowrap;
112
+ flex-grow: 1;
113
+ flex-shrink: 0;
114
+ text-align: right;
115
+ margin-top: .375rem;
116
+ padding: .25rem 0
117
+ }
118
+
119
+ @media (max-width: 480px) {
120
+ .jp-masthead__nav {
121
+ text-align: left
122
+ }
123
+ }
124
+
125
+ .jp-dash-section-header {
126
+ display: flex;
127
+ flex-wrap: wrap;
128
+ margin: 2.5rem 0 .5rem;
129
+ }
130
+
131
+ .jp-dash-section-header__name {
132
+ display: inline-block;
133
+ margin-top: 0;
134
+ margin-bottom: 0;
135
+ font-size: 1.25rem;
136
  font-weight: 400;
137
+ white-space: nowrap;
 
 
 
 
 
138
  }
139
 
140
+ .vp-wrap {
141
+ margin: 0 auto;
142
+ text-align: left;
143
+ max-width: 65rem;
144
+ padding: 1.5rem;
145
+ }
146
+
147
+ @media only screen and (min-width: 660px) {
148
+ .vp-row {
149
+ display: flex;
150
+ }
151
+
152
+ .vp-row .vp-col {
153
+ flex-basis: 50%;
154
+ }
155
+
156
+ .vp-row .vp-col:first-child {
157
+ margin-right: 1rem;
158
+ }
159
+
160
+ .vp-notice__wide img {
161
+ float: left;
162
+ margin-right: 2.5em;
163
+ }
164
  }
165
 
166
+ @media only screen and (max-width: 660px) {
167
+ .vp-notice__wide {
168
+ text-align: center;
169
+ }
170
+
171
+ .vp-notice__wide img,
172
+ .vp-notice__wide p {
173
+ margin-bottom: 2em;
174
+ }
175
  }
176
 
177
+ .vp-notice__wide .dops-card {
178
+ padding-top: 2.5em;
179
+ padding-bottom: 2.5em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  }
181
 
182
+ .vp-notice__wide img {
183
+ width: 200px;
184
+ }
185
+
186
+ .vp-notice__wide h2 {
187
+ margin-top: 0;
188
  }
189
 
190
+ /* Form */
191
+
192
+ .dops-button {
193
+ background: white;
194
+ border: solid #d5d5d5;
195
+ border-width: 1px 1px 2px;
196
+ color: #414141;
197
+ cursor: pointer;
198
  display: inline-block;
 
199
  margin: 0;
200
+ outline: 0;
201
+ overflow: hidden;
202
+ font-size: 14px;
203
+ font-weight: 500;
204
+ line-height: 21px;
205
+ text-overflow: ellipsis;
206
  text-decoration: none;
207
+ vertical-align: top;
208
+ box-sizing: border-box;
209
+ border-radius: 4px;
210
+ padding: 7px 14px 9px;
211
+ -webkit-appearance: none;
212
+ -moz-appearance: none;
213
+ appearance: none;
214
+ }
215
+
216
+ .dops-button:hover {
217
+ border-color: #bbb;
218
+ color: #414141;
219
+ }
220
+
221
+ .dops-button:active {
222
+ border-width: 2px 1px 1px;
223
+ }
224
+
225
+ .dops-button[disabled], .dops-button:disabled {
226
+ color: #eee;
227
+ background: white;
228
+ border-color: #eee;
229
+ cursor: default;
230
+ }
231
+
232
+ .dops-button[disabled]:active, .dops-button:disabled:active {
233
+ border-width: 1px 1px 2px;
234
+ }
235
+
236
+ .dops-button:focus {
237
+ outline: 0;
238
+ border-color: #00aadc;
239
+ box-shadow: 0 0 0 2px #78dcfa;
240
+ }
241
+
242
+ .dops-button.is-compact {
243
+ padding: 7px;
244
+ color: #888;
245
+ font-size: 11px;
246
+ line-height: 1;
247
+ text-transform: uppercase;
248
+ }
249
+
250
+ .dops-button.is-compact:disabled {
251
+ color: #eee;
252
+ }
253
+
254
+ .dops-button.is-primary {
255
+ background: #00aadc;
256
+ border-color: #0087be;
257
+ color: white;
258
+ }
259
+
260
+ .dops-button.is-primary:hover, .dops-button.is-primary:focus {
261
+ border-color: #005082;
262
+ color: white;
263
+ }
264
+
265
+ .dops-button.is-primary[disabled], .dops-button.is-primary:disabled {
266
+ background: #bceefd;
267
+ border-color: #8cc9e2;
268
+ color: white;
269
+ }
270
+
271
+ .dops-button.is-primary.is-compact {
272
+ color: white;
273
  white-space: nowrap;
 
 
 
274
  }
275
 
276
+ .dops-button.is-scary {
277
+ color: #d94f4f;
 
 
 
278
  }
279
 
280
+ .dops-button.is-scary:hover, .dops-button.is-scary:focus {
281
+ border-color: #d94f4f;
 
282
  }
283
 
284
+ .dops-button.is-scary:focus {
285
+ box-shadow: 0 0 0 2px #eba3a3;
 
 
 
 
286
  }
287
 
288
+ .dops-button.is-scary[disabled], .dops-button.is-scary:disabled {
289
+ color: #f4cdcd;
290
+ border-color: #eee;
291
+ }
292
 
293
+ .dops-button-group {
294
+ flex-grow: 1;
295
+ align-self: center;
296
+ font-size: 0;
297
+ }
298
 
299
+ .dops-textarea {
300
+ box-sizing: border-box;
301
+ margin: 0;
302
+ padding: 0.4375rem 0.875rem;
303
+ min-height: 5.75rem;
304
+ width: 100%;
305
+ color: #414141;
306
+ font-size: 1rem;
307
+ line-height: 1.5;
308
+ border: 1px solid #d5d5d5;
309
+ background-color: #fff;
310
+ transition: all .15s ease-in-out;
311
+ box-shadow: none;
312
  }
313
 
314
+ .dops-textarea:-ms-input-placeholder {
315
+ color: #a2a2a2;
 
316
  }
317
 
318
+ .dops-textarea::-ms-input-placeholder {
319
+ color: #a2a2a2;
 
 
 
 
320
  }
321
 
322
+ .dops-textarea::placeholder {
323
+ color: #a2a2a2;
324
  }
325
 
326
+ .dops-textarea:hover {
327
+ border-color: #bbb;
 
328
  }
329
 
330
+ .dops-textarea:focus {
331
+ border-color: #0087be;
332
+ outline: none;
333
+ box-shadow: 0 0 0 2px #78dcfa;
334
+ }
335
+
336
+ .dops-textarea:focus::-ms-clear {
337
+ display: none;
338
  }
339
 
340
+ .dops-textarea:disabled {
341
+ background: #f6f6f6;
342
+ border-color: #eee;
343
+ color: #bbb;
344
+ -webkit-text-fill-color: #bbb;
345
  }
346
 
347
+ .dops-textarea:disabled:hover {
348
+ cursor: default;
349
  }
350
 
351
+ .dops-textarea:disabled:-ms-input-placeholder {
352
+ color: #bbb;
353
+ }
354
 
355
+ .dops-textarea:disabled::-ms-input-placeholder {
356
+ color: #bbb;
357
+ }
358
+
359
+ .dops-textarea:disabled::placeholder {
360
+ color: #bbb;
361
+ }
362
+
363
+ /* Card */
364
 
365
+ .dops-card {
366
+ display: block;
367
  position: relative;
368
+ margin: 0 auto 10px auto;
369
+ padding: 16px;
370
+ box-sizing: border-box;
371
+ background: white;
372
+ box-shadow: 0 0 0 1px rgba(213, 213, 213, 0.5), 0 1px 2px #eee;
373
+ }
374
+
375
+ .dops-card:after {
376
+ content: ".";
377
+ display: block;
378
+ height: 0;
379
+ clear: both;
380
+ visibility: hidden;
381
+ }
382
+
383
+ @media (min-width: 481px) {
384
+ .dops-card {
385
+ margin-bottom: 16px;
386
+ padding: 24px;
387
+ }
388
+ }
389
+
390
+ .dops-card.is-compact {
391
+ margin-bottom: 1px;
392
+ }
393
+
394
+ @media (min-width: 481px) {
395
+ .dops-card.is-compact {
396
+ margin-bottom: 1px;
397
+ padding: 16px 24px;
398
+ }
399
+ }
400
+
401
+ /**
402
+ * Footer
403
+ */
404
+ .jp-footer {
405
+ text-align: center;
406
+ margin: 1rem 0 2rem
407
+ }
408
+
409
+ @media (max-width: 1040px) {
410
+ .jp-footer {
411
+ margin: 2rem 0 1.5rem
412
+ }
413
+ }
414
+
415
+ @media (max-width: 660px) {
416
+ .jp-footer {
417
+ margin: 1.5rem 0 1rem
418
+ }
419
+ }
420
+
421
+ .jp-footer__a8c-attr-container {
422
+ margin-bottom: .5rem
423
+ }
424
+
425
+ .jp-footer__a8c-attr {
426
+ width: 11.25rem
427
  }
428
 
429
+ .jp-footer__a8c-attr path {
430
+ fill: #888
431
+ }
432
+
433
+ .jp-footer__links {
434
+ border-top: 1px #e1e1e1 solid;
435
+ border-bottom: 1px #e1e1e1 solid;
436
  margin-top: 0;
437
+ margin-bottom: 1rem
 
 
 
 
438
  }
439
 
440
+ @media (max-width: 660px) {
441
+ .jp-footer__links {
442
+ border-bottom: none
443
  }
444
  }
445
 
446
+ .jp-footer__link-item {
447
+ display: inline-block;
448
+ margin-bottom: 0
449
+ }
450
+
451
+ @media (min-width: 661px) {
452
+ .jp-footer__link-item {
453
+ display: inline-block
454
+ }
455
+ }
456
+
457
+ @media (max-width: 660px) {
458
+ .jp-footer__link-item {
459
+ display: block;
460
+ border-bottom: 1px #e1e1e1 solid
461
+ }
462
+ }
463
+
464
+ .jp-footer__link {
465
+ padding: 1rem .5rem;
466
+ color: #888;
467
+ display: inline-block;
468
+ cursor: pointer
469
+ }
470
+
471
+ .jp-footer__link:visited {
472
+ color: #888
473
+ }
474
+
475
+ .jp-footer__link:hover, .jp-footer__link:active {
476
+ color: #272727
477
+ }
478
+
479
+ @media (max-width: 660px) {
480
+ .jp-footer__link {
481
+ display: block;
482
+ padding: .5rem 0;
483
+ border-bottom: 1px #e1e1e1 solid
484
+ }
485
+
486
+ .jp-footer__link:last-of-type {
487
+ border-bottom: none
488
+ }
489
+ }
490
+
491
+ /* ==========================================================================
492
+ Helpers
493
+ ========================================================================== */
494
+
495
+ /* Clearfix */
496
+ .clearfix,
497
+ .clrfix {
498
+ zoom:1;
499
+ }
500
+
501
+ .clearfix:after,
502
+ .clrfix:after {
503
+ content:".";
504
+ display:block;
505
+ height:0;
506
+ width:0;
507
+ line-height:0;
508
+ clear:both;
509
+ visibility:hidden;
510
  }
511
 
512
  /* --- Trial period notice --- */
556
  background-size: 300px 420px;
557
  }
558
 
559
+ #vp-wrap #no-access-credentials p {
560
  margin: 20px 0;
561
  color: #333;
562
  font-size: 14px;
563
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
564
  text-align: left;
565
  line-height: 1.4;
566
+ background: none;
567
  }
568
 
569
  @media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3, '/', 2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5) {
583
  color: #fff;
584
  color: rgba(255,255,255,0.9);
585
  font-size: 12px;
 
586
  line-height: 24px;
587
  text-shadow: none;
588
  border-radius: 2px;
627
 
628
  #vp-ticker {
629
  position: relative; /* WAT */
630
+ top: 0;
631
  margin: 0 20px 20px 0;
632
  padding: 9px 13px;
633
  border-radius: 4px;
634
+ background: #333;
635
  color: #ddd;
636
  }
637
 
799
  Progress Bars
800
  ========================================================================== */
801
 
 
 
 
 
802
  #vp_progress:after {
803
  /* clearfix */
804
  content: ".";
809
  }
810
 
811
  .vp_graphs {
812
+ background: #333;
813
  color: #FFF;
814
  float: left;
815
  width: 380px;
851
  }
852
  }
853
 
 
854
  .vp_graphs ul {
855
  padding: 0 0 5px 0;
856
  float: left;
877
  background: linear-gradient(top, rgba(41,154,11,1) 0%,rgba(41,154,11,1) 100%);
878
  }
879
 
880
+ #vp-wrap #vp_progress .vp_graphs ul li {
881
+ width: 100%;
882
+ }
883
+
884
  #vp_progress .completed .percentage,
885
  #vp_progress .completed .title {
886
  color: #fff;
890
  float: left;
891
  width: 215px;
892
  padding: 4px;
893
+ background: #252525;
894
  margin: 0 5px 0 0;
895
  border: 1px solid rgba(255,255,255,0.1);
896
  border-radius: 20px;
910
  }
911
  }
912
 
 
913
  #vp_progress .bar span {
914
  float: left;
915
  height: 22px;
991
  margin-bottom: 0;
992
  }
993
 
994
+ /**
995
+ * Jetpack logo
996
+ */
997
+ .jp-power {
998
+ display: flex;
999
+ justify-content: center;
1000
+ align-items: center;
1001
+ }
1002
+ .jp-power__text {
1003
+ color: #888;
1004
+ margin-right: 10px;
1005
+ }
1006
 
1007
+ .jetpack-logo {
1008
+ vertical-align: middle;
 
 
 
 
 
 
1009
  }
1010
 
1011
+ .jetpack-logo__icon-circle,
1012
+ .jetpack-logo__text {
1013
+ fill: #636d75;
 
 
 
 
 
 
 
 
 
1014
  }
vaultpress.php CHANGED
@@ -1,2637 +1,123 @@
1
  <?php
2
- /*
3
  * Plugin Name: VaultPress
4
  * Plugin URI: http://vaultpress.com/?utm_source=plugin-uri&amp;utm_medium=plugin-description&amp;utm_campaign=1.0
5
  * Description: Protect your content, themes, plugins, and settings with <strong>realtime backup</strong> and <strong>automated security scanning</strong> from <a href="http://vaultpress.com/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">VaultPress</a>. Activate, enter your registration key, and never worry again. <a href="http://vaultpress.com/help/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">Need some help?</a>
6
- * Version: 1.9.10
7
  * Author: Automattic
8
  * Author URI: http://vaultpress.com/?utm_source=author-uri&amp;utm_medium=plugin-description&amp;utm_campaign=1.0
9
  * License: GPL2+
10
  * Text Domain: vaultpress
11
  * Domain Path: /languages/
 
 
12
  */
13
 
14
- // don't call the file directly
15
- defined( 'ABSPATH' ) or die();
16
 
17
- class VaultPress {
18
- var $option_name = 'vaultpress';
19
- var $auto_register_option = 'vaultpress_auto_register';
20
- var $db_version = 4;
21
- var $plugin_version = '1.9.10';
22
 
23
- function __construct() {
24
- register_activation_hook( __FILE__, array( $this, 'activate' ) );
25
- register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
26
-
27
- $this->options_blog_id = get_current_blog_id();
28
- $options = get_option( $this->option_name );
29
- if ( !is_array( $options ) )
30
- $options = array();
31
-
32
- $defaults = array(
33
- 'db_version' => 0,
34
- 'key' => '',
35
- 'secret' => '',
36
- 'connection' => false,
37
- 'service_ips_cidr' => false
38
- );
39
-
40
- $this->options = wp_parse_args( $options, $defaults );
41
- $this->reset_pings();
42
-
43
- $this->upgrade();
44
-
45
- $this->add_global_actions_and_filters();
46
-
47
- if ( is_admin() ) {
48
- $this->add_admin_actions_and_filters();
49
- }
50
-
51
- if ( $this->is_registered() ) {
52
- $do_not_backup = $this->get_option( 'do_not_backup' ) || $this->get_option( 'do_not_send_backup_pings' );
53
- if ( $do_not_backup )
54
- $this->add_vp_required_filters();
55
- else
56
- $this->add_listener_actions_and_filters();
57
- }
58
- }
59
-
60
- static function &init() {
61
- static $instance = false;
62
-
63
- if ( !$instance ) {
64
- $instance = new VaultPress();
65
- }
66
-
67
- return $instance;
68
- }
69
-
70
- static function register( $registration_key ) {
71
- $vp = self::init();
72
-
73
- $nonce = wp_create_nonce( 'vp_register_' . $registration_key );
74
- $args = array( 'registration_key' => $registration_key, 'nonce' => $nonce );
75
- $response = $vp->contact_service( 'register', $args );
76
-
77
- // Check for an error
78
- if ( ! empty( $response['faultCode'] ) )
79
- return new WP_Error( $response['faultCode'], $response['faultString'] );
80
-
81
- // Validate result
82
- if ( empty( $response['key'] ) || empty( $response['secret'] ) || empty( $response['nonce'] ) || $nonce != $response['nonce'] )
83
- return new WP_Error( 1, __( 'There was a problem trying to register your VaultPress subscription.' ) );
84
-
85
- // Store the result, force a connection test.
86
- $vp->update_option( 'key', $response['key'] );
87
- $vp->update_option( 'secret', $response['secret'] );
88
- $vp->check_connection( true );
89
-
90
- return true;
91
- }
92
-
93
- function activate( $network_wide ) {
94
- $type = $network_wide ? 'network' : 'single';
95
- $this->update_option( 'activated', $type );
96
-
97
- // force a connection check after an activation
98
- $this->clear_connection();
99
-
100
- if ( get_option( 'vaultpress_auto_connect' ) ) {
101
- $this->register_via_jetpack( true );
102
- }
103
- }
104
-
105
- function deactivate() {
106
- if ( $this->is_registered() )
107
- $this->contact_service( 'plugin_status', array( 'vp_plugin_status' => 'deactivated' ) );
108
- }
109
-
110
- function upgrade() {
111
- $current_db_version = $this->get_option( 'db_version' );
112
-
113
- if ( $current_db_version < 1 ) {
114
- $this->options['connection'] = get_option( 'vaultpress_connection' );
115
- $this->options['key'] = get_option( 'vaultpress_key' );
116
- $this->options['secret'] = get_option( 'vaultpress_secret' );
117
- $this->options['service_ips'] = get_option( 'vaultpress_service_ips' );
118
-
119
- // remove old options
120
- $old_options = array(
121
- 'vaultpress_connection',
122
- 'vaultpress_hostname',
123
- 'vaultpress_key',
124
- 'vaultpress_secret',
125
- 'vaultpress_service_ips',
126
- 'vaultpress_timeout',
127
- 'vp_allow_remote_execution',
128
- 'vp_debug_request_signing',
129
- 'vp_disable_firewall',
130
- );
131
-
132
- foreach ( $old_options as $option )
133
- delete_option( $option );
134
-
135
- $this->options['db_version'] = $this->db_version;
136
- $this->update_options();
137
- }
138
-
139
- if ( $current_db_version < 2 ) {
140
- $this->delete_option( 'timeout' );
141
- $this->delete_option( 'disable_firewall' );
142
- $this->update_option( 'db_version', $this->db_version );
143
- $this->clear_connection();
144
- }
145
-
146
- if ( $current_db_version < 3 ) {
147
- $this->update_firewall();
148
- $this->update_option( 'db_version', $this->db_version );
149
- $this->clear_connection();
150
- }
151
-
152
- if ( $current_db_version < 4 ) {
153
- $this->update_firewall();
154
- $this->update_option( 'db_version', $this->db_version );
155
- $this->clear_connection();
156
- }
157
- }
158
-
159
- function get_option( $key ) {
160
- if ( 'hostname' == $key ) {
161
- if ( defined( 'VAULTPRESS_HOSTNAME' ) )
162
- return VAULTPRESS_HOSTNAME;
163
- else
164
- return 'vaultpress.com';
165
- }
166
-
167
- if ( 'timeout' == $key ) {
168
- if ( defined( 'VAULTPRESS_TIMEOUT' ) )
169
- return VAULTPRESS_TIMEOUT;
170
- else
171
- return 60;
172
- }
173
-
174
- if ( 'disable_firewall' == $key ) {
175
- if ( defined( 'VAULTPRESS_DISABLE_FIREWALL' ) )
176
- return VAULTPRESS_DISABLE_FIREWALL;
177
- else
178
- return false;
179
- }
180
-
181
- if ( ( 'key' == $key || 'secret' == $key ) && empty( $this->options[$key] ) ) {
182
- return '';
183
- }
184
-
185
- // allow_forwarded_for can be overrided by config, or stored in or out of the vp option
186
- if ( 'allow_forwarded_for' === $key ) {
187
- if ( defined( 'ALLOW_FORWARDED_FOR' ) ) {
188
- return ALLOW_FORWARDED_FOR;
189
- }
190
-
191
- $standalone_option = get_option( 'vaultpress_allow_forwarded_for' );
192
- if ( ! empty( $standalone_option ) ) {
193
- return $standalone_option;
194
- }
195
- }
196
-
197
- if ( isset( $this->options[$key] ) )
198
- return $this->options[$key];
199
-
200
- return false;
201
- }
202
-
203
- function update_option( $key, $value ) {
204
- if ( 'allow_forwarded_for' === $key ) {
205
- update_option( 'vaultpress_allow_forwarded_for', $value );
206
-
207
- if ( isset( $this->options[ $key ] ) ) {
208
- unset( $this->options[ $key ] );
209
- $this->update_options();
210
- }
211
- return;
212
- }
213
-
214
- $this->options[$key] = $value;
215
- $this->update_options();
216
- }
217
-
218
- function delete_option( $key ) {
219
- if ( 'allow_forwarded_for' === $key ) {
220
- delete_option( 'vaultpress_allow_forwarded_for' );
221
- }
222
-
223
- unset( $this->options[$key] );
224
- $this->update_options();
225
- }
226
-
227
- function update_options() {
228
- // Avoid overwriting the VaultPress option if current blog_id has changed since reading it
229
- if ( get_current_blog_id() !== $this->options_blog_id ) {
230
- return;
231
- }
232
-
233
- update_option( $this->option_name, $this->options );
234
- }
235
-
236
- function admin_init() {
237
- if ( !current_user_can( 'manage_options' ) )
238
- return;
239
-
240
- load_plugin_textdomain( 'vaultpress', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
241
- }
242
-
243
- function admin_head() {
244
- if ( !current_user_can( 'manage_options' ) )
245
- return;
246
-
247
- if ( $activated = $this->get_option( 'activated' ) ) {
248
- if ( 'network' == $activated ) {
249
- add_action( 'network_admin_notices', array( $this, 'activated_notice' ) );
250
- } else {
251
- foreach ( array( 'user_admin_notices', 'admin_notices' ) as $filter )
252
- add_action( $filter, array( $this, 'activated_notice' ) );
253
- }
254
- }
255
-
256
- // ask the user to connect their site w/ VP
257
- if ( !$this->is_registered() ) {
258
- foreach ( array( 'user_admin_notices', 'admin_notices' ) as $filter )
259
- add_action( $filter, array( $this, 'connect_notice' ) );
260
-
261
- // if we have an error make sure to let the user know about it
262
- } else {
263
- $error_code = $this->get_option( 'connection_error_code' );
264
- if ( !empty( $error_code ) ) {
265
- foreach ( array( 'user_admin_notices', 'admin_notices' ) as $filter )
266
- add_action( $filter, array( $this, 'error_notice' ) );
267
- }
268
- }
269
- }
270
-
271
- function admin_menu() {
272
- // if Jetpack is loaded then we need to wait for that menu to be added
273
- if ( class_exists( 'Jetpack' ) )
274
- add_action( 'jetpack_admin_menu', array( $this, 'load_menu' ) );
275
- else
276
- $this->load_menu();
277
- }
278
-
279
- function load_menu() {
280
- if ( class_exists( 'Jetpack' ) ) {
281
- $hook = add_submenu_page( 'jetpack', 'VaultPress', 'VaultPress', 'manage_options', 'vaultpress', array( $this, 'ui' ) );
282
- } else {
283
- $hook = add_menu_page( 'VaultPress', 'VaultPress', 'manage_options', 'vaultpress', array( $this, 'ui' ), 'div' );
284
- }
285
-
286
- add_action( "load-$hook", array( $this, 'ui_load' ) );
287
- add_action( 'admin_print_styles', array( $this, 'styles' ) );
288
- }
289
-
290
- function styles() {
291
- if ( !current_user_can( 'manage_options' ) || !is_admin() )
292
- return;
293
-
294
- wp_enqueue_style( 'vaultpress-nav', plugins_url( '/nav-styles.css', __FILE__ ), false, date( 'Ymd' ) );
295
-
296
- if ( isset( $_GET['page'] ) && 'vaultpress' == $_GET['page'] )
297
- wp_enqueue_style( 'vaultpress', plugins_url( '/styles.css', __FILE__ ), false, date( 'Ymd' ) );
298
- }
299
-
300
- // display a security threat notice if one exists
301
- function toolbar( $wp_admin_bar ) {
302
- global $wp_version;
303
-
304
- // these new toolbar functions were introduced in 3.3
305
- // http://codex.wordpress.org/Function_Reference/add_node
306
- if ( version_compare( $wp_version, '3.3', '<') )
307
- return;
308
-
309
- if ( !current_user_can( 'manage_options' ) )
310
- return;
311
-
312
- $messages = $this->get_messages();
313
- if ( !empty( $messages['security_notice_count'] ) ) {
314
- $count = (int)$messages['security_notice_count'];
315
- if ( $count > 0 ) {
316
- $count = number_format( $count, 0 );
317
- $wp_admin_bar->add_node( array(
318
- 'id' => 'vp-notice',
319
- 'title' => '<span class="ab-icon"></span>' .
320
- sprintf( _n( '%s Security Threat', '%s Security Threats', $count , 'vaultpress'), $count ),
321
- 'parent' => 'top-secondary',
322
- 'href' => sprintf( 'https://dashboard.vaultpress.com/%d/security/', $messages['site_id'] ),
323
- 'meta' => array(
324
- 'title' => __( 'Visit VaultPress Security' , 'vaultpress'),
325
- 'onclick' => 'window.open( this.href ); return false;',
326
- 'class' => 'error'
327
- ),
328
- ) );
329
- }
330
- }
331
- }
332
-
333
- // get any messages from the VP servers
334
- function get_messages( $force_reload = false ) {
335
- $last_contact = $this->get_option( 'messages_last_contact' );
336
-
337
- // only run the messages check every 30 minutes
338
- if ( ( time() - (int)$last_contact ) > 1800 || $force_reload ) {
339
- $messages = base64_decode( $this->contact_service( 'messages', array() ) );
340
- $messages = unserialize( $messages );
341
- $this->update_option( 'messages_last_contact', time() );
342
- $this->update_option( 'messages', $messages );
343
- } else {
344
- $messages = $this->get_option( 'messages' );
345
- }
346
-
347
- return $messages;
348
- }
349
-
350
- function server_url() {
351
- if ( !isset( $this->_server_url ) ) {
352
- $scheme = is_ssl() ? 'https' : 'http';
353
- $this->_server_url = sprintf( '%s://%s/', $scheme, $this->get_option( 'hostname' ) );
354
- }
355
-
356
- return $this->_server_url;
357
- }
358
-
359
- // show message if plugin is activated but not connected to VaultPress
360
- function connect_notice() {
361
- if ( isset( $_GET['page'] ) && 'vaultpress' == $_GET['page'] )
362
- return;
363
-
364
- $message = sprintf(
365
- __( 'You must enter your registration key before VaultPress can back up and secure your site. <a href="%1$s">Register&nbsp;VaultPress</a>', 'vaultpress' ),
366
- admin_url( 'admin.php?page=vaultpress' )
367
  );
368
- $this->ui_message( $message, 'notice', __( 'VaultPress needs your attention!', 'vaultpress' ) );
369
- }
370
-
371
- // show message after activation
372
- function activated_notice() {
373
- if ( 'network' == $this->get_option( 'activated' ) ) {
374
- $message = sprintf(
375
- __( 'Each site will need to be registered with VaultPress separately. You can purchase new keys from your <a href="%1$s">VaultPress&nbsp;Dashboard</a>.', 'vaultpress' ),
376
- 'https://dashboard.vaultpress.com/'
377
- );
378
- $this->ui_message( $message, 'activated', __( 'VaultPress has been activated across your network!', 'vaultpress' ) );
379
-
380
- // key and secret already exist in db
381
- } elseif ( $this->is_registered() ) {
382
- if ( $this->check_connection() ) {
383
- }
384
- }
385
-
386
- $this->delete_option( 'activated' );
387
- }
388
-
389
- function error_notice() {
390
- $error_message = $this->get_option( 'connection_error_message' );
391
-
392
- // link to the VaultPress page if we're not already there
393
- if ( !isset( $_GET['page'] ) || 'vaultpress' != $_GET['page'] )
394
- $error_message .= ' ' . sprintf( '<a href="%s">%s</a>', admin_url( 'admin.php?page=vaultpress' ), __( 'Visit&nbsp;the&nbsp;VaultPress&nbsp;page' , 'vaultpress') );
395
-
396
- $screen = get_current_screen();
397
- if ( !in_array( $screen->id, array( 'about', 'about-user', 'about-network' ) ) && !empty( $error_message ) )
398
- $this->ui_message( $error_message, 'error' );
399
- }
400
-
401
- function ui() {
402
- if ( $this->is_localhost() ) {
403
- $this->update_option( 'connection', time() );
404
- $this->update_option( 'connection_error_code', 'error_localhost' );
405
- $this->update_option( 'connection_error_message', 'Hostnames such as localhost or 127.0.0.1 can not be reached by vaultpress.com and will not work with the service. Sites must be publicly accessible in order to work with VaultPress.' );
406
- $this->error_notice();
407
- return;
408
- }
409
-
410
- if ( !empty( $_GET['error'] ) ) {
411
- $this->error_notice();
412
- $this->clear_connection();
413
- }
414
-
415
- if ( !$this->is_registered() ) {
416
- $this->ui_register();
417
- return;
418
- }
419
-
420
- $status = $this->contact_service( 'status' );
421
- if ( !$status ) {
422
- $error_code = $this->get_option( 'connection_error_code' );
423
- if ( 0 == $error_code )
424
- $this->ui_fatal_error();
425
- else
426
- $this->ui_register();
427
- return;
428
- }
429
-
430
- $ticker = $this->contact_service( 'ticker' );
431
- if ( is_array( $ticker ) && isset( $ticker['faultCode'] ) ) {
432
- $this->error_notice();
433
- $this->ui_register();
434
- return;
435
- }
436
-
437
- $this->ui_main();
438
  }
439
 
440
- function ui_load() {
441
- if ( !current_user_can( 'manage_options' ) )
442
- return;
443
-
444
- if ( isset( $_POST['action'] ) && 'delete-vp-settings' == $_POST['action'] ) {
445
- check_admin_referer( 'delete_vp_settings' );
446
-
447
- $ai_ping_queue_size = $this->ai_ping_queue_size();
448
- if ( ! empty( $ai_ping_queue_size->option_count ) && $ai_ping_queue_size->option_count > 1 ) {
449
- $this->ai_ping_queue_delete();
450
- }
451
-
452
- delete_option( $this->option_name );
453
- delete_option( 'vaultpress_service_ips_external_cidr' );
454
- delete_option( '_vp_signatures' );
455
- delete_option( '_vp_config_option_name_ignore' );
456
- delete_option( '_vp_config_post_meta_name_ignore' );
457
- delete_option( '_vp_config_should_ignore_files' );
458
- delete_option( '_vp_current_scan' );
459
- delete_option( 'vaultpress_auto_register' );
460
-
461
- wp_redirect( admin_url( 'admin.php?page=vaultpress&delete-vp-settings=1' ) );
462
- exit();
463
- }
464
-
465
- // run code that might be updating the registration key
466
- if ( isset( $_POST['action'] ) && 'register' == $_POST['action'] ) {
467
- check_admin_referer( 'vaultpress_register' );
468
-
469
- // reset the connection info so messages don't cross
470
- $this->clear_connection();
471
-
472
- // if registering via Jetpack, get a key...
473
- if ( isset( $_POST['key_source'] ) && 'jetpack' === $_POST['key_source'] ) {
474
- $registration_key = $this->get_key_via_jetpack();
475
- if ( is_wp_error( $registration_key ) ) {
476
- $this->update_option( 'connection_error_code', -2 );
477
- $this->update_option(
478
- 'connection_error_message',
479
- sprintf( __('<strong>Failed to register VaultPress via Jetpack</strong>: %s. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ),
480
- esc_html( $registration_key->get_error_message() ), 'http://vaultpress.com/contact/' )
481
- );
482
- wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
483
- exit();
484
- }
485
- } else {
486
- $registration_key = trim( $_POST[ 'registration_key' ] );
487
- }
488
 
489
- if ( empty( $registration_key ) ) {
490
- $this->update_option( 'connection_error_code', 1 );
491
- $this->update_option(
492
- 'connection_error_message',
493
- sprintf(
494
- __( '<strong>That\'s not a valid registration key.</strong> Head over to the <a href="%1$s" title="Sign in to your VaultPress Dashboard">VaultPress&nbsp;Dashboard</a> to find your key.', 'vaultpress' ),
495
- 'https://dashboard.vaultpress.com/'
496
- )
 
497
  );
498
- wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
499
- exit();
500
- }
501
-
502
- // try to register the plugin
503
- $nonce = wp_create_nonce( 'vp_register_' . $registration_key );
504
- $args = array( 'registration_key' => $registration_key, 'nonce' => $nonce );
505
- $response = $this->contact_service( 'register', $args );
506
-
507
- // we received an error from the VaultPress servers
508
- if ( !empty( $response['faultCode'] ) ) {
509
- $this->update_option( 'connection_error_code', $response['faultCode'] );
510
- $this->update_option( 'connection_error_message', $response['faultString'] );
511
- wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
512
- exit();
513
- }
514
-
515
- // make sure the returned data looks valid
516
- if ( empty( $response['key'] ) || empty( $response['secret'] ) || empty( $response['nonce'] ) || $nonce != $response['nonce'] ) {
517
- $this->update_option( 'connection_error_code', 1 );
518
- $this->update_option( 'connection_error_message', sprintf( __( 'There was a problem trying to register your subscription. Please try again. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
519
- wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
520
- exit();
521
- }
522
-
523
- // need to update these values in the db so the servers can try connecting to the plugin
524
- $this->update_option( 'key', $response['key'] );
525
- $this->update_option( 'secret', $response['secret'] );
526
- if ( $this->check_connection( true ) ) {
527
- wp_redirect( admin_url( 'admin.php?page=vaultpress' ) );
528
- exit();
529
- }
530
-
531
- // reset the key and secret
532
- $this->update_option( 'key', '' );
533
- $this->update_option( 'secret', '' );
534
- wp_redirect( admin_url( 'admin.php?page=vaultpress&error=true' ) );
535
- exit();
536
- }
537
- }
538
-
539
- function ui_register() {
540
- $jetpack_email = $this->get_jetpack_email();
541
- $jetpack_available = ! empty( $jetpack_email ) && ! is_wp_error( $jetpack_email );
542
-
543
- ?>
544
- <div id="vp-wrap" class="wrap">
545
- <div id="vp-head">
546
- <h2>VaultPress <a href="https://dashboard.vaultpress.com/" class="button-secondary" target="_blank"><?php _e( 'Visit Dashboard', 'vaultpress' ); ?></a></h2>
547
- </div>
548
-
549
- <div id="vp_registration" <?php if ( $jetpack_available ) { echo 'class="jetpack-available"'; } ?>>
550
-
551
- <div class="grid">
552
- <div class="vp_card-dark half">
553
- <h2><?php _e( 'The VaultPress plugin <strong>requires a subscription</strong>.', 'vaultpress' ); ?></h2>
554
- <p class="vp_card-description"><?php _e( 'Get realtime backups, automated security scanning, and support from WordPress&nbsp;experts.', 'vaultpress' ); ?></p>
555
- <a class="vp_button-mega" href="https://vaultpress.com/plugin/?utm_source=plugin-unregistered&amp;utm_medium=view-plans-and-pricing&amp;utm_campaign=1.0-plugin"><?php _e( 'View plans and pricing&nbsp;&raquo;', 'vaultpress' ); ?></a>
556
- </div>
557
-
558
- <div class="vp_card half">
559
- <h2><?php _e( 'Already have a VaultPress&nbsp;account?', 'vaultpress' ); ?></h2>
560
- <p class="vp_card-description"><?php _e( 'Paste your registration key&nbsp;below:', 'vaultpress' ); ?></p>
561
- <form method="post" action="">
562
- <fieldset>
563
- <textarea class="vp_input-register" placeholder="<?php echo esc_attr( __( 'Enter your key here...', 'vaultpress' ) ); ?>" name="registration_key"></textarea>
564
- <button class="vp_button-secondary"><?php _e( 'Register ', 'vaultpress' ); ?></button>
565
- <input type="hidden" name="action" value="register" />
566
- <?php wp_nonce_field( 'vaultpress_register' ); ?>
567
- </fieldset>
568
- </form>
569
  </div>
570
- </div><!-- .card-grid -->
571
- </div><!-- #vp_registration -->
572
-
573
- <?php $this->ui_delete_vp_settings_button(); ?>
574
- </div><!-- #vp-head -->
575
- <?php
576
- }
577
-
578
- function ui_main() {
579
- ?>
580
- <div id="vp-wrap" class="vp-wrap">
581
  <?php
582
- $response = base64_decode( $this->contact_service( 'plugin_ui' ) );
583
- echo $response;
584
- ?>
585
-
586
- <?php $this->ui_delete_vp_settings_button(); ?>
587
- </div>
588
- <?php
589
  }
590
 
591
- function ui_fatal_error() {
592
- ?>
593
- <div id="vp-wrap" class="vp-wrap">
594
- <h2>VaultPress</h2>
595
-
596
- <p><?php printf( __( 'Yikes! We&rsquo;ve run into a serious issue and can&rsquo;t connect to %1$s.', 'vaultpress' ), esc_html( $this->get_option( 'hostname' ) ) ); ?></p>
597
- <p><?php printf( __( 'Please make sure that your website is accessible via the Internet. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ); ?></p>
598
- </div>
599
- <?php
600
- }
601
-
602
- function ui_message( $message, $type = 'notice', $heading = '' ) {
603
- if ( empty( $heading ) ) {
604
- switch ( $type ) {
605
- case 'error':
606
- $heading = __( 'Oops... there seems to be a problem.', 'vaultpress' );
607
- break;
608
-
609
- case 'success':
610
- $heading = __( 'Yay! Things look good.', 'vaultpress' );
611
- break;
612
 
613
- default:
614
- $heading = __( 'VaultPress needs your attention!', 'vaultpress' );
615
- break;
616
- }
617
- }
618
- ?>
619
- <div id="vp-notice" class="vp-notice vp-<?php echo $type; ?> wrap clearfix">
620
- <div class="vp-message">
621
- <h3><?php echo $heading; ?></h3>
622
- <p><?php echo $message; ?></p>
623
- </div>
624
- </div>
625
- <?php
 
 
 
 
 
626
  }
627
-
628
- function ui_delete_vp_settings_button() {
 
 
629
  ?>
630
- <div class="grid" style="margin-top: 10px;">
631
- <div class="vp_card half">
632
  <?php
633
- if ( isset( $_GET['delete-vp-settings'] ) && 1 == (int) $_GET['delete-vp-settings'] ) {
634
- ?>
635
- <p><?php _e( 'All VaultPress settings have been deleted.', 'vaultpress' ); ?></p>
636
- <?php
637
- } else {
638
- ?>
639
- <h2><?php _e( 'Delete VaultPress Settings', 'vaultpress' ); ?></h2>
640
- <p class="vp_card-description"><?php _e( 'Warning: Clicking this button will reset ALL VaultPress options in the database.', 'vaultpress' ); ?></p>
641
- <form method="post" action="">
642
- <button class="vp_button-secondary"><?php _e( 'Delete all VaultPress Settings', 'vaultpress' ); ?></button>
643
- <input type="hidden" name="action" value="delete-vp-settings"/>
644
- <?php wp_nonce_field( 'delete_vp_settings' ); ?>
645
- </form>
646
- <?php
647
- }
648
  ?>
649
- </div>
650
- </div><!-- .card-grid -->
651
  <?php
652
  }
653
-
654
- function get_config( $key ) {
655
- $val = get_option( $key );
656
- if ( $val )
657
- return $val;
658
- switch( $key ) {
659
- case '_vp_config_option_name_ignore':
660
- $val = $this->get_option_name_ignore( true );
661
- update_option( '_vp_config_option_name_ignore', $val );
662
- break;
663
- case '_vp_config_post_meta_name_ignore':
664
- $val = $this->get_post_meta_name_ignore( true );
665
- update_option( '_vp_config_post_meta_name_ignore', $val );
666
- break;
667
- case '_vp_config_should_ignore_files':
668
- $val = $this->get_should_ignore_files( true );
669
- update_option( '_vp_config_should_ignore_files', $val );
670
- break;
671
- }
672
- return $val;
673
- }
674
-
675
- // Option name patterns to ignore
676
- function get_option_name_ignore( $return_defaults = false ) {
677
- $defaults = array(
678
- 'vaultpress',
679
- 'cron',
680
- 'wpsupercache_gc_time',
681
- 'rewrite_rules',
682
- 'akismet_spam_count',
683
- '/_transient_/',
684
- '/^_vp_/',
685
- );
686
- if ( $return_defaults )
687
- return $defaults;
688
- $ignore_names = $this->get_config( '_vp_config_option_name_ignore' );
689
- return array_unique( array_merge( $defaults, $ignore_names ) );
690
- }
691
-
692
- // post meta name patterns to ignore
693
- function get_post_meta_name_ignore( $return_defaults = false ) {
694
- $defaults = array(
695
- 'pvc_views'
696
- );
697
- if ( $return_defaults )
698
- return $defaults;
699
- $ignore_names = $this->get_config( '_vp_config_post_meta_name_ignore' );
700
- return array_unique( array_merge( $defaults, $ignore_names ) );
701
- }
702
-
703
- // file name patterns to ignore
704
- function get_should_ignore_files( $return_defaults = false ) {
705
- $defaults = array();
706
- if ( $return_defaults )
707
- return $defaults;
708
- $ignore_names = (array) $this->get_config( '_vp_config_should_ignore_files' );
709
- return array_unique( array_merge( $defaults, $ignore_names ) );
710
- }
711
-
712
- ###
713
- ### Section: Backup Notification Hooks
714
- ###
715
-
716
- // Handle Handle Notifying VaultPress of Options Activity At this point the options table has already been modified
717
- //
718
- // Note: we handle deleted, instead of delete because VaultPress backs up options by name (which are unique,) that
719
- // means that we do not need to resolve an id like we would for, say, a post.
720
- function option_handler( $option_name ) {
721
- global $wpdb;
722
- // Step 1 -- exclusionary rules, don't send these options to vaultpress, because they
723
- // either change constantly and/or are inconsequential to the blog itself and/or they
724
- // are specific to the VaultPress plugin process and we want to avoid recursion
725
- $should_ping = true;
726
- $ignore_names = $this->get_option_name_ignore();
727
- foreach( (array)$ignore_names as $val ) {
728
- if ( $val{0} == '/' ) {
729
- if ( preg_match( $val, $option_name ) )
730
- $should_ping = false;
731
- } else {
732
- if ( $val == $option_name )
733
- $should_ping = false;
734
- }
735
- if ( !$should_ping )
736
- break;
737
- }
738
- if ( $should_ping )
739
- $this->add_ping( 'db', array( 'option' => $option_name ) );
740
-
741
- // Step 2 -- If WordPress is about to kick off a some "cron" action, we need to
742
- // flush vaultpress, because the "remote" cron threads done via http fetch will
743
- // be happening completely inside the window of this thread. That thread will
744
- // be expecting touched and accounted for tables
745
- if ( $option_name == '_transient_doing_cron' )
746
- $this->do_pings();
747
-
748
- return $option_name;
749
- }
750
-
751
- // Handle Notifying VaultPress of Comment Activity
752
- function comment_action_handler( $comment_id ) {
753
- if ( !is_array( $comment_id ) ) {
754
- if ( wp_get_comment_status( $comment_id ) != 'spam' )
755
- $this->add_ping( 'db', array( 'comment' => $comment_id ) );
756
- } else {
757
- foreach ( $comment_id as $id ) {
758
- if ( wp_get_comment_status( $comment_id ) != 'spam' )
759
- $this->add_ping( 'db', array( 'comment' => $id) );
760
- }
761
- }
762
- }
763
-
764
- // Handle Notifying VaultPress of Theme Switches
765
- function theme_action_handler( $theme ) {
766
- $this->add_ping( 'themes', array( 'theme' => get_option( 'stylesheet' ) ) );
767
- }
768
-
769
- // Handle Notifying VaultPress of Upload Activity
770
- function upload_handler( $file ) {
771
- $this->add_ping( 'uploads', array( 'upload' => str_replace( $this->resolve_upload_path(), '', $file['file'] ) ) );
772
- return $file;
773
- }
774
-
775
- // Handle Notifying VaultPress of Plugin Activation/Deactivation
776
- function plugin_action_handler( $plugin='' ) {
777
- $this->add_ping( 'plugins', array( 'name' => $plugin ) );
778
- }
779
-
780
- // Handle Notifying VaultPress of User Edits
781
- function userid_action_handler( $user_or_id ) {
782
- if ( is_object($user_or_id) )
783
- $userid = intval( $user_or_id->ID );
784
- else
785
- $userid = intval( $user_or_id );
786
- if ( !$userid )
787
- return;
788
- $this->add_ping( 'db', array( 'user' => $userid ) );
789
- }
790
-
791
- // Handle Notifying VaultPress of term changes
792
- function term_handler( $term_id, $tt_id=null ) {
793
- $this->add_ping( 'db', array( 'term' => $term_id ) );
794
- if ( $tt_id )
795
- $this->term_taxonomy_handler( $tt_id );
796
- }
797
-
798
- // Handle Notifying VaultPress of term_taxonomy changes
799
- function term_taxonomy_handler( $tt_id ) {
800
- $this->add_ping( 'db', array( 'term_taxonomy' => $tt_id ) );
801
- }
802
- // add(ed)_term_taxonomy handled via the created_term hook, the term_taxonomy_handler is called by the term_handler
803
-
804
- // Handle Notifying VaultPress of term_taxonomy changes
805
- function term_taxonomies_handler( $tt_ids ) {
806
- foreach( (array)$tt_ids as $tt_id ) {
807
- $this->term_taxonomy_handler( $tt_id );
808
- }
809
- }
810
-
811
- // Handle Notifying VaultPress of term_relationship changes
812
- function term_relationship_handler( $object_id, $term_id ) {
813
- $this->add_ping( 'db', array( 'term_relationship' => array( 'object_id' => $object_id, 'term_taxonomy_id' => $term_id ) ) );
814
- }
815
-
816
- // Handle Notifying VaultPress of term_relationship changes
817
- function term_relationships_handler( $object_id, $term_ids ) {
818
- foreach ( (array)$term_ids as $term_id ) {
819
- $this->term_relationship_handler( $object_id, $term_id );
820
- }
821
- }
822
-
823
- // Handle Notifying VaultPress of term_relationship changes
824
- function set_object_terms_handler( $object_id, $terms, $tt_ids ) {
825
- $this->term_relationships_handler( $object_id, $tt_ids );
826
- }
827
-
828
- // Handle Notifying VaultPress of UserMeta changes
829
- function usermeta_action_handler( $umeta_id, $user_id, $meta_key, $meta_value='' ) {
830
- $this->add_ping( 'db', array( 'usermeta' => $umeta_id ) );
831
- }
832
-
833
- // Handle Notifying VaultPress of Post Changes
834
- function post_action_handler($post_id) {
835
- if ( current_filter() == 'delete_post' )
836
- return $this->add_ping( 'db', array( 'post' => $post_id ), 'delete_post' );
837
- return $this->add_ping( 'db', array( 'post' => $post_id ), 'edit_post' );
838
- }
839
-
840
- // Handle Notifying VaultPress of Link Changes
841
- function link_action_handler( $link_id ) {
842
- $this->add_ping( 'db', array( 'link' => $link_id ) );
843
- }
844
-
845
- // Handle Notifying VaultPress of Commentmeta Changes
846
- function commentmeta_insert_handler( $meta_id, $comment_id=null ) {
847
- if ( empty( $comment_id ) || wp_get_comment_status( $comment_id ) != 'spam' )
848
- $this->add_ping( 'db', array( 'commentmeta' => $meta_id ) );
849
- }
850
-
851
- function commentmeta_modification_handler( $meta_id, $object_id, $meta_key, $meta_value ) {
852
- if ( !is_array( $meta_id ) )
853
- return $this->add_ping( 'db', array( 'commentmeta' => $meta_id ) );
854
- foreach ( $meta_id as $id ) {
855
- $this->add_ping( 'db', array( 'commentmeta' => $id ) );
856
- }
857
- }
858
-
859
- // Handle Notifying VaultPress of PostMeta changes via newfangled metadata functions
860
- function postmeta_insert_handler( $meta_id, $post_id, $meta_key, $meta_value='' ) {
861
- if ( in_array( $meta_key, $this->get_post_meta_name_ignore() ) )
862
- return;
863
-
864
- $this->add_ping( 'db', array( 'postmeta' => $meta_id ) );
865
- }
866
-
867
- function postmeta_modification_handler( $meta_id, $object_id, $meta_key, $meta_value ) {
868
- if ( in_array( $meta_key, $this->get_post_meta_name_ignore() ) )
869
- return;
870
-
871
- if ( !is_array( $meta_id ) )
872
- return $this->add_ping( 'db', array( 'postmeta' => $meta_id ) );
873
- foreach ( $meta_id as $id ) {
874
- $this->add_ping( 'db', array( 'postmeta' => $id ) );
875
- }
876
- }
877
-
878
- // Handle Notifying VaultPress of PostMeta changes via old school cherypicked hooks
879
- function postmeta_action_handler( $meta_id, $post_id = null, $meta_key = null ) {
880
- if ( in_array( $meta_key, $this->get_post_meta_name_ignore() ) )
881
- return;
882
-
883
- if ( !is_array($meta_id) )
884
- return $this->add_ping( 'db', array( 'postmeta' => $meta_id ) );
885
- foreach ( $meta_id as $id )
886
- $this->add_ping( 'db', array( 'postmeta' => $id ) );
887
- }
888
-
889
- // WooCommerce notifications
890
- function woocommerce_tax_rate_handler( $id ) {
891
- $this->generic_change_handler( 'woocommerce_tax_rates', array( 'tax_rate_id' => $id ) );
892
- $this->block_change_handler( 'woocommerce_tax_rate_locations', array( 'tax_rate_id' => $id ) );
893
- }
894
-
895
- function woocommerce_order_item_handler( $id ) { $this->generic_change_handler( 'woocommerce_order_items', array( 'order_item_id' => $id ) ); }
896
- function woocommerce_order_item_meta_handler( $id ) { $this->generic_change_handler( 'woocommerce_order_itemmeta', array( 'meta_id' => $id ) ); }
897
- function woocommerce_attribute_handler( $id ) { $this->generic_change_handler( 'woocommerce_attribute_taxonomies', array( 'attribute_id' => $id ) ); }
898
-
899
- function generic_change_handler( $table, $key ) {
900
- $this->add_ping( 'db', array( $table => $key ) );
901
- }
902
-
903
- function block_change_handler( $table, $query ) {
904
- $this->add_ping( 'db', array( "bulk~{$table}" => $query ) );
905
- }
906
-
907
- function verify_table( $table ) {
908
- global $wpdb;
909
- $status = $wpdb->get_row( $wpdb->prepare( "SHOW TABLE STATUS WHERE Name = %s", $table ) );
910
- if ( !$status || !$status->Update_time || !$status->Comment || $status->Engine != 'MyISAM' )
911
- return true;
912
- if ( preg_match( '/([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2})/', $status->Comment, $m ) )
913
- return ( $m[1] == $status->Update_time );
914
- return false;
915
- }
916
-
917
- // Emulate $wpdb->last_table
918
- function record_table( $table ) {
919
- global $vaultpress_last_table;
920
- $vaultpress_last_table = $table;
921
- return $table;
922
- }
923
-
924
- // Emulate $wpdb->last_table
925
- function get_last_table() {
926
- global $wpdb, $vaultpress_last_table;
927
- if ( is_object( $wpdb ) && isset( $wpdb->last_table ) )
928
- return $wpdb->last_table;
929
- return $vaultpress_last_table;
930
- }
931
-
932
- // Emulate hyperdb::is_write_query()
933
- function is_write_query( $q ) {
934
- $word = strtoupper( substr( trim( $q ), 0, 20 ) );
935
- if ( 0 === strpos( $word, 'SELECT' ) )
936
- return false;
937
- if ( 0 === strpos( $word, 'SHOW' ) )
938
- return false;
939
- if ( 0 === strpos( $word, 'CHECKSUM' ) )
940
- return false;
941
- return true;
942
- }
943
-
944
- // Emulate hyperdb::get_table_from_query()
945
- function get_table_from_query( $q ) {
946
- global $wpdb, $vaultpress_last_table;
947
-
948
- if ( is_object( $wpdb ) && method_exists( $wpdb, "get_table_from_query" ) )
949
- return $wpdb->get_table_from_query( $q );
950
-
951
- // Remove characters that can legally trail the table name
952
- $q = rtrim( $q, ';/-#' );
953
- // allow ( select... ) union [...] style queries. Use the first queries table name.
954
- $q = ltrim( $q, "\t (" );
955
-
956
- // Quickly match most common queries
957
- if ( preg_match( '/^\s*(?:'
958
- . 'SELECT.*?\s+FROM'
959
- . '|INSERT(?:\s+IGNORE)?(?:\s+INTO)?'
960
- . '|REPLACE(?:\s+INTO)?'
961
- . '|UPDATE(?:\s+IGNORE)?'
962
- . '|DELETE(?:\s+IGNORE)?(?:\s+FROM)?'
963
- . ')\s+`?(\w+)`?/is', $q, $maybe) )
964
- return $this->record_table($maybe[1] );
965
-
966
- // Refer to the previous query
967
- if ( preg_match( '/^\s*SELECT.*?\s+FOUND_ROWS\(\)/is', $q ) )
968
- return $this->get_last_table();
969
-
970
- // Big pattern for the rest of the table-related queries in MySQL 5.0
971
- if ( preg_match( '/^\s*(?:'
972
- . '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
973
- . '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?'
974
- . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?'
975
- . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?'
976
- . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:\s+FROM)?'
977
- . '|DESCRIBE|DESC|EXPLAIN|HANDLER'
978
- . '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?'
979
- . '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|OPTIMIZE|REPAIR).*\s+TABLE'
980
- . '|TRUNCATE(?:\s+TABLE)?'
981
- . '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?'
982
- . '|ALTER(?:\s+IGNORE)?\s+TABLE'
983
- . '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?'
984
- . '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON'
985
- . '|DROP\s+INDEX.*\s+ON'
986
- . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE'
987
- . '|(?:GRANT|REVOKE).*ON\s+TABLE'
988
- . '|SHOW\s+(?:.*FROM|.*TABLE)'
989
- . ')\s+`?(\w+)`?/is', $q, $maybe ) )
990
- return $this->record_table( $maybe[1] );
991
-
992
- // All unmatched queries automatically fall to the global master
993
- return $this->record_table( '' );
994
- }
995
-
996
- function table_notify_columns( $table ) {
997
- $want_cols = array(
998
- // data
999
- 'posts' => '`ID`',
1000
- 'users' => '`ID`',
1001
- 'links' => '`link_id`',
1002
- 'options' => '`option_id`,`option_name`',
1003
- 'comments' => '`comment_ID`',
1004
- // metadata
1005
- 'postmeta' => '`meta_id`',
1006
- 'commentmeta' => '`meta_id`',
1007
- 'usermeta' => '`umeta_id`',
1008
- // taxonomy
1009
- 'term_relationships' => '`object_id`,`term_taxonomy_id`',
1010
- 'term_taxonomy' => '`term_taxonomy_id`',
1011
- 'terms' => '`term_id`',
1012
- // plugin special cases
1013
- 'wpo_campaign' => '`id`', // WP-o-Matic
1014
- 'wpo_campaign_category' => '`id`', // WP-o-Matic
1015
- 'wpo_campaign_feed' => '`id`', // WP-o-Matic
1016
- 'wpo_campaign_post' => '`id`', // WP-o-Matic
1017
- 'wpo_campaign_word' => '`id`', // WP-o-Matic
1018
- 'wpo_log' => '`id`', // WP-o-Matic
1019
- );
1020
- if ( isset( $want_cols[$table] ) )
1021
- return $want_cols[$table];
1022
- return '*';
1023
- }
1024
-
1025
- /**
1026
- * Use an option ID to ensure a unique ping ID for the site.
1027
- *
1028
- * @return int|false The new ping number. False, if there was an error.
1029
- */
1030
- function ai_ping_next() {
1031
- global $wpdb;
1032
-
1033
- if ( ! $this->allow_ai_pings() ) {
1034
- return false;
1035
- }
1036
-
1037
- $name = "_vp_ai_ping";
1038
- $wpdb->query( $wpdb->prepare( "DELETE FROM `$wpdb->options` WHERE `option_name` = %s;", $name ) );
1039
- $success = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, '', 'no')", $name ) );
1040
- if ( ! $success ) {
1041
- return false;
1042
- }
1043
- return $wpdb->insert_id;
1044
- }
1045
-
1046
- function ai_ping_insert( $value ) {
1047
- if ( ! $this->allow_ai_pings() ) {
1048
- return false;
1049
- }
1050
-
1051
- $new_id = $this->ai_ping_next();
1052
-
1053
- if ( !$new_id )
1054
- return false;
1055
- add_option( '_vp_ai_ping_' . $new_id, $value, '', 'no' );
1056
- }
1057
-
1058
- function allow_ai_pings() {
1059
- static $allow_ai_pings = null;
1060
-
1061
- if ( null === $allow_ai_pings ) {
1062
- $queue_size = $this->ai_ping_queue_size();
1063
- $size_limit = 50 * 1024 * 1024;
1064
- $allow_ai_pings = ( $queue_size->option_count < 100 && $queue_size->option_size < $size_limit );
1065
- }
1066
-
1067
- return $allow_ai_pings;
1068
- }
1069
-
1070
- function ai_ping_queue_size() {
1071
- global $wpdb;
1072
- return $wpdb->get_row( "SELECT COUNT(`option_id`) `option_count`, SUM(LENGTH(`option_value`)) `option_size` FROM $wpdb->options WHERE `option_name` LIKE '\_vp\_ai\_ping\_%'" );
1073
- }
1074
-
1075
- function ai_ping_get( $num=1, $order='ASC' ) {
1076
- global $wpdb;
1077
- if ( strtolower($order) != 'desc' )
1078
- $order = 'ASC';
1079
- else
1080
- $order = 'DESC';
1081
- return $wpdb->get_results( $wpdb->prepare(
1082
- "SELECT * FROM $wpdb->options WHERE `option_name` LIKE '\_vp\_ai\_ping\_%%' ORDER BY `option_id` $order LIMIT %d",
1083
- min( 10, max( 1, (int)$num ) )
1084
- ) );
1085
- }
1086
-
1087
- function ai_ping_queue_delete() {
1088
- global $wpdb;
1089
-
1090
- return $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE '\_vp\_ai\_ping%'" );
1091
- }
1092
-
1093
- function request_firewall_update( $external_services = false ) {
1094
- $args = array( 'timeout' => $this->get_option( 'timeout' ), 'sslverify' => true );
1095
- $hostname = $this->get_option( 'hostname' );
1096
- $path = $external_services ? 'service-ips-external' : 'service-ips';
1097
-
1098
- $data = false;
1099
- $https_error = null;
1100
- $retry = 2;
1101
- $protocol = 'https';
1102
- do {
1103
- $retry--;
1104
- $args['sslverify'] = 'https' == $protocol ? true : false;
1105
- $r = wp_remote_get( $url=sprintf( "%s://%s/%s?cidr_ranges=1", $protocol, $hostname, $path ), $args );
1106
- if ( 200 == wp_remote_retrieve_response_code( $r ) ) {
1107
- if ( 99 == $this->get_option( 'connection_error_code' ) )
1108
- $this->clear_connection();
1109
- $data = @unserialize( wp_remote_retrieve_body( $r ) );
1110
- break;
1111
- }
1112
- if ( 'https' == $protocol ) {
1113
- $https_error = $r;
1114
- $protocol = 'http';
1115
- }
1116
- usleep( 100 );
1117
- } while( $retry > 0 );
1118
-
1119
- if ( $https_error != null && ! empty( $data ) ) {
1120
- $r_code = wp_remote_retrieve_response_code( $https_error );
1121
- if ( 200 != $r_code ) {
1122
- $error_message = sprintf( 'Unexpected HTTP response code %s', $r_code );
1123
- if ( false === $r_code )
1124
- $error_message = 'Unable to find an HTTP transport that supports SSL verification';
1125
- elseif ( is_wp_error( $https_error ) )
1126
- $error_message = $https_error->get_error_message();
1127
-
1128
- $this->update_option( 'connection', time() );
1129
- $this->update_option( 'connection_error_code', 99 );
1130
- $this->update_option( 'connection_error_message', sprintf( __('Warning: The VaultPress plugin is using an insecure protocol because it cannot verify the identity of the VaultPress server. Please contact your hosting provider, and ask them to check that SSL certificate verification is correctly configured on this server. The request failed with the following error: "%s". If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), esc_html( $error_message ), 'http://vaultpress.com/contact/' ) );
1131
- }
1132
- }
1133
-
1134
- return $data;
1135
- }
1136
-
1137
- function update_firewall() {
1138
- $data = $this->request_firewall_update();
1139
- if ( $data ) {
1140
- $newval = array( 'updated' => time(), 'data' => $data );
1141
- $this->update_option( 'service_ips_cidr', $newval );
1142
- }
1143
-
1144
- $external_data = $this->request_firewall_update( true );
1145
- if ( $external_data ) {
1146
- $external_newval = array( 'updated' => time(), 'data' => $external_data );
1147
-
1148
- delete_option( 'vaultpress_service_ips_external_cidr' );
1149
- add_option( 'vaultpress_service_ips_external_cidr', $external_newval, '', 'no' );
1150
- }
1151
-
1152
- if ( !empty( $data ) && !empty( $external_data ) )
1153
- $data = array_merge( $data, $external_data );
1154
-
1155
- if ( $data ) {
1156
- return $data;
1157
- } else {
1158
- return null;
1159
- }
1160
- }
1161
-
1162
- // Update local cache of VP plan settings, based on a ping or connection test result
1163
- function update_plan_settings( $message ) {
1164
- if ( array_key_exists( 'do_backups', $message ) )
1165
- $this->update_option( 'do_not_backup', ( false === $message['do_backups'] ) || ( '0' === $message['do_backups'] ) );
1166
-
1167
- if ( array_key_exists( 'do_backup_pings', $message ) )
1168
- $this->update_option( 'do_not_send_backup_pings', ( false === $message['do_backup_pings'] ) || ( '0' === $message['do_backup_pings'] ) );
1169
- }
1170
-
1171
- function check_connection( $force_check = false ) {
1172
- $connection = $this->get_option( 'connection' );
1173
-
1174
- if ( !$force_check && !empty( $connection ) ) {
1175
- // already established a connection
1176
- if ( 'ok' == $connection )
1177
- return true;
1178
-
1179
- // only run the connection check every 5 minutes
1180
- if ( ( time() - (int)$connection ) < 300 )
1181
- return false;
1182
- }
1183
-
1184
- // if we're running a connection test we don't want to run it a second time
1185
- $connection_test = $this->get_option( 'connection_test' );
1186
- if ( ! empty( $connection_test ) )
1187
- return true;
1188
-
1189
- // force update firewall settings
1190
- $this->update_firewall();
1191
-
1192
- // Generate a random string for ping-backs to use for identification
1193
- $connection_test_key = wp_generate_password( 32, false );
1194
- $this->update_option( 'connection_test', $connection_test_key );
1195
-
1196
- // initial connection test to server
1197
- $this->delete_option( 'allow_forwarded_for' );
1198
- $host = ( ! empty( $_SERVER['HTTP_HOST'] ) ) ? $_SERVER['HTTP_HOST'] : parse_url( $this->site_url(), PHP_URL_HOST );
1199
- $connect = $this->contact_service( 'test', array( 'host' => $host, 'uri' => $_SERVER['REQUEST_URI'], 'ssl' => is_ssl() ) );
1200
-
1201
- // we can't see the servers at all
1202
- if ( !$connect ) {
1203
- $this->update_option( 'connection', time() );
1204
- $this->update_option( 'connection_error_code', 0 );
1205
- $this->update_option( 'connection_error_message', sprintf( __( 'Cannot connect to the VaultPress servers. Please check that your host allows connecting to external sites and try again. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
1206
-
1207
- $this->delete_option( 'connection_test' );
1208
- return false;
1209
- }
1210
-
1211
- // VaultPress gave us a meaningful error
1212
- if ( !empty( $connect['faultCode'] ) ) {
1213
- $this->update_option( 'connection', time() );
1214
- $this->update_option( 'connection_error_code', $connect['faultCode'] );
1215
- $this->update_option( 'connection_error_message', $connect['faultString'] );
1216
- $this->delete_option( 'connection_test' );
1217
- return false;
1218
- }
1219
-
1220
- $this->update_plan_settings( $connect );
1221
-
1222
- if ( !empty( $connect['signatures'] ) ) {
1223
- delete_option( '_vp_signatures' );
1224
- add_option( '_vp_signatures', maybe_unserialize( $connect['signatures'] ), '', 'no' );
1225
- }
1226
-
1227
- // test connection between the site and the servers
1228
- $connect = (string)$this->contact_service( 'test', array( 'type' => 'connect', 'test_key' => $connection_test_key ) );
1229
- if ( 'ok' != $connect ) {
1230
- if ( 'error' == $connect ) {
1231
- $this->update_option( 'connection_error_code', -1 );
1232
- $this->update_option( 'connection_error_message', sprintf( __( 'The VaultPress servers cannot connect to your site. Please check that your site is visible over the Internet and there are no firewall or load balancer settings on your server that might be blocking the communication. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
1233
- } elseif ( !empty( $connect['faultCode'] ) ) {
1234
- $this->update_option( 'connection_error_code', $connect['faultCode'] );
1235
- $this->update_option( 'connection_error_message', $connect['faultString'] );
1236
- }
1237
-
1238
- $this->update_option( 'connection', time() );
1239
- $this->delete_option( 'connection_test' );
1240
- return false;
1241
- }
1242
-
1243
- // successful connection established
1244
- $this->update_option( 'connection', 'ok' );
1245
- $this->delete_option( 'connection_error_code' );
1246
- $this->delete_option( 'connection_error_message' );
1247
- $this->delete_option( 'connection_test' );
1248
- return true;
1249
- }
1250
-
1251
- function get_login_tokens() {
1252
- // By default the login token is valid for 30 minutes.
1253
- $nonce_life = $this->get_option( 'nonce_life' ) ? $this->get_option( 'nonce_life' ) : 1800;
1254
- $salt = wp_salt( 'nonce' ) . md5( $this->get_option( 'secret' ) );
1255
- $nonce_life /= 2;
1256
-
1257
- return array(
1258
- 'previous' => substr( hash_hmac( 'md5', 'vp-login' . ceil( time() / $nonce_life - 1 ), $salt ), -12, 10 ),
1259
- 'current' => substr( hash_hmac( 'md5', 'vp-login' . ceil( time() / $nonce_life ), $salt ), -12, 10 ),
1260
- );
1261
- }
1262
- function add_js_token() {
1263
- $nonce = $this->get_login_tokens();
1264
- $token = $nonce['current'];
1265
-
1266
- // Uglyfies the JS code before sending it to the browser.
1267
- $whitelist = array( 'charAt', 'all', 'setAttribute', 'document', 'createElement', 'appendChild', 'input', 'hidden', 'type', 'name', 'value', 'getElementById', 'loginform', '_vp' );
1268
- shuffle( $whitelist );
1269
- $whitelist = array_flip( $whitelist );
1270
-
1271
- $set = array(
1272
- 0 => array( '+[]', 'e^e' ),
1273
- 1 => array( '+!![]', '2>>1', "e[{$whitelist['type']}].charCodeAt(3)>>6" ),
1274
- 2 => array( '(+!![])<<1', "e[{$whitelist['_vp']}].replace(/_/,'').length" ),
1275
- 3 => array( "(Math.log(2<<4)+[])[e[{$whitelist['charAt']}]](0)", "e[{$whitelist['_vp']}].length" ),
1276
- 4 => array( '(+!![])<<2', "e[{$whitelist['input']}].length^1", "e[{$whitelist['name']}].length" ),
1277
- 5 => array( '((1<<2)+1)', 'parseInt("f",0x10)/3' ),
1278
- 6 => array( '(7^1)', "e[{$whitelist['hidden']}].length" ),
1279
- 7 => array( '(3<<1)+1', "e[{$whitelist['hidden']}].length^1" ),
1280
- 8 => array( '(0x101>>5)', "e[{$whitelist['document']}].length" ),
1281
- 9 => array( '(0x7^4)*(3+[])', "e[{$whitelist['loginform']}].length", "(1<<e[{$whitelist['_vp']}].length)^1" ),
1282
- 'a' => array( "(![]+\"\")[e[{$whitelist['charAt']}]](1)", "e[{$whitelist['appendChild']}][e[{$whitelist['charAt']}]](0)", "e[{$whitelist['name']}][e[{$whitelist['charAt']}]](1)" ),
1283
- 'b' => array( "([]+{})[e[{$whitelist['charAt']}]](2)", "({}+[])[e[{$whitelist['charAt']}]](2)" ),
1284
- 'c' => array( "([]+{})[e[{$whitelist['charAt']}]](5)", "e[{$whitelist['createElement']}][e[{$whitelist['charAt']}]](0)" ),
1285
- 'd' => array( "([][0]+\"\")[e[{$whitelist['charAt']}]](2)", "([][0]+[])[e[{$whitelist['charAt']}]](2)" ),
1286
- 'e' => array( "(!![]+[])[e[{$whitelist['charAt']}]](3)", "(!![]+\"\")[e[{$whitelist['charAt']}]](3)" ),
1287
- 'f' => array( "(![]+[])[e[{$whitelist['charAt']}]](0)", "([]+![])[e[{$whitelist['charAt']}]](e^e)", "([]+![])[e[{$whitelist['charAt']}]](0)" ),
1288
- );
1289
-
1290
- $js_code = <<<JS
1291
- <script type="text/javascript">
1292
- /* <![CDATA[ */
1293
- (function(){
1294
- var i,e='%s'.split('|'),_=[%s],s=function(a,b,c){a[b]=c};
1295
- if(this[e[{$whitelist['document']}]][e[{$whitelist['all']}]]){
1296
- try {
1297
- i=this[e[{$whitelist['document']}]][e[{$whitelist['createElement']}]]('<'+e[{$whitelist['input']}]+' '+e[{$whitelist['name']}]+'='+(e[{$whitelist['_vp']}]+(!![]))+' />');
1298
- }catch(e){}
1299
- }
1300
- if(!i){
1301
- i=this[e[{$whitelist['document']}]][e[{$whitelist['createElement']}]](e[{$whitelist['input']}]);
1302
- s(i,e[{$whitelist['name']}],e[{$whitelist['_vp']}]+(!![]));
1303
- }
1304
- s(i,e[{$whitelist['type']}],e[{$whitelist['hidden']}]).
1305
- s(i,e[{$whitelist['value']}],(%s+""));
1306
- try {
1307
- var __=this[e[{$whitelist['document']}]][e[{$whitelist['getElementById']}]](e[{$whitelist['loginform']}]);
1308
- __[e[{$whitelist['appendChild']}]](i);
1309
- } catch(e){}
1310
- })();
1311
- /* ]]> */
1312
- </script>
1313
- JS;
1314
- $chars = array();
1315
- for ( $i = 0; $i < strlen( $token ); $i++ ) {
1316
- if ( isset( $set[$token{$i}] ) ) {
1317
- $k = array_rand( $set[$token{$i}], 1 );
1318
- $chars[] = $set[$token{$i}][$k];
1319
- } else {
1320
- $chars[] = $token{$i};
1321
- }
1322
- }
1323
- $random = array_unique( $chars );
1324
- shuffle( $random );
1325
- $random = array_flip( $random );
1326
-
1327
- foreach( $chars as $i => $v )
1328
- $chars[$i] = sprintf( '_[%d]', $random[$v] );
1329
-
1330
- $code = preg_replace(
1331
- "#[\n\r\t]#",
1332
- '',
1333
- sprintf( $js_code,
1334
- join( '|', array_keys( $whitelist ) ),
1335
- join( ',', array_keys( $random ) ),
1336
- join( '+"")+(', $chars )
1337
- )
1338
- );
1339
- echo $code;
1340
- }
1341
-
1342
- function authenticate( $user, $username, $password ) {
1343
- if ( is_wp_error( $user ) )
1344
- return $user;
1345
- if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST || defined( 'APP_REQUEST' ) && APP_REQUEST ) {
1346
- // Try to log in with the username and password.
1347
- }
1348
- $retval = $user;
1349
- if ( empty( $_POST['_vptrue'] ) || !in_array( $_POST['_vptrue'], $this->get_login_tokens(), true ) )
1350
- $retval = new WP_Error( 'invalid_token', __( 'Invalid token. Please try to log in again.' ) );
1351
-
1352
- return $retval;
1353
- }
1354
-
1355
- function parse_request( $wp ) {
1356
- if ( !isset( $_GET['vaultpress'] ) || $_GET['vaultpress'] !== 'true' )
1357
- return $wp;
1358
-
1359
- global $wpdb, $current_blog;
1360
-
1361
- // just in case we have any plugins that decided to spit some data out already...
1362
- @ob_end_clean();
1363
- // Headers to avoid search engines indexing "invalid api call signature" pages.
1364
- if ( !headers_sent() ) {
1365
- header( 'X-Robots-Tag: none' );
1366
- header( 'X-Robots-Tag: unavailable_after: 1 Oct 2012 00:00:00 PST', false );
1367
- }
1368
-
1369
- if ( isset( $_GET['ticker'] ) && function_exists( 'current_user_can' ) && current_user_can( 'manage_options' ) )
1370
- die( (string)$this->contact_service( 'ticker' ) );
1371
-
1372
- $_POST = array_map( 'stripslashes_deep', $_POST );
1373
-
1374
- global $wpdb, $bdb, $bfs;
1375
- define( 'VAULTPRESS_API', true );
1376
-
1377
- if ( !$this->validate_api_signature() ) {
1378
- global $__vp_validate_error;
1379
- die( 'invalid api call signature [' . base64_encode( serialize( $__vp_validate_error ) ) . ']' );
1380
- }
1381
-
1382
- if ( !empty( $_GET['ge'] ) ) {
1383
- // "ge" -- "GET encoding"
1384
- if ( '1' === $_GET['ge'] )
1385
- $_GET['action'] = base64_decode( $_GET['action'] );
1386
- if ( '2' === $_GET['ge'] )
1387
- $_GET['action'] = str_rot13( $_GET['action'] );
1388
- }
1389
-
1390
- if ( !empty( $_GET['pe'] ) ) {
1391
- // "pe" -- POST encoding
1392
- if ( '1' === $_GET['pe'] ) {
1393
- foreach( $_POST as $idx => $val ) {
1394
- if ( $idx === 'signature' )
1395
- continue;
1396
- $_POST[ base64_decode( $idx ) ] = base64_decode( $val );
1397
- unset( $_POST[$idx] );
1398
- }
1399
- }
1400
- if ( '2' === $_GET['pe'] ) {
1401
- foreach( $_POST as $idx => $val ) {
1402
- if ( $idx === 'signature' )
1403
- continue;
1404
- $_POST[ base64_decode( $idx ) ] = str_rot13( $val );
1405
- unset( $_POST[$idx] );
1406
- }
1407
- }
1408
- }
1409
-
1410
- if ( !isset( $bdb ) ) {
1411
- require_once( dirname( __FILE__ ) . '/class.vaultpress-database.php' );
1412
- require_once( dirname( __FILE__ ) . '/class.vaultpress-filesystem.php' );
1413
-
1414
- $bdb = new VaultPress_Database();
1415
- $bfs = new VaultPress_Filesystem();
1416
- }
1417
-
1418
- header( 'Content-Type: text/plain' );
1419
-
1420
- /*
1421
- * general:ping
1422
- *
1423
- * catchup:get
1424
- * catchup:delete
1425
- *
1426
- * db:tables
1427
- * db:explain
1428
- * db:cols
1429
- *
1430
- * plugins|themes|uploads|content|root:active
1431
- * plugins|themes|uploads|content|root:dir
1432
- * plugins|themes|uploads|content|root:ls
1433
- * plugins|themes|uploads|content|root:stat
1434
- * plugins|themes|uploads|content|root:get
1435
- * plugins|themes|uploads|content|root:checksum
1436
- *
1437
- * config:get
1438
- * config:set
1439
- *
1440
- */
1441
- if ( !isset( $_GET['action'] ) )
1442
- die();
1443
-
1444
- switch ( $_GET['action'] ) {
1445
- default:
1446
- die();
1447
- break;
1448
- case 'exec':
1449
- $code = $_POST['code'];
1450
- if ( !$code )
1451
- $this->response( "No Code Found" );
1452
- $syntax_check = @eval( 'return true;' . $code );
1453
- if ( !$syntax_check )
1454
- $this->response( "Code Failed Syntax Check" );
1455
- $this->response( eval( $code . ';' ) );
1456
- die();
1457
- break;
1458
- case 'catchup:get':
1459
- $this->response( $this->ai_ping_get( (int)$_POST['num'], (string)$_POST['order'] ) );
1460
- break;
1461
- case 'catchup:delete':
1462
- if ( isset( $_POST['pings'] ) ) {
1463
- foreach( unserialize( $_POST['pings'] ) as $ping ) {
1464
- if ( 0 === strpos( $ping, '_vp_ai_ping_' ) )
1465
- delete_option( $ping );
1466
- }
1467
- }
1468
- break;
1469
- case 'general:ping':
1470
- global $wp_version, $wp_db_version, $manifest_version;
1471
- @error_reporting(0);
1472
- $http_modules = array();
1473
- $httpd = null;
1474
- if ( function_exists( 'apache_get_modules' ) ) {
1475
- if ( isset( $_POST['apache_modules'] ) && $_POST['apache_modules'] == 1 )
1476
- $http_modules = apache_get_modules();
1477
- else
1478
- $http_modules = null;
1479
- if ( function_exists( 'apache_get_version' ) ) {
1480
- $version_pieces = explode( ' ', apache_get_version() );
1481
- $httpd = array_shift( $version_pieces );
1482
- }
1483
- }
1484
- if ( !$httpd && 0 === stripos( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) ) {
1485
- $software_pieces = explode( ' ', $_SERVER['SERVER_SOFTWARE'] );
1486
- $httpd = array_shift( $software_pieces );
1487
- if ( isset( $_POST['apache_modules'] ) && $_POST['apache_modules'] == 1 )
1488
- $http_modules = 'unknown';
1489
- else
1490
- $http_modules = null;
1491
- }
1492
- if ( !$httpd && defined( 'IIS_SCRIPT' ) && IIS_SCRIPT ) {
1493
- $httpd = 'IIS';
1494
- }
1495
- if ( !$httpd && function_exists( 'nsapi_request_headers' ) ) {
1496
- $httpd = 'NSAPI';
1497
- }
1498
- if ( !$httpd )
1499
- $httpd = 'unknown';
1500
- $mvars = array();
1501
- if ( isset( $_POST['mysql_variables'] ) && $_POST['mysql_variables'] == 1 ) {
1502
- foreach ( $wpdb->get_results( "SHOW VARIABLES" ) as $row )
1503
- $mvars["$row->Variable_name"] = $row->Value;
1504
- }
1505
-
1506
- $this->update_plan_settings( $_POST );
1507
-
1508
- $ms_global_tables = array_merge( $wpdb->global_tables, $wpdb->ms_global_tables );
1509
- $tinfo = array();
1510
- $tprefix = $wpdb->prefix;
1511
- if ( $this->is_multisite() ) {
1512
- $tprefix = $wpdb->get_blog_prefix( $current_blog->blog_id );
1513
- }
1514
- $like_string = str_replace( '_', '\_', $tprefix ) . "%";
1515
- foreach ( $wpdb->get_results( $wpdb->prepare( "SHOW TABLE STATUS LIKE %s", $like_string ) ) as $row ) {
1516
- if ( $this->is_main_site() ) {
1517
- $matches = array();
1518
- preg_match( '/' . $tprefix . '(\d+)_/', $row->Name, $matches );
1519
- if ( isset( $matches[1] ) && (int) $current_blog->blog_id !== (int) $matches[1] )
1520
- continue;
1521
- }
1522
-
1523
- $table = preg_replace( '/^' . preg_quote( $wpdb->prefix ) . '/', '', $row->Name );
1524
-
1525
- if ( !$this->is_main_site() && $tprefix == $wpdb->prefix ) {
1526
- if ( in_array( $table, $ms_global_tables ) )
1527
- continue;
1528
- if ( preg_match( '/' . $tprefix . '(\d+)_/', $row->Name ) )
1529
- continue;
1530
- }
1531
-
1532
- $tinfo[$table] = array();
1533
- foreach ( (array)$row as $i => $v )
1534
- $tinfo[$table][$i] = $v;
1535
- if ( empty( $tinfo[$table] ) )
1536
- unset( $tinfo[$table] );
1537
- }
1538
-
1539
- if ( $this->is_main_site() ) {
1540
- foreach ( (array) $ms_global_tables as $ms_global_table ) {
1541
- $ms_table_status = $wpdb->get_row( $wpdb->prepare( "SHOW TABLE STATUS LIKE %s", $wpdb->base_prefix . $ms_global_table ) );
1542
- if ( !$ms_table_status )
1543
- continue;
1544
- $table = substr( $ms_table_status->Name, strlen( $wpdb->base_prefix ) );
1545
- $tinfo[$table] = array();
1546
- foreach ( (array) $ms_table_status as $i => $v )
1547
- $tinfo[$table][$i] = $v;
1548
- if ( empty( $tinfo[$table] ) )
1549
- unset( $tinfo[$table] );
1550
- }
1551
- }
1552
-
1553
- if ( isset( $_POST['php_ini'] ) && $_POST['php_ini'] == 1 )
1554
- $ini_vals = @ini_get_all();
1555
- else
1556
- $ini_vals = null;
1557
- if ( function_exists( 'sys_getloadavg' ) )
1558
- $loadavg = sys_getloadavg();
1559
- else
1560
- $loadavg = null;
1561
-
1562
- require_once ABSPATH . '/wp-admin/includes/plugin.php';
1563
- if ( function_exists( 'get_plugin_data' ) )
1564
- $vaultpress_response_info = get_plugin_data( __FILE__ );
1565
- else
1566
- $vaultpress_response_info = array( 'Version' => $this->plugin_version );
1567
- $vaultpress_response_info['deferred_pings'] = (int)$this->ai_ping_queue_size()->option_count;
1568
- $vaultpress_response_info['vaultpress_hostname'] = $this->get_option( 'hostname' );
1569
- $vaultpress_response_info['vaultpress_timeout'] = $this->get_option( 'timeout' );
1570
- $vaultpress_response_info['disable_firewall'] = $this->get_option( 'disable_firewall' );
1571
- $vaultpress_response_info['allow_forwarded_for'] = $this->get_option( 'allow_forwarded_for' );
1572
- $vaultpress_response_info['is_writable'] = is_writable( __FILE__ );
1573
-
1574
- $_wptype = 's';
1575
- if ( $this->is_multisite() ) {
1576
- global $wpmu_version;
1577
- if ( isset( $wpmu_version ) )
1578
- $_wptype = 'mu';
1579
- else
1580
- $_wptype = 'ms';
1581
- }
1582
-
1583
- $upload_url = '';
1584
- $upload_dir = wp_upload_dir();
1585
- if ( isset( $upload_dir['baseurl'] ) ) {
1586
- $upload_url = $upload_dir['baseurl'];
1587
- if ( false === strpos( $upload_url, 'http' ) )
1588
- $upload_url = untrailingslashit( site_url() ) . $upload_url;
1589
- }
1590
-
1591
- if ( defined( 'VP_DISABLE_UNAME' ) && VP_DISABLE_UNAME ) {
1592
- $uname_a = '';
1593
- $uname_n = '';
1594
- } else {
1595
- $uname_a = @php_uname( 'a' );
1596
- $uname_n = @php_uname( 'n' );
1597
- }
1598
-
1599
- $this->response( array(
1600
- 'vaultpress' => $vaultpress_response_info,
1601
- 'wordpress' => array(
1602
- 'wp_version' => $wp_version,
1603
- 'wp_db_version' => $wp_db_version,
1604
- 'locale' => get_locale(),
1605
- 'manifest_version' => $manifest_version,
1606
- 'prefix' => $wpdb->prefix,
1607
- 'is_multisite' => $this->is_multisite(),
1608
- 'is_main_site' => $this->is_main_site(),
1609
- 'blog_id' => isset( $current_blog ) ? $current_blog->blog_id : null,
1610
- 'theme' => (string) ( function_exists( 'wp_get_theme' ) ? wp_get_theme() : get_current_theme() ),
1611
- 'plugins' => preg_replace( '#/.*$#', '', get_option( 'active_plugins' ) ),
1612
- 'tables' => $tinfo,
1613
- 'name' => get_bloginfo( 'name' ),
1614
- 'upload_url' => $upload_url,
1615
- 'site_url' => $this->site_url(),
1616
- 'home_url' => ( function_exists( 'home_url' ) ? home_url() : get_option( 'home' ) ),
1617
- 'type' => $_wptype,
1618
- ),
1619
- 'server' => array(
1620
- 'host' => $_SERVER['HTTP_HOST'],
1621
- 'server' => $uname_n,
1622
- 'load' => $loadavg,
1623
- 'info' => $uname_a,
1624
- 'time' => time(),
1625
- 'php' => array( 'version' => phpversion(), 'ini' => $ini_vals, 'directory_separator' => DIRECTORY_SEPARATOR ),
1626
- 'httpd' => array(
1627
- 'type' => $httpd,
1628
- 'modules' => $http_modules,
1629
- ),
1630
- 'mysql' => $mvars,
1631
- ),
1632
- ) );
1633
- break;
1634
- case 'db:prefix':
1635
- $this->response( $wpdb->prefix );
1636
- break;
1637
- case 'db:wpdb':
1638
- if ( !$_POST['query'] )
1639
- die( "naughty naughty" );
1640
- $query = @base64_decode( $_POST['query'] );
1641
- if ( !$query )
1642
- die( "naughty naughty" );
1643
- if ( !$_POST['function'] )
1644
- $function = $function;
1645
- else
1646
- $function = $_POST['function'];
1647
- $this->response( $bdb->wpdb( $query, $function ) );
1648
- break;
1649
- case 'db:diff':
1650
- case 'db:count':
1651
- case 'db:cols':
1652
- if ( isset( $_POST['limit'] ) )
1653
- $limit = $_POST['limit'];
1654
- else
1655
- $limit = null;
1656
-
1657
- if ( isset( $_POST['offset'] ) )
1658
- $offset = $_POST['offset'];
1659
- else
1660
- $offset = null;
1661
-
1662
- if ( isset( $_POST['columns'] ) )
1663
- $columns = $_POST['columns'];
1664
- else
1665
- $columns = null;
1666
-
1667
- if ( isset( $_POST['signatures'] ) )
1668
- $signatures = $_POST['signatures'];
1669
- else
1670
- $signatures = null;
1671
-
1672
- if ( isset( $_POST['where'] ) )
1673
- $where = $_POST['where'];
1674
- else
1675
- $where = null;
1676
-
1677
- if ( isset( $_POST['table'] ) ) {
1678
- $parse_create_table = isset( $_POST['use_new_hash'] ) && $_POST['use_new_hash'] ? true : false;
1679
- $bdb->attach( base64_decode( $_POST['table'] ), $parse_create_table );
1680
- }
1681
-
1682
- $action_pieces = explode( ':', $_GET['action'] );
1683
- switch ( array_pop( $action_pieces ) ) {
1684
- case 'diff':
1685
- if ( !$signatures ) die( 'naughty naughty' );
1686
- // encoded because mod_security sees this as an SQL injection attack
1687
- $this->response( $bdb->diff( unserialize( base64_decode( $signatures ) ) ) );
1688
- case 'count':
1689
- if ( !$columns ) die( 'naughty naughty' );
1690
- $this->response( $bdb->count( unserialize( $columns ) ) );
1691
- case 'cols':
1692
- if ( !$columns ) die( 'naughty naughty' );
1693
- $this->response( $bdb->get_cols( unserialize( $columns ), $limit, $offset, $where ) );
1694
- }
1695
-
1696
- break;
1697
- case 'db:tables':
1698
- case 'db:explain':
1699
- case 'db:show_create':
1700
- if ( isset( $_POST['filter'] ) )
1701
- $filter = $_POST['filter'];
1702
- else
1703
- $filter = null;
1704
-
1705
- if ( isset( $_POST['table'] ) )
1706
- $bdb->attach( base64_decode( $_POST['table'] ) );
1707
-
1708
- $action_pieces = explode( ':', $_GET['action'] );
1709
- switch ( array_pop( $action_pieces ) ) {
1710
- default:
1711
- die( "naughty naughty" );
1712
- case 'tables':
1713
- $this->response( $bdb->get_tables( $filter ) );
1714
- case 'explain':
1715
- $this->response( $bdb->explain() );
1716
- case 'show_create':
1717
- $this->response( $bdb->show_create() );
1718
- }
1719
- break;
1720
- case 'db:restore':
1721
- if ( !empty( $_POST['path'] ) && isset( $_POST['hash'] ) ) {
1722
- $delete = !isset( $_POST['remove'] ) || $_POST['remove'] && 'false' !== $_POST['remove'];
1723
- $this->response( $bdb->restore( $_POST['path'], $_POST['hash'], $delete ) );
1724
- }
1725
- break;
1726
- case 'themes:active':
1727
- $this->response( get_option( 'current_theme' ) );
1728
- case 'plugins:active':
1729
- $this->response( preg_replace( '#/.*$#', '', get_option( 'active_plugins' ) ) );
1730
- break;
1731
- case 'plugins:checksum': case 'uploads:checksum': case 'themes:checksum': case 'content:checksum': case 'root:checksum':
1732
- case 'plugins:ls': case 'uploads:ls': case 'themes:ls': case 'content:ls': case 'root:ls':
1733
- case 'plugins:dir': case 'uploads:dir': case 'themes:dir': case 'content:dir': case 'root:dir':
1734
- case 'plugins:stat': case 'uploads:stat': case 'themes:stat': case 'content:stat': case 'root:stat':
1735
- case 'plugins:get': case 'uploads:get': case 'themes:get': case 'content:get': case 'root:get':
1736
-
1737
- $action_pieces = explode( ':', $_GET['action'] );
1738
- $bfs->want( array_shift( $action_pieces ) );
1739
-
1740
- if ( isset( $_POST['path'] ) )
1741
- $path = $_POST['path'];
1742
- else
1743
- $path = '';
1744
-
1745
- if ( !$bfs->validate( $path ) )
1746
- die( "naughty naughty" );
1747
-
1748
- if ( isset( $_POST['sha1'] ) && $_POST['sha1'] )
1749
- $sha1 = true;
1750
- else
1751
- $sha1 = false;
1752
-
1753
- if ( isset( $_POST['md5'] ) && $_POST['md5'] )
1754
- $md5 = true;
1755
- else
1756
- $md5 = false;
1757
-
1758
- if ( isset( $_POST['limit'] ) && $_POST['limit'] )
1759
- $limit=$_POST['limit'];
1760
- else
1761
- $limit = false;
1762
-
1763
- if ( isset( $_POST['offset'] ) && $_POST['offset'] )
1764
- $offset = $_POST['offset'];
1765
- else
1766
- $offset = false;
1767
-
1768
- if ( isset( $_POST['recursive'] ) )
1769
- $recursive = (bool)$_POST['recursive'];
1770
- else
1771
- $recursive = false;
1772
-
1773
- if ( isset( $_POST['full_list'] ) )
1774
- $full_list = (bool)$_POST['full_list'];
1775
- else
1776
- $full_list = false;
1777
-
1778
- $action_pieces = explode( ':', $_GET['action'] );
1779
- switch ( array_pop( $action_pieces ) ) {
1780
- default:
1781
- die( "naughty naughty" );
1782
- case 'checksum':
1783
- $list = array();
1784
- $this->response( $bfs->dir_checksum( $path, $list, $recursive ) );
1785
- case 'dir':
1786
- $this->response( $bfs->dir_examine( $path, $recursive ) );
1787
- case 'stat':
1788
- $this->response( $bfs->stat( $bfs->dir.$path ) );
1789
- case 'get':
1790
- $bfs->fdump( $bfs->dir.$path );
1791
- case 'ls':
1792
- $this->response( $bfs->ls( $path, $md5, $sha1, $limit, $offset, $full_list ) );
1793
- }
1794
- break;
1795
- case 'config:get':
1796
- if ( !isset( $_POST['key'] ) || !$_POST['key'] )
1797
- $this->response( false );
1798
- $key = '_vp_config_' . base64_decode( $_POST['key'] );
1799
- $this->response( base64_encode( maybe_serialize( $this->get_config( $key ) ) ) );
1800
- break;
1801
- case 'config:set':
1802
- if ( !isset( $_POST['key'] ) || !$_POST['key'] ) {
1803
- $this->response( false );
1804
- break;
1805
- }
1806
- $key = '_vp_config_' . base64_decode( $_POST['key'] );
1807
- if ( !isset( $_POST['val'] ) || !$_POST['val'] ) {
1808
- if ( !isset($_POST['delete']) || !$_POST['delete'] ) {
1809
- $this->response( false );
1810
- } else {
1811
- $this->response( delete_option( $key ) );
1812
- }
1813
- break;
1814
- }
1815
- $val = maybe_unserialize( base64_decode( $_POST['val'] ) );
1816
- $this->response( update_option( $key, $val ) );
1817
- break;
1818
- }
1819
- die();
1820
- }
1821
-
1822
- function _fix_ixr_null_to_string( &$args ) {
1823
- if ( is_array( $args ) )
1824
- foreach ( $args as $k => $v )
1825
- $args[$k] = $this->_fix_ixr_null_to_string( $v );
1826
- else if ( is_object( $args ) )
1827
- foreach ( get_object_vars( $args ) as $k => $v )
1828
- $args->$k = $this->_fix_ixr_null_to_string( $v );
1829
- else
1830
- return null == $args ? '' : $args;
1831
- return $args;
1832
- }
1833
-
1834
- function is_localhost() {
1835
- $site_url = $this->site_url();
1836
- if ( empty( $site_url ) )
1837
- return false;
1838
- $parts = parse_url( $site_url );
1839
- if ( !empty( $parts['host'] ) && in_array( $parts['host'], array( 'localhost', '127.0.0.1' ) ) )
1840
- return true;
1841
- return false;
1842
- }
1843
-
1844
- function contact_service( $action, $args = array() ) {
1845
- if ( 'test' != $action && 'register' != $action && !$this->check_connection() )
1846
- return false;
1847
-
1848
- global $current_user;
1849
- if ( !isset( $args['args'] ) )
1850
- $args['args'] = '';
1851
- $old_timeout = ini_get( 'default_socket_timeout' );
1852
- $timeout = $this->get_option( 'timeout' );
1853
- if ( function_exists( 'ini_set' ) )
1854
- ini_set( 'default_socket_timeout', $timeout );
1855
- $hostname = $this->get_option( 'hostname' );
1856
-
1857
- if ( !class_exists( 'VaultPress_IXR_SSL_Client' ) )
1858
- require_once( dirname( __FILE__ ) . '/class.vaultpress-ixr-ssl-client.php' );
1859
- $useragent = 'VaultPress/' . $this->plugin_version . '; ' . $this->site_url();
1860
- $client = new VaultPress_IXR_SSL_Client( $hostname, '/xmlrpc.php', 80, $timeout, $useragent );
1861
-
1862
- if ( 'vaultpress.com' == $hostname )
1863
- $client->ssl();
1864
-
1865
- // Begin audit trail breadcrumbs
1866
- if ( isset( $current_user ) && is_object( $current_user ) && isset( $current_user->ID ) ) {
1867
- $args['cause_user_id'] = intval( $current_user->ID );
1868
- $args['cause_user_login'] = (string)$current_user->user_login;
1869
- } else {
1870
- $args['cause_user_id'] = -1;
1871
- $args['cause_user_login'] = '';
1872
- }
1873
- $args['cause_ip'] = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null ;
1874
- $args['cause_uri'] = isset( $_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : null;
1875
- $args['cause_method'] = isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : null;
1876
- // End audit trail breadcrumbs
1877
-
1878
- $args['version'] = $this->plugin_version;
1879
- $args['locale'] = get_locale();
1880
- $args['site_url'] = $this->site_url();
1881
-
1882
- $salt = md5( time() . serialize( $_SERVER ) );
1883
- $args['key'] = $this->get_option( 'key' );
1884
- $this->_fix_ixr_null_to_string( $args );
1885
- $args['signature'] = $this->sign_string( serialize( $args ), $this->get_option( 'secret' ), $salt ).":$salt";
1886
-
1887
- $client->query( 'vaultpress.'.$action, new IXR_Base64( serialize( $args ) ) );
1888
- $rval = $client->message ? $client->getResponse() : '';
1889
- if ( function_exists( 'ini_set' ) )
1890
- ini_set( 'default_socket_timeout', $old_timeout );
1891
-
1892
- // we got an error from the servers
1893
- if ( is_array( $rval ) && isset( $rval['faultCode'] ) ) {
1894
- $this->update_option( 'connection', time() );
1895
- $this->update_option( 'connection_error_code', $rval['faultCode'] );
1896
- $this->update_option( 'connection_error_message', $rval['faultString'] );
1897
- }
1898
-
1899
- return $rval;
1900
- }
1901
-
1902
- function validate_api_signature() {
1903
- global $__vp_validate_error;
1904
- if ( !empty( $_POST['signature'] ) ) {
1905
- if ( is_string( $_POST['signature'] ) ) {
1906
- $sig = $_POST['signature'];
1907
- } else {
1908
- $__vp_validate_error = array( 'error' => 'invalid_signature_format' );
1909
- return false;
1910
- }
1911
- } else {
1912
- $__vp_validate_error = array( 'error' => 'no_signature' );
1913
- return false;
1914
- }
1915
-
1916
- $secret = $this->get_option( 'secret' );
1917
- if ( !$secret ) {
1918
- $__vp_validate_error = array( 'error' => 'missing_secret' );
1919
- return false;
1920
- }
1921
- if ( !$this->get_option( 'disable_firewall' ) ) {
1922
- if ( ! $this->check_firewall() )
1923
- return false;
1924
- }
1925
- $sig = explode( ':', $sig );
1926
- if ( !is_array( $sig ) || count( $sig ) != 2 || !isset( $sig[0] ) || !isset( $sig[1] ) ) {
1927
- $__vp_validate_error = array( 'error' => 'invalid_signature_format' );
1928
- return false;
1929
- }
1930
-
1931
- // Pass 1 -- new method
1932
- $uri = preg_replace( '/^[^?]+\?/', '?', $_SERVER['REQUEST_URI'] );
1933
- $post = $_POST;
1934
- unset( $post['signature'] );
1935
- // Work around for dd-formmailer plugin
1936
- if ( isset( $post['_REPEATED'] ) )
1937
- unset( $post['_REPEATED'] );
1938
- ksort( $post );
1939
- $to_sign = serialize( array( 'uri' => $uri, 'post' => $post ) );
1940
-
1941
- if ( $this->can_use_openssl() ) {
1942
- $sslsig = '';
1943
- if ( isset( $post['sslsig'] ) ) {
1944
- $sslsig = $post['sslsig'];
1945
- unset( $post['sslsig'] );
1946
- }
1947
- if ( 1 === openssl_verify( serialize( array( 'uri' => $uri, 'post' => $post ) ), base64_decode( $sslsig ), $this->get_option( 'public_key' ) ) ) {
1948
- return true;
1949
- } else {
1950
- $__vp_validate_error = array( 'error' => 'invalid_signed_data' );
1951
- return false;
1952
- }
1953
- }
1954
-
1955
- $signature = $this->sign_string( $to_sign, $secret, $sig[1] );
1956
- if ( hash_equals( $sig[0], $signature ) ) {
1957
- return true;
1958
- }
1959
-
1960
- $__vp_validate_error = array( 'error' => 'invalid_signed_data' );
1961
- return false;
1962
- }
1963
-
1964
- function ip_in_cidr( $ip, $cidr ) {
1965
- list ($net, $mask) = explode( '/', $cidr );
1966
- return ( ip2long( $ip ) & ~((1 << (32 - $mask)) - 1) ) == ( ip2long( $net ) & ~((1 << (32 - $mask)) - 1) );
1967
- }
1968
-
1969
- function ip_in_cidrs( $ip, $cidrs ) {
1970
- foreach ( (array)$cidrs as $cidr ) {
1971
- if ( $this->ip_in_cidr( $ip, $cidr ) ) {
1972
- return $cidr;
1973
- }
1974
- }
1975
-
1976
- return false;
1977
- }
1978
-
1979
- function check_firewall() {
1980
- global $__vp_validate_error;
1981
-
1982
- $stored_cidrs = $this->get_option( 'service_ips_cidr' );
1983
- $stored_ext_cidrs = get_option( 'vaultpress_service_ips_external_cidr' );
1984
-
1985
- $one_day_ago = time() - 86400;
1986
- if ( empty( $stored_cidrs ) || empty( $stored_ext_cidrs ) || $stored_cidrs['updated'] < $one_day_ago ) {
1987
- $cidrs = $this->update_firewall();
1988
- }
1989
-
1990
- if ( empty( $cidrs ) ) {
1991
- $cidrs = array_merge( $stored_cidrs['data'], $stored_ext_cidrs['data'] );
1992
- }
1993
-
1994
- if ( empty( $cidrs ) ) {
1995
- // No up-to-date info; fall back on the old methods.
1996
- if ( $this->do_c_block_firewall() ) {
1997
- return true;
1998
- } else {
1999
- $__vp_validate_error = array( 'error' => 'empty_vp_ip_cidr_range' );
2000
- return false;
2001
- }
2002
- }
2003
-
2004
- // Figure out possible remote IPs
2005
- $remote_ips = array();
2006
- if ( !empty( $_SERVER['REMOTE_ADDR'] ) )
2007
- $remote_ips['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
2008
-
2009
- // If this is a pingback during a connection test, search for valid-looking ips among headers
2010
- $connection_test_key = $this->get_option( 'connection_test' );
2011
- $testing_all_headers = ( ! empty( $_POST['test_key'] ) && $_POST['test_key'] === $connection_test_key );
2012
- if ( $testing_all_headers ) {
2013
- $remote_ips = array_filter( $_SERVER, array( $this, 'looks_like_ip_list' ) );
2014
- }
2015
-
2016
- // If there is a pre-configured forwarding IP header, check that.
2017
- $forward_header = $this->get_option( 'allow_forwarded_for' );
2018
- if ( true === $forward_header || 1 == $forward_header ) {
2019
- $forward_header = 'HTTP_X_FORWARDED_FOR';
2020
- }
2021
- if ( ! empty( $forward_header ) && ! empty( $_SERVER[ $forward_header ] ) ) {
2022
- $remote_ips[ $forward_header ] = $_SERVER[ $forward_header ];
2023
- }
2024
-
2025
- if ( empty( $remote_ips ) ) {
2026
- $__vp_validate_error = array( 'error' => 'no_remote_addr', 'detail' => (int) $this->get_option( 'allow_forwarded_for' ) ); // shouldn't happen
2027
- return false;
2028
- }
2029
-
2030
- foreach ( $remote_ips as $header_name => $ip_list ) {
2031
- $ips = explode( ',', $ip_list );
2032
- foreach ( $ips as $ip ) {
2033
- $ip = preg_replace( '#^::(ffff:)?#', '', $ip );
2034
- if ( $cidr = $this->ip_in_cidrs( $ip, $cidrs ) ) {
2035
- // Successful match found. If testing all headers, note the successful header.
2036
- if ( $testing_all_headers && 'REMOTE_ADDR' !== $header_name ) {
2037
- $this->update_option( 'allow_forwarded_for', $header_name );
2038
- }
2039
-
2040
- return true;
2041
- }
2042
- }
2043
- }
2044
-
2045
- $__vp_validate_error = array( 'error' => 'remote_addr_fail', 'detail' => $remote_ips );
2046
- return false;
2047
- }
2048
-
2049
- // Returns true if $value looks like a comma-separated list of IPs
2050
- function looks_like_ip_list( $value ) {
2051
- if ( ! is_string( $value ) ) {
2052
- return false;
2053
- }
2054
-
2055
- $items = explode( ',', $value );
2056
- foreach ( $items as $item ) {
2057
- if ( ip2long( $item ) === false ) {
2058
- return false;
2059
- }
2060
- }
2061
-
2062
- return true;
2063
- }
2064
-
2065
- function do_c_block_firewall() {
2066
- // Perform the firewall check by class-c ip blocks
2067
- $rxs = $this->get_option( 'service_ips' );
2068
- $service_ips_external = get_option( 'vaultpress_service_ips_external' );
2069
-
2070
- if ( !empty( $rxs['data'] ) && !empty( $service_ips_external['data'] ) )
2071
- $rxs = array_merge( $rxs['data'], $service_ips_external['data'] );
2072
- if ( ! $rxs )
2073
- return false;
2074
- return $this->validate_ip_address( $rxs );
2075
- }
2076
-
2077
- function validate_ip_address( $rxs ) {
2078
- global $__vp_validate_error;
2079
- if ( empty( $rxs ) ) {
2080
- $__vp_validate_error = array( 'error' => 'empty_vp_ip_range' );
2081
- return false;
2082
- }
2083
-
2084
- $remote_ips = array();
2085
-
2086
- if ( $this->get_option( 'allow_forwarded_for') && !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
2087
- $remote_ips = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
2088
-
2089
- if ( !empty( $_SERVER['REMOTE_ADDR'] ) )
2090
- $remote_ips[] = $_SERVER['REMOTE_ADDR'];
2091
-
2092
- if ( empty( $remote_ips ) ) {
2093
- $__vp_validate_error = array( 'error' => 'no_remote_addr', 'detail' => (int) $this->get_option( 'allow_forwarded_for' ) ); // shouldn't happen
2094
- return false;
2095
- }
2096
-
2097
- $iprx = '/^([0-9]+\.[0-9]+\.[0-9]+\.)([0-9]+)$/';
2098
-
2099
- foreach ( $remote_ips as $_remote_ip ) {
2100
- $remote_ip = preg_replace( '#^::(ffff:)?#', '', $_remote_ip );
2101
- if ( !preg_match( $iprx, $remote_ip, $r ) ) {
2102
- $__vp_validate_error = array( 'error' => "remote_addr_fail", 'detail' => $_remote_ip );
2103
- return false;
2104
- }
2105
-
2106
- foreach ( (array)$rxs as $begin => $end ) {
2107
- if ( !preg_match( $iprx, $begin, $b ) )
2108
- continue;
2109
- if ( !preg_match( $iprx, $end, $e ) )
2110
- continue;
2111
- if ( $r[1] != $b[1] || $r[1] != $e[1] )
2112
- continue;
2113
- $me = $r[2];
2114
- $b = min( (int)$b[2], (int)$e[2] );
2115
- $e = max( (int)$b[2], (int)$e[2] );
2116
- if ( $me >= $b && $me <= $e ) {
2117
- return true;
2118
- }
2119
- }
2120
- }
2121
- $__vp_validate_error = array( 'error' => 'remote_addr_fail', 'detail' => $remote_ips );
2122
-
2123
- return false;
2124
- }
2125
-
2126
- function sign_string( $string, $secret, $salt ) {
2127
- return hash_hmac( 'sha1', "$string:$salt", $secret );
2128
- }
2129
-
2130
- function can_use_openssl() {
2131
- if ( !function_exists( 'openssl_verify' ) )
2132
- return false;
2133
- $pk = $this->get_option( 'public_key' );
2134
- if ( empty( $pk ) )
2135
- return false;
2136
- if ( 1 !== (int) $this->get_option( 'use_openssl_signing' ) )
2137
- return false;
2138
- return true;
2139
- }
2140
-
2141
- function response( $response, $raw = false ) {
2142
- // "re" -- "Response Encoding"
2143
- if ( !empty( $_GET['re'] ) )
2144
- header( sprintf( 'X-VP-Encoded: X%d', abs( intval( $_GET['re'] ) ) ) );
2145
- if ( $raw ) {
2146
- if ( !isset( $_GET['re'] ) )
2147
- die( $response );
2148
- else if ( '1' === $_GET['re'] )
2149
- die( base64_encode( $response ) );
2150
- else if ( '2' === $_GET['re'] )
2151
- die( str_rot13( $response ) );
2152
- else
2153
- die( $response );
2154
- }
2155
- list( $usec, $sec ) = explode( " ", microtime() );
2156
- $r = new stdClass();
2157
- $r->req_vector = floatval( $_GET['vector'] );
2158
- $r->rsp_vector = ( (float)$usec + (float)$sec );
2159
- if ( function_exists( "getrusage" ) )
2160
- $r->rusage = getrusage();
2161
- else
2162
- $r->rusage = false;
2163
- if ( function_exists( "memory_get_peak_usage" ) )
2164
- $r->peak_memory_usage = memory_get_peak_usage( true );
2165
- else
2166
- $r->peak_memory_usage = false;
2167
- if ( function_exists( "memory_get_usage" ) )
2168
- $r->memory_usage = memory_get_usage( true );
2169
- else
2170
- $r->memory_usage = false;
2171
- $r->response = $response;
2172
- if ( !isset( $_GET['re'] ) )
2173
- die( serialize( $r ) );
2174
- else if ( '1' === $_GET['re'] )
2175
- die( base64_encode( serialize( $r ) ) );
2176
- else if ( '2' === $_GET['re'] )
2177
- die( str_rot13( serialize( $r ) ) );
2178
- else
2179
- die( serialize( $r ) );
2180
- }
2181
-
2182
- function reset_pings() {
2183
- global $vaultpress_pings;
2184
- $vaultpress_pings = array(
2185
- 'version' => 1,
2186
- 'count' => 0,
2187
- 'editedtables' => array(),
2188
- 'plugins' => array(),
2189
- 'themes' => array(),
2190
- 'uploads' => array(),
2191
- 'db' => array(),
2192
- 'debug' => array(),
2193
- 'security' => array(),
2194
- );
2195
- }
2196
-
2197
- function add_ping( $type, $data, $hook=null ) {
2198
- global $vaultpress_pings;
2199
- if ( defined( 'WP_IMPORTING' ) && constant( 'WP_IMPORTING' ) )
2200
- return;
2201
- if ( isset( $_GET ) && isset( $_GET['comment_status'] ) && isset( $_GET['delete_all'] ) && 'spam' == $_GET['comment_status'] )
2202
- return; // Skip pings from mass spam delete.
2203
- if ( !array_key_exists( $type, $vaultpress_pings ) )
2204
- return;
2205
-
2206
- switch( $type ) {
2207
- case 'editedtables';
2208
- $vaultpress_pings[$type] = $data;
2209
- return;
2210
- case 'uploads':
2211
- case 'themes':
2212
- case 'plugins':
2213
- if ( !is_array( $data ) ) {
2214
- $data = array( $data );
2215
- }
2216
- foreach ( $data as $val ) {
2217
- if ( in_array( $data, $vaultpress_pings[$type] ) )
2218
- continue;
2219
- $vaultpress_pings['count']++;
2220
- $vaultpress_pings[$type][]=$val;
2221
- }
2222
- return;
2223
- case 'db':
2224
- $_keys = array_keys( $data );
2225
- $subtype = array_shift( $_keys );
2226
- if ( !isset( $vaultpress_pings[$type][$subtype] ) )
2227
- $vaultpress_pings[$type][$subtype] = array();
2228
- if ( in_array( $data, $vaultpress_pings[$type][$subtype] ) )
2229
- return;
2230
- $vaultpress_pings['count']++;
2231
- $vaultpress_pings[$type][$subtype][] = $data;
2232
- return;
2233
- default:
2234
- if ( in_array( $data, $vaultpress_pings[$type] ) )
2235
- return;
2236
- $vaultpress_pings['count']++;
2237
- $vaultpress_pings[$type][] = $data;
2238
- return;
2239
- }
2240
- }
2241
-
2242
- function do_pings() {
2243
- global $wpdb, $vaultpress_pings, $__vp_recursive_ping_lock;
2244
- if ( defined( 'WP_IMPORTING' ) && constant( 'WP_IMPORTING' ) )
2245
- return;
2246
-
2247
- if ( !isset( $wpdb ) ) {
2248
- $wpdb = new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
2249
- $close_wpdb = true;
2250
- } else {
2251
- $close_wpdb = false;
2252
- }
2253
-
2254
- if ( !$vaultpress_pings['count'] )
2255
- return;
2256
-
2257
- // Short circuit the contact process if we know that we can't contact the service
2258
- if ( isset( $__vp_recursive_ping_lock ) && $__vp_recursive_ping_lock ) {
2259
- $this->ai_ping_insert( serialize( $vaultpress_pings ) );
2260
- if ( $close_wpdb ) {
2261
- $wpdb->__destruct();
2262
- unset( $wpdb );
2263
- }
2264
- $this->reset_pings();
2265
- return;
2266
- }
2267
-
2268
- $ping_attempts = 0;
2269
- do {
2270
- $ping_attempts++;
2271
- $rval = $this->contact_service( 'ping', array( 'args' => $vaultpress_pings ) );
2272
- if ( $rval || $ping_attempts >= 3 )
2273
- break;
2274
- if ( !$rval )
2275
- usleep(500000);
2276
- } while ( true );
2277
- if ( !$rval ) {
2278
- if ( $this->get_option( 'connection_error_code' ) !== -8 ) { // Do not save pings when the subscription is inactive.
2279
- $__vp_recursive_ping_lock = true;
2280
- $this->ai_ping_insert( serialize( $vaultpress_pings ) );
2281
- }
2282
- }
2283
- $this->reset_pings();
2284
- if ( $close_wpdb ) {
2285
- $wpdb->__destruct();
2286
- unset( $wpdb );
2287
- }
2288
- return $rval;
2289
- }
2290
-
2291
- function resolve_content_dir() {
2292
- // Take the easy way out
2293
- if ( defined( 'WP_CONTENT_DIR' ) ) {
2294
- if ( substr( WP_CONTENT_DIR, -1 ) != DIRECTORY_SEPARATOR )
2295
- return WP_CONTENT_DIR . DIRECTORY_SEPARATOR;
2296
- return WP_CONTENT_DIR;
2297
- }
2298
- // Best guess
2299
- if ( defined( 'ABSPATH' ) ) {
2300
- if ( substr( ABSPATH, -1 ) != DIRECTORY_SEPARATOR )
2301
- return ABSPATH . DIRECTORY_SEPARATOR . 'wp-content' . DIRECTORY_SEPARATOR;
2302
- return ABSPATH . 'wp-content' . DIRECTORY_SEPARATOR;
2303
- }
2304
- // Run with a solid assumption: WP_CONTENT_DIR/vaultpress/vaultpress.php
2305
- return dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR;
2306
- }
2307
-
2308
- function resolve_upload_path() {
2309
- $upload_path = false;
2310
- $upload_dir = wp_upload_dir();
2311
-
2312
- if ( isset( $upload_dir['basedir'] ) )
2313
- $upload_path = $upload_dir['basedir'];
2314
-
2315
- // Nothing recorded? use a best guess!
2316
- if ( !$upload_path || $upload_path == realpath( ABSPATH ) )
2317
- return $this->resolve_content_dir() . 'uploads' . DIRECTORY_SEPARATOR;
2318
-
2319
- if ( substr( $upload_path, -1 ) != DIRECTORY_SEPARATOR )
2320
- $upload_path .= DIRECTORY_SEPARATOR;
2321
-
2322
- return $upload_path;
2323
- }
2324
-
2325
- function load_first( $value ) {
2326
- $value = array_unique( $value ); // just in case there are duplicates
2327
- return array_merge(
2328
- preg_grep( '/vaultpress\.php$/', $value ),
2329
- preg_grep( '/vaultpress\.php$/', $value, PREG_GREP_INVERT )
2330
- );
2331
- }
2332
-
2333
- function is_multisite() {
2334
- if ( function_exists( 'is_multisite' ) )
2335
- return is_multisite();
2336
-
2337
- return false;
2338
- }
2339
-
2340
- function is_main_site() {
2341
- if ( !function_exists( 'is_main_site' ) || !$this->is_multisite() )
2342
- return true;
2343
-
2344
- return is_main_site();
2345
- }
2346
-
2347
- function is_registered() {
2348
- $key = $this->get_option( 'key' );
2349
- $secret = $this->get_option( 'secret' );
2350
- return !empty( $key ) && !empty( $secret );
2351
- }
2352
-
2353
- function clear_connection() {
2354
- $this->delete_option( 'connection' );
2355
- $this->delete_option( 'connection_error_code' );
2356
- $this->delete_option( 'connection_error_message' );
2357
- $this->delete_option( 'connection_test' );
2358
- }
2359
-
2360
- function site_url() {
2361
- $site_url = '';
2362
-
2363
- // compatibility for WordPress MU Domain Mapping plugin
2364
- if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING && ! function_exists( 'domain_mapping_siteurl' ) ) {
2365
- if ( !function_exists( 'is_plugin_active' ) )
2366
- require_once ABSPATH . '/wp-admin/includes/plugin.php';
2367
-
2368
- $plugin = 'wordpress-mu-domain-mapping/domain_mapping.php';
2369
- if ( is_plugin_active( $plugin ) )
2370
- include_once( WP_PLUGIN_DIR . '/' . $plugin );
2371
- }
2372
-
2373
- if ( function_exists( 'domain_mapping_siteurl' ) )
2374
- $site_url = domain_mapping_siteurl( false );
2375
-
2376
- if ( empty( $site_url ) )
2377
- $site_url = site_url();
2378
-
2379
- return $site_url;
2380
- }
2381
-
2382
- /**
2383
- * Sync the VaultPress options to WordPress.com if the Jetpack plugin is active.
2384
- */
2385
- function sync_jetpack_options() {
2386
- if ( class_exists( 'Jetpack_Sync' ) && method_exists( 'Jetpack_Sync', 'sync_options' ) && defined( 'JETPACK__VERSION' ) && version_compare( JETPACK__VERSION, '4.1', '<' ) ) {
2387
- Jetpack_Sync::sync_options( __FILE__, $this->auto_register_option, $this->option_name );
2388
- }
2389
- }
2390
-
2391
- /**
2392
- * Add the VaultPress options to the Jetpack options management whitelist.
2393
- * Allows Jetpack to register VaultPress options automatically.
2394
- *
2395
- * @param array $options The list of whitelisted option names.
2396
- *
2397
- * @return array The updated whitelist
2398
- */
2399
- function add_to_jetpack_options_whitelist( $options ) {
2400
- $options[] = $this->option_name;
2401
- $options[] = $this->auto_register_option;
2402
-
2403
- return $options;
2404
- }
2405
-
2406
- /**
2407
- * When the VaultPress auto-register option is updated, run the registration call.
2408
- *
2409
- * This should only be run when the option is updated from the Jetpack/WP.com
2410
- * API call, and only if the new key is different than the old key.
2411
- *
2412
- * @param mixed $old_value The old option value, or the option name (if add_option).
2413
- * @param mixed $value The new option value.
2414
- */
2415
- function updated_auto_register_option( $old_value, $value ) {
2416
- // Not an API call or CLI call
2417
- if ( ! class_exists( 'WPCOM_JSON_API_Update_Option_Endpoint' ) && ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
2418
- return;
2419
- }
2420
-
2421
- remove_action( "update_option_{$this->auto_register_option}", array( $this, 'updated_auto_register_option' ) );
2422
-
2423
- $defaults = array(
2424
- 'key' => false,
2425
- 'action' => 'register', // or `response`
2426
- 'status' => 'working',
2427
- 'error' => false,
2428
- );
2429
-
2430
- // `wp_parse_args` uses arrays, might as well be explicit about it.
2431
- $registration = (array) json_decode( $value );
2432
- $registration = wp_parse_args( $registration, $defaults );
2433
-
2434
- // If we have a working connection, don't update the key.
2435
- if ( $this->check_connection( true ) ) {
2436
- $registration['action'] = 'response';
2437
- $registration['error'] = 'VaultPress is already registered on this site.';
2438
- update_option( $this->auto_register_option, json_encode( $registration ) );
2439
- return;
2440
- }
2441
-
2442
- if ( ! $registration['key'] ) {
2443
- return;
2444
- }
2445
-
2446
- $registration['action'] = 'response';
2447
-
2448
- $response = $this->register( $registration['key'] );
2449
- if ( is_wp_error( $response ) ) {
2450
- $registration['status'] = 'broken';
2451
- $registration['error'] = $response->get_error_message();
2452
- } else if ( $this->get_option( 'connection_error_code' ) ) {
2453
- $registration['status'] = 'broken';
2454
- $registration['error'] = $this->get_option( 'connection_error_message' );
2455
- } else {
2456
- $registration['error'] = false;
2457
- }
2458
-
2459
- update_option( $this->auto_register_option, json_encode( $registration ) );
2460
- }
2461
-
2462
- function add_global_actions_and_filters() {
2463
- add_action( 'init', array( $this, 'sync_jetpack_options' ), 0, 99 );
2464
- add_filter( 'jetpack_options_whitelist', array( $this, 'add_to_jetpack_options_whitelist' ) );
2465
- add_action( "update_option_{$this->auto_register_option}", array( $this, 'updated_auto_register_option' ), 10, 2 );
2466
- add_action( "add_option_{$this->auto_register_option}", array( $this, 'updated_auto_register_option' ), 10, 2 );
2467
- }
2468
-
2469
- function add_admin_actions_and_filters() {
2470
- add_action( 'admin_init', array( $this, 'admin_init' ) );
2471
- add_action( 'admin_menu', array( $this, 'admin_menu' ), 5 ); # Priority 5, so it's called before Jetpack's admin_menu.
2472
- add_action( 'admin_head', array( $this, 'admin_head' ) );
2473
- }
2474
-
2475
- function add_listener_actions_and_filters() {
2476
- add_action( 'admin_bar_menu', array( $this, 'toolbar' ), 999 );
2477
- add_action( 'admin_bar_init', array( $this, 'styles' ) );
2478
-
2479
- // Comments
2480
- add_action( 'delete_comment', array( $this, 'comment_action_handler' ) );
2481
- add_action( 'wp_set_comment_status', array( $this, 'comment_action_handler' ) );
2482
- add_action( 'trashed_comment', array( $this, 'comment_action_handler' ) );
2483
- add_action( 'untrashed_comment', array( $this, 'comment_action_handler' ) );
2484
- add_action( 'wp_insert_comment', array( $this, 'comment_action_handler' ) );
2485
- add_action( 'comment_post', array( $this, 'comment_action_handler' ) );
2486
- add_action( 'edit_comment', array( $this, 'comment_action_handler' ) );
2487
-
2488
- // Commentmeta
2489
- add_action( 'added_comment_meta', array( $this, 'commentmeta_insert_handler' ), 10, 2 );
2490
- add_action( 'updated_comment_meta', array( $this, 'commentmeta_modification_handler' ), 10, 4 );
2491
- add_action( 'deleted_comment_meta', array( $this, 'commentmeta_modification_handler' ), 10, 4 );
2492
-
2493
- // Users
2494
- if ( $this->is_main_site() ) {
2495
- add_action( 'user_register', array( $this, 'userid_action_handler' ) );
2496
- add_action( 'password_reset', array( $this, 'userid_action_handler' ) );
2497
- add_action( 'profile_update', array( $this, 'userid_action_handler' ) );
2498
- add_action( 'user_register', array( $this, 'userid_action_handler' ) );
2499
- add_action( 'deleted_user', array( $this, 'userid_action_handler' ) );
2500
- }
2501
-
2502
- // Usermeta
2503
- if ( $this->is_main_site() ) {
2504
- add_action( 'added_usermeta', array( $this, 'usermeta_action_handler' ), 10, 4 );
2505
- add_action( 'update_usermeta', array( $this, 'usermeta_action_handler' ), 10, 4 );
2506
- add_action( 'delete_usermeta', array( $this, 'usermeta_action_handler' ), 10, 4 );
2507
- }
2508
-
2509
- // Posts
2510
- add_action( 'delete_post', array( $this, 'post_action_handler' ) );
2511
- add_action( 'trash_post', array( $this, 'post_action_handler' ) );
2512
- add_action( 'untrash_post', array( $this, 'post_action_handler' ) );
2513
- add_action( 'edit_post', array( $this, 'post_action_handler' ) );
2514
- add_action( 'save_post', array( $this, 'post_action_handler' ) );
2515
- add_action( 'wp_insert_post', array( $this, 'post_action_handler' ) );
2516
- add_action( 'edit_attachment', array( $this, 'post_action_handler' ) );
2517
- add_action( 'add_attachment', array( $this, 'post_action_handler' ) );
2518
- add_action( 'delete_attachment', array( $this, 'post_action_handler' ) );
2519
- add_action( 'private_to_published', array( $this, 'post_action_handler' ) );
2520
- add_action( 'wp_restore_post_revision', array( $this, 'post_action_handler' ) );
2521
-
2522
- // Postmeta
2523
- add_action( 'added_post_meta', array( $this, 'postmeta_insert_handler' ), 10, 4 );
2524
- add_action( 'update_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2525
- add_action( 'updated_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2526
- add_action( 'delete_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2527
- add_action( 'deleted_post_meta', array( $this, 'postmeta_modification_handler' ), 10, 4 );
2528
- add_action( 'added_postmeta', array( $this, 'postmeta_action_handler' ), 10, 3 );
2529
- add_action( 'update_postmeta', array( $this, 'postmeta_action_handler' ), 10, 3 );
2530
- add_action( 'delete_postmeta', array( $this, 'postmeta_action_handler' ), 10, 3 );
2531
-
2532
- // Links
2533
- add_action( 'edit_link', array( $this, 'link_action_handler' ) );
2534
- add_action( 'add_link', array( $this, 'link_action_handler' ) );
2535
- add_action( 'delete_link', array( $this, 'link_action_handler' ) );
2536
-
2537
- // Taxonomy
2538
- add_action( 'created_term', array( $this, 'term_handler' ), 2 );
2539
- add_action( 'edited_terms', array( $this, 'term_handler' ), 2 );
2540
- add_action( 'delete_term', array( $this, 'term_handler' ), 2 );
2541
- add_action( 'edit_term_taxonomy', array( $this, 'term_taxonomy_handler' ) );
2542
- add_action( 'delete_term_taxonomy', array( $this, 'term_taxonomy_handler' ) );
2543
- add_action( 'edit_term_taxonomies', array( $this, 'term_taxonomies_handler' ) );
2544
- add_action( 'add_term_relationship', array( $this, 'term_relationship_handler' ), 10, 2 );
2545
- add_action( 'delete_term_relationships', array( $this, 'term_relationships_handler' ), 10, 2 );
2546
- add_action( 'set_object_terms', array( $this, 'set_object_terms_handler' ), 10, 3 );
2547
-
2548
- // Files
2549
- if ( $this->is_main_site() ) {
2550
- add_action( 'switch_theme', array( $this, 'theme_action_handler' ) );
2551
- add_action( 'activate_plugin', array( $this, 'plugin_action_handler' ) );
2552
- add_action( 'deactivate_plugin', array( $this, 'plugin_action_handler' ) );
2553
- }
2554
- add_action( 'wp_handle_upload', array( $this, 'upload_handler' ) );
2555
-
2556
- // Options
2557
- add_action( 'deleted_option', array( $this, 'option_handler' ), 1 );
2558
- add_action( 'updated_option', array( $this, 'option_handler' ), 1 );
2559
- add_action( 'added_option', array( $this, 'option_handler' ), 1 );
2560
-
2561
- $this->add_woocommerce_actions();
2562
- $this->add_vp_required_filters();
2563
- }
2564
-
2565
- function add_woocommerce_actions() {
2566
- add_action( 'woocommerce_tax_rate_deleted', array( $this, 'woocommerce_tax_rate_handler' ), 10, 1 );
2567
- add_action( 'woocommerce_tax_rate_updated', array( $this, 'woocommerce_tax_rate_handler' ), 10, 1 );
2568
- add_action( 'woocommerce_tax_rate_added', array( $this, 'woocommerce_tax_rate_handler' ), 10, 1 );
2569
-
2570
- add_action( 'woocommerce_new_order_item', array( $this, 'woocommerce_order_item_handler' ), 10, 1 );
2571
- add_action( 'woocommerce_update_order_item', array( $this, 'woocommerce_order_item_handler' ), 10, 1 );
2572
- add_action( 'woocommerce_delete_order_item', array( $this, 'woocommerce_order_item_handler' ), 10, 1 );
2573
-
2574
- add_action( 'added_order_item_meta', array( $this, 'woocommerce_order_item_meta_handler' ), 10, 1 );
2575
- add_action( 'updated_order_item_meta', array( $this, 'woocommerce_order_item_meta_handler' ), 10, 1 );
2576
- add_action( 'deleted_order_item_meta', array( $this, 'woocommerce_order_item_meta_handler' ), 10, 1 );
2577
-
2578
- add_action( 'woocommerce_attribute_added', array( $this, 'woocommerce_attribute_handler' ), 10, 1 );
2579
- add_action( 'woocommerce_attribute_updated', array( $this, 'woocommerce_attribute_handler' ), 10, 1 );
2580
- add_action( 'woocommerce_attribute_deleted', array( $this, 'woocommerce_attribute_handler' ), 10, 1 );
2581
- }
2582
-
2583
- function add_vp_required_filters() {
2584
- // Log ins
2585
- if ( $this->get_option( 'login_lockdown' ) ) {
2586
- add_action( 'login_form', array( $this, 'add_js_token' ) );
2587
- add_filter( 'authenticate', array( $this, 'authenticate' ), 999 );
2588
- }
2589
-
2590
- // Report back to VaultPress
2591
- add_action( 'shutdown', array( $this, 'do_pings' ) );
2592
-
2593
- // VaultPress likes being first in line
2594
- add_filter( 'pre_update_option_active_plugins', array( $this, 'load_first' ) );
2595
- }
2596
-
2597
- function get_jetpack_email() {
2598
- if ( !class_exists('Jetpack') )
2599
- return false;
2600
-
2601
- Jetpack::load_xml_rpc_client();
2602
- $xml = new Jetpack_IXR_Client( array( 'user_id' => get_current_user_id() ) );
2603
- $xml->query( 'wpcom.getUserEmail' );
2604
- if ( ! $xml->isError() ) {
2605
- return $xml->getResponse();
2606
- }
2607
-
2608
- return new WP_Error( $xml->getErrorCode(), $xml->getErrorMessage() );
2609
- }
2610
-
2611
- function get_key_via_jetpack( $already_purchased = false ) {
2612
- if ( !class_exists('Jetpack') )
2613
- return false;
2614
-
2615
- Jetpack::load_xml_rpc_client();
2616
- $xml = new Jetpack_IXR_Client( array( 'user_id' => Jetpack_Options::get_option( 'master_user' ) ) );
2617
- $xml->query( 'vaultpress.registerSite', $already_purchased );
2618
- if ( ! $xml->isError() ) {
2619
- return $xml->getResponse();
2620
- }
2621
-
2622
- return new WP_Error( $xml->getErrorCode(), $xml->getErrorMessage() );
2623
- }
2624
-
2625
- function register_via_jetpack( $already_purchased = false ) {
2626
- $registration_key = $this->get_key_via_jetpack( $already_purchased );
2627
- if ( is_wp_error( $registration_key ) ) {
2628
- return $registration_key;
2629
- }
2630
-
2631
- return self::register( $registration_key );
2632
- }
2633
  }
2634
 
 
2635
  $vaultpress = VaultPress::init();
2636
 
2637
  if ( isset( $_GET['vaultpress'] ) && $_GET['vaultpress'] ) {
1
  <?php
2
+ /**
3
  * Plugin Name: VaultPress
4
  * Plugin URI: http://vaultpress.com/?utm_source=plugin-uri&amp;utm_medium=plugin-description&amp;utm_campaign=1.0
5
  * Description: Protect your content, themes, plugins, and settings with <strong>realtime backup</strong> and <strong>automated security scanning</strong> from <a href="http://vaultpress.com/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">VaultPress</a>. Activate, enter your registration key, and never worry again. <a href="http://vaultpress.com/help/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">Need some help?</a>
6
+ * Version: 2.0
7
  * Author: Automattic
8
  * Author URI: http://vaultpress.com/?utm_source=author-uri&amp;utm_medium=plugin-description&amp;utm_campaign=1.0
9
  * License: GPL2+
10
  * Text Domain: vaultpress
11
  * Domain Path: /languages/
12
+ *
13
+ * @package VaultPress
14
  */
15
 
16
+ // don't call the file directly.
17
+ defined( 'ABSPATH' ) || die();
18
 
19
+ define( 'VAULTPRESS__MINIMUM_PHP_VERSION', '5.3.2' );
20
+ define( 'VAULTPRESS__VERSION', '2.0' );
21
+ define( 'VAULTPRESS__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
 
 
22
 
23
+ /**
24
+ * First, we check for our supported version of PHP. If it fails,
25
+ * we "pause" VaultPress by ending the loading process and displaying an admin_notice to inform the site owner.
26
+ */
27
+ if ( version_compare( phpversion(), VAULTPRESS__MINIMUM_PHP_VERSION, '<' ) ) {
28
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
29
+ error_log(
30
+ sprintf(
31
+ /* translators: Placeholders are numbers, versions of PHP in use on the site, and required by VaultPress. */
32
+ esc_html__( 'Your version of PHP (%1$s) is lower than the version required by VaultPress (%2$s). Please update PHP to continue enjoying VaultPress.', 'vaultpress' ),
33
+ esc_html( phpversion() ),
34
+ VAULTPRESS__MINIMUM_PHP_VERSION
35
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
 
39
+ /**
40
+ * Outputs an admin notice for folks running an outdated version of PHP.
41
+ *
42
+ * @todo: Remove once WP 5.2 is the minimum version.
43
+ *
44
+ * @since 2.0.0
45
+ */
46
+ function vaultpress_admin_unsupported_php_notice() {
47
+ $update_php_url = ( function_exists( 'wp_get_update_php_url' ) ? wp_get_update_php_url() : 'https://wordpress.org/support/update-php/' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ ?>
50
+ <div class="notice notice-error is-dismissible">
51
+ <p>
52
+ <?php
53
+ printf(
54
+ /* translators: Placeholders are numbers, versions of PHP in use on the site, and required by VaultPress. */
55
+ esc_html__( 'Your version of PHP (%1$s) is lower than the version required by VaultPress (%2$s). Please update PHP to continue enjoying VaultPress.', 'vaultpress' ),
56
+ esc_html( phpversion() ),
57
+ esc_html( VAULTPRESS__MINIMUM_PHP_VERSION )
58
  );
59
+ ?>
60
+ </p>
61
+ <p class="button-container">
62
+ <?php
63
+ printf(
64
+ '<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
65
+ esc_url( $update_php_url ),
66
+ __( 'Learn more about updating PHP' ),
67
+ /* translators: accessibility text */
68
+ __( '(opens in a new tab)' )
69
+ );
70
+ ?>
71
+ </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  </div>
 
 
 
 
 
 
 
 
 
 
 
73
  <?php
 
 
 
 
 
 
 
74
  }
75
 
76
+ add_action( 'admin_notices', 'vaultpress_admin_unsupported_php_notice' );
77
+ return;
78
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ /**
81
+ * Load all the packages.
82
+ *
83
+ * We want to fail gracefully if `composer install` has not been executed yet, so we are checking for the autoloader.
84
+ * If the autoloader is not present, let's log the failure, pause VaultPress, and display a nice admin notice.
85
+ */
86
+ $loader = VAULTPRESS__PLUGIN_DIR . 'vendor/autoload_packages.php';
87
+
88
+ if ( is_readable( $loader ) ) {
89
+ require $loader;
90
+ } else {
91
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
92
+ error_log(
93
+ wp_kses(
94
+ __( 'Your installation of VaultPress is incomplete. If you installed it from GitHub, please run <code>composer install</code>.', 'vaultpress' ),
95
+ array( 'code' => true )
96
+ )
97
+ );
98
  }
99
+ /**
100
+ * Outputs an admin notice for folks running VaultPress without having run `composer install`.
101
+ */
102
+ function vaultpress_admin_missing_autoloader() {
103
  ?>
104
+ <div class="notice notice-error is-dismissible">
105
+ <p>
106
  <?php
107
+ echo wp_kses(
108
+ __( 'Your installation of VaultPress is incomplete. If you installed it from GitHub, please run <code>composer install</code>.', 'vaultpress' ),
109
+ array( 'code' => true )
110
+ );
 
 
 
 
 
 
 
 
 
 
 
111
  ?>
112
+ </p>
113
+ </div>
114
  <?php
115
  }
116
+ add_action( 'admin_notices', 'vaultpress_admin_missing_autoloader' );
117
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
 
120
+ require_once VAULTPRESS__PLUGIN_DIR . 'class-vaultpress.php';
121
  $vaultpress = VaultPress::init();
122
 
123
  if ( isset( $_GET['vaultpress'] ) && $_GET['vaultpress'] ) {
vendor/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInit3a75cf5e3a8a600ae6ae79f2b0d1d6de::getLoader();
vendor/autoload_packages.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file `autoload_packages.php`was generated by automattic/jetpack-autoloader.
4
+ *
5
+ * From your plugin include this file with:
6
+ * require_once . plugin_dir_path( __FILE__ ) . '/vendor/autoload_packages.php';
7
+ *
8
+ * @package Automattic\Jetpack\Autoloader
9
+ */
10
+
11
+ // phpcs:disable PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
12
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_namespaceFound
13
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_ns_cFound
14
+
15
+ namespace Automattic\Jetpack\Autoloader;
16
+
17
+ if ( ! function_exists( __NAMESPACE__ . '\enqueue_package_class' ) ) {
18
+ global $jetpack_packages_classes;
19
+
20
+ if ( ! is_array( $jetpack_packages_classes ) ) {
21
+ $jetpack_packages_classes = array();
22
+ }
23
+ /**
24
+ * Adds the version of a package to the $jetpack_packages global array so that
25
+ * the autoloader is able to find it.
26
+ *
27
+ * @param string $class_name Name of the class that you want to autoload.
28
+ * @param string $version Version of the class.
29
+ * @param string $path Absolute path to the class so that we can load it.
30
+ */
31
+ function enqueue_package_class( $class_name, $version, $path ) {
32
+ global $jetpack_packages_classes;
33
+
34
+ if ( ! isset( $jetpack_packages_classes[ $class_name ] ) ) {
35
+ $jetpack_packages_classes[ $class_name ] = array(
36
+ 'version' => $version,
37
+ 'path' => $path,
38
+ );
39
+ }
40
+ // If we have a @dev version set always use that one!
41
+ if ( 'dev-' === substr( $jetpack_packages_classes[ $class_name ]['version'], 0, 4 ) ) {
42
+ return;
43
+ }
44
+
45
+ // Always favour the @dev version. Since that version is the same as bleeding edge.
46
+ // We need to make sure that we don't do this in production!
47
+ if ( 'dev-' === substr( $version, 0, 4 ) ) {
48
+ $jetpack_packages_classes[ $class_name ] = array(
49
+ 'version' => $version,
50
+ 'path' => $path,
51
+ );
52
+
53
+ return;
54
+ }
55
+ // Set the latest version!
56
+ if ( version_compare( $jetpack_packages_classes[ $class_name ]['version'], $version, '<' ) ) {
57
+ $jetpack_packages_classes[ $class_name ] = array(
58
+ 'version' => $version,
59
+ 'path' => $path,
60
+ );
61
+ }
62
+ }
63
+ }
64
+
65
+ if ( ! function_exists( __NAMESPACE__ . '\autoloader' ) ) {
66
+ /**
67
+ * Used for autoloading jetpack packages.
68
+ *
69
+ * @param string $class_name Class Name to load.
70
+ */
71
+ function autoloader( $class_name ) {
72
+ global $jetpack_packages_classes;
73
+
74
+ if ( isset( $jetpack_packages_classes[ $class_name ] ) ) {
75
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
76
+ // TODO ideally we shouldn't skip any of these, see: https://github.com/Automattic/jetpack/pull/12646.
77
+ $ignore = in_array(
78
+ $class_name,
79
+ array(
80
+ 'Automattic\Jetpack\JITM',
81
+ 'Automattic\Jetpack\Connection\Manager',
82
+ 'Automattic\Jetpack\Connection\Manager_Interface',
83
+ 'Automattic\Jetpack\Connection\XMLRPC_Connector',
84
+ 'Jetpack_Options',
85
+ 'Jetpack_Signature',
86
+ 'Automattic\Jetpack\Sync\Main',
87
+ 'Automattic\Jetpack\Constants',
88
+ 'Automattic\Jetpack\Tracking',
89
+ 'Automattic\Jetpack\Plugin\Tracking',
90
+ ),
91
+ true
92
+ );
93
+ if ( ! $ignore && function_exists( 'did_action' ) && ! did_action( 'plugins_loaded' ) ) {
94
+ _doing_it_wrong(
95
+ esc_html( $class_name ),
96
+ sprintf(
97
+ /* translators: %s Name of a PHP Class */
98
+ esc_html__( 'Not all plugins have loaded yet but we requested the class %s', 'jetpack' ),
99
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
100
+ $class_name
101
+ ),
102
+ esc_html( $jetpack_packages_classes[ $class_name ]['version'] )
103
+ );
104
+ }
105
+ }
106
+
107
+ if ( file_exists( $jetpack_packages_classes[ $class_name ]['path'] ) ) {
108
+ require_once $jetpack_packages_classes[ $class_name ]['path'];
109
+
110
+ return true;
111
+ }
112
+ }
113
+
114
+ return false;
115
+ }
116
+
117
+ // Add the jetpack autoloader.
118
+ spl_autoload_register( __NAMESPACE__ . '\autoloader' );
119
+ }
120
+ /**
121
+ * Prepare all the classes for autoloading.
122
+ */
123
+ function enqueue_packages_6d59d070f6e47eeebec97f53b0905662() {
124
+ $class_map = require_once dirname( __FILE__ ) . '/composer/autoload_classmap_package.php';
125
+ foreach ( $class_map as $class_name => $class_info ) {
126
+ enqueue_package_class( $class_name, $class_info['version'], $class_info['path'] );
127
+ }
128
+ }
129
+ enqueue_packages_6d59d070f6e47eeebec97f53b0905662();
vendor/automattic/jetpack-autoloader/README.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ A custom autoloader for Composer
2
+ =====================================
3
+
4
+ This is a custom autoloader generator that uses a classmap to always load the latest version of a class.
5
+
6
+ The problem this autoloader is trying to solve is conflicts that arise when two or more plugins use the same package, but one of the plugins uses an older version of said package.
7
+
8
+ This is solved by keeping an in memory map of all the different classes that can be loaded, and updating the map with the path to the latest version of the package for the autoloader to find when we instantiate the class.
9
+ This only works if we instantiate the class after all the plugins have loaded. That is why the class produces an error if the plugin calls a class but has not loaded all the plugins yet.
10
+
11
+ It diverges from the default Composer autoloader setup in the following ways:
12
+
13
+ * It creates an `autoload_classmap_package.php` file in the `vendor/composer` directory.
14
+ * This file includes the version numbers from each package that is used.
15
+ * The autoloader will only load the latest version of the library no matter what plugin loads the library.
16
+ * Only call the library classes after all the plugins have loaded and the `plugins_loaded` action has fired.
17
+
18
+
19
+ Usage
20
+ -----
21
+
22
+ In your project's `composer.json`, add the following lines:
23
+
24
+ ```json
25
+ {
26
+ "require-dev": {
27
+ "automattic/jetpack-autoloader": "^1"
28
+ }
29
+ }
30
+ ```
31
+
32
+ After the next update/install, you will have a `vendor/autoload_packages.php` file.
33
+ Load the file in your plugin via main plugin file.
34
+
35
+ In the main plugin you will also need to include the files like this.
36
+ ```php
37
+ require_once . plugin_dir_path( __FILE__ ) . '/vendor/autoload_packages.php';
38
+ ```
39
+
40
+
41
+ Current Limitations
42
+ -----
43
+
44
+ We currently only support packages that autoload via psr-4 definition in their package.
vendor/automattic/jetpack-autoloader/composer.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "automattic/jetpack-autoloader",
3
+ "description": "Creates a custom autoloader for a plugin or theme.",
4
+ "type": "composer-plugin",
5
+ "license": "GPL-2.0-or-later",
6
+ "require": {
7
+ "composer-plugin-api": "^1.1"
8
+ },
9
+ "require-dev": {
10
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5"
11
+ },
12
+ "autoload": {
13
+ "psr-4": {
14
+ "Automattic\\Jetpack\\Autoloader\\": "src"
15
+ }
16
+ },
17
+ "extra": {
18
+ "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin"
19
+ },
20
+ "scripts": {
21
+ "phpunit": [
22
+ "@composer install",
23
+ "./vendor/phpunit/phpunit/phpunit --colors=always"
24
+ ]
25
+ },
26
+ "minimum-stability": "dev",
27
+ "prefer-stable": true
28
+ }
vendor/automattic/jetpack-autoloader/src/AutoloadGenerator.php ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Autoloader Generator.
4
+ *
5
+ * @package Automattic\Jetpack\Autoloader
6
+ */
7
+
8
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_useFound
9
+ // phpcs:disable PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
10
+ // phpcs:disable PHPCompatibility.FunctionDeclarations.NewClosure.Found
11
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_namespaceFound
12
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_dirFound
13
+ // phpcs:disable WordPress.Files.FileName.InvalidClassFileName
14
+ // phpcs:disable WordPress.Files.FileName.NotHyphenatedLowercase
15
+ // phpcs:disable WordPress.Files.FileName.InvalidClassFileName
16
+ // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_var_export
17
+ // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents
18
+ // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_read_fopen
19
+ // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_read_fwrite
20
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
21
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.InterpolatedVariableNotSnakeCase
22
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
23
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase
24
+
25
+
26
+ namespace Automattic\Jetpack\Autoloader;
27
+
28
+ use Composer\Autoload\AutoloadGenerator as BaseGenerator;
29
+ use Composer\Autoload\ClassMapGenerator;
30
+ use Composer\Config;
31
+ use Composer\Installer\InstallationManager;
32
+ use Composer\IO\IOInterface;
33
+ use Composer\Package\PackageInterface;
34
+ use Composer\Repository\InstalledRepositoryInterface;
35
+ use Composer\Util\Filesystem;
36
+
37
+ /**
38
+ * Class AutoloadGenerator.
39
+ */
40
+ class AutoloadGenerator extends BaseGenerator {
41
+
42
+ /**
43
+ * Instantiate an AutoloadGenerator object.
44
+ *
45
+ * @param IOInterface $io IO object.
46
+ */
47
+ public function __construct( IOInterface $io = null ) {
48
+ $this->io = $io;
49
+ }
50
+
51
+ /**
52
+ * Dump the autoloader.
53
+ *
54
+ * @param Config $config Config object.
55
+ * @param InstalledRepositoryInterface $localRepo Installed Reposetories object.
56
+ * @param PackageInterface $mainPackage Main Package object.
57
+ * @param InstallationManager $installationManager Manager for installing packages.
58
+ * @param string $targetDir Path to the current target directory.
59
+ * @param bool $scanPsr0Packages Whether to search for packages. Currently hard coded to always be false.
60
+ * @param string $suffix The autoloader suffix, ignored since we want our autoloader to only be included once.
61
+ */
62
+ public function dump(
63
+ Config $config,
64
+ InstalledRepositoryInterface $localRepo,
65
+ PackageInterface $mainPackage,
66
+ InstallationManager $installationManager,
67
+ $targetDir,
68
+ $scanPsr0Packages = null, // Not used we always optimize.
69
+ $suffix = null
70
+ ) {
71
+
72
+ $filesystem = new Filesystem();
73
+ $filesystem->ensureDirectoryExists( $config->get( 'vendor-dir' ) );
74
+
75
+ $basePath = $filesystem->normalizePath( realpath( getcwd() ) );
76
+ $vendorPath = $filesystem->normalizePath( realpath( $config->get( 'vendor-dir' ) ) );
77
+ $targetDir = $vendorPath . '/' . $targetDir;
78
+ $filesystem->ensureDirectoryExists( $targetDir );
79
+
80
+ $packageMap = $this->buildPackageMap( $installationManager, $mainPackage, $localRepo->getCanonicalPackages() );
81
+ $autoloads = $this->parseAutoloads( $packageMap, $mainPackage );
82
+
83
+ $classMap = $this->getClassMap( $autoloads, $filesystem, $vendorPath, $basePath );
84
+
85
+ // Generate the files.
86
+ file_put_contents( $targetDir . '/autoload_classmap_package.php', $this->getAutoloadClassmapPackagesFile( $classMap ) );
87
+ $this->io->writeError( '<info>Generated ' . $targetDir . '/autoload_classmap_package.php</info>', true );
88
+
89
+ file_put_contents( $vendorPath . '/autoload_packages.php', $this->getAutoloadPackageFile( $suffix ) );
90
+ $this->io->writeError( '<info>Generated ' . $vendorPath . '/autoload_packages.php</info>', true );
91
+
92
+ }
93
+
94
+ /**
95
+ * This function differs from the composer parseAutoloadsType in that beside returning the path.
96
+ * It also return the path and the version of a package.
97
+ *
98
+ * Currently supports only psr-4 and clasmap parsing.
99
+ *
100
+ * @param array $packageMap Map of all the packages.
101
+ * @param string $type Type of autoloader to use, currently not used, since we only support psr-4.
102
+ * @param PackageInterface $mainPackage Instance of the Package Object.
103
+ *
104
+ * @return array
105
+ */
106
+ protected function parseAutoloadsType( array $packageMap, $type, PackageInterface $mainPackage ) {
107
+ $autoloads = array();
108
+
109
+ if ( 'psr-4' !== $type && 'classmap' !== $type ) {
110
+ return parent::parseAutoloadsType( $packageMap, $type, $mainPackage );
111
+ }
112
+
113
+ foreach ( $packageMap as $item ) {
114
+ list($package, $installPath) = $item;
115
+ $autoload = $package->getAutoload();
116
+
117
+ if ( $package === $mainPackage ) {
118
+ $autoload = array_merge_recursive( $autoload, $package->getDevAutoload() );
119
+ }
120
+
121
+ if ( null !== $package->getTargetDir() && $package !== $mainPackage ) {
122
+ $installPath = substr( $installPath, 0, -strlen( '/' . $package->getTargetDir() ) );
123
+ }
124
+
125
+ if ( 'psr-4' === $type && isset( $autoload['psr-4'] ) && is_array( $autoload['psr-4'] ) ) {
126
+ foreach ( $autoload['psr-4'] as $namespace => $paths ) {
127
+ $paths = is_array( $paths ) ? $paths : array( $paths );
128
+ foreach ( $paths as $path ) {
129
+ $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path;
130
+ $autoloads[ $namespace ][] = array(
131
+ 'path' => $relativePath,
132
+ 'version' => $package->getVersion(), // Version of the class comes from the package - should we try to parse it?
133
+ );
134
+ }
135
+ }
136
+ }
137
+
138
+ if ( 'classmap' === $type && isset( $autoload['classmap'] ) && is_array( $autoload['classmap'] ) ) {
139
+ foreach ( $autoload['classmap'] as $paths ) {
140
+ $paths = is_array( $paths ) ? $paths : array( $paths );
141
+ foreach ( $paths as $path ) {
142
+ $relativePath = empty( $installPath ) ? ( empty( $path ) ? '.' : $path ) : $installPath . '/' . $path;
143
+ $autoloads[] = array(
144
+ 'path' => $relativePath,
145
+ 'version' => $package->getVersion(), // Version of the class comes from the package - should we try to parse it?
146
+ );
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ return $autoloads;
153
+ }
154
+
155
+ /**
156
+ * Take the autoloads array and return the classMap that contains the path and the version for each namespace.
157
+ *
158
+ * @param array $autoloads Array of autoload settings defined defined by the packages.
159
+ * @param Filesystem $filesystem Filesystem class instance.
160
+ * @param string $vendorPath Path to the vendor directory.
161
+ * @param string $basePath Base Path.
162
+ *
163
+ * @return array $classMap
164
+ */
165
+ private function getClassMap( array $autoloads, Filesystem $filesystem, $vendorPath, $basePath ) {
166
+ $blacklist = null;
167
+
168
+ if ( ! empty( $autoloads['exclude-from-classmap'] ) ) {
169
+ $blacklist = '{(' . implode( '|', $autoloads['exclude-from-classmap'] ) . ')}';
170
+ }
171
+
172
+ $classmapString = '';
173
+
174
+ // Scan the PSR-4 and classmap directories for class files, and add them to the class map.
175
+ foreach ( $autoloads['psr-4'] as $namespace => $packages_info ) {
176
+ foreach ( $packages_info as $package ) {
177
+ $dir = $filesystem->normalizePath(
178
+ $filesystem->isAbsolutePath( $package['path'] )
179
+ ? $package['path']
180
+ : $basePath . '/' . $package['path']
181
+ );
182
+ $map = ClassMapGenerator::createMap( $dir, $blacklist, $this->io, $namespace );
183
+
184
+ foreach ( $map as $class => $path ) {
185
+ $classCode = var_export( $class, true );
186
+ $pathCode = $this->getPathCode( $filesystem, $basePath, $vendorPath, $path );
187
+ $versionCode = var_export( $package['version'], true );
188
+ $classmapString .= <<<CLASS_CODE
189
+ $classCode => array(
190
+ 'version' => $versionCode,
191
+ 'path' => $pathCode
192
+ ),
193
+ CLASS_CODE;
194
+ $classmapString .= PHP_EOL;
195
+ }
196
+ }
197
+ }
198
+
199
+ foreach ( $autoloads['classmap'] as $package ) {
200
+ $dir = $filesystem->normalizePath(
201
+ $filesystem->isAbsolutePath( $package['path'] )
202
+ ? $package['path']
203
+ : $basePath . '/' . $package['path']
204
+ );
205
+ $map = ClassMapGenerator::createMap( $dir, $blacklist, $this->io, null );
206
+
207
+ foreach ( $map as $class => $path ) {
208
+ $classCode = var_export( $class, true );
209
+ $pathCode = $this->getPathCode( $filesystem, $basePath, $vendorPath, $path );
210
+ $versionCode = var_export( $package['version'], true );
211
+ $classmapString .= <<<CLASS_CODE
212
+ $classCode => array(
213
+ 'version' => $versionCode,
214
+ 'path' => $pathCode
215
+ ),
216
+ CLASS_CODE;
217
+ $classmapString .= PHP_EOL;
218
+ }
219
+ }
220
+
221
+ return 'array( ' . PHP_EOL . $classmapString . ');' . PHP_EOL;
222
+ }
223
+
224
+ /**
225
+ * Generate the PHP that will be used in the autoload_classmap_package.php files.
226
+ *
227
+ * @param srting $classMap class map array string that is to be written out to the file.
228
+ *
229
+ * @return string
230
+ */
231
+ private function getAutoloadClassmapPackagesFile( $classMap ) {
232
+
233
+ return <<<INCLUDE_CLASSMAP
234
+ <?php
235
+
236
+ // This file `autoload_classmap_packages.php` was auto generated by automattic/jetpack-autoloader.
237
+
238
+ \$vendorDir = dirname(__DIR__);
239
+ \$baseDir = dirname(\$vendorDir);
240
+
241
+ return $classMap
242
+
243
+ INCLUDE_CLASSMAP;
244
+ }
245
+
246
+ /**
247
+ * Generate the PHP that will be used in the autoload_packages.php files.
248
+ *
249
+ * @param string $suffix Unique suffix added to the jetpack_enqueue_packages function.
250
+ *
251
+ * @return string
252
+ */
253
+ private function getAutoloadPackageFile( $suffix ) {
254
+ $sourceLoader = fopen( __DIR__ . '/autoload.php', 'r' );
255
+ $file_contents = stream_get_contents( $sourceLoader );
256
+ $file_contents .= <<<INCLUDE_FILES
257
+ /**
258
+ * Prepare all the classes for autoloading.
259
+ */
260
+ function enqueue_packages_$suffix() {
261
+ \$class_map = require_once dirname( __FILE__ ) . '/composer/autoload_classmap_package.php';
262
+ foreach ( \$class_map as \$class_name => \$class_info ) {
263
+ enqueue_package_class( \$class_name, \$class_info['version'], \$class_info['path'] );
264
+ }
265
+ }
266
+ enqueue_packages_$suffix();
267
+
268
+ INCLUDE_FILES;
269
+
270
+ return $file_contents;
271
+ }
272
+ }
vendor/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Custom Autoloader Composer Plugin, hooks into composer events to generate the custom autoloader.
4
+ *
5
+ * @package Automattic\Jetpack\Autoloader
6
+ */
7
+
8
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_useFound
9
+ // phpcs:disable PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
10
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_namespaceFound
11
+ // phpcs:disable WordPress.Files.FileName.NotHyphenatedLowercase
12
+ // phpcs:disable WordPress.Files.FileName.InvalidClassFileName
13
+ // phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
14
+
15
+ namespace Automattic\Jetpack\Autoloader;
16
+
17
+ use Composer\Composer;
18
+ use Composer\IO\IOInterface;
19
+ use Composer\Script\Event;
20
+ use Composer\Script\ScriptEvents;
21
+ use Composer\Plugin\PluginInterface;
22
+ use Composer\EventDispatcher\EventSubscriberInterface;
23
+
24
+ /**
25
+ * Class CustomAutoloaderPlugin.
26
+ *
27
+ * @package Automattic\Jetpack\Autoloader
28
+ */
29
+ class CustomAutoloaderPlugin implements PluginInterface, EventSubscriberInterface {
30
+
31
+ /**
32
+ * IO object.
33
+ *
34
+ * @var IOInterface IO object.
35
+ */
36
+ private $io;
37
+
38
+ /**
39
+ * Composer object.
40
+ *
41
+ * @var Composer Composer object.
42
+ */
43
+ private $composer;
44
+
45
+ /**
46
+ * Do nothing.
47
+ *
48
+ * @param Composer $composer Composer object.
49
+ * @param IOInterface $io IO object.
50
+ */
51
+ public function activate( Composer $composer, IOInterface $io ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
52
+ $this->composer = $composer;
53
+ $this->io = $io;
54
+ }
55
+
56
+ /**
57
+ * Tell composer to listen for events and do something with them.
58
+ *
59
+ * @return array List of succribed events.
60
+ */
61
+ public static function getSubscribedEvents() {
62
+ return array(
63
+ ScriptEvents::POST_AUTOLOAD_DUMP => 'postAutoloadDump',
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Generate the custom autolaoder.
69
+ *
70
+ * @param Event $event Script event object.
71
+ */
72
+ public function postAutoloadDump( Event $event ) {
73
+
74
+ $installationManager = $this->composer->getInstallationManager();
75
+ $repoManager = $this->composer->getRepositoryManager();
76
+ $localRepo = $repoManager->getLocalRepository();
77
+ $package = $this->composer->getPackage();
78
+ $config = $this->composer->getConfig();
79
+ $optimize = true;
80
+ $suffix = $config->get( 'autoloader-suffix' )
81
+ ? $config->get( 'autoloader-suffix' )
82
+ : md5( uniqid( '', true ) );
83
+
84
+ $generator = new AutoloadGenerator( $this->io );
85
+
86
+ $generator->dump( $config, $localRepo, $package, $installationManager, 'composer', $optimize, $suffix );
87
+ $this->generated = true;
88
+ }
89
+
90
+ }
vendor/automattic/jetpack-autoloader/src/autoload.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file `autoload_packages.php`was generated by automattic/jetpack-autoloader.
4
+ *
5
+ * From your plugin include this file with:
6
+ * require_once . plugin_dir_path( __FILE__ ) . '/vendor/autoload_packages.php';
7
+ *
8
+ * @package Automattic\Jetpack\Autoloader
9
+ */
10
+
11
+ // phpcs:disable PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
12
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_namespaceFound
13
+ // phpcs:disable PHPCompatibility.Keywords.NewKeywords.t_ns_cFound
14
+
15
+ namespace Automattic\Jetpack\Autoloader;
16
+
17
+ if ( ! function_exists( __NAMESPACE__ . '\enqueue_package_class' ) ) {
18
+ global $jetpack_packages_classes;
19
+
20
+ if ( ! is_array( $jetpack_packages_classes ) ) {
21
+ $jetpack_packages_classes = array();
22
+ }
23
+ /**
24
+ * Adds the version of a package to the $jetpack_packages global array so that
25
+ * the autoloader is able to find it.
26
+ *
27
+ * @param string $class_name Name of the class that you want to autoload.
28
+ * @param string $version Version of the class.
29
+ * @param string $path Absolute path to the class so that we can load it.
30
+ */
31
+ function enqueue_package_class( $class_name, $version, $path ) {
32
+ global $jetpack_packages_classes;
33
+
34
+ if ( ! isset( $jetpack_packages_classes[ $class_name ] ) ) {
35
+ $jetpack_packages_classes[ $class_name ] = array(
36
+ 'version' => $version,
37
+ 'path' => $path,
38
+ );
39
+ }
40
+ // If we have a @dev version set always use that one!
41
+ if ( 'dev-' === substr( $jetpack_packages_classes[ $class_name ]['version'], 0, 4 ) ) {
42
+ return;
43
+ }
44
+
45
+ // Always favour the @dev version. Since that version is the same as bleeding edge.
46
+ // We need to make sure that we don't do this in production!
47
+ if ( 'dev-' === substr( $version, 0, 4 ) ) {
48
+ $jetpack_packages_classes[ $class_name ] = array(
49
+ 'version' => $version,
50
+ 'path' => $path,
51
+ );
52
+
53
+ return;
54
+ }
55
+ // Set the latest version!
56
+ if ( version_compare( $jetpack_packages_classes[ $class_name ]['version'], $version, '<' ) ) {
57
+ $jetpack_packages_classes[ $class_name ] = array(
58
+ 'version' => $version,
59
+ 'path' => $path,
60
+ );
61
+ }
62
+ }
63
+ }
64
+
65
+ if ( ! function_exists( __NAMESPACE__ . '\autoloader' ) ) {
66
+ /**
67
+ * Used for autoloading jetpack packages.
68
+ *
69
+ * @param string $class_name Class Name to load.
70
+ */
71
+ function autoloader( $class_name ) {
72
+ global $jetpack_packages_classes;
73
+
74
+ if ( isset( $jetpack_packages_classes[ $class_name ] ) ) {
75
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
76
+ // TODO ideally we shouldn't skip any of these, see: https://github.com/Automattic/jetpack/pull/12646.
77
+ $ignore = in_array(
78
+ $class_name,
79
+ array(
80
+ 'Automattic\Jetpack\JITM',
81
+ 'Automattic\Jetpack\Connection\Manager',
82
+ 'Automattic\Jetpack\Connection\Manager_Interface',
83
+ 'Automattic\Jetpack\Connection\XMLRPC_Connector',
84
+ 'Jetpack_Options',
85
+ 'Jetpack_Signature',
86
+ 'Automattic\Jetpack\Sync\Main',
87
+ 'Automattic\Jetpack\Constants',
88
+ 'Automattic\Jetpack\Tracking',
89
+ 'Automattic\Jetpack\Plugin\Tracking',
90
+ ),
91
+ true
92
+ );
93
+ if ( ! $ignore && function_exists( 'did_action' ) && ! did_action( 'plugins_loaded' ) ) {
94
+ _doing_it_wrong(
95
+ esc_html( $class_name ),
96
+ sprintf(
97
+ /* translators: %s Name of a PHP Class */
98
+ esc_html__( 'Not all plugins have loaded yet but we requested the class %s', 'jetpack' ),
99
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
100
+ $class_name
101
+ ),
102
+ esc_html( $jetpack_packages_classes[ $class_name ]['version'] )
103
+ );
104
+ }
105
+ }
106
+
107
+ if ( file_exists( $jetpack_packages_classes[ $class_name ]['path'] ) ) {
108
+ require_once $jetpack_packages_classes[ $class_name ]['path'];
109
+
110
+ return true;
111
+ }
112
+ }
113
+
114
+ return false;
115
+ }
116
+
117
+ // Add the jetpack autoloader.
118
+ spl_autoload_register( __NAMESPACE__ . '\autoloader' );
119
+ }
vendor/automattic/jetpack-logo/README.md ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Jetpack logo
2
+
3
+ A package that allows you to obtain a Jetpack logo in SVG format.
4
+
5
+ ### Usage
6
+
7
+ Display the default Jetpack logo:
8
+
9
+ ```php
10
+ use Automattic\Jetpack\Assets\Logo;
11
+
12
+ $logo = new Logo();
13
+ echo $logo->render();
14
+ ```
15
+
16
+ ### Styling
17
+
18
+ The Jetpack logo SVG string includes CSS classes to stylize it:
19
+ - `jetpack-logo`: the wrapper <svg> tag.
20
+ - `jetpack-logo__icon-circle`: the circle of the Jetpack mark.
21
+ - `jetpack-logo__icon-triangle`: two shapes that correspond to each triangle in the Jetpack mark.
22
+ - `jetpack-logo__icon-text`: the Jetpack lettering.
23
+
24
+ These shapes can be stylized using CSS. For example, to give the circle and text a blue gray color, we can do:
25
+
26
+ ```css
27
+ .jetpack-logo__icon-circle,
28
+ .jetpack-logo__text {
29
+ fill: #636d75;
30
+ }
31
+ ```
vendor/automattic/jetpack-logo/composer.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "automattic/jetpack-logo",
3
+ "description": "A logo for Jetpack",
4
+ "type": "library",
5
+ "license": "GPL-2.0-or-later",
6
+ "require": {},
7
+ "require-dev": {
8
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5",
9
+ "php-mock/php-mock": "^2.1"
10
+ },
11
+ "autoload": {
12
+ "psr-4": {
13
+ "Automattic\\Jetpack\\Assets\\": "src/"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "phpunit": [
18
+ "@composer install",
19
+ "./vendor/phpunit/phpunit/phpunit --colors=always"
20
+ ]
21
+ },
22
+ "minimum-stability": "dev",
23
+ "prefer-stable": true
24
+ }
vendor/automattic/jetpack-logo/phpunit.xml.dist ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <phpunit bootstrap="tests/php/bootstrap.php" backupGlobals="false" colors="true">
2
+ <testsuites>
3
+ <testsuite name="main">
4
+ <directory prefix="test" suffix=".php">tests/php</directory>
5
+ </testsuite>
6
+ </testsuites>
7
+ </phpunit>
vendor/automattic/jetpack-logo/src/Logo.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A logo for Jetpack.
4
+ *
5
+ * @package jetpack-logo
6
+ */
7
+
8
+ namespace Automattic\Jetpack\Assets;
9
+
10
+ /**
11
+ * Jetpack logo as SVG shapes.
12
+ *
13
+ * Initializes the logo property with a string describing the Jetpack logo.
14
+ * The Jetpack logo SVG string includes CSS classes to stylize it:
15
+ * - jetpack-logo: the wrapper <svg> tag.
16
+ * - jetpack-logo__icon-circle: the circle of the Jetpack mark.
17
+ * - jetpack-logo__icon-triangle: two shapes that correspond to each triangle in the Jetpack mark.
18
+ * - jetpack-logo__icon-text: the Jetpack lettering.
19
+ *
20
+ * @var string
21
+ */
22
+ const JETPACK_LOGO_SVG = <<<'EOSVG'
23
+ <svg xmlns="http://www.w3.org/2000/svg" height="32" class="jetpack-logo" viewBox="0 0 118 32">
24
+ <path class="jetpack-logo__icon-circle" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z" fill="#00be28" />
25
+ <polygon class="jetpack-logo__icon-triangle" points="15,19 7,19 15,3" fill="#fff" />
26
+ <polygon class="jetpack-logo__icon-triangle" points="17,29 17,13 25,13" fill="#fff" />
27
+ <path class="jetpack-logo__text" d="M41.3 26.6c-.5-.7-.9-1.4-1.3-2.1 2.3-1.4 3-2.5 3-4.6V8h-3V6h6v13.4C46 22.8 45 24.8 41.3 26.6zM58.5 21.3c-1.5.5-2.7.6-4.2.6-3.6 0-5.8-1.8-5.8-6 0-3.1 1.9-5.9 5.5-5.9s4.9 2.5 4.9 4.9c0 .8 0 1.5-.1 2h-7.3c.1 2.5 1.5 2.8 3.6 2.8 1.1 0 2.2-.3 3.4-.7C58.5 19 58.5 21.3 58.5 21.3zM56 15c0-1.4-.5-2.9-2-2.9-1.4 0-2.3 1.3-2.4 2.9C51.6 15 56 15 56 15zM65 18.4c0 1.1.8 1.3 1.4 1.3.5 0 2-.2 2.6-.4v2.1c-.9.3-2.5.5-3.7.5-1.5 0-3.2-.5-3.2-3.1V12H60v-2h2.1V7.1H65V10h4v2h-4V18.4zM71 10h3v1.3c1.1-.8 1.9-1.3 3.3-1.3 2.5 0 4.5 1.8 4.5 5.6s-2.2 6.3-5.8 6.3c-.9 0-1.3-.1-2-.3V28h-3V10zM76.5 12.3c-.8 0-1.6.4-2.5 1.2v5.9c.6.1.9.2 1.8.2 2 0 3.2-1.3 3.2-3.9C79 13.4 78.1 12.3 76.5 12.3zM93 22h-3v-1.5c-.9.7-1.9 1.5-3.5 1.5-1.5 0-3.1-1.1-3.1-3.2 0-2.9 2.5-3.4 4.2-3.7l2.4-.3v-.3c0-1.5-.5-2.3-2-2.3-.7 0-2.3.5-3.7 1.1L84 11c1.2-.4 3-1 4.4-1 2.7 0 4.6 1.4 4.6 4.7L93 22zM90 16.4l-2.2.4c-.7.1-1.4.5-1.4 1.6 0 .9.5 1.4 1.3 1.4s1.5-.5 2.3-1V16.4zM104.5 21.3c-1.1.4-2.2.6-3.5.6-4.2 0-5.9-2.4-5.9-5.9 0-3.7 2.3-6 6.1-6 1.4 0 2.3.2 3.2.5V13c-.8-.3-2-.6-3.2-.6-1.7 0-3.2.9-3.2 3.6 0 2.9 1.5 3.8 3.3 3.8.9 0 1.9-.2 3.2-.7V21.3zM110 15.2c.2-.3.2-.8 3.8-5.2h3.7l-4.6 5.7 5 6.3h-3.7l-4.2-5.8V22h-3V6h3V15.2z" />
28
+ </svg>
29
+ EOSVG;
30
+
31
+ /**
32
+ * Create and render a Jetpack logo.
33
+ */
34
+ class Logo {
35
+
36
+ /**
37
+ * Return the Jetpack logo.
38
+ *
39
+ * @return string The Jetpack logo.
40
+ */
41
+ public function render() {
42
+ return JETPACK_LOGO_SVG;
43
+ }
44
+
45
+ /**
46
+ * Return string containing the Jetpack logo.
47
+ *
48
+ * @since 7.5.0
49
+ *
50
+ * @param bool $logotype Should we use the full logotype (logo + text). Default to false.
51
+ *
52
+ * @return string
53
+ */
54
+ public function get_jp_emblem( $logotype = false ) {
55
+ $logo = '<path fill="#00BE28" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16c8.8,0,16-7.2,16-16S24.8,0,16,0z M15.2,18.7h-8l8-15.5V18.7z M16.8,28.8 V13.3h8L16.8,28.8z"/>';
56
+ $text = '
57
+ <path d="M41.3,26.6c-0.5-0.7-0.9-1.4-1.3-2.1c2.3-1.4,3-2.5,3-4.6V8h-3V6h6v13.4C46,22.8,45,24.8,41.3,26.6z" />
58
+ <path d="M65,18.4c0,1.1,0.8,1.3,1.4,1.3c0.5,0,2-0.2,2.6-0.4v2.1c-0.9,0.3-2.5,0.5-3.7,0.5c-1.5,0-3.2-0.5-3.2-3.1V12H60v-2h2.1V7.1 H65V10h4v2h-4V18.4z" />
59
+ <path d="M71,10h3v1.3c1.1-0.8,1.9-1.3,3.3-1.3c2.5,0,4.5,1.8,4.5,5.6s-2.2,6.3-5.8,6.3c-0.9,0-1.3-0.1-2-0.3V28h-3V10z M76.5,12.3 c-0.8,0-1.6,0.4-2.5,1.2v5.9c0.6,0.1,0.9,0.2,1.8,0.2c2,0,3.2-1.3,3.2-3.9C79,13.4,78.1,12.3,76.5,12.3z" />
60
+ <path d="M93,22h-3v-1.5c-0.9,0.7-1.9,1.5-3.5,1.5c-1.5,0-3.1-1.1-3.1-3.2c0-2.9,2.5-3.4,4.2-3.7l2.4-0.3v-0.3c0-1.5-0.5-2.3-2-2.3 c-0.7,0-2.3,0.5-3.7,1.1L84,11c1.2-0.4,3-1,4.4-1c2.7,0,4.6,1.4,4.6,4.7L93,22z M90,16.4l-2.2,0.4c-0.7,0.1-1.4,0.5-1.4,1.6 c0,0.9,0.5,1.4,1.3,1.4s1.5-0.5,2.3-1V16.4z" />
61
+ <path d="M104.5,21.3c-1.1,0.4-2.2,0.6-3.5,0.6c-4.2,0-5.9-2.4-5.9-5.9c0-3.7,2.3-6,6.1-6c1.4,0,2.3,0.2,3.2,0.5V13 c-0.8-0.3-2-0.6-3.2-0.6c-1.7,0-3.2,0.9-3.2,3.6c0,2.9,1.5,3.8,3.3,3.8c0.9,0,1.9-0.2,3.2-0.7V21.3z" />
62
+ <path d="M110,15.2c0.2-0.3,0.2-0.8,3.8-5.2h3.7l-4.6,5.7l5,6.3h-3.7l-4.2-5.8V22h-3V6h3V15.2z" />
63
+ <path d="M58.5,21.3c-1.5,0.5-2.7,0.6-4.2,0.6c-3.6,0-5.8-1.8-5.8-6c0-3.1,1.9-5.9,5.5-5.9s4.9,2.5,4.9,4.9c0,0.8,0,1.5-0.1,2h-7.3 c0.1,2.5,1.5,2.8,3.6,2.8c1.1,0,2.2-0.3,3.4-0.7C58.5,19,58.5,21.3,58.5,21.3z M56,15c0-1.4-0.5-2.9-2-2.9c-1.4,0-2.3,1.3-2.4,2.9 C51.6,15,56,15,56,15z" />
64
+ ';
65
+ return sprintf(
66
+ '<svg id="jetpack-logo__icon" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 %1$s 32">%2$s</svg>',
67
+ ( true === $logotype ? '118' : '32' ),
68
+ ( true === $logotype ? $logo . $text : $logo )
69
+ );
70
+ }
71
+ }
vendor/automattic/jetpack-logo/tests/php/bootstrap.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+
3
+ require_once __DIR__ . '/../../vendor/autoload.php';
vendor/automattic/jetpack-logo/tests/php/test_Logo.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Automattic\Jetpack\Assets\Logo;
4
+
5
+ use PHPUnit\Framework\TestCase;
6
+
7
+ class Test_Logo extends TestCase {
8
+
9
+ /**
10
+ * Ensure the rendered logo has all the CSS classes needed for styling.
11
+ */
12
+ function test_constructor_default_logo() {
13
+ $logo = new Logo();
14
+ $logo_render = $logo->render();
15
+ $this->assertContains( '<svg xmlns="http://www.w3.org/2000/svg"', $logo_render );
16
+ $this->assertContains( 'class="jetpack-logo"', $logo_render );
17
+ $this->assertContains( 'class="jetpack-logo__icon-circle"', $logo_render );
18
+ $this->assertEquals( 2, preg_match_all( '/class="jetpack-logo__icon-triangle"/', $logo_render ) );
19
+ $this->assertContains( 'class="jetpack-logo__text"', $logo_render );
20
+ }
21
+
22
+ }
vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17
+ *
18
+ * $loader = new \Composer\Autoload\ClassLoader();
19
+ *
20
+ * // register classes with namespaces
21
+ * $loader->add('Symfony\Component', __DIR__.'/component');
22
+ * $loader->add('Symfony', __DIR__.'/framework');
23
+ *
24
+ * // activate the autoloader
25
+ * $loader->register();
26
+ *
27
+ * // to enable searching the include path (eg. for PEAR packages)
28
+ * $loader->setUseIncludePath(true);
29
+ *
30
+ * In this example, if you try to use a class in the Symfony\Component
31
+ * namespace or one of its children (Symfony\Component\Console for instance),
32
+ * the autoloader will first look for the class under the component/
33
+ * directory, and it will then fallback to the framework/ directory if not
34
+ * found before giving up.
35
+ *
36
+ * This class is loosely based on the Symfony UniversalClassLoader.
37
+ *
38
+ * @author Fabien Potencier <fabien@symfony.com>
39
+ * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+ private $classMapAuthoritative = false;
57
+ private $missingClasses = array();
58
+ private $apcuPrefix;
59
+
60
+ public function getPrefixes()
61
+ {
62
+ if (!empty($this->prefixesPsr0)) {
63
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
64
+ }
65
+
66
+ return array();
67
+ }
68
+
69
+ public function getPrefixesPsr4()
70
+ {
71
+ return $this->prefixDirsPsr4;
72
+ }
73
+
74
+ public function getFallbackDirs()
75
+ {
76
+ return $this->fallbackDirsPsr0;
77
+ }
78
+
79
+ public function getFallbackDirsPsr4()
80
+ {
81
+ return $this->fallbackDirsPsr4;
82
+ }
83
+
84
+ public function getClassMap()
85
+ {
86
+ return $this->classMap;
87
+ }
88
+
89
+ /**
90
+ * @param array $classMap Class to filename map
91
+ */
92
+ public function addClassMap(array $classMap)
93
+ {
94
+ if ($this->classMap) {
95
+ $this->classMap = array_merge($this->classMap, $classMap);
96
+ } else {
97
+ $this->classMap = $classMap;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Registers a set of PSR-0 directories for a given prefix, either
103
+ * appending or prepending to the ones previously set for this prefix.
104
+ *
105
+ * @param string $prefix The prefix
106
+ * @param array|string $paths The PSR-0 root directories
107
+ * @param bool $prepend Whether to prepend the directories
108
+ */
109
+ public function add($prefix, $paths, $prepend = false)
110
+ {
111
+ if (!$prefix) {
112
+ if ($prepend) {
113
+ $this->fallbackDirsPsr0 = array_merge(
114
+ (array) $paths,
115
+ $this->fallbackDirsPsr0
116
+ );
117
+ } else {
118
+ $this->fallbackDirsPsr0 = array_merge(
119
+ $this->fallbackDirsPsr0,
120
+ (array) $paths
121
+ );
122
+ }
123
+
124
+ return;
125
+ }
126
+
127
+ $first = $prefix[0];
128
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
129
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
130
+
131
+ return;
132
+ }
133
+ if ($prepend) {
134
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
135
+ (array) $paths,
136
+ $this->prefixesPsr0[$first][$prefix]
137
+ );
138
+ } else {
139
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
140
+ $this->prefixesPsr0[$first][$prefix],
141
+ (array) $paths
142
+ );
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Registers a set of PSR-4 directories for a given namespace, either
148
+ * appending or prepending to the ones previously set for this namespace.
149
+ *
150
+ * @param string $prefix The prefix/namespace, with trailing '\\'
151
+ * @param array|string $paths The PSR-4 base directories
152
+ * @param bool $prepend Whether to prepend the directories
153
+ *
154
+ * @throws \InvalidArgumentException
155
+ */
156
+ public function addPsr4($prefix, $paths, $prepend = false)
157
+ {
158
+ if (!$prefix) {
159
+ // Register directories for the root namespace.
160
+ if ($prepend) {
161
+ $this->fallbackDirsPsr4 = array_merge(
162
+ (array) $paths,
163
+ $this->fallbackDirsPsr4
164
+ );
165
+ } else {
166
+ $this->fallbackDirsPsr4 = array_merge(
167
+ $this->fallbackDirsPsr4,
168
+ (array) $paths
169
+ );
170
+ }
171
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
172
+ // Register directories for a new namespace.
173
+ $length = strlen($prefix);
174
+ if ('\\' !== $prefix[$length - 1]) {
175
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
176
+ }
177
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
178
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
179
+ } elseif ($prepend) {
180
+ // Prepend directories for an already registered namespace.
181
+ $this->prefixDirsPsr4[$prefix] = array_merge(
182
+ (array) $paths,
183
+ $this->prefixDirsPsr4[$prefix]
184
+ );
185
+ } else {
186
+ // Append directories for an already registered namespace.
187
+ $this->prefixDirsPsr4[$prefix] = array_merge(
188
+ $this->prefixDirsPsr4[$prefix],
189
+ (array) $paths
190
+ );
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Registers a set of PSR-0 directories for a given prefix,
196
+ * replacing any others previously set for this prefix.
197
+ *
198
+ * @param string $prefix The prefix
199
+ * @param array|string $paths The PSR-0 base directories
200
+ */
201
+ public function set($prefix, $paths)
202
+ {
203
+ if (!$prefix) {
204
+ $this->fallbackDirsPsr0 = (array) $paths;
205
+ } else {
206
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Registers a set of PSR-4 directories for a given namespace,
212
+ * replacing any others previously set for this namespace.
213
+ *
214
+ * @param string $prefix The prefix/namespace, with trailing '\\'
215
+ * @param array|string $paths The PSR-4 base directories
216
+ *
217
+ * @throws \InvalidArgumentException
218
+ */
219
+ public function setPsr4($prefix, $paths)
220
+ {
221
+ if (!$prefix) {
222
+ $this->fallbackDirsPsr4 = (array) $paths;
223
+ } else {
224
+ $length = strlen($prefix);
225
+ if ('\\' !== $prefix[$length - 1]) {
226
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
227
+ }
228
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
229
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Turns on searching the include path for class files.
235
+ *
236
+ * @param bool $useIncludePath
237
+ */
238
+ public function setUseIncludePath($useIncludePath)
239
+ {
240
+ $this->useIncludePath = $useIncludePath;
241
+ }
242
+
243
+ /**
244
+ * Can be used to check if the autoloader uses the include path to check
245
+ * for classes.
246
+ *
247
+ * @return bool
248
+ */
249
+ public function getUseIncludePath()
250
+ {
251
+ return $this->useIncludePath;
252
+ }
253
+
254
+ /**
255
+ * Turns off searching the prefix and fallback directories for classes
256
+ * that have not been registered with the class map.
257
+ *
258
+ * @param bool $classMapAuthoritative
259
+ */
260
+ public function setClassMapAuthoritative($classMapAuthoritative)
261
+ {
262
+ $this->classMapAuthoritative = $classMapAuthoritative;
263
+ }
264
+
265
+ /**
266
+ * Should class lookup fail if not found in the current class map?
267
+ *
268
+ * @return bool
269
+ */
270
+ public function isClassMapAuthoritative()
271
+ {
272
+ return $this->classMapAuthoritative;
273
+ }
274
+
275
+ /**
276
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
+ *
278
+ * @param string|null $apcuPrefix
279
+ */
280
+ public function setApcuPrefix($apcuPrefix)
281
+ {
282
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283
+ }
284
+
285
+ /**
286
+ * The APCu prefix in use, or null if APCu caching is not enabled.
287
+ *
288
+ * @return string|null
289
+ */
290
+ public function getApcuPrefix()
291
+ {
292
+ return $this->apcuPrefix;
293
+ }
294
+
295
+ /**
296
+ * Registers this instance as an autoloader.
297
+ *
298
+ * @param bool $prepend Whether to prepend the autoloader or not
299
+ */
300
+ public function register($prepend = false)
301
+ {
302
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
303
+ }
304
+
305
+ /**
306
+ * Unregisters this instance as an autoloader.
307
+ */
308
+ public function unregister()
309
+ {
310
+ spl_autoload_unregister(array($this, 'loadClass'));
311
+ }
312
+
313
+ /**
314
+ * Loads the given class or interface.
315
+ *
316
+ * @param string $class The name of the class
317
+ * @return bool|null True if loaded, null otherwise
318
+ */
319
+ public function loadClass($class)
320
+ {
321
+ if ($file = $this->findFile($class)) {
322
+ includeFile($file);
323
+
324
+ return true;
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Finds the path to the file where the class is defined.
330
+ *
331
+ * @param string $class The name of the class
332
+ *
333
+ * @return string|false The path if found, false otherwise
334
+ */
335
+ public function findFile($class)
336
+ {
337
+ // class map lookup
338
+ if (isset($this->classMap[$class])) {
339
+ return $this->classMap[$class];
340
+ }
341
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342
+ return false;
343
+ }
344
+ if (null !== $this->apcuPrefix) {
345
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346
+ if ($hit) {
347
+ return $file;
348
+ }
349
+ }
350
+
351
+ $file = $this->findFileWithExtension($class, '.php');
352
+
353
+ // Search for Hack files if we are running on HHVM
354
+ if (false === $file && defined('HHVM_VERSION')) {
355
+ $file = $this->findFileWithExtension($class, '.hh');
356
+ }
357
+
358
+ if (null !== $this->apcuPrefix) {
359
+ apcu_add($this->apcuPrefix.$class, $file);
360
+ }
361
+
362
+ if (false === $file) {
363
+ // Remember that this class does not exist.
364
+ $this->missingClasses[$class] = true;
365
+ }
366
+
367
+ return $file;
368
+ }
369
+
370
+ private function findFileWithExtension($class, $ext)
371
+ {
372
+ // PSR-4 lookup
373
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
374
+
375
+ $first = $class[0];
376
+ if (isset($this->prefixLengthsPsr4[$first])) {
377
+ $subPath = $class;
378
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
379
+ $subPath = substr($subPath, 0, $lastPos);
380
+ $search = $subPath . '\\';
381
+ if (isset($this->prefixDirsPsr4[$search])) {
382
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
384
+ if (file_exists($file = $dir . $pathEnd)) {
385
+ return $file;
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+
392
+ // PSR-4 fallback dirs
393
+ foreach ($this->fallbackDirsPsr4 as $dir) {
394
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
395
+ return $file;
396
+ }
397
+ }
398
+
399
+ // PSR-0 lookup
400
+ if (false !== $pos = strrpos($class, '\\')) {
401
+ // namespaced class name
402
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
403
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
404
+ } else {
405
+ // PEAR-like class name
406
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
407
+ }
408
+
409
+ if (isset($this->prefixesPsr0[$first])) {
410
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
411
+ if (0 === strpos($class, $prefix)) {
412
+ foreach ($dirs as $dir) {
413
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
414
+ return $file;
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+
421
+ // PSR-0 fallback dirs
422
+ foreach ($this->fallbackDirsPsr0 as $dir) {
423
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
424
+ return $file;
425
+ }
426
+ }
427
+
428
+ // PSR-0 include paths.
429
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
430
+ return $file;
431
+ }
432
+
433
+ return false;
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Scope isolated include.
439
+ *
440
+ * Prevents access to $this/self from included files.
441
+ */
442
+ function includeFile($file)
443
+ {
444
+ include $file;
445
+ }
vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
vendor/composer/autoload_classmap_package.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // This file `autoload_classmap_packages.php` was auto generated by automattic/jetpack-autoloader.
4
+
5
+ $vendorDir = dirname(__DIR__);
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'VariableAnalysis\\Tests\\VariableAnalysisTest' => array(
10
+ 'version' => '2.6.4.0',
11
+ 'path' => $vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Tests/CodeAnalysis/VariableAnalysisTest.php'
12
+ ),
13
+ 'VariableAnalysis\\Tests\\BaseTestCase' => array(
14
+ 'version' => '2.6.4.0',
15
+ 'path' => $vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Tests/BaseTestCase.php'
16
+ ),
17
+ 'VariableAnalysis\\Lib\\VariableInfo' => array(
18
+ 'version' => '2.6.4.0',
19
+ 'path' => $vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Lib/VariableInfo.php'
20
+ ),
21
+ 'VariableAnalysis\\Lib\\Constants' => array(
22
+ 'version' => '2.6.4.0',
23
+ 'path' => $vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Lib/Constants.php'
24
+ ),
25
+ 'VariableAnalysis\\Lib\\ScopeInfo' => array(
26
+ 'version' => '2.6.4.0',
27
+ 'path' => $vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Lib/ScopeInfo.php'
28
+ ),
29
+ 'VariableAnalysis\\Lib\\Helpers' => array(
30
+ 'version' => '2.6.4.0',
31
+ 'path' => $vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Lib/Helpers.php'
32
+ ),
33
+ 'VariableAnalysis\\Sniffs\\CodeAnalysis\\VariableAnalysisSniff' => array(
34
+ 'version' => '2.6.4.0',
35
+ 'path' => $vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php'
36
+ ),
37
+ 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin' => array(
38
+ 'version' => '0.5.0.0',
39
+ 'path' => $vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src/Plugin.php'
40
+ ),
41
+ 'Automattic\\Jetpack\\Standards\\PostInstall' => array(
42
+ 'version' => '9999999-dev',
43
+ 'path' => $vendorDir . '/automattic/jetpack-standards/PostInstall.php'
44
+ ),
45
+ 'Automattic\\Jetpack\\Autoloader\\AutoloadGenerator' => array(
46
+ 'version' => '1.2.0.0',
47
+ 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/AutoloadGenerator.php'
48
+ ),
49
+ 'Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin' => array(
50
+ 'version' => '1.2.0.0',
51
+ 'path' => $vendorDir . '/automattic/jetpack-autoloader/src/CustomAutoloaderPlugin.php'
52
+ ),
53
+ 'Automattic\\Jetpack\\Assets\\Logo' => array(
54
+ 'version' => '1.1.0.0',
55
+ 'path' => $vendorDir . '/automattic/jetpack-logo/src/Logo.php'
56
+ ),
57
+ );
58
+
vendor/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'VariableAnalysis\\' => array($vendorDir . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis'),
10
+ 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'),
11
+ 'Automattic\\Jetpack\\Standards\\' => array($vendorDir . '/automattic/jetpack-standards'),
12
+ 'Automattic\\Jetpack\\Autoloader\\' => array($vendorDir . '/automattic/jetpack-autoloader/src'),
13
+ 'Automattic\\Jetpack\\Assets\\' => array($vendorDir . '/automattic/jetpack-logo/src'),
14
+ );
vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInit3a75cf5e3a8a600ae6ae79f2b0d1d6de
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ public static function getLoader()
17
+ {
18
+ if (null !== self::$loader) {
19
+ return self::$loader;
20
+ }
21
+
22
+ spl_autoload_register(array('ComposerAutoloaderInit3a75cf5e3a8a600ae6ae79f2b0d1d6de', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit3a75cf5e3a8a600ae6ae79f2b0d1d6de', 'loadClassLoader'));
25
+
26
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
+ if ($useStaticLoader) {
28
+ require_once __DIR__ . '/autoload_static.php';
29
+
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit3a75cf5e3a8a600ae6ae79f2b0d1d6de::getInitializer($loader));
31
+ } else {
32
+ $map = require __DIR__ . '/autoload_namespaces.php';
33
+ foreach ($map as $namespace => $path) {
34
+ $loader->set($namespace, $path);
35
+ }
36
+
37
+ $map = require __DIR__ . '/autoload_psr4.php';
38
+ foreach ($map as $namespace => $path) {
39
+ $loader->setPsr4($namespace, $path);
40
+ }
41
+
42
+ $classMap = require __DIR__ . '/autoload_classmap.php';
43
+ if ($classMap) {
44
+ $loader->addClassMap($classMap);
45
+ }
46
+ }
47
+
48
+ $loader->register(true);
49
+
50
+ return $loader;
51
+ }
52
+ }
vendor/composer/autoload_static.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
7
+ class ComposerStaticInit3a75cf5e3a8a600ae6ae79f2b0d1d6de
8
+ {
9
+ public static $prefixLengthsPsr4 = array (
10
+ 'V' =>
11
+ array (
12
+ 'VariableAnalysis\\' => 17,
13
+ ),
14
+ 'D' =>
15
+ array (
16
+ 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => 55,
17
+ ),
18
+ 'A' =>
19
+ array (
20
+ 'Automattic\\Jetpack\\Standards\\' => 29,
21
+ 'Automattic\\Jetpack\\Autoloader\\' => 30,
22
+ 'Automattic\\Jetpack\\Assets\\' => 26,
23
+ ),
24
+ );
25
+
26
+ public static $prefixDirsPsr4 = array (
27
+ 'VariableAnalysis\\' =>
28
+ array (
29
+ 0 => __DIR__ . '/..' . '/sirbrillig/phpcs-variable-analysis/VariableAnalysis',
30
+ ),
31
+ 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' =>
32
+ array (
33
+ 0 => __DIR__ . '/..' . '/dealerdirect/phpcodesniffer-composer-installer/src',
34
+ ),
35
+ 'Automattic\\Jetpack\\Standards\\' =>
36
+ array (
37
+ 0 => __DIR__ . '/..' . '/automattic/jetpack-standards',
38
+ ),
39
+ 'Automattic\\Jetpack\\Autoloader\\' =>
40
+ array (
41
+ 0 => __DIR__ . '/..' . '/automattic/jetpack-autoloader/src',
42
+ ),
43
+ 'Automattic\\Jetpack\\Assets\\' =>
44
+ array (
45
+ 0 => __DIR__ . '/..' . '/automattic/jetpack-logo/src',
46
+ ),
47
+ );
48
+
49
+ public static function getInitializer(ClassLoader $loader)
50
+ {
51
+ return \Closure::bind(function () use ($loader) {
52
+ $loader->prefixLengthsPsr4 = ComposerStaticInit3a75cf5e3a8a600ae6ae79f2b0d1d6de::$prefixLengthsPsr4;
53
+ $loader->prefixDirsPsr4 = ComposerStaticInit3a75cf5e3a8a600ae6ae79f2b0d1d6de::$prefixDirsPsr4;
54
+
55
+ }, null, ClassLoader::class);
56
+ }
57
+ }
vendor/composer/installed.json ADDED
@@ -0,0 +1,493 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "automattic/jetpack-autoloader",
4
+ "version": "v1.2.0",
5
+ "version_normalized": "1.2.0.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/Automattic/jetpack-autoloader.git",
9
+ "reference": "4ad9631e68e9da8b8a764615766287becfb27f81"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/4ad9631e68e9da8b8a764615766287becfb27f81",
14
+ "reference": "4ad9631e68e9da8b8a764615766287becfb27f81",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "composer-plugin-api": "^1.1"
19
+ },
20
+ "require-dev": {
21
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5"
22
+ },
23
+ "time": "2019-06-24T15:13:23+00:00",
24
+ "type": "composer-plugin",
25
+ "extra": {
26
+ "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin"
27
+ },
28
+ "installation-source": "dist",
29
+ "autoload": {
30
+ "psr-4": {
31
+ "Automattic\\Jetpack\\Autoloader\\": "src"
32
+ }
33
+ },
34
+ "notification-url": "https://packagist.org/downloads/",
35
+ "license": [
36
+ "GPL-2.0-or-later"
37
+ ],
38
+ "description": "Creates a custom autoloader for a plugin or theme."
39
+ },
40
+ {
41
+ "name": "automattic/jetpack-logo",
42
+ "version": "v1.1.0",
43
+ "version_normalized": "1.1.0.0",
44
+ "source": {
45
+ "type": "git",
46
+ "url": "https://github.com/Automattic/jetpack-logo.git",
47
+ "reference": "c02750b6af95d114ba08562a7df74bab98235fef"
48
+ },
49
+ "dist": {
50
+ "type": "zip",
51
+ "url": "https://api.github.com/repos/Automattic/jetpack-logo/zipball/c02750b6af95d114ba08562a7df74bab98235fef",
52
+ "reference": "c02750b6af95d114ba08562a7df74bab98235fef",
53
+ "shasum": ""
54
+ },
55
+ "require-dev": {
56
+ "php-mock/php-mock": "^2.1",
57
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5"
58
+ },
59
+ "time": "2019-06-10T21:57:07+00:00",
60
+ "type": "library",
61
+ "installation-source": "dist",
62
+ "autoload": {
63
+ "psr-4": {
64
+ "Automattic\\Jetpack\\Assets\\": "src/"
65
+ }
66
+ },
67
+ "notification-url": "https://packagist.org/downloads/",
68
+ "license": [
69
+ "GPL-2.0-or-later"
70
+ ],
71
+ "description": "A logo for Jetpack"
72
+ },
73
+ {
74
+ "name": "automattic/jetpack-standards",
75
+ "version": "dev-master",
76
+ "version_normalized": "9999999-dev",
77
+ "source": {
78
+ "type": "git",
79
+ "url": "https://github.com/Automattic/jetpack-standards.git",
80
+ "reference": "1453b5eafe67bc82d0361e4d76a113cbd11c8149"
81
+ },
82
+ "dist": {
83
+ "type": "zip",
84
+ "url": "https://api.github.com/repos/Automattic/jetpack-standards/zipball/1453b5eafe67bc82d0361e4d76a113cbd11c8149",
85
+ "reference": "1453b5eafe67bc82d0361e4d76a113cbd11c8149",
86
+ "shasum": ""
87
+ },
88
+ "require": {
89
+ "composer-plugin-api": "^1.1",
90
+ "dealerdirect/phpcodesniffer-composer-installer": "0.5.0",
91
+ "phpcompatibility/phpcompatibility-wp": "2.0.0",
92
+ "sirbrillig/phpcs-variable-analysis": "2.6.4",
93
+ "wp-coding-standards/wpcs": "2.1.1"
94
+ },
95
+ "time": "2019-05-21T18:08:46+00:00",
96
+ "type": "composer-plugin",
97
+ "extra": {
98
+ "class": "Automattic\\Jetpack\\Standards\\PostInstall"
99
+ },
100
+ "installation-source": "source",
101
+ "autoload": {
102
+ "psr-4": {
103
+ "Automattic\\Jetpack\\Standards\\": ""
104
+ }
105
+ },
106
+ "notification-url": "https://packagist.org/downloads/",
107
+ "license": [
108
+ "GPL-2.0-or-later"
109
+ ],
110
+ "description": "Adds basic Jetpack standards to a project."
111
+ },
112
+ {
113
+ "name": "dealerdirect/phpcodesniffer-composer-installer",
114
+ "version": "v0.5.0",
115
+ "version_normalized": "0.5.0.0",
116
+ "source": {
117
+ "type": "git",
118
+ "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
119
+ "reference": "e749410375ff6fb7a040a68878c656c2e610b132"
120
+ },
121
+ "dist": {
122
+ "type": "zip",
123
+ "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132",
124
+ "reference": "e749410375ff6fb7a040a68878c656c2e610b132",
125
+ "shasum": ""
126
+ },
127
+ "require": {
128
+ "composer-plugin-api": "^1.0",
129
+ "php": "^5.3|^7",
130
+ "squizlabs/php_codesniffer": "^2|^3"
131
+ },
132
+ "require-dev": {
133
+ "composer/composer": "*",
134
+ "phpcompatibility/php-compatibility": "^9.0",
135
+ "sensiolabs/security-checker": "^4.1.0"
136
+ },
137
+ "time": "2018-10-26T13:21:45+00:00",
138
+ "type": "composer-plugin",
139
+ "extra": {
140
+ "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
141
+ },
142
+ "installation-source": "dist",
143
+ "autoload": {
144
+ "psr-4": {
145
+ "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
146
+ }
147
+ },
148
+ "notification-url": "https://packagist.org/downloads/",
149
+ "license": [
150
+ "MIT"
151
+ ],
152
+ "authors": [
153
+ {
154
+ "name": "Franck Nijhof",
155
+ "email": "franck.nijhof@dealerdirect.com",
156
+ "homepage": "http://www.frenck.nl",
157
+ "role": "Developer / IT Manager"
158
+ }
159
+ ],
160
+ "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
161
+ "homepage": "http://www.dealerdirect.com",
162
+ "keywords": [
163
+ "PHPCodeSniffer",
164
+ "PHP_CodeSniffer",
165
+ "code quality",
166
+ "codesniffer",
167
+ "composer",
168
+ "installer",
169
+ "phpcs",
170
+ "plugin",
171
+ "qa",
172
+ "quality",
173
+ "standard",
174
+ "standards",
175
+ "style guide",
176
+ "stylecheck",
177
+ "tests"
178
+ ]
179
+ },
180
+ {
181
+ "name": "phpcompatibility/php-compatibility",
182
+ "version": "9.2.0",
183
+ "version_normalized": "9.2.0.0",
184
+ "source": {
185
+ "type": "git",
186
+ "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
187
+ "reference": "3db1bf1e28123fd574a4ae2e9a84072826d51b5e"
188
+ },
189
+ "dist": {
190
+ "type": "zip",
191
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/3db1bf1e28123fd574a4ae2e9a84072826d51b5e",
192
+ "reference": "3db1bf1e28123fd574a4ae2e9a84072826d51b5e",
193
+ "shasum": ""
194
+ },
195
+ "require": {
196
+ "php": ">=5.3",
197
+ "squizlabs/php_codesniffer": "^2.3 || ^3.0.2"
198
+ },
199
+ "conflict": {
200
+ "squizlabs/php_codesniffer": "2.6.2"
201
+ },
202
+ "require-dev": {
203
+ "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
204
+ },
205
+ "suggest": {
206
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
207
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
208
+ },
209
+ "time": "2019-06-27T19:58:56+00:00",
210
+ "type": "phpcodesniffer-standard",
211
+ "installation-source": "dist",
212
+ "notification-url": "https://packagist.org/downloads/",
213
+ "license": [
214
+ "LGPL-3.0-or-later"
215
+ ],
216
+ "authors": [
217
+ {
218
+ "name": "Contributors",
219
+ "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
220
+ },
221
+ {
222
+ "name": "Wim Godden",
223
+ "homepage": "https://github.com/wimg",
224
+ "role": "lead"
225
+ },
226
+ {
227
+ "name": "Juliette Reinders Folmer",
228
+ "homepage": "https://github.com/jrfnl",
229
+ "role": "lead"
230
+ }
231
+ ],
232
+ "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
233
+ "homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
234
+ "keywords": [
235
+ "compatibility",
236
+ "phpcs",
237
+ "standards"
238
+ ]
239
+ },
240
+ {
241
+ "name": "phpcompatibility/phpcompatibility-paragonie",
242
+ "version": "1.0.1",
243
+ "version_normalized": "1.0.1.0",
244
+ "source": {
245
+ "type": "git",
246
+ "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git",
247
+ "reference": "9160de79fcd683b5c99e9c4133728d91529753ea"
248
+ },
249
+ "dist": {
250
+ "type": "zip",
251
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/9160de79fcd683b5c99e9c4133728d91529753ea",
252
+ "reference": "9160de79fcd683b5c99e9c4133728d91529753ea",
253
+ "shasum": ""
254
+ },
255
+ "require": {
256
+ "phpcompatibility/php-compatibility": "^9.0"
257
+ },
258
+ "require-dev": {
259
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4"
260
+ },
261
+ "suggest": {
262
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
263
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
264
+ },
265
+ "time": "2018-12-16T19:10:44+00:00",
266
+ "type": "phpcodesniffer-standard",
267
+ "installation-source": "dist",
268
+ "notification-url": "https://packagist.org/downloads/",
269
+ "license": [
270
+ "LGPL-3.0-or-later"
271
+ ],
272
+ "authors": [
273
+ {
274
+ "name": "Wim Godden",
275
+ "role": "lead"
276
+ },
277
+ {
278
+ "name": "Juliette Reinders Folmer",
279
+ "role": "lead"
280
+ }
281
+ ],
282
+ "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.",
283
+ "homepage": "http://phpcompatibility.com/",
284
+ "keywords": [
285
+ "compatibility",
286
+ "paragonie",
287
+ "phpcs",
288
+ "polyfill",
289
+ "standards"
290
+ ]
291
+ },
292
+ {
293
+ "name": "phpcompatibility/phpcompatibility-wp",
294
+ "version": "2.0.0",
295
+ "version_normalized": "2.0.0.0",
296
+ "source": {
297
+ "type": "git",
298
+ "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git",
299
+ "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd"
300
+ },
301
+ "dist": {
302
+ "type": "zip",
303
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/cb303f0067cd5b366a41d4fb0e254fb40ff02efd",
304
+ "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd",
305
+ "shasum": ""
306
+ },
307
+ "require": {
308
+ "phpcompatibility/php-compatibility": "^9.0",
309
+ "phpcompatibility/phpcompatibility-paragonie": "^1.0"
310
+ },
311
+ "require-dev": {
312
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
313
+ },
314
+ "suggest": {
315
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
316
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
317
+ },
318
+ "time": "2018-10-07T18:31:37+00:00",
319
+ "type": "phpcodesniffer-standard",
320
+ "installation-source": "dist",
321
+ "notification-url": "https://packagist.org/downloads/",
322
+ "license": [
323
+ "LGPL-3.0-or-later"
324
+ ],
325
+ "authors": [
326
+ {
327
+ "name": "Wim Godden",
328
+ "role": "lead"
329
+ },
330
+ {
331
+ "name": "Juliette Reinders Folmer",
332
+ "role": "lead"
333
+ }
334
+ ],
335
+ "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.",
336
+ "homepage": "http://phpcompatibility.com/",
337
+ "keywords": [
338
+ "compatibility",
339
+ "phpcs",
340
+ "standards",
341
+ "wordpress"
342
+ ]
343
+ },
344
+ {
345
+ "name": "sirbrillig/phpcs-variable-analysis",
346
+ "version": "v2.6.4",
347
+ "version_normalized": "2.6.4.0",
348
+ "source": {
349
+ "type": "git",
350
+ "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git",
351
+ "reference": "fd217f2077fbcc287aded2b52147e68d208ace4b"
352
+ },
353
+ "dist": {
354
+ "type": "zip",
355
+ "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/fd217f2077fbcc287aded2b52147e68d208ace4b",
356
+ "reference": "fd217f2077fbcc287aded2b52147e68d208ace4b",
357
+ "shasum": ""
358
+ },
359
+ "require": {
360
+ "php": ">=5.6.0"
361
+ },
362
+ "require-dev": {
363
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
364
+ "limedeck/phpunit-detailed-printer": "^3.1",
365
+ "phpunit/phpunit": "^6.5",
366
+ "sirbrillig/phpcs-import-detection": "^1.1",
367
+ "squizlabs/php_codesniffer": "^3.1"
368
+ },
369
+ "time": "2019-05-10T21:08:30+00:00",
370
+ "type": "phpcodesniffer-standard",
371
+ "installation-source": "dist",
372
+ "autoload": {
373
+ "psr-4": {
374
+ "VariableAnalysis\\": "VariableAnalysis/"
375
+ }
376
+ },
377
+ "notification-url": "https://packagist.org/downloads/",
378
+ "license": [
379
+ "BSD-2-Clause"
380
+ ],
381
+ "authors": [
382
+ {
383
+ "name": "Payton Swick",
384
+ "email": "payton@foolord.com"
385
+ },
386
+ {
387
+ "name": "Sam Graham",
388
+ "email": "php-codesniffer-variableanalysis@illusori.co.uk"
389
+ }
390
+ ],
391
+ "description": "A PHPCS sniff to detect problems with variables."
392
+ },
393
+ {
394
+ "name": "squizlabs/php_codesniffer",
395
+ "version": "3.4.2",
396
+ "version_normalized": "3.4.2.0",
397
+ "source": {
398
+ "type": "git",
399
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
400
+ "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8"
401
+ },
402
+ "dist": {
403
+ "type": "zip",
404
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8",
405
+ "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8",
406
+ "shasum": ""
407
+ },
408
+ "require": {
409
+ "ext-simplexml": "*",
410
+ "ext-tokenizer": "*",
411
+ "ext-xmlwriter": "*",
412
+ "php": ">=5.4.0"
413
+ },
414
+ "require-dev": {
415
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
416
+ },
417
+ "time": "2019-04-10T23:49:02+00:00",
418
+ "bin": [
419
+ "bin/phpcs",
420
+ "bin/phpcbf"
421
+ ],
422
+ "type": "library",
423
+ "extra": {
424
+ "branch-alias": {
425
+ "dev-master": "3.x-dev"
426
+ }
427
+ },
428
+ "installation-source": "dist",
429
+ "notification-url": "https://packagist.org/downloads/",
430
+ "license": [
431
+ "BSD-3-Clause"
432
+ ],
433
+ "authors": [
434
+ {
435
+ "name": "Greg Sherwood",
436
+ "role": "lead"
437
+ }
438
+ ],
439
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
440
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
441
+ "keywords": [
442
+ "phpcs",
443
+ "standards"
444
+ ]
445
+ },
446
+ {
447
+ "name": "wp-coding-standards/wpcs",
448
+ "version": "2.1.1",
449
+ "version_normalized": "2.1.1.0",
450
+ "source": {
451
+ "type": "git",
452
+ "url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
453
+ "reference": "bd9c33152115e6741e3510ff7189605b35167908"
454
+ },
455
+ "dist": {
456
+ "type": "zip",
457
+ "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/bd9c33152115e6741e3510ff7189605b35167908",
458
+ "reference": "bd9c33152115e6741e3510ff7189605b35167908",
459
+ "shasum": ""
460
+ },
461
+ "require": {
462
+ "php": ">=5.4",
463
+ "squizlabs/php_codesniffer": "^3.3.1"
464
+ },
465
+ "require-dev": {
466
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
467
+ "phpcompatibility/php-compatibility": "^9.0",
468
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
469
+ },
470
+ "suggest": {
471
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
472
+ },
473
+ "time": "2019-05-21T02:50:00+00:00",
474
+ "type": "phpcodesniffer-standard",
475
+ "installation-source": "dist",
476
+ "notification-url": "https://packagist.org/downloads/",
477
+ "license": [
478
+ "MIT"
479
+ ],
480
+ "authors": [
481
+ {
482
+ "name": "Contributors",
483
+ "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors"
484
+ }
485
+ ],
486
+ "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
487
+ "keywords": [
488
+ "phpcs",
489
+ "standards",
490
+ "wordpress"
491
+ ]
492
+ }
493
+ ]