s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members) - Version 111216

Version Description

Download this release

Release Info

Developer PriMoThemes
Plugin Icon 128x128 s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members)
Version 111216
Comparing to
See all releases

Code changes from version 111206 to 111216

includes/classes/files-in.inc.php CHANGED
@@ -50,8 +50,8 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
50
  $_g = !empty ($_GET) ? $_GET : array ();
51
  $_g = c_ws_plugin__s2member_utils_strings::trim_deep (stripslashes_deep ($_g));
52
  /**/
53
- $creating = (is_array ($create = $create_file_download_url)) ? true : false; /* Creating URL? */
54
- $serving = (!$creating) ? true : false; /* If NOT creating a File Download URL, we're serving one. */
55
  /**/
56
  $req["file_download"] = ($creating) ? @$create["file_download"] : @$_g["s2member_file_download"];
57
  $req["file_download_key"] = ($creating) ? @$create["file_download_key"] : @$_g["s2member_file_download_key"];
@@ -75,18 +75,18 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
75
  {
76
  $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;
77
  $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;
78
- $using_amazon_storage = ($using_amazon_s3_storage || $using_amazon_cf_storage) ? true : false; /* Either/or? */
79
  /**/
80
  $excluded = apply_filters ("ws_plugin__s2member_check_file_download_access_excluded", false, get_defined_vars ());
81
  $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;
82
  $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;
83
  $updating_user_counter = (!$checking_user || ($creating && (!isset ($req["count_against_user"]) || !filter_var ($req["count_against_user"], FILTER_VALIDATE_BOOLEAN)))) ? false : true;
84
  /**/
85
- if (($serving || $creating) && $checking_user) /* In either case, the following routines apply whenever we ARE ``$checking_user``. */
86
  {
87
  if (!$using_amazon_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $req["file_download"]))
88
  {
89
- if ($serving) /* We only need this section when/if we're actually serving. */
90
  status_header (404) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
91
  . exit (_x ('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
92
  /**/
@@ -96,7 +96,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
96
  /**/
97
  else if ($req["file_download_key"] && is_string ($req["file_download_key"]) && !$valid_file_download_key)
98
  {
99
- if ($serving) /* We only need this section when/if we're actually serving. */
100
  status_header (503) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
101
  . exit (_x ('<strong>503 ( Invalid Key ):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', "s2member-front", "s2member"));
102
  /**/
@@ -106,17 +106,17 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
106
  /**/
107
  else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"] || ($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads ()) === false)
108
  {
109
- if ($serving) /* We only need remote functionality when/if we're actually serving. */
110
  if (!has_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization"))
111
  add_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
112
  /**/
113
- if ($creating) /* We only need remote functionality when/if we're actually serving. */
114
  if (has_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization"))
115
  remove_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
116
  /**/
117
  if ((isset ($file_downloads_enabled_by_site_owner, $min_level_4_downloads) && $file_downloads_enabled_by_site_owner === false) || ($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads ()) === false)
118
  {
119
- if ($serving) /* We only need this section when/if we're actually serving. */
120
  status_header (503) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
121
  . 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"));
122
  /**/
@@ -128,7 +128,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
128
  {
129
  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)))
130
  {
131
- if ($serving) /* We only need this section when/if we're actually serving. */
132
  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 ();
133
  /**/
134
  else /* Else return false. */
@@ -137,14 +137,14 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
137
  /**/
138
  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)))
139
  {
140
- if ($serving) /* We only need this section when/if we're actually serving. */
141
  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 ();
142
  /**/
143
  else /* Else return false. */
144
  return false;
145
  }
146
  /**/
147
- else if ($serving) /* We only need this section when/if we're actually serving. */
148
  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 ();
149
  /**/
150
  else /* Else return false. */
@@ -153,7 +153,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
153
  /**/
154
  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))
155
  {
156
- if ($serving) /* We only need this section when/if we're actually serving. */
157
  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 ();
158
  /**/
159
  else /* Else return false. */
@@ -162,16 +162,16 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
162
  /**/
163
  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))
164
  {
165
- if ($serving) /* We only need this section when/if we're actually serving. */
166
  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 ();
167
  /**/
168
  else /* Else return false. */
169
  return false;
170
  }
171
  /**/
172
- else if ($serving || $creating) /* In either case, the following routines apply. */
173
  {
174
- $user_previous_file_downloads = 0; /* Downloads the User has already; in current period/cycle. */
175
  $user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = false;
176
  /**/
177
  $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 ();
@@ -186,18 +186,18 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
186
  {
187
  if (strtotime ($user_file_download_access_log_entry["date"]) < strtotime ("-" . $user_file_downloads["allowed_days"] . " days"))
188
  {
189
- unset ($user_file_download_access_log[$user_file_download_access_log_entry_key]); /* Remove it from the `log`. */
190
- $user_file_download_access_arc[] = $user_file_download_access_log_entry; /* Move `log` entry to the `archive` now. */
191
  }
192
  else if (strtotime ($user_file_download_access_log_entry["date"]) >= strtotime ("-" . $user_file_downloads["allowed_days"] . " days"))
193
  {
194
- $user_previous_file_downloads++; /* Previous files always count against this User/Member; it's already in the `log`. */
195
  /**/
196
  $_user_file_download_access_log_entry = &$user_file_download_access_log[$user_file_download_access_log_entry_key];
197
  $_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = false;
198
  /**/
199
- if ($user_file_download_access_log_entry["file"] === $req["file_download"]) /* Already downloaded this file? If yes, mark this flag as true. */
200
- $user_already_downloaded_this_file = $_user_already_downloaded_this_file = true; /* Already downloaded this file? If yes, mark as true. */
201
  /**/
202
  else if (preg_replace ($streaming_variations, "", $user_file_download_access_log_entry["file"]) === preg_replace ($streaming_variations, "", $req["file_download"]))
203
  $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;
@@ -213,21 +213,21 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
213
  }
214
  }
215
  }
216
- else /* Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries by mistake. */
217
- unset ($user_file_download_access_log[$user_file_download_access_log_entry_key]); /* Remove from `log`. */
218
  }
219
  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)
220
  $user_file_download_access_log[] = array ("date" => date ("Y-m-d"), "time" => time (), "ltime" => time (), "file" => $req["file_download"], "counter" => 1);
221
  /**/
222
  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"))
223
  {
224
- if ($serving) /* We only need this section when/if we're actually serving. */
225
  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 ();
226
  /**/
227
  else /* Else return false. */
228
  return false;
229
  }
230
- else if /* Save/update counter? */ ($updating_user_counter) /* By default, we do NOT update the counter when a URL is simply being created for access. */
231
  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));
232
  }
233
  }
@@ -236,7 +236,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
236
  {
237
  if (!$using_amazon_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $req["file_download"]))
238
  {
239
- if ($serving) /* We only need this section when/if we're actually serving. */
240
  status_header (404) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
241
  . exit (_x ('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
242
  /**/
@@ -245,7 +245,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
245
  }
246
  }
247
  /**/
248
- if ($serving || $creating) /* In either case, the following routines apply. */
249
  {
250
  $basename = basename ($req["file_download"]);
251
  $mimetypes = parse_ini_file (dirname (dirname (dirname (__FILE__))) . "/includes/mime-types.ini");
@@ -276,7 +276,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
276
  /**/
277
  if ($using_amazon_s3_storage && ($serving || ($creating && $url_to_storage_source)))
278
  {
279
- if ($serving) /* We only need this section when/if we're actually serving. */
280
  wp_redirect (c_ws_plugin__s2member_files_in::amazon_s3_url ($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)) . exit ();
281
  /**/
282
  else /* Else return File Download URL. */
@@ -285,14 +285,14 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
285
  /**/
286
  else if ($using_amazon_cf_storage && ($serving || ($creating && $url_to_storage_source)))
287
  {
288
- if ($serving) /* We only need this section when/if we're actually serving. */
289
  wp_redirect (c_ws_plugin__s2member_files_in::amazon_cf_url ($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)) . exit ();
290
  /**/
291
  else /* Else return File Download URL. */
292
  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 ());
293
  }
294
  /**/
295
- else if ($creating && $rewriting) /* Creating a rewrite URL, pointing to local storage. */
296
  {
297
  $url = ($rewrite_base) ? rtrim ($rewrite_base, "/") : rtrim ($rewrite_base_guess, "/");
298
  $url .= (isset ($req["file_download_key"])) ? (($key) ? "/s2member-file-download-key-" . $key : "") : "";
@@ -302,15 +302,14 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
302
  $url .= (isset ($req["file_remote"])) ? (($remote) ? "/s2member-file-remote" : "/s2member-file-remote-no") : "";
303
  $url .= (isset ($req["skip_confirmation"])) ? (($skip_confirmation) ? "/s2member-skip-confirmation" : "/s2member-skip-confirmation-no") : "";
304
  /**/
305
- $url = $url . "/" . $req["file_download"]; /* File Download Access URL via `mod_rewrite` functionality. */
306
  $url = ($ssl) ? preg_replace ("/^https?/", "https", $url) : preg_replace ("/^https?/", "http", $url);
307
  /**/
308
  return apply_filters ("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars ());
309
  }
310
  /**/
311
- else if ($creating) /* Else we're creating a URL w/ a query-string; w/ local storage. */
312
- {
313
- /* * Note: we don't URL encode unreserved chars. Improves media player compatibility. */
314
  $_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep (urlencode ($key)) : "";
315
  $_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep (urlencode ($storage)) : "";
316
  $_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep (urlencode ($req["file_download"]));
@@ -328,14 +327,14 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
328
  return apply_filters ("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars ());
329
  }
330
  /**/
331
- else /* Else, ``if ($serving)`` , use local storage option (default). */
332
  {
333
  @set_time_limit (0) . @ini_set ("zlib.output_compression", 0);
334
  /**/
335
- status_header (200); /* 200 OK status header. */
336
  /**/
 
337
  header ("Accept-Ranges: none");
338
- header ("Content-Encoding: none");
339
  header ("Content-Type: " . $mimetype);
340
  header ("Expires: " . gmdate ("D, d M Y H:i:s", strtotime ("-1 week")) . " GMT");
341
  header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");
@@ -345,7 +344,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
345
  /**/
346
  header ('Content-Disposition: ' . (($inline) ? "inline" : "attachment") . '; filename="' . $basename . '"');
347
  /**/
348
- eval ('while (@ob_end_clean ());'); /* End/clean any output buffers that may exist already. Prep for content delivery. */
349
  /**/
350
  $_chunk_file = ($_SERVER["SERVER_PROTOCOL"] === "HTTP/1.1" && preg_match ("/apache/i", $_SERVER["SERVER_SOFTWARE"])) ? true : false;
351
  /**/
@@ -356,7 +355,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
356
  if (apply_filters ("ws_plugin__s2member_chunk_file_downloads_w_content_length", true, get_defined_vars ()))
357
  header ("Content-Length: " . $length);
358
  /**/
359
- header ("Transfer-Encoding: chunked"); /* `Transfer-Encoding: chunked` conserves memory. */
360
  /**/
361
  while (!feof ($resource) && ($chunk_size = strlen ($data = fread ($resource, $_chunk_size))))
362
  eval ('echo dechex ($chunk_size) . "\r\n". $data . "\r\n"; @flush ();');
@@ -371,11 +370,11 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
371
  header ("Content-Length: " . $length);
372
  /**/
373
  while (!feof ($resource) && ($flush_size = strlen ($data = fread ($resource, $_flush_size))))
374
- eval ('echo $data; @flush ();'); /* Conserves memory. */
375
  }
376
- else if ($length) /* Else, use: ``file_get_contents()``. */
377
  {
378
- @ini_set ("memory_limit", WP_MAX_MEMORY_LIMIT); /* RAM/memory. */
379
  header ("Content-Length: " . $length) . exit (file_get_contents ($file));
380
  }
381
  else /* Else, we have an empty file with no length. */
@@ -386,16 +385,16 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
386
  }
387
  }
388
  /**/
389
- else if ($serving && $req["file_download"]) /* We only need this section when/if we're actually serving. */
390
  status_header (503) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
391
  . exit (_x ('<strong>503: Access denied.</strong> Invalid File Download specs.', "s2member-front", "s2member"));
392
  /**/
393
- else if ($creating) /* We only need this section when/if we're creating a URL. */
394
  return false;
395
  /**/
396
  do_action ("ws_plugin__s2member_after_file_download_access", get_defined_vars ());
397
  /**/
398
- return ($creating) ? false : null; /* If creating, false. */
399
  }
400
  /**
401
  * Generates a File Download URL for access to a file protected by s2Member.
@@ -413,10 +412,10 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
413
  public static function create_file_download_url ($config = FALSE, $get_streamer_array = FALSE)
414
  {
415
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
416
- do_action ("ws_plugin__s2member_before_create_file_download_url", get_defined_vars ()); /* Be VERY careful, if you use this Hook. */
417
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
418
  /**/
419
- $config = (is_array ($config)) ? $config : array (); /* This absolutely MUST be an array. */
420
  /**/
421
  $config["file_download"] = (isset ($config["file_download"]) && is_string ($config["file_download"])) ? trim ($config["file_download"], "/") : @$config["file_download"];
422
  $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"];
@@ -424,10 +423,10 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
424
  $config["url_to_storage_source"] = /* Force a streaming URL here via ``$get_streamer_array``? */ ($get_streamer_array) ? true : @$config["url_to_storage_source"];
425
  $config["file_stream"] = /* Force a streaming URL here via ``$get_streamer_array``? */ ($get_streamer_array) ? true : @$config["file_stream"];
426
  /**/
427
- if (($_url = c_ws_plugin__s2member_files_in::check_file_download_access (($create_file_download_url = $config))) /* Successfully created a URL to the file? */)
428
  {
429
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
430
- do_action ("ws_plugin__s2member_during_create_file_download_url", get_defined_vars ()); /* Be VERY careful, if you use this Hook. */
431
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
432
  /**/
433
  $extension = strtolower (substr ($config["file_download"], strrpos ($config["file_download"], ".") + 1));
@@ -440,11 +439,11 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
440
  else if ($get_streamer_array && $streaming && is_array ($ups = c_ws_plugin__s2member_utils_urls::parse_url ($_url)) && isset ($ups["scheme"], $ups["host"]) && ($streamer = $ups["scheme"] . "://" . $ups["host"] . ((!empty ($ups["port"])) ? ":" . $ups["port"] : "")) && ($url = c_ws_plugin__s2member_files_in::check_file_download_access (array_merge ($config, array ("file_stream" => false, "check_user" => false, "count_against_user" => false)))))
441
  $return = array ("streamer" => $streamer, "file" => preg_replace ("/^" . preg_quote ($streamer, "/") . "\//", "", $_url), "url" => preg_replace ("/^.+?\:/", (($ssl) ? "https:" : "http:"), $url));
442
  /**/
443
- else if ($get_streamer_array) /* Else, we MUST return false here, unable to acquire streamer/file. */
444
- $return = false; /* We MUST return false here, unable to acquire streamer. */
445
  /**/
446
  else /* Else return URL string ( ``$get_streamer_array`` is false ). */
447
- $return = $_url; /* Else return URL string. */
448
  }
449
  /**/
450
  return apply_filters ("ws_plugin__s2member_create_file_download_url", ((isset ($return)) ? $return : false), get_defined_vars ());
@@ -476,18 +475,17 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
476
  {
477
  header ('WWW-Authenticate: Basic realm="' . c_ws_plugin__s2member_utils_strings::esc_dq (strip_tags (_x ("Members Only", "s2member-front", "s2member"))) . '"');
478
  /**/
479
- status_header (401); /* Send an unauthorized 401 status header now. */
480
- header ("Content-Type: text/html; charset=utf-8"); /* Content-Type with UTF-8. */
481
- eval ('while (@ob_end_clean ());'); /* End/clean any output buffers that may exist. */
482
  /**/
483
  exit (_x ('<strong>401:</strong> Sorry, access denied.', "s2member-front", "s2member"));
484
  }
485
  else if (is_object ($_user = new WP_User ($_SERVER["PHP_AUTH_USER"])) && !empty ($_user->ID))
486
- $user = $_user; /* Now assign ``$user``. */
487
  /**/
488
  do_action ("ws_plugin__s2member_during_check_file_remote_authorization_after", get_defined_vars ());
489
  }
490
- /**/
491
  return apply_filters ("ws_plugin__s2member_check_file_remote_authorization", $user, get_defined_vars ());
492
  }
493
  /**
@@ -506,16 +504,15 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
506
  do_action ("_ws_plugin__s2member_before_check_file_download_key", get_defined_vars ());
507
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
508
  /**/
509
- if ($file && is_string ($file) && ($file = trim ($file, "/")) && $key && is_string ($key)) /* Requirements to properly validate. */
510
  {
511
  if ($key === c_ws_plugin__s2member_files::file_download_key ($file) || $key === c_ws_plugin__s2member_files::file_download_key ("/" . $file))
512
- $valid = true; /* File Download Key is valid. */
513
  else if ($key === c_ws_plugin__s2member_files::file_download_key ($file, "ip-forever") || $key === c_ws_plugin__s2member_files::file_download_key ("/" . $file, "ip-forever"))
514
- $valid = true; /* File Download Key is valid. */
515
  else if ($key === c_ws_plugin__s2member_files::file_download_key ($file, "universal") || $key === c_ws_plugin__s2member_files::file_download_key ("/" . $file, "universal"))
516
- $valid = true; /* File Download Key is valid. */
517
  }
518
- /**/
519
  return apply_filters ("ws_plugin__s2member_check_file_download_key", ((isset ($valid) && $valid) ? true : false), get_defined_vars ());
520
  }
521
  /**
@@ -549,7 +546,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
549
  */
