Version Description
= v140816 =
(Maintenance Release) Upgrade immediately.
Download this release
Release Info
Developer | JasWSInc |
Plugin | ![]() |
Version | 140816 |
Comparing to | |
See all releases |
Code changes from version 140725 to 140816
- checksum.txt +1 -1
- includes/classes/access-cap-times.inc.php +1 -1
- includes/classes/auto-eots.inc.php +1 -0
- includes/classes/files-in.inc.php +1308 -1276
- includes/classes/ip-restrictions.inc.php +7 -8
- includes/classes/list-servers.inc.php +32 -0
- includes/classes/login-customizations.inc.php +4 -3
- includes/classes/login-redirects.inc.php +198 -184
- includes/classes/menu-pages.inc.php +677 -732
- includes/classes/mo-page.inc.php +1 -1
- includes/classes/pages-sp.inc.php +96 -104
- includes/classes/pages.inc.php +94 -103
- includes/classes/paypal-return-in-subscr-modify-w-level.inc.php +4 -4
- includes/classes/paypal-return-in-subscr-or-wa-w-level.inc.php +379 -374
- includes/classes/paypal-return-in-wa-ccaps-wo-level.inc.php +4 -4
- includes/classes/paypal-return-in-web-accept-sp.inc.php +4 -4
- includes/classes/posts-sp.inc.php +122 -107
- includes/classes/posts.inc.php +119 -107
- includes/classes/querys.inc.php +378 -372
- includes/classes/registration-times.inc.php +1 -1
- includes/classes/return-templates.inc.php +65 -69
- includes/classes/roles-caps.inc.php +155 -155
- includes/classes/ruris.inc.php +94 -95
- includes/classes/sc-files-in.inc.php +311 -143
- includes/classes/utils-arrays.inc.php +1 -1
- includes/classes/utils-conds.inc.php +29 -0
- includes/classes/utils-gets.inc.php +391 -333
- includes/classes/utils-users.inc.php +3 -11
- includes/functions/class-autoloader.inc.php +75 -76
- includes/menu-pages/down-ops.inc.php +656 -649
- includes/menu-pages/gen-ops.inc.php +8 -1
- includes/menu-pages/integrations.inc.php +72 -74
- includes/menu-pages/menu-pages-s-min.js +1 -1
- includes/menu-pages/menu-pages-s.js +20 -19
- includes/menu-pages/res-ops.inc.php +1 -1
- includes/templates/players/jwplayer-v6-rtmp-only.php +1 -4
- includes/templates/players/jwplayer-v6-rtmp.php +1 -5
- includes/templates/players/jwplayer-v6.php +1 -4
- includes/translations/s2member.pot +1905 -1907
- readme.txt +33 -4
- s2member.php +4 -4
checksum.txt
CHANGED
@@ -1 +1 @@
|
|
1 |
-
|
1 |
+
fe5b4d8fea0ad64e6be257a6b6bba04c
|
includes/classes/access-cap-times.inc.php
CHANGED
@@ -211,7 +211,7 @@ if(!class_exists('c_ws_plugin__s2member_access_cap_times'))
|
|
211 |
|
212 |
// $update_ac_times = empty($ac_times) ? FALSE : TRUE;
|
213 |
$ac_times_min = !empty($ac_times) ? min(array_keys($ac_times)) : 0;
|
214 |
-
if(($r_time = c_ws_plugin__s2member_registration_times::registration_time
|
215 |
$ac_times[number_format(($r_time += .0001), 4, '.', '')] = 'level0';
|
216 |
|
217 |
if(is_array($pr_times = get_user_option('s2member_paid_registration_times', $user_id)))
|
211 |
|
212 |
// $update_ac_times = empty($ac_times) ? FALSE : TRUE;
|
213 |
$ac_times_min = !empty($ac_times) ? min(array_keys($ac_times)) : 0;
|
214 |
+
if(($r_time = c_ws_plugin__s2member_registration_times::registration_time($user_id)) && (empty($ac_times_min) || $r_time < $ac_times_min))
|
215 |
$ac_times[number_format(($r_time += .0001), 4, '.', '')] = 'level0';
|
216 |
|
217 |
if(is_array($pr_times = get_user_option('s2member_paid_registration_times', $user_id)))
|
includes/classes/auto-eots.inc.php
CHANGED
@@ -169,6 +169,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
|
|
169 |
delete_user_option ($user_id, "s2member_auto_eot_time");
|
170 |
|
171 |
delete_user_option ($user_id, "s2member_file_download_access_log");
|
|
|
172 |
|
173 |
c_ws_plugin__s2member_user_notes::append_user_notes ($user_id, "Demoted by s2Member: " . date ("D M j, Y g:i a T"));
|
174 |
|
169 |
delete_user_option ($user_id, "s2member_auto_eot_time");
|
170 |
|
171 |
delete_user_option ($user_id, "s2member_file_download_access_log");
|
172 |
+
delete_user_option ($user_id, "s2member_authnet_payment_failures");
|
173 |
|
174 |
c_ws_plugin__s2member_user_notes::append_user_notes ($user_id, "Demoted by s2Member: " . date ("D M j, Y g:i a T"));
|
175 |
|
includes/classes/files-in.inc.php
CHANGED
@@ -1,1411 +1,1443 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* File Download routines for s2Member (inner processing routines).
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Files
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if(realpath(__FILE__) === realpath($_SERVER
|
18 |
-
exit
|
19 |
-
|
20 |
-
if(!class_exists
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
{
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
$_g = !empty($_GET) ? $_GET : array();
|
51 |
-
$_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_g));
|
52 |
-
|
53 |
-
$creating = /* Creating URL? */ (is_array($create = $create_file_download_url)) ? true : false;
|
54 |
-
$serving = /* If NOT creating a File Download URL, we're serving one. */ (!$creating) ? true : false;
|
55 |
-
$serving_range = $range = /* Default values (so these variables DO get defined at all times). */ false;
|
56 |
-
if /* If we're serving, let's see if we're serving a byte-range request here. */($serving)
|
57 |
{
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
if(is_string($_header) && strcasecmp($_header, "range") === 0)
|
63 |
-
$range = $_value;
|
64 |
-
if /* Serving a range? */($range)
|
65 |
-
$serving_range = true;
|
66 |
-
unset($_header, $_value);
|
67 |
}
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
-
|
86 |
-
|
|
|
87 |
{
|
88 |
-
|
89 |
-
|
90 |
-
$using_amazon_storage = /* Either? */ ($using_amazon_cf_storage || $using_amazon_s3_storage) ? true : false;
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
$updating_user_counter = ($serving_range || !$checking_user || ($creating && (!isset($req["count_against_user"]) || !filter_var($req["count_against_user"], FILTER_VALIDATE_BOOLEAN)))) ? false : true;
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
status_header(404);
|
105 |
-
header("Content-Type: text/html; charset=UTF-8");
|
106 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
107 |
-
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
|
108 |
-
}
|
109 |
-
else // Else return false.
|
110 |
-
return false;
|
111 |
-
}
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
120 |
-
exit(_x('<strong>503 (Invalid Key):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', "s2member-front", "s2member"));
|
121 |
-
}
|
122 |
-
else // Else return false.
|
123 |
-
return false;
|
124 |
-
}
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
|
132 |
-
|
133 |
-
|
134 |
-
remove_filter("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
139 |
-
{
|
140 |
-
status_header(503);
|
141 |
-
header("Content-Type: text/html; charset=UTF-8");
|
142 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
143 |
-
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› General Options -› Membership Options Page</code>.', "s2member-front", "s2member"));
|
144 |
-
}
|
145 |
-
else // Else return false.
|
146 |
-
return false;
|
147 |
-
}
|
148 |
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
header("Content-Type: text/html; charset=UTF-8");
|
155 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
156 |
-
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› Download Options -› Basic Download Restrictions</code>.', "s2member-front", "s2member"));
|
157 |
-
}
|
158 |
-
else // Else return false.
|
159 |
-
return false;
|
160 |
-
}
|
161 |
-
|
162 |
-
else if(!is_object($user = apply_filters("ws_plugin__s2member_check_file_download_access_user", ((is_user_logged_in()) ? wp_get_current_user() : false), get_defined_vars())) || empty($user->ID) || !($user_id = $user->ID) || !is_array($user_file_downloads = c_ws_plugin__s2member_files::user_downloads($user)) || (!$user->has_cap("administrator") && (!$user_file_downloads["allowed"] || !$user_file_downloads["allowed_days"])))
|
163 |
-
{
|
164 |
-
if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//", $req["file_download"], $m) && strlen($req_level = $m[1]) && (!is_object($user) || empty($user->ID) || !$user->has_cap("access_s2member_level".$req_level)))
|
165 |
-
{
|
166 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
167 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "level", $req_level, $_SERVER["REQUEST_URI"]).exit();
|
168 |
-
|
169 |
-
else // Else return false.
|
170 |
-
return false;
|
171 |
-
}
|
172 |
-
|
173 |
-
else if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//", $req["file_download"], $m) && strlen($req_ccap = preg_replace("/-/", "_", $m[1])) && (!is_object($user) || empty($user->ID) || !$user->has_cap("access_s2member_ccap_".$req_ccap)))
|
174 |
-
{
|
175 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
176 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "ccap", $req_ccap, $_SERVER["REQUEST_URI"]).exit();
|
177 |
-
|
178 |
-
else // Else return false.
|
179 |
-
return false;
|
180 |
-
}
|
181 |
-
|
182 |
-
else if /* We only need this section when/if we're actually serving. */($serving)
|
183 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "level", $min_level_4_downloads, $_SERVER["REQUEST_URI"]).exit();
|
184 |
-
|
185 |
-
else // Else return false.
|
186 |
-
return false;
|
187 |
-
}
|
188 |
-
|
189 |
-
else if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//", $req["file_download"], $m) && strlen($req_level = $m[1]) && !$user->has_cap("access_s2member_level".$req_level))
|
190 |
-
{
|
191 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
192 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "level", $req_level, $_SERVER["REQUEST_URI"]).exit();
|
193 |
-
|
194 |
-
else // Else return false.
|
195 |
-
return false;
|
196 |
-
}
|
197 |
-
|
198 |
-
else if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//", $req["file_download"], $m) && strlen($req_ccap = preg_replace("/-/", "_", $m[1])) && !$user->has_cap("access_s2member_ccap_".$req_ccap))
|
199 |
-
{
|
200 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
201 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "ccap", $req_ccap, $_SERVER["REQUEST_URI"]).exit();
|
202 |
-
|
203 |
-
else // Else return false.
|
204 |
-
return false;
|
205 |
-
}
|
206 |
-
|
207 |
-
else if /* In either case, the following routines apply. */($serving || $creating)
|
208 |
-
{
|
209 |
-
$user_previous_file_downloads = /* Downloads the User has already; in current period/cycle. */ 0;
|
210 |
-
$user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = false;
|
211 |
-
|
212 |
-
$user_file_download_access_log = (is_array($user_file_download_access_log = get_user_option("s2member_file_download_access_log", $user_id))) ? $user_file_download_access_log : array();
|
213 |
-
$user_file_download_access_arc = (is_array($user_file_download_access_arc = get_user_option("s2member_file_download_access_arc", $user_id))) ? $user_file_download_access_arc : array();
|
214 |
-
|
215 |
-
$streaming_file_extns = c_ws_plugin__s2member_utils_strings::preg_quote_deep($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["streaming_file_extns"], "/");
|
216 |
-
$streaming_variations = /* Only count one streaming media file variation. */ "/\.(".implode("|", $streaming_file_extns).")#x2F;i";
|
217 |
-
|
218 |
-
foreach($user_file_download_access_log as $user_file_download_access_log_entry_key => $user_file_download_access_log_entry)
|
219 |
-
{
|
220 |
-
if( /* Weed out corrupt/empty log entries. */isset($user_file_download_access_log_entry["date"], $user_file_download_access_log_entry["file"]))
|
221 |
-
{
|
222 |
-
if(strtotime($user_file_download_access_log_entry["date"]) < strtotime("-".$user_file_downloads["allowed_days"]." days"))
|
223 |
-
{
|
224 |
-
unset /* Remove it from the `log`. */($user_file_download_access_log[$user_file_download_access_log_entry_key]);
|
225 |
-
$user_file_download_access_arc[] = /* Move `log` entry to the `archive` now. */ $user_file_download_access_log_entry;
|
226 |
-
}
|
227 |
-
else if(strtotime($user_file_download_access_log_entry["date"]) >= strtotime("-".$user_file_downloads["allowed_days"]." days"))
|
228 |
-
{
|
229 |
-
$user_previous_file_downloads++; // Previous files always count against this User/Member.
|
230 |
-
|
231 |
-
$_user_file_download_access_log_entry = &$user_file_download_access_log[$user_file_download_access_log_entry_key];
|
232 |
-
$_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = false;
|
233 |
-
|
234 |
-
if /* Already downloaded this file? If yes, mark this flag as true. */($user_file_download_access_log_entry["file"] === $req["file_download"])
|
235 |
-
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = /* Already downloaded this file? If yes, mark as true. */ true;
|
236 |
-
|
237 |
-
else if(preg_replace($streaming_variations, "", $user_file_download_access_log_entry["file"]) === preg_replace($streaming_variations, "", $req["file_download"]))
|
238 |
-
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = true;
|
239 |
-
|
240 |
-
if( /* Updating counter? */$updating_user_counter && ($_user_already_downloaded_this_file || $_user_already_downloaded_a_streaming_variation_of_this_file))
|
241 |
-
{
|
242 |
-
$_user_file_download_access_log_entry /* First, we update the last download time for this file. */["ltime"] = time();
|
243 |
-
|
244 |
-
if( /* Backward compatibility here. Is this even set? */!empty($user_file_download_access_log_entry["counter"]))
|
245 |
-
$_user_file_download_access_log_entry["counter"] = (int)$user_file_download_access_log_entry["counter"] + 1;
|
246 |
-
else // Backward compatibility here. Default value to `1`, if this is NOT even set yet.
|
247 |
-
$_user_file_download_access_log_entry["counter"] = 1 + 1;
|
248 |
-
}
|
249 |
-
}
|
250 |
-
}
|
251 |
-
else // Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries.
|
252 |
-
unset /* Remove. */($user_file_download_access_log[$user_file_download_access_log_entry_key]);
|
253 |
-
}
|
254 |
-
if( /* Updating counter? */$updating_user_counter && /* Do we need a new log entry for this file? */ !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file)
|
255 |
-
$user_file_download_access_log[] = array("date" => date("Y-m-d"), "time" => time(), "ltime" => time(), "file" => $req["file_download"], "counter" => 1);
|
256 |
-
|
257 |
-
if($user_previous_file_downloads >= $user_file_downloads["allowed"] && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file && !$user->has_cap("administrator"))
|
258 |
-
{
|
259 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
260 |
-
wp_redirect(add_query_arg(urlencode_deep(array("_s2member_seeking" => array("type" => "file", "file" => $req["file_download"], "_uri" => base64_encode($_SERVER["REQUEST_URI"])), "s2member_seeking" => "file-".$req["file_download"])), get_page_link($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"])), apply_filters("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars())).exit();
|
261 |
-
|
262 |
-
else // Else return false.
|
263 |
-
return false;
|
264 |
-
}
|
265 |
-
else if /* Save/update counter? By default, we do NOT update the counter when a URL is simply being created for access. */($updating_user_counter)
|
266 |
-
update_user_option($user_id, "s2member_file_download_access_log", c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_log)).update_user_option($user_id, "s2member_file_download_access_arc", c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_arc));
|
267 |
-
}
|
268 |
-
}
|
269 |
-
}
|
270 |
-
else // Otherwise, we're either NOT ``$checking_user``; or permission was granted with a valid File Download Key.
|
271 |
{
|
272 |
-
|
273 |
-
|
274 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
275 |
-
{
|
276 |
-
status_header(404);
|
277 |
-
header("Content-Type: text/html; charset=UTF-8");
|
278 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
279 |
-
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
|
280 |
-
}
|
281 |
-
else // Else return false.
|
282 |
-
return false;
|
283 |
-
}
|
284 |
}
|
285 |
-
|
286 |
-
if /* In either case, the following routines apply. */($serving || $creating)
|
287 |
{
|
288 |
-
$
|
289 |
-
$mimetypes = parse_ini_file(dirname(dirname(dirname(__FILE__)))."/includes/mime-types.ini");
|
290 |
-
$extension = strtolower(substr($req["file_download"], strrpos($req["file_download"], ".") + 1));
|
291 |
|
292 |
-
$
|
|
|
293 |
|
294 |
-
|
295 |
-
|
296 |
-
$ssl = (isset($req["file_ssl"])) ? filter_var($req["file_ssl"], FILTER_VALIDATE_BOOLEAN) : ((is_ssl()) ? true : false);
|
297 |
-
$storage = ($req["file_storage"] && is_string($req["file_storage"])) ? strtolower($req["file_storage"]) : false;
|
298 |
-
$remote = (isset($req["file_remote"])) ? filter_var($req["file_remote"], FILTER_VALIDATE_BOOLEAN) : false;
|
299 |
|
300 |
-
$
|
301 |
-
|
302 |
-
$rewrite_base = ($req["file_rewrite_base"] && is_string($req["file_rewrite_base"])) ? $req["file_rewrite_base"] : false;
|
303 |
-
$rewrite = $rewriting = (!$rewrite_base && isset($req["file_rewrite"])) ? filter_var($req["file_rewrite"], FILTER_VALIDATE_BOOLEAN) : (($rewrite_base) ? true : false);
|
304 |
-
unset /* A little housekeeping here. */($_basename_dir_app_data);
|
305 |
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
$pathinfo = (!$using_amazon_storage) ? pathinfo(($file = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"]."/".$req["file_download"])) : array();
|
310 |
-
$mimetype = ($mimetypes[$extension]) ? $mimetypes[$extension] : "application/octet-stream";
|
311 |
-
$disposition = (($inline) ? "inline" : "attachment")."; filename=\"".c_ws_plugin__s2member_utils_strings::esc_dq($basename)."\"; filename*=UTF-8''".rawurlencode($basename);
|
312 |
-
$length = (!$using_amazon_storage && $file) ? filesize($file) : -1;
|
313 |
-
|
314 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
|
315 |
-
do_action("ws_plugin__s2member_during_file_download_access", get_defined_vars());
|
316 |
-
unset($__refs, $__v);
|
317 |
-
|
318 |
-
if($using_amazon_storage && $using_amazon_cf_storage && ($serving || ($creating && $url_to_storage_source)))
|
319 |
-
{
|
320 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
321 |
-
wp_redirect(c_ws_plugin__s2member_files_in::amazon_cf_url($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)).exit();
|
322 |
|
323 |
-
|
324 |
-
|
325 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
|
332 |
-
|
333 |
-
|
334 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
|
336 |
-
|
337 |
-
|
338 |
-
$_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : "";
|
339 |
-
$_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : "";
|
340 |
-
$_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req["file_download"]));
|
341 |
-
$_url_e_file = str_ireplace("%2F", "/", $_url_e_file);
|
342 |
-
|
343 |
-
$url = ($rewrite_base) ? rtrim($rewrite_base, "/") : rtrim($rewrite_base_guess, "/");
|
344 |
-
$url .= (isset($req["file_download_key"])) ? (($key && $_url_e_key) ? "/s2member-file-download-key-".$_url_e_key : "") : "";
|
345 |
-
$url .= (isset($req["file_stream"])) ? (($stream) ? "/s2member-file-stream" : "/s2member-file-stream-no") : "";
|
346 |
-
$url .= (isset($req["file_inline"])) ? (($inline) ? "/s2member-file-inline" : "/s2member-file-inline-no") : "";
|
347 |
-
$url .= (isset($req["file_storage"])) ? (($storage && $_url_e_storage) ? "/s2member-file-storage-".$_url_e_storage : "") : "";
|
348 |
-
$url .= (isset($req["file_remote"])) ? (($remote) ? "/s2member-file-remote" : "/s2member-file-remote-no") : "";
|
349 |
-
$url .= (isset($req["skip_confirmation"])) ? (($skip_confirmation) ? "/s2member-skip-confirmation" : "/s2member-skip-confirmation-no") : "";
|
350 |
-
|
351 |
-
$url = /* File Download Access URL via `mod_rewrite` functionality. */ $url."/".$_url_e_file;
|
352 |
-
$url = ($ssl) ? preg_replace("/^https?/", "https", $url) : preg_replace("/^https?/", "http", $url);
|
353 |
-
|
354 |
-
return apply_filters("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars());
|
355 |
-
}
|
356 |
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
|
371 |
-
|
372 |
-
|
373 |
|
374 |
-
|
375 |
-
|
376 |
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
@ini_set("zlib.output_compression", 0);
|
382 |
-
if(function_exists("apache_setenv"))
|
383 |
-
@apache_setenv("no-gzip", "1");
|
384 |
-
|
385 |
-
$content_encoding_header = "Content-Encoding:"; // Default value; standards compliant.
|
386 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_content_encodong_none"])
|
387 |
-
$content_encoding_header = "Content-Encoding: none";
|
388 |
-
|
389 |
-
while /* Cleans existing output buffers. */(@ob_end_clean());
|
390 |
-
|
391 |
-
if /* Requesting a specific byte range? */($range)
|
392 |
-
{
|
393 |
-
if /* Invalid range? */(strpos($range, "=") === FALSE)
|
394 |
-
{
|
395 |
-
status_header(416);
|
396 |
-
nocache_headers();
|
397 |
-
header($content_encoding_header);
|
398 |
-
header("Accept-Ranges: bytes");
|
399 |
-
header("Content-Type: ".$mimetype);
|
400 |
-
header("Content-Length: ".$length);
|
401 |
-
header("Content-Disposition: ".$disposition);
|
402 |
-
exit /* Stop here (invalid). */();
|
403 |
-
}
|
404 |
-
list($range_type, $byte_range) = preg_split("/\s*\=\s*/", $range, 2);
|
405 |
-
|
406 |
-
$range_type = strtolower(trim($range_type));
|
407 |
-
$byte_range = trim($byte_range);
|
408 |
-
|
409 |
-
if /* Invalid range type? */($range_type !== "bytes")
|
410 |
-
{
|
411 |
-
status_header(416);
|
412 |
-
nocache_headers();
|
413 |
-
header($content_encoding_header);
|
414 |
-
header("Accept-Ranges: bytes");
|
415 |
-
header("Content-Type: ".$mimetype);
|
416 |
-
header("Content-Length: ".$length);
|
417 |
-
header("Content-Disposition: ".$disposition);
|
418 |
-
exit /* Stop here (invalid). */();
|
419 |
-
}
|
420 |
-
$byte_ranges = preg_split("/\s*,\s*/", $byte_range);
|
421 |
-
|
422 |
-
if /* Invalid byte range? */(strpos($byte_ranges[0], "-") === FALSE)
|
423 |
-
{
|
424 |
-
status_header(416);
|
425 |
-
nocache_headers();
|
426 |
-
header($content_encoding_header);
|
427 |
-
header("Accept-Ranges: bytes");
|
428 |
-
header("Content-Type: ".$mimetype);
|
429 |
-
header("Content-Length: ".$length);
|
430 |
-
header("Content-Disposition: ".$disposition);
|
431 |
-
exit /* Stop here (invalid). */();
|
432 |
-
}
|
433 |
-
|
434 |
-
// Only dealing with the first byte range. Others are simply ignored here.
|
435 |
-
list($byte_range_start, $byte_range_stops) = preg_split("/\s*\-\s*/", $byte_ranges[0], 2);
|
436 |
-
|
437 |
-
$byte_range_start = trim($byte_range_start);
|
438 |
-
$byte_range_stops = trim($byte_range_stops);
|
439 |
-
|
440 |
-
$byte_range_start = ($byte_range_start === "") ? NULL : (integer)$byte_range_start;
|
441 |
-
$byte_range_stops = ($byte_range_stops === "") ? NULL : (integer)$byte_range_stops;
|
442 |
-
|
443 |
-
if(!isset($byte_range_start) && $byte_range_stops > 0 && $byte_range_stops <= $length)
|
444 |
-
{
|
445 |
-
$byte_range_start = $length - $byte_range_stops;
|
446 |
-
$byte_range_stops = /* The last X number of bytes. */ $length - 1;
|
447 |
-
}
|
448 |
-
else if(!isset($byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1)
|
449 |
-
{
|
450 |
-
$byte_range_stops = /* To the end of the file in this case. */ $length - 1;
|
451 |
-
}
|
452 |
-
else if(isset($byte_range_start, $byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1 && $byte_range_stops > $byte_range_start && $byte_range_stops <= $length - 1) {
|
453 |
-
// Nothing to do in this case, starts/stops already defined properly.
|
454 |
-
}
|
455 |
-
else // We have an invalid byte range.
|
456 |
-
{
|
457 |
-
status_header(416);
|
458 |
-
nocache_headers();
|
459 |
-
header($content_encoding_header);
|
460 |
-
header("Accept-Ranges: bytes");
|
461 |
-
header("Content-Type: ".$mimetype);
|
462 |
-
header("Content-Length: ".$length);
|
463 |
-
header("Content-Disposition: ".$disposition);
|
464 |
-
exit /* Stop here (invalid). */();
|
465 |
-
}
|
466 |
-
// Range.
|
467 |
-
status_header(206);
|
468 |
-
nocache_headers();
|
469 |
-
header($content_encoding_header);
|
470 |
-
header("Accept-Ranges: bytes");
|
471 |
-
header("Content-Type: ".$mimetype);
|
472 |
-
header("Content-Range: bytes ".$byte_range_start."-".$byte_range_stops."/".$length);
|
473 |
-
$byte_range_size = $byte_range_stops - $byte_range_start + 1;
|
474 |
-
header("Content-Length: ".$byte_range_size);
|
475 |
-
header("Content-Disposition: ".$disposition);
|
476 |
-
}
|
477 |
-
else // A normal request (NOT a specific byte range).
|
478 |
-
{
|
479 |
-
status_header(200);
|
480 |
-
nocache_headers();
|
481 |
-
header($content_encoding_header);
|
482 |
-
header("Accept-Ranges: bytes");
|
483 |
-
header("Content-Type: ".$mimetype);
|
484 |
-
header("Content-Length: ".$length);
|
485 |
-
header("Content-Disposition: ".$disposition);
|
486 |
-
}
|
487 |
-
if(is_resource($resource = fopen($file, "rb")))
|
488 |
-
{
|
489 |
-
if($range)
|
490 |
-
{
|
491 |
-
$_bytes_to_read = $byte_range_size;
|
492 |
-
fseek($resource, $byte_range_start);
|
493 |
-
}
|
494 |
-
else // Entire file.
|
495 |
-
$_bytes_to_read = $length;
|
496 |
-
|
497 |
-
$chunk_size = apply_filters("ws_plugin__s2member_file_downloads_chunk_size", 2097152, get_defined_vars());
|
498 |
-
|
499 |
-
while /* We have bytes to read here. */($_bytes_to_read)
|
500 |
-
{
|
501 |
-
$_bytes_to_read -= ($_reading = ($_bytes_to_read > $chunk_size) ? $chunk_size : $_bytes_to_read);
|
502 |
-
echo /* Serve file in chunks (default chunk size is 2MB). */ fread($resource, $_reading);
|
503 |
-
flush /* Flush each chunk to the browser as it is served (avoids high memory consumption). */();
|
504 |
-
}
|
505 |
-
fclose /* Close file resource handle. */($resource);
|
506 |
-
unset /* Housekeeping. */($_bytes_to_read, $_reading);
|
507 |
-
}
|
508 |
-
exit /* Stop execution now (the file has been served). */();
|
509 |
-
}
|
510 |
-
}
|
511 |
}
|
512 |
-
|
513 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
514 |
{
|
515 |
-
status_header(
|
516 |
-
|
517 |
-
|
518 |
-
|
|
|
|
|
|
|
519 |
}
|
520 |
-
|
521 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
522 |
|
523 |
-
|
524 |
|
525 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
526 |
}
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
* @return string A File Download URL string on success; or an array on success, with elements `streamer`, `file`, `url` when/if ``$get_streamer_array`` is true; else false on any type of failure.
|
537 |
-
*
|
538 |
-
* @see s2Member\API_Functions\s2member_file_download_url()
|
539 |
-
*/
|
540 |
-
public static function create_file_download_url($config = FALSE, $get_streamer_array = FALSE)
|
541 |
-
{
|
542 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
|
543 |
-
do_action("ws_plugin__s2member_before_create_file_download_url", get_defined_vars());
|
544 |
-
unset($__refs, $__v);
|
545 |
-
|
546 |
-
$config = (is_array($config)) ? $config : /* This absolutely MUST be an array. */ array();
|
547 |
|
548 |
-
|
549 |
-
$config["file_download_key"] = (isset($config["file_download"]) && is_string($config["file_download"]) && !empty($config["file_download_key"])) ? c_ws_plugin__s2member_files::file_download_key($config["file_download"], ((in_array($config["file_download_key"], array("ip-forever", "universal", "cache-compatible"))) ? $config["file_download_key"] : false)) : @$config["file_download_key"];
|
550 |
|
551 |
-
|
552 |
-
|
553 |
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
563 |
|
564 |
-
|
565 |
-
|
|
|
566 |
|
567 |
-
|
568 |
-
|
569 |
|
570 |
-
|
571 |
-
|
572 |
|
573 |
-
|
574 |
-
|
575 |
-
}
|
576 |
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
* @package s2Member\Files
|
583 |
-
* @since 110926
|
584 |
-
*
|
585 |
-
* @attaches-to ``add_filter("ws_plugin__s2member_check_file_download_access_user");``
|
586 |
-
*
|
587 |
-
* @param object $user Expects a WP_User object passed in by the Filter.
|
588 |
-
* @return obj A `WP_User` object, possibly obtained through Header Authorization.
|
589 |
-
*/
|
590 |
-
public static function check_file_remote_authorization($user = FALSE)
|
591 |
-
{
|
592 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$__v;
|
593 |
-
do_action("ws_plugin__s2member_before_check_file_remote_authorization", get_defined_vars());
|
594 |
-
unset($__refs, $__v);
|
595 |
|
596 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
|
598 |
-
|
599 |
-
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
|
602 |
-
|
603 |
-
|
604 |
-
$auth = trim(preg_replace("/^.+?\s+/", "", $_SERVER["HTTP_AUTHORIZATION"]));
|
605 |
-
$auth = explode(":", base64_decode($auth), 2);
|
606 |
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
header('WWW-Authenticate: Basic realm="'.c_ws_plugin__s2member_utils_strings::esc_dq(strip_tags(_x("Members Only", "s2member-front", "s2member"))).'"');
|
613 |
|
614 |
-
|
615 |
-
|
616 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
617 |
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
622 |
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
638 |
{
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
644 |
{
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
else if($key === c_ws_plugin__s2member_files::file_download_key($file, "universal") || $key === c_ws_plugin__s2member_files::file_download_key("/".$file, "universal"))
|
650 |
-
$valid = /* File Download Key is valid. */ true;
|
651 |
-
}
|
652 |
-
return apply_filters("ws_plugin__s2member_check_file_download_key", ((isset($valid) && $valid) ? true : false), get_defined_vars());
|
653 |
-
}
|
654 |
-
/**
|
655 |
-
* Creates an Amazon S3 HMAC-SHA1 signature.
|
656 |
-
*
|
657 |
-
* @package s2Member\Files
|
658 |
-
* @since 110524RC
|
659 |
-
*
|
660 |
-
* @param string $string Input string/data, to be signed by this routine.
|
661 |
-
* @return string An HMAC-SHA1 signature for Amazon S3.
|
662 |
-
*/
|
663 |
-
public static function amazon_s3_sign($string = FALSE)
|
664 |
-
{
|
665 |
-
$s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
666 |
|
667 |
-
|
668 |
-
|
669 |
-
/**
|
670 |
-
* Creates an Amazon S3 HMAC-SHA1 signature URL.
|
671 |
-
*
|
672 |
-
* @package s2Member\Files
|
673 |
-
* @since 110926
|
674 |
-
*
|
675 |
-
* @param string $file Input file path, to be signed by this routine.
|
676 |
-
* @param bool $stream Is this resource file to be served as streaming media?
|
677 |
-
* @param bool $inline Is this resource file to be served inline, or no?
|
678 |
-
* @param bool $ssl Is this resource file to be served via SSL, or no?
|
679 |
-
* @param string $basename The absolute basename of the resource file.
|
680 |
-
* @param string $mimetype The MIME content-type of the resource file.
|
681 |
-
* @return string An HMAC-SHA1 signature URL for Amazon S3.
|
682 |
-
*/
|
683 |
-
public static function amazon_s3_url($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
|
684 |
-
{
|
685 |
-
$file = /* Trim / force string. */ trim((string)$file, "/");
|
686 |
-
$url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($file));
|
687 |
-
$url_e_file = str_ireplace("%2F", "/", $url_e_file);
|
688 |
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
$s3c["expires"] = strtotime("+".apply_filters("ws_plugin__s2member_amazon_s3_file_expires_time", "24 hours", get_defined_vars()));
|
694 |
|
695 |
-
|
696 |
-
|
697 |
-
|
|
|
|
|
|
|
698 |
|
699 |
-
|
|
|
|
|
|
|
|
|
|
|
700 |
|
701 |
-
|
|
|
702 |
}
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
$s3c[$option] = $option_value;
|
717 |
-
|
718 |
-
$cfc["distros_s3_access_id"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_s3_access_id"];
|
719 |
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
736 |
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
744 |
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
751 |
|
752 |
-
|
753 |
-
|
754 |
|
755 |
-
|
756 |
-
|
757 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Cross-Domain Policy. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
758 |
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
else if(isset($s3_response["code"], $s3_response["message"]))
|
763 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
764 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Bucket Policy. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
765 |
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
else if(isset($s3_response["code"], $s3_response["message"]))
|
770 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
771 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Bucket ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
772 |
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to acquire/read existing Amazon S3 Bucket ACLs. Unexpected response.", "s2member-admin", "s2member"));
|
778 |
-
}
|
779 |
-
else if(isset($s3_response["code"], $s3_response["message"]))
|
780 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
781 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon S3 Bucket ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
782 |
|
783 |
-
else
|
784 |
-
return array
|
785 |
-
}
|
786 |
-
else // Else, we use a default error code and message.
|
787 |
-
return array("success" => false, "code" => -99, "message" => _x("Unable to auto-configure existing Amazon S3 Bucket ACLs. Incomplete Amazon S3 configuration options. Missing one of: Amazon S3 Bucket, Access Key, or Secret Key.", "s2member-admin", "s2member"));
|
788 |
-
}
|
789 |
-
/**
|
790 |
-
* Creates an Amazon CloudFront HMAC-SHA1 signature.
|
791 |
-
*
|
792 |
-
* @package s2Member\Files
|
793 |
-
* @since 110926
|
794 |
-
*
|
795 |
-
* @param string $string Input string/data, to be signed by this routine.
|
796 |
-
* @return string An HMAC-SHA1 signature for Amazon CloudFront.
|
797 |
-
*/
|
798 |
-
public static function amazon_cf_sign($string = FALSE)
|
799 |
-
{
|
800 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
801 |
|
802 |
-
|
803 |
-
|
804 |
-
/**
|
805 |
-
* Creates an Amazon CloudFront RSA-SHA1 signature.
|
806 |
-
*
|
807 |
-
* @package s2Member\Files
|
808 |
-
* @since 110926
|
809 |
-
*
|
810 |
-
* @param string $string Input string/data, to be signed by this routine.
|
811 |
-
* @return str|bool An RSA-SHA1 signature for Amazon CloudFront, else false on failure.
|
812 |
-
*/
|
813 |
-
public static function amazon_cf_rsa_sign($string = FALSE)
|
814 |
-
{
|
815 |
-
$cfc["private_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"];
|
816 |
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
* Creates an Amazon CloudFront RSA-SHA1 signature URL.
|
821 |
-
*
|
822 |
-
* @package s2Member\Files
|
823 |
-
* @since 110926
|
824 |
-
*
|
825 |
-
* @param string $file Input file path, to be signed by this routine.
|
826 |
-
* @param bool $stream Is this resource file to be served as streaming media?
|
827 |
-
* @param bool $inline Is this resource file to be served inline, or no?
|
828 |
-
* @param bool $ssl Is this resource file to be served via SSL, or no?
|
829 |
-
* @param string $basename The absolute basename of the resource file.
|
830 |
-
* @param string $mimetype The MIME content-type of the resource file.
|
831 |
-
* @return string An RSA-SHA1 signature URL for Amazon CloudFront.
|
832 |
-
*/
|
833 |
-
public static function amazon_cf_url($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
|
834 |
-
{
|
835 |
-
$file = /* Trim & force string. */ trim((string)$file, "/");
|
836 |
-
$url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($file));
|
837 |
-
$url_e_file = str_ireplace("%2F", "/", $url_e_file);
|
838 |
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
|
843 |
-
|
|
|
|
|
|
|
844 |
|
845 |
-
|
846 |
-
|
847 |
-
$cf_stream_extn_resource_exclusions = array_unique((array)apply_filters("ws_plugin__s2member_amazon_cf_file_streaming_extension_resource_exclusions", array("mp3" /* MP3 files should NOT include an extension in their resource reference. */), get_defined_vars()));
|
848 |
-
$cf_resource = ($stream) ? ((in_array($cf_extn, $cf_stream_extn_resource_exclusions)) ? substr($file, 0, strrpos($file, ".")) : $file) : "http".(($ssl) ? "s" : "")."://".(($cfc["distro_downloads_cname"]) ? $cfc["distro_downloads_cname"] : $cfc["distro_downloads_dname"])."/".$url_e_file;
|
849 |
-
$cf_url = ($stream) ? "rtmp".(($ssl) ? "e" : "")."://".(($cfc["distro_streaming_cname"]) ? $cfc["distro_streaming_cname"] : $cfc["distro_streaming_dname"])."/cfx/st/".$file : "http".(($ssl) ? "s" : "")."://".(($cfc["distro_downloads_cname"]) ? $cfc["distro_downloads_cname"] : $cfc["distro_downloads_dname"])."/".$url_e_file;
|
850 |
-
$cf_policy = '{"Statement":[{"Resource":"'.c_ws_plugin__s2member_utils_strings::esc_dq($cf_resource).'","Condition":{'.(($cf_ip_res) ? '"IpAddress":{"AWS:SourceIp":"'.c_ws_plugin__s2member_utils_strings::esc_dq($_SERVER["REMOTE_ADDR"]).'/32"},' : '').'"DateLessThan":{"AWS:EpochTime":'.(int)$cfc["expires"].'}}}]}';
|
851 |
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
* Auto-configures Amazon S3/CloudFront distros.
|
860 |
-
*
|
861 |
-
* @package s2Member\Files
|
862 |
-
* @since 110926
|
863 |
-
*
|
864 |
-
* @return array Array containing a true `success` element on success, else a failure array.
|
865 |
-
* Failure array will contain a failure `code`, and a failure `message`.
|
866 |
-
*/
|
867 |
-
public static function amazon_cf_auto_configure_distros()
|
868 |
-
{
|
869 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
870 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
871 |
-
$cfc[$option] = $option_value;
|
872 |
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
|
877 |
-
|
878 |
-
{
|
879 |
-
if /* We MUST have Amazon CloudFront Keys in order to auto-configure. */($cfc["private_key"] && $cfc["private_key_id"])
|
880 |
-
{
|
881 |
-
if(!$cfc["distro_downloads_id"] || ($cfc["distro_downloads_id"] && ($cf_get_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro($cfc["distro_downloads_id"], "downloads")) && ($cf_get_response["success"] || $cf_get_response["code"] === 404)))
|
882 |
{
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
else if($cfc["distro_downloads_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
|
887 |
-
return array("success" => false, "code" => -86, "message" => _x("Unable to delete existing Amazon CloudFront Downloads Distro. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
888 |
-
|
889 |
-
else if($cfc["distro_downloads_id"] && $cf_get_response && $cf_get_response["success"] && $cf_get_response["deployed"] && ($cf_del_response = c_ws_plugin__s2member_files_in::amazon_cf_del_distro($cfc["distro_downloads_id"], $cf_get_response["etag"], $cf_get_response["xml"])) && $cf_del_response["success"])
|
890 |
-
$cf_distro_downloads_clear = /* Clear, ready for a new one. */ true;
|
891 |
|
892 |
-
|
893 |
-
|
894 |
-
|
|
|
|
|
895 |
|
896 |
-
|
897 |
{
|
898 |
-
|
899 |
-
|
900 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
901 |
{
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
return array("success" => false, "code" => -87, "message" => _x("Unable to delete existing Amazon CloudFront Streaming Distro. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
907 |
-
|
908 |
-
else if($cfc["distro_streaming_id"] && $cf_get_response && $cf_get_response["success"] && $cf_get_response["deployed"] && ($cf_del_response = c_ws_plugin__s2member_files_in::amazon_cf_del_distro($cfc["distro_streaming_id"], $cf_get_response["etag"], $cf_get_response["xml"])) && $cf_del_response["success"])
|
909 |
-
$cf_distro_streaming_clear = /* Clear, ready for a new one. */ true;
|
910 |
-
|
911 |
-
else if(isset($cf_del_response["code"], $cf_del_response["message"]))
|
912 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
913 |
-
return array("success" => false, "code" => $cf_del_response["code"], "message" => sprintf(_x("Unable to delete existing Amazon CloudFront Streaming Distro. %s", "s2member-admin", "s2member"), $cf_del_response["message"]));
|
914 |
-
|
915 |
-
if /* Successfully cleared? Ready for a new one? */(isset($cf_distro_streaming_clear) && $cf_distro_streaming_clear)
|
916 |
-
{
|
917 |
-
unset /* Unset these before processing additional routines. Prevents problems in error reporting. */($cf_get_response, $cf_del_response);
|
918 |
-
|
919 |
-
if(!$cfc["distros_access_id"] || ($cfc["distros_access_id"] && ($cf_get_response = c_ws_plugin__s2member_files_in::amazon_cf_get_access_origin_identity($cfc["distros_access_id"])) && ($cf_get_response["success"] || $cf_get_response["code"] === 404)))
|
920 |
-
{
|
921 |
-
if(!$cfc["distros_access_id"] || ($cfc["distros_access_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
|
922 |
-
$cf_distros_access_clear = /* Clear, ready for a new one. */ true;
|
923 |
-
|
924 |
-
else if($cfc["distros_access_id"] && $cf_get_response && $cf_get_response["success"] && ($cf_del_response = c_ws_plugin__s2member_files_in::amazon_cf_del_access_origin_identity($cfc["distros_access_id"], $cf_get_response["etag"], $cf_get_response["xml"])) && $cf_del_response["success"])
|
925 |
-
$cf_distros_access_clear = /* Clear, ready for a new one. */ true;
|
926 |
-
|
927 |
-
else if(isset($cf_del_response["code"], $cf_del_response["message"]))
|
928 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
929 |
-
return array("success" => false, "code" => $cf_del_response["code"], "message" => sprintf(_x("Unable to delete existing Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_del_response["message"]));
|
930 |
-
|
931 |
-
if /* Successfully cleared? Ready for a new one? */(isset($cf_distros_access_clear) && $cf_distros_access_clear)
|
932 |
-
{
|
933 |
-
unset /* Unset these before processing additional routines. Prevents problems in error reporting. */($cf_get_response, $cf_del_response);
|
934 |
-
|
935 |
-
$cfc = array_merge($cfc, array("distros_access_id" => "", "distros_s3_access_id" => "", "distro_downloads_id" => "", "distro_downloads_dname" => "", "distro_streaming_id" => "", "distro_streaming_dname" => "", "distros_auto_config_status" => ""));
|
936 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distros_access_id" => "", "ws_plugin__s2member_amazon_cf_files_distros_s3_access_id" => "", "ws_plugin__s2member_amazon_cf_files_distro_downloads_id" => "", "ws_plugin__s2member_amazon_cf_files_distro_downloads_dname" => "", "ws_plugin__s2member_amazon_cf_files_distro_streaming_id" => "", "ws_plugin__s2member_amazon_cf_files_distro_streaming_dname" => "", "ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" => "");
|
937 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
938 |
-
|
939 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distros_access_origin_identity()) && $cf_response["success"])
|
940 |
-
{
|
941 |
-
$cfc = array_merge($cfc, array("distros_access_id" => $cf_response["distros_access_id"], "distros_s3_access_id" => $cf_response["distros_s3_access_id"]));
|
942 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distros_access_id" => $cf_response["distros_access_id"], "ws_plugin__s2member_amazon_cf_files_distros_s3_access_id" => $cf_response["distros_s3_access_id"]);
|
943 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
944 |
-
|
945 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro("downloads")) && $cf_response["success"])
|
946 |
-
{
|
947 |
-
$cfc = array_merge($cfc, array("distro_downloads_id" => $cf_response["distro_downloads_id"], "distro_downloads_dname" => $cf_response["distro_downloads_dname"]));
|
948 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distro_downloads_id" => $cf_response["distro_downloads_id"], "ws_plugin__s2member_amazon_cf_files_distro_downloads_dname" => $cf_response["distro_downloads_dname"]);
|
949 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
950 |
-
|
951 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro("streaming")) && $cf_response["success"])
|
952 |
-
{
|
953 |
-
$cfc = array_merge($cfc, array("distro_streaming_id" => $cf_response["distro_streaming_id"], "distro_streaming_dname" => $cf_response["distro_streaming_dname"]));
|
954 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distro_streaming_id" => $cf_response["distro_streaming_id"], "ws_plugin__s2member_amazon_cf_files_distro_streaming_dname" => $cf_response["distro_streaming_dname"]);
|
955 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
956 |
-
|
957 |
-
for($a = 1, $attempts = 4, $sleep = 2, sleep($sleep); $a <= $attempts; $a++, (($a <= $attempts) ? sleep($sleep) : null))
|
958 |
-
/* Allow a generous propagation time here. Amazon's high-availability services do NOT guarantee real-time updates.
|
959 |
-
Since we DO need a fully propagated Origin Access Identity now, we need to make several attempts at success.
|
960 |
-
For further details, please see this thread: <https://forums.aws.amazon.com/message.jspa?messageID=42875>. */
|
961 |
-
if(($s3_response = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls()) && $s3_response["success"])
|
962 |
-
{
|
963 |
-
$cfc = array_merge($cfc, array("distros_auto_config_status" => "configured"));
|
964 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" => "configured");
|
965 |
-
c_ws_plugin__s2member_menu_pages::update_all_options( /* Now configured! */$cf_options, true, false, false, false, false);
|
966 |
-
return /* Successfully configured Amazon S3/CloudFront distros. */ array("success" => true, "code" => null, "message" => null);
|
967 |
-
}
|
968 |
-
if(isset($s3_response["code"], $s3_response["message"]))
|
969 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
970 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
971 |
-
|
972 |
-
else // Else, we use a default error code and message.
|
973 |
-
return array("success" => false, "code" => -88, "message" => _x("Unable to update existing Amazon S3 ACLs. Connection failed.", "s2member-admin", "s2member"));
|
974 |
-
}
|
975 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
976 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
977 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Streaming Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
978 |
-
|
979 |
-
else // Else, we use a default error code and message.
|
980 |
-
return array("success" => false, "code" => -89, "message" => _x("Unable to create Amazon CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
|
981 |
-
}
|
982 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
983 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
984 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Downloads Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
985 |
-
|
986 |
-
else // Else, we use a default error code and message.
|
987 |
-
return array("success" => false, "code" => -90, "message" => _x("Unable to create Amazon CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
|
988 |
-
}
|
989 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
990 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
991 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
992 |
-
|
993 |
-
else // Else, we use a default error code and message.
|
994 |
-
return array("success" => false, "code" => -91, "message" => _x("Unable to create Amazon CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
|
995 |
-
}
|
996 |
-
else // Else, we use a default error code and message.
|
997 |
-
return array("success" => false, "code" => -92, "message" => _x("Unable to clear existing Amazon CloudFront Origin Access Identity.", "s2member-admin", "s2member"));
|
998 |
-
}
|
999 |
-
else if(isset($cf_get_response["code"], $cf_get_response["message"]))
|
1000 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1001 |
-
return array("success" => false, "code" => $cf_get_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_get_response["message"]));
|
1002 |
-
|
1003 |
-
else // Else, we use a default error code and message.
|
1004 |
-
return array("success" => false, "code" => -93, "message" => _x("Unable to acquire existing Amazon CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
|
1005 |
-
}
|
1006 |
-
else // Else, we use a default error code and message.
|
1007 |
-
return array("success" => false, "code" => -94, "message" => _x("Unable to clear existing Amazon CloudFront Streaming Distro.", "s2member-admin", "s2member"));
|
1008 |
}
|
1009 |
-
|
1010 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon
|
1011 |
-
return array
|
1012 |
|
1013 |
else // Else, we use a default error code and message.
|
1014 |
-
return array
|
1015 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1016 |
else // Else, we use a default error code and message.
|
1017 |
-
return array
|
1018 |
}
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
|
|
|
|
|
|
|
1023 |
else // Else, we use a default error code and message.
|
1024 |
-
return array
|
1025 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1026 |
else // Else, we use a default error code and message.
|
1027 |
-
return array
|
1028 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1029 |
else // Else, we use a default error code and message.
|
1030 |
-
return array
|
1031 |
}
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
{
|
1046 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1047 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1048 |
-
$cfc[$option] = $option_value;
|
1049 |
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1053 |
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1059 |
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
return array("success" => true, "code" => null, "message" => null, "etag" => trim($cf_response["headers"]["etag"]), "xml" => trim($cf_response["body"]));
|
1064 |
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1071 |
|
1072 |
-
|
1073 |
-
|
1074 |
-
}
|
1075 |
-
else // Else, we use a default error code and message.
|
1076 |
-
return array("success" => false, "code" => -99, "message" => _x("Unable to acquire existing Amazon CloudFront Origin Access Identity. Invalid Access ID.", "s2member-admin", "s2member"));
|
1077 |
-
}
|
1078 |
-
/**
|
1079 |
-
* Deletes an Amazon S3/CloudFront Access Origin Identity.
|
1080 |
-
*
|
1081 |
-
* @package s2Member\Files
|
1082 |
-
* @since 110926
|
1083 |
-
*
|
1084 |
-
* @param string $access_id Required. An Origin Access ID.
|
1085 |
-
* @param string $access_id_etag Required. An Origin Access ETag header.
|
1086 |
-
* @param string $access_id_xml Required. An Origin Access Identity's XML configuration.
|
1087 |
-
* @return array Array containing a true `success` element on success, else a failure array.
|
1088 |
-
* Failure array will contain a failure `code`, and a failure `message`.
|
1089 |
-
*/
|
1090 |
-
public static function amazon_cf_del_access_origin_identity($access_id = FALSE, $access_id_etag = FALSE, $access_id_xml = FALSE)
|
1091 |
-
{
|
1092 |
-
if($access_id && is_string($access_id) && $access_id_etag && is_string($access_id_etag) && $access_id_xml && is_string($access_id_xml))
|
1093 |
-
{
|
1094 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1095 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1096 |
-
$cfc[$option] = $option_value;
|
1097 |
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
|
|
1107 |
|
1108 |
-
|
1109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1110 |
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
|
|
|
|
|
|
1114 |
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1131 |
{
|
1132 |
-
foreach($GLOBALS
|
1133 |
-
if(preg_match
|
1134 |
$cfc[$option] = $option_value;
|
1135 |
|
1136 |
-
$s3c
|
1137 |
-
$cfc
|
1138 |
-
$cfc
|
1139 |
|
1140 |
-
$cf_domain
|
1141 |
-
$cf_date
|
1142 |
-
$
|
1143 |
-
$
|
1144 |
-
$
|
1145 |
-
$
|
1146 |
-
$cf_args = array("method" => "POST", "redirection" => 5, "body" => $cf_distros_access_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1147 |
|
1148 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote
|
1149 |
-
|
1150 |
-
if(preg_match("/\<CloudFrontOriginAccessIdentity.*?\>(.+?)\<\/CloudFrontOriginAccessIdentity\>/is", $cf_response["body"], $cf_distros_access_tag) && preg_match("/\<Id\>(.+?)\<\/Id\>/is", $cf_distros_access_tag[1], $cf_distros_access_id_tag) && preg_match("/\<S3CanonicalUserId\>(.+?)\<\/S3CanonicalUserId\>/is", $cf_distros_access_tag[1], $cf_distros_s3_access_id_tag))
|
1151 |
-
return array("success" => true, "code" => null, "message" => null, "distros_access_id" => trim($cf_distros_access_id_tag[1]), "distros_s3_access_id" => trim($cf_distros_s3_access_id_tag[1]));
|
1152 |
|
1153 |
-
|
1154 |
-
return array("success" => false, "code" => -98, "message" => _x("Unable to create/read Amazon CloudFront Origin Access Identity. Unexpected response.", "s2member-admin", "s2member"));
|
1155 |
-
}
|
1156 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1157 |
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1158 |
-
return array
|
1159 |
|
1160 |
else // Else, we use a default error code and message.
|
1161 |
-
return array
|
1162 |
}
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
* Failure array will contain a failure `code`, and a failure `message`.
|
1173 |
-
*/
|
1174 |
-
public static function amazon_cf_get_distro($distro_id = FALSE, $distro_type = FALSE)
|
1175 |
-
{
|
1176 |
-
if($distro_id && is_string($distro_id) && $distro_type && is_string($distro_type) && in_array($distro_type, array("downloads", "streaming")))
|
1177 |
-
{
|
1178 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1179 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1180 |
-
$cfc[$option] = $option_value;
|
1181 |
-
|
1182 |
-
$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
|
1183 |
-
$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
|
1184 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
1185 |
-
|
1186 |
-
$cf_domain = "cloudfront.amazonaws.com";
|
1187 |
-
$cf_date = gmdate("D, d M Y H:i:s")." GMT";
|
1188 |
-
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1189 |
-
$cf_location = ($distro_type === "streaming") ? "/2010-11-01/streaming-distribution/".$distro_id : "/2010-11-01/distribution/".$distro_id;
|
1190 |
-
$cf_args = array("method" => "GET", "redirection" => 5, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1191 |
-
|
1192 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && (($cf_response["code"] === 404 && $cf_response["message"]) || ($cf_response["code"] === 200 && !empty($cf_response["headers"]["etag"]) && !empty($cf_response["body"]))))
|
1193 |
-
{
|
1194 |
-
if($cf_response["code"] === 200 && !empty($cf_response["headers"]["etag"]) && !empty($cf_response["body"]))
|
1195 |
-
return array("success" => true, "code" => null, "message" => null, "etag" => trim($cf_response["headers"]["etag"]), "xml" => trim($cf_response["body"]), "deployed" => ((stripos($cf_response["body"], "<Status>Deployed</Status>") !== false) ? true : false));
|
1196 |
-
|
1197 |
-
else /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1198 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Existing Amazon CloudFront Distro NOT found. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1199 |
-
}
|
1200 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1201 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1202 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon CloudFront Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1203 |
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
|
|
1223 |
{
|
1224 |
-
if
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1247 |
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
|
1252 |
-
else // Else, we use a default error code and message.
|
1253 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to disable existing Amazon CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
|
1254 |
-
}
|
1255 |
-
else // Else, we use a default error code and message.
|
1256 |
-
return array("success" => false, "code" => -98, "message" => _x("Existing Amazon CloudFront Distro cannot be disabled at this time. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
1257 |
-
}
|
1258 |
-
else // Else, we use a default error code and message.
|
1259 |
-
return array("success" => true, "code" => null, "message" => null, "etag" => $distro_id_etag, "xml" => $distro_id_xml, "deployed" => ((stripos($distro_id_xml, "<Status>Deployed</Status>") !== false) ? true : false));
|
1260 |
-
}
|
1261 |
else // Else, we use a default error code and message.
|
1262 |
-
return array
|
1263 |
}
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
{
|
1278 |
-
if($distro_id && is_string($distro_id) && $distro_id_etag && is_string($distro_id_etag) && $distro_id_xml && is_string($distro_id_xml) && ($distro_id_type = (stripos($distro_id_xml, "<StreamingDistribution") !== false) ? "streaming" : ((stripos($distro_id_xml, "<Distribution") !== false) ? "downloads" : false)) && preg_match("/\<CallerReference\>(.+?)\<\/CallerReference\>/is", $distro_id_xml, $distro_id_reference_tag) && ($distro_id_reference = $distro_id_reference_tag[1]))
|
1279 |
-
{
|
1280 |
-
if /* Check distro status before we even begin processing this deletion. */(stripos($distro_id_xml, "<Status>Deployed</Status>") !== false)
|
1281 |
-
{
|
1282 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_disable_distro($distro_id, $distro_id_etag, $distro_id_xml)) && $cf_response["success"])
|
1283 |
-
{
|
1284 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro($distro_id, $distro_id_type)) && $cf_response["success"] && $cf_response["deployed"])
|
1285 |
-
{
|
1286 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1287 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1288 |
-
$cfc[$option] = $option_value;
|
1289 |
-
|
1290 |
-
$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
|
1291 |
-
$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
|
1292 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
1293 |
-
|
1294 |
-
$cf_domain = "cloudfront.amazonaws.com";
|
1295 |
-
$cf_date = gmdate("D, d M Y H:i:s")." GMT";
|
1296 |
-
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1297 |
-
$cf_location = ($distro_id_type === "streaming") ? "/2010-11-01/streaming-distribution/".$distro_id : "/2010-11-01/distribution/".$distro_id;
|
1298 |
-
$cf_args = array("method" => "DELETE", "redirection" => 5, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $cf_response["etag"], "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1299 |
-
|
1300 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && ($cf_response["code"] === 200 || $cf_response["code"] === 204 /* Deleted. */))
|
1301 |
-
return /* Deleted successfully. */ array("success" => true, "code" => null, "message" => null);
|
1302 |
-
|
1303 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1304 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1305 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to delete existing Amazon CloudFront Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1306 |
-
|
1307 |
-
else // Else, we use a default error code and message.
|
1308 |
-
return array("success" => false, "code" => -94, "message" => _x("Unable to delete existing Amazon CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
|
1309 |
-
}
|
1310 |
-
else if(isset($cf_response["success"], $cf_response["deployed"]) && $cf_response["success"] && !$cf_response["deployed"])
|
1311 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1312 |
-
return array("success" => false, "code" => -95, "message" => _x("Existing Amazon CloudFront Distro cannot be deleted at this time. Still in a `pending` state after having been disabled by s2Member. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
1313 |
-
|
1314 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1315 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1316 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to check status of existing Amazon CloudFront Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1317 |
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1324 |
|
1325 |
-
else // Else, we use a default error code and message.
|
1326 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to disable existing Amazon CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
|
1327 |
-
}
|
1328 |
-
else // Else, we use a default error code and message.
|
1329 |
-
return array("success" => false, "code" => -98, "message" => _x("Existing Amazon CloudFront Distro cannot be deleted at this time. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
1330 |
-
}
|
1331 |
else // Else, we use a default error code and message.
|
1332 |
-
return array
|
1333 |
}
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
|
|
|
|
|
|
|
|
1345 |
{
|
1346 |
-
if
|
1347 |
-
|
1348 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1349 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1350 |
-
$cfc[$option] = $option_value;
|
1351 |
-
|
1352 |
-
$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
|
1353 |
-
$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
|
1354 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
1355 |
-
|
1356 |
-
$cf_domain = "cloudfront.amazonaws.com";
|
1357 |
-
$cf_date = gmdate("D, d M Y H:i:s")." GMT";
|
1358 |
-
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1359 |
-
|
1360 |
-
if /* Create a `downloads` Distro? This uses a different XML schema. */($distro_type === "downloads")
|
1361 |
-
{
|
1362 |
-
$cf_location = /* Create distro. */ "/2010-11-01/distribution";
|
1363 |
-
$cf_distro_downloads_reference = time().".".md5("downloads".$s3c["bucket"].$s3c["access_key"].$s3c["secret_key"].$cfc["private_key"].$cfc["private_key_id"].$cfc["distro_downloads_cname"]);
|
1364 |
-
$cf_distro_downloads_xml = '<?xml version="1.0" encoding="UTF-8"?><DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/"><S3Origin><DNSName>'.esc_html($s3c["bucket"]).'.s3.amazonaws.com</DNSName><OriginAccessIdentity>origin-access-identity/cloudfront/'.esc_html($cfc["distros_access_id"]).'</OriginAccessIdentity></S3Origin><CallerReference>'.esc_html($cf_distro_downloads_reference).'</CallerReference>'.(($cfc["distro_downloads_cname"]) ? '<CNAME>'.esc_html($cfc["distro_downloads_cname"]).'</CNAME>' : '').'<Comment>'.esc_html(sprintf(_x("Created by s2Member, for S3 Bucket: %s.", "s2member-admin", "s2member"), $s3c["bucket"])).'</Comment><Enabled>true</Enabled><DefaultRootObject>index.html</DefaultRootObject><TrustedSigners><Self/></TrustedSigners></DistributionConfig>';
|
1365 |
-
$cf_args = array("method" => "POST", "redirection" => 5, "body" => $cf_distro_downloads_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1366 |
-
|
1367 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && ($cf_response["code"] === 200 || $cf_response["code"] === 201 /* Created. */))
|
1368 |
-
{
|
1369 |
-
if(preg_match("/\<Distribution.*?\>(.+?)\<\/Distribution\>/is", $cf_response["body"], $cf_distro_downloads_tag) && preg_match("/\<Id\>(.+?)\<\/Id\>/is", $cf_distro_downloads_tag[1], $cf_distro_downloads_id_tag) && preg_match("/\<DomainName\>(.+?)\<\/DomainName\>/is", $cf_distro_downloads_tag[1], $cf_distro_downloads_dname_tag))
|
1370 |
-
return array("success" => true, "code" => null, "message" => null, "distro_downloads_id" => trim($cf_distro_downloads_id_tag[1]), "distro_downloads_dname" => trim($cf_distro_downloads_dname_tag[1]));
|
1371 |
|
1372 |
-
else // Else, we use a default error code and message.
|
1373 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to create/read Amazon CloudFront Downloads Distro. Unexpected response.", "s2member-admin", "s2member"));
|
1374 |
-
}
|
1375 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1376 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1377 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Downloads Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1378 |
-
|
1379 |
-
else // Else, we use a default error code and message.
|
1380 |
-
return array("success" => false, "code" => -98, "message" => _x("Unable to create Amazon CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
|
1381 |
-
}
|
1382 |
-
|
1383 |
-
else if /* Create a `streaming` Distro? A different XML schema. */($distro_type === "streaming")
|
1384 |
-
{
|
1385 |
-
$cf_location = /* Create streaming distro. */ "/2010-11-01/streaming-distribution";
|
1386 |
-
$cf_distro_streaming_reference = time().".".md5("streaming".$s3c["bucket"].$s3c["access_key"].$s3c["secret_key"].$cfc["private_key"].$cfc["private_key_id"].$cfc["distro_streaming_cname"]);
|
1387 |
-
$cf_distro_streaming_xml = '<?xml version="1.0" encoding="UTF-8"?><StreamingDistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/"><S3Origin><DNSName>'.esc_html($s3c["bucket"]).'.s3.amazonaws.com</DNSName><OriginAccessIdentity>origin-access-identity/cloudfront/'.esc_html($cfc["distros_access_id"]).'</OriginAccessIdentity></S3Origin><CallerReference>'.esc_html($cf_distro_streaming_reference).'</CallerReference>'.(($cfc["distro_streaming_cname"]) ? '<CNAME>'.esc_html($cfc["distro_streaming_cname"]).'</CNAME>' : '').'<Comment>'.esc_html(sprintf(_x("Created by s2Member, for S3 Bucket: %s.", "s2member-admin", "s2member"), $s3c["bucket"])).'</Comment><Enabled>true</Enabled><DefaultRootObject>index.html</DefaultRootObject><TrustedSigners><Self/></TrustedSigners></StreamingDistributionConfig>';
|
1388 |
-
$cf_args = array("method" => "POST", "redirection" => 5, "body" => $cf_distro_streaming_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1389 |
-
|
1390 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && ($cf_response["code"] === 200 || $cf_response["code"] === 201 /* Created. */))
|
1391 |
-
{
|
1392 |
-
if(preg_match("/\<StreamingDistribution.*?\>(.+?)\<\/StreamingDistribution\>/is", $cf_response["body"], $cf_distro_streaming_tag) && preg_match("/\<Id\>(.+?)\<\/Id\>/is", $cf_distro_streaming_tag[1], $cf_distro_streaming_id_tag) && preg_match("/\<DomainName\>(.+?)\<\/DomainName\>/is", $cf_distro_streaming_tag[1], $cf_distro_streaming_dname_tag))
|
1393 |
-
return array("success" => true, "code" => null, "message" => null, "distro_streaming_id" => trim($cf_distro_streaming_id_tag[1]), "distro_streaming_dname" => trim($cf_distro_streaming_dname_tag[1]));
|
1394 |
-
|
1395 |
-
else // Else, we use a default error code and message.
|
1396 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to create/read Amazon CloudFront Streaming Distro. Unexpected response.", "s2member-admin", "s2member"));
|
1397 |
-
}
|
1398 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1399 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1400 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Streaming Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1401 |
-
|
1402 |
-
else // Else, we use a default error code and message.
|
1403 |
-
return array("success" => false, "code" => -98, "message" => _x("Unable to create Amazon CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
|
1404 |
-
}
|
1405 |
-
}
|
1406 |
else // Else, we use a default error code and message.
|
1407 |
-
return array
|
1408 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1409 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1410 |
}
|
1411 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* File Download routines for s2Member (inner processing routines).
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Files
|
15 |
+
* @since 3.5
|
16 |
+
*/
|
17 |
+
if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
|
18 |
+
exit('Do not access this file directly.');
|
19 |
+
|
20 |
+
if(!class_exists('c_ws_plugin__s2member_files_in'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* File Download routines for s2Member (inner processing routines).
|
24 |
+
*
|
25 |
+
* @package s2Member\Files
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_files_in
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles Download Access permissions.
|
32 |
+
*
|
33 |
+
* @package s2Member\Files
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @attaches-to ``add_action('init');``
|
37 |
+
* @also-called-by API Function {@link s2Member\API_Functions\s2member_file_download_url()}, w/ ``$create_file_download_url`` param.
|
38 |
+
*
|
39 |
+
* @param null|array $create_file_download_url Optional. If this function is called directly, we can pass arguments through this array.
|
40 |
+
* Possible array elements: `file_download` *(required)*, `file_download_key`, `file_stream`, `file_inline`, `file_storage`, `file_remote`, `file_ssl`, `file_rewrite`, `file_rewrite_base`, `skip_confirmation`, `url_to_storage_source`, `count_against_user`, `check_user`.
|
41 |
+
*
|
42 |
+
* @return null|string If called directly with ``$create_file_download_url``, returns a string with the URL, based on configuration.
|
43 |
+
* Else, this function may exit script execution after serving a File Download.
|
44 |
+
*/
|
45 |
+
public static function check_file_download_access($create_file_download_url = NULL)
|
46 |
+
{
|
47 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
|
48 |
+
do_action('ws_plugin__s2member_before_file_download_access', get_defined_vars());
|
49 |
+
unset($__refs, $__v); // Housekeeping.
|
50 |
+
|
51 |
+
$_g = !empty($_GET) ? $_GET : array();
|
52 |
+
$_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_g));
|
53 |
+
|
54 |
+
$creating = (is_array($create = $create_file_download_url)) ? TRUE : FALSE; // Creating URL?
|
55 |
+
$serving = (!$creating) ? TRUE : FALSE; // If NOT creating a File Download URL, we're serving one.
|
56 |
+
$serving_range = $range = FALSE; // Default values (so these variables DO get defined at all times).
|
57 |
+
|
58 |
+
if($serving) // If we're serving, let's see if we're serving a byte-range request here.
|
59 |
{
|
60 |
+
$range = (string)@$_SERVER['HTTP_RANGE'];
|
61 |
+
|
62 |
+
if(!$range && function_exists('apache_request_headers'))
|
63 |
+
{
|
64 |
+
foreach((array)apache_request_headers() as $_header => $_value)
|
65 |
+
// Note: ``apache_request_headers()`` works in FastCGI too, starting w/ PHP v5.4.
|
66 |
+
if(is_string($_header) && strcasecmp($_header, 'range') === 0)
|
67 |
+
$range = $_value;
|
68 |
+
}
|
69 |
+
unset($_header, $_value); // Housekeeping.
|
70 |
+
|
71 |
+
if($range) $serving_range = TRUE;
|
72 |
+
}
|
73 |
+
$req['file_download'] = ($creating) ? @$create['file_download'] : @$_g['s2member_file_download'];
|
74 |
+
$req['file_download_key'] = ($creating) ? @$create['file_download_key'] : @$_g['s2member_file_download_key'];
|
75 |
+
|
76 |
+
$req['file_stream'] = ($creating) ? @$create['file_stream'] : @$_g['s2member_file_stream'];
|
77 |
+
$req['file_inline'] = ($creating) ? @$create['file_inline'] : @$_g['s2member_file_inline'];
|
78 |
+
$req['file_storage'] = ($creating) ? @$create['file_storage'] : @$_g['s2member_file_storage'];
|
79 |
+
$req['file_remote'] = ($creating) ? @$create['file_remote'] : @$_g['s2member_file_remote'];
|
80 |
+
$req['file_ssl'] = ($creating) ? @$create['file_ssl'] : @$_g['s2member_file_ssl'];
|
81 |
+
|
82 |
+
$req['file_rewrite'] = ($creating) ? @$create['file_rewrite'] : NULL;
|
83 |
+
$req['file_rewrite_base'] = ($creating) ? @$create['file_rewrite_base'] : NULL;
|
84 |
+
|
85 |
+
$req['skip_confirmation'] = ($creating) ? @$create['skip_confirmation'] : NULL;
|
86 |
+
$req['url_to_storage_source'] = ($creating) ? @$create['url_to_storage_source'] : NULL;
|
87 |
+
$req['count_against_user'] = ($creating) ? @$create['count_against_user'] : NULL;
|
88 |
+
$req['check_user'] = ($creating) ? @$create['check_user'] : NULL;
|
89 |
+
|
90 |
+
if($req['file_download'] && is_string($req['file_download']) && ($req['file_download'] = trim($req['file_download'], '/')))
|
91 |
+
if(strpos($req['file_download'], '..') === FALSE && strpos(basename($req['file_download']), '.') !== 0)
|
92 |
+
{
|
93 |
+
$using_amazon_cf_storage = ((!$req['file_storage'] || strcasecmp((string)$req['file_storage'], 'cf') === 0) && c_ws_plugin__s2member_utils_conds::using_amazon_cf_storage()) ? TRUE : FALSE;
|
94 |
+
$using_amazon_s3_storage = ((!$req['file_storage'] || strcasecmp((string)$req['file_storage'], 's3') === 0) && c_ws_plugin__s2member_utils_conds::using_amazon_s3_storage()) ? TRUE : FALSE;
|
95 |
+
$using_amazon_storage = ($using_amazon_cf_storage || $using_amazon_s3_storage) ? TRUE : FALSE;
|
96 |
+
|
97 |
+
$excluded = apply_filters('ws_plugin__s2member_check_file_download_access_excluded', FALSE, get_defined_vars());
|
98 |
+
$valid_file_download_key = ($req['file_download_key'] && is_string($req['file_download_key']) && $creating && (!isset($req['check_user']) || !filter_var($req['check_user'], FILTER_VALIDATE_BOOLEAN)) && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN))) ? TRUE : FALSE;
|
99 |
+
$valid_file_download_key = (!$valid_file_download_key && $req['file_download_key'] && is_string($req['file_download_key'])) ? c_ws_plugin__s2member_files_in::check_file_download_key($req['file_download'], $req['file_download_key']) : FALSE;
|
100 |
+
$checking_user = ($excluded || $valid_file_download_key || ($creating && (!isset($req['check_user']) || !filter_var($req['check_user'], FILTER_VALIDATE_BOOLEAN)) && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN)))) ? FALSE : TRUE;
|
101 |
+
$updating_user_counter = ($serving_range || !$checking_user || ($creating && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN)))) ? FALSE : TRUE;
|
102 |
+
|
103 |
+
if(($serving || $creating) && $checking_user) // In either case, the following routines apply whenever we ARE ``$checking_user``.
|
104 |
{
|
105 |
+
if(!$using_amazon_storage && !file_exists($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'].'/'.$req['file_download']))
|
106 |
+
{
|
107 |
+
if($serving) // We only need this section when/if we're actually serving.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
{
|
109 |
+
status_header(404);
|
110 |
+
header('Content-Type: text/html; charset=UTF-8');
|
111 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
112 |
+
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', 's2member-front', 's2member'));
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
+
return FALSE; // Else return false.
|
115 |
+
}
|
116 |
+
else if($req['file_download_key'] && is_string($req['file_download_key']) && !$valid_file_download_key)
|
117 |
+
{
|
118 |
+
if($serving) // We only need this section when/if we're actually serving.
|
119 |
+
{
|
120 |
+
status_header(503);
|
121 |
+
header('Content-Type: text/html; charset=UTF-8');
|
122 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
123 |
+
exit(_x('<strong>503 (Invalid Key):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', 's2member-front', 's2member'));
|
124 |
+
}
|
125 |
+
return FALSE; // Else return false.
|
126 |
+
}
|
127 |
+
else // Default behavior; check file download access against the current user.
|
128 |
+
{
|
129 |
+
if($serving) // We only need remote functionality when/if we're actually serving.
|
130 |
+
if(!has_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization'))
|
131 |
+
add_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization', 10, 2);
|
132 |
+
|
133 |
+
if($creating) // We only need remote functionality when/if we're actually serving.
|
134 |
+
if(has_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization'))
|
135 |
+
remove_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization', 10, 2);
|
136 |
+
|
137 |
+
if(!$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
138 |
+
{
|
139 |
+
if($serving) // We only need this section when/if we're actually serving.
|
140 |
+
{
|
141 |
+
status_header(503);
|
142 |
+
header('Content-Type: text/html; charset=UTF-8');
|
143 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
144 |
+
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› General Options -› Membership Options Page</code>.', 's2member-front', 's2member'));
|
145 |
+
}
|
146 |
+
return FALSE; // Else return false.
|
147 |
+
}
|
148 |
+
else if(($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads()) === FALSE)
|
149 |
+
{
|
150 |
+
if($serving) // We only need this section when/if we're actually serving.
|
151 |
+
{
|
152 |
+
status_header(503);
|
153 |
+
header('Content-Type: text/html; charset=UTF-8');
|
154 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
155 |
+
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› Download Options -› Basic Download Restrictions</code>.', 's2member-front', 's2member'));
|
156 |
+
}
|
157 |
+
return FALSE; // Else return false.
|
158 |
+
}
|
159 |
+
else if(!is_object($user = apply_filters('ws_plugin__s2member_check_file_download_access_user', ((is_user_logged_in()) ? wp_get_current_user() : FALSE), get_defined_vars())) || empty($user->ID) || !($user_id = $user->ID) || !is_array($user_file_downloads = c_ws_plugin__s2member_files::user_downloads($user)) || (!$user->has_cap('administrator') && (!$user_file_downloads['allowed'] || !$user_file_downloads['allowed_days'])))
|
160 |
+
{
|
161 |
+
if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//', $req['file_download'], $m) && strlen($req_level = $m[1]) && (!is_object($user) || empty($user->ID) || !$user->has_cap('access_s2member_level'.$req_level)))
|
162 |
+
{
|
163 |
+
if($serving) // We only need this section when/if we're actually serving.
|
164 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $req_level, $_SERVER['REQUEST_URI']).exit();
|
165 |
|
166 |
+
return FALSE; // Else return false.
|
167 |
+
}
|
168 |
+
else if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//', $req['file_download'], $m) && strlen($req_ccap = preg_replace('/-/', '_', $m[1])) && (!is_object($user) || empty($user->ID) || !$user->has_cap('access_s2member_ccap_'.$req_ccap)))
|
169 |
{
|
170 |
+
if($serving) // We only need this section when/if we're actually serving.
|
171 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'ccap', $req_ccap, $_SERVER['REQUEST_URI']).exit();
|
|
|
172 |
|
173 |
+
return FALSE; // Else return false.
|
174 |
+
}
|
175 |
+
else if($serving) // We only need this section when/if we're actually serving.
|
176 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $min_level_4_downloads, $_SERVER['REQUEST_URI']).exit();
|
|
|
177 |
|
178 |
+
return FALSE; // Else return false.
|
179 |
+
}
|
180 |
+
else if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//', $req['file_download'], $m) && strlen($req_level = $m[1]) && !$user->has_cap('access_s2member_level'.$req_level))
|
181 |
+
{
|
182 |
+
if($serving) // We only need this section when/if we're actually serving.
|
183 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $req_level, $_SERVER['REQUEST_URI']).exit();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
|
185 |
+
return FALSE; // Else return false.
|
186 |
+
}
|
187 |
+
else if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//', $req['file_download'], $m) && strlen($req_ccap = preg_replace('/-/', '_', $m[1])) && !$user->has_cap('access_s2member_ccap_'.$req_ccap))
|
188 |
+
{
|
189 |
+
if($serving) // We only need this section when/if we're actually serving.
|
190 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'ccap', $req_ccap, $_SERVER['REQUEST_URI']).exit();
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
|
192 |
+
return FALSE; // Else return false.
|
193 |
+
}
|
194 |
+
else if($serving || $creating) // In either case, the following routines apply.
|
195 |
+
{
|
196 |
+
$user_previous_file_downloads = 0; // Downloads the User has already; in current period/cycle.
|
197 |
+
$user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
|
198 |
|
199 |
+
$user_file_download_access_log = (is_array($user_file_download_access_log = get_user_option('s2member_file_download_access_log', $user_id))) ? $user_file_download_access_log : array();
|
200 |
+
$user_file_download_access_arc = (is_array($user_file_download_access_arc = get_user_option('s2member_file_download_access_arc', $user_id))) ? $user_file_download_access_arc : array();
|
|
|
201 |
|
202 |
+
$streaming_file_extns = c_ws_plugin__s2member_utils_strings::preg_quote_deep($GLOBALS['WS_PLUGIN__']['s2member']['c']['streaming_file_extns'], '/');
|
203 |
+
$streaming_variations = '/\.('.implode('|', $streaming_file_extns).')#x2F;i'; // Only count one streaming media file variation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
+
foreach($user_file_download_access_log as $user_file_download_access_log_entry_key => $user_file_download_access_log_entry)
|
206 |
+
{
|
207 |
+
if(isset($user_file_download_access_log_entry['date'], $user_file_download_access_log_entry['file'])) // Weed out corrupt/empty log entries.
|
208 |
+
{
|
209 |
+
if(strtotime($user_file_download_access_log_entry['date']) < strtotime('-'.$user_file_downloads['allowed_days'].' days'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
{
|
211 |
+
unset($user_file_download_access_log[$user_file_download_access_log_entry_key]); // Remove it from the `log`.
|
212 |
+
$user_file_download_access_arc[] = $user_file_download_access_log_entry; // Move `log` entry to the `archive` now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
}
|
214 |
+
else if(strtotime($user_file_download_access_log_entry['date']) >= strtotime('-'.$user_file_downloads['allowed_days'].' days'))
|
|
|
215 |
{
|
216 |
+
$user_previous_file_downloads++; // Previous files always count against this User/Member.
|
|
|
|
|
217 |
|
218 |
+
$_user_file_download_access_log_entry = & $user_file_download_access_log[$user_file_download_access_log_entry_key];
|
219 |
+
$_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
|
220 |
|
221 |
+
if($user_file_download_access_log_entry['file'] === $req['file_download']) // Already downloaded this file? If yes, mark this flag as true.
|
222 |
+
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = TRUE; // Already downloaded this file? If yes, mark as true.
|
|
|
|
|
|
|
223 |
|
224 |
+
else if(preg_replace($streaming_variations, '', $user_file_download_access_log_entry['file']) === preg_replace($streaming_variations, '', $req['file_download']))
|
225 |
+
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = TRUE;
|
|
|
|
|
|
|
226 |
|
227 |
+
if($updating_user_counter && ($_user_already_downloaded_this_file || $_user_already_downloaded_a_streaming_variation_of_this_file)) // Updating counter?
|
228 |
+
{
|
229 |
+
$_user_file_download_access_log_entry['ltime'] = time(); // First, we update the last download time for this file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
|
231 |
+
if(!empty($user_file_download_access_log_entry['counter'])) // Backward compatibility here. Is this even set?
|
232 |
+
$_user_file_download_access_log_entry['counter'] = (int)$user_file_download_access_log_entry['counter'] + 1;
|
233 |
+
else // Backward compatibility here. Default value to `1`, if this is NOT even set yet.
|
234 |
+
$_user_file_download_access_log_entry['counter'] = 1 + 1;
|
235 |
+
}
|
236 |
+
}
|
237 |
+
}
|
238 |
+
else // Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries.
|
239 |
+
unset($user_file_download_access_log[$user_file_download_access_log_entry_key]); // Remove.
|
240 |
+
}
|
241 |
+
if($updating_user_counter && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file) // Do we need a new log entry for this file?
|
242 |
+
$user_file_download_access_log[] = array('date' => date('Y-m-d'), 'time' => time(), 'ltime' => time(), 'file' => $req['file_download'], 'counter' => 1);
|
243 |
|
244 |
+
if($user_previous_file_downloads >= $user_file_downloads['allowed'] && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file && !$user->has_cap('administrator'))
|
245 |
+
{
|
246 |
+
if($serving) // We only need this section when/if we're actually serving.
|
247 |
+
wp_redirect(add_query_arg(urlencode_deep(array('_s2member_seeking' => array('type' => 'file', 'file' => $req['file_download'], '_uri' => base64_encode($_SERVER['REQUEST_URI'])), 's2member_seeking' => 'file-'.$req['file_download'])), get_page_link($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'])), apply_filters('ws_plugin__s2member_content_redirect_status', 301, get_defined_vars())).exit();
|
248 |
|
249 |
+
return FALSE; // Else return false.
|
250 |
+
}
|
251 |
+
else if($updating_user_counter) // Save/update counter? By default, we do NOT update the counter when a URL is simply being created for access.
|
252 |
+
update_user_option($user_id, 's2member_file_download_access_log', c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_log)).update_user_option($user_id, 's2member_file_download_access_arc', c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_arc));
|
253 |
+
}
|
254 |
+
}
|
255 |
+
}
|
256 |
+
else // Otherwise, we're either NOT ``$checking_user``; or permission was granted with a valid File Download Key.
|
257 |
+
{
|
258 |
+
if(!$using_amazon_storage && !file_exists($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'].'/'.$req['file_download']))
|
259 |
+
{
|
260 |
+
if($serving) // We only need this section when/if we're actually serving.
|
261 |
+
{
|
262 |
+
status_header(404);
|
263 |
+
header('Content-Type: text/html; charset=UTF-8');
|
264 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
265 |
+
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', 's2member-front', 's2member'));
|
266 |
+
}
|
267 |
+
return FALSE; // Else return false.
|
268 |
+
}
|
269 |
+
}
|
270 |
+
if($serving || $creating) // In either case, the following routines apply.
|
271 |
+
{
|
272 |
+
$basename = basename($req['file_download']);
|
273 |
+
$mimetypes = parse_ini_file(dirname(dirname(dirname(__FILE__))).'/includes/mime-types.ini');
|
274 |
+
$extension = strtolower(substr($req['file_download'], strrpos($req['file_download'], '.') + 1));
|
275 |
+
|
276 |
+
$key = ($req['file_download_key'] && is_string($req['file_download_key'])) ? $req['file_download_key'] : FALSE;
|
277 |
+
|
278 |
+
$stream = (isset($req['file_stream'])) ? filter_var($req['file_stream'], FILTER_VALIDATE_BOOLEAN) : ((in_array($extension, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_stream_extensions']))) ? TRUE : FALSE);
|
279 |
+
$inline = (!$stream && isset($req['file_inline'])) ? filter_var($req['file_inline'], FILTER_VALIDATE_BOOLEAN) : (($stream || in_array($extension, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_inline_extensions']))) ? TRUE : FALSE);
|
280 |
+
$ssl = (isset($req['file_ssl'])) ? filter_var($req['file_ssl'], FILTER_VALIDATE_BOOLEAN) : ((is_ssl()) ? TRUE : FALSE);
|
281 |
+
$storage = ($req['file_storage'] && is_string($req['file_storage'])) ? strtolower($req['file_storage']) : FALSE;
|
282 |
+
$remote = (isset($req['file_remote'])) ? filter_var($req['file_remote'], FILTER_VALIDATE_BOOLEAN) : FALSE;
|
283 |
+
|
284 |
+
$_basename_dir_app_data = c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir']);
|
285 |
+
$rewrite_base_guess = (is_dir(dirname($GLOBALS['WS_PLUGIN__']['s2member']['c']['dir']).'/'.$_basename_dir_app_data)) ? dirname($GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url']).'/'.$_basename_dir_app_data : content_url('/'.$_basename_dir_app_data);
|
286 |
+
$rewrite_base = ($req['file_rewrite_base'] && is_string($req['file_rewrite_base'])) ? $req['file_rewrite_base'] : FALSE;
|
287 |
+
$rewrite = $rewriting = (!$rewrite_base && isset($req['file_rewrite'])) ? filter_var($req['file_rewrite'], FILTER_VALIDATE_BOOLEAN) : (($rewrite_base) ? TRUE : FALSE);
|
288 |
+
unset($_basename_dir_app_data); // A little housekeeping here.
|
289 |
+
|
290 |
+
$skip_confirmation = (isset($req['skip_confirmation'])) ? filter_var($req['skip_confirmation'], FILTER_VALIDATE_BOOLEAN) : FALSE;
|
291 |
+
$url_to_storage_source = (isset($req['url_to_storage_source'])) ? filter_var($req['url_to_storage_source'], FILTER_VALIDATE_BOOLEAN) : FALSE;
|
292 |
+
|
293 |
+
$file = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'].'/'.$req['file_download'];
|
294 |
+
$pathinfo = (!$using_amazon_storage && $file) ? pathinfo($file) : array();
|
295 |
+
$mimetype = ($mimetypes[$extension]) ? $mimetypes[$extension] : 'application/octet-stream';
|
296 |
+
$disposition = (($inline) ? 'inline' : 'attachment').'; filename="'.c_ws_plugin__s2member_utils_strings::esc_dq($basename).'"; filename*=UTF-8\'\''.rawurlencode($basename);
|
297 |
+
$length = (!$using_amazon_storage && $file) ? filesize($file) : -1;
|
298 |
+
|
299 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $__v;
|
300 |
+
do_action('ws_plugin__s2member_during_file_download_access', get_defined_vars());
|
301 |
+
unset($__refs, $__v); // Housekeeping.
|
302 |
+
|
303 |
+
if($using_amazon_storage && $using_amazon_cf_storage && ($serving || ($creating && $url_to_storage_source)))
|
304 |
+
{
|
305 |
+
if($serving) // We only need this section when/if we're actually serving.
|
306 |
+
wp_redirect(c_ws_plugin__s2member_files_in::amazon_cf_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype)).exit();
|
307 |
+
|
308 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', c_ws_plugin__s2member_files_in::amazon_cf_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype), get_defined_vars());
|
309 |
+
}
|
310 |
+
else if($using_amazon_storage && $using_amazon_s3_storage && ($serving || ($creating && $url_to_storage_source)))
|
311 |
+
{
|
312 |
+
if($serving) // We only need this section when/if we're actually serving.
|
313 |
+
wp_redirect(c_ws_plugin__s2member_files_in::amazon_s3_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype)).exit();
|
314 |
+
|
315 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', c_ws_plugin__s2member_files_in::amazon_s3_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype), get_defined_vars());
|
316 |
+
}
|
317 |
+
else if($creating && $rewriting) // Creating a rewrite URL, pointing to local storage.
|
318 |
+
{ // Note: we don't URL encode unreserved chars. Improves media player compatibility.
|
319 |
+
|
320 |
+
$_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : '';
|
321 |
+
$_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : '';
|
322 |
+
$_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req['file_download']));
|
323 |
+
$_url_e_file = str_ireplace('%2F', '/', $_url_e_file);
|
324 |
+
|
325 |
+
$url = ($rewrite_base) ? rtrim($rewrite_base, '/') : rtrim($rewrite_base_guess, '/');
|
326 |
+
$url .= (isset($req['file_download_key'])) ? (($key && $_url_e_key) ? '/s2member-file-download-key-'.$_url_e_key : '') : '';
|
327 |
+
$url .= (isset($req['file_stream'])) ? (($stream) ? '/s2member-file-stream' : '/s2member-file-stream-no') : '';
|
328 |
+
$url .= (isset($req['file_inline'])) ? (($inline) ? '/s2member-file-inline' : '/s2member-file-inline-no') : '';
|
329 |
+
$url .= (isset($req['file_storage'])) ? (($storage && $_url_e_storage) ? '/s2member-file-storage-'.$_url_e_storage : '') : '';
|
330 |
+
$url .= (isset($req['file_remote'])) ? (($remote) ? '/s2member-file-remote' : '/s2member-file-remote-no') : '';
|
331 |
+
$url .= (isset($req['skip_confirmation'])) ? (($skip_confirmation) ? '/s2member-skip-confirmation' : '/s2member-skip-confirmation-no') : '';
|
332 |
+
|
333 |
+
$url = $url.'/'.$_url_e_file; // File Download Access URL via `mod_rewrite` functionality.
|
334 |
+
$url = ($ssl) ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
|
335 |
+
|
336 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
|
337 |
+
}
|
338 |
+
else if($creating) // Else we're creating a URL w/ a query-string; w/ local storage.
|
339 |
+
{ // Note: we don't URL encode unreserved chars. Improves media player compatibility.
|
340 |
+
|
341 |
+
$_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : '';
|
342 |
+
$_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : '';
|
343 |
+
$_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req['file_download']));
|
344 |
+
$_url_e_file = str_ireplace('%2F', '/', $_url_e_file);
|
345 |
+
|
346 |
+
$url = (isset($req['file_download_key'])) ? (($key && $_url_e_key) ? '&s2member_file_download_key='.$_url_e_key : '') : '';
|
347 |
+
$url .= (isset($req['file_stream'])) ? (($stream) ? '&s2member_file_stream=yes' : '&s2member_file_stream=no') : '';
|
348 |
+
$url .= (isset($req['file_inline'])) ? (($inline) ? '&s2member_file_inline=yes' : '&s2member_file_inline=no') : '';
|
349 |
+
$url .= (isset($req['file_storage'])) ? (($storage && $_url_e_storage) ? '&s2member_file_storage='.$_url_e_storage : '') : '';
|
350 |
+
$url .= (isset($req['file_remote'])) ? (($remote) ? '&s2member_file_remote=yes' : '&s2member_file_remote=no') : '';
|
351 |
+
$url .= (isset($req['skip_confirmation'])) ? (($skip_confirmation) ? '&s2member_skip_confirmation=yes' : '&s2member_skip_confirmation=no') : '';
|
352 |
+
|
353 |
+
$url = site_url('/?'.ltrim($url.'&s2member_file_download=/'.$_url_e_file, '&'));
|
354 |
+
$url = ($ssl) ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
|
355 |
+
|
356 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
|
357 |
+
}
|
358 |
+
else if($serving) // Else, ``if ($serving)``, use local storage.
|
359 |
+
{
|
360 |
+
@set_time_limit(0);
|
361 |
+
|
362 |
+
@ini_set('zlib.output_compression', 0);
|
363 |
+
if(function_exists('apache_setenv'))
|
364 |
+
@apache_setenv('no-gzip', '1');
|
365 |
+
|
366 |
+
$content_encoding_header = 'Content-Encoding:'; // Default value; standards compliant.
|
367 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_content_encodong_none'])
|
368 |
+
$content_encoding_header = 'Content-Encoding: none';
|
369 |
+
|
370 |
+
while(@ob_end_clean()) ; // Cleans existing output buffers.
|
371 |
+
|
372 |
+
if($range) // Requesting a specific byte range?
|
373 |
+
{
|
374 |
+
if(strpos($range, '=') === FALSE) // Invalid range?
|
375 |
+
{
|
376 |
+
status_header(416);
|
377 |
+
nocache_headers();
|
378 |
+
header($content_encoding_header);
|
379 |
+
header('Accept-Ranges: bytes');
|
380 |
+
header('Content-Type: '.$mimetype);
|
381 |
+
header('Content-Length: '.$length);
|
382 |
+
header('Content-Disposition: '.$disposition);
|
383 |
+
exit(); // Stop here (invalid).
|
384 |
+
}
|
385 |
+
list($range_type, $byte_range) = preg_split('/\s*\=\s*/', $range, 2);
|
386 |
|
387 |
+
$range_type = strtolower(trim($range_type));
|
388 |
+
$byte_range = trim($byte_range);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
|
390 |
+
if($range_type !== 'bytes') // Invalid range type?
|
391 |
+
{
|
392 |
+
status_header(416);
|
393 |
+
nocache_headers();
|
394 |
+
header($content_encoding_header);
|
395 |
+
header('Accept-Ranges: bytes');
|
396 |
+
header('Content-Type: '.$mimetype);
|
397 |
+
header('Content-Length: '.$length);
|
398 |
+
header('Content-Disposition: '.$disposition);
|
399 |
+
exit(); // Stop here (invalid).
|
400 |
+
}
|
401 |
+
$byte_ranges = preg_split('/\s*,\s*/', $byte_range);
|
402 |
|
403 |
+
if(strpos($byte_ranges[0], '-') === FALSE) // Invalid byte range?
|
404 |
+
{
|
405 |
+
status_header(416);
|
406 |
+
nocache_headers();
|
407 |
+
header($content_encoding_header);
|
408 |
+
header('Accept-Ranges: bytes');
|
409 |
+
header('Content-Type: '.$mimetype);
|
410 |
+
header('Content-Length: '.$length);
|
411 |
+
header('Content-Disposition: '.$disposition);
|
412 |
+
exit(); // Stop here (invalid).
|
413 |
+
}
|
414 |
+
// Only dealing with the first byte range. Others are simply ignored here.
|
415 |
+
list($byte_range_start, $byte_range_stops) = preg_split('/\s*\-\s*/', $byte_ranges[0], 2);
|
416 |
|
417 |
+
$byte_range_start = trim($byte_range_start);
|
418 |
+
$byte_range_stops = trim($byte_range_stops);
|
419 |
|
420 |
+
$byte_range_start = ($byte_range_start === '') ? NULL : (integer)$byte_range_start;
|
421 |
+
$byte_range_stops = ($byte_range_stops === '') ? NULL : (integer)$byte_range_stops;
|
422 |
|
423 |
+
if(!isset($byte_range_start) && $byte_range_stops > 0 && $byte_range_stops <= $length)
|
424 |
+
{
|
425 |
+
$byte_range_start = $length - $byte_range_stops;
|
426 |
+
$byte_range_stops = $length - 1; // The last X number of bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
}
|
428 |
+
else if(!isset($byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1)
|
429 |
+
{
|
430 |
+
$byte_range_stops = $length - 1; // To the end of the file in this case.
|
431 |
+
}
|
432 |
+
else if(isset($byte_range_start, $byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1 && $byte_range_stops > $byte_range_start && $byte_range_stops <= $length - 1)
|
433 |
+
{
|
434 |
+
// Nothing to do in this case, starts/stops already defined properly.
|
435 |
+
}
|
436 |
+
else // We have an invalid byte range.
|
437 |
+
{
|
438 |
+
status_header(416);
|
439 |
+
nocache_headers();
|
440 |
+
header($content_encoding_header);
|
441 |
+
header('Accept-Ranges: bytes');
|
442 |
+
header('Content-Type: '.$mimetype);
|