550
  public static function amazon_s3_url ($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
551
  {
552
- $file = trim ((string)$file, "/"); /* Trim / force string. */
553
  /**/
554
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
555
  if (preg_match ("/^amazon_s3_files_/", $option) && ($option = preg_replace ("/^amazon_s3_files_/", "", $option)))
@@ -562,6 +559,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
562
  $s3_signature = base64_encode (c_ws_plugin__s2member_files_in::amazon_s3_sign ("GET\n\n\n" . $s3c["expires"] . "\n" . "/" . $s3c["bucket"] . $s3_raw_file));
563
  /**/
564
  $s3_url = ((strtolower ($s3c["bucket"]) !== $s3c["bucket"])) ? "http" . (($ssl) ? "s" : "") . "://s3.amazonaws.com/" . $s3c["bucket"] . $s3_file : "http" . (($ssl) ? "s" : "") . "://" . $s3c["bucket"] . ".s3.amazonaws.com" . $s3_file;
 
565
  return add_query_arg (c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep /* Don't encode unreserved chars. Maximizes media player compatibility. */
566
  (urlencode_deep (array ("AWSAccessKeyId" => $s3c["access_key"], "Expires" => $s3c["expires"], "Signature" => $s3_signature))), $s3_url);
567
  }
@@ -582,7 +580,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
582
  /**/
583
  $cfc["distros_s3_access_id"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_s3_access_id"];
584
  /**/
585
- if ($s3c["bucket"] && $s3c["access_key"] && $s3c["secret_key"]) /* Must have Amazon® S3 Bucket/Keys. */
586
  {
587
  $s3_date = gmdate ("D, d M Y H:i:s") . " GMT";
588
  $s3_location = ((strtolower ($s3c["bucket"]) !== $s3c["bucket"])) ? "/" . $s3c["bucket"] . "/?acl" : "/?acl";
@@ -602,7 +600,8 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
602
  if (($s3_response = c_ws_plugin__s2member_utils_urls::remote ("https://" . $s3_domain . $s3_location, false, array_merge ($s3_args, array ("timeout" => 20)), "array")) && $s3_response["code"] === 200)
603
  {
604
  $s3_location = ((strtolower ($s3c["bucket"]) !== $s3c["bucket"])) ? "/" . $s3c["bucket"] . "/?policy" : "/?policy";
605
- $s3_policy_json = '{"Version":"2008-10-17","Id":"' . md5 ("s2Member/CloudFront") . '","Statement":[{"Sid":"s2Member/CloudFront","Effect":"Allow","Principal":{"CanonicalUser":"' . c_ws_plugin__s2member_utils_strings::esc_dq ($cfc["distros_s3_access_id"]) . '"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::' . c_ws_plugin__s2member_utils_strings::esc_dq ($s3c["bucket"]) . '/*"}]}';
 
606
  $s3_signature = base64_encode (c_ws_plugin__s2member_files_in::amazon_s3_sign ("PUT\n\napplication/json\n" . $s3_date . "\n/" . $s3c["bucket"] . "/?policy"));
607
  $s3_args = array ("method" => "PUT", "body" => $s3_policy_json, "headers" => array ("Host" => $s3_domain, "Content-Type" => "application/json", "Date" => $s3_date, "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature));
608
  /**/
@@ -614,7 +613,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
614
  $s3_args = array ("method" => "PUT", "body" => $s3_policy_xml, "headers" => array ("Host" => $s3_domain, "Content-Type" => "text/xml", "Date" => $s3_date, "X-Amz-Acl" => "public-read", "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature));
615
  /**/
616
  if (($s3_response = c_ws_plugin__s2member_utils_urls::remote ("https://" . $s3_domain . $s3_location, false, array_merge ($s3_args, array ("timeout" => 20)), "array")) && $s3_response["code"] === 200)
617
- return array ("success" => true, "code" => null, "message" => null); /* Successfully configured Amazon® S3 Bucket ACLs and Policy. */
618
  /**/
619
  else if (isset ($s3_response["code"], $s3_response["message"]))
620
  /* 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. */
@@ -699,7 +698,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
699
  */
700
  public static function amazon_cf_url ($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
701
  {
702
- $file = trim ((string)$file, "/"); /* Trim / force string. */
703
  /**/
704
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
705
  if (preg_match ("/^amazon_cf_files_/", $option) && ($option = preg_replace ("/^amazon_cf_files_/", "", $option)))
@@ -707,8 +706,8 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
707
  /**/
708
  $cfc["expires"] = strtotime ("+" . apply_filters ("ws_plugin__s2member_amazon_cf_file_expires_time", "24 hours", get_defined_vars ()));
709
  /**/
710
- $cf_extn = strtolower (substr ($file, strrpos ($file, ".") + 1)); /* Parses the file extension out so we can scan it in some special scenarios. */
711
- $cf_ip_res = (c_ws_plugin__s2member_utils_conds::is_localhost ()) ? false : true; /* Do NOT restrict access to a particular IP during `localhost` development. The IP may NOT be the same one Amazon® CloudFront sees. */
712
  $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 ()));
713
  $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"]) . "/" . $file;
714
  $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"]) . "/" . $file;
@@ -740,63 +739,63 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
740
  $cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
741
  $cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
742
  /**/
743
- if ($s3c["bucket"] && $s3c["access_key"] && $s3c["secret_key"]) /* We MUST have an Amazon® S3 Bucket and Keys. */
744
  {
745
- if ($cfc["private_key"] && $cfc["private_key_id"]) /* We MUST have Amazon® CloudFront Keys in order to auto-configure. */
746
  {
747
  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)))
748
  {
749
  if (!$cfc["distro_downloads_id"] || ($cfc["distro_downloads_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
750
- $cf_distro_downloads_clear = true; /* Clear, ready for a new one. */
751
  /**/
752
  else if ($cfc["distro_downloads_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
753
  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"));
754
  /**/
755
  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"])
756
- $cf_distro_downloads_clear = true; /* Clear, ready for a new one. */
757
  /**/
758
  else if (isset ($cf_del_response["code"], $cf_del_response["message"]))
759
  /* 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. */
760
  return array ("success" => false, "code" => $cf_del_response["code"], "message" => sprintf (_x ("Unable to delete existing Amazon® CloudFront Downloads Distro. %s", "s2member-admin", "s2member"), $cf_del_response["message"]));
761
  /**/
762
- if (isset ($cf_distro_downloads_clear) && $cf_distro_downloads_clear) /* Successfully cleared? Ready for a new one? */
763
  {
764
- unset ($cf_get_response, $cf_del_response); /* Unset these before processing additional routines. Prevents problems in error reporting. */
765
  /**/
766
  if (!$cfc["distro_streaming_id"] || ($cfc["distro_streaming_id"] && ($cf_get_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro ($cfc["distro_streaming_id"], "streaming")) && ($cf_get_response["success"] || $cf_get_response["code"] === 404)))
767
  {
768
  if (!$cfc["distro_streaming_id"] || ($cfc["distro_streaming_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
769
- $cf_distro_streaming_clear = true; /* Clear, ready for a new one. */
770
  /**/
771
  else if ($cfc["distro_streaming_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
772
  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"));
773
  /**/
774
  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"])
775
- $cf_distro_streaming_clear = true; /* Clear, ready for a new one. */
776
  /**/
777
  else if (isset ($cf_del_response["code"], $cf_del_response["message"]))
778
  /* 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. */
779
  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"]));
780
  /**/
781
- if (isset ($cf_distro_streaming_clear) && $cf_distro_streaming_clear) /* Successfully cleared? Ready for a new one? */
782
  {
783
- unset ($cf_get_response, $cf_del_response); /* Unset these before processing additional routines. Prevents problems in error reporting. */
784
  /**/
785
  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)))
786
  {
787
  if (!$cfc["distros_access_id"] || ($cfc["distros_access_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
788
- $cf_distros_access_clear = true; /* Clear, ready for a new one. */
789
  /**/
790
  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"])
791
- $cf_distros_access_clear = true; /* Clear, ready for a new one. */
792
  /**/
793
  else if (isset ($cf_del_response["code"], $cf_del_response["message"]))
794
  /* 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. */
795
  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"]));
796
  /**/
797
- if (isset ($cf_distros_access_clear) && $cf_distros_access_clear) /* Successfully cleared? Ready for a new one? */
798
  {
799
- unset ($cf_get_response, $cf_del_response); /* Unset these before processing additional routines. Prevents problems in error reporting. */
800
  /**/
801
  $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" => ""));
802
  $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" => "");
@@ -820,16 +819,18 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
820
  $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"]);
821
  c_ws_plugin__s2member_menu_pages::update_all_options ($cf_options, true, false, false, false, false);
822
  /**/
823
- if (($s3_response = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls ()) && $s3_response["success"])
824
- {
825
- $cfc = array_merge ($cfc, array ("distros_auto_config_status" => "success"));
826
- $cf_options = array ("ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" => "configured");
827
- c_ws_plugin__s2member_menu_pages::update_all_options ( /* Now configured! */$cf_options, true, false, false, false, false);
828
- /**/
829
- return array ("success" => true, "code" => null, "message" => null); /* Successfully configured Amazon® S3/CloudFront distros. */
830
- }
831
- /**/
832
- else if (isset ($s3_response["code"], $s3_response["message"]))
 
 
833
  /* 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. */
834
  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"]));
835
  /**/
@@ -905,7 +906,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
905
  */
906
  public static function amazon_cf_get_access_origin_identity ($access_id = FALSE)
907
  {
908
- if ($access_id && is_string ($access_id)) /* Valid parameters? */
909
  {
910
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
911
  if (preg_match ("/^amazon_cf_files_/", $option) && ($option = preg_replace ("/^amazon_cf_files_/", "", $option)))
@@ -970,7 +971,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
970
  $cf_args = array ("method" => "DELETE", "headers" => array ("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $access_id_etag, "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
971
  /**/
972
  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. */))
973
- return array ("success" => true, "code" => null, "message" => null); /* Deleted successfully. */
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. */
@@ -1085,13 +1086,11 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
1085
  */
1086
  public static function amazon_cf_disable_distro ($distro_id = FALSE, $distro_id_etag = FALSE, $distro_id_xml = FALSE)
1087
  {
1088
- if ($distro_id && is_string ($distro_id) && $distro_id_etag && is_string ($distro_id_etag) && $distro_id_xml && is_string ($distro_id_xml) /* Parse type/reference too. */
1089
- && ($distro_id_type = (stripos ($distro_id_xml, "<StreamingDistribution") !== false) ? "streaming" : ((stripos ($distro_id_xml, "<Distribution") !== false) ? "downloads" : false)) #
1090
- && preg_match ("/\<CallerReference\>(.+?)\<\/CallerReference\>/is", $distro_id_xml, $distro_id_reference_tag) && ($distro_id_reference = $distro_id_reference_tag[1]))
1091
  {
1092
- if (stripos ($distro_id_xml, "<Enabled>false</Enabled>") === false) /* Only if it has NOT already been disabled. We do NOT need to do it again. */
1093
  {
1094
- if (stripos ($distro_id_xml, "<Status>Deployed</Status>") !== false) /* Check distro status before we even begin processing. */
1095
  {
1096
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
1097
  if (preg_match ("/^amazon_cf_files_/", $option) && ($option = preg_replace ("/^amazon_cf_files_/", "", $option)))
@@ -1141,11 +1140,9 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
1141
  */
1142
  public static function amazon_cf_del_distro ($distro_id = FALSE, $distro_id_etag = FALSE, $distro_id_xml = FALSE)
1143
  {
1144
- if ($distro_id && is_string ($distro_id) && $distro_id_etag && is_string ($distro_id_etag) && $distro_id_xml && is_string ($distro_id_xml) /* Parse type/reference too. */
1145
- && ($distro_id_type = (stripos ($distro_id_xml, "<StreamingDistribution") !== false) ? "streaming" : ((stripos ($distro_id_xml, "<Distribution") !== false) ? "downloads" : false)) #
1146
- && preg_match ("/\<CallerReference\>(.+?)\<\/CallerReference\>/is", $distro_id_xml, $distro_id_reference_tag) && ($distro_id_reference = $distro_id_reference_tag[1]))
1147
  {
1148
- if (stripos ($distro_id_xml, "<Status>Deployed</Status>") !== false) /* Check distro status before we even begin processing this deletion. */
1149
  {
1150
  if (($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_disable_distro ($distro_id, $distro_id_etag, $distro_id_xml)) && $cf_response["success"])
1151
  {
@@ -1166,7 +1163,7 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
1166
  $cf_args = array ("method" => "DELETE", "headers" => array ("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $cf_response["etag"], "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
1167
  /**/
1168
  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. */))
1169
- return array ("success" => true, "code" => null, "message" => null); /* Deleted successfully. */
1170
  /**/
1171
  else if (isset ($cf_response["code"], $cf_response["message"]))
1172
  /* 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. */
@@ -1225,9 +1222,9 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
1225
  $cf_date = gmdate ("D, d M Y H:i:s") . " GMT";
1226
  $cf_signature = base64_encode (c_ws_plugin__s2member_files_in::amazon_cf_sign ($cf_date));
1227
  /**/
1228
- if ($distro_type === "downloads") /* Create a `downloads` Distro? This uses a different XML schema. */
1229
  {
1230
- $cf_location = "/2010-11-01/distribution"; /* Create distro. */
1231
  $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"]);
1232
  $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>';
1233
  $cf_args = array ("method" => "POST", "body" => $cf_distro_downloads_xml, "headers" => array ("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
@@ -1236,19 +1233,21 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
1236
  {
1237
  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))
1238
  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]));
 
1239
  else /* Else, we use a default error code and message. */
1240
  return array ("success" => false, "code" => -97, "message" => _x ("Unable to create/read Amazon® CloudFront Downloads Distro. Unexpected response.", "s2member-admin", "s2member"));
1241
  }
1242
  else if (isset ($cf_response["code"], $cf_response["message"]))
1243
  /* 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. */
1244
  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"]));
 
1245
  else /* Else, we use a default error code and message. */
1246
  return array ("success" => false, "code" => -98, "message" => _x ("Unable to create Amazon® CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
1247
  }
1248
  /**/
1249
- else if ($distro_type === "streaming") /* Create a `streaming` Distro? A different XML schema. */
1250
  {
1251
- $cf_location = "/2010-11-01/streaming-distribution"; /* Create streaming distro. */
1252
  $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"]);
1253
  $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>';
1254
  $cf_args = array ("method" => "POST", "body" => $cf_distro_streaming_xml, "headers" => array ("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
@@ -1257,12 +1256,14 @@ if (!class_exists ("c_ws_plugin__s2member_files_in"))
1257
  {
1258
  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))
1259
  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]));
 
1260
  else /* Else, we use a default error code and message. */
1261
  return array ("success" => false, "code" => -97, "message" => _x ("Unable to create/read Amazon® CloudFront Streaming Distro. Unexpected response.", "s2member-admin", "s2member"));
1262
  }
1263
  else if (isset ($cf_response["code"], $cf_response["message"]))
1264
  /* 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. */
1265
  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"]));
 
1266
  else /* Else, we use a default error code and message. */
1267
  return array ("success" => false, "code" => -98, "message" => _x ("Unable to create Amazon® CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
1268
  }
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
  /**/
56
  $req["file_download"] = ($creating) ? @$create["file_download"] : @$_g["s2member_file_download"];
57
  $req["file_download_key"] = ($creating) ? @$create["file_download_key"] : @$_g["s2member_file_download_key"];
75
  {
76
  $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;
77
  $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;
78
+ $using_amazon_storage = /* Either/or? */ ($using_amazon_s3_storage || $using_amazon_cf_storage) ? true : false;
79
  /**/
80
  $excluded = apply_filters ("ws_plugin__s2member_check_file_download_access_excluded", false, get_defined_vars ());
81
  $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;
82
  $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;
83
  $updating_user_counter = (!$checking_user || ($creating && (!isset ($req["count_against_user"]) || !filter_var ($req["count_against_user"], FILTER_VALIDATE_BOOLEAN)))) ? false : true;
84
  /**/
85
+ if ( /* In either case, the following routines apply whenever we ARE ``$checking_user``. */($serving || $creating) && $checking_user)
86
  {
87
  if (!$using_amazon_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $req["file_download"]))
88
  {
89
+ if /* We only need this section when/if we're actually serving. */ ($serving)
90
  status_header (404) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
91
  . exit (_x ('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
92
  /**/
96
  /**/
97
  else if ($req["file_download_key"] && is_string ($req["file_download_key"]) && !$valid_file_download_key)
98
  {
99
+ if /* We only need this section when/if we're actually serving. */ ($serving)
100
  status_header (503) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
101
  . exit (_x ('<strong>503 ( Invalid Key ):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', "s2member-front", "s2member"));
102
  /**/
106
  /**/
107
  else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"] || ($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads ()) === false)
108
  {
109
+ if /* We only need remote functionality when/if we're actually serving. */ ($serving)
110
  if (!has_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization"))
111
  add_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
112
  /**/
113
+ if /* We only need remote functionality when/if we're actually serving. */ ($creating)
114
  if (has_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization"))
115
  remove_filter ("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
116
  /**/
117
  if ((isset ($file_downloads_enabled_by_site_owner, $min_level_4_downloads) && $file_downloads_enabled_by_site_owner === false) || ($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads ()) === false)
118
  {
119
+ if /* We only need this section when/if we're actually serving. */ ($serving)
120
  status_header (503) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
121
  . 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"));
122
  /**/
128
  {
129
  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)))
130
  {
131
+ if /* We only need this section when/if we're actually serving. */ ($serving)
132
  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 ();
133
  /**/
134
  else /* Else return false. */
137
  /**/
138
  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)))
139
  {
140
+ if /* We only need this section when/if we're actually serving. */ ($serving)
141
  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 ();
142
  /**/
143
  else /* Else return false. */
144
  return false;
145
  }
146
  /**/
147
+ else if /* We only need this section when/if we're actually serving. */ ($serving)
148
  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 ();
149
  /**/
150
  else /* Else return false. */
153
  /**/
154
  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))
155
  {
156
+ if /* We only need this section when/if we're actually serving. */ ($serving)
157
  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 ();
158
  /**/
159
  else /* Else return false. */
162
  /**/
163
  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))
164
  {
165
+ if /* We only need this section when/if we're actually serving. */ ($serving)
166
  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 ();
167
  /**/
168
  else /* Else return false. */
169
  return false;
170
  }
171
  /**/
172
+ else if /* In either case, the following routines apply. */ ($serving || $creating)
173
  {
174
+ $user_previous_file_downloads = /* Downloads the User has already; in current period/cycle. */ 0;
175
  $user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = false;
176
  /**/
177
  $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 ();
186
  {
187
  if (strtotime ($user_file_download_access_log_entry["date"]) < strtotime ("-" . $user_file_downloads["allowed_days"] . " days"))
188
  {
189
+ unset /* Remove it from the `log`. */ ($user_file_download_access_log[$user_file_download_access_log_entry_key]);
190
+ $user_file_download_access_arc[] = /* Move `log` entry to the `archive` now. */ $user_file_download_access_log_entry;
191
  }
192
  else if (strtotime ($user_file_download_access_log_entry["date"]) >= strtotime ("-" . $user_file_downloads["allowed_days"] . " days"))
193
  {
194
+ $user_previous_file_downloads++; /* Previous files always count against this User/Member. */
195
  /**/
196
  $_user_file_download_access_log_entry = &$user_file_download_access_log[$user_file_download_access_log_entry_key];
197
  $_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = false;
198
  /**/
199
+ if /* Already downloaded this file? If yes, mark this flag as true. */ ($user_file_download_access_log_entry["file"] === $req["file_download"])
200
+ $user_already_downloaded_this_file = $_user_already_downloaded_this_file = /* Already downloaded this file? If yes, mark as true. */ true;
201
  /**/
202
  else if (preg_replace ($streaming_variations, "", $user_file_download_access_log_entry["file"]) === preg_replace ($streaming_variations, "", $req["file_download"]))
203
  $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;
213
  }
214
  }
215
  }
216
+ else /* Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries. */
217
+ unset ($user_file_download_access_log[$user_file_download_access_log_entry_key]); /* Remove. */
218
  }
219
  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)
220
  $user_file_download_access_log[] = array ("date" => date ("Y-m-d"), "time" => time (), "ltime" => time (), "file" => $req["file_download"], "counter" => 1);
221
  /**/
222
  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"))
223
  {
224
+ if /* We only need this section when/if we're actually serving. */ ($serving)
225
  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 ();
226
  /**/
227
  else /* Else return false. */
228
  return false;
229
  }
230
+ 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)
231
  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));
232
  }
233
  }
236
  {
237
  if (!$using_amazon_storage && !file_exists ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"] . "/" . $req["file_download"]))
238
  {
239
+ if /* We only need this section when/if we're actually serving. */ ($serving)
240
  status_header (404) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
241
  . exit (_x ('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
242
  /**/
245
  }
246
  }
247
  /**/
248
+ if /* In either case, the following routines apply. */ ($serving || $creating)
249
  {
250
  $basename = basename ($req["file_download"]);
251
  $mimetypes = parse_ini_file (dirname (dirname (dirname (__FILE__))) . "/includes/mime-types.ini");
276
  /**/
277
  if ($using_amazon_s3_storage && ($serving || ($creating && $url_to_storage_source)))
278
  {
279
+ if /* We only need this section when/if we're actually serving. */ ($serving)
280
  wp_redirect (c_ws_plugin__s2member_files_in::amazon_s3_url ($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)) . exit ();
281
  /**/
282
  else /* Else return File Download URL. */
285
  /**/
286
  else if ($using_amazon_cf_storage && ($serving || ($creating && $url_to_storage_source)))
287
  {
288
+ if /* We only need this section when/if we're actually serving. */ ($serving)
289
  wp_redirect (c_ws_plugin__s2member_files_in::amazon_cf_url ($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)) . exit ();
290
  /**/
291
  else /* Else return File Download URL. */
292
  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 ());
293
  }
294
  /**/
295
+ else if /* Creating a rewrite URL, pointing to local storage. */ ($creating && $rewriting)
296
  {
297
  $url = ($rewrite_base) ? rtrim ($rewrite_base, "/") : rtrim ($rewrite_base_guess, "/");
298
  $url .= (isset ($req["file_download_key"])) ? (($key) ? "/s2member-file-download-key-" . $key : "") : "";
302
  $url .= (isset ($req["file_remote"])) ? (($remote) ? "/s2member-file-remote" : "/s2member-file-remote-no") : "";
303
  $url .= (isset ($req["skip_confirmation"])) ? (($skip_confirmation) ? "/s2member-skip-confirmation" : "/s2member-skip-confirmation-no") : "";
304
  /**/
305
+ $url = /* File Download Access URL via `mod_rewrite` functionality. */ $url . "/" . $req["file_download"];
306
  $url = ($ssl) ? preg_replace ("/^https?/", "https", $url) : preg_replace ("/^https?/", "http", $url);
307
  /**/
308
  return apply_filters ("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars ());
309
  }
310
  /**/
311
+ else if /* Else we're creating a URL w/ a query-string; w/ local storage. */ ($creating)
312
+ { /* Note: we don't URL encode unreserved chars. Improves media player compatibility. */
 
313
  $_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep (urlencode ($key)) : "";
314
  $_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep (urlencode ($storage)) : "";
315
  $_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep (urlencode ($req["file_download"]));
327
  return apply_filters ("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars ());
328
  }
329
  /**/
330
+ else /* Else, ``if ($serving)``, use local storage option. */
331
  {
332
  @set_time_limit (0) . @ini_set ("zlib.output_compression", 0);
333
  /**/
334
+ status_header /* 200 OK status header. */ (200);
335
  /**/
336
+ header ("Content-Encoding:");
337
  header ("Accept-Ranges: none");
 
338
  header ("Content-Type: " . $mimetype);
339
  header ("Expires: " . gmdate ("D, d M Y H:i:s", strtotime ("-1 week")) . " GMT");
340
  header ("Last-Modified: " . gmdate ("D, d M Y H:i:s") . " GMT");
344
  /**/
345
  header ('Content-Disposition: ' . (($inline) ? "inline" : "attachment") . '; filename="' . $basename . '"');
346
  /**/
347
+ eval /* End/clean any output buffers that may exist already. Prep for content delivery. */ ('while (@ob_end_clean ());');
348
  /**/
349
  $_chunk_file = ($_SERVER["SERVER_PROTOCOL"] === "HTTP/1.1" && preg_match ("/apache/i", $_SERVER["SERVER_SOFTWARE"])) ? true : false;
350
  /**/
355
  if (apply_filters ("ws_plugin__s2member_chunk_file_downloads_w_content_length", true, get_defined_vars ()))
356
  header ("Content-Length: " . $length);
357
  /**/
358
+ header /* `Transfer-Encoding: chunked` conserves memory. */ ("Transfer-Encoding: chunked");
359
  /**/
360
  while (!feof ($resource) && ($chunk_size = strlen ($data = fread ($resource, $_chunk_size))))
361
  eval ('echo dechex ($chunk_size) . "\r\n". $data . "\r\n"; @flush ();');
370
  header ("Content-Length: " . $length);
371
  /**/
372
  while (!feof ($resource) && ($flush_size = strlen ($data = fread ($resource, $_flush_size))))
373
+ eval /* Conserves memory. */ ('echo $data; @flush ();');
374
  }
375
+ else if /* Else, use: ``file_get_contents()``. */ ($length)
376
  {
377
+ @ini_set /* RAM/memory. */ ("memory_limit", WP_MAX_MEMORY_LIMIT);
378
  header ("Content-Length: " . $length) . exit (file_get_contents ($file));
379
  }
380
  else /* Else, we have an empty file with no length. */
385
  }
386
  }
387
  /**/
388
+ else if /* We only need this section when/if we're actually serving. */ ($serving && $req["file_download"])
389
  status_header (503) . header ("Content-Type: text/html; charset=utf-8") . eval ('while (@ob_end_clean ());') #
390
  . exit (_x ('<strong>503: Access denied.</strong> Invalid File Download specs.', "s2member-front", "s2member"));
391
  /**/
392
+ else if /* We only need this section when/if we're creating a URL. */ ($creating)
393
  return false;
394
  /**/
395
  do_action ("ws_plugin__s2member_after_file_download_access", get_defined_vars ());
396
  /**/
397
+ return ($creating) ? /* If creating, false. */ false : null;
398
  }
399
  /**
400
  * Generates a File Download URL for access to a file protected by s2Member.
412
  public static function create_file_download_url ($config = FALSE, $get_streamer_array = FALSE)
413
  {
414
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
415
+ do_action ("ws_plugin__s2member_before_create_file_download_url", get_defined_vars ());
416
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
417
  /**/
418
+ $config = (is_array ($config)) ? $config : /* This absolutely MUST be an array. */ array ();
419
  /**/
420
  $config["file_download"] = (isset ($config["file_download"]) && is_string ($config["file_download"])) ? trim ($config["file_download"], "/") : @$config["file_download"];
421
  $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"];
423
  $config["url_to_storage_source"] = /* Force a streaming URL here via ``$get_streamer_array``? */ ($get_streamer_array) ? true : @$config["url_to_storage_source"];
424
  $config["file_stream"] = /* Force a streaming URL here via ``$get_streamer_array``? */ ($get_streamer_array) ? true : @$config["file_stream"];
425
  /**/
426
+ if (($_url = c_ws_plugin__s2member_files_in::check_file_download_access /* Successfully created a URL to the file? */ (($create_file_download_url = $config))))
427
  {
428
  eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
429
+ do_action ("ws_plugin__s2member_during_create_file_download_url", get_defined_vars ());
430
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
431
  /**/
432
  $extension = strtolower (substr ($config["file_download"], strrpos ($config["file_download"], ".") + 1));
439
  else if ($get_streamer_array && $streaming && is_array ($ups = c_ws_plugin__s2member_utils_urls::parse_url ($_url)) && isset ($ups["scheme"], $ups["host"]) && ($streamer = $ups["scheme"] . "://" . $ups["host"] . ((!empty ($ups["port"])) ? ":" . $ups["port"] : "")) && ($url = c_ws_plugin__s2member_files_in::check_file_download_access (array_merge ($config, array ("file_stream" => false, "check_user" => false, "count_against_user" => false)))))
440
  $return = array ("streamer" => $streamer, "file" => preg_replace ("/^" . preg_quote ($streamer, "/") . "\//", "", $_url), "url" => preg_replace ("/^.+?\:/", (($ssl) ? "https:" : "http:"), $url));
441
  /**/
442
+ else if /* If streamer, we MUST return false here; unable to acquire streamer/file. */ ($get_streamer_array)
443
+ $return = /* We MUST return false here, unable to acquire streamer/file. */ false;
444
  /**/
445
  else /* Else return URL string ( ``$get_streamer_array`` is false ). */
446
+ $return = /* Else return URL string. */ $_url;
447
  }
448
  /**/
449
  return apply_filters ("ws_plugin__s2member_create_file_download_url", ((isset ($return)) ? $return : false), get_defined_vars ());
475
  {
476
  header ('WWW-Authenticate: Basic realm="' . c_ws_plugin__s2member_utils_strings::esc_dq (strip_tags (_x ("Members Only", "s2member-front", "s2member"))) . '"');
477
  /**/
478
+ status_header /* Send an unauthorized 401 status header now. */ (401);
479
+ header /* Content-Type with UTF-8. */ ("Content-Type: text/html; charset=utf-8");
480
+ eval /* End/clean any output buffers that may exist. */ ('while (@ob_end_clean ());');
481
  /**/
482
  exit (_x ('<strong>401:</strong> Sorry, access denied.', "s2member-front", "s2member"));
483
  }
484
  else if (is_object ($_user = new WP_User ($_SERVER["PHP_AUTH_USER"])) && !empty ($_user->ID))
485
+ $user = /* Now assign ``$user``. */ $_user;
486
  /**/
487
  do_action ("ws_plugin__s2member_during_check_file_remote_authorization_after", get_defined_vars ());
488
  }
 
489
  return apply_filters ("ws_plugin__s2member_check_file_remote_authorization", $user, get_defined_vars ());
490
  }
491
  /**
504
  do_action ("_ws_plugin__s2member_before_check_file_download_key", get_defined_vars ());
505
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
506
  /**/
507
+ if ($file && is_string ($file) && ($file = trim ($file, "/")) && $key && is_string ($key))
508
  {
509
  if ($key === c_ws_plugin__s2member_files::file_download_key ($file) || $key === c_ws_plugin__s2member_files::file_download_key ("/" . $file))
510
+ $valid = /* File Download Key is valid. */ true;
511
  else if ($key === c_ws_plugin__s2member_files::file_download_key ($file, "ip-forever") || $key === c_ws_plugin__s2member_files::file_download_key ("/" . $file, "ip-forever"))
512
+ $valid = /* File Download Key is valid. */ true;
513
  else if ($key === c_ws_plugin__s2member_files::file_download_key ($file, "universal") || $key === c_ws_plugin__s2member_files::file_download_key ("/" . $file, "universal"))
514
+ $valid = /* File Download Key is valid. */ true;
515
  }
 
516
  return apply_filters ("ws_plugin__s2member_check_file_download_key", ((isset ($valid) && $valid) ? true : false), get_defined_vars ());
517
  }
518
  /**
546
  */
547
  public static function amazon_s3_url ($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
548
  {
549
+ $file = /* Trim / force string. */ trim ((string)$file, "/");
550
  /**/
551
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
552
  if (preg_match ("/^amazon_s3_files_/", $option) && ($option = preg_replace ("/^amazon_s3_files_/", "", $option)))
559
  $s3_signature = base64_encode (c_ws_plugin__s2member_files_in::amazon_s3_sign ("GET\n\n\n" . $s3c["expires"] . "\n" . "/" . $s3c["bucket"] . $s3_raw_file));
560
  /**/
561
  $s3_url = ((strtolower ($s3c["bucket"]) !== $s3c["bucket"])) ? "http" . (($ssl) ? "s" : "") . "://s3.amazonaws.com/" . $s3c["bucket"] . $s3_file : "http" . (($ssl) ? "s" : "") . "://" . $s3c["bucket"] . ".s3.amazonaws.com" . $s3_file;
562
+ /**/
563
  return add_query_arg (c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep /* Don't encode unreserved chars. Maximizes media player compatibility. */
564
  (urlencode_deep (array ("AWSAccessKeyId" => $s3c["access_key"], "Expires" => $s3c["expires"], "Signature" => $s3_signature))), $s3_url);
565
  }
580
  /**/
581
  $cfc["distros_s3_access_id"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_s3_access_id"];
582
  /**/
583
+ if /* Must have Amazon® S3 Bucket/Keys. */ ($s3c["bucket"] && $s3c["access_key"] && $s3c["secret_key"])
584
  {
585
  $s3_date = gmdate ("D, d M Y H:i:s") . " GMT";
586
  $s3_location = ((strtolower ($s3c["bucket"]) !== $s3c["bucket"])) ? "/" . $s3c["bucket"] . "/?acl" : "/?acl";
600
  if (($s3_response = c_ws_plugin__s2member_utils_urls::remote ("https://" . $s3_domain . $s3_location, false, array_merge ($s3_args, array ("timeout" => 20)), "array")) && $s3_response["code"] === 200)
601
  {
602
  $s3_location = ((strtolower ($s3c["bucket"]) !== $s3c["bucket"])) ? "/" . $s3c["bucket"] . "/?policy" : "/?policy";
603
+ ($s3_policy_id = md5 (uniqid ("s2Member/CloudFront:", true))) . ($s3_policy_sid = md5 (uniqid ("s2Member/CloudFront:", true)));
604
+ $s3_policy_json = '{"Version":"2008-10-17","Id":"' . c_ws_plugin__s2member_utils_strings::esc_dq ($s3_policy_id) . '","Statement":[{"Sid":"' . c_ws_plugin__s2member_utils_strings::esc_dq ($s3_policy_sid) . '","Effect":"Allow","Principal":{"CanonicalUser":"' . c_ws_plugin__s2member_utils_strings::esc_dq ($cfc["distros_s3_access_id"]) . '"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::' . c_ws_plugin__s2member_utils_strings::esc_dq ($s3c["bucket"]) . '/*"}]}';
605
  $s3_signature = base64_encode (c_ws_plugin__s2member_files_in::amazon_s3_sign ("PUT\n\napplication/json\n" . $s3_date . "\n/" . $s3c["bucket"] . "/?policy"));
606
  $s3_args = array ("method" => "PUT", "body" => $s3_policy_json, "headers" => array ("Host" => $s3_domain, "Content-Type" => "application/json", "Date" => $s3_date, "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature));
607
  /**/
613
  $s3_args = array ("method" => "PUT", "body" => $s3_policy_xml, "headers" => array ("Host" => $s3_domain, "Content-Type" => "text/xml", "Date" => $s3_date, "X-Amz-Acl" => "public-read", "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature));
614
  /**/
615
  if (($s3_response = c_ws_plugin__s2member_utils_urls::remote ("https://" . $s3_domain . $s3_location, false, array_merge ($s3_args, array ("timeout" => 20)), "array")) && $s3_response["code"] === 200)
616
+ return /* Successfully configured Amazon® S3 Bucket ACLs and Policy. */ array ("success" => true, "code" => null, "message" => null);
617
  /**/
618
  else if (isset ($s3_response["code"], $s3_response["message"]))
619
  /* 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. */
698
  */
699
  public static function amazon_cf_url ($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
700
  {
701
+ $file = /* Trim / force string. */ trim ((string)$file, "/");
702
  /**/
703
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
704
  if (preg_match ("/^amazon_cf_files_/", $option) && ($option = preg_replace ("/^amazon_cf_files_/", "", $option)))
706
  /**/
707
  $cfc["expires"] = strtotime ("+" . apply_filters ("ws_plugin__s2member_amazon_cf_file_expires_time", "24 hours", get_defined_vars ()));
708
  /**/
709
+ $cf_extn = /* Parses the file extension out so we can scan it in some special scenarios. */ strtolower (substr ($file, strrpos ($file, ".") + 1));
710
+ $cf_ip_res = /* Do NOT restrict access to a particular IP during `localhost` development. The IP may NOT be the same one Amazon® CloudFront sees. */ (c_ws_plugin__s2member_utils_conds::is_localhost ()) ? false : true;
711
  $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 ()));
712
  $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"]) . "/" . $file;
713
  $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"]) . "/" . $file;
739
  $cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
740
  $cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
741
  /**/
742
+ if /* We MUST have an Amazon® S3 Bucket and Keys. */ ($s3c["bucket"] && $s3c["access_key"] && $s3c["secret_key"])
743
  {
744
+ if /* We MUST have Amazon® CloudFront Keys in order to auto-configure. */ ($cfc["private_key"] && $cfc["private_key_id"])
745
  {
746
  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)))
747
  {
748
  if (!$cfc["distro_downloads_id"] || ($cfc["distro_downloads_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
749
+ $cf_distro_downloads_clear = /* Clear, ready for a new one. */ true;
750
  /**/
751
  else if ($cfc["distro_downloads_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
752
  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"));
753
  /**/
754
  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"])
755
+ $cf_distro_downloads_clear = /* Clear, ready for a new one. */ true;
756
  /**/
757
  else if (isset ($cf_del_response["code"], $cf_del_response["message"]))
758
  /* 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. */
759
  return array ("success" => false, "code" => $cf_del_response["code"], "message" => sprintf (_x ("Unable to delete existing Amazon® CloudFront Downloads Distro. %s", "s2member-admin", "s2member"), $cf_del_response["message"]));
760
  /**/
761
+ if /* Successfully cleared? Ready for a new one? */ (isset ($cf_distro_downloads_clear) && $cf_distro_downloads_clear)
762
  {
763
+ unset /* Unset these before processing additional routines. Prevents problems in error reporting. */ ($cf_get_response, $cf_del_response);
764
  /**/
765
  if (!$cfc["distro_streaming_id"] || ($cfc["distro_streaming_id"] && ($cf_get_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro ($cfc["distro_streaming_id"], "streaming")) && ($cf_get_response["success"] || $cf_get_response["code"] === 404)))
766
  {
767
  if (!$cfc["distro_streaming_id"] || ($cfc["distro_streaming_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
768
+ $cf_distro_streaming_clear = /* Clear, ready for a new one. */ true;
769
  /**/
770
  else if ($cfc["distro_streaming_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
771
  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"));
772
  /**/
773
  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"])
774
+ $cf_distro_streaming_clear = /* Clear, ready for a new one. */ true;
775
  /**/
776
  else if (isset ($cf_del_response["code"], $cf_del_response["message"]))
777
  /* 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. */
778
  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"]));
779
  /**/
780
+ if /* Successfully cleared? Ready for a new one? */ (isset ($cf_distro_streaming_clear) && $cf_distro_streaming_clear)
781
  {
782
+ unset /* Unset these before processing additional routines. Prevents problems in error reporting. */ ($cf_get_response, $cf_del_response);
783
  /**/
784
  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)))
785
  {
786
  if (!$cfc["distros_access_id"] || ($cfc["distros_access_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
787
+ $cf_distros_access_clear = /* Clear, ready for a new one. */ true;
788
  /**/
789
  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"])
790
+ $cf_distros_access_clear = /* Clear, ready for a new one. */ true;
791
  /**/
792
  else if (isset ($cf_del_response["code"], $cf_del_response["message"]))
793
  /* 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. */
794
  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"]));
795
  /**/
796
+ if /* Successfully cleared? Ready for a new one? */ (isset ($cf_distros_access_clear) && $cf_distros_access_clear)
797
  {
798
+ unset /* Unset these before processing additional routines. Prevents problems in error reporting. */ ($cf_get_response, $cf_del_response);
799
  /**/
800
  $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" => ""));
801
  $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" => "");
819
  $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"]);
820
  c_ws_plugin__s2member_menu_pages::update_all_options ($cf_options, true, false, false, false, false);
821
  /**/
822
+ for ($a = 1, $attempts = 4, $sleep = 2, sleep ($sleep); $a <= $attempts; $a++, (($a <= $attempts) ? sleep ($sleep) : null))
823
+ /* Allow a generous propagation time here. Amazon's high-availability services do NOT guarantee real-time updates.
824
+ Since we DO need a fully propagated Origin Access Identity now, we need to make several attempts at success.
825
+ For further details, please see this thread: <https://forums.aws.amazon.com/message.jspa?messageID=42875>. */
826
+ if (($s3_response = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls ()) && $s3_response["success"])
827
+ {
828
+ $cfc = array_merge ($cfc, array ("distros_auto_config_status" => "configured"));
829
+ $cf_options = array ("ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" => "configured");
830
+ c_ws_plugin__s2member_menu_pages::update_all_options ( /* Now configured! */$cf_options, true, false, false, false, false);
831
+ return /* Successfully configured Amazon® S3/CloudFront distros. */ array ("success" => true, "code" => null, "message" => null);
832
+ }
833
+ if (isset ($s3_response["code"], $s3_response["message"]))
834
  /* 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. */
835
  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"]));
836
  /**/
906
  */
907
  public static function amazon_cf_get_access_origin_identity ($access_id = FALSE)
908
  {
909
+ if /* Valid parameters? */ ($access_id && is_string ($access_id))
910
  {
911
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
912
  if (preg_match ("/^amazon_cf_files_/", $option) && ($option = preg_replace ("/^amazon_cf_files_/", "", $option)))
971
  $cf_args = array ("method" => "DELETE", "headers" => array ("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $access_id_etag, "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
972
  /**/
973
  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. */))
974
+ return /* Deleted successfully. */ array ("success" => true, "code" => null, "message" => null);
975
  /**/
976
  else if (isset ($cf_response["code"], $cf_response["message"]))
977
  /* 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. */
1086
  */
1087
  public static function amazon_cf_disable_distro ($distro_id = FALSE, $distro_id_etag = FALSE, $distro_id_xml = FALSE)
1088
  {
1089
+ 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]))
 
 
1090
  {
1091
+ if /* Only if it has NOT already been disabled. We do NOT need to do it again. */ (stripos ($distro_id_xml, "<Enabled>false</Enabled>") === false)
1092
  {
1093
+ if /* Check distro status before we even begin processing. */ (stripos ($distro_id_xml, "<Status>Deployed</Status>") !== false)
1094
  {
1095
  foreach ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
1096
  if (preg_match ("/^amazon_cf_files_/", $option) && ($option = preg_replace ("/^amazon_cf_files_/", "", $option)))
1140
  */
1141
  public static function amazon_cf_del_distro ($distro_id = FALSE, $distro_id_etag = FALSE, $distro_id_xml = FALSE)
1142
  {
1143
+ 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]))
 
 
1144
  {
1145
+ if /* Check distro status before we even begin processing this deletion. */ (stripos ($distro_id_xml, "<Status>Deployed</Status>") !== false)
1146
  {
1147
  if (($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_disable_distro ($distro_id, $distro_id_etag, $distro_id_xml)) && $cf_response["success"])
1148
  {
1163
  $cf_args = array ("method" => "DELETE", "headers" => array ("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $cf_response["etag"], "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
1164
  /**/
1165
  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. */))
1166
+ return /* Deleted successfully. */ array ("success" => true, "code" => null, "message" => null);
1167
  /**/
1168
  else if (isset ($cf_response["code"], $cf_response["message"]))
1169
  /* 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. */
1222
  $cf_date = gmdate ("D, d M Y H:i:s") . " GMT";
1223
  $cf_signature = base64_encode (c_ws_plugin__s2member_files_in::amazon_cf_sign ($cf_date));
1224
  /**/
1225
+ if /* Create a `downloads` Distro? This uses a different XML schema. */ ($distro_type === "downloads")
1226
  {
1227
+ $cf_location = /* Create distro. */ "/2010-11-01/distribution";
1228
  $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"]);
1229
  $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>';
1230
  $cf_args = array ("method" => "POST", "body" => $cf_distro_downloads_xml, "headers" => array ("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
1233
  {
1234
  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))
1235
  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]));
1236
+ /**/
1237
  else /* Else, we use a default error code and message. */
1238
  return array ("success" => false, "code" => -97, "message" => _x ("Unable to create/read Amazon® CloudFront Downloads Distro. Unexpected response.", "s2member-admin", "s2member"));
1239
  }
1240
  else if (isset ($cf_response["code"], $cf_response["message"]))
1241
  /* 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. */
1242
  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"]));
1243
+ /**/
1244
  else /* Else, we use a default error code and message. */
1245
  return array ("success" => false, "code" => -98, "message" => _x ("Unable to create Amazon® CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
1246
  }
1247
  /**/
1248
+ else if /* Create a `streaming` Distro? A different XML schema. */ ($distro_type === "streaming")
1249
  {
1250
+ $cf_location = /* Create streaming distro. */ "/2010-11-01/streaming-distribution";
1251
  $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"]);
1252
  $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>';
1253
  $cf_args = array ("method" => "POST", "body" => $cf_distro_streaming_xml, "headers" => array ("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS " . $cfc["access_key"] . ":" . $cf_signature));
1256
  {
1257
  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))
1258
  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]));
1259
+ /**/
1260
  else /* Else, we use a default error code and message. */
1261
  return array ("success" => false, "code" => -97, "message" => _x ("Unable to create/read Amazon® CloudFront Streaming Distro. Unexpected response.", "s2member-admin", "s2member"));
1262
  }
1263
  else if (isset ($cf_response["code"], $cf_response["message"]))
1264
  /* 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. */
1265
  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"]));
1266
+ /**/
1267
  else /* Else, we use a default error code and message. */
1268
  return array ("success" => false, "code" => -98, "message" => _x ("Unable to create Amazon® CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
1269
  }
includes/classes/files.inc.php CHANGED
@@ -157,19 +157,16 @@ if (!class_exists ("c_ws_plugin__s2member_files"))
157
  /**/
158
  $file = ($file && is_string ($file) && ($file = trim ($file, "/"))) ? $file : "";
159
  /**/
160
- if ($directive === "ip-forever") /* Current IP forever. */
161
- eval ('$allow_caching = false; $salt = $file . $_SERVER["REMOTE_ADDR"];');
162
  /**/
163
  else if ($directive === "universal" || $directive === "cache-compatible" || $directive)
164
- eval ('$allow_caching = true; $salt = $file;');
165
  /**/
166
- else /* Otherwise, we use the default ``$salt``, which is VERY restrictive; even to a specific browser. */
167
- eval ('$allow_caching = false; $salt = date ("Y-m-d") . $_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_USER_AGENT"] . $file;');
168
  /**/
169
- $key = md5 (c_ws_plugin__s2member_utils_encryption::xencrypt ($salt, false, false));
170
- /**/
171
- if ($allow_caching === false) /* Disallow caching? */
172
- c_ws_plugin__s2member_no_cache::no_cache_constants (true);
173
  /**/
174
  return apply_filters ("ws_plugin__s2member_file_download_key", $key, get_defined_vars ());
175
  }
157
  /**/
158
  $file = ($file && is_string ($file) && ($file = trim ($file, "/"))) ? $file : "";
159
  /**/
160
+ if ($directive === "ip-forever" && c_ws_plugin__s2member_no_cache::no_cache_constants (true))
161
+ $salt = $file . $_SERVER["REMOTE_ADDR"];
162
  /**/
163
  else if ($directive === "universal" || $directive === "cache-compatible" || $directive)
164
+ $salt = /* Just the file name. This IS cachable. */ $file;
165
  /**/
166
+ else if (c_ws_plugin__s2member_no_cache::no_cache_constants (true))
167
+ $salt = date ("Y-m-d") . $_SERVER["REMOTE_ADDR"] . $_SERVER["HTTP_USER_AGENT"] . $file;
168
  /**/
169
+ $key = (!empty ($salt)) ? md5 (c_ws_plugin__s2member_utils_encryption::xencrypt ($salt, false, false)) : "";
 
 
 
170
  /**/
171
  return apply_filters ("ws_plugin__s2member_file_download_key", $key, get_defined_vars ());
172
  }
includes/classes/menu-pages.inc.php CHANGED
@@ -15,7 +15,7 @@
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_menu_pages"))
21
  {
@@ -27,6 +27,15 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
27
  */
28
  class c_ws_plugin__s2member_menu_pages
29
  {
 
 
 
 
 
 
 
 
 
30
  /**
31
  * Saves all options from any menu page.
32
  *
@@ -48,7 +57,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
48
  {
49
  $updated_all_options = false; /* Initialize this to a value of false. Initializing this variable here makes it an available reference-variable to Hooks/Filters. */
50
  /**/
51
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
52
  do_action ("ws_plugin__s2member_before_update_all_options", get_defined_vars ()); /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
53
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
54
  /**/
@@ -70,7 +79,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
70
  /**/
71
  unset ($key, $value); /* Unset these utility variables now. This prevents bleeding vars into Hooks/Filters that are of no use. */
72
  /**/
73
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
74
  do_action ("ws_plugin__s2member_during_update_all_options", get_defined_vars ()); /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
75
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
76
  /**/
@@ -110,7 +119,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
110
  $updated_all_options = true; /* Flag indicating this routine was processed successfully; and that all s2Member options have been updated successfully.*/
111
  }
112
  /**/
113
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
114
  do_action ("ws_plugin__s2member_after_update_all_options", get_defined_vars ()); /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
115
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
116
  /**/
@@ -261,7 +270,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
261
  */
262
  public static function _add_settings_link ($actions = FALSE, $plugin_file = FALSE)
263
  {
264
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
265
  do_action ("_ws_plugin__s2member_before_add_settings_link", get_defined_vars ());
266
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
267
  /**/
@@ -270,7 +279,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
270
  $settings = '<a href="' . esc_attr (admin_url ("/admin.php?page=ws-plugin--s2member-gen-ops")) . '">Settings</a>';
271
  array_unshift ($actions, apply_filters ("ws_plugin__s2member_add_settings_link", $settings, get_defined_vars ()));
272
  /**/
273
- eval ('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
274
  do_action ("_ws_plugin__s2member_during_add_settings_link", get_defined_vars ());
275
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
276
  }
@@ -293,10 +302,10 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
293
  /**/
294
  if (!empty ($_GET["page"]) && preg_match ("/ws-plugin--s2member-/", $_GET["page"]))
295
  {
296
- wp_enqueue_script ("jquery");
297
- wp_enqueue_script ("thickbox");
298
- wp_enqueue_script ("media-upload");
299
- wp_enqueue_script ("jquery-ui-core");
300
  wp_enqueue_script ("jquery-sprintf", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/includes/jquery/jquery.sprintf/jquery.sprintf-min.js", array ("jquery"), c_ws_plugin__s2member_utilities::ver_checksum ());
301
  wp_enqueue_script ("jquery-json-ps", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/includes/jquery/jquery.json-ps/jquery.json-ps-min.js", array ("jquery"), c_ws_plugin__s2member_utilities::ver_checksum ());
302
  wp_enqueue_script ("jquery-ui-effects", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/includes/jquery/jquery.ui-effects/jquery.ui-effects-min.js", array ("jquery", "jquery-ui-core"), c_ws_plugin__s2member_utilities::ver_checksum ());
@@ -325,7 +334,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
325
  /**/
326
  if (!empty ($_GET["page"]) && preg_match ("/ws-plugin--s2member-/", $_GET["page"]))
327
  {
328
- wp_enqueue_style ("thickbox");
329
  wp_enqueue_style ("ws-plugin--s2member-menu-pages", site_url ("/?ws_plugin__s2member_menu_pages_css=" . urlencode (mt_rand ())), array ("thickbox"), c_ws_plugin__s2member_utilities::ver_checksum (), "all");
330
  /**/
331
  do_action ("ws_plugin__s2member_during_add_admin_styles", get_defined_vars ());
@@ -495,12 +504,16 @@ if (!class_exists ("c_ws_plugin__s2member_menu_pages"))
495
  c_ws_plugin__s2member_admin_notices::display_admin_notice ('Unprotected. The .htaccess protection file ( <code>' . esc_html (c_ws_plugin__s2member_utils_dirs::doc_root_path ($htaccess)) . '</code> ) does not contain <code>deny from all</code>. Inside your .htaccess file, add this:<br /><pre>' . esc_html ($htaccess_contents) . '</pre>', true);
496
  /**/
497
  if (!empty ($_POST["ws_plugin__s2member_amazon_cf_files_auto_configure_distros"]) && ($nonce = $_POST["ws_plugin__s2member_amazon_cf_files_auto_configure_distros"]) && wp_verify_nonce ($nonce, "ws-plugin--s2member-amazon-cf-files-auto-configure-distros"))
498
- /**/
499
- if (($amazon_cf_auto_configure_distros = c_ws_plugin__s2member_files_in::amazon_cf_auto_configure_distros ()) && $amazon_cf_auto_configure_distros["success"]) /* CNAME instructions here too. */
500
  c_ws_plugin__s2member_admin_notices::display_admin_notice ('Amazon® CloudFront Distributions auto-configured successfully. Please allow 30 minutes for propagation.' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]) ? '<br /><em>Downloads Distribution CNAME: <code>' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]) . ' &mdash;&raquo; ' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_dname"]) . '</code></em>' : '') . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]) ? '<br /><em>Streaming Distribution CNAME: <code>' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]) . ' &mdash;&raquo; ' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_dname"]) . '</code></em>' : ''));
501
- /**/
502
  else /* Else there was an error. We need to report this back to the site owner so they can understand what's going on. */
503
- ($GLOBALS["ws_plugin__s2member_cf_auto_configure_distros_error"] = true) . c_ws_plugin__s2member_admin_notices::display_admin_notice ('Unable to auto-configure Amazon® CloudFront Distributions.<br />Error code: <code>' . esc_html ($amazon_cf_auto_configure_distros["code"]) . '</code>. Error Message: <code>' . esc_html ($amazon_cf_auto_configure_distros["message"]) . '</code>', true);
 
 
 
 
 
 
504
  /**/
505
  include_once dirname (dirname (__FILE__)) . "/menu-pages/down-ops.inc.php";
506
  /**/
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_menu_pages"))
21
  {
27
  */
28
  class c_ws_plugin__s2member_menu_pages
29
  {
30
+ /**
31
+ * Pre-display errors.
32
+ *
33
+ * @package s2Member\Menu_Pages
34
+ * @since 111209
35
+ *
36
+ * @var array
37
+ */
38
+ public static $pre_display_errors = array ();
39
  /**
40
  * Saves all options from any menu page.
41
  *
57
  {
58
  $updated_all_options = false; /* Initialize this to a value of false. Initializing this variable here makes it an available reference-variable to Hooks/Filters. */
59
  /**/
60
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
61
  do_action ("ws_plugin__s2member_before_update_all_options", get_defined_vars ()); /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
62
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
63
  /**/
79
  /**/
80
  unset ($key, $value); /* Unset these utility variables now. This prevents bleeding vars into Hooks/Filters that are of no use. */
81
  /**/
82
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
83
  do_action ("ws_plugin__s2member_during_update_all_options", get_defined_vars ()); /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
84
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
85
  /**/
119
  $updated_all_options = true; /* Flag indicating this routine was processed successfully; and that all s2Member options have been updated successfully.*/
120
  }
121
  /**/
122
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
123
  do_action ("ws_plugin__s2member_after_update_all_options", get_defined_vars ()); /* If you use this Hook, be sure to use ``wp_verify_nonce()``. */
124
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
125
  /**/
270
  */
271
  public static function _add_settings_link ($actions = FALSE, $plugin_file = FALSE)
272
  {
273
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
274
  do_action ("_ws_plugin__s2member_before_add_settings_link", get_defined_vars ());
275
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
276
  /**/
279
  $settings = '<a href="' . esc_attr (admin_url ("/admin.php?page=ws-plugin--s2member-gen-ops")) . '">Settings</a>';
280
  array_unshift ($actions, apply_filters ("ws_plugin__s2member_add_settings_link", $settings, get_defined_vars ()));
281
  /**/
282
+ eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
283
  do_action ("_ws_plugin__s2member_during_add_settings_link", get_defined_vars ());
284
  unset ($__refs, $__v); /* Unset defined __refs, __v. */
285
  }
302
  /**/
303
  if (!empty ($_GET["page"]) && preg_match ("/ws-plugin--s2member-/", $_GET["page"]))
304
  {
305
+ wp_enqueue_script("jquery");
306
+ wp_enqueue_script("thickbox");
307
+ wp_enqueue_script("media-upload");
308
+ wp_enqueue_script("jquery-ui-core");
309
  wp_enqueue_script ("jquery-sprintf", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/includes/jquery/jquery.sprintf/jquery.sprintf-min.js", array ("jquery"), c_ws_plugin__s2member_utilities::ver_checksum ());
310
  wp_enqueue_script ("jquery-json-ps", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/includes/jquery/jquery.json-ps/jquery.json-ps-min.js", array ("jquery"), c_ws_plugin__s2member_utilities::ver_checksum ());
311
  wp_enqueue_script ("jquery-ui-effects", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/includes/jquery/jquery.ui-effects/jquery.ui-effects-min.js", array ("jquery", "jquery-ui-core"), c_ws_plugin__s2member_utilities::ver_checksum ());
334
  /**/
335
  if (!empty ($_GET["page"]) && preg_match ("/ws-plugin--s2member-/", $_GET["page"]))
336
  {
337
+ wp_enqueue_style("thickbox");
338
  wp_enqueue_style ("ws-plugin--s2member-menu-pages", site_url ("/?ws_plugin__s2member_menu_pages_css=" . urlencode (mt_rand ())), array ("thickbox"), c_ws_plugin__s2member_utilities::ver_checksum (), "all");
339
  /**/
340
  do_action ("ws_plugin__s2member_during_add_admin_styles", get_defined_vars ());
504
  c_ws_plugin__s2member_admin_notices::display_admin_notice ('Unprotected. The .htaccess protection file ( <code>' . esc_html (c_ws_plugin__s2member_utils_dirs::doc_root_path ($htaccess)) . '</code> ) does not contain <code>deny from all</code>. Inside your .htaccess file, add this:<br /><pre>' . esc_html ($htaccess_contents) . '</pre>', true);
505
  /**/
506
  if (!empty ($_POST["ws_plugin__s2member_amazon_cf_files_auto_configure_distros"]) && ($nonce = $_POST["ws_plugin__s2member_amazon_cf_files_auto_configure_distros"]) && wp_verify_nonce ($nonce, "ws-plugin--s2member-amazon-cf-files-auto-configure-distros"))
507
+ if (($amazon_cf_auto_configure_distros = c_ws_plugin__s2member_files_in::amazon_cf_auto_configure_distros ()) && $amazon_cf_auto_configure_distros["success"])
 
508
  c_ws_plugin__s2member_admin_notices::display_admin_notice ('Amazon® CloudFront Distributions auto-configured successfully. Please allow 30 minutes for propagation.' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]) ? '<br /><em>Downloads Distribution CNAME: <code>' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]) . ' &mdash;&raquo; ' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_dname"]) . '</code></em>' : '') . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]) ? '<br /><em>Streaming Distribution CNAME: <code>' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]) . ' &mdash;&raquo; ' . esc_html ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_dname"]) . '</code></em>' : ''));
 
509
  else /* Else there was an error. We need to report this back to the site owner so they can understand what's going on. */
510
+ (c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"] = true) . c_ws_plugin__s2member_admin_notices::display_admin_notice ('Unable to auto-configure Amazon® CloudFront Distributions.<br />Error code: <code>' . esc_html ($amazon_cf_auto_configure_distros["code"]) . '</code>. Error Message: <code>' . esc_html ($amazon_cf_auto_configure_distros["message"]) . '</code>', true);
511
+ /**/
512
+ if (!empty ($_POST["ws_plugin__s2member_amazon_s3_files_auto_configure_acls"]) && ($nonce = $_POST["ws_plugin__s2member_amazon_s3_files_auto_configure_acls"]) && wp_verify_nonce ($nonce, "ws-plugin--s2member-amazon-s3-files-auto-configure-acls"))
513
+ if (($amazon_s3_auto_configure_acls = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls ()) && $amazon_s3_auto_configure_acls["success"])
514
+ c_ws_plugin__s2member_admin_notices::display_admin_notice ('Amazon® S3 ACLs auto-configured successfully.');
515
+ else /* Else there was an error. We need to report this back to the site owner so they can understand what's going on. */
516
+ (c_ws_plugin__s2member_menu_pages::$pre_display_errors["s3_files_auto_configure_acls"] = true) . c_ws_plugin__s2member_admin_notices::display_admin_notice ('Unable to auto-configure Amazon® S3 ACLs.<br />Error code: <code>' . esc_html ($amazon_s3_auto_configure_acls["code"]) . '</code>. Error Message: <code>' . esc_html ($amazon_s3_auto_configure_acls["message"]) . '</code>', true);
517
  /**/
518
  include_once dirname (dirname (__FILE__)) . "/menu-pages/down-ops.inc.php";
519
  /**/
includes/classes/utils-arrays.inc.php CHANGED
@@ -15,7 +15,7 @@
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_utils_arrays"))
21
  {
@@ -114,13 +114,13 @@ if (!class_exists ("c_ws_plugin__s2member_utils_arrays"))
114
  return false;
115
  }
116
  /**
117
- * Removes all null-value array keys from an array *( or even a multi-dimensional array )*.
118
  *
119
  * @package s2Member\Utilities
120
  * @since 111101
121
  *
122
  * @param array $array An input array.
123
- * @return array Returns the ``$array`` after having reduced it to a non-null set of values.
124
  */
125
  public static function remove_nulls ($array = FALSE)
126
  {
@@ -129,10 +129,33 @@ if (!class_exists ("c_ws_plugin__s2member_utils_arrays"))
129
  foreach ($array as $key => &$value)
130
  {
131
  if (is_array ($value) /* Recursive function call here. */)
132
- $value = c_ws_plugin__s2member_utils_arrays::remove_null_keys ($value);
133
  /**/
134
- else if (is_null ($value) /* Is it null? */)
135
- unset($array[$key]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
  return $array;
138
  }
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_utils_arrays"))
21
  {
114
  return false;
115
  }
116
  /**
117
+ * Removes all null values from an array *( or even a multi-dimensional array )*.
118
  *
119
  * @package s2Member\Utilities
120
  * @since 111101
121
  *
122
  * @param array $array An input array.
123
+ * @return array Returns the ``$array`` after having reduced its set of values.
124
  */
125
  public static function remove_nulls ($array = FALSE)
126
  {
129
  foreach ($array as $key => &$value)
130
  {
131
  if (is_array ($value) /* Recursive function call here. */)
132
+ $value = c_ws_plugin__s2member_utils_arrays::remove_nulls ($value);
133
  /**/
134
+ else if (is_null /* Is it null? */ ($value))
135
+ unset ($array[$key]);
136
+ }
137
+ return $array;
138
+ }
139
+ /**
140
+ * Removes all 0-byte strings from an array *( or even a multi-dimensional array )*.
141
+ *
142
+ * @package s2Member\Utilities
143
+ * @since 111216
144
+ *
145
+ * @param array $array An input array.
146
+ * @return array Returns the ``$array`` after having reduced its set of values.
147
+ */
148
+ public static function remove_0b_strings ($array = FALSE)
149
+ {
150
+ $array = (array)$array;
151
+ /**/
152
+ foreach ($array as $key => &$value)
153
+ {
154
+ if (is_array ($value) /* Recursive function call here. */)
155
+ $value = c_ws_plugin__s2member_utils_arrays::remove_0b_strings ($value);
156
+ /**/
157
+ else if (is_string ($value) && !strlen ($value))
158
+ unset ($array[$key]);
159
  }
160
  return $array;
161
  }
includes/classes/utils-urls.inc.php CHANGED
@@ -64,7 +64,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
64
  if ( /* If BuddyPress is installed. */c_ws_plugin__s2member_utils_conds::bp_is_installed ())
65
  return site_url (((function_exists ("bp_get_signup_slug")) ? bp_get_signup_slug () . "/" : BP_REGISTER_SLUG . "/"));
66
  /**/
67
- return false; /* Default return false. */
68
  }
69
  /**
70
  * Filters content redirection status *( uses 302s for browsers )*.
@@ -161,12 +161,12 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
161
  /**/
162
  if (is_string ($url_uri) && /* And, there is a query string? */ strpos ($url_uri, "?") !== false)
163
  {
164
- list ($_, $query) = preg_split ("/\?/", $url_uri, 2); /* Split @ query string marker. */
165
  $query = /* See: <https://bugs.php.net/bug.php?id=38143>. */ str_replace ("://", urlencode ("://"), $query);
166
  $url_uri = /* Put it all back together again, after the above modifications. */ $_ . "?" . $query;
167
  unset /* A little housekeeping here. Unset these vars. */ ($_, $query);
168
  }
169
- $parse = /* Let PHP work its magic via ``parse_url()``. */ @parse_url ($url_uri, $component);
170
  /**/
171
  if ($clean_path && isset ($parse["path"]) && is_string ($parse["path"]) && !empty ($parse["path"]))
172
  $parse["path"] = /* Clean up the path now. */ preg_replace ("/\/+/", "/", $parse["path"]);
@@ -184,23 +184,29 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
184
  * @param str $url Full URL with possible query string parameters.
185
  * @param str|array $post_vars Optional. Either a string of POST vars, or an array.
186
  * @param array $args Optional. An array of additional arguments used by ``wp_remote_request()``.
187
- * @param bool $return Optional. One of: `body|array`. Defaults to `body`. If `array`, an array with the following elements:
188
- * `code` *(http response code)*, `message` *(http response message)*, `headers` *(an array of lowercase headers)*, `body` *(the response body string)*, `response` *(response array)*.
189
- * @return str|array|bool Requested response data from the remote location *(see ``$return`` parameter )*, else false on failure.
190
  */
191
- public static function remote ($url = FALSE, $post_vars = FALSE, $args = FALSE, $return = FALSE)
192
  {
193
- if ($url && is_string ($url) /* We MUST have a valid full URL (string) before we do anything in this routine. */)
194
  {
195
- $args = (!is_array ($args)) ? array (): $args; /* Force array, and disable SSL verification. */
196
  $args["sslverify"] = (!isset ($args["sslverify"])) ? /* Off. */ false : $args["sslverify"];
197
  /**/
198
  if ((is_array ($post_vars) || is_string ($post_vars)) && !empty ($post_vars))
199
  $args = array_merge ($args, array ("method" => "POST", "body" => $post_vars));
200
  /**/
201
- $response = wp_remote_request ($url, $args); /* Process the remote request now. */
 
 
202
  /**/
203
- if (strcasecmp ((string)$return, "array") === 0 && !is_wp_error ($response) && is_array ($response))
 
 
 
 
204
  {
205
  $a = array ("code" => (int)wp_remote_retrieve_response_code ($response));
206
  $a = array_merge ($a, array ("message" => wp_remote_retrieve_response_message ($response)));
@@ -238,23 +244,23 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
238
  $default_url_shortener = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["default_url_shortener"];
239
  $default_custom_str_url_shortener = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["default_custom_str_url_shortener"];
240
  /**/
241
- $apis = array ("tiny_url", "goo_gl"); /* The shortening APIs currently pre-integrated in this release of s2Member. */
242
  /**/
243
  if ($url && ($api = /* If specific, use it. Otherwise, use the default shortening API. */ ($api_sp) ? $api_sp : $default_url_shortener))
244
  {
245
  if (!$api_sp && ($custom_url = trim (apply_filters ("ws_plugin__s2member_url_shorten", false, get_defined_vars ()))) && stripos ($custom_url, "http") === 0)
246
- return ($shorter_url = $custom_url); /* Using whatever other shortener API you prefer, over the ones available by default with s2Member. */
247
  /**/
248
  else if (!$api_sp && stripos ($default_custom_str_url_shortener, "http") === 0 && ($custom_url = trim (c_ws_plugin__s2member_utils_urls::remote (str_ireplace (array ("%%s2_long_url%%", "%%s2_long_url_md5%%"), array (rawurlencode ($url), urlencode (md5 ($url))), $default_custom_str_url_shortener)))) && stripos ($custom_url, "http") === 0)
249
- return ($shorter_url = $custom_url); /* Using whatever other shortener API that a site owner prefers, over the ones available by default with s2Member. */
250
  /**/
251
  else if ($api === "tiny_url" && ($tiny_url = trim (c_ws_plugin__s2member_utils_urls::remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($url)))) && stripos ($tiny_url, "http") === 0)
252
- return ($shorter_url = $tiny_url); /* The default tinyURL API: <http://tinyurl.com/api-create.php?url=http://www.example.com/>.
253
  /**/
254
  else if ($api === "goo_gl" && ($goo_gl = json_decode (trim (c_ws_plugin__s2member_utils_urls::remote ("https://www.googleapis.com/urlshortener/v1/url" . ((($goo_gl_key = apply_filters ("ws_plugin__s2member_url_shorten_api_goo_gl_key", false))) ? "?key=" . urlencode ($goo_gl_key) : ""), json_encode (array ("longUrl" => $url)), array ("headers" => array ("Content-Type" => "application/json")))), true)) && !empty ($goo_gl["id"]) && is_string ($goo_gl_url = $goo_gl["id"]) && stripos ($goo_gl_url, "http") === 0)
255
- return ($shorter_url = $goo_gl_url); /* Google® API: <http://code.google.com/apis/urlshortener/v1/getting_started.html>.
256
  /**/
257
- else if ($try_backups && count ($apis) > 1) /* Try backups? This way we can still shorten the URL with a backup. */
258
  /**/
259
  foreach /* Try other backup APIs now. */ (array_diff ($apis, array ($api)) as $backup)
260
  if (($backup = c_ws_plugin__s2member_utils_urls::shorten ($url, $backup, false)))
@@ -304,7 +310,8 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
304
  if ($url_uri_query && is_string /* We DO allow empty query strings. So we can sign a URL without one. */ ($query))
305
  {
306
  wp_parse_str /* Parse the query string into an array of ``$vars``. Then sort & serialize them into a string. */ ($query, $vars);
307
- $vars = serialize (c_ws_plugin__s2member_utils_arrays::ksort_deep (c_ws_plugin__s2member_utils_strings::trim_deep ($vars)));
 
308
  /**/
309
  $sig = /* The s2Member-generated signature. */ ($time = time ()) . "-" . md5 ($key . $time . $vars);
310
  /**/
@@ -341,7 +348,8 @@ if (!class_exists ("c_ws_plugin__s2member_utils_urls"))
341
  $query = /* Remove existing s2Member-generated signatures. */ c_ws_plugin__s2member_utils_urls::remove_s2member_sigs ($query, $sig_var);
342
  /**/
343
  wp_parse_str /* Parse the query string into an array of ``$vars``. Then sort & serialize them into a string. */ ($query, $vars);
344
- $vars = serialize (c_ws_plugin__s2member_utils_arrays::ksort_deep (c_ws_plugin__s2member_utils_strings::trim_deep ($vars)));
 
345
  /**/
346
  ($time = $sigs[1][($i = count ($sigs[1]) - 1)]) . ($sig = $sigs[2][$i]) . ($valid_sig = md5 ($key . $time . $vars));
347
  /**/
64
  if ( /* If BuddyPress is installed. */c_ws_plugin__s2member_utils_conds::bp_is_installed ())
65
  return site_url (((function_exists ("bp_get_signup_slug")) ? bp_get_signup_slug () . "/" : BP_REGISTER_SLUG . "/"));
66
  /**/
67
+ return /* Default return false. */ false;
68
  }
69
  /**
70
  * Filters content redirection status *( uses 302s for browsers )*.
161
  /**/
162
  if (is_string ($url_uri) && /* And, there is a query string? */ strpos ($url_uri, "?") !== false)
163
  {
164
+ list ($_, $query) = preg_split /* Split @ query string marker. */ ("/\?/", $url_uri, 2);
165
  $query = /* See: <https://bugs.php.net/bug.php?id=38143>. */ str_replace ("://", urlencode ("://"), $query);
166
  $url_uri = /* Put it all back together again, after the above modifications. */ $_ . "?" . $query;
167
  unset /* A little housekeeping here. Unset these vars. */ ($_, $query);
168
  }
169
+ $parse = @parse_url /* Let PHP work its magic via ``parse_url()``. */ ($url_uri, $component);
170
  /**/
171
  if ($clean_path && isset ($parse["path"]) && is_string ($parse["path"]) && !empty ($parse["path"]))
172
  $parse["path"] = /* Clean up the path now. */ preg_replace ("/\/+/", "/", $parse["path"]);
184
  * @param str $url Full URL with possible query string parameters.
185
  * @param str|array $post_vars Optional. Either a string of POST vars, or an array.
186
  * @param array $args Optional. An array of additional arguments used by ``wp_remote_request()``.
187
+ * @param bool $return_array Optional. If true, instead of a string, we return an array with elements:
188
+ * `code` *(http response code)*, `message` *(http response message)*, `headers` *(an array of lowercase headers)*, `body` *(the response body string)*, `response` *(full response array)*.
189
+ * @return str|array|bool Requested response str|array from remote location *(see ``$return_array`` parameter )*; else (bool)`false` on failure.
190
  */
191
+ public static function remote ($url = FALSE, $post_vars = FALSE, $args = FALSE, $return_array = FALSE)
192
  {
193
+ if ($url && /* We MUST have a valid full URL (string) before we do anything in this routine. */ is_string ($url))
194
  {
195
+ $args = /* Force array, and disable SSL verification. */ (!is_array ($args)) ? array (): $args;
196
  $args["sslverify"] = (!isset ($args["sslverify"])) ? /* Off. */ false : $args["sslverify"];
197
  /**/
198
  if ((is_array ($post_vars) || is_string ($post_vars)) && !empty ($post_vars))
199
  $args = array_merge ($args, array ("method" => "POST", "body" => $post_vars));
200
  /**/
201
+ if (!empty ($args["method"]) && strcasecmp ((string)$args["method"], "DELETE") === 0)
202
+ /* WordPress® v3.3 and prior, does NOT support `DELETE` via cURL unfortunately. */
203
+ add_filter ("use_curl_transport", "__return_false", /* ID via priority. */ 111209554);
204
  /**/
205
+ $response = /* Process remote request via ``wp_remote_request()``. */ wp_remote_request ($url, $args);
206
+ /**/
207
+ remove_filter /* Remove this Filter now. */ ("use_curl_transport", "__return_false", 111209554);
208
+ /**/
209
+ if ($return_array && !is_wp_error ($response) && is_array ($response))
210
  {
211
  $a = array ("code" => (int)wp_remote_retrieve_response_code ($response));
212
  $a = array_merge ($a, array ("message" => wp_remote_retrieve_response_message ($response)));
244
  $default_url_shortener = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["default_url_shortener"];
245
  $default_custom_str_url_shortener = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["default_custom_str_url_shortener"];
246
  /**/
247
+ $apis = /* The shortening APIs currently pre-integrated in this release of s2Member. */ array ("tiny_url", "goo_gl");
248
  /**/
249
  if ($url && ($api = /* If specific, use it. Otherwise, use the default shortening API. */ ($api_sp) ? $api_sp : $default_url_shortener))
250
  {
251
  if (!$api_sp && ($custom_url = trim (apply_filters ("ws_plugin__s2member_url_shorten", false, get_defined_vars ()))) && stripos ($custom_url, "http") === 0)
252
+ return /* Using whatever other shortener API you prefer, over the ones available by default with s2Member. */ ($shorter_url = $custom_url);
253
  /**/
254
  else if (!$api_sp && stripos ($default_custom_str_url_shortener, "http") === 0 && ($custom_url = trim (c_ws_plugin__s2member_utils_urls::remote (str_ireplace (array ("%%s2_long_url%%", "%%s2_long_url_md5%%"), array (rawurlencode ($url), urlencode (md5 ($url))), $default_custom_str_url_shortener)))) && stripos ($custom_url, "http") === 0)
255
+ return /* Using whatever other shortener API that a site owner prefers, over the ones available by default with s2Member. */ ($shorter_url = $custom_url);
256
  /**/
257
  else if ($api === "tiny_url" && ($tiny_url = trim (c_ws_plugin__s2member_utils_urls::remote ("http://tinyurl.com/api-create.php?url=" . rawurlencode ($url)))) && stripos ($tiny_url, "http") === 0)
258
+ return /* The default tinyURL API: <http://tinyurl.com/api-create.php?url=http://www.example.com/>. */ ($shorter_url = $tiny_url);
259
  /**/
260
  else if ($api === "goo_gl" && ($goo_gl = json_decode (trim (c_ws_plugin__s2member_utils_urls::remote ("https://www.googleapis.com/urlshortener/v1/url" . ((($goo_gl_key = apply_filters ("ws_plugin__s2member_url_shorten_api_goo_gl_key", false))) ? "?key=" . urlencode ($goo_gl_key) : ""), json_encode (array ("longUrl" => $url)), array ("headers" => array ("Content-Type" => "application/json")))), true)) && !empty ($goo_gl["id"]) && is_string ($goo_gl_url = $goo_gl["id"]) && stripos ($goo_gl_url, "http") === 0)
261
+ return /* Google® API: <http://code.google.com/apis/urlshortener/v1/getting_started.html>. */ ($shorter_url = $goo_gl_url);
262
  /**/
263
+ else if /* Try backups? This way we can still shorten the URL with a backup. */ ($try_backups && count ($apis) > 1)
264
  /**/
265
  foreach /* Try other backup APIs now. */ (array_diff ($apis, array ($api)) as $backup)
266
  if (($backup = c_ws_plugin__s2member_utils_urls::shorten ($url, $backup, false)))
310
  if ($url_uri_query && is_string /* We DO allow empty query strings. So we can sign a URL without one. */ ($query))
311
  {
312
  wp_parse_str /* Parse the query string into an array of ``$vars``. Then sort & serialize them into a string. */ ($query, $vars);
313
+ $vars = c_ws_plugin__s2member_utils_arrays::remove_0b_strings (c_ws_plugin__s2member_utils_strings::trim_deep ($vars));
314
+ $vars = serialize (c_ws_plugin__s2member_utils_arrays::ksort_deep ($vars));
315
  /**/
316
  $sig = /* The s2Member-generated signature. */ ($time = time ()) . "-" . md5 ($key . $time . $vars);
317
  /**/
348
  $query = /* Remove existing s2Member-generated signatures. */ c_ws_plugin__s2member_utils_urls::remove_s2member_sigs ($query, $sig_var);
349
  /**/
350
  wp_parse_str /* Parse the query string into an array of ``$vars``. Then sort & serialize them into a string. */ ($query, $vars);
351
+ $vars = c_ws_plugin__s2member_utils_arrays::remove_0b_strings (c_ws_plugin__s2member_utils_strings::trim_deep ($vars));
352
+ $vars = serialize (c_ws_plugin__s2member_utils_arrays::ksort_deep ($vars));
353
  /**/
354
  ($time = $sigs[1][($i = count ($sigs[1]) - 1)]) . ($sig = $sigs[2][$i]) . ($valid_sig = md5 ($key . $time . $vars));
355
  /**/
includes/menu-pages/down-ops.inc.php CHANGED
@@ -15,7 +15,7 @@
15
  * @since 3.0
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_menu_page_down_ops"))
21
  {
@@ -248,7 +248,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_down_ops"))
248
  {
249
  do_action ("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_amazon_s3", get_defined_vars ());
250
  /**/
251
- echo '<div class="ws-menu-page-group" title="Amazon® S3/CDN Storage Option"' . (($GLOBALS["ws_plugin__s2member_cf_auto_configure_distros_error"]) ? ' default-state="open"' : '') . '>' . "\n";
252
  /**/
253
  echo '<div class="ws-menu-page-section ws-plugin--s2member-amazon-s3-section">' . "\n";
254
  echo '<h3>Amazon® S3/CDN Storage &amp; Delivery ( optional )</h3>' . "\n";
@@ -333,7 +333,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_down_ops"))
333
  {
334
  do_action ("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_amazon_cf", get_defined_vars ());
335
  /**/
336
- echo '<div class="ws-menu-page-group" title="Amazon® S3/CloudFront CDN Storage Option"' . (($GLOBALS["ws_plugin__s2member_cf_auto_configure_distros_error"]) ? ' default-state="open"' : '') . '>' . "\n";
337
  /**/
338
  echo '<div class="ws-menu-page-section ws-plugin--s2member-amazon-cf-section">' . "\n";
339
  echo '<h3>Amazon® S3/CloudFront CDN Storage &amp; Delivery ( optional )</h3>' . "\n";
@@ -410,7 +410,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_down_ops"))
410
  echo '<tr>' . "\n";
411
  /**/
412
  echo '<td>' . "\n";
413
- echo '<input type="checkbox" name="ws_plugin__s2member_amazon_cf_files_auto_configure_distros" id="ws-plugin--s2member-amazon-cf-files-auto-configure-distros" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-amazon-cf-files-auto-configure-distros")) . '"' . (($GLOBALS["ws_plugin__s2member_cf_auto_configure_distros_error"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-amazon-cf-files-auto-configure-distros"><strong>Yes</strong>, automatically configure my Amazon® CloudFront Distributions &amp; Amazon® S3 ACLs for me.</label><br />' . "\n";
414
  echo '<em>s2Member will auto-configure and/or delete &amp; re-configure your Amazon® CloudFront Distributions for you.</em>' . "\n";
415
  echo '</td>' . "\n";
416
  /**/
@@ -418,7 +418,7 @@ if (!class_exists ("c_ws_plugin__s2member_menu_page_down_ops"))
418
  echo '<tr>' . "\n";
419
  /**/
420
  echo '<td>' . "\n";
421
- echo '<input type="checkbox" name="ws_plugin__s2member_amazon_cf_files_auto_configure_distros_w_cnames" id="ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames")) . '"' . (($GLOBALS["ws_plugin__s2member_cf_auto_configure_distros_error"] && ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"] || $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"])) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames"><strong>Yes</strong>, I want s2Member to auto-configure using custom CNAMES that I\'ll setup.</label><br />' . "\n";
422
  echo '<em>* Optional, do NOT check this box unless you know what you\'re doing. This requires DNS changes.</em>' . "\n";
423
  echo '</td>' . "\n";
424
  /**/
15
  * @since 3.0
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_menu_page_down_ops"))
21
  {
248
  {
249
  do_action ("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_amazon_s3", get_defined_vars ());
250
  /**/
251
+ echo '<div class="ws-menu-page-group" title="Amazon® S3/CDN Storage Option"' . ((c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"]) ? ' default-state="open"' : '') . '>' . "\n";
252
  /**/
253
  echo '<div class="ws-menu-page-section ws-plugin--s2member-amazon-s3-section">' . "\n";
254
  echo '<h3>Amazon® S3/CDN Storage &amp; Delivery ( optional )</h3>' . "\n";
333
  {
334
  do_action ("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_amazon_cf", get_defined_vars ());
335
  /**/
336
+ echo '<div class="ws-menu-page-group" title="Amazon® S3/CloudFront CDN Storage Option"' . ((c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"]) ? ' default-state="open"' : '') . '>' . "\n";
337
  /**/
338
  echo '<div class="ws-menu-page-section ws-plugin--s2member-amazon-cf-section">' . "\n";
339
  echo '<h3>Amazon® S3/CloudFront CDN Storage &amp; Delivery ( optional )</h3>' . "\n";
410
  echo '<tr>' . "\n";
411
  /**/
412
  echo '<td>' . "\n";
413
+ echo '<input type="checkbox" name="ws_plugin__s2member_amazon_cf_files_auto_configure_distros" id="ws-plugin--s2member-amazon-cf-files-auto-configure-distros" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-amazon-cf-files-auto-configure-distros")) . '"' . ((c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"]) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-amazon-cf-files-auto-configure-distros"><strong>Yes</strong>, automatically configure my Amazon® CloudFront Distributions &amp; Amazon® S3 ACLs for me.</label><br />' . "\n";
414
  echo '<em>s2Member will auto-configure and/or delete &amp; re-configure your Amazon® CloudFront Distributions for you.</em>' . "\n";
415
  echo '</td>' . "\n";
416
  /**/
418
  echo '<tr>' . "\n";
419
  /**/
420
  echo '<td>' . "\n";
421
+ echo '<input type="checkbox" name="ws_plugin__s2member_amazon_cf_files_auto_configure_distros_w_cnames" id="ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames" value="' . esc_attr (wp_create_nonce ("ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames")) . '"' . ((c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"] && ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"] || $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"])) ? ' checked="checked"' : '') . ' /> <label for="ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames"><strong>Yes</strong>, I want s2Member to auto-configure using custom CNAMES that I\'ll setup.</label><br />' . "\n";
422
  echo '<em>* Optional, do NOT check this box unless you know what you\'re doing. This requires DNS changes.</em>' . "\n";
423
  echo '</td>' . "\n";
424
  /**/
includes/menu-pages/menu-pages-s.js CHANGED
@@ -20,7 +20,7 @@ jQuery(document).ready (function($)
20
  return String(str).replace (/"/g, '&quot;').replace (/\</g, '&lt;').replace (/\>/g, '&gt;');
21
  };
22
  /**/
23
- if (location.href.match /* Any/all s2Member® pages. */ (/page\=ws-plugin--s2member/))
24
  {
25
  $('input.ws-plugin--s2member-update-roles-button, input.ws-plugin--s2member-reset-roles-button').click (function()
26
  {
20
  return String(str).replace (/"/g, '&quot;').replace (/\</g, '&lt;').replace (/\>/g, '&gt;');
21
  };
22
  /**/
23
+ if (location.href.match /* Any & all s2Member® pages. */ (/page\=ws-plugin--s2member/))
24
  {
25
  $('input.ws-plugin--s2member-update-roles-button, input.ws-plugin--s2member-reset-roles-button').click (function()
26
  {
includes/translations/s2member.pot CHANGED
@@ -1,10 +1,10 @@
1
- # Copyright (C) 2010
2
- # This file is distributed under the same license as the package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/.__s2member\n"
7
- "POT-Creation-Date: 2011-12-06 11:47:21+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -92,17 +92,17 @@ msgctxt "s2member-front"
92
  msgid "<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>."
93
  msgstr ""
94
 
95
- #: s2member/includes/classes/files-in.inc.php:391
96
  msgctxt "s2member-front"
97
  msgid "<strong>503: Access denied.</strong> Invalid File Download specs."
98
  msgstr ""
99
 
100
- #: s2member/includes/classes/files-in.inc.php:477
101
  msgctxt "s2member-front"
102
  msgid "Members Only"
103
  msgstr ""
104
 
105
- #: s2member/includes/classes/files-in.inc.php:483
106
  msgctxt "s2member-front"
107
  msgid "<strong>401:</strong> Sorry, access denied."
108
  msgstr ""
@@ -111,12 +111,12 @@ msgstr ""
111
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
112
  #. `%s` if you like.
113
 
114
- #: s2member/includes/classes/files-in.inc.php:621
115
  msgctxt "s2member-admin"
116
  msgid "Unable to update existing Amazon® S3 Cross-Domain Policy. %s"
117
  msgstr ""
118
 
119
- #: s2member/includes/classes/files-in.inc.php:624
120
  msgctxt "s2member-admin"
121
  msgid "Unable to update existing Amazon® S3 Cross-Domain Policy. Connection failed."
122
  msgstr ""
@@ -125,12 +125,12 @@ msgstr ""
125
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
126
  #. `%s` if you like.
127
 
128
- #: s2member/includes/classes/files-in.inc.php:628
129
  msgctxt "s2member-admin"
130
  msgid "Unable to update existing Amazon® S3 Bucket Policy. %s"
131
  msgstr ""
132
 
133
- #: s2member/includes/classes/files-in.inc.php:631
134
  msgctxt "s2member-admin"
135
  msgid "Unable to update existing Amazon® S3 Bucket Policy. Connection failed."
136
  msgstr ""
@@ -139,17 +139,17 @@ msgstr ""
139
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
140
  #. `%s` if you like.
141
 
142
- #: s2member/includes/classes/files-in.inc.php:635
143
  msgctxt "s2member-admin"
144
  msgid "Unable to update existing Amazon® S3 Bucket ACLs. %s"
145
  msgstr ""
146
 
147
- #: s2member/includes/classes/files-in.inc.php:638
148
  msgctxt "s2member-admin"
149
  msgid "Unable to update existing Amazon® S3 Bucket ACLs. Connection failed."
150
  msgstr ""
151
 
152
- #: s2member/includes/classes/files-in.inc.php:641
153
  msgctxt "s2member-admin"
154
  msgid "Unable to acquire/read existing Amazon® S3 Bucket ACLs. Unexpected response."
155
  msgstr ""
@@ -158,22 +158,22 @@ msgstr ""
158
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
159
  #. `%s` if you like.
160
 
161
- #: s2member/includes/classes/files-in.inc.php:645
162
  msgctxt "s2member-admin"
163
  msgid "Unable to acquire existing Amazon® S3 Bucket ACLs. %s"
164
  msgstr ""
165
 
166
- #: s2member/includes/classes/files-in.inc.php:648
167
  msgctxt "s2member-admin"
168
  msgid "Unable to acquire existing Amazon® S3 Bucket ACLs. Connection failed."
169
  msgstr ""
170
 
171
- #: s2member/includes/classes/files-in.inc.php:651
172
  msgctxt "s2member-admin"
173
  msgid "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."
174
  msgstr ""
175
 
176
- #: s2member/includes/classes/files-in.inc.php:753
177
  msgctxt "s2member-admin"
178
  msgid "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."
179
  msgstr ""
@@ -182,12 +182,12 @@ msgstr ""
182
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
183
  #. exclude `%s` if you like.
184
 
185
- #: s2member/includes/classes/files-in.inc.php:760
186
  msgctxt "s2member-admin"
187
  msgid "Unable to delete existing Amazon® CloudFront Downloads Distro. %s"
188
  msgstr ""
189
 
190
- #: s2member/includes/classes/files-in.inc.php:772
191
  msgctxt "s2member-admin"
192
  msgid "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."
193
  msgstr ""
@@ -196,7 +196,7 @@ msgstr ""
196
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
197
  #. exclude `%s` if you like.
198
 
199
- #: s2member/includes/classes/files-in.inc.php:779
200
  msgctxt "s2member-admin"
201
  msgid "Unable to delete existing Amazon® CloudFront Streaming Distro. %s"
202
  msgstr ""
@@ -205,8 +205,8 @@ msgstr ""
205
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
206
  #. exclude `%s` if you like.
207
 
208
- #: s2member/includes/classes/files-in.inc.php:795
209
- #: s2member/includes/classes/files-in.inc.php:977
210
  msgctxt "s2member-admin"
211
  msgid "Unable to delete existing Amazon® CloudFront Origin Access Identity. %s"
212
  msgstr ""
@@ -215,12 +215,12 @@ msgstr ""
215
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
216
  #. `%s` if you like.
217
 
218
- #: s2member/includes/classes/files-in.inc.php:834
219
  msgctxt "s2member-admin"
220
  msgid "Unable to update existing Amazon® S3 ACLs. %s"
221
  msgstr ""
222
 
223
- #: s2member/includes/classes/files-in.inc.php:837
224
  msgctxt "s2member-admin"
225
  msgid "Unable to update existing Amazon® S3 ACLs. Connection failed."
226
  msgstr ""
@@ -229,14 +229,14 @@ msgstr ""
229
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
230
  #. exclude `%s` if you like.
231
 
232
- #: s2member/includes/classes/files-in.inc.php:841
233
  #: s2member/includes/classes/files-in.inc.php:1265
234
  msgctxt "s2member-admin"
235
  msgid "Unable to create Amazon® CloudFront Streaming Distro. %s"
236
  msgstr ""
237
 
238
- #: s2member/includes/classes/files-in.inc.php:844
239
- #: s2member/includes/classes/files-in.inc.php:1267
240
  msgctxt "s2member-admin"
241
  msgid "Unable to create Amazon® CloudFront Streaming Distro. Connection failed."
242
  msgstr ""
@@ -245,14 +245,14 @@ msgstr ""
245
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
246
  #. exclude `%s` if you like.
247
 
248
- #: s2member/includes/classes/files-in.inc.php:848
249
- #: s2member/includes/classes/files-in.inc.php:1244
250
  msgctxt "s2member-admin"
251
  msgid "Unable to create Amazon® CloudFront Downloads Distro. %s"
252
  msgstr ""
253
 
254
- #: s2member/includes/classes/files-in.inc.php:851
255
- #: s2member/includes/classes/files-in.inc.php:1246
256
  msgctxt "s2member-admin"
257
  msgid "Unable to create Amazon® CloudFront Downloads Distro. Connection failed."
258
  msgstr ""
@@ -261,19 +261,19 @@ msgstr ""
261
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
262
  #. exclude `%s` if you like.
263
 
264
- #: s2member/includes/classes/files-in.inc.php:855
265
- #: s2member/includes/classes/files-in.inc.php:1022
266
  msgctxt "s2member-admin"
267
  msgid "Unable to create Amazon® CloudFront Origin Access Identity. %s"
268
  msgstr ""
269
 
270
- #: s2member/includes/classes/files-in.inc.php:858
271
- #: s2member/includes/classes/files-in.inc.php:1025
272
  msgctxt "s2member-admin"
273
  msgid "Unable to create Amazon® CloudFront Origin Access Identity. Connection failed."
274
  msgstr ""
275
 
276
- #: s2member/includes/classes/files-in.inc.php:861
277
  msgctxt "s2member-admin"
278
  msgid "Unable to clear existing Amazon® CloudFront Origin Access Identity."
279
  msgstr ""
@@ -282,19 +282,19 @@ msgstr ""
282
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
283
  #. exclude `%s` if you like.
284
 
285
- #: s2member/includes/classes/files-in.inc.php:865
286
- #: s2member/includes/classes/files-in.inc.php:934
287
  msgctxt "s2member-admin"
288
  msgid "Unable to acquire existing Amazon® CloudFront Origin Access Identity. %s"
289
  msgstr ""
290
 
291
- #: s2member/includes/classes/files-in.inc.php:868
292
- #: s2member/includes/classes/files-in.inc.php:937
293
  msgctxt "s2member-admin"
294
  msgid "Unable to acquire existing Amazon® CloudFront Origin Access Identity. Connection failed."
295
  msgstr ""
296
 
297
- #: s2member/includes/classes/files-in.inc.php:871
298
  msgctxt "s2member-admin"
299
  msgid "Unable to clear existing Amazon® CloudFront Streaming Distro."
300
  msgstr ""
@@ -303,17 +303,17 @@ msgstr ""
303
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
304
  #. exclude `%s` if you like.
305
 
306
- #: s2member/includes/classes/files-in.inc.php:875
307
  msgctxt "s2member-admin"
308
  msgid "Unable to acquire existing Amazon® CloudFront Streaming Distro. %s"
309
  msgstr ""
310
 
311
- #: s2member/includes/classes/files-in.inc.php:878
312
  msgctxt "s2member-admin"
313
  msgid "Unable to acquire existing Amazon® CloudFront Streaming Distro. Connection failed."
314
  msgstr ""
315
 
316
- #: s2member/includes/classes/files-in.inc.php:881
317
  msgctxt "s2member-admin"
318
  msgid "Unable to clear existing Amazon® CloudFront Downloads Distro."
319
  msgstr ""
@@ -322,22 +322,22 @@ msgstr ""
322
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
323
  #. exclude `%s` if you like.
324
 
325
- #: s2member/includes/classes/files-in.inc.php:885
326
  msgctxt "s2member-admin"
327
  msgid "Unable to acquire existing Amazon® CloudFront Downloads Distro. %s"
328
  msgstr ""
329
 
330
- #: s2member/includes/classes/files-in.inc.php:888
331
  msgctxt "s2member-admin"
332
  msgid "Unable to acquire existing Amazon® CloudFront Downloads Distro. Connection failed."
333
  msgstr ""
334
 
335
- #: s2member/includes/classes/files-in.inc.php:891
336
  msgctxt "s2member-admin"
337
  msgid "Unable to auto-configure Amazon® CloudFront Distros. Incomplete Amazon® CloudFront configuration options. Missing of one: Amazon® CloudFront Private Key-Pair-ID, or Private Key file contents."
338
  msgstr ""
339
 
340
- #: s2member/includes/classes/files-in.inc.php:894
341
  msgctxt "s2member-admin"
342
  msgid "Unable to auto-configure Amazon® S3/CloudFront Distros. Incomplete Amazon® S3 configuration options. Missing one of: Amazon® S3 Bucket, Access Key, or Secret Key. You must provide s2Member with an Amazon® S3 configuration before enabling CloudFront."
343
  msgstr ""
@@ -346,34 +346,34 @@ msgstr ""
346
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
347
  #. exclude `%s` if you like.
348
 
349
- #: s2member/includes/classes/files-in.inc.php:930
350
  msgctxt "s2member-admin"
351
  msgid "Existing Amazon® CloudFront Origin Access Identity NOT found. %s"
352
  msgstr ""
353
 
354
- #: s2member/includes/classes/files-in.inc.php:940
355
  msgctxt "s2member-admin"
356
  msgid "Unable to acquire existing Amazon® CloudFront Origin Access Identity. Invalid Access ID."
357
  msgstr ""
358
 
359
- #: s2member/includes/classes/files-in.inc.php:980
360
  msgctxt "s2member-admin"
361
  msgid "Unable to delete existing Amazon® CloudFront Origin Access Identity. Connection failed."
362
  msgstr ""
363
 
364
- #: s2member/includes/classes/files-in.inc.php:983
365
  msgctxt "s2member-admin"
366
  msgid "Unable to delete existing Amazon® CloudFront Origin Access Identity. Invalid Access ID, ETag, or XML config."
367
  msgstr ""
368
 
369
- #: s2member/includes/classes/files-in.inc.php:1009
370
- #: s2member/includes/classes/files-in.inc.php:1232
371
- #: s2member/includes/classes/files-in.inc.php:1253
372
  msgctxt "s2member-admin"
373
  msgid "Created by s2Member, for S3 Bucket: %s."
374
  msgstr ""
375
 
376
- #: s2member/includes/classes/files-in.inc.php:1018
377
  msgctxt "s2member-admin"
378
  msgid "Unable to create/read Amazon® CloudFront Origin Access Identity. Unexpected response."
379
  msgstr ""
@@ -382,7 +382,7 @@ msgstr ""
382
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
383
  #. exclude `%s` if you like.
384
 
385
- #: s2member/includes/classes/files-in.inc.php:1062
386
  msgctxt "s2member-admin"
387
  msgid "Existing Amazon® CloudFront Distro NOT found. %s"
388
  msgstr ""
@@ -391,17 +391,17 @@ msgstr ""
391
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
392
  #. exclude `%s` if you like.
393
 
394
- #: s2member/includes/classes/files-in.inc.php:1066
395
  msgctxt "s2member-admin"
396
  msgid "Unable to acquire existing Amazon® CloudFront Distro. %s"
397
  msgstr ""
398
 
399
- #: s2member/includes/classes/files-in.inc.php:1069
400
  msgctxt "s2member-admin"
401
  msgid "Unable to acquire existing Amazon® CloudFront Distro. Connection failed."
402
  msgstr ""
403
 
404
- #: s2member/includes/classes/files-in.inc.php:1072
405
  msgctxt "s2member-admin"
406
  msgid "Unable to acquire existing Amazon® CloudFront Distro. Invalid Distro ID and/or Distro type."
407
  msgstr ""
@@ -410,24 +410,24 @@ msgstr ""
410
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
411
  #. exclude `%s` if you like.
412
 
413
- #: s2member/includes/classes/files-in.inc.php:1116
414
- #: s2member/includes/classes/files-in.inc.php:1191
415
  msgctxt "s2member-admin"
416
  msgid "Unable to disable existing Amazon® CloudFront Distro. %s"
417
  msgstr ""
418
 
419
- #: s2member/includes/classes/files-in.inc.php:1119
420
- #: s2member/includes/classes/files-in.inc.php:1194
421
  msgctxt "s2member-admin"
422
  msgid "Unable to disable existing Amazon® CloudFront Distro. Connection failed."
423
  msgstr ""
424
 
425
- #: s2member/includes/classes/files-in.inc.php:1122
426
  msgctxt "s2member-admin"
427
  msgid "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."
428
  msgstr ""
429
 
430
- #: s2member/includes/classes/files-in.inc.php:1128
431
  msgctxt "s2member-admin"
432
  msgid "Unable to disable existing Amazon® CloudFront Distro. Invalid Distro ID, ETag, or XML config."
433
  msgstr ""
@@ -436,12 +436,12 @@ msgstr ""
436
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
437
  #. exclude `%s` if you like.
438
 
439
- #: s2member/includes/classes/files-in.inc.php:1173
440
  msgctxt "s2member-admin"
441
  msgid "Unable to delete existing Amazon® CloudFront Distro. %s"
442
  msgstr ""
443
 
444
- #: s2member/includes/classes/files-in.inc.php:1176
445
  msgctxt "s2member-admin"
446
  msgid "Unable to delete existing Amazon® CloudFront Distro. Connection failed."
447
  msgstr ""
@@ -450,7 +450,7 @@ msgstr ""
450
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
451
  #. exclude `%s` if you like.
452
 
453
- #: s2member/includes/classes/files-in.inc.php:1180
454
  msgctxt "s2member-admin"
455
  msgid "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."
456
  msgstr ""
@@ -459,27 +459,27 @@ msgstr ""
459
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
460
  #. exclude `%s` if you like.
461
 
462
- #: s2member/includes/classes/files-in.inc.php:1184
463
  msgctxt "s2member-admin"
464
  msgid "Unable to check status of existing Amazon® CloudFront Distro. %s"
465
  msgstr ""
466
 
467
- #: s2member/includes/classes/files-in.inc.php:1187
468
  msgctxt "s2member-admin"
469
  msgid "Unable to check status of existing Amazon® CloudFront Distro. Connection failed."
470
  msgstr ""
471
 
472
- #: s2member/includes/classes/files-in.inc.php:1197
473
  msgctxt "s2member-admin"
474
  msgid "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."
475
  msgstr ""
476
 
477
- #: s2member/includes/classes/files-in.inc.php:1200
478
  msgctxt "s2member-admin"
479
  msgid "Unable to delete existing Amazon® CloudFront Distro. Invalid Distro ID or ETag."
480
  msgstr ""
481
 
482
- #: s2member/includes/classes/files-in.inc.php:1240
483
  msgctxt "s2member-admin"
484
  msgid "Unable to create/read Amazon® CloudFront Downloads Distro. Unexpected response."
485
  msgstr ""
@@ -489,7 +489,7 @@ msgctxt "s2member-admin"
489
  msgid "Unable to create/read Amazon® CloudFront Streaming Distro. Unexpected response."
490
  msgstr ""
491
 
492
- #: s2member/includes/classes/files-in.inc.php:1271
493
  msgctxt "s2member-admin"
494
  msgid "Unable to create Amazon® CloudFront Distro. Invalid Distro type."
495
  msgstr ""
@@ -3387,7 +3387,7 @@ msgctxt "s2member-front"
3387
  msgid "<div>Sorry, your Coupon is N/A, invalid or expired.</div>"
3388
  msgstr ""
3389
 
3390
- #: s2member-pro/includes/classes/gateways/clickbank/clickbank-return-in.inc.php:182
3391
  msgctxt "s2member-front"
3392
  msgid ""
3393
  "ERROR: Unexpected txnType. Please contact Support for assistance.\n"
@@ -3395,7 +3395,7 @@ msgid ""
3395
  "The ClickBank® txnType did not match a required action."
3396
  msgstr ""
3397
 
3398
- #: s2member-pro/includes/classes/gateways/clickbank/clickbank-return-in.inc.php:217
3399
  msgctxt "s2member-front"
3400
  msgid ""
3401
  "ERROR: Unable to verify POST vars. Please contact Support for assistance.\n"
1
+ # Copyright (C) 2010 s2Member
2
+ # This file is distributed under the same license as the s2Member package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: s2Member 111216\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/.__s2member\n"
7
+ "POT-Creation-Date: 2011-12-16 07:13:27+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
92
  msgid "<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>."
93
  msgstr ""
94
 
95
+ #: s2member/includes/classes/files-in.inc.php:390
96
  msgctxt "s2member-front"
97
  msgid "<strong>503: Access denied.</strong> Invalid File Download specs."
98
  msgstr ""
99
 
100
+ #: s2member/includes/classes/files-in.inc.php:476
101
  msgctxt "s2member-front"
102
  msgid "Members Only"
103
  msgstr ""
104
 
105
+ #: s2member/includes/classes/files-in.inc.php:482
106
  msgctxt "s2member-front"
107
  msgid "<strong>401:</strong> Sorry, access denied."
108
  msgstr ""
111
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
112
  #. `%s` if you like.
113
 
114
+ #: s2member/includes/classes/files-in.inc.php:620
115
  msgctxt "s2member-admin"
116
  msgid "Unable to update existing Amazon® S3 Cross-Domain Policy. %s"
117
  msgstr ""
118
 
119
+ #: s2member/includes/classes/files-in.inc.php:623
120
  msgctxt "s2member-admin"
121
  msgid "Unable to update existing Amazon® S3 Cross-Domain Policy. Connection failed."
122
  msgstr ""
125
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
126
  #. `%s` if you like.
127
 
128
+ #: s2member/includes/classes/files-in.inc.php:627
129
  msgctxt "s2member-admin"
130
  msgid "Unable to update existing Amazon® S3 Bucket Policy. %s"
131
  msgstr ""
132
 
133
+ #: s2member/includes/classes/files-in.inc.php:630
134
  msgctxt "s2member-admin"
135
  msgid "Unable to update existing Amazon® S3 Bucket Policy. Connection failed."
136
  msgstr ""
139
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
140
  #. `%s` if you like.
141
 
142
+ #: s2member/includes/classes/files-in.inc.php:634
143
  msgctxt "s2member-admin"
144
  msgid "Unable to update existing Amazon® S3 Bucket ACLs. %s"
145
  msgstr ""
146
 
147
+ #: s2member/includes/classes/files-in.inc.php:637
148
  msgctxt "s2member-admin"
149
  msgid "Unable to update existing Amazon® S3 Bucket ACLs. Connection failed."
150
  msgstr ""
151
 
152
+ #: s2member/includes/classes/files-in.inc.php:640
153
  msgctxt "s2member-admin"
154
  msgid "Unable to acquire/read existing Amazon® S3 Bucket ACLs. Unexpected response."
155
  msgstr ""
158
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
159
  #. `%s` if you like.
160
 
161
+ #: s2member/includes/classes/files-in.inc.php:644
162
  msgctxt "s2member-admin"
163
  msgid "Unable to acquire existing Amazon® S3 Bucket ACLs. %s"
164
  msgstr ""
165
 
166
+ #: s2member/includes/classes/files-in.inc.php:647
167
  msgctxt "s2member-admin"
168
  msgid "Unable to acquire existing Amazon® S3 Bucket ACLs. Connection failed."
169
  msgstr ""
170
 
171
+ #: s2member/includes/classes/files-in.inc.php:650
172
  msgctxt "s2member-admin"
173
  msgid "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."
174
  msgstr ""
175
 
176
+ #: s2member/includes/classes/files-in.inc.php:752
177
  msgctxt "s2member-admin"
178
  msgid "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."
179
  msgstr ""
182
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
183
  #. exclude `%s` if you like.
184
 
185
+ #: s2member/includes/classes/files-in.inc.php:759
186
  msgctxt "s2member-admin"
187
  msgid "Unable to delete existing Amazon® CloudFront Downloads Distro. %s"
188
  msgstr ""
189
 
190
+ #: s2member/includes/classes/files-in.inc.php:771
191
  msgctxt "s2member-admin"
192
  msgid "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."
193
  msgstr ""
196
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
197
  #. exclude `%s` if you like.
198
 
199
+ #: s2member/includes/classes/files-in.inc.php:778
200
  msgctxt "s2member-admin"
201
  msgid "Unable to delete existing Amazon® CloudFront Streaming Distro. %s"
202
  msgstr ""
205
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
206
  #. exclude `%s` if you like.
207
 
208
+ #: s2member/includes/classes/files-in.inc.php:794
209
+ #: s2member/includes/classes/files-in.inc.php:978
210
  msgctxt "s2member-admin"
211
  msgid "Unable to delete existing Amazon® CloudFront Origin Access Identity. %s"
212
  msgstr ""
215
  #. message, which comes from the Amazon® S3 API call. Feel free to exclude
216
  #. `%s` if you like.
217
 
218
+ #: s2member/includes/classes/files-in.inc.php:835
219
  msgctxt "s2member-admin"
220
  msgid "Unable to update existing Amazon® S3 ACLs. %s"
221
  msgstr ""
222
 
223
+ #: s2member/includes/classes/files-in.inc.php:838
224
  msgctxt "s2member-admin"
225
  msgid "Unable to update existing Amazon® S3 ACLs. Connection failed."
226
  msgstr ""
229
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
230
  #. exclude `%s` if you like.
231
 
232
+ #: s2member/includes/classes/files-in.inc.php:842
233
  #: s2member/includes/classes/files-in.inc.php:1265
234
  msgctxt "s2member-admin"
235
  msgid "Unable to create Amazon® CloudFront Streaming Distro. %s"
236
  msgstr ""
237
 
238
+ #: s2member/includes/classes/files-in.inc.php:845
239
+ #: s2member/includes/classes/files-in.inc.php:1268
240
  msgctxt "s2member-admin"
241
  msgid "Unable to create Amazon® CloudFront Streaming Distro. Connection failed."
242
  msgstr ""
245
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
246
  #. exclude `%s` if you like.
247
 
248
+ #: s2member/includes/classes/files-in.inc.php:849
249
+ #: s2member/includes/classes/files-in.inc.php:1242
250
  msgctxt "s2member-admin"
251
  msgid "Unable to create Amazon® CloudFront Downloads Distro. %s"
252
  msgstr ""
253
 
254
+ #: s2member/includes/classes/files-in.inc.php:852
255
+ #: s2member/includes/classes/files-in.inc.php:1245
256
  msgctxt "s2member-admin"
257
  msgid "Unable to create Amazon® CloudFront Downloads Distro. Connection failed."
258
  msgstr ""
261
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
262
  #. exclude `%s` if you like.
263
 
264
+ #: s2member/includes/classes/files-in.inc.php:856
265
+ #: s2member/includes/classes/files-in.inc.php:1023
266
  msgctxt "s2member-admin"
267
  msgid "Unable to create Amazon® CloudFront Origin Access Identity. %s"
268
  msgstr ""
269
 
270
+ #: s2member/includes/classes/files-in.inc.php:859
271
+ #: s2member/includes/classes/files-in.inc.php:1026
272
  msgctxt "s2member-admin"
273
  msgid "Unable to create Amazon® CloudFront Origin Access Identity. Connection failed."
274
  msgstr ""
275
 
276
+ #: s2member/includes/classes/files-in.inc.php:862
277
  msgctxt "s2member-admin"
278
  msgid "Unable to clear existing Amazon® CloudFront Origin Access Identity."
279
  msgstr ""
282
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
283
  #. exclude `%s` if you like.
284
 
285
+ #: s2member/includes/classes/files-in.inc.php:866
286
+ #: s2member/includes/classes/files-in.inc.php:935
287
  msgctxt "s2member-admin"
288
  msgid "Unable to acquire existing Amazon® CloudFront Origin Access Identity. %s"
289
  msgstr ""
290
 
291
+ #: s2member/includes/classes/files-in.inc.php:869
292
+ #: s2member/includes/classes/files-in.inc.php:938
293
  msgctxt "s2member-admin"
294
  msgid "Unable to acquire existing Amazon® CloudFront Origin Access Identity. Connection failed."
295
  msgstr ""
296
 
297
+ #: s2member/includes/classes/files-in.inc.php:872
298
  msgctxt "s2member-admin"
299
  msgid "Unable to clear existing Amazon® CloudFront Streaming Distro."
300
  msgstr ""
303
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
304
  #. exclude `%s` if you like.
305
 
306
+ #: s2member/includes/classes/files-in.inc.php:876
307
  msgctxt "s2member-admin"
308
  msgid "Unable to acquire existing Amazon® CloudFront Streaming Distro. %s"
309
  msgstr ""
310
 
311
+ #: s2member/includes/classes/files-in.inc.php:879
312
  msgctxt "s2member-admin"
313
  msgid "Unable to acquire existing Amazon® CloudFront Streaming Distro. Connection failed."
314
  msgstr ""
315
 
316
+ #: s2member/includes/classes/files-in.inc.php:882
317
  msgctxt "s2member-admin"
318
  msgid "Unable to clear existing Amazon® CloudFront Downloads Distro."
319
  msgstr ""
322
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
323
  #. exclude `%s` if you like.
324
 
325
+ #: s2member/includes/classes/files-in.inc.php:886
326
  msgctxt "s2member-admin"
327
  msgid "Unable to acquire existing Amazon® CloudFront Downloads Distro. %s"
328
  msgstr ""
329
 
330
+ #: s2member/includes/classes/files-in.inc.php:889
331
  msgctxt "s2member-admin"
332
  msgid "Unable to acquire existing Amazon® CloudFront Downloads Distro. Connection failed."
333
  msgstr ""
334
 
335
+ #: s2member/includes/classes/files-in.inc.php:892
336
  msgctxt "s2member-admin"
337
  msgid "Unable to auto-configure Amazon® CloudFront Distros. Incomplete Amazon® CloudFront configuration options. Missing of one: Amazon® CloudFront Private Key-Pair-ID, or Private Key file contents."
338
  msgstr ""
339
 
340
+ #: s2member/includes/classes/files-in.inc.php:895
341
  msgctxt "s2member-admin"
342
  msgid "Unable to auto-configure Amazon® S3/CloudFront Distros. Incomplete Amazon® S3 configuration options. Missing one of: Amazon® S3 Bucket, Access Key, or Secret Key. You must provide s2Member with an Amazon® S3 configuration before enabling CloudFront."
343
  msgstr ""
346
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
347
  #. exclude `%s` if you like.
348
 
349
+ #: s2member/includes/classes/files-in.inc.php:931
350
  msgctxt "s2member-admin"
351
  msgid "Existing Amazon® CloudFront Origin Access Identity NOT found. %s"
352
  msgstr ""
353
 
354
+ #: s2member/includes/classes/files-in.inc.php:941
355
  msgctxt "s2member-admin"
356
  msgid "Unable to acquire existing Amazon® CloudFront Origin Access Identity. Invalid Access ID."
357
  msgstr ""
358
 
359
+ #: s2member/includes/classes/files-in.inc.php:981
360
  msgctxt "s2member-admin"
361
  msgid "Unable to delete existing Amazon® CloudFront Origin Access Identity. Connection failed."
362
  msgstr ""
363
 
364
+ #: s2member/includes/classes/files-in.inc.php:984
365
  msgctxt "s2member-admin"
366
  msgid "Unable to delete existing Amazon® CloudFront Origin Access Identity. Invalid Access ID, ETag, or XML config."
367
  msgstr ""
368
 
369
+ #: s2member/includes/classes/files-in.inc.php:1010
370
+ #: s2member/includes/classes/files-in.inc.php:1229
371
+ #: s2member/includes/classes/files-in.inc.php:1252
372
  msgctxt "s2member-admin"
373
  msgid "Created by s2Member, for S3 Bucket: %s."
374
  msgstr ""
375
 
376
+ #: s2member/includes/classes/files-in.inc.php:1019
377
  msgctxt "s2member-admin"
378
  msgid "Unable to create/read Amazon® CloudFront Origin Access Identity. Unexpected response."
379
  msgstr ""
382
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
383
  #. exclude `%s` if you like.
384
 
385
+ #: s2member/includes/classes/files-in.inc.php:1063
386
  msgctxt "s2member-admin"
387
  msgid "Existing Amazon® CloudFront Distro NOT found. %s"
388
  msgstr ""
391
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
392
  #. exclude `%s` if you like.
393
 
394
+ #: s2member/includes/classes/files-in.inc.php:1067
395
  msgctxt "s2member-admin"
396
  msgid "Unable to acquire existing Amazon® CloudFront Distro. %s"
397
  msgstr ""
398
 
399
+ #: s2member/includes/classes/files-in.inc.php:1070
400
  msgctxt "s2member-admin"
401
  msgid "Unable to acquire existing Amazon® CloudFront Distro. Connection failed."
402
  msgstr ""
403
 
404
+ #: s2member/includes/classes/files-in.inc.php:1073
405
  msgctxt "s2member-admin"
406
  msgid "Unable to acquire existing Amazon® CloudFront Distro. Invalid Distro ID and/or Distro type."
407
  msgstr ""
410
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
411
  #. exclude `%s` if you like.
412
 
413
+ #: s2member/includes/classes/files-in.inc.php:1115
414
+ #: s2member/includes/classes/files-in.inc.php:1188
415
  msgctxt "s2member-admin"
416
  msgid "Unable to disable existing Amazon® CloudFront Distro. %s"
417
  msgstr ""
418
 
419
+ #: s2member/includes/classes/files-in.inc.php:1118
420
+ #: s2member/includes/classes/files-in.inc.php:1191
421
  msgctxt "s2member-admin"
422
  msgid "Unable to disable existing Amazon® CloudFront Distro. Connection failed."
423
  msgstr ""
424
 
425
+ #: s2member/includes/classes/files-in.inc.php:1121
426
  msgctxt "s2member-admin"
427
  msgid "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."
428
  msgstr ""
429
 
430
+ #: s2member/includes/classes/files-in.inc.php:1127
431
  msgctxt "s2member-admin"
432
  msgid "Unable to disable existing Amazon® CloudFront Distro. Invalid Distro ID, ETag, or XML config."
433
  msgstr ""
436
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
437
  #. exclude `%s` if you like.
438
 
439
+ #: s2member/includes/classes/files-in.inc.php:1170
440
  msgctxt "s2member-admin"
441
  msgid "Unable to delete existing Amazon® CloudFront Distro. %s"
442
  msgstr ""
443
 
444
+ #: s2member/includes/classes/files-in.inc.php:1173
445
  msgctxt "s2member-admin"
446
  msgid "Unable to delete existing Amazon® CloudFront Distro. Connection failed."
447
  msgstr ""
450
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
451
  #. exclude `%s` if you like.
452
 
453
+ #: s2member/includes/classes/files-in.inc.php:1177
454
  msgctxt "s2member-admin"
455
  msgid "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."
456
  msgstr ""
459
  #. message, which comes from the Amazon® CloudFront API call. Feel free to
460
  #. exclude `%s` if you like.
461
 
462
+ #: s2member/includes/classes/files-in.inc.php:1181
463
  msgctxt "s2member-admin"
464
  msgid "Unable to check status of existing Amazon® CloudFront Distro. %s"
465
  msgstr ""
466
 
467
+ #: s2member/includes/classes/files-in.inc.php:1184
468
  msgctxt "s2member-admin"
469
  msgid "Unable to check status of existing Amazon® CloudFront Distro. Connection failed."
470
  msgstr ""
471
 
472
+ #: s2member/includes/classes/files-in.inc.php:1194
473
  msgctxt "s2member-admin"
474
  msgid "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."
475
  msgstr ""
476
 
477
+ #: s2member/includes/classes/files-in.inc.php:1197
478
  msgctxt "s2member-admin"
479
  msgid "Unable to delete existing Amazon® CloudFront Distro. Invalid Distro ID or ETag."
480
  msgstr ""
481
 
482
+ #: s2member/includes/classes/files-in.inc.php:1238
483
  msgctxt "s2member-admin"
484
  msgid "Unable to create/read Amazon® CloudFront Downloads Distro. Unexpected response."
485
  msgstr ""
489
  msgid "Unable to create/read Amazon® CloudFront Streaming Distro. Unexpected response."
490
  msgstr ""
491
 
492
+ #: s2member/includes/classes/files-in.inc.php:1272
493
  msgctxt "s2member-admin"
494
  msgid "Unable to create Amazon® CloudFront Distro. Invalid Distro type."
495
  msgstr ""
3387
  msgid "<div>Sorry, your Coupon is N/A, invalid or expired.</div>"
3388
  msgstr ""
3389
 
3390
+ #: s2member-pro/includes/classes/gateways/clickbank/clickbank-return-in.inc.php:181
3391
  msgctxt "s2member-front"
3392
  msgid ""
3393
  "ERROR: Unexpected txnType. Please contact Support for assistance.\n"
3395
  "The ClickBank® txnType did not match a required action."
3396
  msgstr ""
3397
 
3398
+ #: s2member-pro/includes/classes/gateways/clickbank/clickbank-return-in.inc.php:216
3399
  msgctxt "s2member-front"
3400
  msgid ""
3401
  "ERROR: Unable to verify POST vars. Please contact Support for assistance.\n"
readme.txt CHANGED
@@ -1,7 +1,7 @@
1
  === s2Member® ( Membership w/ PayPal® ) ===
2
 
3
- Version: 111206
4
- Stable tag: 111206
5
  Framework: WS-P-110523
6
 
7
  SSL Compatible: yes
@@ -179,6 +179,11 @@ Please visit s2Member.com for [video tutorials](http://www.s2member.com/videos/)
179
 
180
  == Changelog ==
181
 
 
 
 
 
 
182
  = v111206 =
183
  * (s2Member/s2Member Pro) **WordPress® v3.3**. Updates for compatibility with WordPress® v3.3. This release of s2Member also remains compatible with the WordPress® v3.2.x series.
184
  * (s2Member/s2Member Pro) **Bug fix**. An important bug was identified in s2Member's handling of certain EOT events associated with Subscr. Modifications *( under the right scenario )*. Fixed in this release.
1
  === s2Member® ( Membership w/ PayPal® ) ===
2
 
3
+ Version: 111216
4
+ Stable tag: 111216
5
  Framework: WS-P-110523
6
 
7
  SSL Compatible: yes
179
 
180
  == Changelog ==
181
 
182
+ = v111216 =
183
+ * (s2Member/s2Member Pro) **Bug fix**. ClickBank® not passing all s2 Vars after return from a non-recurring transaction. Fixed in this release. For further details, please see [this thread](http://www.primothemes.com/forums/viewtopic.php?f=4&t=16256#p56649).
184
+ * (s2Member) **Bug fix**. Amazon® S3/CloudFront issues with ACLs upon auto-configuration routine. Leading to a 400 error code. Fixed in this release. For further details, please see [this thread](http://www.primothemes.com/forums/viewtopic.php?f=4&t=15853&p=56158#p56159).
185
+ * (s2Member/s2Member Pro) **WordPress® v3.3 / v3.4**. Updates for compatibility with WordPress® v3.3, and initial compatibility scans against WordPress® v3.4-alpha. Everything looks good. This release of s2Member also remains compatible with the WordPress® v3.2.x series.
186
+
187
  = v111206 =
188
  * (s2Member/s2Member Pro) **WordPress® v3.3**. Updates for compatibility with WordPress® v3.3. This release of s2Member also remains compatible with the WordPress® v3.2.x series.
189
  * (s2Member/s2Member Pro) **Bug fix**. An important bug was identified in s2Member's handling of certain EOT events associated with Subscr. Modifications *( under the right scenario )*. Fixed in this release.
s2member.php CHANGED
@@ -19,8 +19,8 @@
19
  */
20
  /* -- This section for WordPress® parsing. ------------------------------------------------------------------------------
21
 
22
- Version: 111206
23
- Stable tag: 111206
24
  Framework: WS-P-110523
25
 
26
  SSL Compatible: yes
@@ -31,12 +31,12 @@ WP Multisite Compatible: yes
31
  Multisite Blog Farm Compatible: yes
32
 
33
  PayPal® Standard Compatible: yes
34
- PayPal® Pro Compatible: w/ s2Member Pro
35
- Google® Checkout Compatible: w/ s2Member Pro
36
- Authorize.Net® Compatible: w/ s2Member Pro
37
- ClickBank® Compatible: w/ s2Member Pro
38
- AliPay® Compatible: w/ s2Member Pro
39
- ccBill® Compatible: w/ s2Member Pro
40
 
41
  Tested up to: 3.3
42
  Requires at least: 3.2
@@ -76,7 +76,7 @@ if (realpath (__FILE__) === realpath ($_SERVER["SCRIPT_FILENAME"]))
76
  * @var str
77
  */
78
  if (!defined ("WS_PLUGIN__S2MEMBER_VERSION"))
79
- define ("WS_PLUGIN__S2MEMBER_VERSION", "111206");
80
  /**
81
  * Minimum PHP version required to run s2Member.
82
  *
@@ -106,7 +106,7 @@ if (!defined ("WS_PLUGIN__S2MEMBER_MIN_WP_VERSION"))
106
  * @var str
107
  */
108
  if (!defined ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION"))
109
- define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "111206");
110
  /*
111
  Several compatibility checks.
112
  If all pass, load the s2Member plugin.
19
  */
20
  /* -- This section for WordPress® parsing. ------------------------------------------------------------------------------
21
 
22
+ Version: 111216
23
+ Stable tag: 111216
24
  Framework: WS-P-110523
25
 
26
  SSL Compatible: yes
31
  Multisite Blog Farm Compatible: yes
32
 
33
  PayPal® Standard Compatible: yes
34
+ PayPal® Pro Compatible: yes w/ s2Member Pro
35
+ Google® Checkout Compatible: yes w/ s2Member Pro
36
+ Authorize.Net® Compatible: yes w/ s2Member Pro
37
+ ClickBank® Compatible: yes w/ s2Member Pro
38
+ AliPay® Compatible: yes w/ s2Member Pro
39
+ ccBill® Compatible: yes w/ s2Member Pro
40
 
41
  Tested up to: 3.3
42
  Requires at least: 3.2
76
  * @var str
77
  */
78
  if (!defined ("WS_PLUGIN__S2MEMBER_VERSION"))
79
+ define ("WS_PLUGIN__S2MEMBER_VERSION", "111216");
80
  /**
81
  * Minimum PHP version required to run s2Member.
82
  *
106
  * @var str
107
  */
108
  if (!defined ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION"))
109
+ define ("WS_PLUGIN__S2MEMBER_MIN_PRO_VERSION", "111216");
110
  /*
111
  Several compatibility checks.
112
  If all pass, load the s2Member plugin.