Version Description
= v140816 =
(Maintenance Release) Upgrade immediately.
Download this release
Release Info
Developer | JasWSInc |
Plugin | s2Member Framework (Member Roles, Capabilities, Membership, PayPal Members) |
Version | 140816 |
Comparing to | |
See all releases |
Code changes from version 140725 to 140816
- checksum.txt +1 -1
- includes/classes/access-cap-times.inc.php +1 -1
- includes/classes/auto-eots.inc.php +1 -0
- includes/classes/files-in.inc.php +1308 -1276
- includes/classes/ip-restrictions.inc.php +7 -8
- includes/classes/list-servers.inc.php +32 -0
- includes/classes/login-customizations.inc.php +4 -3
- includes/classes/login-redirects.inc.php +198 -184
- includes/classes/menu-pages.inc.php +677 -732
- includes/classes/mo-page.inc.php +1 -1
- includes/classes/pages-sp.inc.php +96 -104
- includes/classes/pages.inc.php +94 -103
- includes/classes/paypal-return-in-subscr-modify-w-level.inc.php +4 -4
- includes/classes/paypal-return-in-subscr-or-wa-w-level.inc.php +379 -374
- includes/classes/paypal-return-in-wa-ccaps-wo-level.inc.php +4 -4
- includes/classes/paypal-return-in-web-accept-sp.inc.php +4 -4
- includes/classes/posts-sp.inc.php +122 -107
- includes/classes/posts.inc.php +119 -107
- includes/classes/querys.inc.php +378 -372
- includes/classes/registration-times.inc.php +1 -1
- includes/classes/return-templates.inc.php +65 -69
- includes/classes/roles-caps.inc.php +155 -155
- includes/classes/ruris.inc.php +94 -95
- includes/classes/sc-files-in.inc.php +311 -143
- includes/classes/utils-arrays.inc.php +1 -1
- includes/classes/utils-conds.inc.php +29 -0
- includes/classes/utils-gets.inc.php +391 -333
- includes/classes/utils-users.inc.php +3 -11
- includes/functions/class-autoloader.inc.php +75 -76
- includes/menu-pages/down-ops.inc.php +656 -649
- includes/menu-pages/gen-ops.inc.php +8 -1
- includes/menu-pages/integrations.inc.php +72 -74
- includes/menu-pages/menu-pages-s-min.js +1 -1
checksum.txt
CHANGED
@@ -1 +1 @@
|
|
1 |
-
|
1 |
+
fe5b4d8fea0ad64e6be257a6b6bba04c
|
includes/classes/access-cap-times.inc.php
CHANGED
@@ -211,7 +211,7 @@ if(!class_exists('c_ws_plugin__s2member_access_cap_times'))
|
|
211 |
|
212 |
// $update_ac_times = empty($ac_times) ? FALSE : TRUE;
|
213 |
$ac_times_min = !empty($ac_times) ? min(array_keys($ac_times)) : 0;
|
214 |
-
if(($r_time = c_ws_plugin__s2member_registration_times::registration_time()) && (empty($ac_times_min) || $r_time < $ac_times_min))
|
215 |
$ac_times[number_format(($r_time += .0001), 4, '.', '')] = 'level0';
|
216 |
|
217 |
if(is_array($pr_times = get_user_option('s2member_paid_registration_times', $user_id)))
|
211 |
|
212 |
// $update_ac_times = empty($ac_times) ? FALSE : TRUE;
|
213 |
$ac_times_min = !empty($ac_times) ? min(array_keys($ac_times)) : 0;
|
214 |
+
if(($r_time = c_ws_plugin__s2member_registration_times::registration_time($user_id)) && (empty($ac_times_min) || $r_time < $ac_times_min))
|
215 |
$ac_times[number_format(($r_time += .0001), 4, '.', '')] = 'level0';
|
216 |
|
217 |
if(is_array($pr_times = get_user_option('s2member_paid_registration_times', $user_id)))
|
includes/classes/auto-eots.inc.php
CHANGED
@@ -169,6 +169,7 @@ if (!class_exists ("c_ws_plugin__s2member_auto_eots"))
|
|
169 |
delete_user_option ($user_id, "s2member_auto_eot_time");
|
170 |
|
171 |
delete_user_option ($user_id, "s2member_file_download_access_log");
|
|
|
172 |
|
173 |
c_ws_plugin__s2member_user_notes::append_user_notes ($user_id, "Demoted by s2Member: " . date ("D M j, Y g:i a T"));
|
174 |
|
169 |
delete_user_option ($user_id, "s2member_auto_eot_time");
|
170 |
|
171 |
delete_user_option ($user_id, "s2member_file_download_access_log");
|
172 |
+
delete_user_option ($user_id, "s2member_authnet_payment_failures");
|
173 |
|
174 |
c_ws_plugin__s2member_user_notes::append_user_notes ($user_id, "Demoted by s2Member: " . date ("D M j, Y g:i a T"));
|
175 |
|
includes/classes/files-in.inc.php
CHANGED
@@ -1,1411 +1,1443 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* File Download routines for s2Member (inner processing routines).
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Files
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if(realpath(__FILE__) === realpath($_SERVER[
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if(!class_exists(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
{
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
$_g = !empty($_GET) ? $_GET : array();
|
51 |
-
$_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_g));
|
52 |
-
|
53 |
-
$creating = /* Creating URL? */ (is_array($create = $create_file_download_url)) ? true : false;
|
54 |
-
$serving = /* If NOT creating a File Download URL, we're serving one. */ (!$creating) ? true : false;
|
55 |
-
$serving_range = $range = /* Default values (so these variables DO get defined at all times). */ false;
|
56 |
-
if /* If we're serving, let's see if we're serving a byte-range request here. */($serving)
|
57 |
{
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
if(is_string($_header) && strcasecmp($_header, "range") === 0)
|
63 |
-
$range = $_value;
|
64 |
-
if /* Serving a range? */($range)
|
65 |
-
$serving_range = true;
|
66 |
-
unset($_header, $_value);
|
67 |
}
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
-
|
86 |
-
|
|
|
87 |
{
|
88 |
-
$
|
89 |
-
|
90 |
-
$using_amazon_storage = /* Either? */ ($using_amazon_cf_storage || $using_amazon_s3_storage) ? true : false;
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
$updating_user_counter = ($serving_range || !$checking_user || ($creating && (!isset($req["count_against_user"]) || !filter_var($req["count_against_user"], FILTER_VALIDATE_BOOLEAN)))) ? false : true;
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
status_header(404);
|
105 |
-
header("Content-Type: text/html; charset=UTF-8");
|
106 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
107 |
-
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
|
108 |
-
}
|
109 |
-
else // Else return false.
|
110 |
-
return false;
|
111 |
-
}
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
120 |
-
exit(_x('<strong>503 (Invalid Key):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', "s2member-front", "s2member"));
|
121 |
-
}
|
122 |
-
else // Else return false.
|
123 |
-
return false;
|
124 |
-
}
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
131 |
|
132 |
-
|
133 |
-
|
134 |
-
remove_filter("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
139 |
-
{
|
140 |
-
status_header(503);
|
141 |
-
header("Content-Type: text/html; charset=UTF-8");
|
142 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
143 |
-
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› General Options -› Membership Options Page</code>.', "s2member-front", "s2member"));
|
144 |
-
}
|
145 |
-
else // Else return false.
|
146 |
-
return false;
|
147 |
-
}
|
148 |
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
header("Content-Type: text/html; charset=UTF-8");
|
155 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
156 |
-
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› Download Options -› Basic Download Restrictions</code>.', "s2member-front", "s2member"));
|
157 |
-
}
|
158 |
-
else // Else return false.
|
159 |
-
return false;
|
160 |
-
}
|
161 |
-
|
162 |
-
else if(!is_object($user = apply_filters("ws_plugin__s2member_check_file_download_access_user", ((is_user_logged_in()) ? wp_get_current_user() : false), get_defined_vars())) || empty($user->ID) || !($user_id = $user->ID) || !is_array($user_file_downloads = c_ws_plugin__s2member_files::user_downloads($user)) || (!$user->has_cap("administrator") && (!$user_file_downloads["allowed"] || !$user_file_downloads["allowed_days"])))
|
163 |
-
{
|
164 |
-
if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//", $req["file_download"], $m) && strlen($req_level = $m[1]) && (!is_object($user) || empty($user->ID) || !$user->has_cap("access_s2member_level".$req_level)))
|
165 |
-
{
|
166 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
167 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "level", $req_level, $_SERVER["REQUEST_URI"]).exit();
|
168 |
-
|
169 |
-
else // Else return false.
|
170 |
-
return false;
|
171 |
-
}
|
172 |
-
|
173 |
-
else if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//", $req["file_download"], $m) && strlen($req_ccap = preg_replace("/-/", "_", $m[1])) && (!is_object($user) || empty($user->ID) || !$user->has_cap("access_s2member_ccap_".$req_ccap)))
|
174 |
-
{
|
175 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
176 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "ccap", $req_ccap, $_SERVER["REQUEST_URI"]).exit();
|
177 |
-
|
178 |
-
else // Else return false.
|
179 |
-
return false;
|
180 |
-
}
|
181 |
-
|
182 |
-
else if /* We only need this section when/if we're actually serving. */($serving)
|
183 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "level", $min_level_4_downloads, $_SERVER["REQUEST_URI"]).exit();
|
184 |
-
|
185 |
-
else // Else return false.
|
186 |
-
return false;
|
187 |
-
}
|
188 |
-
|
189 |
-
else if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//", $req["file_download"], $m) && strlen($req_level = $m[1]) && !$user->has_cap("access_s2member_level".$req_level))
|
190 |
-
{
|
191 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
192 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "level", $req_level, $_SERVER["REQUEST_URI"]).exit();
|
193 |
-
|
194 |
-
else // Else return false.
|
195 |
-
return false;
|
196 |
-
}
|
197 |
-
|
198 |
-
else if(preg_match("/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//", $req["file_download"], $m) && strlen($req_ccap = preg_replace("/-/", "_", $m[1])) && !$user->has_cap("access_s2member_ccap_".$req_ccap))
|
199 |
-
{
|
200 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
201 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */("file", $req["file_download"], "ccap", $req_ccap, $_SERVER["REQUEST_URI"]).exit();
|
202 |
-
|
203 |
-
else // Else return false.
|
204 |
-
return false;
|
205 |
-
}
|
206 |
-
|
207 |
-
else if /* In either case, the following routines apply. */($serving || $creating)
|
208 |
-
{
|
209 |
-
$user_previous_file_downloads = /* Downloads the User has already; in current period/cycle. */ 0;
|
210 |
-
$user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = false;
|
211 |
-
|
212 |
-
$user_file_download_access_log = (is_array($user_file_download_access_log = get_user_option("s2member_file_download_access_log", $user_id))) ? $user_file_download_access_log : array();
|
213 |
-
$user_file_download_access_arc = (is_array($user_file_download_access_arc = get_user_option("s2member_file_download_access_arc", $user_id))) ? $user_file_download_access_arc : array();
|
214 |
-
|
215 |
-
$streaming_file_extns = c_ws_plugin__s2member_utils_strings::preg_quote_deep($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["streaming_file_extns"], "/");
|
216 |
-
$streaming_variations = /* Only count one streaming media file variation. */ "/\.(".implode("|", $streaming_file_extns).")$/i";
|
217 |
-
|
218 |
-
foreach($user_file_download_access_log as $user_file_download_access_log_entry_key => $user_file_download_access_log_entry)
|
219 |
-
{
|
220 |
-
if( /* Weed out corrupt/empty log entries. */isset($user_file_download_access_log_entry["date"], $user_file_download_access_log_entry["file"]))
|
221 |
-
{
|
222 |
-
if(strtotime($user_file_download_access_log_entry["date"]) < strtotime("-".$user_file_downloads["allowed_days"]." days"))
|
223 |
-
{
|
224 |
-
unset /* Remove it from the `log`. */($user_file_download_access_log[$user_file_download_access_log_entry_key]);
|
225 |
-
$user_file_download_access_arc[] = /* Move `log` entry to the `archive` now. */ $user_file_download_access_log_entry;
|
226 |
-
}
|
227 |
-
else if(strtotime($user_file_download_access_log_entry["date"]) >= strtotime("-".$user_file_downloads["allowed_days"]." days"))
|
228 |
-
{
|
229 |
-
$user_previous_file_downloads++; // Previous files always count against this User/Member.
|
230 |
-
|
231 |
-
$_user_file_download_access_log_entry = &$user_file_download_access_log[$user_file_download_access_log_entry_key];
|
232 |
-
$_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = false;
|
233 |
-
|
234 |
-
if /* Already downloaded this file? If yes, mark this flag as true. */($user_file_download_access_log_entry["file"] === $req["file_download"])
|
235 |
-
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = /* Already downloaded this file? If yes, mark as true. */ true;
|
236 |
-
|
237 |
-
else if(preg_replace($streaming_variations, "", $user_file_download_access_log_entry["file"]) === preg_replace($streaming_variations, "", $req["file_download"]))
|
238 |
-
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = true;
|
239 |
-
|
240 |
-
if( /* Updating counter? */$updating_user_counter && ($_user_already_downloaded_this_file || $_user_already_downloaded_a_streaming_variation_of_this_file))
|
241 |
-
{
|
242 |
-
$_user_file_download_access_log_entry /* First, we update the last download time for this file. */["ltime"] = time();
|
243 |
-
|
244 |
-
if( /* Backward compatibility here. Is this even set? */!empty($user_file_download_access_log_entry["counter"]))
|
245 |
-
$_user_file_download_access_log_entry["counter"] = (int)$user_file_download_access_log_entry["counter"] + 1;
|
246 |
-
else // Backward compatibility here. Default value to `1`, if this is NOT even set yet.
|
247 |
-
$_user_file_download_access_log_entry["counter"] = 1 + 1;
|
248 |
-
}
|
249 |
-
}
|
250 |
-
}
|
251 |
-
else // Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries.
|
252 |
-
unset /* Remove. */($user_file_download_access_log[$user_file_download_access_log_entry_key]);
|
253 |
-
}
|
254 |
-
if( /* Updating counter? */$updating_user_counter && /* Do we need a new log entry for this file? */ !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file)
|
255 |
-
$user_file_download_access_log[] = array("date" => date("Y-m-d"), "time" => time(), "ltime" => time(), "file" => $req["file_download"], "counter" => 1);
|
256 |
-
|
257 |
-
if($user_previous_file_downloads >= $user_file_downloads["allowed"] && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file && !$user->has_cap("administrator"))
|
258 |
-
{
|
259 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
260 |
-
wp_redirect(add_query_arg(urlencode_deep(array("_s2member_seeking" => array("type" => "file", "file" => $req["file_download"], "_uri" => base64_encode($_SERVER["REQUEST_URI"])), "s2member_seeking" => "file-".$req["file_download"])), get_page_link($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"])), apply_filters("ws_plugin__s2member_content_redirect_status", 301, get_defined_vars())).exit();
|
261 |
-
|
262 |
-
else // Else return false.
|
263 |
-
return false;
|
264 |
-
}
|
265 |
-
else if /* Save/update counter? By default, we do NOT update the counter when a URL is simply being created for access. */($updating_user_counter)
|
266 |
-
update_user_option($user_id, "s2member_file_download_access_log", c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_log)).update_user_option($user_id, "s2member_file_download_access_arc", c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_arc));
|
267 |
-
}
|
268 |
-
}
|
269 |
-
}
|
270 |
-
else // Otherwise, we're either NOT ``$checking_user``; or permission was granted with a valid File Download Key.
|
271 |
{
|
272 |
-
|
273 |
-
|
274 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
275 |
-
{
|
276 |
-
status_header(404);
|
277 |
-
header("Content-Type: text/html; charset=UTF-8");
|
278 |
-
while (@ob_end_clean ()); // Clean any existing output buffers.
|
279 |
-
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
|
280 |
-
}
|
281 |
-
else // Else return false.
|
282 |
-
return false;
|
283 |
-
}
|
284 |
}
|
285 |
-
|
286 |
-
if /* In either case, the following routines apply. */($serving || $creating)
|
287 |
{
|
288 |
-
$
|
289 |
-
$mimetypes = parse_ini_file(dirname(dirname(dirname(__FILE__)))."/includes/mime-types.ini");
|
290 |
-
$extension = strtolower(substr($req["file_download"], strrpos($req["file_download"], ".") + 1));
|
291 |
|
292 |
-
$
|
|
|
293 |
|
294 |
-
|
295 |
-
|
296 |
-
$ssl = (isset($req["file_ssl"])) ? filter_var($req["file_ssl"], FILTER_VALIDATE_BOOLEAN) : ((is_ssl()) ? true : false);
|
297 |
-
$storage = ($req["file_storage"] && is_string($req["file_storage"])) ? strtolower($req["file_storage"]) : false;
|
298 |
-
$remote = (isset($req["file_remote"])) ? filter_var($req["file_remote"], FILTER_VALIDATE_BOOLEAN) : false;
|
299 |
|
300 |
-
$
|
301 |
-
|
302 |
-
$rewrite_base = ($req["file_rewrite_base"] && is_string($req["file_rewrite_base"])) ? $req["file_rewrite_base"] : false;
|
303 |
-
$rewrite = $rewriting = (!$rewrite_base && isset($req["file_rewrite"])) ? filter_var($req["file_rewrite"], FILTER_VALIDATE_BOOLEAN) : (($rewrite_base) ? true : false);
|
304 |
-
unset /* A little housekeeping here. */($_basename_dir_app_data);
|
305 |
|
306 |
-
$
|
307 |
-
|
308 |
-
|
309 |
-
$pathinfo = (!$using_amazon_storage) ? pathinfo(($file = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"]."/".$req["file_download"])) : array();
|
310 |
-
$mimetype = ($mimetypes[$extension]) ? $mimetypes[$extension] : "application/octet-stream";
|
311 |
-
$disposition = (($inline) ? "inline" : "attachment")."; filename=\"".c_ws_plugin__s2member_utils_strings::esc_dq($basename)."\"; filename*=UTF-8''".rawurlencode($basename);
|
312 |
-
$length = (!$using_amazon_storage && $file) ? filesize($file) : -1;
|
313 |
-
|
314 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
315 |
-
do_action("ws_plugin__s2member_during_file_download_access", get_defined_vars());
|
316 |
-
unset($__refs, $__v);
|
317 |
-
|
318 |
-
if($using_amazon_storage && $using_amazon_cf_storage && ($serving || ($creating && $url_to_storage_source)))
|
319 |
-
{
|
320 |
-
if /* We only need this section when/if we're actually serving. */($serving)
|
321 |
-
wp_redirect(c_ws_plugin__s2member_files_in::amazon_cf_url($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)).exit();
|
322 |
|
323 |
-
|
324 |
-
|
325 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
|
332 |
-
|
333 |
-
|
334 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
|
336 |
-
|
337 |
-
|
338 |
-
$_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : "";
|
339 |
-
$_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : "";
|
340 |
-
$_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req["file_download"]));
|
341 |
-
$_url_e_file = str_ireplace("%2F", "/", $_url_e_file);
|
342 |
-
|
343 |
-
$url = ($rewrite_base) ? rtrim($rewrite_base, "/") : rtrim($rewrite_base_guess, "/");
|
344 |
-
$url .= (isset($req["file_download_key"])) ? (($key && $_url_e_key) ? "/s2member-file-download-key-".$_url_e_key : "") : "";
|
345 |
-
$url .= (isset($req["file_stream"])) ? (($stream) ? "/s2member-file-stream" : "/s2member-file-stream-no") : "";
|
346 |
-
$url .= (isset($req["file_inline"])) ? (($inline) ? "/s2member-file-inline" : "/s2member-file-inline-no") : "";
|
347 |
-
$url .= (isset($req["file_storage"])) ? (($storage && $_url_e_storage) ? "/s2member-file-storage-".$_url_e_storage : "") : "";
|
348 |
-
$url .= (isset($req["file_remote"])) ? (($remote) ? "/s2member-file-remote" : "/s2member-file-remote-no") : "";
|
349 |
-
$url .= (isset($req["skip_confirmation"])) ? (($skip_confirmation) ? "/s2member-skip-confirmation" : "/s2member-skip-confirmation-no") : "";
|
350 |
-
|
351 |
-
$url = /* File Download Access URL via `mod_rewrite` functionality. */ $url."/".$_url_e_file;
|
352 |
-
$url = ($ssl) ? preg_replace("/^https?/", "https", $url) : preg_replace("/^https?/", "http", $url);
|
353 |
-
|
354 |
-
return apply_filters("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars());
|
355 |
-
}
|
356 |
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
|
371 |
-
|
372 |
-
|
373 |
|
374 |
-
|
375 |
-
|
376 |
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
@ini_set("zlib.output_compression", 0);
|
382 |
-
if(function_exists("apache_setenv"))
|
383 |
-
@apache_setenv("no-gzip", "1");
|
384 |
-
|
385 |
-
$content_encoding_header = "Content-Encoding:"; // Default value; standards compliant.
|
386 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_content_encodong_none"])
|
387 |
-
$content_encoding_header = "Content-Encoding: none";
|
388 |
-
|
389 |
-
while /* Cleans existing output buffers. */(@ob_end_clean());
|
390 |
-
|
391 |
-
if /* Requesting a specific byte range? */($range)
|
392 |
-
{
|
393 |
-
if /* Invalid range? */(strpos($range, "=") === FALSE)
|
394 |
-
{
|
395 |
-
status_header(416);
|
396 |
-
nocache_headers();
|
397 |
-
header($content_encoding_header);
|
398 |
-
header("Accept-Ranges: bytes");
|
399 |
-
header("Content-Type: ".$mimetype);
|
400 |
-
header("Content-Length: ".$length);
|
401 |
-
header("Content-Disposition: ".$disposition);
|
402 |
-
exit /* Stop here (invalid). */();
|
403 |
-
}
|
404 |
-
list($range_type, $byte_range) = preg_split("/\s*\=\s*/", $range, 2);
|
405 |
-
|
406 |
-
$range_type = strtolower(trim($range_type));
|
407 |
-
$byte_range = trim($byte_range);
|
408 |
-
|
409 |
-
if /* Invalid range type? */($range_type !== "bytes")
|
410 |
-
{
|
411 |
-
status_header(416);
|
412 |
-
nocache_headers();
|
413 |
-
header($content_encoding_header);
|
414 |
-
header("Accept-Ranges: bytes");
|
415 |
-
header("Content-Type: ".$mimetype);
|
416 |
-
header("Content-Length: ".$length);
|
417 |
-
header("Content-Disposition: ".$disposition);
|
418 |
-
exit /* Stop here (invalid). */();
|
419 |
-
}
|
420 |
-
$byte_ranges = preg_split("/\s*,\s*/", $byte_range);
|
421 |
-
|
422 |
-
if /* Invalid byte range? */(strpos($byte_ranges[0], "-") === FALSE)
|
423 |
-
{
|
424 |
-
status_header(416);
|
425 |
-
nocache_headers();
|
426 |
-
header($content_encoding_header);
|
427 |
-
header("Accept-Ranges: bytes");
|
428 |
-
header("Content-Type: ".$mimetype);
|
429 |
-
header("Content-Length: ".$length);
|
430 |
-
header("Content-Disposition: ".$disposition);
|
431 |
-
exit /* Stop here (invalid). */();
|
432 |
-
}
|
433 |
-
|
434 |
-
// Only dealing with the first byte range. Others are simply ignored here.
|
435 |
-
list($byte_range_start, $byte_range_stops) = preg_split("/\s*\-\s*/", $byte_ranges[0], 2);
|
436 |
-
|
437 |
-
$byte_range_start = trim($byte_range_start);
|
438 |
-
$byte_range_stops = trim($byte_range_stops);
|
439 |
-
|
440 |
-
$byte_range_start = ($byte_range_start === "") ? NULL : (integer)$byte_range_start;
|
441 |
-
$byte_range_stops = ($byte_range_stops === "") ? NULL : (integer)$byte_range_stops;
|
442 |
-
|
443 |
-
if(!isset($byte_range_start) && $byte_range_stops > 0 && $byte_range_stops <= $length)
|
444 |
-
{
|
445 |
-
$byte_range_start = $length - $byte_range_stops;
|
446 |
-
$byte_range_stops = /* The last X number of bytes. */ $length - 1;
|
447 |
-
}
|
448 |
-
else if(!isset($byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1)
|
449 |
-
{
|
450 |
-
$byte_range_stops = /* To the end of the file in this case. */ $length - 1;
|
451 |
-
}
|
452 |
-
else if(isset($byte_range_start, $byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1 && $byte_range_stops > $byte_range_start && $byte_range_stops <= $length - 1) {
|
453 |
-
// Nothing to do in this case, starts/stops already defined properly.
|
454 |
-
}
|
455 |
-
else // We have an invalid byte range.
|
456 |
-
{
|
457 |
-
status_header(416);
|
458 |
-
nocache_headers();
|
459 |
-
header($content_encoding_header);
|
460 |
-
header("Accept-Ranges: bytes");
|
461 |
-
header("Content-Type: ".$mimetype);
|
462 |
-
header("Content-Length: ".$length);
|
463 |
-
header("Content-Disposition: ".$disposition);
|
464 |
-
exit /* Stop here (invalid). */();
|
465 |
-
}
|
466 |
-
// Range.
|
467 |
-
status_header(206);
|
468 |
-
nocache_headers();
|
469 |
-
header($content_encoding_header);
|
470 |
-
header("Accept-Ranges: bytes");
|
471 |
-
header("Content-Type: ".$mimetype);
|
472 |
-
header("Content-Range: bytes ".$byte_range_start."-".$byte_range_stops."/".$length);
|
473 |
-
$byte_range_size = $byte_range_stops - $byte_range_start + 1;
|
474 |
-
header("Content-Length: ".$byte_range_size);
|
475 |
-
header("Content-Disposition: ".$disposition);
|
476 |
-
}
|
477 |
-
else // A normal request (NOT a specific byte range).
|
478 |
-
{
|
479 |
-
status_header(200);
|
480 |
-
nocache_headers();
|
481 |
-
header($content_encoding_header);
|
482 |
-
header("Accept-Ranges: bytes");
|
483 |
-
header("Content-Type: ".$mimetype);
|
484 |
-
header("Content-Length: ".$length);
|
485 |
-
header("Content-Disposition: ".$disposition);
|
486 |
-
}
|
487 |
-
if(is_resource($resource = fopen($file, "rb")))
|
488 |
-
{
|
489 |
-
if($range)
|
490 |
-
{
|
491 |
-
$_bytes_to_read = $byte_range_size;
|
492 |
-
fseek($resource, $byte_range_start);
|
493 |
-
}
|
494 |
-
else // Entire file.
|
495 |
-
$_bytes_to_read = $length;
|
496 |
-
|
497 |
-
$chunk_size = apply_filters("ws_plugin__s2member_file_downloads_chunk_size", 2097152, get_defined_vars());
|
498 |
-
|
499 |
-
while /* We have bytes to read here. */($_bytes_to_read)
|
500 |
-
{
|
501 |
-
$_bytes_to_read -= ($_reading = ($_bytes_to_read > $chunk_size) ? $chunk_size : $_bytes_to_read);
|
502 |
-
echo /* Serve file in chunks (default chunk size is 2MB). */ fread($resource, $_reading);
|
503 |
-
flush /* Flush each chunk to the browser as it is served (avoids high memory consumption). */();
|
504 |
-
}
|
505 |
-
fclose /* Close file resource handle. */($resource);
|
506 |
-
unset /* Housekeeping. */($_bytes_to_read, $_reading);
|
507 |
-
}
|
508 |
-
exit /* Stop execution now (the file has been served). */();
|
509 |
-
}
|
510 |
-
}
|
511 |
}
|
512 |
-
|
513 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
514 |
{
|
515 |
-
status_header(
|
516 |
-
|
517 |
-
|
518 |
-
|
|
|
|
|
|
|
519 |
}
|
520 |
-
|
521 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
522 |
|
523 |
-
|
524 |
|
525 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
526 |
}
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
* @return string A File Download URL string on success; or an array on success, with elements `streamer`, `file`, `url` when/if ``$get_streamer_array`` is true; else false on any type of failure.
|
537 |
-
*
|
538 |
-
* @see s2Member\API_Functions\s2member_file_download_url()
|
539 |
-
*/
|
540 |
-
public static function create_file_download_url($config = FALSE, $get_streamer_array = FALSE)
|
541 |
-
{
|
542 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
543 |
-
do_action("ws_plugin__s2member_before_create_file_download_url", get_defined_vars());
|
544 |
-
unset($__refs, $__v);
|
545 |
-
|
546 |
-
$config = (is_array($config)) ? $config : /* This absolutely MUST be an array. */ array();
|
547 |
|
548 |
-
|
549 |
-
$config["file_download_key"] = (isset($config["file_download"]) && is_string($config["file_download"]) && !empty($config["file_download_key"])) ? c_ws_plugin__s2member_files::file_download_key($config["file_download"], ((in_array($config["file_download_key"], array("ip-forever", "universal", "cache-compatible"))) ? $config["file_download_key"] : false)) : @$config["file_download_key"];
|
550 |
|
551 |
-
|
552 |
-
|
553 |
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
563 |
|
564 |
-
|
565 |
-
|
|
|
566 |
|
567 |
-
|
568 |
-
|
569 |
|
570 |
-
|
571 |
-
|
572 |
|
573 |
-
|
574 |
-
|
575 |
-
}
|
576 |
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
* @package s2Member\Files
|
583 |
-
* @since 110926
|
584 |
-
*
|
585 |
-
* @attaches-to ``add_filter("ws_plugin__s2member_check_file_download_access_user");``
|
586 |
-
*
|
587 |
-
* @param object $user Expects a WP_User object passed in by the Filter.
|
588 |
-
* @return obj A `WP_User` object, possibly obtained through Header Authorization.
|
589 |
-
*/
|
590 |
-
public static function check_file_remote_authorization($user = FALSE)
|
591 |
-
{
|
592 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
593 |
-
do_action("ws_plugin__s2member_before_check_file_remote_authorization", get_defined_vars());
|
594 |
-
unset($__refs, $__v);
|
595 |
|
596 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
|
598 |
-
|
599 |
-
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
|
602 |
-
|
603 |
-
|
604 |
-
$auth = trim(preg_replace("/^.+?\s+/", "", $_SERVER["HTTP_AUTHORIZATION"]));
|
605 |
-
$auth = explode(":", base64_decode($auth), 2);
|
606 |
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
header('WWW-Authenticate: Basic realm="'.c_ws_plugin__s2member_utils_strings::esc_dq(strip_tags(_x("Members Only", "s2member-front", "s2member"))).'"');
|
613 |
|
614 |
-
|
615 |
-
|
616 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
617 |
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
622 |
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
638 |
{
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
644 |
{
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
else if($key === c_ws_plugin__s2member_files::file_download_key($file, "universal") || $key === c_ws_plugin__s2member_files::file_download_key("/".$file, "universal"))
|
650 |
-
$valid = /* File Download Key is valid. */ true;
|
651 |
-
}
|
652 |
-
return apply_filters("ws_plugin__s2member_check_file_download_key", ((isset($valid) && $valid) ? true : false), get_defined_vars());
|
653 |
-
}
|
654 |
-
/**
|
655 |
-
* Creates an Amazon S3 HMAC-SHA1 signature.
|
656 |
-
*
|
657 |
-
* @package s2Member\Files
|
658 |
-
* @since 110524RC
|
659 |
-
*
|
660 |
-
* @param string $string Input string/data, to be signed by this routine.
|
661 |
-
* @return string An HMAC-SHA1 signature for Amazon S3.
|
662 |
-
*/
|
663 |
-
public static function amazon_s3_sign($string = FALSE)
|
664 |
-
{
|
665 |
-
$s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
666 |
|
667 |
-
|
668 |
-
|
669 |
-
/**
|
670 |
-
* Creates an Amazon S3 HMAC-SHA1 signature URL.
|
671 |
-
*
|
672 |
-
* @package s2Member\Files
|
673 |
-
* @since 110926
|
674 |
-
*
|
675 |
-
* @param string $file Input file path, to be signed by this routine.
|
676 |
-
* @param bool $stream Is this resource file to be served as streaming media?
|
677 |
-
* @param bool $inline Is this resource file to be served inline, or no?
|
678 |
-
* @param bool $ssl Is this resource file to be served via SSL, or no?
|
679 |
-
* @param string $basename The absolute basename of the resource file.
|
680 |
-
* @param string $mimetype The MIME content-type of the resource file.
|
681 |
-
* @return string An HMAC-SHA1 signature URL for Amazon S3.
|
682 |
-
*/
|
683 |
-
public static function amazon_s3_url($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
|
684 |
-
{
|
685 |
-
$file = /* Trim / force string. */ trim((string)$file, "/");
|
686 |
-
$url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($file));
|
687 |
-
$url_e_file = str_ireplace("%2F", "/", $url_e_file);
|
688 |
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
$s3c["expires"] = strtotime("+".apply_filters("ws_plugin__s2member_amazon_s3_file_expires_time", "24 hours", get_defined_vars()));
|
694 |
|
695 |
-
|
696 |
-
|
697 |
-
|
|
|
|
|
|
|
698 |
|
699 |
-
|
|
|
|
|
|
|
|
|
|
|
700 |
|
701 |
-
|
|
|
702 |
}
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
$s3c[$option] = $option_value;
|
717 |
-
|
718 |
-
$cfc["distros_s3_access_id"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_s3_access_id"];
|
719 |
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
736 |
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
744 |
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
751 |
|
752 |
-
|
753 |
-
|
754 |
|
755 |
-
|
756 |
-
|
757 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Cross-Domain Policy. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
758 |
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
else if(isset($s3_response["code"], $s3_response["message"]))
|
763 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
764 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Bucket Policy. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
765 |
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
else if(isset($s3_response["code"], $s3_response["message"]))
|
770 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
771 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Bucket ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
772 |
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to acquire/read existing Amazon S3 Bucket ACLs. Unexpected response.", "s2member-admin", "s2member"));
|
778 |
-
}
|
779 |
-
else if(isset($s3_response["code"], $s3_response["message"]))
|
780 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
781 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon S3 Bucket ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
782 |
|
783 |
-
else
|
784 |
-
return array(
|
785 |
-
}
|
786 |
-
else // Else, we use a default error code and message.
|
787 |
-
return array("success" => false, "code" => -99, "message" => _x("Unable to auto-configure existing Amazon S3 Bucket ACLs. Incomplete Amazon S3 configuration options. Missing one of: Amazon S3 Bucket, Access Key, or Secret Key.", "s2member-admin", "s2member"));
|
788 |
-
}
|
789 |
-
/**
|
790 |
-
* Creates an Amazon CloudFront HMAC-SHA1 signature.
|
791 |
-
*
|
792 |
-
* @package s2Member\Files
|
793 |
-
* @since 110926
|
794 |
-
*
|
795 |
-
* @param string $string Input string/data, to be signed by this routine.
|
796 |
-
* @return string An HMAC-SHA1 signature for Amazon CloudFront.
|
797 |
-
*/
|
798 |
-
public static function amazon_cf_sign($string = FALSE)
|
799 |
-
{
|
800 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
801 |
|
802 |
-
|
803 |
-
|
804 |
-
/**
|
805 |
-
* Creates an Amazon CloudFront RSA-SHA1 signature.
|
806 |
-
*
|
807 |
-
* @package s2Member\Files
|
808 |
-
* @since 110926
|
809 |
-
*
|
810 |
-
* @param string $string Input string/data, to be signed by this routine.
|
811 |
-
* @return str|bool An RSA-SHA1 signature for Amazon CloudFront, else false on failure.
|
812 |
-
*/
|
813 |
-
public static function amazon_cf_rsa_sign($string = FALSE)
|
814 |
-
{
|
815 |
-
$cfc["private_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"];
|
816 |
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
* Creates an Amazon CloudFront RSA-SHA1 signature URL.
|
821 |
-
*
|
822 |
-
* @package s2Member\Files
|
823 |
-
* @since 110926
|
824 |
-
*
|
825 |
-
* @param string $file Input file path, to be signed by this routine.
|
826 |
-
* @param bool $stream Is this resource file to be served as streaming media?
|
827 |
-
* @param bool $inline Is this resource file to be served inline, or no?
|
828 |
-
* @param bool $ssl Is this resource file to be served via SSL, or no?
|
829 |
-
* @param string $basename The absolute basename of the resource file.
|
830 |
-
* @param string $mimetype The MIME content-type of the resource file.
|
831 |
-
* @return string An RSA-SHA1 signature URL for Amazon CloudFront.
|
832 |
-
*/
|
833 |
-
public static function amazon_cf_url($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
|
834 |
-
{
|
835 |
-
$file = /* Trim & force string. */ trim((string)$file, "/");
|
836 |
-
$url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($file));
|
837 |
-
$url_e_file = str_ireplace("%2F", "/", $url_e_file);
|
838 |
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
|
843 |
-
|
|
|
|
|
|
|
844 |
|
845 |
-
|
846 |
-
|
847 |
-
$cf_stream_extn_resource_exclusions = array_unique((array)apply_filters("ws_plugin__s2member_amazon_cf_file_streaming_extension_resource_exclusions", array("mp3" /* MP3 files should NOT include an extension in their resource reference. */), get_defined_vars()));
|
848 |
-
$cf_resource = ($stream) ? ((in_array($cf_extn, $cf_stream_extn_resource_exclusions)) ? substr($file, 0, strrpos($file, ".")) : $file) : "http".(($ssl) ? "s" : "")."://".(($cfc["distro_downloads_cname"]) ? $cfc["distro_downloads_cname"] : $cfc["distro_downloads_dname"])."/".$url_e_file;
|
849 |
-
$cf_url = ($stream) ? "rtmp".(($ssl) ? "e" : "")."://".(($cfc["distro_streaming_cname"]) ? $cfc["distro_streaming_cname"] : $cfc["distro_streaming_dname"])."/cfx/st/".$file : "http".(($ssl) ? "s" : "")."://".(($cfc["distro_downloads_cname"]) ? $cfc["distro_downloads_cname"] : $cfc["distro_downloads_dname"])."/".$url_e_file;
|
850 |
-
$cf_policy = '{"Statement":[{"Resource":"'.c_ws_plugin__s2member_utils_strings::esc_dq($cf_resource).'","Condition":{'.(($cf_ip_res) ? '"IpAddress":{"AWS:SourceIp":"'.c_ws_plugin__s2member_utils_strings::esc_dq($_SERVER["REMOTE_ADDR"]).'/32"},' : '').'"DateLessThan":{"AWS:EpochTime":'.(int)$cfc["expires"].'}}}]}';
|
851 |
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
* Auto-configures Amazon S3/CloudFront distros.
|
860 |
-
*
|
861 |
-
* @package s2Member\Files
|
862 |
-
* @since 110926
|
863 |
-
*
|
864 |
-
* @return array Array containing a true `success` element on success, else a failure array.
|
865 |
-
* Failure array will contain a failure `code`, and a failure `message`.
|
866 |
-
*/
|
867 |
-
public static function amazon_cf_auto_configure_distros()
|
868 |
-
{
|
869 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
870 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
871 |
-
$cfc[$option] = $option_value;
|
872 |
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
|
877 |
-
|
878 |
-
{
|
879 |
-
if /* We MUST have Amazon CloudFront Keys in order to auto-configure. */($cfc["private_key"] && $cfc["private_key_id"])
|
880 |
-
{
|
881 |
-
if(!$cfc["distro_downloads_id"] || ($cfc["distro_downloads_id"] && ($cf_get_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro($cfc["distro_downloads_id"], "downloads")) && ($cf_get_response["success"] || $cf_get_response["code"] === 404)))
|
882 |
{
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
else if($cfc["distro_downloads_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
|
887 |
-
return array("success" => false, "code" => -86, "message" => _x("Unable to delete existing Amazon CloudFront Downloads Distro. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
888 |
-
|
889 |
-
else if($cfc["distro_downloads_id"] && $cf_get_response && $cf_get_response["success"] && $cf_get_response["deployed"] && ($cf_del_response = c_ws_plugin__s2member_files_in::amazon_cf_del_distro($cfc["distro_downloads_id"], $cf_get_response["etag"], $cf_get_response["xml"])) && $cf_del_response["success"])
|
890 |
-
$cf_distro_downloads_clear = /* Clear, ready for a new one. */ true;
|
891 |
|
892 |
-
|
893 |
-
|
894 |
-
|
|
|
|
|
895 |
|
896 |
-
|
897 |
{
|
898 |
-
|
899 |
-
|
900 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
901 |
{
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
return array("success" => false, "code" => -87, "message" => _x("Unable to delete existing Amazon CloudFront Streaming Distro. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
907 |
-
|
908 |
-
else if($cfc["distro_streaming_id"] && $cf_get_response && $cf_get_response["success"] && $cf_get_response["deployed"] && ($cf_del_response = c_ws_plugin__s2member_files_in::amazon_cf_del_distro($cfc["distro_streaming_id"], $cf_get_response["etag"], $cf_get_response["xml"])) && $cf_del_response["success"])
|
909 |
-
$cf_distro_streaming_clear = /* Clear, ready for a new one. */ true;
|
910 |
-
|
911 |
-
else if(isset($cf_del_response["code"], $cf_del_response["message"]))
|
912 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
913 |
-
return array("success" => false, "code" => $cf_del_response["code"], "message" => sprintf(_x("Unable to delete existing Amazon CloudFront Streaming Distro. %s", "s2member-admin", "s2member"), $cf_del_response["message"]));
|
914 |
-
|
915 |
-
if /* Successfully cleared? Ready for a new one? */(isset($cf_distro_streaming_clear) && $cf_distro_streaming_clear)
|
916 |
-
{
|
917 |
-
unset /* Unset these before processing additional routines. Prevents problems in error reporting. */($cf_get_response, $cf_del_response);
|
918 |
-
|
919 |
-
if(!$cfc["distros_access_id"] || ($cfc["distros_access_id"] && ($cf_get_response = c_ws_plugin__s2member_files_in::amazon_cf_get_access_origin_identity($cfc["distros_access_id"])) && ($cf_get_response["success"] || $cf_get_response["code"] === 404)))
|
920 |
-
{
|
921 |
-
if(!$cfc["distros_access_id"] || ($cfc["distros_access_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
|
922 |
-
$cf_distros_access_clear = /* Clear, ready for a new one. */ true;
|
923 |
-
|
924 |
-
else if($cfc["distros_access_id"] && $cf_get_response && $cf_get_response["success"] && ($cf_del_response = c_ws_plugin__s2member_files_in::amazon_cf_del_access_origin_identity($cfc["distros_access_id"], $cf_get_response["etag"], $cf_get_response["xml"])) && $cf_del_response["success"])
|
925 |
-
$cf_distros_access_clear = /* Clear, ready for a new one. */ true;
|
926 |
-
|
927 |
-
else if(isset($cf_del_response["code"], $cf_del_response["message"]))
|
928 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
929 |
-
return array("success" => false, "code" => $cf_del_response["code"], "message" => sprintf(_x("Unable to delete existing Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_del_response["message"]));
|
930 |
-
|
931 |
-
if /* Successfully cleared? Ready for a new one? */(isset($cf_distros_access_clear) && $cf_distros_access_clear)
|
932 |
-
{
|
933 |
-
unset /* Unset these before processing additional routines. Prevents problems in error reporting. */($cf_get_response, $cf_del_response);
|
934 |
-
|
935 |
-
$cfc = array_merge($cfc, array("distros_access_id" => "", "distros_s3_access_id" => "", "distro_downloads_id" => "", "distro_downloads_dname" => "", "distro_streaming_id" => "", "distro_streaming_dname" => "", "distros_auto_config_status" => ""));
|
936 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distros_access_id" => "", "ws_plugin__s2member_amazon_cf_files_distros_s3_access_id" => "", "ws_plugin__s2member_amazon_cf_files_distro_downloads_id" => "", "ws_plugin__s2member_amazon_cf_files_distro_downloads_dname" => "", "ws_plugin__s2member_amazon_cf_files_distro_streaming_id" => "", "ws_plugin__s2member_amazon_cf_files_distro_streaming_dname" => "", "ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" => "");
|
937 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
938 |
-
|
939 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distros_access_origin_identity()) && $cf_response["success"])
|
940 |
-
{
|
941 |
-
$cfc = array_merge($cfc, array("distros_access_id" => $cf_response["distros_access_id"], "distros_s3_access_id" => $cf_response["distros_s3_access_id"]));
|
942 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distros_access_id" => $cf_response["distros_access_id"], "ws_plugin__s2member_amazon_cf_files_distros_s3_access_id" => $cf_response["distros_s3_access_id"]);
|
943 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
944 |
-
|
945 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro("downloads")) && $cf_response["success"])
|
946 |
-
{
|
947 |
-
$cfc = array_merge($cfc, array("distro_downloads_id" => $cf_response["distro_downloads_id"], "distro_downloads_dname" => $cf_response["distro_downloads_dname"]));
|
948 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distro_downloads_id" => $cf_response["distro_downloads_id"], "ws_plugin__s2member_amazon_cf_files_distro_downloads_dname" => $cf_response["distro_downloads_dname"]);
|
949 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
950 |
-
|
951 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro("streaming")) && $cf_response["success"])
|
952 |
-
{
|
953 |
-
$cfc = array_merge($cfc, array("distro_streaming_id" => $cf_response["distro_streaming_id"], "distro_streaming_dname" => $cf_response["distro_streaming_dname"]));
|
954 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distro_streaming_id" => $cf_response["distro_streaming_id"], "ws_plugin__s2member_amazon_cf_files_distro_streaming_dname" => $cf_response["distro_streaming_dname"]);
|
955 |
-
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
|
956 |
-
|
957 |
-
for($a = 1, $attempts = 4, $sleep = 2, sleep($sleep); $a <= $attempts; $a++, (($a <= $attempts) ? sleep($sleep) : null))
|
958 |
-
/* Allow a generous propagation time here. Amazon's high-availability services do NOT guarantee real-time updates.
|
959 |
-
Since we DO need a fully propagated Origin Access Identity now, we need to make several attempts at success.
|
960 |
-
For further details, please see this thread: <https://forums.aws.amazon.com/message.jspa?messageID=42875>. */
|
961 |
-
if(($s3_response = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls()) && $s3_response["success"])
|
962 |
-
{
|
963 |
-
$cfc = array_merge($cfc, array("distros_auto_config_status" => "configured"));
|
964 |
-
$cf_options = array("ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" => "configured");
|
965 |
-
c_ws_plugin__s2member_menu_pages::update_all_options( /* Now configured! */$cf_options, true, false, false, false, false);
|
966 |
-
return /* Successfully configured Amazon S3/CloudFront distros. */ array("success" => true, "code" => null, "message" => null);
|
967 |
-
}
|
968 |
-
if(isset($s3_response["code"], $s3_response["message"]))
|
969 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */
|
970 |
-
return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"]));
|
971 |
-
|
972 |
-
else // Else, we use a default error code and message.
|
973 |
-
return array("success" => false, "code" => -88, "message" => _x("Unable to update existing Amazon S3 ACLs. Connection failed.", "s2member-admin", "s2member"));
|
974 |
-
}
|
975 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
976 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
977 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Streaming Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
978 |
-
|
979 |
-
else // Else, we use a default error code and message.
|
980 |
-
return array("success" => false, "code" => -89, "message" => _x("Unable to create Amazon CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
|
981 |
-
}
|
982 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
983 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
984 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Downloads Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
985 |
-
|
986 |
-
else // Else, we use a default error code and message.
|
987 |
-
return array("success" => false, "code" => -90, "message" => _x("Unable to create Amazon CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
|
988 |
-
}
|
989 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
990 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
991 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
992 |
-
|
993 |
-
else // Else, we use a default error code and message.
|
994 |
-
return array("success" => false, "code" => -91, "message" => _x("Unable to create Amazon CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
|
995 |
-
}
|
996 |
-
else // Else, we use a default error code and message.
|
997 |
-
return array("success" => false, "code" => -92, "message" => _x("Unable to clear existing Amazon CloudFront Origin Access Identity.", "s2member-admin", "s2member"));
|
998 |
-
}
|
999 |
-
else if(isset($cf_get_response["code"], $cf_get_response["message"]))
|
1000 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1001 |
-
return array("success" => false, "code" => $cf_get_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_get_response["message"]));
|
1002 |
-
|
1003 |
-
else // Else, we use a default error code and message.
|
1004 |
-
return array("success" => false, "code" => -93, "message" => _x("Unable to acquire existing Amazon CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
|
1005 |
-
}
|
1006 |
-
else // Else, we use a default error code and message.
|
1007 |
-
return array("success" => false, "code" => -94, "message" => _x("Unable to clear existing Amazon CloudFront Streaming Distro.", "s2member-admin", "s2member"));
|
1008 |
}
|
1009 |
-
|
1010 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon
|
1011 |
-
return array(
|
1012 |
|
1013 |
else // Else, we use a default error code and message.
|
1014 |
-
return array(
|
1015 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1016 |
else // Else, we use a default error code and message.
|
1017 |
-
return array(
|
1018 |
}
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
|
|
|
|
|
|
|
1023 |
else // Else, we use a default error code and message.
|
1024 |
-
return array(
|
1025 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1026 |
else // Else, we use a default error code and message.
|
1027 |
-
return array(
|
1028 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1029 |
else // Else, we use a default error code and message.
|
1030 |
-
return array(
|
1031 |
}
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
{
|
1046 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1047 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1048 |
-
$cfc[$option] = $option_value;
|
1049 |
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1053 |
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1059 |
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
return array("success" => true, "code" => null, "message" => null, "etag" => trim($cf_response["headers"]["etag"]), "xml" => trim($cf_response["body"]));
|
1064 |
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon CloudFront Origin Access Identity. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1071 |
|
1072 |
-
|
1073 |
-
|
1074 |
-
}
|
1075 |
-
else // Else, we use a default error code and message.
|
1076 |
-
return array("success" => false, "code" => -99, "message" => _x("Unable to acquire existing Amazon CloudFront Origin Access Identity. Invalid Access ID.", "s2member-admin", "s2member"));
|
1077 |
-
}
|
1078 |
-
/**
|
1079 |
-
* Deletes an Amazon S3/CloudFront Access Origin Identity.
|
1080 |
-
*
|
1081 |
-
* @package s2Member\Files
|
1082 |
-
* @since 110926
|
1083 |
-
*
|
1084 |
-
* @param string $access_id Required. An Origin Access ID.
|
1085 |
-
* @param string $access_id_etag Required. An Origin Access ETag header.
|
1086 |
-
* @param string $access_id_xml Required. An Origin Access Identity's XML configuration.
|
1087 |
-
* @return array Array containing a true `success` element on success, else a failure array.
|
1088 |
-
* Failure array will contain a failure `code`, and a failure `message`.
|
1089 |
-
*/
|
1090 |
-
public static function amazon_cf_del_access_origin_identity($access_id = FALSE, $access_id_etag = FALSE, $access_id_xml = FALSE)
|
1091 |
-
{
|
1092 |
-
if($access_id && is_string($access_id) && $access_id_etag && is_string($access_id_etag) && $access_id_xml && is_string($access_id_xml))
|
1093 |
-
{
|
1094 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1095 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1096 |
-
$cfc[$option] = $option_value;
|
1097 |
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
|
|
1107 |
|
1108 |
-
|
1109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1110 |
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
|
|
|
|
|
|
1114 |
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1131 |
{
|
1132 |
-
foreach($GLOBALS[
|
1133 |
-
if(preg_match(
|
1134 |
$cfc[$option] = $option_value;
|
1135 |
|
1136 |
-
$s3c[
|
1137 |
-
$cfc[
|
1138 |
-
$cfc[
|
1139 |
|
1140 |
-
$cf_domain
|
1141 |
-
$cf_date
|
1142 |
-
$
|
1143 |
-
$
|
1144 |
-
$
|
1145 |
-
$
|
1146 |
-
$cf_args = array("method" => "POST", "redirection" => 5, "body" => $cf_distros_access_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1147 |
|
1148 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote(
|
1149 |
-
|
1150 |
-
if(preg_match("/\<CloudFrontOriginAccessIdentity.*?\>(.+?)\<\/CloudFrontOriginAccessIdentity\>/is", $cf_response["body"], $cf_distros_access_tag) && preg_match("/\<Id\>(.+?)\<\/Id\>/is", $cf_distros_access_tag[1], $cf_distros_access_id_tag) && preg_match("/\<S3CanonicalUserId\>(.+?)\<\/S3CanonicalUserId\>/is", $cf_distros_access_tag[1], $cf_distros_s3_access_id_tag))
|
1151 |
-
return array("success" => true, "code" => null, "message" => null, "distros_access_id" => trim($cf_distros_access_id_tag[1]), "distros_s3_access_id" => trim($cf_distros_s3_access_id_tag[1]));
|
1152 |
|
1153 |
-
|
1154 |
-
return array("success" => false, "code" => -98, "message" => _x("Unable to create/read Amazon CloudFront Origin Access Identity. Unexpected response.", "s2member-admin", "s2member"));
|
1155 |
-
}
|
1156 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1157 |
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1158 |
-
return array(
|
1159 |
|
1160 |
else // Else, we use a default error code and message.
|
1161 |
-
return array(
|
1162 |
}
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
* Failure array will contain a failure `code`, and a failure `message`.
|
1173 |
-
*/
|
1174 |
-
public static function amazon_cf_get_distro($distro_id = FALSE, $distro_type = FALSE)
|
1175 |
-
{
|
1176 |
-
if($distro_id && is_string($distro_id) && $distro_type && is_string($distro_type) && in_array($distro_type, array("downloads", "streaming")))
|
1177 |
-
{
|
1178 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1179 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1180 |
-
$cfc[$option] = $option_value;
|
1181 |
-
|
1182 |
-
$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
|
1183 |
-
$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
|
1184 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
1185 |
-
|
1186 |
-
$cf_domain = "cloudfront.amazonaws.com";
|
1187 |
-
$cf_date = gmdate("D, d M Y H:i:s")." GMT";
|
1188 |
-
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1189 |
-
$cf_location = ($distro_type === "streaming") ? "/2010-11-01/streaming-distribution/".$distro_id : "/2010-11-01/distribution/".$distro_id;
|
1190 |
-
$cf_args = array("method" => "GET", "redirection" => 5, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1191 |
-
|
1192 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && (($cf_response["code"] === 404 && $cf_response["message"]) || ($cf_response["code"] === 200 && !empty($cf_response["headers"]["etag"]) && !empty($cf_response["body"]))))
|
1193 |
-
{
|
1194 |
-
if($cf_response["code"] === 200 && !empty($cf_response["headers"]["etag"]) && !empty($cf_response["body"]))
|
1195 |
-
return array("success" => true, "code" => null, "message" => null, "etag" => trim($cf_response["headers"]["etag"]), "xml" => trim($cf_response["body"]), "deployed" => ((stripos($cf_response["body"], "<Status>Deployed</Status>") !== false) ? true : false));
|
1196 |
-
|
1197 |
-
else /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1198 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Existing Amazon CloudFront Distro NOT found. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1199 |
-
}
|
1200 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1201 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1202 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon CloudFront Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1203 |
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
|
|
1223 |
{
|
1224 |
-
if(
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1247 |
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
|
1252 |
-
else // Else, we use a default error code and message.
|
1253 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to disable existing Amazon CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
|
1254 |
-
}
|
1255 |
-
else // Else, we use a default error code and message.
|
1256 |
-
return array("success" => false, "code" => -98, "message" => _x("Existing Amazon CloudFront Distro cannot be disabled at this time. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
1257 |
-
}
|
1258 |
-
else // Else, we use a default error code and message.
|
1259 |
-
return array("success" => true, "code" => null, "message" => null, "etag" => $distro_id_etag, "xml" => $distro_id_xml, "deployed" => ((stripos($distro_id_xml, "<Status>Deployed</Status>") !== false) ? true : false));
|
1260 |
-
}
|
1261 |
else // Else, we use a default error code and message.
|
1262 |
-
return array(
|
1263 |
}
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
{
|
1278 |
-
if($distro_id && is_string($distro_id) && $distro_id_etag && is_string($distro_id_etag) && $distro_id_xml && is_string($distro_id_xml) && ($distro_id_type = (stripos($distro_id_xml, "<StreamingDistribution") !== false) ? "streaming" : ((stripos($distro_id_xml, "<Distribution") !== false) ? "downloads" : false)) && preg_match("/\<CallerReference\>(.+?)\<\/CallerReference\>/is", $distro_id_xml, $distro_id_reference_tag) && ($distro_id_reference = $distro_id_reference_tag[1]))
|
1279 |
-
{
|
1280 |
-
if /* Check distro status before we even begin processing this deletion. */(stripos($distro_id_xml, "<Status>Deployed</Status>") !== false)
|
1281 |
-
{
|
1282 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_disable_distro($distro_id, $distro_id_etag, $distro_id_xml)) && $cf_response["success"])
|
1283 |
-
{
|
1284 |
-
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro($distro_id, $distro_id_type)) && $cf_response["success"] && $cf_response["deployed"])
|
1285 |
-
{
|
1286 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1287 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1288 |
-
$cfc[$option] = $option_value;
|
1289 |
-
|
1290 |
-
$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
|
1291 |
-
$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
|
1292 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
1293 |
-
|
1294 |
-
$cf_domain = "cloudfront.amazonaws.com";
|
1295 |
-
$cf_date = gmdate("D, d M Y H:i:s")." GMT";
|
1296 |
-
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1297 |
-
$cf_location = ($distro_id_type === "streaming") ? "/2010-11-01/streaming-distribution/".$distro_id : "/2010-11-01/distribution/".$distro_id;
|
1298 |
-
$cf_args = array("method" => "DELETE", "redirection" => 5, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $cf_response["etag"], "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1299 |
-
|
1300 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && ($cf_response["code"] === 200 || $cf_response["code"] === 204 /* Deleted. */))
|
1301 |
-
return /* Deleted successfully. */ array("success" => true, "code" => null, "message" => null);
|
1302 |
-
|
1303 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1304 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1305 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to delete existing Amazon CloudFront Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1306 |
-
|
1307 |
-
else // Else, we use a default error code and message.
|
1308 |
-
return array("success" => false, "code" => -94, "message" => _x("Unable to delete existing Amazon CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
|
1309 |
-
}
|
1310 |
-
else if(isset($cf_response["success"], $cf_response["deployed"]) && $cf_response["success"] && !$cf_response["deployed"])
|
1311 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1312 |
-
return array("success" => false, "code" => -95, "message" => _x("Existing Amazon CloudFront Distro cannot be deleted at this time. Still in a `pending` state after having been disabled by s2Member. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
1313 |
-
|
1314 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1315 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1316 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to check status of existing Amazon CloudFront Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1317 |
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1324 |
|
1325 |
-
else // Else, we use a default error code and message.
|
1326 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to disable existing Amazon CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
|
1327 |
-
}
|
1328 |
-
else // Else, we use a default error code and message.
|
1329 |
-
return array("success" => false, "code" => -98, "message" => _x("Existing Amazon CloudFront Distro cannot be deleted at this time. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member's auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.", "s2member-admin", "s2member"));
|
1330 |
-
}
|
1331 |
else // Else, we use a default error code and message.
|
1332 |
-
return array(
|
1333 |
}
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
|
|
|
|
|
|
|
|
1345 |
{
|
1346 |
-
if($
|
1347 |
-
|
1348 |
-
foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
|
1349 |
-
if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
|
1350 |
-
$cfc[$option] = $option_value;
|
1351 |
-
|
1352 |
-
$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
|
1353 |
-
$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
|
1354 |
-
$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
|
1355 |
-
|
1356 |
-
$cf_domain = "cloudfront.amazonaws.com";
|
1357 |
-
$cf_date = gmdate("D, d M Y H:i:s")." GMT";
|
1358 |
-
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1359 |
-
|
1360 |
-
if /* Create a `downloads` Distro? This uses a different XML schema. */($distro_type === "downloads")
|
1361 |
-
{
|
1362 |
-
$cf_location = /* Create distro. */ "/2010-11-01/distribution";
|
1363 |
-
$cf_distro_downloads_reference = time().".".md5("downloads".$s3c["bucket"].$s3c["access_key"].$s3c["secret_key"].$cfc["private_key"].$cfc["private_key_id"].$cfc["distro_downloads_cname"]);
|
1364 |
-
$cf_distro_downloads_xml = '<?xml version="1.0" encoding="UTF-8"?><DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/"><S3Origin><DNSName>'.esc_html($s3c["bucket"]).'.s3.amazonaws.com</DNSName><OriginAccessIdentity>origin-access-identity/cloudfront/'.esc_html($cfc["distros_access_id"]).'</OriginAccessIdentity></S3Origin><CallerReference>'.esc_html($cf_distro_downloads_reference).'</CallerReference>'.(($cfc["distro_downloads_cname"]) ? '<CNAME>'.esc_html($cfc["distro_downloads_cname"]).'</CNAME>' : '').'<Comment>'.esc_html(sprintf(_x("Created by s2Member, for S3 Bucket: %s.", "s2member-admin", "s2member"), $s3c["bucket"])).'</Comment><Enabled>true</Enabled><DefaultRootObject>index.html</DefaultRootObject><TrustedSigners><Self/></TrustedSigners></DistributionConfig>';
|
1365 |
-
$cf_args = array("method" => "POST", "redirection" => 5, "body" => $cf_distro_downloads_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1366 |
-
|
1367 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && ($cf_response["code"] === 200 || $cf_response["code"] === 201 /* Created. */))
|
1368 |
-
{
|
1369 |
-
if(preg_match("/\<Distribution.*?\>(.+?)\<\/Distribution\>/is", $cf_response["body"], $cf_distro_downloads_tag) && preg_match("/\<Id\>(.+?)\<\/Id\>/is", $cf_distro_downloads_tag[1], $cf_distro_downloads_id_tag) && preg_match("/\<DomainName\>(.+?)\<\/DomainName\>/is", $cf_distro_downloads_tag[1], $cf_distro_downloads_dname_tag))
|
1370 |
-
return array("success" => true, "code" => null, "message" => null, "distro_downloads_id" => trim($cf_distro_downloads_id_tag[1]), "distro_downloads_dname" => trim($cf_distro_downloads_dname_tag[1]));
|
1371 |
|
1372 |
-
else // Else, we use a default error code and message.
|
1373 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to create/read Amazon CloudFront Downloads Distro. Unexpected response.", "s2member-admin", "s2member"));
|
1374 |
-
}
|
1375 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1376 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1377 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Downloads Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1378 |
-
|
1379 |
-
else // Else, we use a default error code and message.
|
1380 |
-
return array("success" => false, "code" => -98, "message" => _x("Unable to create Amazon CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
|
1381 |
-
}
|
1382 |
-
|
1383 |
-
else if /* Create a `streaming` Distro? A different XML schema. */($distro_type === "streaming")
|
1384 |
-
{
|
1385 |
-
$cf_location = /* Create streaming distro. */ "/2010-11-01/streaming-distribution";
|
1386 |
-
$cf_distro_streaming_reference = time().".".md5("streaming".$s3c["bucket"].$s3c["access_key"].$s3c["secret_key"].$cfc["private_key"].$cfc["private_key_id"].$cfc["distro_streaming_cname"]);
|
1387 |
-
$cf_distro_streaming_xml = '<?xml version="1.0" encoding="UTF-8"?><StreamingDistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/"><S3Origin><DNSName>'.esc_html($s3c["bucket"]).'.s3.amazonaws.com</DNSName><OriginAccessIdentity>origin-access-identity/cloudfront/'.esc_html($cfc["distros_access_id"]).'</OriginAccessIdentity></S3Origin><CallerReference>'.esc_html($cf_distro_streaming_reference).'</CallerReference>'.(($cfc["distro_streaming_cname"]) ? '<CNAME>'.esc_html($cfc["distro_streaming_cname"]).'</CNAME>' : '').'<Comment>'.esc_html(sprintf(_x("Created by s2Member, for S3 Bucket: %s.", "s2member-admin", "s2member"), $s3c["bucket"])).'</Comment><Enabled>true</Enabled><DefaultRootObject>index.html</DefaultRootObject><TrustedSigners><Self/></TrustedSigners></StreamingDistributionConfig>';
|
1388 |
-
$cf_args = array("method" => "POST", "redirection" => 5, "body" => $cf_distro_streaming_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
|
1389 |
-
|
1390 |
-
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote("https://".$cf_domain.$cf_location, false, array_merge($cf_args, array("timeout" => 20)), "array")) && ($cf_response["code"] === 200 || $cf_response["code"] === 201 /* Created. */))
|
1391 |
-
{
|
1392 |
-
if(preg_match("/\<StreamingDistribution.*?\>(.+?)\<\/StreamingDistribution\>/is", $cf_response["body"], $cf_distro_streaming_tag) && preg_match("/\<Id\>(.+?)\<\/Id\>/is", $cf_distro_streaming_tag[1], $cf_distro_streaming_id_tag) && preg_match("/\<DomainName\>(.+?)\<\/DomainName\>/is", $cf_distro_streaming_tag[1], $cf_distro_streaming_dname_tag))
|
1393 |
-
return array("success" => true, "code" => null, "message" => null, "distro_streaming_id" => trim($cf_distro_streaming_id_tag[1]), "distro_streaming_dname" => trim($cf_distro_streaming_dname_tag[1]));
|
1394 |
-
|
1395 |
-
else // Else, we use a default error code and message.
|
1396 |
-
return array("success" => false, "code" => -97, "message" => _x("Unable to create/read Amazon CloudFront Streaming Distro. Unexpected response.", "s2member-admin", "s2member"));
|
1397 |
-
}
|
1398 |
-
else if(isset($cf_response["code"], $cf_response["message"]))
|
1399 |
-
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1400 |
-
return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Unable to create Amazon CloudFront Streaming Distro. %s", "s2member-admin", "s2member"), $cf_response["message"]));
|
1401 |
-
|
1402 |
-
else // Else, we use a default error code and message.
|
1403 |
-
return array("success" => false, "code" => -98, "message" => _x("Unable to create Amazon CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
|
1404 |
-
}
|
1405 |
-
}
|
1406 |
else // Else, we use a default error code and message.
|
1407 |
-
return array(
|
1408 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1409 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1410 |
}
|
1411 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* File Download routines for s2Member (inner processing routines).
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Files
|
15 |
+
* @since 3.5
|
16 |
+
*/
|
17 |
+
if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
|
18 |
+
exit('Do not access this file directly.');
|
19 |
+
|
20 |
+
if(!class_exists('c_ws_plugin__s2member_files_in'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* File Download routines for s2Member (inner processing routines).
|
24 |
+
*
|
25 |
+
* @package s2Member\Files
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_files_in
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles Download Access permissions.
|
32 |
+
*
|
33 |
+
* @package s2Member\Files
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @attaches-to ``add_action('init');``
|
37 |
+
* @also-called-by API Function {@link s2Member\API_Functions\s2member_file_download_url()}, w/ ``$create_file_download_url`` param.
|
38 |
+
*
|
39 |
+
* @param null|array $create_file_download_url Optional. If this function is called directly, we can pass arguments through this array.
|
40 |
+
* Possible array elements: `file_download` *(required)*, `file_download_key`, `file_stream`, `file_inline`, `file_storage`, `file_remote`, `file_ssl`, `file_rewrite`, `file_rewrite_base`, `skip_confirmation`, `url_to_storage_source`, `count_against_user`, `check_user`.
|
41 |
+
*
|
42 |
+
* @return null|string If called directly with ``$create_file_download_url``, returns a string with the URL, based on configuration.
|
43 |
+
* Else, this function may exit script execution after serving a File Download.
|
44 |
+
*/
|
45 |
+
public static function check_file_download_access($create_file_download_url = NULL)
|
46 |
+
{
|
47 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
48 |
+
do_action('ws_plugin__s2member_before_file_download_access', get_defined_vars());
|
49 |
+
unset($__refs, $__v); // Housekeeping.
|
50 |
+
|
51 |
+
$_g = !empty($_GET) ? $_GET : array();
|
52 |
+
$_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_g));
|
53 |
+
|
54 |
+
$creating = (is_array($create = $create_file_download_url)) ? TRUE : FALSE; // Creating URL?
|
55 |
+
$serving = (!$creating) ? TRUE : FALSE; // If NOT creating a File Download URL, we're serving one.
|
56 |
+
$serving_range = $range = FALSE; // Default values (so these variables DO get defined at all times).
|
57 |
+
|
58 |
+
if($serving) // If we're serving, let's see if we're serving a byte-range request here.
|
59 |
{
|
60 |
+
$range = (string)@$_SERVER['HTTP_RANGE'];
|
61 |
+
|
62 |
+
if(!$range && function_exists('apache_request_headers'))
|
63 |
+
{
|
64 |
+
foreach((array)apache_request_headers() as $_header => $_value)
|
65 |
+
// Note: ``apache_request_headers()`` works in FastCGI too, starting w/ PHP v5.4.
|
66 |
+
if(is_string($_header) && strcasecmp($_header, 'range') === 0)
|
67 |
+
$range = $_value;
|
68 |
+
}
|
69 |
+
unset($_header, $_value); // Housekeeping.
|
70 |
+
|
71 |
+
if($range) $serving_range = TRUE;
|
72 |
+
}
|
73 |
+
$req['file_download'] = ($creating) ? @$create['file_download'] : @$_g['s2member_file_download'];
|
74 |
+
$req['file_download_key'] = ($creating) ? @$create['file_download_key'] : @$_g['s2member_file_download_key'];
|
75 |
+
|
76 |
+
$req['file_stream'] = ($creating) ? @$create['file_stream'] : @$_g['s2member_file_stream'];
|
77 |
+
$req['file_inline'] = ($creating) ? @$create['file_inline'] : @$_g['s2member_file_inline'];
|
78 |
+
$req['file_storage'] = ($creating) ? @$create['file_storage'] : @$_g['s2member_file_storage'];
|
79 |
+
$req['file_remote'] = ($creating) ? @$create['file_remote'] : @$_g['s2member_file_remote'];
|
80 |
+
$req['file_ssl'] = ($creating) ? @$create['file_ssl'] : @$_g['s2member_file_ssl'];
|
81 |
+
|
82 |
+
$req['file_rewrite'] = ($creating) ? @$create['file_rewrite'] : NULL;
|
83 |
+
$req['file_rewrite_base'] = ($creating) ? @$create['file_rewrite_base'] : NULL;
|
84 |
+
|
85 |
+
$req['skip_confirmation'] = ($creating) ? @$create['skip_confirmation'] : NULL;
|
86 |
+
$req['url_to_storage_source'] = ($creating) ? @$create['url_to_storage_source'] : NULL;
|
87 |
+
$req['count_against_user'] = ($creating) ? @$create['count_against_user'] : NULL;
|
88 |
+
$req['check_user'] = ($creating) ? @$create['check_user'] : NULL;
|
89 |
+
|
90 |
+
if($req['file_download'] && is_string($req['file_download']) && ($req['file_download'] = trim($req['file_download'], '/')))
|
91 |
+
if(strpos($req['file_download'], '..') === FALSE && strpos(basename($req['file_download']), '.') !== 0)
|
92 |
+
{
|
93 |
+
$using_amazon_cf_storage = ((!$req['file_storage'] || strcasecmp((string)$req['file_storage'], 'cf') === 0) && c_ws_plugin__s2member_utils_conds::using_amazon_cf_storage()) ? TRUE : FALSE;
|
94 |
+
$using_amazon_s3_storage = ((!$req['file_storage'] || strcasecmp((string)$req['file_storage'], 's3') === 0) && c_ws_plugin__s2member_utils_conds::using_amazon_s3_storage()) ? TRUE : FALSE;
|
95 |
+
$using_amazon_storage = ($using_amazon_cf_storage || $using_amazon_s3_storage) ? TRUE : FALSE;
|
96 |
+
|
97 |
+
$excluded = apply_filters('ws_plugin__s2member_check_file_download_access_excluded', FALSE, get_defined_vars());
|
98 |
+
$valid_file_download_key = ($req['file_download_key'] && is_string($req['file_download_key']) && $creating && (!isset($req['check_user']) || !filter_var($req['check_user'], FILTER_VALIDATE_BOOLEAN)) && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN))) ? TRUE : FALSE;
|
99 |
+
$valid_file_download_key = (!$valid_file_download_key && $req['file_download_key'] && is_string($req['file_download_key'])) ? c_ws_plugin__s2member_files_in::check_file_download_key($req['file_download'], $req['file_download_key']) : FALSE;
|
100 |
+
$checking_user = ($excluded || $valid_file_download_key || ($creating && (!isset($req['check_user']) || !filter_var($req['check_user'], FILTER_VALIDATE_BOOLEAN)) && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN)))) ? FALSE : TRUE;
|
101 |
+
$updating_user_counter = ($serving_range || !$checking_user || ($creating && (!isset($req['count_against_user']) || !filter_var($req['count_against_user'], FILTER_VALIDATE_BOOLEAN)))) ? FALSE : TRUE;
|
102 |
+
|
103 |
+
if(($serving || $creating) && $checking_user) // In either case, the following routines apply whenever we ARE ``$checking_user``.
|
104 |
{
|
105 |
+
if(!$using_amazon_storage && !file_exists($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'].'/'.$req['file_download']))
|
106 |
+
{
|
107 |
+
if($serving) // We only need this section when/if we're actually serving.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
{
|
109 |
+
status_header(404);
|
110 |
+
header('Content-Type: text/html; charset=UTF-8');
|
111 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
112 |
+
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', 's2member-front', 's2member'));
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
+
return FALSE; // Else return false.
|
115 |
+
}
|
116 |
+
else if($req['file_download_key'] && is_string($req['file_download_key']) && !$valid_file_download_key)
|
117 |
+
{
|
118 |
+
if($serving) // We only need this section when/if we're actually serving.
|
119 |
+
{
|
120 |
+
status_header(503);
|
121 |
+
header('Content-Type: text/html; charset=UTF-8');
|
122 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
123 |
+
exit(_x('<strong>503 (Invalid Key):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', 's2member-front', 's2member'));
|
124 |
+
}
|
125 |
+
return FALSE; // Else return false.
|
126 |
+
}
|
127 |
+
else // Default behavior; check file download access against the current user.
|
128 |
+
{
|
129 |
+
if($serving) // We only need remote functionality when/if we're actually serving.
|
130 |
+
if(!has_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization'))
|
131 |
+
add_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization', 10, 2);
|
132 |
+
|
133 |
+
if($creating) // We only need remote functionality when/if we're actually serving.
|
134 |
+
if(has_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization'))
|
135 |
+
remove_filter('ws_plugin__s2member_check_file_download_access_user', 'c_ws_plugin__s2member_files_in::check_file_remote_authorization', 10, 2);
|
136 |
+
|
137 |
+
if(!$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
138 |
+
{
|
139 |
+
if($serving) // We only need this section when/if we're actually serving.
|
140 |
+
{
|
141 |
+
status_header(503);
|
142 |
+
header('Content-Type: text/html; charset=UTF-8');
|
143 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
144 |
+
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› General Options -› Membership Options Page</code>.', 's2member-front', 's2member'));
|
145 |
+
}
|
146 |
+
return FALSE; // Else return false.
|
147 |
+
}
|
148 |
+
else if(($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads()) === FALSE)
|
149 |
+
{
|
150 |
+
if($serving) // We only need this section when/if we're actually serving.
|
151 |
+
{
|
152 |
+
status_header(503);
|
153 |
+
header('Content-Type: text/html; charset=UTF-8');
|
154 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
155 |
+
exit(_x('<strong>503: Basic File Downloads are NOT enabled yet.</strong> Please contact Support for assistance. If you are the site owner, please configure: <code>s2Member -› Download Options -› Basic Download Restrictions</code>.', 's2member-front', 's2member'));
|
156 |
+
}
|
157 |
+
return FALSE; // Else return false.
|
158 |
+
}
|
159 |
+
else if(!is_object($user = apply_filters('ws_plugin__s2member_check_file_download_access_user', ((is_user_logged_in()) ? wp_get_current_user() : FALSE), get_defined_vars())) || empty($user->ID) || !($user_id = $user->ID) || !is_array($user_file_downloads = c_ws_plugin__s2member_files::user_downloads($user)) || (!$user->has_cap('administrator') && (!$user_file_downloads['allowed'] || !$user_file_downloads['allowed_days'])))
|
160 |
+
{
|
161 |
+
if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//', $req['file_download'], $m) && strlen($req_level = $m[1]) && (!is_object($user) || empty($user->ID) || !$user->has_cap('access_s2member_level'.$req_level)))
|
162 |
+
{
|
163 |
+
if($serving) // We only need this section when/if we're actually serving.
|
164 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $req_level, $_SERVER['REQUEST_URI']).exit();
|
165 |
|
166 |
+
return FALSE; // Else return false.
|
167 |
+
}
|
168 |
+
else if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//', $req['file_download'], $m) && strlen($req_ccap = preg_replace('/-/', '_', $m[1])) && (!is_object($user) || empty($user->ID) || !$user->has_cap('access_s2member_ccap_'.$req_ccap)))
|
169 |
{
|
170 |
+
if($serving) // We only need this section when/if we're actually serving.
|
171 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'ccap', $req_ccap, $_SERVER['REQUEST_URI']).exit();
|
|
|
172 |
|
173 |
+
return FALSE; // Else return false.
|
174 |
+
}
|
175 |
+
else if($serving) // We only need this section when/if we're actually serving.
|
176 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $min_level_4_downloads, $_SERVER['REQUEST_URI']).exit();
|
|
|
177 |
|
178 |
+
return FALSE; // Else return false.
|
179 |
+
}
|
180 |
+
else if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]level([0-9]+)\//', $req['file_download'], $m) && strlen($req_level = $m[1]) && !$user->has_cap('access_s2member_level'.$req_level))
|
181 |
+
{
|
182 |
+
if($serving) // We only need this section when/if we're actually serving.
|
183 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'level', $req_level, $_SERVER['REQUEST_URI']).exit();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
|
185 |
+
return FALSE; // Else return false.
|
186 |
+
}
|
187 |
+
else if(preg_match('/(?:^|\/)access[_\-]s2member[_\-]ccap[_\-](.+?)\//', $req['file_download'], $m) && strlen($req_ccap = preg_replace('/-/', '_', $m[1])) && !$user->has_cap('access_s2member_ccap_'.$req_ccap))
|
188 |
+
{
|
189 |
+
if($serving) // We only need this section when/if we're actually serving.
|
190 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('file', $req['file_download'], 'ccap', $req_ccap, $_SERVER['REQUEST_URI']).exit();
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
|
192 |
+
return FALSE; // Else return false.
|
193 |
+
}
|
194 |
+
else if($serving || $creating) // In either case, the following routines apply.
|
195 |
+
{
|
196 |
+
$user_previous_file_downloads = 0; // Downloads the User has already; in current period/cycle.
|
197 |
+
$user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
|
198 |
|
199 |
+
$user_file_download_access_log = (is_array($user_file_download_access_log = get_user_option('s2member_file_download_access_log', $user_id))) ? $user_file_download_access_log : array();
|
200 |
+
$user_file_download_access_arc = (is_array($user_file_download_access_arc = get_user_option('s2member_file_download_access_arc', $user_id))) ? $user_file_download_access_arc : array();
|
|
|
201 |
|
202 |
+
$streaming_file_extns = c_ws_plugin__s2member_utils_strings::preg_quote_deep($GLOBALS['WS_PLUGIN__']['s2member']['c']['streaming_file_extns'], '/');
|
203 |
+
$streaming_variations = '/\.('.implode('|', $streaming_file_extns).')$/i'; // Only count one streaming media file variation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
+
foreach($user_file_download_access_log as $user_file_download_access_log_entry_key => $user_file_download_access_log_entry)
|
206 |
+
{
|
207 |
+
if(isset($user_file_download_access_log_entry['date'], $user_file_download_access_log_entry['file'])) // Weed out corrupt/empty log entries.
|
208 |
+
{
|
209 |
+
if(strtotime($user_file_download_access_log_entry['date']) < strtotime('-'.$user_file_downloads['allowed_days'].' days'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
{
|
211 |
+
unset($user_file_download_access_log[$user_file_download_access_log_entry_key]); // Remove it from the `log`.
|
212 |
+
$user_file_download_access_arc[] = $user_file_download_access_log_entry; // Move `log` entry to the `archive` now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
}
|
214 |
+
else if(strtotime($user_file_download_access_log_entry['date']) >= strtotime('-'.$user_file_downloads['allowed_days'].' days'))
|
|
|
215 |
{
|
216 |
+
$user_previous_file_downloads++; // Previous files always count against this User/Member.
|
|
|
|
|
217 |
|
218 |
+
$_user_file_download_access_log_entry = & $user_file_download_access_log[$user_file_download_access_log_entry_key];
|
219 |
+
$_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = FALSE;
|
220 |
|
221 |
+
if($user_file_download_access_log_entry['file'] === $req['file_download']) // Already downloaded this file? If yes, mark this flag as true.
|
222 |
+
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = TRUE; // Already downloaded this file? If yes, mark as true.
|
|
|
|
|
|
|
223 |
|
224 |
+
else if(preg_replace($streaming_variations, '', $user_file_download_access_log_entry['file']) === preg_replace($streaming_variations, '', $req['file_download']))
|
225 |
+
$user_already_downloaded_this_file = $_user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = TRUE;
|
|
|
|
|
|
|
226 |
|
227 |
+
if($updating_user_counter && ($_user_already_downloaded_this_file || $_user_already_downloaded_a_streaming_variation_of_this_file)) // Updating counter?
|
228 |
+
{
|
229 |
+
$_user_file_download_access_log_entry['ltime'] = time(); // First, we update the last download time for this file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
|
231 |
+
if(!empty($user_file_download_access_log_entry['counter'])) // Backward compatibility here. Is this even set?
|
232 |
+
$_user_file_download_access_log_entry['counter'] = (int)$user_file_download_access_log_entry['counter'] + 1;
|
233 |
+
else // Backward compatibility here. Default value to `1`, if this is NOT even set yet.
|
234 |
+
$_user_file_download_access_log_entry['counter'] = 1 + 1;
|
235 |
+
}
|
236 |
+
}
|
237 |
+
}
|
238 |
+
else // Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries.
|
239 |
+
unset($user_file_download_access_log[$user_file_download_access_log_entry_key]); // Remove.
|
240 |
+
}
|
241 |
+
if($updating_user_counter && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file) // Do we need a new log entry for this file?
|
242 |
+
$user_file_download_access_log[] = array('date' => date('Y-m-d'), 'time' => time(), 'ltime' => time(), 'file' => $req['file_download'], 'counter' => 1);
|
243 |
|
244 |
+
if($user_previous_file_downloads >= $user_file_downloads['allowed'] && !$user_already_downloaded_this_file && !$user_already_downloaded_a_streaming_variation_of_this_file && !$user->has_cap('administrator'))
|
245 |
+
{
|
246 |
+
if($serving) // We only need this section when/if we're actually serving.
|
247 |
+
wp_redirect(add_query_arg(urlencode_deep(array('_s2member_seeking' => array('type' => 'file', 'file' => $req['file_download'], '_uri' => base64_encode($_SERVER['REQUEST_URI'])), 's2member_seeking' => 'file-'.$req['file_download'])), get_page_link($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'])), apply_filters('ws_plugin__s2member_content_redirect_status', 301, get_defined_vars())).exit();
|
248 |
|
249 |
+
return FALSE; // Else return false.
|
250 |
+
}
|
251 |
+
else if($updating_user_counter) // Save/update counter? By default, we do NOT update the counter when a URL is simply being created for access.
|
252 |
+
update_user_option($user_id, 's2member_file_download_access_log', c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_log)).update_user_option($user_id, 's2member_file_download_access_arc', c_ws_plugin__s2member_utils_arrays::array_unique($user_file_download_access_arc));
|
253 |
+
}
|
254 |
+
}
|
255 |
+
}
|
256 |
+
else // Otherwise, we're either NOT ``$checking_user``; or permission was granted with a valid File Download Key.
|
257 |
+
{
|
258 |
+
if(!$using_amazon_storage && !file_exists($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'].'/'.$req['file_download']))
|
259 |
+
{
|
260 |
+
if($serving) // We only need this section when/if we're actually serving.
|
261 |
+
{
|
262 |
+
status_header(404);
|
263 |
+
header('Content-Type: text/html; charset=UTF-8');
|
264 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
265 |
+
exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', 's2member-front', 's2member'));
|
266 |
+
}
|
267 |
+
return FALSE; // Else return false.
|
268 |
+
}
|
269 |
+
}
|
270 |
+
if($serving || $creating) // In either case, the following routines apply.
|
271 |
+
{
|
272 |
+
$basename = basename($req['file_download']);
|
273 |
+
$mimetypes = parse_ini_file(dirname(dirname(dirname(__FILE__))).'/includes/mime-types.ini');
|
274 |
+
$extension = strtolower(substr($req['file_download'], strrpos($req['file_download'], '.') + 1));
|
275 |
+
|
276 |
+
$key = ($req['file_download_key'] && is_string($req['file_download_key'])) ? $req['file_download_key'] : FALSE;
|
277 |
+
|
278 |
+
$stream = (isset($req['file_stream'])) ? filter_var($req['file_stream'], FILTER_VALIDATE_BOOLEAN) : ((in_array($extension, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_stream_extensions']))) ? TRUE : FALSE);
|
279 |
+
$inline = (!$stream && isset($req['file_inline'])) ? filter_var($req['file_inline'], FILTER_VALIDATE_BOOLEAN) : (($stream || in_array($extension, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_inline_extensions']))) ? TRUE : FALSE);
|
280 |
+
$ssl = (isset($req['file_ssl'])) ? filter_var($req['file_ssl'], FILTER_VALIDATE_BOOLEAN) : ((is_ssl()) ? TRUE : FALSE);
|
281 |
+
$storage = ($req['file_storage'] && is_string($req['file_storage'])) ? strtolower($req['file_storage']) : FALSE;
|
282 |
+
$remote = (isset($req['file_remote'])) ? filter_var($req['file_remote'], FILTER_VALIDATE_BOOLEAN) : FALSE;
|
283 |
+
|
284 |
+
$_basename_dir_app_data = c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir']);
|
285 |
+
$rewrite_base_guess = (is_dir(dirname($GLOBALS['WS_PLUGIN__']['s2member']['c']['dir']).'/'.$_basename_dir_app_data)) ? dirname($GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url']).'/'.$_basename_dir_app_data : content_url('/'.$_basename_dir_app_data);
|
286 |
+
$rewrite_base = ($req['file_rewrite_base'] && is_string($req['file_rewrite_base'])) ? $req['file_rewrite_base'] : FALSE;
|
287 |
+
$rewrite = $rewriting = (!$rewrite_base && isset($req['file_rewrite'])) ? filter_var($req['file_rewrite'], FILTER_VALIDATE_BOOLEAN) : (($rewrite_base) ? TRUE : FALSE);
|
288 |
+
unset($_basename_dir_app_data); // A little housekeeping here.
|
289 |
+
|
290 |
+
$skip_confirmation = (isset($req['skip_confirmation'])) ? filter_var($req['skip_confirmation'], FILTER_VALIDATE_BOOLEAN) : FALSE;
|
291 |
+
$url_to_storage_source = (isset($req['url_to_storage_source'])) ? filter_var($req['url_to_storage_source'], FILTER_VALIDATE_BOOLEAN) : FALSE;
|
292 |
+
|
293 |
+
$file = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'].'/'.$req['file_download'];
|
294 |
+
$pathinfo = (!$using_amazon_storage && $file) ? pathinfo($file) : array();
|
295 |
+
$mimetype = ($mimetypes[$extension]) ? $mimetypes[$extension] : 'application/octet-stream';
|
296 |
+
$disposition = (($inline) ? 'inline' : 'attachment').'; filename="'.c_ws_plugin__s2member_utils_strings::esc_dq($basename).'"; filename*=UTF-8\'\''.rawurlencode($basename);
|
297 |
+
$length = (!$using_amazon_storage && $file) ? filesize($file) : -1;
|
298 |
+
|
299 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
300 |
+
do_action('ws_plugin__s2member_during_file_download_access', get_defined_vars());
|
301 |
+
unset($__refs, $__v); // Housekeeping.
|
302 |
+
|
303 |
+
if($using_amazon_storage && $using_amazon_cf_storage && ($serving || ($creating && $url_to_storage_source)))
|
304 |
+
{
|
305 |
+
if($serving) // We only need this section when/if we're actually serving.
|
306 |
+
wp_redirect(c_ws_plugin__s2member_files_in::amazon_cf_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype)).exit();
|
307 |
+
|
308 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', c_ws_plugin__s2member_files_in::amazon_cf_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype), get_defined_vars());
|
309 |
+
}
|
310 |
+
else if($using_amazon_storage && $using_amazon_s3_storage && ($serving || ($creating && $url_to_storage_source)))
|
311 |
+
{
|
312 |
+
if($serving) // We only need this section when/if we're actually serving.
|
313 |
+
wp_redirect(c_ws_plugin__s2member_files_in::amazon_s3_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype)).exit();
|
314 |
+
|
315 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', c_ws_plugin__s2member_files_in::amazon_s3_url($req['file_download'], $stream, $inline, $ssl, $basename, $mimetype), get_defined_vars());
|
316 |
+
}
|
317 |
+
else if($creating && $rewriting) // Creating a rewrite URL, pointing to local storage.
|
318 |
+
{ // Note: we don't URL encode unreserved chars. Improves media player compatibility.
|
319 |
+
|
320 |
+
$_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : '';
|
321 |
+
$_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : '';
|
322 |
+
$_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req['file_download']));
|
323 |
+
$_url_e_file = str_ireplace('%2F', '/', $_url_e_file);
|
324 |
+
|
325 |
+
$url = ($rewrite_base) ? rtrim($rewrite_base, '/') : rtrim($rewrite_base_guess, '/');
|
326 |
+
$url .= (isset($req['file_download_key'])) ? (($key && $_url_e_key) ? '/s2member-file-download-key-'.$_url_e_key : '') : '';
|
327 |
+
$url .= (isset($req['file_stream'])) ? (($stream) ? '/s2member-file-stream' : '/s2member-file-stream-no') : '';
|
328 |
+
$url .= (isset($req['file_inline'])) ? (($inline) ? '/s2member-file-inline' : '/s2member-file-inline-no') : '';
|
329 |
+
$url .= (isset($req['file_storage'])) ? (($storage && $_url_e_storage) ? '/s2member-file-storage-'.$_url_e_storage : '') : '';
|
330 |
+
$url .= (isset($req['file_remote'])) ? (($remote) ? '/s2member-file-remote' : '/s2member-file-remote-no') : '';
|
331 |
+
$url .= (isset($req['skip_confirmation'])) ? (($skip_confirmation) ? '/s2member-skip-confirmation' : '/s2member-skip-confirmation-no') : '';
|
332 |
+
|
333 |
+
$url = $url.'/'.$_url_e_file; // File Download Access URL via `mod_rewrite` functionality.
|
334 |
+
$url = ($ssl) ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
|
335 |
+
|
336 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
|
337 |
+
}
|
338 |
+
else if($creating) // Else we're creating a URL w/ a query-string; w/ local storage.
|
339 |
+
{ // Note: we don't URL encode unreserved chars. Improves media player compatibility.
|
340 |
+
|
341 |
+
$_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : '';
|
342 |
+
$_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : '';
|
343 |
+
$_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req['file_download']));
|
344 |
+
$_url_e_file = str_ireplace('%2F', '/', $_url_e_file);
|
345 |
+
|
346 |
+
$url = (isset($req['file_download_key'])) ? (($key && $_url_e_key) ? '&s2member_file_download_key='.$_url_e_key : '') : '';
|
347 |
+
$url .= (isset($req['file_stream'])) ? (($stream) ? '&s2member_file_stream=yes' : '&s2member_file_stream=no') : '';
|
348 |
+
$url .= (isset($req['file_inline'])) ? (($inline) ? '&s2member_file_inline=yes' : '&s2member_file_inline=no') : '';
|
349 |
+
$url .= (isset($req['file_storage'])) ? (($storage && $_url_e_storage) ? '&s2member_file_storage='.$_url_e_storage : '') : '';
|
350 |
+
$url .= (isset($req['file_remote'])) ? (($remote) ? '&s2member_file_remote=yes' : '&s2member_file_remote=no') : '';
|
351 |
+
$url .= (isset($req['skip_confirmation'])) ? (($skip_confirmation) ? '&s2member_skip_confirmation=yes' : '&s2member_skip_confirmation=no') : '';
|
352 |
+
|
353 |
+
$url = site_url('/?'.ltrim($url.'&s2member_file_download=/'.$_url_e_file, '&'));
|
354 |
+
$url = ($ssl) ? preg_replace('/^https?/', 'https', $url) : preg_replace('/^https?/', 'http', $url);
|
355 |
+
|
356 |
+
return apply_filters('ws_plugin__s2member_file_download_access_url', $url, get_defined_vars());
|
357 |
+
}
|
358 |
+
else if($serving) // Else, ``if ($serving)``, use local storage.
|
359 |
+
{
|
360 |
+
@set_time_limit(0);
|
361 |
+
|
362 |
+
@ini_set('zlib.output_compression', 0);
|
363 |
+
if(function_exists('apache_setenv'))
|
364 |
+
@apache_setenv('no-gzip', '1');
|
365 |
+
|
366 |
+
$content_encoding_header = 'Content-Encoding:'; // Default value; standards compliant.
|
367 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_content_encodong_none'])
|
368 |
+
$content_encoding_header = 'Content-Encoding: none';
|
369 |
+
|
370 |
+
while(@ob_end_clean()) ; // Cleans existing output buffers.
|
371 |
+
|
372 |
+
if($range) // Requesting a specific byte range?
|
373 |
+
{
|
374 |
+
if(strpos($range, '=') === FALSE) // Invalid range?
|
375 |
+
{
|
376 |
+
status_header(416);
|
377 |
+
nocache_headers();
|
378 |
+
header($content_encoding_header);
|
379 |
+
header('Accept-Ranges: bytes');
|
380 |
+
header('Content-Type: '.$mimetype);
|
381 |
+
header('Content-Length: '.$length);
|
382 |
+
header('Content-Disposition: '.$disposition);
|
383 |
+
exit(); // Stop here (invalid).
|
384 |
+
}
|
385 |
+
list($range_type, $byte_range) = preg_split('/\s*\=\s*/', $range, 2);
|
386 |
|
387 |
+
$range_type = strtolower(trim($range_type));
|
388 |
+
$byte_range = trim($byte_range);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
|
390 |
+
if($range_type !== 'bytes') // Invalid range type?
|
391 |
+
{
|
392 |
+
status_header(416);
|
393 |
+
nocache_headers();
|
394 |
+
header($content_encoding_header);
|
395 |
+
header('Accept-Ranges: bytes');
|
396 |
+
header('Content-Type: '.$mimetype);
|
397 |
+
header('Content-Length: '.$length);
|
398 |
+
header('Content-Disposition: '.$disposition);
|
399 |
+
exit(); // Stop here (invalid).
|
400 |
+
}
|
401 |
+
$byte_ranges = preg_split('/\s*,\s*/', $byte_range);
|
402 |
|
403 |
+
if(strpos($byte_ranges[0], '-') === FALSE) // Invalid byte range?
|
404 |
+
{
|
405 |
+
status_header(416);
|
406 |
+
nocache_headers();
|
407 |
+
header($content_encoding_header);
|
408 |
+
header('Accept-Ranges: bytes');
|
409 |
+
header('Content-Type: '.$mimetype);
|
410 |
+
header('Content-Length: '.$length);
|
411 |
+
header('Content-Disposition: '.$disposition);
|
412 |
+
exit(); // Stop here (invalid).
|
413 |
+
}
|
414 |
+
// Only dealing with the first byte range. Others are simply ignored here.
|
415 |
+
list($byte_range_start, $byte_range_stops) = preg_split('/\s*\-\s*/', $byte_ranges[0], 2);
|
416 |
|
417 |
+
$byte_range_start = trim($byte_range_start);
|
418 |
+
$byte_range_stops = trim($byte_range_stops);
|
419 |
|
420 |
+
$byte_range_start = ($byte_range_start === '') ? NULL : (integer)$byte_range_start;
|
421 |
+
$byte_range_stops = ($byte_range_stops === '') ? NULL : (integer)$byte_range_stops;
|
422 |
|
423 |
+
if(!isset($byte_range_start) && $byte_range_stops > 0 && $byte_range_stops <= $length)
|
424 |
+
{
|
425 |
+
$byte_range_start = $length - $byte_range_stops;
|
426 |
+
$byte_range_stops = $length - 1; // The last X number of bytes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
427 |
}
|
428 |
+
else if(!isset($byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1)
|
429 |
+
{
|
430 |
+
$byte_range_stops = $length - 1; // To the end of the file in this case.
|
431 |
+
}
|
432 |
+
else if(isset($byte_range_start, $byte_range_stops) && $byte_range_start >= 0 && $byte_range_start < $length - 1 && $byte_range_stops > $byte_range_start && $byte_range_stops <= $length - 1)
|
433 |
+
{
|
434 |
+
// Nothing to do in this case, starts/stops already defined properly.
|
435 |
+
}
|
436 |
+
else // We have an invalid byte range.
|
437 |
+
{
|
438 |
+
status_header(416);
|
439 |
+
nocache_headers();
|
440 |
+
header($content_encoding_header);
|
441 |
+
header('Accept-Ranges: bytes');
|
442 |
+
header('Content-Type: '.$mimetype);
|
443 |
+
header('Content-Length: '.$length);
|
444 |
+
header('Content-Disposition: '.$disposition);
|
445 |
+
exit(); // Stop here (invalid).
|
446 |
+
}
|
447 |
+
status_header(206);
|
448 |
+
nocache_headers();
|
449 |
+
header($content_encoding_header);
|
450 |
+
header('Accept-Ranges: bytes');
|
451 |
+
header('Content-Type: '.$mimetype);
|
452 |
+
header('Content-Range: bytes '.$byte_range_start.'-'.$byte_range_stops.'/'.$length);
|
453 |
+
$byte_range_size = $byte_range_stops - $byte_range_start + 1;
|
454 |
+
header('Content-Length: '.$byte_range_size);
|
455 |
+
header('Content-Disposition: '.$disposition);
|
456 |
+
}
|
457 |
+
else // A normal request (NOT a specific byte range).
|
458 |
{
|
459 |
+
status_header(200);
|
460 |
+
nocache_headers();
|
461 |
+
header($content_encoding_header);
|
462 |
+
header('Accept-Ranges: bytes');
|
463 |
+
header('Content-Type: '.$mimetype);
|
464 |
+
header('Content-Length: '.$length);
|
465 |
+
header('Content-Disposition: '.$disposition);
|
466 |
}
|
467 |
+
if(is_resource($resource = fopen($file, 'rb')))
|
468 |
+
{
|
469 |
+
if($range && isset($byte_range_size, $byte_range_start))
|
470 |
+
{
|
471 |
+
$_bytes_to_read = $byte_range_size;
|
472 |
+
fseek($resource, $byte_range_start);
|
473 |
+
}
|
474 |
+
else $_bytes_to_read = $length; // Entire file.
|
475 |
|
476 |
+
$chunk_size = apply_filters('ws_plugin__s2member_file_downloads_chunk_size', 2097152, get_defined_vars());
|
477 |
|
478 |
+
while($_bytes_to_read) // While we have bytes to read here.
|
479 |
+
{
|
480 |
+
$_bytes_to_read -= ($_reading = ($_bytes_to_read > $chunk_size) ? $chunk_size : $_bytes_to_read);
|
481 |
+
echo fread($resource, $_reading); // Serve file in chunks (default chunk size is 2MB).
|
482 |
+
flush(); // Flush each chunk to the browser as it is served (avoids high memory consumption).
|
483 |
+
}
|
484 |
+
fclose($resource); // Close file resource handle.
|
485 |
+
unset($_bytes_to_read, $_reading); // Housekeeping.
|
486 |
+
}
|
487 |
+
exit(); // Stop execution now (the file has been served).
|
488 |
+
}
|
489 |
}
|
490 |
+
}
|
491 |
+
else if($serving && $req['file_download']) // Only when/if serving.
|
492 |
+
{
|
493 |
+
status_header(503);
|
494 |
+
header('Content-Type: text/html; charset=UTF-8');
|
495 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
496 |
+
exit(_x('<strong>503: Access denied.</strong> Invalid File Download specs.', 's2member-front', 's2member'));
|
497 |
+
}
|
498 |
+
else if($creating) return FALSE; // We only need this section when/if we're creating a URL.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
499 |
|
500 |
+
do_action('ws_plugin__s2member_after_file_download_access', get_defined_vars());
|
|
|
501 |
|
502 |
+
return ($creating) ? FALSE : NULL; // If creating, false.
|
503 |
+
}
|
504 |
|
505 |
+
/**
|
506 |
+
* Generates a File Download URL for access to a file protected by s2Member.
|
507 |
+
*
|
508 |
+
* @package s2Member\Files
|
509 |
+
* @since 110926
|
510 |
+
*
|
511 |
+
* @param array $config Required. This is an array of configuration options associated with permissions being checked against the current User/Member; and also the actual URL generated by this routine.
|
512 |
+
* Possible ``$config`` array elements: `file_download` *(required)*, `file_download_key`, `file_stream`, `file_inline`, `file_storage`, `file_remote`, `file_ssl`, `file_rewrite`, `file_rewrite_base`, `skip_confirmation`, `url_to_storage_source`, `count_against_user`, `check_user`.
|
513 |
+
* @param bool $get_streamer_array Optional. Defaults to `false`. If `true`, this function will return an array with the following elements: `streamer`, `file`, `url`. For further details, please review this section in your Dashboard: `s2Member -› Download Options -› JW Player & RTMP Protocol Examples`.
|
514 |
+
*
|
515 |
+
* @return string A File Download URL string on success; or an array on success, with elements `streamer`, `file`, `url` when/if ``$get_streamer_array`` is true; else false on any type of failure.
|
516 |
+
*
|
517 |
+
* @see s2Member\API_Functions\s2member_file_download_url()
|
518 |
+
*/
|
519 |
+
public static function create_file_download_url($config = array(), $get_streamer_array = FALSE)
|
520 |
+
{
|
521 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
522 |
+
do_action('ws_plugin__s2member_before_create_file_download_url', get_defined_vars());
|
523 |
+
unset($__refs, $__v); // Housekeeping.
|
524 |
+
|
525 |
+
$config = (is_array($config)) ? $config : array(); // This absolutely MUST be an array.
|
526 |
+
|
527 |
+
$config['file_download'] = (isset($config['file_download']) && is_string($config['file_download'])) ? trim($config['file_download'], '/') : '';
|
528 |
+
$config['file_download_key'] = (!empty($config['file_download_key']) && is_string($config['file_download'])) ? 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)) : '';
|
529 |
+
|
530 |
+
$config['url_to_storage_source'] = ($get_streamer_array) ? TRUE : @$config['url_to_storage_source']; // Force a streaming URL here via ``$get_streamer_array``?
|
531 |
+
$config['file_stream'] = ($get_streamer_array) ? TRUE : @$config['file_stream']; // Force a streaming URL here via ``$get_streamer_array``?
|
532 |
+
|
533 |
+
if(($url_ = c_ws_plugin__s2member_files_in::check_file_download_access(($config)))) // Successfully created a URL to the file?
|
534 |
+
{
|
535 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
536 |
+
do_action('ws_plugin__s2member_during_create_file_download_url', get_defined_vars());
|
537 |
+
unset($__refs, $__v); // Housekeeping.
|
538 |
|
539 |
+
$extension = strtolower(substr($config['file_download'], strrpos($config['file_download'], '.') + 1));
|
540 |
+
$streaming = (isset($config['file_stream'])) ? filter_var($config['file_stream'], FILTER_VALIDATE_BOOLEAN) : ((in_array($extension, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_stream_extensions']))) ? TRUE : FALSE);
|
541 |
+
$ssl = (isset($config['file_ssl'])) ? filter_var($config['file_ssl'], FILTER_VALIDATE_BOOLEAN) : ((is_ssl()) ? TRUE : FALSE);
|
542 |
|
543 |
+
if($get_streamer_array && $streaming && ($cfx = '/cfx/st') && ($cfx_pos = strpos($url_, $cfx)) !== FALSE && ($streamer = substr($url_, 0, $cfx_pos + strlen($cfx))) && ($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)))))
|
544 |
+
$return = array('streamer' => $streamer, 'prefix' => $extension.':', 'file' => preg_replace('/^'.preg_quote($streamer, '/').'\//', '', $url_), 'url' => preg_replace('/^.+?\:/', (($ssl) ? 'https:' : 'http:'), $url));
|
545 |
|
546 |
+
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)))))
|
547 |
+
$return = array('streamer' => $streamer, 'prefix' => '', 'file' => preg_replace('/^'.preg_quote($streamer, '/').'\//', '', $url_), 'url' => preg_replace('/^.+?\:/', (($ssl) ? 'https:' : 'http:'), $url));
|
548 |
|
549 |
+
else if($get_streamer_array) // If streamer, we MUST return false here; unable to acquire streamer/file.
|
550 |
+
$return = FALSE; // We MUST return false here, unable to acquire streamer/file.
|
|
|
551 |
|
552 |
+
else // Else return URL string ( ``$get_streamer_array`` is false ).
|
553 |
+
$return = $url_; // Else return URL string.
|
554 |
+
}
|
555 |
+
return apply_filters('ws_plugin__s2member_create_file_download_url', ((isset($return)) ? $return : FALSE), get_defined_vars());
|
556 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
557 |
|
558 |
+
/**
|
559 |
+
* Checks Header Authorization for Remote File Downloads.
|
560 |
+
*
|
561 |
+
* @package s2Member\Files
|
562 |
+
* @since 110926
|
563 |
+
*
|
564 |
+
* @attaches-to ``add_filter('ws_plugin__s2member_check_file_download_access_user');``
|
565 |
+
*
|
566 |
+
* @param WP_User $user Expects a WP_User object passed in by the Filter.
|
567 |
+
*
|
568 |
+
* @return WP_User A `WP_User` object, possibly obtained through Header Authorization.
|
569 |
+
*/
|
570 |
+
public static function check_file_remote_authorization($user = NULL)
|
571 |
+
{
|
572 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
573 |
+
do_action('ws_plugin__s2member_before_check_file_remote_authorization', get_defined_vars());
|
574 |
+
unset($__refs, $__v); // Housekeeping.
|
575 |
+
|
576 |
+
$_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep(((!empty($_GET)) ? $_GET : array())));
|
577 |
+
|
578 |
+
if(!is_object($user) && isset($_g['s2member_file_remote']) && filter_var($_g['s2member_file_remote'], FILTER_VALIDATE_BOOLEAN))
|
579 |
+
{
|
580 |
+
do_action('ws_plugin__s2member_during_check_file_remote_authorization_before', get_defined_vars());
|
581 |
+
|
582 |
+
if((empty($_SERVER['PHP_AUTH_USER']) || $_SERVER['PHP_AUTH_USER'] === 'NOUSER') && !empty($_SERVER['HTTP_AUTHORIZATION']))
|
583 |
+
{
|
584 |
+
$auth = trim(preg_replace('/^.+?\s+/', '', $_SERVER['HTTP_AUTHORIZATION']));
|
585 |
+
$auth = explode(':', base64_decode($auth), 2);
|
586 |
+
|
587 |
+
if(!empty($auth[0])) $_SERVER['PHP_AUTH_USER'] = $auth[0];
|
588 |
+
if(!empty($auth[1])) $_SERVER['PHP_AUTH_PW'] = $auth[1];
|
589 |
+
}
|
590 |
+
if(empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW']) || !user_pass_ok($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']))
|
591 |
+
{
|
592 |
+
header('WWW-Authenticate: Basic realm="'.c_ws_plugin__s2member_utils_strings::esc_dq(strip_tags(_x('Members Only', 's2member-front', 's2member'))).'"');
|
593 |
+
|
594 |
+
status_header(401); // Send an unauthorized 401 status header now.
|
595 |
+
header('Content-Type: text/html; charset=UTF-8'); // Content-Type with UTF-8.
|
596 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
597 |
+
|
598 |
+
exit(_x('<strong>401:</strong> Sorry, access denied.', 's2member-front', 's2member'));
|
599 |
+
}
|
600 |
+
else if(is_object($_user = new WP_User($_SERVER['PHP_AUTH_USER'])) && !empty($_user->ID))
|
601 |
+
$user = $_user; // Now assign ``$user``.
|
602 |
+
|
603 |
+
do_action('ws_plugin__s2member_during_check_file_remote_authorization_after', get_defined_vars());
|
604 |
+
}
|
605 |
+
return apply_filters('ws_plugin__s2member_check_file_remote_authorization', $user, get_defined_vars());
|
606 |
+
}
|
607 |
|
608 |
+
/**
|
609 |
+
* Checks a File Download Key for validity.
|
610 |
+
*
|
611 |
+
* @package s2Member\Files
|
612 |
+
* @since 110926
|
613 |
+
*
|
614 |
+
* @param string $file Input File Download to validate.
|
615 |
+
* @param string $key Input File Download Key to validate.
|
616 |
+
*
|
617 |
+
* @return bool True if valid, else false.
|
618 |
+
*/
|
619 |
+
public static function check_file_download_key($file = '', $key = '')
|
620 |
+
{
|
621 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
622 |
+
do_action('_ws_plugin__s2member_before_check_file_download_key', get_defined_vars());
|
623 |
+
unset($__refs, $__v); // Housekeeping.
|
624 |
+
|
625 |
+
if($file && is_string($file) && ($file = trim($file, '/')) && $key && is_string($key))
|
626 |
+
{
|
627 |
+
if($key === c_ws_plugin__s2member_files::file_download_key($file) || $key === c_ws_plugin__s2member_files::file_download_key('/'.$file))
|
628 |
+
$valid = TRUE; // File Download Key is valid.
|
629 |
|
630 |
+
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'))
|
631 |
+
$valid = TRUE; // File Download Key is valid.
|
|
|
|
|
632 |
|
633 |
+
else if($key === c_ws_plugin__s2member_files::file_download_key($file, 'universal') || $key === c_ws_plugin__s2member_files::file_download_key('/'.$file, 'universal'))
|
634 |
+
$valid = TRUE; // File Download Key is valid.
|
635 |
+
}
|
636 |
+
return apply_filters('ws_plugin__s2member_check_file_download_key', ((isset($valid) && $valid) ? TRUE : FALSE), get_defined_vars());
|
637 |
+
}
|
|
|
638 |
|
639 |
+
/**
|
640 |
+
* Creates an Amazon S3 HMAC-SHA1 signature.
|
641 |
+
*
|
642 |
+
* @package s2Member\Files
|
643 |
+
* @since 110524RC
|
644 |
+
*
|
645 |
+
* @param string $string Input string/data, to be signed by this routine.
|
646 |
+
*
|
647 |
+
* @return string An HMAC-SHA1 signature for Amazon S3.
|
648 |
+
*/
|
649 |
+
public static function amazon_s3_sign($string = '')
|
650 |
+
{
|
651 |
+
$s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
652 |
+
|
653 |
+
return c_ws_plugin__s2member_utils_strings::hmac_sha1_sign((string)$string, $s3c['secret_key']);
|
654 |
+
}
|
655 |
|
656 |
+
/**
|
657 |
+
* Creates an Amazon S3 HMAC-SHA1 signature URL.
|
658 |
+
*
|
659 |
+
* @package s2Member\Files
|
660 |
+
* @since 110926
|
661 |
+
*
|
662 |
+
* @param string $file Input file path, to be signed by this routine.
|
663 |
+
* @param bool $stream Is this resource file to be served as streaming media?
|
664 |
+
* @param bool $inline Is this resource file to be served inline, or no?
|
665 |
+
* @param bool $ssl Is this resource file to be served via SSL, or no?
|
666 |
+
* @param string $basename The absolute basename of the resource file.
|
667 |
+
* @param string $mimetype The MIME content-type of the resource file.
|
668 |
+
*
|
669 |
+
* @return string An HMAC-SHA1 signature URL for Amazon S3.
|
670 |
+
*/
|
671 |
+
public static function amazon_s3_url($file = '', $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = '', $mimetype = '')
|
672 |
+
{
|
673 |
+
$file = trim((string)$file, '/'); // Trim / force string.
|
674 |
+
$url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($file));
|
675 |
+
$url_e_file = str_ireplace('%2F', '/', $url_e_file);
|
676 |
+
|
677 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
678 |
+
if(preg_match('/^amazon_s3_files_/', $option) && ($option = preg_replace('/^amazon_s3_files_/', '', $option)))
|
679 |
+
$s3c[$option] = $option_value;
|
680 |
+
|
681 |
+
$s3c['expires'] = strtotime('+'.apply_filters('ws_plugin__s2member_amazon_s3_file_expires_time', '24 hours', get_defined_vars()));
|
682 |
+
|
683 |
+
$s3_file = add_query_arg(c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode_deep(array('response-cache-control' => ($s3_cache_control = 'no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0'), 'response-content-disposition' => ($s3_content_disposition = (((bool)$inline) ? 'inline' : 'attachment').'; filename="'.(string)$basename.'"'), 'response-content-type' => ($s3_content_type = (string)$mimetype), 'response-expires' => ($s3_expires = gmdate('D, d M Y H:i:s', strtotime('-1 week')).' GMT')))), '/'.$url_e_file);
|
684 |
+
$s3_raw_file = add_query_arg(array('response-cache-control' => $s3_cache_control, 'response-content-disposition' => $s3_content_disposition, 'response-content-type' => $s3_content_type, 'response-expires' => $s3_expires), '/'.$url_e_file);
|
685 |
+
$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));
|
686 |
+
|
687 |
+
$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;
|
688 |
+
|
689 |
+
return add_query_arg(c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode_deep(array('AWSAccessKeyId' => $s3c['access_key'], 'Expires' => $s3c['expires'], 'Signature' => $s3_signature))), $s3_url);
|
690 |
+
}
|
691 |
|
692 |
+
/**
|
693 |
+
* Auto-configures an Amazon S3 Bucket's ACLs.
|
694 |
+
*
|
695 |
+
* @package s2Member\Files
|
696 |
+
* @since 110926
|
697 |
+
*
|
698 |
+
* @return array Array containing a true `success` element on success, else a failure array.
|
699 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
700 |
+
*/
|
701 |
+
public static function amazon_s3_auto_configure_acls()
|
702 |
+
{
|
703 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
704 |
+
if(preg_match('/^amazon_s3_files_/', $option) && ($option = preg_replace('/^amazon_s3_files_/', '', $option)))
|
705 |
+
$s3c[$option] = $option_value;
|
706 |
+
|
707 |
+
$cfc['distros_s3_access_id'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distros_s3_access_id'];
|
708 |
+
|
709 |
+
if(!empty($s3c) && $s3c['bucket'] && $s3c['access_key'] && $s3c['secret_key']) // Must have Amazon S3 Bucket/Keys.
|
710 |
+
{
|
711 |
+
$s3_date = gmdate('D, d M Y H:i:s').' GMT';
|
712 |
+
$s3_location = ((strtolower($s3c['bucket']) !== $s3c['bucket'])) ? '/'.$s3c['bucket'].'/?acl' : '/?acl';
|
713 |
+
$s3_domain = ((strtolower($s3c['bucket']) !== $s3c['bucket'])) ? 's3.amazonaws.com' : $s3c['bucket'].'.s3.amazonaws.com';
|
714 |
+
$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign('GET'."\n\n\n".$s3_date."\n".'/'.$s3c['bucket'].'/?acl'));
|
715 |
+
$s3_args = array('method' => 'GET', 'redirection' => 5, 'headers' => array('Host' => $s3_domain, 'Date' => $s3_date, 'Authorization' => 'AWS '.$s3c['access_key'].':'.$s3_signature));
|
716 |
+
|
717 |
+
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)
|
718 |
+
{
|
719 |
+
if(preg_match('/\<Owner\>(.+?)\<\/Owner\>/is', $s3_response['body'], $s3_owner_tag) && preg_match('/\<ID\>(.+?)\<\/ID\>/is', $s3_owner_tag[1], $s3_owner_id_tag) && (preg_match('/\<DisplayName\>(.*?)\<\/DisplayName\>/is', $s3_owner_tag[1], $s3_owner_display_name_tag) || ($s3_owner_display_name_tag = array('-', 'Owner'))))
|
720 |
{
|
721 |
+
$s3_owner = array('access_id' => trim($s3_owner_id_tag[1]), 'display_name' => trim($s3_owner_display_name_tag[1]));
|
722 |
+
$s3_acls_xml = '<AccessControlPolicy><Owner><ID>'.esc_html($s3_owner['access_id']).'</ID><DisplayName>'.esc_html($s3_owner['display_name']).'</DisplayName></Owner><AccessControlList><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>'.esc_html($s3_owner['access_id']).'</ID><DisplayName>'.esc_html($s3_owner['display_name']).'</DisplayName></Grantee><Permission>FULL_CONTROL</Permission></Grant>'.(($cfc['distros_s3_access_id']) ? '<Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>'.esc_html($cfc['distros_s3_access_id']).'</ID><DisplayName>s2Member/CloudFront</DisplayName></Grantee><Permission>READ</Permission></Grant>' : '').'</AccessControlList></AccessControlPolicy>';
|
723 |
+
$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign('PUT'."\n\n".'application/xml'."\n".$s3_date."\n".'/'.$s3c['bucket'].'/?acl'));
|
724 |
+
$s3_args = array('method' => 'PUT', 'redirection' => 5, 'body' => $s3_acls_xml, 'headers' => array('Host' => $s3_domain, 'Content-Type' => 'application/xml', 'Date' => $s3_date, 'Authorization' => 'AWS '.$s3c['access_key'].':'.$s3_signature));
|
725 |
+
|
726 |
+
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)
|
727 |
+
{
|
728 |
+
$s3_location = ((strtolower($s3c['bucket']) !== $s3c['bucket'])) ? '/'.$s3c['bucket'].'/?policy' : '/?policy';
|
729 |
+
($s3_policy_id = md5(uniqid('s2Member/CloudFront:', TRUE))).($s3_policy_sid = md5(uniqid('s2Member/CloudFront:', TRUE)));
|
730 |
+
$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']).'/*"}]}';
|
731 |
+
$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign('PUT'."\n\n".'application/json'."\n".$s3_date."\n".'/'.$s3c['bucket'].'/?policy'));
|
732 |
+
$s3_args = array('method' => 'PUT', 'redirection' => 5, 'body' => $s3_policy_json, 'headers' => array('Host' => $s3_domain, 'Content-Type' => 'application/json', 'Date' => $s3_date, 'Authorization' => 'AWS '.$s3c['access_key'].':'.$s3_signature));
|
733 |
+
|
734 |
+
if(!$cfc['distros_s3_access_id'] || (($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 || $s3_response['code'] === 204)))
|
735 |
{
|
736 |
+
$s3_location = ((strtolower($s3c['bucket']) !== $s3c['bucket'])) ? '/'.$s3c['bucket'].'/crossdomain.xml' : '/crossdomain.xml';
|
737 |
+
$s3_policy_xml = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents(dirname(dirname(__FILE__)).'/templates/cfg-files/s2-cross-xml.php')));
|
738 |
+
$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign('PUT'."\n\n".'text/xml'."\n".$s3_date."\n".'x-amz-acl:public-read'."\n".'/'.$s3c['bucket'].'/crossdomain.xml'));
|
739 |
+
$s3_args = array('method' => 'PUT', 'redirection' => 5, '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));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
740 |
|
741 |
+
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)
|
742 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL); // Successfully configured Amazon S3 Bucket ACLs and Policy.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
743 |
|
744 |
+
else if(isset($s3_response['code'], $s3_response['message']))
|
745 |
+
/* 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. */
|
746 |
+
return array('success' => FALSE, 'code' => $s3_response['code'], 'message' => sprintf(_x('Unable to update existing Amazon S3 Cross-Domain Policy. %s', 's2member-admin', 's2member'), $s3_response['message']));
|
|
|
|
|
747 |
|
748 |
+
else // Else, we use a default error code and message.
|
749 |
+
return array('success' => FALSE, 'code' => -94, 'message' => _x('Unable to update existing Amazon S3 Cross-Domain Policy. Connection failed.', 's2member-admin', 's2member'));
|
750 |
+
}
|
751 |
+
else if(isset($s3_response['code'], $s3_response['message']))
|
752 |
+
/* 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. */
|
753 |
+
return array('success' => FALSE, 'code' => $s3_response['code'], 'message' => sprintf(_x('Unable to update existing Amazon S3 Bucket Policy. %s', 's2member-admin', 's2member'), $s3_response['message']));
|
754 |
|
755 |
+
else // Else, we use a default error code and message.
|
756 |
+
return array('success' => FALSE, 'code' => -95, 'message' => _x('Unable to update existing Amazon S3 Bucket Policy. Connection failed.', 's2member-admin', 's2member'));
|
757 |
+
}
|
758 |
+
else if(isset($s3_response['code'], $s3_response['message']))
|
759 |
+
/* 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. */
|
760 |
+
return array('success' => FALSE, 'code' => $s3_response['code'], 'message' => sprintf(_x('Unable to update existing Amazon S3 Bucket ACLs. %s', 's2member-admin', 's2member'), $s3_response['message']));
|
761 |
|
762 |
+
else // Else, we use a default error code and message.
|
763 |
+
return array('success' => FALSE, 'code' => -96, 'message' => _x('Unable to update existing Amazon S3 Bucket ACLs. Connection failed.', 's2member-admin', 's2member'));
|
764 |
}
|
765 |
+
else // Else, we use a default error code and message.
|
766 |
+
return array('success' => FALSE, 'code' => -97, 'message' => _x('Unable to acquire/read existing Amazon S3 Bucket ACLs. Unexpected response.', 's2member-admin', 's2member'));
|
767 |
+
}
|
768 |
+
else if(isset($s3_response['code'], $s3_response['message']))
|
769 |
+
/* 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. */
|
770 |
+
return array('success' => FALSE, 'code' => $s3_response['code'], 'message' => sprintf(_x('Unable to acquire existing Amazon S3 Bucket ACLs. %s', 's2member-admin', 's2member'), $s3_response['message']));
|
771 |
+
|
772 |
+
else // Else, we use a default error code and message.
|
773 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Unable to acquire existing Amazon S3 Bucket ACLs. Connection failed.', 's2member-admin', 's2member'));
|
774 |
+
}
|
775 |
+
else // Else, we use a default error code and message.
|
776 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to auto-configure existing Amazon S3 Bucket ACLs. Incomplete Amazon S3 configuration options. Missing one of: Amazon S3 Bucket, Access Key, or Secret Key.', 's2member-admin', 's2member'));
|
777 |
+
}
|
|
|
|
|
|
|
778 |
|
779 |
+
/**
|
780 |
+
* Creates an Amazon CloudFront HMAC-SHA1 signature.
|
781 |
+
*
|
782 |
+
* @package s2Member\Files
|
783 |
+
* @since 110926
|
784 |
+
*
|
785 |
+
* @param string $string Input string/data, to be signed by this routine.
|
786 |
+
*
|
787 |
+
* @return string An HMAC-SHA1 signature for Amazon CloudFront.
|
788 |
+
*/
|
789 |
+
public static function amazon_cf_sign($string = '')
|
790 |
+
{
|
791 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
792 |
+
|
793 |
+
return c_ws_plugin__s2member_utils_strings::hmac_sha1_sign((string)$string, ($cfc['secret_key'] = $s3c['secret_key']));
|
794 |
+
}
|
795 |
|
796 |
+
/**
|
797 |
+
* Creates an Amazon CloudFront RSA-SHA1 signature.
|
798 |
+
*
|
799 |
+
* @package s2Member\Files
|
800 |
+
* @since 110926
|
801 |
+
*
|
802 |
+
* @param string $string Input string/data, to be signed by this routine.
|
803 |
+
*
|
804 |
+
* @return string|bool An RSA-SHA1 signature for Amazon CloudFront, else false on failure.
|
805 |
+
*/
|
806 |
+
public static function amazon_cf_rsa_sign($string = '')
|
807 |
+
{
|
808 |
+
$cfc['private_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_private_key'];
|
809 |
+
|
810 |
+
return c_ws_plugin__s2member_utils_strings::rsa_sha1_sign((string)$string, $cfc['private_key']);
|
811 |
+
}
|
812 |
|
813 |
+
/**
|
814 |
+
* Creates an Amazon CloudFront RSA-SHA1 signature URL.
|
815 |
+
*
|
816 |
+
* @package s2Member\Files
|
817 |
+
* @since 110926
|
818 |
+
*
|
819 |
+
* @param string $file Input file path, to be signed by this routine.
|
820 |
+
* @param bool $stream Is this resource file to be served as streaming media?
|
821 |
+
* @param bool $inline Is this resource file to be served inline, or no?
|
822 |
+
* @param bool $ssl Is this resource file to be served via SSL, or no?
|
823 |
+
* @param string $basename The absolute basename of the resource file.
|
824 |
+
* @param string $mimetype The MIME content-type of the resource file.
|
825 |
+
*
|
826 |
+
* @return string An RSA-SHA1 signature URL for Amazon CloudFront.
|
827 |
+
*/
|
828 |
+
public static function amazon_cf_url($file = '', $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = '', $mimetype = '')
|
829 |
+
{
|
830 |
+
$file = trim((string)$file, '/'); // Trim & force string.
|
831 |
+
$url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($file));
|
832 |
+
$url_e_file = str_ireplace('%2F', '/', $url_e_file);
|
833 |
+
|
834 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
835 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
836 |
+
$cfc[$option] = $option_value;
|
837 |
+
|
838 |
+
$cfc['expires'] = strtotime('+'.apply_filters('ws_plugin__s2member_amazon_cf_file_expires_time', '24 hours', get_defined_vars()));
|
839 |
+
|
840 |
+
$cf_extn = strtolower(substr($file, strrpos($file, '.') + 1)); // Parses the file extension out so we can scan it in some special scenarios.
|
841 |
+
$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.
|
842 |
+
$cf_stream_extn_resource_exclusions = array_unique((array)apply_filters('ws_plugin__s2member_amazon_cf_file_streaming_extension_resource_exclusions', array('mp3'), get_defined_vars())); // MP3 files should NOT include an extension in their resource reference.
|
843 |
+
$cf_resource = ($stream) ? ((in_array($cf_extn, $cf_stream_extn_resource_exclusions)) ? substr($file, 0, strrpos($file, '.')) : $file) : 'http'.(($ssl) ? 's' : '').'://'.(($cfc['distro_downloads_cname']) ? $cfc['distro_downloads_cname'] : $cfc['distro_downloads_dname']).'/'.$url_e_file;
|
844 |
+
$cf_url = ($stream) ? 'rtmp'.(($ssl) ? 'e' : '').'://'.(($cfc['distro_streaming_cname']) ? $cfc['distro_streaming_cname'] : $cfc['distro_streaming_dname']).'/cfx/st/'.$file : 'http'.(($ssl) ? 's' : '').'://'.(($cfc['distro_downloads_cname']) ? $cfc['distro_downloads_cname'] : $cfc['distro_downloads_dname']).'/'.$url_e_file;
|
845 |
+
$cf_policy = '{"Statement":[{"Resource":"'.c_ws_plugin__s2member_utils_strings::esc_dq($cf_resource).'","Condition":{'.(($cf_ip_res) ? '"IpAddress":{"AWS:SourceIp":"'.c_ws_plugin__s2member_utils_strings::esc_dq($_SERVER['REMOTE_ADDR']).'/32"},' : '').'"DateLessThan":{"AWS:EpochTime":'.(int)$cfc['expires'].'}}}]}';
|
846 |
+
|
847 |
+
$cf_signature = c_ws_plugin__s2member_files_in::amazon_cf_rsa_sign($cf_policy);
|
848 |
+
$cf_base64_url_safe_policy = c_ws_plugin__s2member_utils_strings::base64_url_safe_encode($cf_policy, array('+', '=', '/'), array('-', '_', '~'), FALSE);
|
849 |
+
$cf_base64_url_safe_signature = c_ws_plugin__s2member_utils_strings::base64_url_safe_encode($cf_signature, array('+', '=', '/'), array('-', '_', '~'), FALSE);
|
850 |
+
|
851 |
+
return add_query_arg(c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode_deep(array('Policy' => $cf_base64_url_safe_policy, 'Signature' => $cf_base64_url_safe_signature, 'Key-Pair-Id' => $cfc['private_key_id']))), $cf_url);
|
852 |
+
}
|
853 |
|
854 |
+
/**
|
855 |
+
* Auto-configures Amazon S3/CloudFront distros.
|
856 |
+
*
|
857 |
+
* @package s2Member\Files
|
858 |
+
* @since 110926
|
859 |
+
*
|
860 |
+
* @return array Array containing a true `success` element on success, else a failure array.
|
861 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
862 |
+
*/
|
863 |
+
public static function amazon_cf_auto_configure_distros()
|
864 |
+
{
|
865 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
866 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
867 |
+
$cfc[$option] = $option_value;
|
868 |
+
|
869 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
870 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
871 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
872 |
+
|
873 |
+
if($s3c['bucket'] && $s3c['access_key'] && $s3c['secret_key']) // We MUST have an Amazon S3 Bucket and Keys.
|
874 |
+
{
|
875 |
+
if($cfc['private_key'] && $cfc['private_key_id']) // We MUST have Amazon CloudFront Keys in order to auto-configure.
|
876 |
+
{
|
877 |
+
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)))
|
878 |
+
{
|
879 |
+
if(!$cfc['distro_downloads_id'] || ($cfc['distro_downloads_id'] && !empty($cf_get_response) && !$cf_get_response['success'] && $cf_get_response['code'] === 404))
|
880 |
+
$cf_distro_downloads_clear = TRUE; // Clear, ready for a new one.
|
881 |
|
882 |
+
else if($cfc['distro_downloads_id'] && !empty($cf_get_response) && $cf_get_response['success'] && !$cf_get_response['deployed'])
|
883 |
+
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'));
|
884 |
|
885 |
+
else if($cfc['distro_downloads_id'] && !empty($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'])
|
886 |
+
$cf_distro_downloads_clear = TRUE; // Clear, ready for a new one.
|
|
|
887 |
|
888 |
+
else if(isset($cf_del_response['code'], $cf_del_response['message']))
|
889 |
+
/* 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. */
|
890 |
+
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']));
|
|
|
|
|
|
|
891 |
|
892 |
+
if(isset($cf_distro_downloads_clear) && $cf_distro_downloads_clear) // Successfully cleared? Ready for a new one?
|
893 |
+
{
|
894 |
+
unset($cf_get_response, $cf_del_response); // Unset these before processing additional routines. Prevents problems in error reporting.
|
|
|
|
|
|
|
895 |
|
896 |
+
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)))
|
897 |
+
{
|
898 |
+
if(!$cfc['distro_streaming_id'] || ($cfc['distro_streaming_id'] && !empty($cf_get_response) && !$cf_get_response['success'] && $cf_get_response['code'] === 404))
|
899 |
+
$cf_distro_streaming_clear = TRUE; // Clear, ready for a new one.
|
|
|
|
|
|
|
|
|
|
|
900 |
|
901 |
+
else if($cfc['distro_streaming_id'] && !empty($cf_get_response) && $cf_get_response['success'] && !$cf_get_response['deployed'])
|
902 |
+
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'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
903 |
|
904 |
+
else if($cfc['distro_streaming_id'] && !empty($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'])
|
905 |
+
$cf_distro_streaming_clear = TRUE; // Clear, ready for a new one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
906 |
|
907 |
+
else if(isset($cf_del_response['code'], $cf_del_response['message']))
|
908 |
+
/* 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. */
|
909 |
+
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']));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
910 |
|
911 |
+
if(isset($cf_distro_streaming_clear) && $cf_distro_streaming_clear) // Successfully cleared? Ready for a new one?
|
912 |
+
{
|
913 |
+
unset($cf_get_response, $cf_del_response); // Unset these before processing additional routines. Prevents problems in error reporting.
|
914 |
|
915 |
+
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)))
|
916 |
+
{
|
917 |
+
if(!$cfc['distros_access_id'] || ($cfc['distros_access_id'] && !empty($cf_get_response) && !$cf_get_response['success'] && $cf_get_response['code'] === 404))
|
918 |
+
$cf_distros_access_clear = TRUE; // Clear, ready for a new one.
|
919 |
|
920 |
+
else if($cfc['distros_access_id'] && !empty($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'])
|
921 |
+
$cf_distros_access_clear = TRUE; // Clear, ready for a new one.
|
|
|
|
|
|
|
|
|
922 |
|
923 |
+
else if(isset($cf_del_response['code'], $cf_del_response['message']))
|
924 |
+
/* 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. */
|
925 |
+
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']));
|
926 |
|
927 |
+
if(isset($cf_distros_access_clear) && $cf_distros_access_clear) // Successfully cleared? Ready for a new one?
|
928 |
+
{
|
929 |
+
unset($cf_get_response, $cf_del_response); // Unset these before processing additional routines. Prevents problems in error reporting.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
930 |
|
931 |
+
$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' => ''));
|
932 |
+
$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' => '');
|
933 |
+
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, TRUE, FALSE, FALSE, FALSE, FALSE);
|
934 |
|
935 |
+
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distros_access_origin_identity()) && $cf_response['success'])
|
|
|
|
|
|
|
|
|
936 |
{
|
937 |
+
$cfc = array_merge($cfc, array('distros_access_id' => $cf_response['distros_access_id'], 'distros_s3_access_id' => $cf_response['distros_s3_access_id']));
|
938 |
+
$cf_options = array('ws_plugin__s2member_amazon_cf_files_distros_access_id' => $cf_response['distros_access_id'], 'ws_plugin__s2member_amazon_cf_files_distros_s3_access_id' => $cf_response['distros_s3_access_id']);
|
939 |
+
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, TRUE, FALSE, FALSE, FALSE, FALSE);
|
|
|
|
|
|
|
|
|
|
|
940 |
|
941 |
+
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro('downloads')) && $cf_response['success'])
|
942 |
+
{
|
943 |
+
$cfc = array_merge($cfc, array('distro_downloads_id' => $cf_response['distro_downloads_id'], 'distro_downloads_dname' => $cf_response['distro_downloads_dname']));
|
944 |
+
$cf_options = array('ws_plugin__s2member_amazon_cf_files_distro_downloads_id' => $cf_response['distro_downloads_id'], 'ws_plugin__s2member_amazon_cf_files_distro_downloads_dname' => $cf_response['distro_downloads_dname']);
|
945 |
+
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, TRUE, FALSE, FALSE, FALSE, FALSE);
|
946 |
|
947 |
+
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro('streaming')) && $cf_response['success'])
|
948 |
{
|
949 |
+
$cfc = array_merge($cfc, array('distro_streaming_id' => $cf_response['distro_streaming_id'], 'distro_streaming_dname' => $cf_response['distro_streaming_dname']));
|
950 |
+
$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']);
|
951 |
+
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, TRUE, FALSE, FALSE, FALSE, FALSE);
|
952 |
+
|
953 |
+
for($a = 1, $attempts = 4, $sleep = 2, sleep($sleep); $a <= $attempts; $a++, (($a <= $attempts) ? sleep($sleep) : NULL))
|
954 |
+
/* Allow a generous propagation time here. Amazon\'s high-availability services do NOT guarantee real-time updates.
|
955 |
+
Since we DO need a fully propagated Origin Access Identity now, we need to make several attempts at success.
|
956 |
+
For further details, please see this thread: <https://forums.aws.amazon.com/message.jspa?messageID=42875>. */
|
957 |
+
if(($s3_response = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls()) && $s3_response['success'])
|
958 |
{
|
959 |
+
$cfc = array_merge($cfc, array('distros_auto_config_status' => 'configured'));
|
960 |
+
$cf_options = array('ws_plugin__s2member_amazon_cf_files_distros_auto_config_status' => 'configured');
|
961 |
+
c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, TRUE, FALSE, FALSE, FALSE, FALSE); // Now configured!
|
962 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL); // Successfully configured Amazon S3/CloudFront distros.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
963 |
}
|
964 |
+
if(isset($s3_response['code'], $s3_response['message']))
|
965 |
+
/* 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. */
|
966 |
+
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']));
|
967 |
|
968 |
else // Else, we use a default error code and message.
|
969 |
+
return array('success' => FALSE, 'code' => -88, 'message' => _x('Unable to update existing Amazon S3 ACLs. Connection failed.', 's2member-admin', 's2member'));
|
970 |
}
|
971 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
972 |
+
/* 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. */
|
973 |
+
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']));
|
974 |
+
|
975 |
+
else // Else, we use a default error code and message.
|
976 |
+
return array('success' => FALSE, 'code' => -89, 'message' => _x('Unable to create Amazon CloudFront Streaming Distro. Connection failed.', 's2member-admin', 's2member'));
|
977 |
+
}
|
978 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
979 |
+
/* 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. */
|
980 |
+
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']));
|
981 |
+
|
982 |
else // Else, we use a default error code and message.
|
983 |
+
return array('success' => FALSE, 'code' => -90, 'message' => _x('Unable to create Amazon CloudFront Downloads Distro. Connection failed.', 's2member-admin', 's2member'));
|
984 |
}
|
985 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
986 |
+
/* 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. */
|
987 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to create Amazon CloudFront Origin Access Identity. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
988 |
|
989 |
+
else // Else, we use a default error code and message.
|
990 |
+
return array('success' => FALSE, 'code' => -91, 'message' => _x('Unable to create Amazon CloudFront Origin Access Identity. Connection failed.', 's2member-admin', 's2member'));
|
991 |
+
}
|
992 |
else // Else, we use a default error code and message.
|
993 |
+
return array('success' => FALSE, 'code' => -92, 'message' => _x('Unable to clear existing Amazon CloudFront Origin Access Identity.', 's2member-admin', 's2member'));
|
994 |
}
|
995 |
+
else if(isset($cf_get_response['code'], $cf_get_response['message']))
|
996 |
+
/* 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. */
|
997 |
+
return array('success' => FALSE, 'code' => $cf_get_response['code'], 'message' => sprintf(_x('Unable to acquire existing Amazon CloudFront Origin Access Identity. %s', 's2member-admin', 's2member'), $cf_get_response['message']));
|
998 |
+
|
999 |
+
else // Else, we use a default error code and message.
|
1000 |
+
return array('success' => FALSE, 'code' => -93, 'message' => _x('Unable to acquire existing Amazon CloudFront Origin Access Identity. Connection failed.', 's2member-admin', 's2member'));
|
1001 |
+
}
|
1002 |
else // Else, we use a default error code and message.
|
1003 |
+
return array('success' => FALSE, 'code' => -94, 'message' => _x('Unable to clear existing Amazon CloudFront Streaming Distro.', 's2member-admin', 's2member'));
|
1004 |
}
|
1005 |
+
else if(isset($cf_get_response['code'], $cf_get_response['message']))
|
1006 |
+
/* 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. */
|
1007 |
+
return array('success' => FALSE, 'code' => $cf_get_response['code'], 'message' => sprintf(_x('Unable to acquire existing Amazon CloudFront Streaming Distro. %s', 's2member-admin', 's2member'), $cf_get_response['message']));
|
1008 |
+
|
1009 |
+
else // Else, we use a default error code and message.
|
1010 |
+
return array('success' => FALSE, 'code' => -95, 'message' => _x('Unable to acquire existing Amazon CloudFront Streaming Distro. Connection failed.', 's2member-admin', 's2member'));
|
1011 |
+
}
|
1012 |
else // Else, we use a default error code and message.
|
1013 |
+
return array('success' => FALSE, 'code' => -96, 'message' => _x('Unable to clear existing Amazon CloudFront Downloads Distro.', 's2member-admin', 's2member'));
|
1014 |
}
|
1015 |
+
else if(isset($cf_get_response['code'], $cf_get_response['message']))
|
1016 |
+
/* 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. */
|
1017 |
+
return array('success' => FALSE, 'code' => $cf_get_response['code'], 'message' => sprintf(_x('Unable to acquire existing Amazon CloudFront Downloads Distro. %s', 's2member-admin', 's2member'), $cf_get_response['message']));
|
1018 |
+
|
1019 |
+
else // Else, we use a default error code and message.
|
1020 |
+
return array('success' => FALSE, 'code' => -97, 'message' => _x('Unable to acquire existing Amazon CloudFront Downloads Distro. Connection failed.', 's2member-admin', 's2member'));
|
1021 |
+
}
|
1022 |
+
else // Else, we use a default error code and message.
|
1023 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('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.', 's2member-admin', 's2member'));
|
1024 |
+
}
|
1025 |
+
else // Else, we use a default error code and message.
|
1026 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('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.', 's2member-admin', 's2member'));
|
1027 |
+
}
|
|
|
|
|
|
|
|
|
1028 |
|
1029 |
+
/**
|
1030 |
+
* Acquires an Amazon S3/CloudFront Access Origin Identity.
|
1031 |
+
*
|
1032 |
+
* @package s2Member\Files
|
1033 |
+
* @since 110926
|
1034 |
+
*
|
1035 |
+
* @param string $access_id Required. An Origin Access ID.
|
1036 |
+
*
|
1037 |
+
* @return array Array containing a true `success` and `etag`, `xml` elements on success, else a failure array.
|
1038 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
1039 |
+
*/
|
1040 |
+
public static function amazon_cf_get_access_origin_identity($access_id = '')
|
1041 |
+
{
|
1042 |
+
if($access_id && is_string($access_id)) // Valid parameters?
|
1043 |
+
{
|
1044 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
1045 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
1046 |
+
$cfc[$option] = $option_value;
|
1047 |
+
|
1048 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
1049 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
1050 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
1051 |
+
|
1052 |
+
$cf_domain = 'cloudfront.amazonaws.com';
|
1053 |
+
$cf_date = gmdate('D, d M Y H:i:s').' GMT';
|
1054 |
+
$cf_location = '/2010-11-01/origin-access-identity/cloudfront/'.$access_id;
|
1055 |
+
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1056 |
+
$cf_args = array('method' => 'GET', 'redirection' => 5, 'headers' => array('Host' => $cf_domain, 'Date' => $cf_date, 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
1057 |
+
|
1058 |
+
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$cf_domain.$cf_location, FALSE, array_merge($cf_args, array('timeout' => 20)), 'array')) && (($cf_response['code'] === 404 && $cf_response['message']) || ($cf_response['code'] === 200 && !empty($cf_response['headers']['etag']) && !empty($cf_response['body']))))
|
1059 |
+
{
|
1060 |
+
if($cf_response['code'] === 200 && !empty($cf_response['headers']['etag']) && !empty($cf_response['body']))
|
1061 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL, 'etag' => trim($cf_response['headers']['etag']), 'xml' => trim($cf_response['body']));
|
1062 |
+
|
1063 |
+
else /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1064 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Existing Amazon CloudFront Origin Access Identity NOT found. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1065 |
+
}
|
1066 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1067 |
+
/* 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. */
|
1068 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to acquire existing Amazon CloudFront Origin Access Identity. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1069 |
+
|
1070 |
+
else // Else, we use a default error code and message.
|
1071 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Unable to acquire existing Amazon CloudFront Origin Access Identity. Connection failed.', 's2member-admin', 's2member'));
|
1072 |
+
}
|
1073 |
+
else // Else, we use a default error code and message.
|
1074 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to acquire existing Amazon CloudFront Origin Access Identity. Invalid Access ID.', 's2member-admin', 's2member'));
|
1075 |
+
}
|
1076 |
|
1077 |
+
/**
|
1078 |
+
* Deletes an Amazon S3/CloudFront Access Origin Identity.
|
1079 |
+
*
|
1080 |
+
* @package s2Member\Files
|
1081 |
+
* @since 110926
|
1082 |
+
*
|
1083 |
+
* @param string $access_id Required. An Origin Access ID.
|
1084 |
+
* @param string $access_id_etag Required. An Origin Access ETag header.
|
1085 |
+
* @param string $access_id_xml Required. An Origin Access Identity's XML configuration.
|
1086 |
+
*
|
1087 |
+
* @return array Array containing a true `success` element on success, else a failure array.
|
1088 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
1089 |
+
*/
|
1090 |
+
public static function amazon_cf_del_access_origin_identity($access_id = '', $access_id_etag = '', $access_id_xml = '')
|
1091 |
+
{
|
1092 |
+
if($access_id && is_string($access_id) && $access_id_etag && is_string($access_id_etag) && $access_id_xml && is_string($access_id_xml))
|
1093 |
+
{
|
1094 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
1095 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
1096 |
+
$cfc[$option] = $option_value;
|
1097 |
|
1098 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
1099 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
1100 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
|
|
1101 |
|
1102 |
+
$cf_domain = 'cloudfront.amazonaws.com';
|
1103 |
+
$cf_date = gmdate('D, d M Y H:i:s').' GMT';
|
1104 |
+
$cf_location = '/2010-11-01/origin-access-identity/cloudfront/'.$access_id;
|
1105 |
+
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1106 |
+
$cf_args = array('method' => 'DELETE', 'redirection' => 5, 'headers' => array('Host' => $cf_domain, 'Date' => $cf_date, 'If-Match' => $access_id_etag, 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
|
|
1107 |
|
1108 |
+
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))
|
1109 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL); // Deleted successfully.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1110 |
|
1111 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1112 |
+
/* 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. */
|
1113 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to delete existing Amazon CloudFront Origin Access Identity. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1114 |
|
1115 |
+
else // Else, we use a default error code and message.
|
1116 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Unable to delete existing Amazon CloudFront Origin Access Identity. Connection failed.', 's2member-admin', 's2member'));
|
1117 |
+
}
|
1118 |
+
else // Else, we use a default error code and message.
|
1119 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to delete existing Amazon CloudFront Origin Access Identity. Invalid Access ID, ETag, or XML config.', 's2member-admin', 's2member'));
|
1120 |
+
}
|
1121 |
|
1122 |
+
/**
|
1123 |
+
* Creates an Amazon S3/CloudFront Access Origin Identity for all Distros.
|
1124 |
+
*
|
1125 |
+
* @package s2Member\Files
|
1126 |
+
* @since 110926
|
1127 |
+
*
|
1128 |
+
* @return array Array containing a true `success` and `distros_access_id`, `distros_s3_access_id` elements on success, else a failure array.
|
1129 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
1130 |
+
*/
|
1131 |
+
public static function amazon_cf_create_distros_access_origin_identity()
|
1132 |
+
{
|
1133 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
1134 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
1135 |
+
$cfc[$option] = $option_value;
|
1136 |
+
|
1137 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
1138 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
1139 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
1140 |
+
|
1141 |
+
$cf_domain = 'cloudfront.amazonaws.com';
|
1142 |
+
$cf_date = gmdate('D, d M Y H:i:s').' GMT';
|
1143 |
+
$cf_location = '/2010-11-01/origin-access-identity/cloudfront';
|
1144 |
+
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1145 |
+
$cf_distros_access_reference = time().'.'.md5('access'.$s3c['bucket'].$s3c['access_key'].$s3c['secret_key'].$cfc['private_key'].$cfc['private_key_id']);
|
1146 |
+
$cf_distros_access_xml = '<?xml version="1.0" encoding="UTF-8"?><CloudFrontOriginAccessIdentityConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/"><CallerReference>'.esc_html($cf_distros_access_reference).'</CallerReference><Comment>'.esc_html(sprintf(_x('Created by s2Member, for S3 Bucket: %s.', 's2member-admin', 's2member'), $s3c['bucket'])).'</Comment></CloudFrontOriginAccessIdentityConfig>';
|
1147 |
+
$cf_args = array('method' => 'POST', 'redirection' => 5, 'body' => $cf_distros_access_xml, 'headers' => array('Host' => $cf_domain, 'Content-Type' => 'application/xml', 'Date' => $cf_date, 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
1148 |
+
|
1149 |
+
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$cf_domain.$cf_location, FALSE, array_merge($cf_args, array('timeout' => 20)), 'array')) && ($cf_response['code'] === 200 || $cf_response['code'] === 201))
|
1150 |
+
{
|
1151 |
+
if(preg_match('/\<CloudFrontOriginAccessIdentity.*?\>(.+?)\<\/CloudFrontOriginAccessIdentity\>/is', $cf_response['body'], $cf_distros_access_tag) && preg_match('/\<Id\>(.+?)\<\/Id\>/is', $cf_distros_access_tag[1], $cf_distros_access_id_tag) && preg_match('/\<S3CanonicalUserId\>(.+?)\<\/S3CanonicalUserId\>/is', $cf_distros_access_tag[1], $cf_distros_s3_access_id_tag))
|
1152 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL, 'distros_access_id' => trim($cf_distros_access_id_tag[1]), 'distros_s3_access_id' => trim($cf_distros_s3_access_id_tag[1]));
|
1153 |
|
1154 |
+
else // Else, we use a default error code and message.
|
1155 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Unable to create/read Amazon CloudFront Origin Access Identity. Unexpected response.', 's2member-admin', 's2member'));
|
1156 |
+
}
|
1157 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1158 |
+
/* 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. */
|
1159 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to create Amazon CloudFront Origin Access Identity. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1160 |
|
1161 |
+
else // Else, we use a default error code and message.
|
1162 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to create Amazon CloudFront Origin Access Identity. Connection failed.', 's2member-admin', 's2member'));
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
/**
|
1166 |
+
* Acquires an Amazon S3/CloudFront Distro.
|
1167 |
+
*
|
1168 |
+
* @package s2Member\Files
|
1169 |
+
* @since 110926
|
1170 |
+
*
|
1171 |
+
* @param string $distro_id Required. A Distro ID.
|
1172 |
+
* @param string $distro_type Required: `downloads|streaming`.
|
1173 |
+
*
|
1174 |
+
* @return array Array containing a true `success` and `etag`, `xml`, `deployed` elements on success, else a failure array.
|
1175 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
1176 |
+
*/
|
1177 |
+
public static function amazon_cf_get_distro($distro_id = '', $distro_type = '')
|
1178 |
+
{
|
1179 |
+
if($distro_id && is_string($distro_id) && $distro_type && is_string($distro_type) && in_array($distro_type, array('downloads', 'streaming')))
|
1180 |
+
{
|
1181 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
1182 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
1183 |
+
$cfc[$option] = $option_value;
|
1184 |
+
|
1185 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
1186 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
1187 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
1188 |
+
|
1189 |
+
$cf_domain = 'cloudfront.amazonaws.com';
|
1190 |
+
$cf_date = gmdate('D, d M Y H:i:s').' GMT';
|
1191 |
+
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1192 |
+
$cf_location = ($distro_type === 'streaming') ? '/2010-11-01/streaming-distribution/'.$distro_id : '/2010-11-01/distribution/'.$distro_id;
|
1193 |
+
$cf_args = array('method' => 'GET', 'redirection' => 5, 'headers' => array('Host' => $cf_domain, 'Date' => $cf_date, 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
1194 |
+
|
1195 |
+
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$cf_domain.$cf_location, FALSE, array_merge($cf_args, array('timeout' => 20)), 'array')) && (($cf_response['code'] === 404 && $cf_response['message']) || ($cf_response['code'] === 200 && !empty($cf_response['headers']['etag']) && !empty($cf_response['body']))))
|
1196 |
+
{
|
1197 |
+
if($cf_response['code'] === 200 && !empty($cf_response['headers']['etag']) && !empty($cf_response['body']))
|
1198 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL, 'etag' => trim($cf_response['headers']['etag']), 'xml' => trim($cf_response['body']), 'deployed' => ((stripos($cf_response['body'], '<Status>Deployed</Status>') !== FALSE) ? TRUE : FALSE));
|
1199 |
+
|
1200 |
+
else /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1201 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Existing Amazon CloudFront Distro NOT found. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1202 |
+
}
|
1203 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1204 |
+
/* 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. */
|
1205 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to acquire existing Amazon CloudFront Distro. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1206 |
+
|
1207 |
+
else // Else, we use a default error code and message.
|
1208 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Unable to acquire existing Amazon CloudFront Distro. Connection failed.', 's2member-admin', 's2member'));
|
1209 |
+
}
|
1210 |
+
else // Else, we use a default error code and message.
|
1211 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to acquire existing Amazon CloudFront Distro. Invalid Distro ID and/or Distro type.', 's2member-admin', 's2member'));
|
1212 |
+
}
|
1213 |
+
|
1214 |
+
/**
|
1215 |
+
* Disables an Amazon S3/CloudFront Distro.
|
1216 |
+
*
|
1217 |
+
* @package s2Member\Files
|
1218 |
+
* @since 110926
|
1219 |
+
*
|
1220 |
+
* @param string $distro_id Required. A Distro ID.
|
1221 |
+
* @param string $distro_id_etag Required. A Distro ETag header.
|
1222 |
+
* @param string $distro_id_xml Required. A Distro's XML configuration.
|
1223 |
+
*
|
1224 |
+
* @return array Array containing a true `success` and `etag`, `xml`, `deployed` elements on success, else a failure array.
|
1225 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
1226 |
+
*/
|
1227 |
+
public static function amazon_cf_disable_distro($distro_id = '', $distro_id_etag = '', $distro_id_xml = '')
|
1228 |
+
{
|
1229 |
+
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]))
|
1230 |
+
{
|
1231 |
+
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.
|
1232 |
+
{
|
1233 |
+
if(stripos($distro_id_xml, '<Status>Deployed</Status>') !== FALSE) // Check distro status before we even begin processing.
|
1234 |
{
|
1235 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
1236 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
1237 |
$cfc[$option] = $option_value;
|
1238 |
|
1239 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
1240 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
1241 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
1242 |
|
1243 |
+
$cf_domain = 'cloudfront.amazonaws.com';
|
1244 |
+
$cf_date = gmdate('D, d M Y H:i:s').' GMT';
|
1245 |
+
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1246 |
+
$cf_location = ($distro_id_type === 'streaming') ? '/2010-11-01/streaming-distribution/'.$distro_id.'/config' : '/2010-11-01/distribution/'.$distro_id.'/config';
|
1247 |
+
$cf_distro_xml = ($distro_id_type === 'streaming') ? '<?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></S3Origin><CallerReference>'.esc_html($distro_id_reference).'</CallerReference><Enabled>false</Enabled><TrustedSigners><Self/></TrustedSigners></StreamingDistributionConfig>' : '<?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></S3Origin><CallerReference>'.esc_html($distro_id_reference).'</CallerReference><Enabled>false</Enabled><TrustedSigners><Self/></TrustedSigners></DistributionConfig>';
|
1248 |
+
$cf_args = array('method' => 'PUT', 'redirection' => 5, 'body' => $cf_distro_xml, 'headers' => array('Host' => $cf_domain, 'Content-Type' => 'application/xml', 'Date' => $cf_date, 'If-Match' => $distro_id_etag, 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
|
|
1249 |
|
1250 |
+
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 && !empty($cf_response['headers']['etag']) && !empty($cf_response['body']))
|
1251 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL, 'etag' => trim($cf_response['headers']['etag']), 'xml' => trim($cf_response['body']), 'deployed' => ((stripos($cf_response['body'], '<Status>Deployed</Status>') !== FALSE) ? TRUE : FALSE));
|
|
|
|
|
1252 |
|
1253 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
|
|
|
|
|
|
1254 |
/* 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. */
|
1255 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to disable existing Amazon CloudFront Distro. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1256 |
|
1257 |
else // Else, we use a default error code and message.
|
1258 |
+
return array('success' => FALSE, 'code' => -97, 'message' => _x('Unable to disable existing Amazon CloudFront Distro. Connection failed.', 's2member-admin', 's2member'));
|
1259 |
}
|
1260 |
+
else // Else, we use a default error code and message.
|
1261 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Existing Amazon CloudFront Distro cannot be disabled at this time. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member\'s auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.', 's2member-admin', 's2member'));
|
1262 |
+
}
|
1263 |
+
else // Else, we use a default error code and message.
|
1264 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL, 'etag' => $distro_id_etag, 'xml' => $distro_id_xml, 'deployed' => ((stripos($distro_id_xml, '<Status>Deployed</Status>') !== FALSE) ? TRUE : FALSE));
|
1265 |
+
}
|
1266 |
+
else // Else, we use a default error code and message.
|
1267 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to disable existing Amazon CloudFront Distro. Invalid Distro ID, ETag, or XML config.', 's2member-admin', 's2member'));
|
1268 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1269 |
|
1270 |
+
/**
|
1271 |
+
* Deletes an Amazon S3/CloudFront Distro.
|
1272 |
+
*
|
1273 |
+
* @package s2Member\Files
|
1274 |
+
* @since 110926
|
1275 |
+
*
|
1276 |
+
* @param string $distro_id Required. A Distro ID.
|
1277 |
+
* @param string $distro_id_etag Required. A Distro ETag header.
|
1278 |
+
* @param string $distro_id_xml Required. A Distro's XML configuration.
|
1279 |
+
*
|
1280 |
+
* @return array Array containing a true `success` element on success, else a failure array.
|
1281 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
1282 |
+
*/
|
1283 |
+
public static function amazon_cf_del_distro($distro_id = '', $distro_id_etag = '', $distro_id_xml = '')
|
1284 |
+
{
|
1285 |
+
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]))
|
1286 |
+
{
|
1287 |
+
if(stripos($distro_id_xml, '<Status>Deployed</Status>') !== FALSE) // Check distro status before we even begin processing this deletion.
|
1288 |
+
{
|
1289 |
+
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_disable_distro($distro_id, $distro_id_etag, $distro_id_xml)) && $cf_response['success'])
|
1290 |
{
|
1291 |
+
if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro($distro_id, $distro_id_type)) && $cf_response['success'] && $cf_response['deployed'])
|
1292 |
+
{
|
1293 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
1294 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
1295 |
+
$cfc[$option] = $option_value;
|
1296 |
+
|
1297 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
1298 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
1299 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
1300 |
+
|
1301 |
+
$cf_domain = 'cloudfront.amazonaws.com';
|
1302 |
+
$cf_date = gmdate('D, d M Y H:i:s').' GMT';
|
1303 |
+
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1304 |
+
$cf_location = ($distro_id_type === 'streaming') ? '/2010-11-01/streaming-distribution/'.$distro_id : '/2010-11-01/distribution/'.$distro_id;
|
1305 |
+
$cf_args = array('method' => 'DELETE', 'redirection' => 5, 'headers' => array('Host' => $cf_domain, 'Date' => $cf_date, 'If-Match' => $cf_response['etag'], 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
1306 |
+
|
1307 |
+
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))
|
1308 |
+
return array('success' => TRUE, 'code' => NULL, 'message' => NULL); // Deleted successfully.
|
1309 |
+
|
1310 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1311 |
+
/* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon CloudFront API call. Feel free to exclude `%s` if you like. */
|
1312 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to delete existing Amazon CloudFront Distro. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1313 |
+
|
1314 |
+
else // Else, we use a default error code and message.
|
1315 |
+
return array('success' => FALSE, 'code' => -94, 'message' => _x('Unable to delete existing Amazon CloudFront Distro. Connection failed.', 's2member-admin', 's2member'));
|
1316 |
+
}
|
1317 |
+
else if(isset($cf_response['success'], $cf_response['deployed']) && $cf_response['success'] && !$cf_response['deployed'])
|
1318 |
+
/* 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. */
|
1319 |
+
return array('success' => FALSE, 'code' => -95, 'message' => _x('Existing Amazon CloudFront Distro cannot be deleted at this time. Still in a `pending` state after having been disabled by s2Member. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member\'s auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.', 's2member-admin', 's2member'));
|
1320 |
|
1321 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1322 |
+
/* 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. */
|
1323 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to check status of existing Amazon CloudFront Distro. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1324 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1325 |
else // Else, we use a default error code and message.
|
1326 |
+
return array('success' => FALSE, 'code' => -96, 'message' => _x('Unable to check status of existing Amazon CloudFront Distro. Connection failed.', 's2member-admin', 's2member'));
|
1327 |
}
|
1328 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1329 |
+
/* 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. */
|
1330 |
+
return array('success' => FALSE, 'code' => $cf_response['code'], 'message' => sprintf(_x('Unable to disable existing Amazon CloudFront Distro. %s', 's2member-admin', 's2member'), $cf_response['message']));
|
1331 |
+
|
1332 |
+
else // Else, we use a default error code and message.
|
1333 |
+
return array('success' => FALSE, 'code' => -97, 'message' => _x('Unable to disable existing Amazon CloudFront Distro. Connection failed.', 's2member-admin', 's2member'));
|
1334 |
+
}
|
1335 |
+
else // Else, we use a default error code and message.
|
1336 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Existing Amazon CloudFront Distro cannot be deleted at this time. Still in a `pending` state. Please wait 15 minutes, then try again. There is a certain process that s2Member must strictly adhere to when re-configuring your Amazon CloudFront Distros. You may have to tick the auto-configure checkbox again, and re-run s2Member\'s auto-configuration routine many times, because s2Member will likely run into several `pending` challenges, as it works to completely re-configure your Amazon CloudFront Distros for you. Thanks for your patience. Please wait 15 minutes, then try again.', 's2member-admin', 's2member'));
|
1337 |
+
}
|
1338 |
+
else // Else, we use a default error code and message.
|
1339 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to delete existing Amazon CloudFront Distro. Invalid Distro ID or ETag.', 's2member-admin', 's2member'));
|
1340 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1341 |
|
1342 |
+
/**
|
1343 |
+
* Creates an Amazon S3/CloudFront Distro.
|
1344 |
+
*
|
1345 |
+
* @package s2Member\Files
|
1346 |
+
* @since 110926
|
1347 |
+
*
|
1348 |
+
* @param string $distro_type Required: `downloads|streaming`.
|
1349 |
+
*
|
1350 |
+
* @return array Array containing a true `success` and `distro_[distro_type]_id`, `distro_[distro_type]_dname` elements on success, else a failure array.
|
1351 |
+
* Failure array will contain a failure `code`, and a failure `message`.
|
1352 |
+
*/
|
1353 |
+
public static function amazon_cf_create_distro($distro_type = '')
|
1354 |
+
{
|
1355 |
+
if($distro_type && is_string($distro_type) && in_array($distro_type, array('downloads', 'streaming')))
|
1356 |
+
{
|
1357 |
+
foreach($GLOBALS['WS_PLUGIN__']['s2member']['o'] as $option => $option_value)
|
1358 |
+
if(preg_match('/^amazon_cf_files_/', $option) && ($option = preg_replace('/^amazon_cf_files_/', '', $option)))
|
1359 |
+
$cfc[$option] = $option_value;
|
1360 |
+
|
1361 |
+
$s3c['bucket'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_bucket'];
|
1362 |
+
$cfc['access_key'] = $s3c['access_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_access_key'];
|
1363 |
+
$cfc['secret_key'] = $s3c['secret_key'] = $GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_s3_files_secret_key'];
|
1364 |
+
|
1365 |
+
$cf_domain = 'cloudfront.amazonaws.com';
|
1366 |
+
$cf_date = gmdate('D, d M Y H:i:s').' GMT';
|
1367 |
+
$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
|
1368 |
+
|
1369 |
+
if($distro_type === 'downloads') // Create a `downloads` Distro? This uses a different XML schema.
|
1370 |
+
{
|
1371 |
+
$cf_location = '/2010-11-01/distribution'; // Create distro.
|
1372 |
+
$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']);
|
1373 |
+
$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>';
|
1374 |
+
$cf_args = array('method' => 'POST', 'redirection' => 5, 'body' => $cf_distro_downloads_xml, 'headers' => array('Host' => $cf_domain, 'Content-Type' => 'application/xml', 'Date' => $cf_date, 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
1375 |
+
|
1376 |
+
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$cf_domain.$cf_location, FALSE, array_merge($cf_args, array('timeout' => 20)), 'array')) && ($cf_response['code'] === 200 || $cf_response['code'] === 201))
|
1377 |
+
{
|
1378 |
+
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))
|
1379 |
+
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]));
|
1380 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1381 |
else // Else, we use a default error code and message.
|
1382 |
+
return array('success' => FALSE, 'code' => -97, 'message' => _x('Unable to create/read Amazon CloudFront Downloads Distro. Unexpected response.', 's2member-admin', 's2member'));
|
1383 |
}
|
1384 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1385 |
+
/* 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. */
|
1386 |
+
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']));
|
1387 |
+
|
1388 |
+
else // Else, we use a default error code and message.
|
1389 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Unable to create Amazon CloudFront Downloads Distro. Connection failed.', 's2member-admin', 's2member'));
|
1390 |
+
}
|
1391 |
+
else if($distro_type === 'streaming') // Create a `streaming` Distro? A different XML schema.
|
1392 |
+
{
|
1393 |
+
$cf_location = '/2010-11-01/streaming-distribution'; // Create streaming distro.
|
1394 |
+
$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']);
|
1395 |
+
$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>';
|
1396 |
+
$cf_args = array('method' => 'POST', 'redirection' => 5, 'body' => $cf_distro_streaming_xml, 'headers' => array('Host' => $cf_domain, 'Content-Type' => 'application/xml', 'Date' => $cf_date, 'Authorization' => 'AWS '.$cfc['access_key'].':'.$cf_signature));
|
1397 |
+
|
1398 |
+
if(($cf_response = c_ws_plugin__s2member_utils_urls::remote('https://'.$cf_domain.$cf_location, FALSE, array_merge($cf_args, array('timeout' => 20)), 'array')) && ($cf_response['code'] === 200 || $cf_response['code'] === 201))
|
1399 |
{
|
1400 |
+
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))
|
1401 |
+
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]));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1402 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1403 |
else // Else, we use a default error code and message.
|
1404 |
+
return array('success' => FALSE, 'code' => -97, 'message' => _x('Unable to create/read Amazon CloudFront Streaming Distro. Unexpected response.', 's2member-admin', 's2member'));
|
1405 |
}
|
1406 |
+
else if(isset($cf_response['code'], $cf_response['message']))
|
1407 |
+
/* 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. */
|
1408 |
+
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']));
|
1409 |
+
|
1410 |
+
else // Else, we use a default error code and message.
|
1411 |
+
return array('success' => FALSE, 'code' => -98, 'message' => _x('Unable to create Amazon CloudFront Streaming Distro. Connection failed.', 's2member-admin', 's2member'));
|
1412 |
+
}
|
1413 |
}
|
1414 |
+
// Else, we use a default error code and message (default behavior).
|
1415 |
+
return array('success' => FALSE, 'code' => -99, 'message' => _x('Unable to create Amazon CloudFront Distro. Invalid Distro type.', 's2member-admin', 's2member'));
|
1416 |
+
}
|
1417 |
+
|
1418 |
+
/**
|
1419 |
+
* Resets Amazon S3/CloudFront configuration.
|
1420 |
+
*
|
1421 |
+
* @package s2Member\Files
|
1422 |
+
* @since 140812
|
1423 |
+
*/
|
1424 |
+
public static function reset_aws_cf_config_values()
|
1425 |
+
{
|
1426 |
+
c_ws_plugin__s2member_menu_pages::update_all_options(
|
1427 |
+
array(
|
1428 |
+
'ws_plugin__s2member_amazon_cf_files_private_key' => '',
|
1429 |
+
'ws_plugin__s2member_amazon_cf_files_private_key_id' => '',
|
1430 |
+
'ws_plugin__s2member_amazon_cf_files_distros_access_id' => '',
|
1431 |
+
'ws_plugin__s2member_amazon_cf_files_distros_s3_access_id' => '',
|
1432 |
+
'ws_plugin__s2member_amazon_cf_files_distro_downloads_id' => '',
|
1433 |
+
'ws_plugin__s2member_amazon_cf_files_distro_downloads_cname' => '',
|
1434 |
+
'ws_plugin__s2member_amazon_cf_files_distro_downloads_dname' => '',
|
1435 |
+
'ws_plugin__s2member_amazon_cf_files_distro_streaming_id' => '',
|
1436 |
+
'ws_plugin__s2member_amazon_cf_files_distro_streaming_cname' => '',
|
1437 |
+
'ws_plugin__s2member_amazon_cf_files_distro_streaming_dname' => '',
|
1438 |
+
'ws_plugin__s2member_amazon_cf_files_distros_auto_config_status' => ''
|
1439 |
+
), TRUE, FALSE, FALSE, FALSE, FALSE
|
1440 |
+
);
|
1441 |
+
}
|
1442 |
}
|
1443 |
+
}
|
includes/classes/ip-restrictions.inc.php
CHANGED
@@ -76,8 +76,9 @@ if(!class_exists("c_ws_plugin__s2member_ip_restrictions"))
|
|
76 |
header /* Content-Type text/html with UTF-8. */("Content-Type: text/html; charset=UTF-8");
|
77 |
while (@ob_end_clean ()); // Clean any existing output buffers.
|
78 |
|
79 |
-
$custom_template = (
|
80 |
-
$custom_template = (
|
|
|
81 |
|
82 |
$msg_503 = trim(file_get_contents((($custom_template) ? $custom_template : dirname(dirname(__FILE__))."/templates/errors/ip-restrictions.php")));
|
83 |
$msg_503 = trim(((!$custom_template || !is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? c_ws_plugin__s2member_utilities::evl($msg_503) : $msg_503));
|
@@ -101,8 +102,9 @@ if(!class_exists("c_ws_plugin__s2member_ip_restrictions"))
|
|
101 |
header /* Content-Type text/html with UTF-8. */("Content-Type: text/html; charset=UTF-8");
|
102 |
while (@ob_end_clean ()); // Clean any existing output buffers.
|
103 |
|
104 |
-
$custom_template = (
|
105 |
-
$custom_template = (
|
|
|
106 |
|
107 |
$msg_503 = trim(file_get_contents((($custom_template) ? $custom_template : dirname(dirname(__FILE__))."/templates/errors/ip-restrictions.php")));
|
108 |
$msg_503 = trim(((!$custom_template || !is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? c_ws_plugin__s2member_utilities::evl($msg_503) : $msg_503));
|
@@ -113,7 +115,6 @@ if(!class_exists("c_ws_plugin__s2member_ip_restrictions"))
|
|
113 |
|
114 |
exit /* Clean exit with 503 error message. */($msg_503);
|
115 |
}
|
116 |
-
|
117 |
else // OK, this looks legitimate. Apply Filters here and return true.
|
118 |
{
|
119 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
@@ -123,7 +124,6 @@ if(!class_exists("c_ws_plugin__s2member_ip_restrictions"))
|
|
123 |
return apply_filters("ws_plugin__s2member_ip_restrictions_ok", true, get_defined_vars());
|
124 |
}
|
125 |
}
|
126 |
-
|
127 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
128 |
do_action("ws_plugin__s2member_during_ip_restrictions_ok_yes", get_defined_vars());
|
129 |
unset($__refs, $__v);
|
@@ -297,5 +297,4 @@ if(!class_exists("c_ws_plugin__s2member_ip_restrictions"))
|
|
297 |
exit(apply_filters("ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax", ((isset($success) && $success) ? "1" : "0"), get_defined_vars()));
|
298 |
}
|
299 |
}
|
300 |
-
}
|
301 |
-
?>
|
76 |
header /* Content-Type text/html with UTF-8. */("Content-Type: text/html; charset=UTF-8");
|
77 |
while (@ob_end_clean ()); // Clean any existing output buffers.
|
78 |
|
79 |
+
$custom_template = (is_file (TEMPLATEPATH . "/" . "ip-restrictions.php")) ? TEMPLATEPATH . "/" . "ip-restrictions.php" : '';
|
80 |
+
$custom_template = (is_file (get_stylesheet_directory() . "/" . "ip-restrictions.php")) ? get_stylesheet_directory() . "/" . "ip-restrictions.php" : $custom_template;
|
81 |
+
$custom_template = (is_file (WP_CONTENT_DIR . "/" . "ip-restrictions.php")) ? WP_CONTENT_DIR . "/" . "ip-restrictions.php" : $custom_template;
|
82 |
|
83 |
$msg_503 = trim(file_get_contents((($custom_template) ? $custom_template : dirname(dirname(__FILE__))."/templates/errors/ip-restrictions.php")));
|
84 |
$msg_503 = trim(((!$custom_template || !is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? c_ws_plugin__s2member_utilities::evl($msg_503) : $msg_503));
|
102 |
header /* Content-Type text/html with UTF-8. */("Content-Type: text/html; charset=UTF-8");
|
103 |
while (@ob_end_clean ()); // Clean any existing output buffers.
|
104 |
|
105 |
+
$custom_template = (is_file (TEMPLATEPATH . "/" . "ip-restrictions.php")) ? TEMPLATEPATH . "/" . "ip-restrictions.php" : '';
|
106 |
+
$custom_template = (is_file (get_stylesheet_directory() . "/" . "ip-restrictions.php")) ? get_stylesheet_directory() . "/" . "ip-restrictions.php" : $custom_template;
|
107 |
+
$custom_template = (is_file (WP_CONTENT_DIR . "/" . "ip-restrictions.php")) ? WP_CONTENT_DIR . "/" . "ip-restrictions.php" : $custom_template;
|
108 |
|
109 |
$msg_503 = trim(file_get_contents((($custom_template) ? $custom_template : dirname(dirname(__FILE__))."/templates/errors/ip-restrictions.php")));
|
110 |
$msg_503 = trim(((!$custom_template || !is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? c_ws_plugin__s2member_utilities::evl($msg_503) : $msg_503));
|
115 |
|
116 |
exit /* Clean exit with 503 error message. */($msg_503);
|
117 |
}
|
|
|
118 |
else // OK, this looks legitimate. Apply Filters here and return true.
|
119 |
{
|
120 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
124 |
return apply_filters("ws_plugin__s2member_ip_restrictions_ok", true, get_defined_vars());
|
125 |
}
|
126 |
}
|
|
|
127 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
128 |
do_action("ws_plugin__s2member_during_ip_restrictions_ok_yes", get_defined_vars());
|
129 |
unset($__refs, $__v);
|
297 |
exit(apply_filters("ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax", ((isset($success) && $success) ? "1" : "0"), get_defined_vars()));
|
298 |
}
|
299 |
}
|
300 |
+
}
|
|
includes/classes/list-servers.inc.php
CHANGED
@@ -457,6 +457,38 @@ if(!class_exists('c_ws_plugin__s2member_list_servers'))
|
|
457 |
return apply_filters('ws_plugin__s2member_process_list_server_removals', (isset ($removal_success) && $removal_success), get_defined_vars());
|
458 |
}
|
459 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
/**
|
461 |
* Listens to Collective EOT/MOD Events processed internally by s2Member.
|
462 |
*
|
457 |
return apply_filters('ws_plugin__s2member_process_list_server_removals', (isset ($removal_success) && $removal_success), get_defined_vars());
|
458 |
}
|
459 |
|
460 |
+
/**
|
461 |
+
* See {@link process_list_server_removals()} for further details about this wrapper.
|
462 |
+
*
|
463 |
+
* @param bool $opt_out Defaults to false; must be set to true. Indicates the User IS opting out.
|
464 |
+
* @param bool $clean_user_cache Defaults to true; i.e. we start from a fresh copy of the current user.
|
465 |
+
*
|
466 |
+
* @return bool True if at least one List Server removal is processed successfully, else false.
|
467 |
+
*/
|
468 |
+
public static function process_list_server_removals_against_current_user($opt_out = TRUE, $clean_user_cache = TRUE)
|
469 |
+
{
|
470 |
+
if($clean_user_cache) // Start from a fresh user object here?
|
471 |
+
{
|
472 |
+
clean_user_cache(get_current_user_id());
|
473 |
+
wp_cache_delete(get_current_user_id(), 'user_meta');
|
474 |
+
$user = new WP_User(get_current_user_id());
|
475 |
+
}
|
476 |
+
else $user = wp_get_current_user();
|
477 |
+
|
478 |
+
return self::process_list_server_removals(
|
479 |
+
($role = c_ws_plugin__s2member_user_access::user_access_role($user)),
|
480 |
+
($level = c_ws_plugin__s2member_user_access::user_access_level($user)),
|
481 |
+
($login = $user->user_login),
|
482 |
+
($pass = $user->user_pass),
|
483 |
+
($email = $user->user_email),
|
484 |
+
($fname = $user->first_name),
|
485 |
+
($lname = $user->last_name),
|
486 |
+
($ip = $_SERVER['REMOTE_ADDR']),
|
487 |
+
($opt_out = $opt_out),
|
488 |
+
($user_id = $user->ID)
|
489 |
+
);
|
490 |
+
}
|
491 |
+
|
492 |
/**
|
493 |
* Listens to Collective EOT/MOD Events processed internally by s2Member.
|
494 |
*
|
includes/classes/login-customizations.inc.php
CHANGED
@@ -99,16 +99,17 @@ if(!class_exists('c_ws_plugin__s2member_login_customizations'))
|
|
99 |
$i = apply_filters('ws_plugin__s2member_login_header_styles_important', ' !important', get_defined_vars());
|
100 |
$a = apply_filters('ws_plugin__s2member_login_header_styles_array_after_open', $a, get_defined_vars());
|
101 |
|
102 |
-
$a[] = 'html, body { border:0'.$i.'; background:none'.$i.'; }';
|
103 |
$a[] = 'html { background-color:#'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_color'].$i.'; }';
|
104 |
$a[] = 'html { background-image:url('.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image'].')'.$i.'; }';
|
105 |
$a[] = 'html { background-repeat:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image_repeat'].$i.'; }';
|
|
|
106 |
|
107 |
$a[] = 'body, body * { font-size:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_font_size'].$i.'; }';
|
108 |
$a[] = 'body, body * { font-family:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_font_family'].$i.'; }';
|
109 |
|
110 |
-
$a[] = 'div#login { width:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_logo_src_width'].'px'.$i.'; }';
|
111 |
-
$a[] = 'div#login h1 a { background:url('.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_logo_src'].') no-repeat top center'.$i.'; background-size:
|
112 |
$a[] = 'div#login h1 a { display:block'.$i.'; width:100%'.$i.'; height:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_logo_src_height'].'px'.$i.'; }';
|
113 |
|
114 |
$a[] = 'div#login form { box-shadow:1px 1px 2px #'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_box_shadow_color'].', -1px -1px 2px #'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_box_shadow_color'].$i.'; border-radius:5px'.$i.'; padding-bottom:16px'.$i.'; }';
|
99 |
$i = apply_filters('ws_plugin__s2member_login_header_styles_important', ' !important', get_defined_vars());
|
100 |
$a = apply_filters('ws_plugin__s2member_login_header_styles_array_after_open', $a, get_defined_vars());
|
101 |
|
102 |
+
$a[] = 'html, body { border:0'.$i.'; padding: 10px; background:none'.$i.'; }';
|
103 |
$a[] = 'html { background-color:#'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_color'].$i.'; }';
|
104 |
$a[] = 'html { background-image:url('.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image'].')'.$i.'; }';
|
105 |
$a[] = 'html { background-repeat:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_image_repeat'].$i.'; }';
|
106 |
+
$a[] = '@media (max-width: 767px) { html, body { background-size: contain '.$i.'; } }';
|
107 |
|
108 |
$a[] = 'body, body * { font-size:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_font_size'].$i.'; }';
|
109 |
$a[] = 'body, body * { font-family:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_font_family'].$i.'; }';
|
110 |
|
111 |
+
$a[] = 'div#login { width: 100% '.$i.'; max-width:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_logo_src_width'].'px'.$i.'; }';
|
112 |
+
$a[] = 'div#login h1 a { background:url('.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_logo_src'].') no-repeat top center'.$i.'; background-size:contain'.$i.'; }';
|
113 |
$a[] = 'div#login h1 a { display:block'.$i.'; width:100%'.$i.'; height:'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_logo_src_height'].'px'.$i.'; }';
|
114 |
|
115 |
$a[] = 'div#login form { box-shadow:1px 1px 2px #'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_box_shadow_color'].', -1px -1px 2px #'.$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_reg_background_box_shadow_color'].$i.'; border-radius:5px'.$i.'; padding-bottom:16px'.$i.'; }';
|
includes/classes/login-redirects.inc.php
CHANGED
@@ -1,206 +1,220 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* Login redirections.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Login_Redirects
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit (
|
19 |
-
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
* Handles login redirections.
|
32 |
-
*
|
33 |
-
* @package s2Member\Login_Redirects
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @attaches-to ``add_action("wp_login");``
|
37 |
-
*
|
38 |
-
* @param string $username Expects Username.
|
39 |
-
* @param WP_User $user Expects a WP_User object instance.
|
40 |
-
* @return null Or exits script execution after a redirection takes place.
|
41 |
-
*/
|
42 |
-
public static function login_redirect ($username = FALSE, $user = FALSE)
|
43 |
-
{
|
44 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
45 |
-
do_action("ws_plugin__s2member_before_login_redirect", get_defined_vars ());
|
46 |
-
unset($__refs, $__v);
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
update_user_option ($user_id, "s2member_last_login_time", time());
|
51 |
-
|
52 |
-
if /* Have we got this yet? */ (!get_user_option ("s2member_registration_ip", $user_id))
|
53 |
-
update_user_option ($user_id, "s2member_registration_ip", $_SERVER["REMOTE_ADDR"]);
|
54 |
-
|
55 |
-
if (($logins = (int)get_user_option ("s2member_login_counter", $user_id) + 1) >= 1 || ($logins = 1))
|
56 |
-
update_user_option ($user_id, "s2member_login_counter", $logins);
|
57 |
-
|
58 |
-
if /* Nag em? */ ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["custom_reg_password"])
|
59 |
-
delete_user_setting ("default_password_nag") . update_user_option ($user_id, "default_password_nag", false, true);
|
60 |
-
|
61 |
-
if (($ok = true) && !is_super_admin ($user_id) && $username !== "demo" // Exclude super admins, the `demo` user, and anyone who can edit posts.
|
62 |
-
&& !apply_filters("ws_plugin__s2member_disable_login_ip_restrictions", (($user->has_cap ("edit_posts")) ? true : false), get_defined_vars ()))
|
63 |
-
$ok = c_ws_plugin__s2member_ip_restrictions::ip_restrictions_ok ($_SERVER["REMOTE_ADDR"], strtolower($username));
|
64 |
-
|
65 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_always_http"]) // Alter value of `redirect_to`?
|
66 |
-
if(!empty($_REQUEST["redirect_to"]) && is_string ($_REQUEST["redirect_to"]) && strpos($_REQUEST["redirect_to"], "wp-admin") === FALSE)
|
67 |
-
{
|
68 |
-
$_REQUEST["redirect_to"] = preg_replace("/^https\:\/\//i", "http://", $_REQUEST["redirect_to"]);
|
69 |
-
if(stripos($_REQUEST["redirect_to"], "http://") !== 0) // Force an absolute URL in this case.
|
70 |
-
{
|
71 |
-
$home_path = trim((string)@parse_url(home_url('/'), PHP_URL_PATH), '/');
|
72 |
-
$http_home_base = trim(preg_replace('/\/'.preg_quote($home_path, '/').'\/$/', '', home_url('/', 'http')), '/');
|
73 |
-
$_REQUEST["redirect_to"] = $http_home_base.'/'.ltrim($_REQUEST["redirect_to"], '/');
|
74 |
-
}
|
75 |
-
}
|
76 |
-
if (($redirect = apply_filters("ws_plugin__s2member_login_redirect", (($user->has_cap ("edit_posts")) ? false : true), get_defined_vars ())))
|
77 |
-
{
|
78 |
-
$obey_redirect_to = apply_filters("ws_plugin__s2member_obey_login_redirect_to", /* By default, we obey this. */ true, get_defined_vars ());
|
79 |
-
|
80 |
-
if (!$obey_redirect_to || empty($_REQUEST["redirect_to"]) || !is_string ($_REQUEST["redirect_to"]) || $_REQUEST["redirect_to"] === admin_url () || preg_match ("/^\/?wp-admin\/?$/", $_REQUEST["redirect_to"]))
|
81 |
-
{
|
82 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
83 |
-
do_action("ws_plugin__s2member_during_login_redirect", get_defined_vars ());
|
84 |
-
unset($__refs, $__v);
|
85 |
-
|
86 |
-
if($redirect && is_string ($redirect)) $redirect = $redirect; // Custom?
|
87 |
-
|
88 |
-
else if ($redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url ($user))
|
89 |
-
$redirect = $redirection_url; // Special redirection URL (overrides LWP).
|
90 |
-
|
91 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"])
|
92 |
-
// Else we use the Login Welcome Page configured for s2Member.
|
93 |
-
$redirect = get_page_link ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]);
|
94 |
-
|
95 |
-
else $redirect = home_url("/"); // Default to the home page.
|
96 |
-
|
97 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_always_http"])
|
98 |
-
{
|
99 |
-
$redirect = preg_replace("/^https\:\/\//i", "http://", $redirect);
|
100 |
-
if(stripos($redirect, "http://") !== 0) // Force absolute.
|
101 |
-
{
|
102 |
-
$home_path = trim((string)@parse_url(home_url('/'), PHP_URL_PATH), '/');
|
103 |
-
$http_home_base = trim(preg_replace('/\/'.preg_quote($home_path, '/').'\/$/', '', home_url('/', 'http')), '/');
|
104 |
-
$redirect = $http_home_base.'/'.ltrim($redirect, '/');
|
105 |
-
}
|
106 |
-
}
|
107 |
-
wp_redirect($redirect).exit();
|
108 |
-
}
|
109 |
-
}
|
110 |
-
}
|
111 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
112 |
-
do_action("ws_plugin__s2member_after_login_redirect", get_defined_vars ());
|
113 |
-
unset($__refs, $__v);
|
114 |
-
|
115 |
-
return /* Return for uniformity. */;
|
116 |
-
}
|
117 |
-
/**
|
118 |
-
* Parses a Special Login Redirection URL.
|
119 |
-
*
|
120 |
-
* @package s2Member\Login_Redirects
|
121 |
-
* @since 3.5
|
122 |
-
*
|
123 |
-
* @param object $user Optional. A WP_User object. Defaults to the current User, if logged-in.
|
124 |
-
* @param bool $root_returns_false Defaults to false. True if the function should return false when a URL is reduced to the site root.
|
125 |
-
* @return str|bool A Special Login Redirection URL with Replacement Codes having been parsed, or false if ``$root_returns_false = true`` and the URL is the site root.
|
126 |
-
*/
|
127 |
-
public static function login_redirection_url ($user = FALSE, $root_returns_false = FALSE)
|
128 |
-
{
|
129 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
130 |
-
do_action("ws_plugin__s2member_before_login_redirection_url", get_defined_vars ());
|
131 |
-
unset($__refs, $__v);
|
132 |
|
133 |
-
|
134 |
-
|
135 |
|
136 |
-
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Parses a Special Login Redirection URI.
|
140 |
-
*
|
141 |
-
* @package s2Member\Login_Redirects
|
142 |
-
* @since 3.5
|
143 |
-
*
|
144 |
-
* @param object $user Optional. A WP_User object. Defaults to the current User, if logged-in.
|
145 |
-
* @param bool $root_returns_false Defaults to false. True if the function should return false when a URI is reduced to the site root.
|
146 |
-
* @return str|bool A Special Login Redirection URI with Replacement Codes having been parsed, or false if ``$root_returns_false = true`` and the URI is the site root.
|
147 |
-
*/
|
148 |
-
public static function login_redirection_uri ($user = FALSE, $root_returns_false = FALSE)
|
149 |
-
{
|
150 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
151 |
-
do_action("ws_plugin__s2member_before_login_redirection_uri", get_defined_vars ());
|
152 |
-
unset($__refs, $__v);
|
153 |
|
154 |
-
|
155 |
-
|
|
|
|
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
/**
|
160 |
-
* Fills Replacement Codes in Special Redirection URLs.
|
161 |
-
*
|
162 |
-
* @package s2Member\Login_Redirects
|
163 |
-
* @since 3.5
|
164 |
-
*
|
165 |
-
* @param string $url A URL with possible Replacement Codes in it.
|
166 |
-
* @param object $user Optional. A `WP_User` object. Defaults to the current User, if logged-in.
|
167 |
-
* @param bool $root_returns_false Defaults to false. True if the function should return false when a URL is reduced to the site root.
|
168 |
-
* @return str|bool A Special Login Redirection URL with Replacement Codes having been parsed, or false if ``$root_returns_false = true`` and the URL is the site root.
|
169 |
-
*/
|
170 |
-
public static function fill_login_redirect_rc_vars ($url = FALSE, $user = FALSE, $root_returns_false = FALSE)
|
171 |
{
|
172 |
-
|
173 |
-
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
|
176 |
-
|
177 |
-
$
|
178 |
|
179 |
-
|
|
|
|
|
180 |
|
181 |
-
|
182 |
-
|
|
|
|
|
|
|
183 |
|
184 |
-
$
|
185 |
-
$user_role = (string)c_ws_plugin__s2member_user_access::user_access_role ($user);
|
186 |
-
$user_ccaps = (string)implode ("-", c_ws_plugin__s2member_user_access::user_access_ccaps ($user));
|
187 |
-
$user_logins = ($user) ? (string)(int)get_user_option ("s2member_login_counter", $user_id) : "-1";
|
188 |
|
189 |
-
$
|
190 |
-
|
191 |
-
$url = preg_replace ("/%%current_user_level%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_level), $url);
|
192 |
-
$url = preg_replace ("/%%current_user_role%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_role), $url);
|
193 |
-
$url = preg_replace ("/%%current_user_ccaps%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_ccaps), $url);
|
194 |
-
$url = preg_replace ("/%%current_user_logins%%/i", c_ws_plugin__s2member_utils_strings::esc_refs ($user_logins), $url);
|
195 |
|
196 |
-
|
197 |
-
|
|
|
198 |
|
199 |
-
|
200 |
-
$url = /* In case we need to return false on root URLs (i.e. don't protect the Home Page inadvertently). */ false;
|
201 |
|
202 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
203 |
}
|
|
|
204 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
}
|
206 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Login redirections.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Login_Redirects
|
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_login_redirects'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* Login redirections.
|
24 |
+
*
|
25 |
+
* @package s2Member\Login_Redirects
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_login_redirects
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles login redirections.
|
32 |
+
*
|
33 |
+
* @package s2Member\Login_Redirects
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @attaches-to ``add_action('wp_login');``
|
37 |
+
*
|
38 |
+
* @param string $username Expects Username.
|
39 |
+
* @param WP_User $user Expects a WP_User object instance.
|
40 |
+
*
|
41 |
+
* @return null Or exits script execution after a redirection takes place.
|
42 |
+
*/
|
43 |
+
public static function login_redirect($username = '', $user = NULL)
|
44 |
+
{
|
45 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
46 |
+
do_action('ws_plugin__s2member_before_login_redirect', get_defined_vars());
|
47 |
+
unset($__refs, $__v); // Housekeeping.
|
48 |
+
|
49 |
+
if(is_string($username) && $username && is_object($user) && !empty($user->ID) && ($user_id = $user->ID))
|
50 |
{
|
51 |
+
update_user_option($user_id, 's2member_last_login_time', time());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
+
if(!get_user_option('s2member_registration_ip', $user_id))
|
54 |
+
update_user_option($user_id, 's2member_registration_ip', $_SERVER['REMOTE_ADDR']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
+
if(($logins = (int)get_user_option('s2member_login_counter', $user_id) + 1) >= 1 || ($logins = 1))
|
57 |
+
update_user_option($user_id, 's2member_login_counter', $logins);
|
58 |
|
59 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['custom_reg_password'])
|
60 |
+
delete_user_setting('default_password_nag').update_user_option($user_id, 'default_password_nag', FALSE, TRUE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
+
if(($ok = TRUE) && !is_super_admin($user_id) && $username !== 'demo' // Exclude super admins, the `demo` user, and anyone who can edit posts.
|
63 |
+
&& !apply_filters('ws_plugin__s2member_disable_login_ip_restrictions', (($user->has_cap('edit_posts')) ? TRUE : FALSE), get_defined_vars())
|
64 |
+
)
|
65 |
+
$ok = c_ws_plugin__s2member_ip_restrictions::ip_restrictions_ok($_SERVER['REMOTE_ADDR'], strtolower($username));
|
66 |
|
67 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_always_http']) // Alter value of `redirect_to`?
|
68 |
+
if(!empty($_REQUEST['redirect_to']) && is_string($_REQUEST['redirect_to']) && strpos($_REQUEST['redirect_to'], 'wp-admin') === FALSE)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
{
|
70 |
+
$_REQUEST['redirect_to'] = preg_replace('/^https\:\/\//i', 'http://', $_REQUEST['redirect_to']);
|
71 |
+
if(stripos($_REQUEST['redirect_to'], 'http://') !== 0) // Force an absolute URL in this case.
|
72 |
+
{
|
73 |
+
$home_path = trim((string)@parse_url(home_url('/'), PHP_URL_PATH), '/');
|
74 |
+
$http_home_base = trim(preg_replace('/\/'.preg_quote($home_path, '/').'\/$/', '', home_url('/', 'http')), '/');
|
75 |
+
$_REQUEST['redirect_to'] = $http_home_base.'/'.ltrim($_REQUEST['redirect_to'], '/');
|
76 |
+
}
|
77 |
+
}
|
78 |
+
if(($redirect = apply_filters('ws_plugin__s2member_login_redirect', (($user->has_cap('edit_posts')) ? FALSE : TRUE), get_defined_vars())))
|
79 |
+
{
|
80 |
+
$obey_redirect_to = apply_filters('ws_plugin__s2member_obey_login_redirect_to', TRUE, get_defined_vars());
|
81 |
|
82 |
+
if($obey_redirect_to && (empty($_REQUEST['redirect_to']) || !is_string($_REQUEST['redirect_to']) || $_REQUEST['redirect_to'] === admin_url() || preg_match('/^\/?wp-admin\/?$/', $_REQUEST['redirect_to'])))
|
83 |
+
$obey_redirect_to = FALSE; // Do not obey default redirect_to locations; like those inside the default admin area.
|
84 |
|
85 |
+
else if($obey_redirect_to && !empty($_REQUEST['redirect_to_automatic']) && is_string($redirect))
|
86 |
+
$obey_redirect_to = FALSE; // Do not obey automatic redirects when a custom redirection filter applies.
|
87 |
+
// ↑ NOTE: this will apply to s2Member Pro's One-Time-Offers (Upon Login) also.
|
88 |
|
89 |
+
if(!$obey_redirect_to) // Only if we are NOT obeying the `redirect_to` variable.
|
90 |
+
{
|
91 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
92 |
+
do_action('ws_plugin__s2member_during_login_redirect', get_defined_vars());
|
93 |
+
unset($__refs, $__v); // Housekeeping.
|
94 |
|
95 |
+
if($redirect && is_string($redirect)) $redirect = $redirect;
|
|
|
|
|
|
|
96 |
|
97 |
+
else if($redirection_url = c_ws_plugin__s2member_login_redirects::login_redirection_url($user))
|
98 |
+
$redirect = $redirection_url; // Special redirection URL (overrides LWP).
|
|
|
|
|
|
|
|
|
99 |
|
100 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'])
|
101 |
+
// Else we use the Login Welcome Page configured for s2Member.
|
102 |
+
$redirect = get_page_link($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page']);
|
103 |
|
104 |
+
else $redirect = home_url('/'); // Default to the home page.
|
|
|
105 |
|
106 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_always_http'])
|
107 |
+
{
|
108 |
+
$redirect = preg_replace('/^https\:\/\//i', 'http://', $redirect);
|
109 |
+
if(stripos($redirect, 'http://') !== 0) // Force absolute.
|
110 |
+
{
|
111 |
+
$home_path = trim((string)@parse_url(home_url('/'), PHP_URL_PATH), '/');
|
112 |
+
$http_home_base = trim(preg_replace('/\/'.preg_quote($home_path, '/').'\/$/', '', home_url('/', 'http')), '/');
|
113 |
+
$redirect = $http_home_base.'/'.ltrim($redirect, '/');
|
114 |
+
}
|
115 |
+
}
|
116 |
+
wp_redirect($redirect).exit();
|
117 |
}
|
118 |
+
}
|
119 |
}
|
120 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
121 |
+
do_action('ws_plugin__s2member_after_login_redirect', get_defined_vars());
|
122 |
+
unset($__refs, $__v); // Housekeeping.
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Parses a Special Login Redirection URL.
|
127 |
+
*
|
128 |
+
* @package s2Member\Login_Redirects
|
129 |
+
* @since 3.5
|
130 |
+
*
|
131 |
+
* @param object $user Optional. A WP_User object. Defaults to the current User, if logged-in.
|
132 |
+
* @param bool $root_returns_false Defaults to false. True if the function should return false when a URL is reduced to the site root.
|
133 |
+
*
|
134 |
+
* @return string|bool A Special Login Redirection URL with Replacement Codes having been parsed, or false if ``$root_returns_false = true`` and the URL is the site root.
|
135 |
+
*/
|
136 |
+
public static function login_redirection_url($user = NULL, $root_returns_false = FALSE)
|
137 |
+
{
|
138 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
139 |
+
do_action('ws_plugin__s2member_before_login_redirection_url', get_defined_vars());
|
140 |
+
unset($__refs, $__v); // Housekeeping.
|
141 |
+
|
142 |
+
$url = $GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_override'];
|
143 |
+
$url = c_ws_plugin__s2member_login_redirects::fill_login_redirect_rc_vars($url, $user, $root_returns_false);
|
144 |
+
|
145 |
+
return apply_filters('ws_plugin__s2member_login_redirection_url', $url, get_defined_vars());
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Parses a Special Login Redirection URI.
|
150 |
+
*
|
151 |
+
* @package s2Member\Login_Redirects
|
152 |
+
* @since 3.5
|
153 |
+
*
|
154 |
+
* @param object $user Optional. A WP_User object. Defaults to the current User, if logged-in.
|
155 |
+
* @param bool $root_returns_false Defaults to false. True if the function should return false when a URI is reduced to the site root.
|
156 |
+
*
|
157 |
+
* @return string|bool A Special Login Redirection URI with Replacement Codes having been parsed, or false if ``$root_returns_false = true`` and the URI is the site root.
|
158 |
+
*/
|
159 |
+
public static function login_redirection_uri($user = NULL, $root_returns_false = FALSE)
|
160 |
+
{
|
161 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
162 |
+
do_action('ws_plugin__s2member_before_login_redirection_uri', get_defined_vars());
|
163 |
+
unset($__refs, $__v); // Housekeeping.
|
164 |
+
|
165 |
+
if(($url = c_ws_plugin__s2member_login_redirects::login_redirection_url($user, $root_returns_false)))
|
166 |
+
$uri = c_ws_plugin__s2member_utils_urls::parse_uri($url);
|
167 |
+
|
168 |
+
return apply_filters('ws_plugin__s2member_login_redirection_uri', ((!empty($uri)) ? $uri : FALSE), get_defined_vars());
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Fills Replacement Codes in Special Redirection URLs.
|
173 |
+
*
|
174 |
+
* @package s2Member\Login_Redirects
|
175 |
+
* @since 3.5
|
176 |
+
*
|
177 |
+
* @param string $url A URL with possible Replacement Codes in it.
|
178 |
+
* @param object $user Optional. A `WP_User` object. Defaults to the current User, if logged-in.
|
179 |
+
* @param bool $root_returns_false Defaults to false. True if the function should return false when a URL is reduced to the site root.
|
180 |
+
*
|
181 |
+
* @return string|bool A Special Login Redirection URL with Replacement Codes having been parsed, or false if ``$root_returns_false = true`` and the URL is the site root.
|
182 |
+
*/
|
183 |
+
public static function fill_login_redirect_rc_vars($url = '', $user = NULL, $root_returns_false = FALSE)
|
184 |
+
{
|
185 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
186 |
+
do_action('ws_plugin__s2member_before_fill_login_redirect_rc_vars', get_defined_vars());
|
187 |
+
unset($__refs, $__v); // Housekeeping.
|
188 |
+
|
189 |
+
$url = (string)$url; // Force ``$url`` to a string value.
|
190 |
+
$orig_url = $url; // Record the original URL that was passed in.
|
191 |
+
|
192 |
+
$user = ((is_object($user) || is_object($user = (is_user_logged_in()) ? wp_get_current_user() : NULL)) && !empty($user->ID)) ? $user : NULL;
|
193 |
+
|
194 |
+
$user_id = ($user) ? (string)$user->ID : '';
|
195 |
+
$user_login = ($user) ? (string)strtolower($user->user_login) : '';
|
196 |
+
$user_nicename = ($user) ? (string)strtolower($user->user_nicename) : '';
|
197 |
+
|
198 |
+
$user_level = (string)c_ws_plugin__s2member_user_access::user_access_level($user);
|
199 |
+
$user_role = (string)c_ws_plugin__s2member_user_access::user_access_role($user);
|
200 |
+
$user_ccaps = (string)implode('-', c_ws_plugin__s2member_user_access::user_access_ccaps($user));
|
201 |
+
$user_logins = ($user) ? (string)(int)get_user_option('s2member_login_counter', $user_id) : '-1';
|
202 |
+
|
203 |
+
$url = preg_replace('/%%current_user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_login)), $url);
|
204 |
+
$url = preg_replace('/%%current_user_nicename%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_nicename)), $url);
|
205 |
+
$url = preg_replace('/%%current_user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $url);
|
206 |
+
$url = preg_replace('/%%current_user_level%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_level)), $url);
|
207 |
+
$url = preg_replace('/%%current_user_role%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_role)), $url);
|
208 |
+
$url = preg_replace('/%%current_user_ccaps%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_ccaps)), $url);
|
209 |
+
$url = preg_replace('/%%current_user_logins%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_logins)), $url);
|
210 |
+
|
211 |
+
if($url !== $orig_url && (!($parse = c_ws_plugin__s2member_utils_urls::parse_url($url, -1, FALSE)) || (!empty($parse['path']) && strpos($parse['path'], '//') !== FALSE)))
|
212 |
+
$url = home_url('/'); // Defaults to Home Page. We don't return invalid URLs produced by empty Replacement Codes ( i.e. with `//` ).
|
213 |
+
|
214 |
+
if($root_returns_false && c_ws_plugin__s2member_utils_conds::is_site_root($url)) // Used by s2Member's security gate.
|
215 |
+
$url = FALSE; // In case we need to return false on root URLs (i.e. don't protect the Home Page inadvertently).
|
216 |
+
|
217 |
+
return apply_filters('ws_plugin__s2member_fill_login_redirect_rc_vars', $url, get_defined_vars());
|
218 |
+
}
|
219 |
}
|
220 |
+
}
|
includes/classes/menu-pages.inc.php
CHANGED
@@ -1,897 +1,842 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* Administrative menu pages.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Menu_Pages
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if(realpath(__FILE__) === realpath($_SERVER[
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if(!class_exists(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
* 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 |
-
*
|
42 |
-
* Can also be self-verified; and configured extensively with function parameters.
|
43 |
-
*
|
44 |
-
* @package s2Member\Menu_Pages
|
45 |
-
* @since 3.5
|
46 |
-
*
|
47 |
-
* @param array $new_options Optional. Force feed an array of new options. Defaults to ``$_POST`` vars.
|
48 |
-
* If ``$new_options`` are passed in, be SURE that you've already applied ``stripslashes_deep()``.
|
49 |
-
* @param bool $verified Optional. Defaults to false. If true, ``wp_verify_nonce()`` is skipped in this routine.
|
50 |
-
* @param bool $update_other Optional. Defaults to true. If false, other option-dependent routines will not be processed.
|
51 |
-
* @param bool|array $display_notices Optional. Defaults to true. Can be false, or an array of certain notices that can be displayed.
|
52 |
-
* @param bool|array $enqueue_notices Optional. Defaults to false. Can be true, or an array of certain notices that should be enqueued.
|
53 |
-
* @param bool $request_refresh Optional. Defaults to false. If true, resulting `success` notice will include a link to refresh the menu page.
|
54 |
-
* @return bool True if all s2Member options were updated successfully, else false.
|
55 |
-
*/
|
56 |
-
public static function update_all_options($new_options = FALSE, $verified = FALSE, $update_other = TRUE, $display_notices = TRUE, $enqueue_notices = FALSE, $request_refresh = FALSE)
|
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 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
-
|
65 |
-
|
66 |
-
$options = /* Acquire the full existing configuration options array here. */ $GLOBALS["WS_PLUGIN__"]["s2member"]["o"];
|
67 |
|
68 |
-
|
69 |
-
|
70 |
|
71 |
-
|
72 |
-
|
73 |
|
74 |
-
|
75 |
-
|
76 |
|
77 |
-
|
78 |
-
$options[preg_replace("/^".preg_quote("ws_plugin__s2member_", "/")."/", "", $key)] = $value;
|
79 |
|
80 |
-
|
|
|
|
|
81 |
|
82 |
-
|
83 |
-
|
84 |
-
unset($__refs, $__v);
|
85 |
|
86 |
-
|
87 |
-
|
88 |
|
89 |
-
|
90 |
-
|
91 |
|
92 |
-
|
93 |
-
|
|
|
|
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
if(!$options["membership_options_page"] && ($display_notices === true || in_array("page-conflict-warnings", (array)$display_notices)) && ($notice = '<strong>NOTE:</strong> s2Member security restrictions will NOT be enforced until you\'ve configured a Membership Options Page. See: <code>s2Member -› General Options -› Membership Options Page</code>.'))
|
98 |
-
($enqueue_notices === true || in_array("page-conflict-warnings", (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, "*:*", true) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, true);
|
99 |
|
100 |
-
|
101 |
-
|
102 |
|
103 |
-
|
104 |
-
|
105 |
|
106 |
-
|
107 |
-
|
108 |
|
109 |
-
|
110 |
-
|
111 |
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
|
115 |
-
|
116 |
-
|
117 |
-
}
|
118 |
-
$updated_all_options = /* Flag indicating this routine was processed successfully; and that all s2Member options have been updated successfully.*/ true;
|
119 |
-
}
|
120 |
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
-
|
126 |
-
}
|
127 |
-
/**
|
128 |
-
* Adds option menus / sub-menus.
|
129 |
-
*
|
130 |
-
* @package s2Member\Menu_Pages
|
131 |
-
* @since 3.5
|
132 |
-
*
|
133 |
-
* @attaches-to ``add_action("admin_menu");``
|
134 |
-
*
|
135 |
-
* @return null
|
136 |
-
*/
|
137 |
-
public static function add_admin_options()
|
138 |
-
{
|
139 |
-
do_action("ws_plugin__s2member_before_add_admin_options", get_defined_vars());
|
140 |
|
141 |
-
|
|
|
|
|
142 |
|
143 |
-
|
144 |
-
|
145 |
-
if((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) || apply_filters("ws_plugin__s2member_during_add_admin_options_clear_right_side", false, get_defined_vars()))
|
146 |
-
$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["menu_pages"] = /* Clear right side. */ array();
|
147 |
|
148 |
-
|
|
|
149 |
|
150 |
-
|
151 |
-
|
152 |
-
"create_users", $menu, "c_ws_plugin__s2member_menu_pages::start_page", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]."/images/brand-favicon.png");
|
153 |
|
154 |
-
|
155 |
-
|
156 |
|
157 |
-
|
158 |
-
|
159 |
|
160 |
-
|
161 |
-
|
162 |
|
163 |
-
|
164 |
-
|
165 |
|
166 |
-
|
167 |
-
|
168 |
|
169 |
-
|
170 |
-
|
171 |
|
172 |
-
|
173 |
-
|
174 |
|
175 |
-
|
176 |
-
|
177 |
|
178 |
-
|
179 |
-
|
180 |
|
181 |
-
|
182 |
-
|
183 |
|
184 |
-
|
185 |
-
|
186 |
|
187 |
-
|
188 |
-
|
189 |
|
190 |
-
|
191 |
-
|
192 |
|
193 |
-
|
194 |
-
|
195 |
|
196 |
-
|
197 |
-
|
198 |
|
199 |
-
|
200 |
-
|
201 |
|
202 |
-
|
203 |
-
|
204 |
|
205 |
-
|
206 |
-
|
|
|
|
|
207 |
|
208 |
-
|
209 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
|
211 |
-
|
212 |
-
add_submenu_page($menu, "s2Member Information", "s2Member Info", "create_users", "ws-plugin--s2member-info", "c_ws_plugin__s2member_menu_pages::info_page");
|
213 |
|
214 |
-
|
215 |
-
}
|
216 |
|
217 |
-
|
218 |
|
219 |
-
|
220 |
-
|
221 |
-
/**
|
222 |
-
* Adds network option menus / sub-menus.
|
223 |
-
*
|
224 |
-
* @package s2Member\Menu_Pages
|
225 |
-
* @since 3.5
|
226 |
-
*
|
227 |
-
* @attaches-to ``add_action("network_admin_menu");``
|
228 |
-
*
|
229 |
-
* @return null
|
230 |
-
*/
|
231 |
-
public static function add_network_admin_options()
|
232 |
-
{
|
233 |
-
do_action("ws_plugin__s2member_before_add_network_admin_options", get_defined_vars());
|
234 |
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
|
240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
|
242 |
-
|
|
|
|
|
|
|
|
|
|
|
243 |
|
244 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
|
246 |
-
|
247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
|
249 |
-
|
250 |
-
|
|
|
|
|
251 |
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
* A sort of callback function to add the settings link.
|
258 |
-
*
|
259 |
-
* @package s2Member\Menu_Pages
|
260 |
-
* @since 3.5
|
261 |
-
*
|
262 |
-
* @attaches-to ``add_filter("plugin_action_links");``
|
263 |
-
*
|
264 |
-
* @param array $actions Expects an existing array of actions links, passed in by the Filter.
|
265 |
-
* @param string $plugin_file Expects path to a plugin file. We need to test against this for s2Member.
|
266 |
-
* @return array An array of links, Filtered by this routine.
|
267 |
-
*/
|
268 |
-
public static function _add_settings_link($actions = FALSE, $plugin_file = FALSE)
|
269 |
-
{
|
270 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
271 |
-
do_action("_ws_plugin__s2member_before_add_settings_link", get_defined_vars());
|
272 |
-
unset($__refs, $__v);
|
273 |
|
274 |
-
|
275 |
-
|
276 |
-
$settings = '<a href="'.esc_attr(admin_url("/admin.php?page=ws-plugin--s2member-gen-ops")).'">Settings</a>';
|
277 |
-
array_unshift($actions, apply_filters("ws_plugin__s2member_add_settings_link", $settings, get_defined_vars()));
|
278 |
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
}
|
283 |
|
284 |
-
|
285 |
-
}
|
286 |
-
/**
|
287 |
-
* Enqueue scripts for administrative menu pages.
|
288 |
-
*
|
289 |
-
* @package s2Member\Menu_Pages
|
290 |
-
* @since 3.5
|
291 |
-
*
|
292 |
-
* @attaches-to ``add_action("admin_print_scripts");``
|
293 |
-
*
|
294 |
-
* @return null
|
295 |
-
*/
|
296 |
-
public static function add_admin_scripts()
|
297 |
-
{
|
298 |
-
do_action("ws_plugin__s2member_before_add_admin_scripts", get_defined_vars());
|
299 |
|
300 |
-
|
301 |
-
{
|
302 |
-
wp_enqueue_script("jquery");
|
303 |
-
wp_enqueue_script("thickbox");
|
304 |
-
wp_enqueue_script("media-upload");
|
305 |
-
wp_enqueue_script("jquery-ui-core");
|
306 |
-
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());
|
307 |
-
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());
|
308 |
-
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());
|
309 |
-
wp_enqueue_script("ws-plugin--s2member-menu-pages", site_url("/?ws_plugin__s2member_menu_pages_js=".urlencode(mt_rand())), array("jquery", "thickbox", "media-upload", "jquery-sprintf", "jquery-json-ps", "jquery-ui-core", "jquery-ui-effects", "password-strength-meter"), c_ws_plugin__s2member_utilities::ver_checksum());
|
310 |
|
311 |
-
|
312 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
|
314 |
-
|
315 |
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
* Enqueue styles for administrative menu pages.
|
320 |
-
*
|
321 |
-
* @package s2Member\Menu_Pages
|
322 |
-
* @since 3.5
|
323 |
-
*
|
324 |
-
* @attaches-to ``add_action("admin_print_styles");``
|
325 |
-
*
|
326 |
-
* @return null
|
327 |
-
*/
|
328 |
-
public static function add_admin_styles()
|
329 |
-
{
|
330 |
-
do_action("ws_plugin__s2member_before_add_admin_styles", get_defined_vars());
|
331 |
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
336 |
|
337 |
-
|
338 |
-
|
|
|
339 |
|
340 |
-
|
|
|
341 |
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
* @since 120310
|
349 |
-
*
|
350 |
-
* @return null
|
351 |
-
*/
|
352 |
-
public static function log_file_downloader()
|
353 |
-
{
|
354 |
-
if(!current_user_can("create_users")) return;
|
355 |
-
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site())
|
356 |
-
return; // We do NOT provide this functionality on Child Blogs of a Blog Farm Network.
|
357 |
|
358 |
-
|
359 |
-
|
360 |
-
{
|
361 |
-
$logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"];
|
362 |
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
|
367 |
-
|
368 |
-
@ini_set("memory_limit", apply_filters("admin_memory_limit", WP_MAX_MEMORY_LIMIT));
|
369 |
|
370 |
-
|
371 |
-
if(function_exists("apache_setenv"))
|
372 |
-
@apache_setenv("no-gzip", "1");
|
373 |
|
374 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
|
376 |
-
|
377 |
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
header("Content-Length: ".strlen($log_file_contents));
|
382 |
-
header("Expires: ".gmdate("D, d M Y H:i:s", strtotime("-1 week"))." GMT");
|
383 |
-
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
384 |
-
header("Cache-Control: no-cache, must-revalidate, max-age=0");
|
385 |
-
header("Cache-Control: post-check=0, pre-check=0", false);
|
386 |
-
header("Pragma: no-cache");
|
387 |
|
388 |
-
|
389 |
|
390 |
-
|
391 |
-
}
|
392 |
-
}
|
393 |
-
/**
|
394 |
-
* Handles log file downloads (in ZIP format).
|
395 |
-
*
|
396 |
-
* @package s2Member\Menu_Pages
|
397 |
-
* @since 120310
|
398 |
-
*
|
399 |
-
* @return null
|
400 |
-
*/
|
401 |
-
public static function logs_zip_downloader()
|
402 |
-
{
|
403 |
-
if(!current_user_can("create_users")) return;
|
404 |
-
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site())
|
405 |
-
return; // We do NOT provide this functionality on Child Blogs of a Blog Farm Network.
|
406 |
-
|
407 |
-
if(!empty($_POST["ws_plugin__s2member_logs_download_zip"]) && is_string($nonce = $_POST["ws_plugin__s2member_logs_download_zip"]) && wp_verify_nonce($nonce, "ws-plugin--s2member-logs-download-zip"))
|
408 |
-
{
|
409 |
-
$logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"];
|
410 |
-
$s2member_logs_zip = $logs_dir."/".$_SERVER["HTTP_HOST"]."--s2member-logs.zip";
|
411 |
-
|
412 |
-
if(is_dir($logs_dir)) // Do we have a logs directory?
|
413 |
-
{
|
414 |
-
include_once ABSPATH . "wp-admin/includes/class-pclzip.php";
|
415 |
-
|
416 |
-
if(file_exists($s2member_logs_zip) && is_writable($s2member_logs_zip))
|
417 |
-
unlink($s2member_logs_zip);
|
418 |
-
|
419 |
-
$archive = new PclZip($s2member_logs_zip);
|
420 |
-
$archive->create($logs_dir, PCLZIP_OPT_REMOVE_ALL_PATH);
|
421 |
-
}
|
422 |
-
|
423 |
-
if(file_exists($s2member_logs_zip))
|
424 |
-
$s2member_logs_zip_size = filesize($s2member_logs_zip);
|
425 |
-
else $s2member_logs_zip_size = 0;
|
426 |
-
|
427 |
-
@set_time_limit(0);
|
428 |
-
@ini_set("memory_limit", apply_filters("admin_memory_limit", WP_MAX_MEMORY_LIMIT));
|
429 |
-
|
430 |
-
@ini_set("zlib.output_compression", 0);
|
431 |
-
if(function_exists("apache_setenv"))
|
432 |
-
@apache_setenv("no-gzip", "1");
|
433 |
-
|
434 |
-
while (@ob_end_clean ());
|
435 |
-
|
436 |
-
status_header(200); // 200 OK status header.
|
437 |
-
|
438 |
-
header("Content-Encoding: none");
|
439 |
-
header("Accept-Ranges: none");
|
440 |
-
header("Content-Type: application/zip");
|
441 |
-
header("Content-Length: ".$s2member_logs_zip_size);
|
442 |
-
header("Expires: ".gmdate("D, d M Y H:i:s", strtotime("-1 week"))." GMT");
|
443 |
-
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
|
444 |
-
header("Cache-Control: no-cache, must-revalidate, max-age=0");
|
445 |
-
header("Cache-Control: post-check=0, pre-check=0", false);
|
446 |
-
header("Pragma: no-cache");
|
447 |
-
|
448 |
-
header('Content-Disposition: attachment; filename="'.basename($s2member_logs_zip).'"');
|
449 |
-
|
450 |
-
if($s2member_logs_zip_size && is_resource($resource = fopen($s2member_logs_zip, "rb")))
|
451 |
-
{
|
452 |
-
$_bytes_to_read = $s2member_logs_zip_size; // Total bytes we need to read for this file.
|
453 |
-
|
454 |
-
$chunk_size = apply_filters("ws_plugin__s2member_file_downloads_chunk_size", 2097152, get_defined_vars());
|
455 |
-
|
456 |
-
while /* We have bytes to read here. */($_bytes_to_read)
|
457 |
-
{
|
458 |
-
$_bytes_to_read -= ($_reading = ($_bytes_to_read > $chunk_size) ? $chunk_size : $_bytes_to_read);
|
459 |
-
echo /* Serve file in chunks (default chunk size is 2MB). */ fread($resource, $_reading);
|
460 |
-
flush /* Flush each chunk to the browser as it is served (avoids high memory consumption). */();
|
461 |
-
}
|
462 |
-
fclose /* Close file resource handle. */($resource);
|
463 |
-
unset /* Housekeeping. */($_bytes_to_read, $_reading);
|
464 |
-
}
|
465 |
-
exit; // Clean exit after serving file.
|
466 |
-
}
|
467 |
-
}
|
468 |
-
/**
|
469 |
-
* Archives existing log files and starts fresh with new logs.
|
470 |
-
*
|
471 |
-
* @package s2Member\Menu_Pages
|
472 |
-
* @since 120310
|
473 |
-
*
|
474 |
-
* @return null
|
475 |
-
*/
|
476 |
-
public static function archive_logs_start_fresh()
|
477 |
{
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
if(!empty($_POST["ws_plugin__s2member_logs_archive_start_fresh"]) && is_string($nonce = $_POST["ws_plugin__s2member_logs_archive_start_fresh"]) && wp_verify_nonce($nonce, "ws-plugin--s2member-logs-archive-start-fresh"))
|
483 |
-
{
|
484 |
-
if(is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
|
485 |
-
foreach(scandir($logs_dir) as $log_file) // Archive existing log files here.
|
486 |
-
{
|
487 |
-
if(preg_match("/\.log$/", $log_file) && stripos($log_file, "-ARCHIVED-") === FALSE)
|
488 |
-
if(is_file ($log_dir_file = $logs_dir . "/" . $log_file) && is_writable($log_dir_file))
|
489 |
-
if(!rename ($log_dir_file, preg_replace ("/\.log$/i", "", $log_dir_file) . "-ARCHIVED-" . date ("m-d-Y") . "-" . time () . ".log"))
|
490 |
-
$error = true;
|
491 |
-
}
|
492 |
-
if(!empty($error))
|
493 |
-
c_ws_plugin__s2member_admin_notices::display_admin_notice("Unknown error when attempting to archive log files. Please check directory permissions.", true);
|
494 |
-
else c_ws_plugin__s2member_admin_notices::display_admin_notice("All log files have been archived succesfully.");
|
495 |
-
}
|
496 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
497 |
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
{
|
508 |
-
if(
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
if(!empty($_POST["ws_plugin__s2member_logs_delete_start_fresh"]) && is_string($nonce = $_POST["ws_plugin__s2member_logs_delete_start_fresh"]) && wp_verify_nonce($nonce, "ws-plugin--s2member-logs-delete-start-fresh"))
|
513 |
-
{
|
514 |
-
if(is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"]))
|
515 |
-
foreach(scandir($logs_dir) as $log_file) // Delete existing log files here.
|
516 |
-
{
|
517 |
-
if(preg_match("/\.log$/", $log_file))
|
518 |
-
if(is_file ($log_dir_file = $logs_dir . "/" . $log_file) && is_writable($log_dir_file))
|
519 |
-
if(!unlink($log_dir_file)) $error = true;
|
520 |
-
}
|
521 |
-
if(!empty($error))
|
522 |
-
c_ws_plugin__s2member_admin_notices::display_admin_notice("Unknown error when attempting to delete log files. Please check directory permissions.", true);
|
523 |
-
else c_ws_plugin__s2member_admin_notices::display_admin_notice("All log files have been deleted succesfully.");
|
524 |
-
}
|
525 |
}
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
*
|
532 |
-
* @return null
|
533 |
-
*/
|
534 |
-
public static function start_page()
|
535 |
-
{
|
536 |
-
do_action("ws_plugin__s2member_before_start_page", get_defined_vars());
|
537 |
-
|
538 |
-
include_once dirname(dirname(__FILE__))."/menu-pages/start.inc.php";
|
539 |
-
|
540 |
-
do_action("ws_plugin__s2member_after_start_page", get_defined_vars());
|
541 |
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
|
|
|
|
|
|
|
|
|
|
553 |
{
|
554 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
555 |
|
556 |
-
|
557 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
558 |
|
559 |
-
|
560 |
|
561 |
-
|
|
|
562 |
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
*/
|
573 |
-
public static function gen_ops_page()
|
574 |
-
{
|
575 |
-
do_action("ws_plugin__s2member_before_gen_ops_page", get_defined_vars());
|
576 |
|
577 |
-
|
|
|
578 |
|
579 |
-
|
580 |
|
581 |
-
|
|
|
582 |
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
*/
|
593 |
-
public static function res_ops_page()
|
594 |
-
{
|
595 |
-
do_action("ws_plugin__s2member_before_res_ops_page", get_defined_vars());
|
596 |
|
597 |
-
|
598 |
|
599 |
-
|
600 |
|
601 |
-
|
|
|
602 |
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
*/
|
613 |
-
public static function paypal_ops_page()
|
614 |
-
{
|
615 |
-
do_action("ws_plugin__s2member_before_paypal_ops_page", get_defined_vars());
|
616 |
|
617 |
-
|
618 |
|
619 |
-
|
620 |
|
621 |
-
|
622 |
-
|
623 |
|
624 |
-
|
625 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
626 |
|
627 |
-
|
628 |
-
file_put_contents($htaccess, $htaccess_contents).clearstatcache();
|
629 |
|
630 |
-
|
631 |
-
{
|
632 |
-
if /* If the security-enabled logs directory does not exist yet. */(!is_dir($logs_dir))
|
633 |
-
c_ws_plugin__s2member_admin_notices::display_admin_notice('The security-enabled logs directory (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($logs_dir)).'</code>) does not exist. Please create this directory manually & make it writable (chmod 777).', true);
|
634 |
|
635 |
-
|
636 |
-
|
637 |
|
638 |
-
|
639 |
-
|
640 |
|
641 |
-
|
642 |
-
|
643 |
-
}
|
644 |
|
645 |
-
|
|
|
|
|
|
|
646 |
|
647 |
-
|
|
|
648 |
|
649 |
-
|
650 |
-
|
651 |
-
/**
|
652 |
-
* Builds and handles the Download Options page.
|
653 |
-
*
|
654 |
-
* @package s2Member\Menu_Pages
|
655 |
-
* @since 3.5
|
656 |
-
*
|
657 |
-
* @return null
|
658 |
-
*/
|
659 |
-
public static function down_ops_page()
|
660 |
-
{
|
661 |
-
do_action("ws_plugin__s2member_before_down_ops_page", get_defined_vars());
|
662 |
|
663 |
-
|
|
|
|
|
|
|
664 |
|
665 |
-
|
|
|
666 |
|
667 |
-
|
668 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
669 |
|
670 |
-
|
671 |
-
|
672 |
|
673 |
-
|
674 |
-
|
675 |
|
676 |
-
|
677 |
-
|
678 |
|
679 |
-
|
680 |
-
|
681 |
|
682 |
-
|
683 |
-
|
684 |
|
685 |
-
|
686 |
-
|
687 |
|
688 |
-
|
689 |
-
|
690 |
|
691 |
-
|
692 |
-
|
693 |
|
694 |
-
|
695 |
-
|
696 |
-
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"]).' —» '.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"]).' —» '.esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_dname"]).'</code></em>' : ''));
|
697 |
-
else // Else there was an error. We need to report this back to the site owner so they can understand what's going on.
|
698 |
-
(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);
|
699 |
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
|
706 |
-
|
|
|
|
|
|
|
|
|
707 |
|
708 |
-
|
709 |
|
710 |
-
|
711 |
-
|
712 |
-
/**
|
713 |
-
* Builds and handles the API Tracking options page.
|
714 |
-
*
|
715 |
-
* @package s2Member\Menu_Pages
|
716 |
-
* @since 3.5
|
717 |
-
*
|
718 |
-
* @return null
|
719 |
-
*/
|
720 |
-
public static function trk_ops_page()
|
721 |
-
{
|
722 |
-
do_action("ws_plugin__s2member_before_trk_ops_page", get_defined_vars());
|
723 |
|
724 |
-
c_ws_plugin__s2member_menu_pages::update_all_options();
|
725 |
|
726 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
|
728 |
-
|
729 |
|
730 |
-
|
731 |
-
}
|
732 |
-
/**
|
733 |
-
* Builds and handles the API List Server options page.
|
734 |
-
*
|
735 |
-
* @package s2Member\Menu_Pages
|
736 |
-
* @since 3.5
|
737 |
-
*
|
738 |
-
* @return null
|
739 |
-
*/
|
740 |
-
public static function els_ops_page()
|
741 |
-
{
|
742 |
-
do_action("ws_plugin__s2member_before_els_ops_page", get_defined_vars());
|
743 |
|
744 |
-
|
|
|
745 |
|
746 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
747 |
|
748 |
-
|
749 |
|
750 |
-
|
751 |
-
}
|
752 |
-
/**
|
753 |
-
* Builds and handles the API Notifications page.
|
754 |
-
*
|
755 |
-
* @package s2Member\Menu_Pages
|
756 |
-
* @since 3.5
|
757 |
-
*
|
758 |
-
* @return null
|
759 |
-
*/
|
760 |
-
public static function api_ops_page()
|
761 |
-
{
|
762 |
-
do_action("ws_plugin__s2member_before_api_ops_page", get_defined_vars());
|
763 |
|
764 |
-
|
|
|
765 |
|
766 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
767 |
|
768 |
-
|
769 |
|
770 |
-
|
771 |
-
}
|
772 |
-
/**
|
773 |
-
* Builds and handles the PayPal Button Generator page.
|
774 |
-
*
|
775 |
-
* @package s2Member\Menu_Pages
|
776 |
-
* @since 3.5
|
777 |
-
*
|
778 |
-
* @return null
|
779 |
-
*/
|
780 |
-
public static function paypal_buttons_page()
|
781 |
-
{
|
782 |
-
do_action("ws_plugin__s2member_before_paypal_buttons_page", get_defined_vars());
|
783 |
|
784 |
-
|
785 |
-
|
786 |
|
787 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
788 |
|
789 |
-
|
|
|
790 |
|
791 |
-
|
792 |
-
}
|
793 |
-
/**
|
794 |
-
* Builds and handles the API Scripting page.
|
795 |
-
*
|
796 |
-
* @package s2Member\Menu_Pages
|
797 |
-
* @since 3.5
|
798 |
-
*
|
799 |
-
* @return null
|
800 |
-
*/
|
801 |
-
public static function scripting_page()
|
802 |
-
{
|
803 |
-
do_action("ws_plugin__s2member_before_scripting_page", get_defined_vars());
|
804 |
|
805 |
-
|
|
|
806 |
|
807 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
808 |
|
809 |
-
|
810 |
-
}
|
811 |
-
/**
|
812 |
-
* Builds and handles the Integrations page.
|
813 |
-
*
|
814 |
-
* @package s2Member\Menu_Pages
|
815 |
-
* @since 3.5
|
816 |
-
*
|
817 |
-
* @return null
|
818 |
-
*/
|
819 |
-
public static function integrations_page()
|
820 |
-
{
|
821 |
-
do_action("ws_plugin__s2member_before_integrations_page", get_defined_vars());
|
822 |
|
823 |
-
|
824 |
|
825 |
-
|
|
|
826 |
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
*/
|
837 |
-
public static function logs_page()
|
838 |
-
{
|
839 |
-
do_action("ws_plugin__s2member_before_logs_page", get_defined_vars());
|
840 |
|
841 |
-
|
842 |
-
c_ws_plugin__s2member_menu_pages::archive_logs_start_fresh();
|
843 |
-
c_ws_plugin__s2member_menu_pages::delete_logs_start_fresh();
|
844 |
|
845 |
-
|
|
|
846 |
|
847 |
-
|
848 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
849 |
|
850 |
-
|
851 |
-
|
|
|
852 |
|
853 |
-
|
854 |
-
file_put_contents($htaccess, $htaccess_contents).clearstatcache();
|
855 |
|
856 |
-
|
857 |
-
|
858 |
|
859 |
-
|
860 |
-
|
861 |
|
862 |
-
|
863 |
-
|
864 |
|
865 |
-
|
866 |
-
|
867 |
|
868 |
-
|
869 |
-
|
870 |
|
871 |
-
|
|
|
872 |
|
873 |
-
|
|
|
874 |
|
875 |
-
|
876 |
-
|
877 |
-
/**
|
878 |
-
* Builds and handles the s2Member Info page.
|
879 |
-
*
|
880 |
-
* @package s2Member\Menu_Pages
|
881 |
-
* @since 3.5
|
882 |
-
*
|
883 |
-
* @return null
|
884 |
-
*/
|
885 |
-
public static function info_page()
|
886 |
-
{
|
887 |
-
do_action("ws_plugin__s2member_before_info_page", get_defined_vars());
|
888 |
|
889 |
-
|
890 |
|
891 |
-
|
|
|
892 |
|
893 |
-
|
894 |
-
|
895 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
896 |
}
|
897 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Administrative menu pages.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Menu_Pages
|
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 |
+
{
|
22 |
+
/**
|
23 |
+
* Administrative menu pages.
|
24 |
+
*
|
25 |
+
* @package s2Member\Menu_Pages
|
26 |
+
* @since 3.5
|
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 |
+
/**
|
41 |
+
* Saves all options from any menu page.
|
42 |
+
*
|
43 |
+
* Can also be self-verified; and configured extensively with function parameters.
|
44 |
+
*
|
45 |
+
* @package s2Member\Menu_Pages
|
46 |
+
* @since 3.5
|
47 |
+
*
|
48 |
+
* @param null|array $new_options Optional. Force feed an array of new options. Defaults to ``$_POST`` vars.
|
49 |
+
* If ``$new_options`` are passed in, be SURE that you've already applied ``stripslashes_deep()``.
|
50 |
+
* @param bool $verified Optional. Defaults to false. If true, ``wp_verify_nonce()`` is skipped in this routine.
|
51 |
+
* @param bool $update_other Optional. Defaults to true. If false, other option-dependent routines will not be processed.
|
52 |
+
* @param bool|array $display_notices Optional. Defaults to true. Can be false, or an array of certain notices that can be displayed.
|
53 |
+
* @param bool|array $enqueue_notices Optional. Defaults to false. Can be true, or an array of certain notices that should be enqueued.
|
54 |
+
* @param bool $request_refresh Optional. Defaults to false. If true, resulting `success` notice will include a link to refresh the menu page.
|
55 |
+
*
|
56 |
+
* @return bool True if all s2Member options were updated successfully, else false.
|
57 |
+
*/
|
58 |
+
public static function update_all_options($new_options = NULL, $verified = FALSE, $update_other = TRUE, $display_notices = TRUE, $enqueue_notices = FALSE, $request_refresh = FALSE)
|
59 |
+
{
|
60 |
+
$updated_all_options = FALSE; // Initializing this variable here makes it an available reference-variable to Hooks/Filters.
|
61 |
+
|
62 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
63 |
+
do_action('ws_plugin__s2member_before_update_all_options', get_defined_vars()); // If you use this Hook, be sure to use ``wp_verify_nonce()``.
|
64 |
+
unset($__refs, $__v); // Housekeeping.
|
65 |
+
|
66 |
+
if($verified || (!empty($_POST['ws_plugin__s2member_options_save']) && ($nonce = $_POST['ws_plugin__s2member_options_save']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-options-save')))
|
67 |
+
{
|
68 |
+
$options = $GLOBALS['WS_PLUGIN__']['s2member']['o']; // Acquire the full existing configuration options array here.
|
69 |
|
70 |
+
$new_options = (is_array($new_options)) ? $new_options : ((!empty($_POST) && is_array($_POST)) ? stripslashes_deep($_POST) : array());
|
71 |
+
$new_options = c_ws_plugin__s2member_utils_strings::trim_deep($new_options);
|
|
|
72 |
|
73 |
+
foreach($new_options as $key => $value) // Find all keys contained within ``$new_options`` matching `^ws_plugin__s2member_`.
|
74 |
+
if(strpos($key, 'ws_plugin__s2member_') === 0) // A relevant ``$new_options`` key matching `^ws_plugin__s2member_`?
|
75 |
|
76 |
+
if($key === 'ws_plugin__s2member_configured') // s2Member is now configured (according to these options)?
|
77 |
+
($GLOBALS['WS_PLUGIN__']['s2member']['c']['configured'] = $value).update_option('ws_plugin__s2member_configured', $value);
|
78 |
|
79 |
+
else if(!is_array($value) || (is_array($value) && array_shift($value) === 'update-signal')) // Updating an array?
|
80 |
+
$options[preg_replace('/^'.preg_quote('ws_plugin__s2member_', '/').'/', '', $key)] = $value;
|
81 |
|
82 |
+
unset($key, $value); // Unset these utility variables now. This prevents bleeding vars into Hooks/Filters that are of no use.
|
|
|
83 |
|
84 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
85 |
+
do_action('ws_plugin__s2member_during_update_all_options', get_defined_vars());
|
86 |
+
unset($__refs, $__v); // Housekeeping.
|
87 |
|
88 |
+
$options = ws_plugin__s2member_configure_options_and_their_defaults(($options = array_merge($options, array('options_version' => (string)($options['options_version'] + 0.001)))));
|
89 |
+
update_option('ws_plugin__s2member_options', $options).((is_multisite() && is_main_site()) ? update_site_option('ws_plugin__s2member_options', $options) : NULL).update_option('ws_plugin__s2member_cache', array());
|
|
|
90 |
|
91 |
+
if($update_other === TRUE || in_array('auto_eot_system', (array)$update_other)) // Handle the Auto-EOT System now (enable/disable).
|
92 |
+
($options['auto_eot_system_enabled'] == 1) ? c_ws_plugin__s2member_auto_eots::add_auto_eot_system() : c_ws_plugin__s2member_auto_eots::delete_auto_eot_system();
|
93 |
|
94 |
+
if(($display_notices === TRUE || in_array('success', (array)$display_notices)) && ($notice = '<strong>Options saved.'.(($request_refresh) ? ' Please <a href="'.esc_attr($_SERVER['REQUEST_URI']).'">refresh</a>.' : '').'</strong>'))
|
95 |
+
($enqueue_notices === TRUE || in_array('success', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*') : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice);
|
96 |
|
97 |
+
if(empty($_GET['page']) || $_GET['page'] !== 'ws-plugin--s2member-mms-ops') // Do NOT display page-conflict-warnings on the Main Multisite Configuration panel.
|
98 |
+
{
|
99 |
+
if(!$options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array)$display_notices)) && ($notice = '<strong>NOTE:</strong> s2Member security restrictions will NOT be enforced until you\'ve configured a Membership Options Page. See: <code>s2Member -› General Options -› Membership Options Page</code>.'))
|
100 |
+
($enqueue_notices === TRUE || in_array('page-conflict-warnings', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
|
101 |
|
102 |
+
if($options['login_welcome_page'] && $options['login_welcome_page'] === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array)$display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is the same as your Membership Options Page. Please correct this. See: <code>s2Member -› General Options -› Login Welcome Page</code>.'))
|
103 |
+
($enqueue_notices === TRUE || in_array('page-conflict-warnings', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
|
|
|
|
|
104 |
|
105 |
+
if($options['membership_options_page'] && (string)get_option('page_on_front') === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array)$display_notices)) && ($notice = '<strong>s2Member:</strong> Your Membership Options Page is currently configured as your Home Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this. See: <code>WordPress -› Reading Options</code>. Or change: <code>s2Member -› General Options -› Membership Options Page</code>.'))
|
106 |
+
($enqueue_notices === TRUE || in_array('page-conflict-warnings', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
|
107 |
|
108 |
+
if($options['login_welcome_page'] && (string)get_option('page_on_front') === $options['login_welcome_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array)$display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is currently configured as your Home Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this. See: <code>WordPress -› Reading Options</code>. Or change: <code>s2Member -› General Options -› Login Welcome Page</code>.'))
|
109 |
+
($enqueue_notices === TRUE || in_array('page-conflict-warnings', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
|
110 |
|
111 |
+
if($options['membership_options_page'] && (string)get_option('page_for_posts') === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array)$display_notices)) && ($notice = '<strong>s2Member:</strong> Your Membership Options Page is currently configured as your Posts Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Membership Options Page MUST stand alone. Please correct this. See: <code>WordPress -› Reading Options</code>. Or change: <code>s2Member -› General Options -› Membership Options Page</code>.'))
|
112 |
+
($enqueue_notices === TRUE || in_array('page-conflict-warnings', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
|
113 |
|
114 |
+
if($options['login_welcome_page'] && (string)get_option('page_for_posts') === $options['login_welcome_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array)$display_notices)) && ($notice = '<strong>s2Member:</strong> Your Login Welcome Page is currently configured as your Posts Page (i.e. static page) for WordPress. This causes internal conflicts with s2Member. Your Login Welcome Page MUST stand alone. Please correct this. See: <code>WordPress -› Reading Options</code>. Or change: <code>s2Member -› General Options -› Login Welcome Page</code>.'))
|
115 |
+
($enqueue_notices === TRUE || in_array('page-conflict-warnings', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
|
116 |
|
117 |
+
if($options['file_download_limit_exceeded_page'] && $options['file_download_limit_exceeded_page'] === $options['membership_options_page'] && ($display_notices === TRUE || in_array('page-conflict-warnings', (array)$display_notices)) && ($notice = '<strong>s2Member:</strong> Your Download Limit Exceeded Page is the same as your Membership Options Page. Please correct this. See: <code>s2Member -› Download Options</code>.'))
|
118 |
+
($enqueue_notices === TRUE || in_array('page-conflict-warnings', (array)$enqueue_notices)) ? c_ws_plugin__s2member_admin_notices::enqueue_admin_notice($notice, '*:*', TRUE) : c_ws_plugin__s2member_admin_notices::display_admin_notice($notice, TRUE);
|
119 |
+
}
|
120 |
+
$updated_all_options = TRUE; // Flag indicating this routine was processed successfully; and that all s2Member options have been updated successfully.
|
121 |
+
}
|
122 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
123 |
+
do_action('ws_plugin__s2member_after_update_all_options', get_defined_vars());
|
124 |
+
unset($__refs, $__v); // Housekeeping.
|
125 |
|
126 |
+
return apply_filters('ws_plugin__s2member_update_all_options', (($updated_all_options) ? TRUE : FALSE), get_defined_vars());
|
127 |
+
}
|
|
|
|
|
|
|
128 |
|
129 |
+
/**
|
130 |
+
* Adds option menus / sub-menus.
|
131 |
+
*
|
132 |
+
* @package s2Member\Menu_Pages
|
133 |
+
* @since 3.5
|
134 |
+
*
|
135 |
+
* @attaches-to ``add_action('admin_menu');``
|
136 |
+
*/
|
137 |
+
public static function add_admin_options()
|
138 |
+
{
|
139 |
+
do_action('ws_plugin__s2member_before_add_admin_options', get_defined_vars());
|
140 |
+
|
141 |
+
add_filter('plugin_action_links', 'c_ws_plugin__s2member_menu_pages::_add_settings_link', 10, 2);
|
142 |
+
|
143 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_create_menu_items', TRUE, get_defined_vars()))
|
144 |
+
{
|
145 |
+
if((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) || apply_filters('ws_plugin__s2member_during_add_admin_options_clear_right_side', FALSE, get_defined_vars()))
|
146 |
+
$GLOBALS['WS_PLUGIN__']['s2member']['c']['menu_pages'] = array(); // Clear right side.
|
147 |
|
148 |
+
$menu = apply_filters('ws_plugin__s2member_during_add_admin_options_menu_slug', 'ws-plugin--s2member-start', get_defined_vars());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
|
150 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_menu_page', TRUE, get_defined_vars()))
|
151 |
+
add_menu_page(((c_ws_plugin__s2member_utils_conds::pro_is_installed()) ? 's2Member (Pro)' : 's2Member'), ((c_ws_plugin__s2member_utils_conds::pro_is_installed()) ? 's2Member (Pro)' : 's2Member'),
|
152 |
+
'create_users', $menu, 'c_ws_plugin__s2member_menu_pages::start_page', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/images/brand-favicon.png');
|
153 |
|
154 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_start_page', TRUE, get_defined_vars()))
|
155 |
+
add_submenu_page($menu, 's2Member Quick-Start Guide', 'Quick-Start Guide', 'create_users', 'ws-plugin--s2member-start', 'c_ws_plugin__s2member_menu_pages::start_page');
|
|
|
|
|
156 |
|
157 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_divider_1', TRUE, get_defined_vars()))
|
158 |
+
add_submenu_page($menu, '', '<span style="display:block; margin:1px 0 1px -5px; padding:0; height:1px; line-height:1px; background:#CCCCCC;"></span>', 'create_users', '#');
|
159 |
|
160 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_mms_ops_page', (!is_multisite() || is_main_site()), get_defined_vars()))
|
161 |
+
add_submenu_page($menu, 's2Member Multisite Configuration', 'Multisite (Config)', 'create_users', 'ws-plugin--s2member-mms-ops', 'c_ws_plugin__s2member_menu_pages::mms_ops_page');
|
|
|
162 |
|
163 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_gen_ops_page', TRUE, get_defined_vars()))
|
164 |
+
add_submenu_page($menu, 's2Member General Options', 'General Options', 'create_users', 'ws-plugin--s2member-gen-ops', 'c_ws_plugin__s2member_menu_pages::gen_ops_page');
|
165 |
|
166 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_res_ops_page', TRUE, get_defined_vars()))
|
167 |
+
add_submenu_page($menu, 's2Member Restriction Options', 'Restriction Options', 'create_users', 'ws-plugin--s2member-res-ops', 'c_ws_plugin__s2member_menu_pages::res_ops_page');
|
168 |
|
169 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_down_ops_page', (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars()))
|
170 |
+
add_submenu_page($menu, 's2Member Download Options', 'Download Options', 'create_users', 'ws-plugin--s2member-down-ops', 'c_ws_plugin__s2member_menu_pages::down_ops_page');
|
171 |
|
172 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_divider_2', TRUE, get_defined_vars()))
|
173 |
+
add_submenu_page($menu, '', '<span style="display:block; margin:1px 0 1px -5px; padding:0; height:1px; line-height:1px; background:#CCCCCC;"></span>', 'create_users', '#');
|
174 |
|
175 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_paypal_ops_page', TRUE, get_defined_vars()))
|
176 |
+
add_submenu_page($menu, 's2Member PayPal Options', 'PayPal Options', 'create_users', 'ws-plugin--s2member-paypal-ops', 'c_ws_plugin__s2member_menu_pages::paypal_ops_page');
|
177 |
|
178 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_paypal_buttons_page', TRUE, get_defined_vars()))
|
179 |
+
add_submenu_page($menu, 's2Member PayPal Buttons', 'PayPal Buttons', 'create_users', 'ws-plugin--s2member-paypal-buttons', 'c_ws_plugin__s2member_menu_pages::paypal_buttons_page');
|
180 |
|
181 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_divider_3', TRUE, get_defined_vars()))
|
182 |
+
add_submenu_page($menu, '', '<span style="display:block; margin:1px 0 1px -5px; padding:0; height:1px; line-height:1px; background:#CCCCCC;"></span>', 'create_users', '#');
|
183 |
|
184 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_trk_ops_page', TRUE, get_defined_vars()))
|
185 |
+
add_submenu_page($menu, 's2Member API / Tracking', 'API / Tracking', 'create_users', 'ws-plugin--s2member-trk-ops', 'c_ws_plugin__s2member_menu_pages::trk_ops_page');
|
186 |
|
187 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_els_ops_page', TRUE, get_defined_vars()))
|
188 |
+
add_submenu_page($menu, 's2Member API / List Servers', 'API / List Servers', 'create_users', 'ws-plugin--s2member-els-ops', 'c_ws_plugin__s2member_menu_pages::els_ops_page');
|
189 |
|
190 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_api_ops_page', TRUE, get_defined_vars()))
|
191 |
+
add_submenu_page($menu, 's2Member API / Notifications', 'API / Notifications', 'create_users', 'ws-plugin--s2member-api-ops', 'c_ws_plugin__s2member_menu_pages::api_ops_page');
|
192 |
|
193 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_scripting_page', TRUE, get_defined_vars()))
|
194 |
+
add_submenu_page($menu, 's2Member API / Scripting', 'API / Scripting', 'create_users', 'ws-plugin--s2member-scripting', 'c_ws_plugin__s2member_menu_pages::scripting_page');
|
195 |
|
196 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_divider_4', TRUE, get_defined_vars()))
|
197 |
+
add_submenu_page($menu, '', '<span style="display:block; margin:1px 0 1px -5px; padding:0; height:1px; line-height:1px; background:#CCCCCC;"></span>', 'create_users', '#');
|
198 |
|
199 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_integrations_page', (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars()))
|
200 |
+
add_submenu_page($menu, 's2Member / Other Integrations', 'Other Integrations', 'create_users', 'ws-plugin--s2member-integrations', 'c_ws_plugin__s2member_menu_pages::integrations_page');
|
201 |
|
202 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_divider_5', TRUE, get_defined_vars()))
|
203 |
+
add_submenu_page($menu, '', '<span style="display:block; margin:1px 0 1px -5px; padding:0; height:1px; line-height:1px; background:#CCCCCC;"></span>', 'create_users', '#');
|
204 |
|
205 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_logs_page', (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars()))
|
206 |
+
add_submenu_page($menu, 's2Member Logs', 'Log Files (Debug)', 'create_users', 'ws-plugin--s2member-logs', 'c_ws_plugin__s2member_menu_pages::logs_page');
|
207 |
|
208 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_divider_6', (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars()))
|
209 |
+
add_submenu_page($menu, '', '<span style="display:block; margin:1px 0 1px -5px; padding:0; height:1px; line-height:1px; background:#CCCCCC;"></span>', 'create_users', '#');
|
210 |
|
211 |
+
if(apply_filters('ws_plugin__s2member_during_add_admin_options_add_info_page', (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars()))
|
212 |
+
add_submenu_page($menu, 's2Member Information', 's2Member Info', 'create_users', 'ws-plugin--s2member-info', 'c_ws_plugin__s2member_menu_pages::info_page');
|
213 |
|
214 |
+
do_action('ws_plugin__s2member_during_add_admin_options_additional_pages', get_defined_vars());
|
215 |
+
}
|
216 |
+
do_action('ws_plugin__s2member_after_add_admin_options', get_defined_vars());
|
217 |
+
}
|
218 |
|
219 |
+
/**
|
220 |
+
* Adds network option menus / sub-menus.
|
221 |
+
*
|
222 |
+
* @package s2Member\Menu_Pages
|
223 |
+
* @since 3.5
|
224 |
+
*
|
225 |
+
* @attaches-to ``add_action('network_admin_menu');``
|
226 |
+
*/
|
227 |
+
public static function add_network_admin_options()
|
228 |
+
{
|
229 |
+
do_action('ws_plugin__s2member_before_add_network_admin_options', get_defined_vars());
|
230 |
+
|
231 |
+
if(apply_filters('ws_plugin__s2member_during_add_network_admin_options_create_menu_items', TRUE, get_defined_vars()))
|
232 |
+
{
|
233 |
+
if((is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site()) || apply_filters('ws_plugin__s2member_during_add_network_admin_options_clear_right_side', FALSE, get_defined_vars()))
|
234 |
+
$GLOBALS['WS_PLUGIN__']['s2member']['c']['menu_pages'] = array(); // Clear right side.
|
235 |
|
236 |
+
$menu = 'ws-plugin--s2member-mms-ops'; // Used below for nesting additional sub-menu pages.
|
|
|
237 |
|
238 |
+
add_menu_page('s2Member', 's2Member', 'create_users', $menu, 'c_ws_plugin__s2member_menu_pages::mms_ops_page', $GLOBALS['WS_PLUGIN__']['s2member']['c']['dir_url'].'/images/brand-favicon.png');
|
|
|
239 |
|
240 |
+
add_submenu_page($menu, 's2Member Multisite (Configuration)', 'Multisite (Config)', 'create_users', 'ws-plugin--s2member-mms-ops', 'c_ws_plugin__s2member_menu_pages::mms_ops_page');
|
241 |
|
242 |
+
if(apply_filters('ws_plugin__s2member_during_add_network_admin_options_add_info_page', (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars()))
|
243 |
+
add_submenu_page($menu, 's2Member Information', 's2Member Info', 'create_users', 'ws-plugin--s2member-info', 'c_ws_plugin__s2member_menu_pages::info_page');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
|
245 |
+
do_action('ws_plugin__s2member_during_add_network_admin_options_additional_pages', get_defined_vars());
|
246 |
+
}
|
247 |
+
do_action('ws_plugin__s2member_after_add_network_admin_options', get_defined_vars());
|
248 |
+
}
|
249 |
|
250 |
+
/**
|
251 |
+
* A sort of callback function to add the settings link.
|
252 |
+
*
|
253 |
+
* @package s2Member\Menu_Pages
|
254 |
+
* @since 3.5
|
255 |
+
*
|
256 |
+
* @attaches-to ``add_filter('plugin_action_links');``
|
257 |
+
*
|
258 |
+
* @param array $actions Expects an existing array of actions links, passed in by the Filter.
|
259 |
+
* @param string $plugin_file Expects path to a plugin file. We need to test against this for s2Member.
|
260 |
+
*
|
261 |
+
* @return array An array of links, Filtered by this routine.
|
262 |
+
*/
|
263 |
+
public static function _add_settings_link($actions = array(), $plugin_file = '')
|
264 |
+
{
|
265 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
266 |
+
do_action('_ws_plugin__s2member_before_add_settings_link', get_defined_vars());
|
267 |
+
unset($__refs, $__v); // Housekeeping.
|
268 |
+
|
269 |
+
if($plugin_file === $GLOBALS['WS_PLUGIN__']['s2member']['c']['plugin_basename'] && is_array($actions))
|
270 |
+
{
|
271 |
+
$settings = '<a href="'.esc_attr(admin_url('/admin.php?page=ws-plugin--s2member-gen-ops')).'">Settings</a>';
|
272 |
+
array_unshift($actions, apply_filters('ws_plugin__s2member_add_settings_link', $settings, get_defined_vars()));
|
273 |
|
274 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
275 |
+
do_action('_ws_plugin__s2member_during_add_settings_link', get_defined_vars());
|
276 |
+
unset($__refs, $__v); // Housekeeping.
|
277 |
+
}
|
278 |
+
return apply_filters('_ws_plugin__s2member_add_settings_link', $actions, get_defined_vars());
|
279 |
+
}
|
280 |
|
281 |
+
/**
|
282 |
+
* Enqueue scripts for administrative menu pages.
|
283 |
+
*
|
284 |
+
* @package s2Member\Menu_Pages
|
285 |
+
* @since 3.5
|
286 |
+
*
|
287 |
+
* @attaches-to ``add_action('admin_print_scripts');``
|
288 |
+
*/
|
289 |
+
public static function add_admin_scripts()
|
290 |
+
{
|
291 |
+
do_action('ws_plugin__s2member_before_add_admin_scripts', get_defined_vars());
|
292 |
+
|
293 |
+
if(!empty($_GET['page']) && preg_match('/ws-plugin--s2member-/', $_GET['page']))
|
294 |
+
{
|
295 |
+
wp_enqueue_script('jquery');
|
296 |
+
wp_enqueue_script('thickbox');
|
297 |
+
wp_enqueue_script('media-upload');
|
298 |
+
wp_enqueue_script('jquery-ui-core');
|
299 |
+
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());
|
300 |
+
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());
|
301 |
+
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());
|
302 |
+
wp_enqueue_script('ws-plugin--s2member-menu-pages', site_url('/?ws_plugin__s2member_menu_pages_js='.urlencode(mt_rand())), array('jquery', 'thickbox', 'media-upload', 'jquery-sprintf', 'jquery-json-ps', 'jquery-ui-core', 'jquery-ui-effects', 'password-strength-meter'), c_ws_plugin__s2member_utilities::ver_checksum());
|
303 |
+
|
304 |
+
do_action('ws_plugin__s2member_during_add_admin_scripts', get_defined_vars());
|
305 |
+
}
|
306 |
+
do_action('ws_plugin__s2member_after_add_admin_scripts', get_defined_vars());
|
307 |
+
}
|
308 |
|
309 |
+
/**
|
310 |
+
* Enqueue styles for administrative menu pages.
|
311 |
+
*
|
312 |
+
* @package s2Member\Menu_Pages
|
313 |
+
* @since 3.5
|
314 |
+
*
|
315 |
+
* @attaches-to ``add_action('admin_print_styles');``
|
316 |
+
*/
|
317 |
+
public static function add_admin_styles()
|
318 |
+
{
|
319 |
+
do_action('ws_plugin__s2member_before_add_admin_styles', get_defined_vars());
|
320 |
+
|
321 |
+
if(!empty($_GET['page']) && preg_match('/ws-plugin--s2member-/', $_GET['page']))
|
322 |
+
{
|
323 |
+
wp_enqueue_style('thickbox');
|
324 |
+
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');
|
325 |
|
326 |
+
do_action('ws_plugin__s2member_during_add_admin_styles', get_defined_vars());
|
327 |
+
}
|
328 |
+
do_action('ws_plugin__s2member_after_add_admin_styles', get_defined_vars());
|
329 |
+
}
|
330 |
|
331 |
+
/**
|
332 |
+
* Handles log file downloads.
|
333 |
+
*
|
334 |
+
* @package s2Member\Menu_Pages
|
335 |
+
* @since 120310
|
336 |
+
*/
|
337 |
+
public static function log_file_downloader()
|
338 |
+
{
|
339 |
+
if(!current_user_can('create_users')) return;
|
340 |
+
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site())
|
341 |
+
return; // We do NOT provide this functionality on Child Blogs of a Blog Farm Network.
|
342 |
+
|
343 |
+
if(!empty($_GET['ws_plugin__s2member_download_log_file']) && is_string($log_file = $_GET['ws_plugin__s2member_download_log_file']) && strpos($log_file, '..') === FALSE && strpos(basename($log_file), '.') !== 0)
|
344 |
+
if(!empty($_GET['ws_plugin__s2member_download_log_file_v']) && is_string($nonce = $_GET['ws_plugin__s2member_download_log_file_v']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-download-log-file-v'))
|
345 |
+
{
|
346 |
+
$logs_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'];
|
347 |
|
348 |
+
if(file_exists($logs_dir.'/'.$log_file))
|
349 |
+
$log_file_contents = file_get_contents($logs_dir.'/'.$log_file);
|
350 |
+
else $log_file_contents = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
|
352 |
+
@set_time_limit(0);
|
353 |
+
@ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
|
|
|
|
|
354 |
|
355 |
+
@ini_set('zlib.output_compression', 0);
|
356 |
+
if(function_exists('apache_setenv'))
|
357 |
+
@apache_setenv('no-gzip', '1');
|
|
|
358 |
|
359 |
+
while(@ob_end_clean()) ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
+
status_header(200); // 200 OK status header.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
362 |
|
363 |
+
header('Content-Encoding: none');
|
364 |
+
header('Accept-Ranges: none');
|
365 |
+
header('Content-Type: text/plain; charset=UTF-8');
|
366 |
+
header('Content-Length: '.strlen($log_file_contents));
|
367 |
+
header('Expires: '.gmdate('D, d M Y H:i:s', strtotime('-1 week')).' GMT');
|
368 |
+
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
|
369 |
+
header('Cache-Control: no-cache, must-revalidate, max-age=0');
|
370 |
+
header('Cache-Control: post-check=0, pre-check=0', FALSE);
|
371 |
+
header('Pragma: no-cache');
|
372 |
|
373 |
+
header('Content-Disposition: attachment; filename="'.$log_file.'"');
|
374 |
|
375 |
+
exit($log_file_contents); // Log file.
|
376 |
+
}
|
377 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
378 |
|
379 |
+
/**
|
380 |
+
* Handles log file downloads (in ZIP format).
|
381 |
+
*
|
382 |
+
* @package s2Member\Menu_Pages
|
383 |
+
* @since 120310
|
384 |
+
*/
|
385 |
+
public static function logs_zip_downloader()
|
386 |
+
{
|
387 |
+
if(!current_user_can('create_users')) return;
|
388 |
+
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site())
|
389 |
+
return; // We do NOT provide this functionality on Child Blogs of a Blog Farm Network.
|
390 |
+
|
391 |
+
if(!empty($_POST['ws_plugin__s2member_logs_download_zip']) && is_string($nonce = $_POST['ws_plugin__s2member_logs_download_zip']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-logs-download-zip'))
|
392 |
+
{
|
393 |
+
$logs_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'];
|
394 |
+
$s2member_logs_zip = $logs_dir.'/'.$_SERVER['HTTP_HOST'].'--s2member-logs.zip';
|
395 |
|
396 |
+
if(is_dir($logs_dir)) // Do we have a logs directory?
|
397 |
+
{
|
398 |
+
include_once ABSPATH.'wp-admin/includes/class-pclzip.php';
|
399 |
|
400 |
+
if(file_exists($s2member_logs_zip) && is_writable($s2member_logs_zip))
|
401 |
+
unlink($s2member_logs_zip);
|
402 |
|
403 |
+
$archive = new PclZip($s2member_logs_zip);
|
404 |
+
$archive->create($logs_dir, PCLZIP_OPT_REMOVE_ALL_PATH);
|
405 |
+
}
|
406 |
+
if(file_exists($s2member_logs_zip))
|
407 |
+
$s2member_logs_zip_size = filesize($s2member_logs_zip);
|
408 |
+
else $s2member_logs_zip_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
|
410 |
+
@set_time_limit(0);
|
411 |
+
@ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
|
|
|
|
|
412 |
|
413 |
+
@ini_set('zlib.output_compression', 0);
|
414 |
+
if(function_exists('apache_setenv'))
|
415 |
+
@apache_setenv('no-gzip', '1');
|
416 |
|
417 |
+
while(@ob_end_clean()) ;
|
|
|
418 |
|
419 |
+
status_header(200); // 200 OK status header.
|
|
|
|
|
420 |
|
421 |
+
header('Content-Encoding: none');
|
422 |
+
header('Accept-Ranges: none');
|
423 |
+
header('Content-Type: application/zip');
|
424 |
+
header('Content-Length: '.$s2member_logs_zip_size);
|
425 |
+
header('Expires: '.gmdate('D, d M Y H:i:s', strtotime('-1 week')).' GMT');
|
426 |
+
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
|
427 |
+
header('Cache-Control: no-cache, must-revalidate, max-age=0');
|
428 |
+
header('Cache-Control: post-check=0, pre-check=0', FALSE);
|
429 |
+
header('Pragma: no-cache');
|
430 |
|
431 |
+
header('Content-Disposition: attachment; filename="'.basename($s2member_logs_zip).'"');
|
432 |
|
433 |
+
if($s2member_logs_zip_size && is_resource($resource = fopen($s2member_logs_zip, 'rb')))
|
434 |
+
{
|
435 |
+
$_bytes_to_read = $s2member_logs_zip_size; // Total bytes we need to read for this file.
|
|
|
|
|
|
|
|
|
|
|
|
|
436 |
|
437 |
+
$chunk_size = apply_filters('ws_plugin__s2member_file_downloads_chunk_size', 2097152, get_defined_vars());
|
438 |
|
439 |
+
while($_bytes_to_read) // We have bytes to read here.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
{
|
441 |
+
$_bytes_to_read -= ($_reading = ($_bytes_to_read > $chunk_size) ? $chunk_size : $_bytes_to_read);
|
442 |
+
echo fread($resource, $_reading); // Serve file in chunks (default chunk size is 2MB).
|
443 |
+
flush(); // Flush each chunk to the browser as it is served (avoids high memory consumption).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
444 |
}
|
445 |
+
fclose($resource); // Close file resource handle.
|
446 |
+
unset($_bytes_to_read, $_reading); // Housekeeping.
|
447 |
+
}
|
448 |
+
exit; // Clean exit after serving file.
|
449 |
+
}
|
450 |
+
}
|
451 |
|
452 |
+
/**
|
453 |
+
* Archives existing log files and starts fresh with new logs.
|
454 |
+
*
|
455 |
+
* @package s2Member\Menu_Pages
|
456 |
+
* @since 120310
|
457 |
+
*/
|
458 |
+
public static function archive_logs_start_fresh()
|
459 |
+
{
|
460 |
+
if(!current_user_can('create_users')) return;
|
461 |
+
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site())
|
462 |
+
return; // We do NOT provide this functionality on Child Blogs of a Blog Farm Network.
|
463 |
+
|
464 |
+
if(!empty($_POST['ws_plugin__s2member_logs_archive_start_fresh']) && is_string($nonce = $_POST['ws_plugin__s2member_logs_archive_start_fresh']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-logs-archive-start-fresh'))
|
465 |
+
{
|
466 |
+
if(is_dir($logs_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir']))
|
467 |
+
foreach(scandir($logs_dir) as $log_file) // Archive existing log files here.
|
468 |
{
|
469 |
+
if(preg_match('/\.log$/', $log_file) && stripos($log_file, '-ARCHIVED-') === FALSE)
|
470 |
+
if(is_file($log_dir_file = $logs_dir.'/'.$log_file) && is_writable($log_dir_file))
|
471 |
+
if(!rename($log_dir_file, preg_replace('/\.log$/i', '', $log_dir_file).'-ARCHIVED-'.date('m-d-Y').'-'.time().'.log'))
|
472 |
+
$error = TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
473 |
}
|
474 |
+
if(!empty($error))
|
475 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Unknown error when attempting to archive log files. Please check directory permissions.', TRUE);
|
476 |
+
else c_ws_plugin__s2member_admin_notices::display_admin_notice('All log files have been archived succesfully.');
|
477 |
+
}
|
478 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
479 |
|
480 |
+
/**
|
481 |
+
* Deletes existing log files and starts fresh with new logs.
|
482 |
+
*
|
483 |
+
* @package s2Member\Menu_Pages
|
484 |
+
* @since 120312
|
485 |
+
*/
|
486 |
+
public static function delete_logs_start_fresh()
|
487 |
+
{
|
488 |
+
if(!current_user_can('create_users')) return;
|
489 |
+
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && !is_main_site())
|
490 |
+
return; // We do NOT provide this functionality on Child Blogs of a Blog Farm Network.
|
491 |
+
|
492 |
+
if(!empty($_POST['ws_plugin__s2member_logs_delete_start_fresh']) && is_string($nonce = $_POST['ws_plugin__s2member_logs_delete_start_fresh']) && wp_verify_nonce($nonce, 'ws-plugin--s2member-logs-delete-start-fresh'))
|
493 |
+
{
|
494 |
+
if(is_dir($logs_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir']))
|
495 |
+
foreach(scandir($logs_dir) as $log_file) // Delete existing log files here.
|
496 |
{
|
497 |
+
if(preg_match('/\.log$/', $log_file))
|
498 |
+
if(is_file($log_dir_file = $logs_dir.'/'.$log_file) && is_writable($log_dir_file))
|
499 |
+
if(!unlink($log_dir_file)) $error = TRUE;
|
500 |
+
}
|
501 |
+
if(!empty($error))
|
502 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Unknown error when attempting to delete log files. Please check directory permissions.', TRUE);
|
503 |
+
else c_ws_plugin__s2member_admin_notices::display_admin_notice('All log files have been deleted succesfully.');
|
504 |
+
}
|
505 |
+
}
|
506 |
|
507 |
+
/**
|
508 |
+
* Builds and handles the Quick Start page.
|
509 |
+
*
|
510 |
+
* @package s2Member\Menu_Pages
|
511 |
+
* @since 3.5
|
512 |
+
*/
|
513 |
+
public static function start_page()
|
514 |
+
{
|
515 |
+
do_action('ws_plugin__s2member_before_start_page', get_defined_vars());
|
516 |
|
517 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/start.inc.php';
|
518 |
|
519 |
+
do_action('ws_plugin__s2member_after_start_page', get_defined_vars());
|
520 |
+
}
|
521 |
|
522 |
+
/**
|
523 |
+
* Builds and handles the Main Multisite Options page.
|
524 |
+
*
|
525 |
+
* @package s2Member\Menu_Pages
|
526 |
+
* @since 3.5
|
527 |
+
*/
|
528 |
+
public static function mms_ops_page()
|
529 |
+
{
|
530 |
+
do_action('ws_plugin__s2member_before_mms_ops_page', get_defined_vars());
|
|
|
|
|
|
|
|
|
531 |
|
532 |
+
if(c_ws_plugin__s2member_menu_pages::update_all_options())
|
533 |
+
c_ws_plugin__s2member_mms_patches::mms_patches(TRUE);
|
534 |
|
535 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/mms-ops.inc.php';
|
536 |
|
537 |
+
do_action('ws_plugin__s2member_after_mms_ops_page', get_defined_vars());
|
538 |
+
}
|
539 |
|
540 |
+
/**
|
541 |
+
* Builds and handles the General Options page.
|
542 |
+
*
|
543 |
+
* @package s2Member\Menu_Pages
|
544 |
+
* @since 3.5
|
545 |
+
*/
|
546 |
+
public static function gen_ops_page()
|
547 |
+
{
|
548 |
+
do_action('ws_plugin__s2member_before_gen_ops_page', get_defined_vars());
|
|
|
|
|
|
|
|
|
549 |
|
550 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
551 |
|
552 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/gen-ops.inc.php';
|
553 |
|
554 |
+
do_action('ws_plugin__s2member_after_gen_ops_page', get_defined_vars());
|
555 |
+
}
|
556 |
|
557 |
+
/**
|
558 |
+
* Builds and handles the Restriction Options page.
|
559 |
+
*
|
560 |
+
* @package s2Member\Menu_Pages
|
561 |
+
* @since 3.5
|
562 |
+
*/
|
563 |
+
public static function res_ops_page()
|
564 |
+
{
|
565 |
+
do_action('ws_plugin__s2member_before_res_ops_page', get_defined_vars());
|
|
|
|
|
|
|
|
|
566 |
|
567 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
568 |
|
569 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/res-ops.inc.php';
|
570 |
|
571 |
+
do_action('ws_plugin__s2member_after_res_ops_page', get_defined_vars());
|
572 |
+
}
|
573 |
|
574 |
+
/**
|
575 |
+
* Builds and handles the Paypal Options page.
|
576 |
+
*
|
577 |
+
* @package s2Member\Menu_Pages
|
578 |
+
* @since 3.5
|
579 |
+
*/
|
580 |
+
public static function paypal_ops_page()
|
581 |
+
{
|
582 |
+
do_action('ws_plugin__s2member_before_paypal_ops_page', get_defined_vars());
|
583 |
|
584 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
|
|
585 |
|
586 |
+
$logs_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'];
|
|
|
|
|
|
|
587 |
|
588 |
+
if(!is_dir($logs_dir) && is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($logs_dir))))
|
589 |
+
mkdir($logs_dir, 0777, TRUE).clearstatcache();
|
590 |
|
591 |
+
$htaccess = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'].'/.htaccess';
|
592 |
+
$htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir_htaccess'])));
|
593 |
|
594 |
+
if(is_dir($logs_dir) && is_writable($logs_dir) && !file_exists($htaccess))
|
595 |
+
file_put_contents($htaccess, $htaccess_contents).clearstatcache();
|
|
|
596 |
|
597 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['gateway_debug_logs']) // Logging enabled?
|
598 |
+
{
|
599 |
+
if(!is_dir($logs_dir)) // If the security-enabled logs directory does not exist yet.
|
600 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('The security-enabled logs directory (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($logs_dir)).'</code>) does not exist. Please create this directory manually & make it writable (chmod 777).', TRUE);
|
601 |
|
602 |
+
else if(!is_writable($logs_dir)) // If the logs directory is not writable yet.
|
603 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Permissions error. The security-enabled logs directory (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($logs_dir)).'</code>) is not writable. Please make this directory writable (chmod 777).', TRUE);
|
604 |
|
605 |
+
if(!file_exists($htaccess)) // If the .htaccess file has not been created yet.
|
606 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('The .htaccess protection file (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($htaccess)).'</code>) does not exist. Please create this file manually. Inside your .htaccess file, add this:<br /><pre>'.esc_html($htaccess_contents).'</pre>', TRUE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
607 |
|
608 |
+
else if(!preg_match('/deny from all/i', file_get_contents($htaccess))) // Else if the .htaccess file does not offer the required protection.
|
609 |
+
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);
|
610 |
+
}
|
611 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/paypal-ops.inc.php';
|
612 |
|
613 |
+
do_action('ws_plugin__s2member_after_paypal_ops_page', get_defined_vars());
|
614 |
+
}
|
615 |
|
616 |
+
/**
|
617 |
+
* Builds and handles the Download Options page.
|
618 |
+
*
|
619 |
+
* @package s2Member\Menu_Pages
|
620 |
+
* @since 3.5
|
621 |
+
*/
|
622 |
+
public static function down_ops_page()
|
623 |
+
{
|
624 |
+
do_action('ws_plugin__s2member_before_down_ops_page', get_defined_vars());
|
625 |
+
|
626 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
627 |
+
|
628 |
+
if(!empty($_REQUEST['ws_plugin__s2member_cf_options_reset'])
|
629 |
+
&& wp_verify_nonce($_REQUEST['ws_plugin__s2member_cf_options_reset'], 'ws-plugin--s2member-cf-options-reset'))
|
630 |
+
{
|
631 |
+
c_ws_plugin__s2member_files_in::reset_aws_cf_config_values(); // A full CloudFront reset.
|
632 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon CloudFront configuration reset successfully.');
|
633 |
+
}
|
634 |
+
$files_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'];
|
635 |
|
636 |
+
$htaccess = $GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir'].'/.htaccess';
|
637 |
+
$htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_dir_htaccess'])));
|
638 |
|
639 |
+
$no_gzip_htaccess = ABSPATH.'.htaccess'; // Always located in the absolute root path for WordPress.
|
640 |
+
$no_gzip_htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['files_no_gzip_htaccess'])));
|
641 |
|
642 |
+
if(!c_ws_plugin__s2member_files::no_gzip_rules_in_root_htaccess()) // If s2Member's GZIP exclusions do NOT yet exist in the root `.htaccess` file.
|
643 |
+
c_ws_plugin__s2member_files::write_no_gzip_into_root_htaccess().clearstatcache(); // Handle the root `.htaccess` file now.
|
644 |
|
645 |
+
if(!is_dir($files_dir) && is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($files_dir))))
|
646 |
+
mkdir($files_dir, 0777, TRUE).clearstatcache(); // Create this directory structure now.
|
647 |
|
648 |
+
if(is_dir($files_dir) && is_writable($files_dir) && !file_exists($htaccess)) // This file does NOT exist yet?
|
649 |
+
file_put_contents($htaccess, $htaccess_contents).clearstatcache(); // Create the `.htaccess` file now.
|
650 |
|
651 |
+
if(!c_ws_plugin__s2member_files::no_gzip_rules_in_root_htaccess()) // If s2Member's GZIP exclusions do NOT yet exist in the root `.htaccess` file.
|
652 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Possible GZIP conflict on server. Unable to write GZIP exclusions into root .htaccess file (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($no_gzip_htaccess)).'</code>). Please read the panel below: <strong>Preventing GZIP Conflicts</strong>, and add this section yourself:<br /><pre>'.esc_html($no_gzip_htaccess_contents).'</pre>', TRUE);
|
653 |
|
654 |
+
if(!is_dir($files_dir)) // If the security-enabled files directory does not exist yet.
|
655 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('The security-enabled files directory (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($files_dir)).'</code>) does not exist. Please create this directory manually.', TRUE);
|
656 |
|
657 |
+
if(!file_exists($htaccess)) // If the `.htaccess` file has not been created yet.
|
658 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('The .htaccess protection file (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($htaccess)).'</code>) does not exist. Please create this file manually. Inside your .htaccess file, add this:<br /><pre>'.esc_html($htaccess_contents).'</pre>', TRUE);
|
659 |
|
660 |
+
else if(!preg_match('/deny from all/i', file_get_contents($htaccess))) // Else if the `.htaccess` file does not offer the required protection.
|
661 |
+
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);
|
|
|
|
|
|
|
662 |
|
663 |
+
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'))
|
664 |
+
if(($amazon_cf_auto_configure_distros = c_ws_plugin__s2member_files_in::amazon_cf_auto_configure_distros()) && $amazon_cf_auto_configure_distros['success'])
|
665 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon CloudFront Distributions auto-configured successfully. Please allow 30 minutes for initial propagation. <strong>Tip:</strong> If you try to stream over the RTMP protocol using something like the <code>[s2Stream /]</code> shortcode, and you keep getting an "ID Not Found" error while using JW Player; please note that it can <em>sometimes</em> take a full 24 hours for RTMP (i.e. streaming distributions) to begin working properly. This is because there are a few initialization routines that must complete on the AWS side when you first integrate with CloudFront. Please be patient.'.(($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']).' —» '.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']).' —» '.esc_html($GLOBALS['WS_PLUGIN__']['s2member']['o']['amazon_cf_files_distro_streaming_dname']).'</code></em>' : ''));
|
666 |
+
else // Else there was an error. We need to report this back to the site owner so they can understand what's going on.
|
667 |
+
(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);
|
668 |
|
669 |
+
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'))
|
670 |
+
if(($amazon_s3_auto_configure_acls = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls()) && $amazon_s3_auto_configure_acls['success'])
|
671 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Amazon S3 ACLs auto-configured successfully.');
|
672 |
+
else // Else there was an error. We need to report this back to the site owner so they can understand what's going on.
|
673 |
+
(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);
|
674 |
|
675 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/down-ops.inc.php';
|
676 |
|
677 |
+
do_action('ws_plugin__s2member_after_down_ops_page', get_defined_vars());
|
678 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
679 |
|
|
|
680 |
|
681 |
+
/**
|
682 |
+
* Builds and handles the API Tracking options page.
|
683 |
+
*
|
684 |
+
* @package s2Member\Menu_Pages
|
685 |
+
* @since 3.5
|
686 |
+
*/
|
687 |
+
public static function trk_ops_page()
|
688 |
+
{
|
689 |
+
do_action('ws_plugin__s2member_before_trk_ops_page', get_defined_vars());
|
690 |
|
691 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
692 |
|
693 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/trk-ops.inc.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
694 |
|
695 |
+
do_action('ws_plugin__s2member_after_trk_ops_page', get_defined_vars());
|
696 |
+
}
|
697 |
|
698 |
+
/**
|
699 |
+
* Builds and handles the API List Server options page.
|
700 |
+
*
|
701 |
+
* @package s2Member\Menu_Pages
|
702 |
+
* @since 3.5
|
703 |
+
*/
|
704 |
+
public static function els_ops_page()
|
705 |
+
{
|
706 |
+
do_action('ws_plugin__s2member_before_els_ops_page', get_defined_vars());
|
707 |
|
708 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
709 |
|
710 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/els-ops.inc.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
711 |
|
712 |
+
do_action('ws_plugin__s2member_after_els_ops_page', get_defined_vars());
|
713 |
+
}
|
714 |
|
715 |
+
/**
|
716 |
+
* Builds and handles the API Notifications page.
|
717 |
+
*
|
718 |
+
* @package s2Member\Menu_Pages
|
719 |
+
* @since 3.5
|
720 |
+
*/
|
721 |
+
public static function api_ops_page()
|
722 |
+
{
|
723 |
+
do_action('ws_plugin__s2member_before_api_ops_page', get_defined_vars());
|
724 |
|
725 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
726 |
|
727 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/api-ops.inc.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
728 |
|
729 |
+
do_action('ws_plugin__s2member_after_api_ops_page', get_defined_vars());
|
730 |
+
}
|
731 |
|
732 |
+
/**
|
733 |
+
* Builds and handles the PayPal Button Generator page.
|
734 |
+
*
|
735 |
+
* @package s2Member\Menu_Pages
|
736 |
+
* @since 3.5
|
737 |
+
*/
|
738 |
+
public static function paypal_buttons_page()
|
739 |
+
{
|
740 |
+
do_action('ws_plugin__s2member_before_paypal_buttons_page', get_defined_vars());
|
741 |
|
742 |
+
if(!$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_business'] || !$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_merchant_id'] || !$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_api_username'] || !$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_api_password'] || !$GLOBALS['WS_PLUGIN__']['s2member']['o']['paypal_api_signature'])
|
743 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Please configure <code>s2Member -› PayPal Options</code> first. Once all of your PayPal Options are configured; including your Email Address, Merchant ID, API Username, Password, and Signature; return to this page & generate your PayPal Button(s).', TRUE);
|
744 |
|
745 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/paypal-buttons.inc.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
746 |
|
747 |
+
do_action('ws_plugin__s2member_after_paypal_buttons_page', get_defined_vars());
|
748 |
+
}
|
749 |
|
750 |
+
/**
|
751 |
+
* Builds and handles the API Scripting page.
|
752 |
+
*
|
753 |
+
* @package s2Member\Menu_Pages
|
754 |
+
* @since 3.5
|
755 |
+
*/
|
756 |
+
public static function scripting_page()
|
757 |
+
{
|
758 |
+
do_action('ws_plugin__s2member_before_scripting_page', get_defined_vars());
|
759 |
|
760 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
761 |
|
762 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/scripting.inc.php';
|
763 |
|
764 |
+
do_action('ws_plugin__s2member_after_scripting_page', get_defined_vars());
|
765 |
+
}
|
766 |
|
767 |
+
/**
|
768 |
+
* Builds and handles the Integrations page.
|
769 |
+
*
|
770 |
+
* @package s2Member\Menu_Pages
|
771 |
+
* @since 3.5
|
772 |
+
*/
|
773 |
+
public static function integrations_page()
|
774 |
+
{
|
775 |
+
do_action('ws_plugin__s2member_before_integrations_page', get_defined_vars());
|
|
|
|
|
|
|
|
|
776 |
|
777 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/integrations.inc.php';
|
|
|
|
|
778 |
|
779 |
+
do_action('ws_plugin__s2member_after_integrations_page', get_defined_vars());
|
780 |
+
}
|
781 |
|
782 |
+
/**
|
783 |
+
* Builds and handles the Logs page.
|
784 |
+
*
|
785 |
+
* @package s2Member\Menu_Pages
|
786 |
+
* @since 120310
|
787 |
+
*/
|
788 |
+
public static function logs_page()
|
789 |
+
{
|
790 |
+
do_action('ws_plugin__s2member_before_logs_page', get_defined_vars());
|
791 |
|
792 |
+
c_ws_plugin__s2member_menu_pages::update_all_options();
|
793 |
+
c_ws_plugin__s2member_menu_pages::archive_logs_start_fresh();
|
794 |
+
c_ws_plugin__s2member_menu_pages::delete_logs_start_fresh();
|
795 |
|
796 |
+
$logs_dir = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'];
|
|
|
797 |
|
798 |
+
if(!is_dir($logs_dir) && is_writable(dirname(c_ws_plugin__s2member_utils_dirs::strip_dir_app_data($logs_dir))))
|
799 |
+
mkdir($logs_dir, 0777, TRUE).clearstatcache();
|
800 |
|
801 |
+
$htaccess = $GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir'].'/.htaccess';
|
802 |
+
$htaccess_contents = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS['WS_PLUGIN__']['s2member']['c']['logs_dir_htaccess'])));
|
803 |
|
804 |
+
if(is_dir($logs_dir) && is_writable($logs_dir) && !file_exists($htaccess))
|
805 |
+
file_put_contents($htaccess, $htaccess_contents).clearstatcache();
|
806 |
|
807 |
+
if(!is_dir($logs_dir)) // If the security-enabled logs directory does not exist yet.
|
808 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('The security-enabled logs directory (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($logs_dir)).'</code>) does not exist. Please create this directory manually & make it writable (chmod 777).', TRUE);
|
809 |
|
810 |
+
else if(!is_writable($logs_dir)) // If the logs directory is not writable yet.
|
811 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Permissions error. The security-enabled logs directory (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($logs_dir)).'</code>) is not writable. Please make this directory writable (chmod 777).', TRUE);
|
812 |
|
813 |
+
if(!file_exists($htaccess)) // If the .htaccess file has not been created yet.
|
814 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('The .htaccess protection file (<code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($htaccess)).'</code>) does not exist. Please create this file manually. Inside your .htaccess file, add this:<br /><pre>'.esc_html($htaccess_contents).'</pre>', TRUE);
|
815 |
|
816 |
+
else if(!preg_match('/deny from all/i', file_get_contents($htaccess))) // Else if the .htaccess file does not offer the required protection.
|
817 |
+
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);
|
818 |
|
819 |
+
if(!$GLOBALS['WS_PLUGIN__']['s2member']['o']['gateway_debug_logs']) // Logging disabled?
|
820 |
+
c_ws_plugin__s2member_admin_notices::display_admin_notice('Logging is currently disabled by your configuration.');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
821 |
|
822 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/logs.inc.php';
|
823 |
|
824 |
+
do_action('ws_plugin__s2member_after_logs_page', get_defined_vars());
|
825 |
+
}
|
826 |
|
827 |
+
/**
|
828 |
+
* Builds and handles the s2Member Info page.
|
829 |
+
*
|
830 |
+
* @package s2Member\Menu_Pages
|
831 |
+
* @since 3.5
|
832 |
+
*/
|
833 |
+
public static function info_page()
|
834 |
+
{
|
835 |
+
do_action('ws_plugin__s2member_before_info_page', get_defined_vars());
|
836 |
+
|
837 |
+
include_once dirname(dirname(__FILE__)).'/menu-pages/info.inc.php';
|
838 |
+
|
839 |
+
do_action('ws_plugin__s2member_after_info_page', get_defined_vars());
|
840 |
+
}
|
841 |
}
|
842 |
+
}
|
includes/classes/mo-page.inc.php
CHANGED
@@ -63,7 +63,7 @@ if(!class_exists("c_ws_plugin__s2member_mo_page"))
|
|
63 |
* One of: `post|page|catg|ptag|file|ruri|ccap|sp|sys`.
|
64 |
* Defaults to ``$seeking_type``.
|
65 |
*
|
66 |
-
* @return
|
67 |
*/
|
68 |
public static function wp_redirect_w_mop_vars($seeking_type = FALSE, $seeking_type_value = FALSE, $req_type = FALSE, $req_type_value = FALSE, $seeking_uri = FALSE, $res_type = FALSE)
|
69 |
{
|
63 |
* One of: `post|page|catg|ptag|file|ruri|ccap|sp|sys`.
|
64 |
* Defaults to ``$seeking_type``.
|
65 |
*
|
66 |
+
* @return bool Return-value of inner routine.
|
67 |
*/
|
68 |
public static function wp_redirect_w_mop_vars($seeking_type = FALSE, $seeking_type_value = FALSE, $req_type = FALSE, $req_type_value = FALSE, $seeking_uri = FALSE, $res_type = FALSE)
|
69 |
{
|
includes/classes/pages-sp.inc.php
CHANGED
@@ -1,119 +1,111 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member's Page protection routines *(for specific Pages)*.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Pages
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
* Handles Page Level Access *(for specific Pages)*.
|
32 |
-
*
|
33 |
-
* @package s2Member\Pages
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @param int|string $page_id Numeric Page ID.
|
37 |
-
* @param bool $check_user Test permissions against the current User? Defaults to true.
|
38 |
-
* @return null|array Non-empty array(with details) if access is denied, else null if access is allowed.
|
39 |
-
*
|
40 |
-
* @todo Provide more information in the return array(like MOP Vars).
|
41 |
-
*/
|
42 |
-
public static function check_specific_page_level_access ($page_id = FALSE, $check_user = TRUE)
|
43 |
-
{
|
44 |
-
do_action("ws_plugin__s2member_before_check_specific_page_level_access", get_defined_vars ());
|
45 |
-
|
46 |
-
$excluded = apply_filters("ws_plugin__s2member_check_specific_page_level_access_excluded", false, get_defined_vars ());
|
47 |
-
|
48 |
-
if (!$excluded && is_numeric ($page_id) && ($page_id = (int)$page_id) && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
49 |
-
{
|
50 |
-
$page_uri = c_ws_plugin__s2member_utils_urls::parse_uri (get_page_link ($page_id)); // Get a full valid URI for this Page now.
|
51 |
-
|
52 |
-
if (!c_ws_plugin__s2member_systematics_sp::is_wp_systematic_use_specific_page ($page_id, $page_uri)) // Do NOT touch WordPress Systematics.
|
53 |
-
{
|
54 |
-
$user = (is_user_logged_in () && is_object ($user = wp_get_current_user ()) && !empty($user->ID)) ? $user : false; // Current User's object.
|
55 |
-
|
56 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && $page_id === (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && (!$check_user || !$user || !$user->has_cap ("access_s2member_level0")) && $page_id !== (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
57 |
-
return apply_filters("ws_plugin__s2member_check_specific_page_level_access", array("s2member_level_req" => 0), get_defined_vars ());
|
58 |
-
|
59 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri ($user, "root-returns-false")) && preg_match ("/^" . preg_quote ($login_redirection_uri, "/") . "$/", $page_uri) && (!$check_user || !$user || !$user->has_cap ("access_s2member_level0")) && $page_id !== (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
60 |
-
return apply_filters("ws_plugin__s2member_check_specific_page_level_access", array("s2member_level_req" => 0), get_defined_vars ());
|
61 |
|
62 |
-
|
63 |
-
|
|
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Page Level restrictions. Go through each Level.
|
68 |
-
{
|
69 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_pages"] === "all" && (!$check_user || !$user || !$user->has_cap ("access_s2member_level" . $n)))
|
70 |
-
return apply_filters("ws_plugin__s2member_check_specific_page_level_access", array("s2member_level_req" => $n), get_defined_vars ());
|
71 |
|
72 |
-
|
73 |
-
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
}
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
}
|
99 |
-
|
100 |
-
if (is_array($ccaps_req = get_post_meta ($page_id, "s2member_ccaps_req", true)) && !empty($ccaps_req))
|
101 |
-
{
|
102 |
-
foreach ($ccaps_req as $ccap) // The ``$user`` MUST satisfy ALL Custom Capabilities.
|
103 |
-
if (strlen ($ccap) && (!$check_user || !$user || !$user->has_cap ("access_s2member_ccap_" . $ccap)))
|
104 |
-
return apply_filters("ws_plugin__s2member_check_specific_page_level_access", array("s2member_ccap_req" => $ccap), get_defined_vars ());
|
105 |
-
}
|
106 |
-
|
107 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["specific_ids"] && in_array($page_id, preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["specific_ids"])) && (!$check_user || !c_ws_plugin__s2member_sp_access::sp_access ($page_id, "read-only")))
|
108 |
-
return apply_filters("ws_plugin__s2member_check_specific_page_level_access", array("s2member_sp_req" => $page_id), get_defined_vars ());
|
109 |
-
}
|
110 |
|
111 |
-
|
112 |
-
|
113 |
}
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
}
|
|
|
|
|
117 |
}
|
|
|
|
|
118 |
}
|
119 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member's Page protection routines *(for specific Pages)*.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Pages
|
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_pages_sp'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* s2Member's Page protection routines *(for specific Pages)*.
|
24 |
+
*
|
25 |
+
* @package s2Member\Pages
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_pages_sp
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles Page Level Access *(for specific Pages)*.
|
32 |
+
*
|
33 |
+
* @package s2Member\Pages
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @param int|string $page_id Numeric Page ID.
|
37 |
+
* @param bool $check_user Test permissions against the current User? Defaults to true.
|
38 |
+
*
|
39 |
+
* @return null|array Non-empty array(with details) if access is denied, else null if access is allowed.
|
40 |
+
*/
|
41 |
+
public static function check_specific_page_level_access($page_id = 0, $check_user = TRUE)
|
42 |
+
{
|
43 |
+
do_action('ws_plugin__s2member_before_check_specific_page_level_access', get_defined_vars());
|
44 |
+
|
45 |
+
$excluded = apply_filters('ws_plugin__s2member_check_specific_page_level_access_excluded', FALSE, get_defined_vars());
|
46 |
+
|
47 |
+
if(!$excluded && is_numeric($page_id) && ($page_id = (int)$page_id) && ($page = get_post($page_id)) && $GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
48 |
{
|
49 |
+
$page_uri = c_ws_plugin__s2member_utils_urls::parse_uri(get_page_link($page->ID)); // Get a full valid URI for this Page now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
+
if(!c_ws_plugin__s2member_systematics_sp::is_wp_systematic_use_specific_page($page->ID, $page_uri)) // Do NOT touch WordPress Systematics.
|
52 |
+
{
|
53 |
+
$user = (is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID)) ? $user : FALSE; // Current User's object.
|
54 |
|
55 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'] && $page->ID === (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'] && (!$check_user || !$user || !$user->has_cap('access_s2member_level0')) && $page->ID !== (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
56 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => 0), get_defined_vars());
|
|
|
|
|
|
|
|
|
57 |
|
58 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_override'] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri($user, 'root-returns-false')) && preg_match('/^'.preg_quote($login_redirection_uri, '/').'$/', $page_uri) && (!$check_user || !$user || !$user->has_cap('access_s2member_level0')) && $page->ID !== (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
59 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => 0), get_defined_vars());
|
60 |
|
61 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'] && $page->ID === (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'] && (!$check_user || !$user || !$user->has_cap('access_s2member_level0')) && $page->ID !== (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
62 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => 0), get_defined_vars());
|
|
|
63 |
|
64 |
+
else if(!c_ws_plugin__s2member_systematics_sp::is_systematic_use_specific_page($page->ID, $page_uri)) // However, there are 3 exceptions above.
|
65 |
+
{
|
66 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Page Level restrictions. Go through each Level.
|
67 |
+
{
|
68 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] === 'all' && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
69 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
70 |
+
|
71 |
+
else if(strpos($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'], 'all-') !== FALSE && (in_array('all-page', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) || in_array('all-pages', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts']))) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
72 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
73 |
+
|
74 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] && in_array($page->ID, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'])) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
75 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
76 |
+
}
|
77 |
+
if(has_tag('', $page->ID)) // Here we take a look to see if this Page has any Tags. If so, we need to run the full set of routines against Tags also.
|
78 |
+
{
|
79 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Tag Level restrictions (possibly through Page Tagger). Go through each Level.
|
80 |
+
{
|
81 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] === 'all' && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
82 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
|
84 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] && has_tag(preg_split('/['."\r\n\t".';,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags']), $page->ID) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
85 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
86 |
}
|
87 |
+
}
|
88 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // URIs. Go through each Level.
|
89 |
+
{
|
90 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris']) // URIs configured at this Level?
|
91 |
+
|
92 |
+
foreach(preg_split('/['."\r\n\t".']+/', c_ws_plugin__s2member_ruris::fill_ruri_level_access_rc_vars($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris'], $user)) as $str)
|
93 |
+
if($str && preg_match('/'.preg_quote($str, '/').'/', $page_uri) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
94 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
95 |
+
}
|
96 |
+
if(is_array($ccaps_req = get_post_meta($page->ID, 's2member_ccaps_req', TRUE)) && !empty($ccaps_req))
|
97 |
+
{
|
98 |
+
foreach($ccaps_req as $ccap) // The ``$user`` MUST satisfy ALL Custom Capabilities.
|
99 |
+
if(strlen($ccap) && (!$check_user || !$user || !$user->has_cap('access_s2member_ccap_'.$ccap)))
|
100 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_ccap_req' => $ccap), get_defined_vars());
|
101 |
+
}
|
102 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'] && in_array($page->ID, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'])) && (!$check_user || !c_ws_plugin__s2member_sp_access::sp_access($page->ID, 'read-only')))
|
103 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', array('s2member_sp_req' => $page->ID), get_defined_vars());
|
104 |
}
|
105 |
+
do_action('ws_plugin__s2member_during_check_specific_page_level_access', get_defined_vars());
|
106 |
+
}
|
107 |
}
|
108 |
+
return apply_filters('ws_plugin__s2member_check_specific_page_level_access', NULL, get_defined_vars());
|
109 |
+
}
|
110 |
}
|
111 |
+
}
|
includes/classes/pages.inc.php
CHANGED
@@ -1,117 +1,108 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member's Page protection routines *(for current Page)*.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Pages
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
* @package s2Member\Pages
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @return null Or exits script execution after redirection.
|
37 |
-
*/
|
38 |
-
public static function check_page_level_access ()
|
39 |
-
{
|
40 |
-
global $post; // ``get_the_ID()`` unavailable outside The Loop.
|
41 |
-
|
42 |
-
do_action("ws_plugin__s2member_before_check_page_level_access", get_defined_vars ());
|
43 |
-
|
44 |
-
$excluded = apply_filters("ws_plugin__s2member_check_page_level_access_excluded", false, get_defined_vars ());
|
45 |
-
|
46 |
-
if (!$excluded && is_page () && is_object ($post) && !empty($post->ID) && ($page_id = (int)$post->ID) && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
47 |
-
{
|
48 |
-
if (!c_ws_plugin__s2member_systematics::is_wp_systematic_use_page ()) // Do NOT touch WordPress Systematics. This excludes all WordPress Systematics.
|
49 |
-
{
|
50 |
-
$user = (is_user_logged_in () && is_object ($user = wp_get_current_user ()) && !empty($user->ID)) ? $user : false; // Current User's object.
|
51 |
-
|
52 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && $page_id === (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"] && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level0")) && $page_id !== (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
53 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("page", $page_id, "level", 0, $_SERVER["REQUEST_URI"], "sys") . exit ();
|
54 |
-
|
55 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri ($user, "root-returns-false")) && preg_match ("/^" . preg_quote ($login_redirection_uri, "/") . "$/", $_SERVER["REQUEST_URI"]) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level0")) && $page_id !== (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
56 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("page", $page_id, "level", 0, $_SERVER["REQUEST_URI"], "sys") . exit ();
|
57 |
-
|
58 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"] && $page_id === (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"] && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level0")) && $page_id !== (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
59 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("page", $page_id, "level", 0, $_SERVER["REQUEST_URI"], "sys") . exit ();
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Page Level restrictions. Go through each Level.
|
64 |
-
{
|
65 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_pages"] === "all" && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
66 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("page", $page_id, "level", $n, $_SERVER["REQUEST_URI"]) . exit ();
|
67 |
|
68 |
-
|
69 |
-
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
}
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
}
|
95 |
-
|
96 |
-
if (is_array($ccaps_req = get_post_meta ($page_id, "s2member_ccaps_req", true)) && !empty($ccaps_req) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted'))
|
97 |
-
{
|
98 |
-
foreach ($ccaps_req as $ccap) // The ``$user`` MUST satisfy ALL Custom Capability requirements. Stored as an array of Custom Capabilities.
|
99 |
-
if (strlen ($ccap) && (!$user || !$user->has_cap ("access_s2member_ccap_" . $ccap)) /* Does this ``$user``, have this Custom Capability? */)
|
100 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("page", $page_id, "ccap", $ccap, $_SERVER["REQUEST_URI"], "ccap") . exit ();
|
101 |
-
}
|
102 |
-
|
103 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["specific_ids"] && in_array($page_id, preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["specific_ids"])) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && !c_ws_plugin__s2member_sp_access::sp_access ($page_id))
|
104 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("page", $page_id, "sp", $page_id, $_SERVER["REQUEST_URI"], "sp") . exit ();
|
105 |
-
}
|
106 |
|
107 |
-
|
108 |
-
|
109 |
}
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
|
|
|
|
115 |
}
|
|
|
|
|
116 |
}
|
117 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member's Page protection routines *(for current Page)*.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Pages
|
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_pages'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* s2Member's Page protection routines *(for current Page)*.
|
24 |
+
*
|
25 |
+
* @package s2Member\Pages
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_pages
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles Page Level Access permissions *(for current Page)*.
|
32 |
+
*
|
33 |
+
* @package s2Member\Pages
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @return null Or exits script execution after redirection.
|
37 |
+
*/
|
38 |
+
public static function check_page_level_access()
|
39 |
+
{
|
40 |
+
global $post; // ``get_the_ID()`` unavailable outside The Loop.
|
41 |
+
|
42 |
+
do_action('ws_plugin__s2member_before_check_page_level_access', get_defined_vars());
|
43 |
+
|
44 |
+
$excluded = apply_filters('ws_plugin__s2member_check_page_level_access_excluded', FALSE, get_defined_vars());
|
45 |
+
|
46 |
+
if(!$excluded && is_page() && is_object($post) && !empty($post->ID) && ($page_id = (int)$post->ID) && $GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
47 |
{
|
48 |
+
if(!c_ws_plugin__s2member_systematics::is_wp_systematic_use_page()) // Do NOT touch WordPress Systematics. This excludes all WordPress Systematics.
|
49 |
+
{
|
50 |
+
$user = (is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID)) ? $user : FALSE; // Current User's object.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'] && $page_id === (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'] && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level0')) && $page_id !== (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
53 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', 0, $_SERVER['REQUEST_URI'], 'sys').exit ();
|
|
|
|
|
|
|
|
|
54 |
|
55 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_override'] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri($user, 'root-returns-false')) && preg_match('/^'.preg_quote($login_redirection_uri, '/').'$/', $_SERVER['REQUEST_URI']) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level0')) && $page_id !== (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
56 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', 0, $_SERVER['REQUEST_URI'], 'sys').exit ();
|
57 |
|
58 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'] && $page_id === (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page'] && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level0')) && $page_id !== (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
59 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', 0, $_SERVER['REQUEST_URI'], 'sys').exit ();
|
|
|
60 |
|
61 |
+
else if(!c_ws_plugin__s2member_systematics::is_systematic_use_page()) // Never restrict Systematics. However, there are 3 exceptions above.
|
62 |
+
{
|
63 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Page Level restrictions. Go through each Level.
|
64 |
+
{
|
65 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] === 'all' && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
66 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
67 |
+
|
68 |
+
else if(strpos($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'], 'all-') && (in_array('all-page', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) || in_array('all-pages', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts']))) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
69 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', $n, $_SERVER['REQUEST_URI'], 'post').exit ();
|
70 |
+
|
71 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] && in_array($page_id, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'])) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
72 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
73 |
+
}
|
74 |
+
if(has_tag()) // Here we take a look to see if this Page has any Tags. If so, we need to run the full set of routines against Tags also.
|
75 |
+
{
|
76 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Tag Level restrictions (possibly through Page Tagger). Go through each Level.
|
77 |
+
{
|
78 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] === 'all' && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
79 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', $n, $_SERVER['REQUEST_URI'], 'ptag').exit ();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
|
81 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] && has_tag(preg_split('/['."\r\n\t".';,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'])) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
82 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', $n, $_SERVER['REQUEST_URI'], 'ptag').exit ();
|
83 |
}
|
84 |
+
}
|
85 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // URIs. Go through each Level.
|
86 |
+
{
|
87 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris']) // URIs configured at this Level?
|
88 |
+
|
89 |
+
foreach(preg_split('/['."\r\n\t".']+/', c_ws_plugin__s2member_ruris::fill_ruri_level_access_rc_vars($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris'], $user)) as $str)
|
90 |
+
if($str && preg_match('/'.preg_quote($str, '/').'/', $_SERVER['REQUEST_URI']) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
91 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'level', $n, $_SERVER['REQUEST_URI'], 'ruri').exit ();
|
92 |
+
}
|
93 |
+
if(is_array($ccaps_req = get_post_meta($page_id, 's2member_ccaps_req', TRUE)) && !empty($ccaps_req) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted'))
|
94 |
+
{
|
95 |
+
foreach($ccaps_req as $ccap) // The ``$user`` MUST satisfy ALL Custom Capability requirements. Stored as an array of Custom Capabilities.
|
96 |
+
if(strlen($ccap) && (!$user || !$user->has_cap('access_s2member_ccap_'.$ccap)) /* Does this ``$user``, have this Custom Capability? */)
|
97 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'ccap', $ccap, $_SERVER['REQUEST_URI'], 'ccap').exit ();
|
98 |
+
}
|
99 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'] && in_array($page_id, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'])) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && !c_ws_plugin__s2member_sp_access::sp_access($page_id))
|
100 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('page', $page_id, 'sp', $page_id, $_SERVER['REQUEST_URI'], 'sp').exit ();
|
101 |
}
|
102 |
+
do_action('ws_plugin__s2member_during_check_page_level_access', get_defined_vars());
|
103 |
+
}
|
104 |
}
|
105 |
+
do_action('ws_plugin__s2member_after_check_page_level_access', get_defined_vars());
|
106 |
+
}
|
107 |
}
|
108 |
+
}
|
includes/classes/paypal-return-in-subscr-modify-w-level.inc.php
CHANGED
@@ -216,11 +216,11 @@ if(!class_exists("c_ws_plugin__s2member_paypal_return_in_subscr_modify_w_level")
|
|
216 |
{
|
217 |
$paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
|
218 |
$paypal["s2member_log"][] = "s2Member `txn_type` identified as `subscr_modify`.";
|
219 |
-
$paypal[
|
220 |
|
221 |
-
echo c_ws_plugin__s2member_return_templates::return_template($paypal[
|
222 |
-
|
223 |
-
|
224 |
}
|
225 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
226 |
do_action("ws_plugin__s2member_during_paypal_return_after_subscr_modify", get_defined_vars());
|
216 |
{
|
217 |
$paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
|
218 |
$paypal["s2member_log"][] = "s2Member `txn_type` identified as `subscr_modify`.";
|
219 |
+
$paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
|
220 |
|
221 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
222 |
+
'<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
|
223 |
+
_x('Return to Home Page', 's2member-front', 's2member'), home_url("/"));
|
224 |
}
|
225 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
226 |
do_action("ws_plugin__s2member_during_paypal_return_after_subscr_modify", get_defined_vars());
|
includes/classes/paypal-return-in-subscr-or-wa-w-level.inc.php
CHANGED
@@ -1,384 +1,389 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\PayPal
|
15 |
-
* @since 110720
|
16 |
-
*/
|
17 |
-
if(realpath(__FILE__) === realpath($_SERVER[
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if(!class_exists(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
*
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
{
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
49 |
{
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
$paypal["s2member_log"][] = "Registration Cookies set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
|
287 |
-
|
288 |
-
setcookie("s2member_tracking", ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt($paypal["subscr_id"])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie("s2member_tracking", $s2member_tracking, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE["s2member_tracking"] = $s2member_tracking);
|
289 |
-
|
290 |
-
$paypal["s2member_log"][] = "Transient Tracking Cookie set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.";
|
291 |
-
|
292 |
-
if($processing && $tracking_properties && ($code = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["signup_tracking_codes"]) && is_array($cv = preg_split("/\|/", $paypal["custom"])))
|
293 |
-
{
|
294 |
-
if(($code = preg_replace("/%%cv([0-9]+)%%/ei", 'trim(@$cv[$1])', $code)) && ($code = preg_replace("/%%subscr_id%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_id"]), $code)))
|
295 |
-
if(($code = preg_replace("/%%subscr_baid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_baid"]), $code)) && ($code = preg_replace("/%%subscr_cid%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["subscr_cid"]), $code)))
|
296 |
-
if(($code = preg_replace("/%%initial%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["initial"]), $code)) && ($code = preg_replace("/%%regular%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["regular"]), $code)) && ($code = preg_replace("/%%recurring%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["recurring"]), $code)))
|
297 |
-
if(($code = preg_replace("/%%initial_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["initial_term"]), $code)) && ($code = preg_replace("/%%regular_term%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["regular_term"]), $code)))
|
298 |
-
if(($code = preg_replace("/%%item_number%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["item_number"]), $code)) && ($code = preg_replace("/%%item_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["item_name"]), $code)))
|
299 |
-
if(($code = preg_replace("/%%first_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["first_name"]), $code)) && ($code = preg_replace("/%%last_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["last_name"]), $code)))
|
300 |
-
if(($code = preg_replace("/%%full_name%%/i", c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal["first_name"]." ".$paypal["last_name"])), $code)))
|
301 |
-
if(($code = preg_replace("/%%payer_email%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["payer_email"]), $code)))
|
302 |
-
if(($code = preg_replace("/%%user_ip%%/i", c_ws_plugin__s2member_utils_strings::esc_refs($paypal["ip"]), $code)))
|
303 |
-
|
304 |
-
if(($code = trim(preg_replace("/%%(.+?)%%/i", "", $code))) /* This gets stored into a Transient Queue. */)
|
305 |
-
{
|
306 |
-
$paypal["s2member_log"][] = "Storing Signup Tracking Codes into a Transient Queue. These will be processed on-site.";
|
307 |
-
set_transient("s2m_".md5("s2member_transient_signup_tracking_codes_".$paypal["subscr_id"]), $code, 43200);
|
308 |
-
}
|
309 |
-
}
|
310 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
311 |
-
do_action("ws_plugin__s2member_during_paypal_return_during_subscr_signup_wo_update_vars", get_defined_vars());
|
312 |
-
unset($__refs, $__v);
|
313 |
-
|
314 |
-
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && is_main_site())
|
315 |
-
{
|
316 |
-
if(($redirection_url_after_mms_farm_signup = apply_filters("ws_plugin__s2member_redirection_url_after_mms_farm_signup", false, get_defined_vars())))
|
317 |
-
{
|
318 |
-
$paypal["s2member_log"][] = "Redirecting Customer to a custom URL after signup: ".$redirection_url_after_mms_farm_signup;
|
319 |
-
|
320 |
-
wp_redirect($redirection_url_after_mms_farm_signup);
|
321 |
-
}
|
322 |
-
else if /* Using a custom success redirection URL? */($custom_success_redirection)
|
323 |
-
{
|
324 |
-
$paypal["s2member_log"][] = "Redirecting Customer to a custom URL on success: ".$custom_success_redirection;
|
325 |
-
|
326 |
-
wp_redirect($custom_success_redirection);
|
327 |
-
}
|
328 |
-
else // Else use the default return URL in this scenario, which is the Signup Page.
|
329 |
-
{
|
330 |
-
$paypal["s2member_log"][] = "Redirecting Customer to Signup Page (after displaying a quick thank-you message). They need to Signup/Register now.";
|
331 |
-
|
332 |
-
echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"],
|
333 |
-
_x('<strong>Thank you! Your account has been approved.<br />The next step is to Register a Username for immediate access.</strong>', "s2member-front", "s2member"),
|
334 |
-
_x("Please Register Now (Click Here)", "s2member-front", "s2member"), c_ws_plugin__s2member_utils_urls::wp_signup_url());
|
335 |
-
}
|
336 |
-
}
|
337 |
-
else // Otherwise, this is NOT a Multisite install. Or it is, but the Super Administrator is NOT selling Blog creation.
|
338 |
-
{
|
339 |
-
if(($redirection_url_after_signup = apply_filters("ws_plugin__s2member_redirection_url_after_signup", false, get_defined_vars())))
|
340 |
-
{
|
341 |
-
$paypal["s2member_log"][] = "Redirecting Customer to a custom URL after signup: ".$redirection_url_after_signup;
|
342 |
-
|
343 |
-
wp_redirect($redirection_url_after_signup);
|
344 |
-
}
|
345 |
-
else if /* Using a custom success redirection URL? */($custom_success_redirection)
|
346 |
-
{
|
347 |
-
$paypal["s2member_log"][] = "Redirecting Customer to a custom URL on success: ".$custom_success_redirection;
|
348 |
-
|
349 |
-
wp_redirect($custom_success_redirection);
|
350 |
-
}
|
351 |
-
else // Else use the default return URL in this scenario, which is the Registration Page.
|
352 |
-
{
|
353 |
-
$paypal["s2member_log"][] = "Redirecting Customer to Registration Page (after displaying a quick thank-you message). They need to Register now.";
|
354 |
-
|
355 |
-
echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"],
|
356 |
-
_x('<strong>Thank you! Your account has been approved.<br />The next step is to Register a Username for immediate access.</strong>', "s2member-front", "s2member"),
|
357 |
-
_x("Please Register Now (Click Here)", "s2member-front", "s2member"), c_ws_plugin__s2member_utils_urls::wp_register_url());
|
358 |
-
}
|
359 |
-
}
|
360 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
361 |
-
do_action("ws_plugin__s2member_during_paypal_return_after_subscr_signup_wo_update_vars", get_defined_vars());
|
362 |
-
unset($__refs, $__v);
|
363 |
-
}
|
364 |
-
}
|
365 |
-
else // Page Expired. Duplicate Return-Data.
|
366 |
-
{
|
367 |
-
$paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
|
368 |
-
$paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept|subscr_signup|subscr_payment` ).";
|
369 |
-
$paypal["s2member_log"][] = "Page Expired. Redirecting Customer to the Home Page (after displaying an error message).";
|
370 |
-
|
371 |
-
echo c_ws_plugin__s2member_return_templates::return_template($paypal["subscr_gateway"],
|
372 |
-
_x('<strong>Page Expired:</strong> Duplicate Return-Data.<br />Please contact Support if you need any assistance.', "s2member-front", "s2member"),
|
373 |
-
_x("Back To Home Page", "s2member-front", "s2member"), home_url("/"));
|
374 |
-
}
|
375 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
376 |
-
do_action("ws_plugin__s2member_during_paypal_return_after_subscr_signup", get_defined_vars());
|
377 |
-
unset($__refs, $__v);
|
378 |
-
|
379 |
-
return apply_filters("c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level", $paypal, get_defined_vars());
|
380 |
}
|
381 |
-
|
|
|
|
|
|
|
382 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
}
|
384 |
-
|
|
|
|
|
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\PayPal
|
15 |
+
* @since 110720
|
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_paypal_return_in_subscr_or_wa_w_level'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
|
24 |
+
*
|
25 |
+
* @package s2Member\PayPal
|
26 |
+
* @since 110720
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level
|
29 |
{
|
30 |
/**
|
31 |
+
* s2Member's PayPal Auto-Return/PDT handler (inner processing routine).
|
32 |
+
*
|
33 |
+
* @package s2Member\PayPal
|
34 |
+
* @since 110720
|
35 |
+
*
|
36 |
+
* @param array $vars Required. An array of defined variables passed by {@link s2Member\PayPal\c_ws_plugin__s2member_paypal_return_in::paypal_return()}.
|
37 |
+
*
|
38 |
+
* @return array|bool The original ``$paypal`` array passed in (extracted) from ``$vars``, or false when conditions do NOT apply.
|
39 |
+
*/
|
40 |
+
public static function cp($vars = array()) // Conditional phase for ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
|
41 |
+
{
|
42 |
+
extract($vars, EXTR_OVERWRITE | EXTR_REFS); // Extract all vars passed in from: ``c_ws_plugin__s2member_paypal_notify_in::paypal_notify()``.
|
43 |
+
|
44 |
+
if((!empty($paypal['txn_type']) && preg_match('/^(web_accept|subscr_signup|subscr_payment)$/i', $paypal['txn_type']))
|
45 |
+
&& (!empty($paypal['item_number']) && preg_match($GLOBALS['WS_PLUGIN__']['s2member']['c']['membership_item_number_w_level_regex'], $paypal['item_number']))
|
46 |
+
&& (!empty($paypal['subscr_id']) || (!empty($paypal['txn_id']) && ($paypal['subscr_id'] = $paypal['txn_id'])))
|
47 |
+
&& (!empty($paypal['subscr_baid']) || ($paypal['subscr_baid'] = $paypal['subscr_id']))
|
48 |
+
&& (!empty($paypal['subscr_cid']) || ($paypal['subscr_cid'] = $paypal['subscr_id']))
|
49 |
+
&& (empty($paypal['payment_status']) || empty($payment_status_issues) || !preg_match($payment_status_issues, $paypal['payment_status']))
|
50 |
+
)
|
51 |
{
|
52 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
53 |
+
do_action('ws_plugin__s2member_during_paypal_return_before_subscr_signup', get_defined_vars());
|
54 |
+
unset($__refs, $__v); // Housekeeping.
|
55 |
+
|
56 |
+
if(!get_transient($transient_rtn = 's2m_rtn_'.md5('s2member_transient_'.$_paypal_s)) && set_transient($transient_rtn, time(), 31556926 * 10))
|
57 |
+
{
|
58 |
+
$paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept|subscr_signup|subscr_payment` ).';
|
59 |
+
|
60 |
+
list($paypal['level'], $paypal['ccaps'], $paypal['eotper']) = preg_split('/\:/', $paypal['item_number'], 3);
|
61 |
+
|
62 |
+
$paypal['ip'] = (preg_match('/ip address/i', $paypal['option_name2']) && $paypal['option_selection2']) ? $paypal['option_selection2'] : '';
|
63 |
+
$paypal['ip'] = (!$paypal['ip'] && preg_match('/^[a-z0-9]+~[0-9\.]+$/i', $paypal['invoice'])) ? preg_replace('/^[a-z0-9]+~/i', '', $paypal['invoice']) : $paypal['ip'];
|
64 |
+
$paypal['ip'] = (!$paypal['ip'] && $_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : $paypal['ip'];
|
65 |
+
|
66 |
+
if((preg_match('/^subscr_payment$/i', $paypal['txn_type']) && !empty($_GET['s2member_paypal_return_tra']))
|
67 |
+
&& (($tra = c_ws_plugin__s2member_utils_encryption::decrypt(trim(stripslashes($_GET['s2member_paypal_return_tra'])))) && is_array($tra = maybe_unserialize($tra)))
|
68 |
+
&& (count($tra) === 11 && isset($tra['ta'], $tra['tp'], $tra['tt'], $tra['ra'], $tra['rp'], $tra['rt'], $tra['rr'], $tra['rrt'], $tra['rra'], $tra['invoice'], $tra['checksum']))
|
69 |
+
&& ($tra['invoice'] === $paypal['invoice']) && ($tra['checksum'] === md5($paypal['invoice'].$paypal['ip'].$paypal['item_number']))
|
70 |
+
)
|
71 |
+
{
|
72 |
+
$tracking_properties = TRUE; // Yes, these tracking properties ARE being set here.
|
73 |
+
|
74 |
+
$paypal['period1'] = ($tra['rr'] !== 'BN' && $tra['tp']) ? $tra['tp'].' '.$tra['tt'] : '0 D';
|
75 |
+
$paypal['mc_amount1'] = ($tra['rr'] !== 'BN' && $tra['tp']) ? number_format($tra['ta'], 2, '.', '') : '0.00';
|
76 |
+
|
77 |
+
$paypal['period3'] = $tra['rp'].' '.$tra['rt'];
|
78 |
+
$paypal['mc_amount3'] = $tra['ra'];
|
79 |
+
|
80 |
+
$paypal['recurring'] = ($tra['rr'] === '1') ? '1' : '0';
|
81 |
+
|
82 |
+
$paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
|
83 |
+
$paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
|
84 |
+
$paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
|
85 |
+
$paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
|
86 |
+
$paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
|
87 |
+
|
88 |
+
$ipn_signup_vars = $paypal;
|
89 |
+
unset($ipn_signup_vars['s2member_log']); // Create array of wouldbe IPN signup vars w/o s2member_log.
|
90 |
+
}
|
91 |
+
else if(preg_match('/^(web_accept|subscr_signup)$/i', $paypal['txn_type']))
|
92 |
+
{
|
93 |
+
$tracking_properties = TRUE; // Yes, these tracking properties ARE being set here.
|
94 |
+
|
95 |
+
$paypal['period1'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
|
96 |
+
$paypal['mc_amount1'] = (strlen($paypal['mc_amount1']) && $paypal['mc_amount1'] > 0) ? $paypal['mc_amount1'] : '0.00';
|
97 |
+
|
98 |
+
if(preg_match('/^web_accept$/i', $paypal['txn_type']) /* Conversions for Lifetime & Fixed-Term sales. */)
|
99 |
+
{
|
100 |
+
$paypal['period3'] = ($paypal['eotper']) ? $paypal['eotper'] : '1 L'; // 1 Lifetime.
|
101 |
+
$paypal['mc_amount3'] = $paypal['mc_gross']; // The 'Buy Now' amount is the full gross.
|
102 |
+
}
|
103 |
+
$paypal['initial_term'] = (preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['period1'] : '0 D'; // Defaults to '0 D' (zero days).
|
104 |
+
$paypal['initial'] = (strlen($paypal['mc_amount1']) && preg_match('/^[1-9]/', $paypal['period1'])) ? $paypal['mc_amount1'] : $paypal['mc_amount3'];
|
105 |
+
$paypal['regular'] = $paypal['mc_amount3']; // This is the Regular Payment Amount that is charged to the Customer. Always required by PayPal.
|
106 |
+
$paypal['regular_term'] = $paypal['period3']; // This is just set to keep a standard; this way both initial_term & regular_term are available.
|
107 |
+
$paypal['recurring'] = ($paypal['recurring']) ? $paypal['mc_amount3'] : '0'; // If non-recurring, this should be zero, otherwise Regular.
|
108 |
+
|
109 |
+
$ipn_signup_vars = $paypal;
|
110 |
+
unset($ipn_signup_vars['s2member_log']); // Create array of wouldbe IPN signup vars w/o s2member_log.
|
111 |
+
}
|
112 |
+
else $tracking_properties = FALSE; // Not possible.
|
113 |
+
/*
|
114 |
+
New Subscription with advanced update vars (option_name1, option_selection1)? Used in Subscr. Modifications.
|
115 |
+
*/
|
116 |
+
if(preg_match('/(referenc|associat|updat|upgrad)/i', $paypal['option_name1']) && $paypal['option_selection1'])
|
117 |
{
|
118 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
119 |
+
do_action('ws_plugin__s2member_during_paypal_return_before_subscr_signup_w_update_vars', get_defined_vars());
|
120 |
+
unset($__refs, $__v); // Housekeeping.
|
121 |
+
|
122 |
+
$paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept|subscr_signup|subscr_payment` ) w/ update vars.';
|
123 |
+
|
124 |
+
if(($user_id = c_ws_plugin__s2member_utils_users::get_user_id_with($paypal['subscr_id'], $paypal['option_selection1'])) && is_object($user = new WP_User($user_id)) && $user->ID)
|
125 |
+
{
|
126 |
+
if(!$user->has_cap('administrator') /* Do NOT process this routine on Administrators. */)
|
127 |
{
|
128 |
+
$processing = $modifying = $during = TRUE; // Yes, we ARE processing this.
|
129 |
+
|
130 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
131 |
+
do_action('ws_plugin__s2member_during_paypal_return_during_before_subscr_signup_w_update_vars', get_defined_vars());
|
132 |
+
do_action('ws_plugin__s2member_during_collective_mods', $user_id, get_defined_vars(), 'rtn-upgrade-downgrade', 'modification', 's2member_level'.$paypal['level']);
|
133 |
+
unset($__refs, $__v); // Housekeeping.
|
134 |
+
|
135 |
+
$fields = get_user_option('s2member_custom_fields', $user_id); // These will be needed in the routines below.
|
136 |
+
$user_reg_ip = get_user_option('s2member_registration_ip', $user_id); // Original IP during Registration.
|
137 |
+
$user_reg_ip = $paypal['ip'] = ($user_reg_ip) ? $user_reg_ip : $paypal['ip']; // Now merge conditionally.
|
138 |
+
|
139 |
+
if(is_multisite() && !is_user_member_of_blog($user_id) /* Must have a Role on this Blog. */)
|
140 |
+
{
|
141 |
+
add_existing_user_to_blog(array('user_id' => $user_id, 'role' => 's2member_level'.$paypal['level']));
|
142 |
+
$user = new WP_User($user_id);
|
143 |
+
}
|
144 |
+
$current_role = c_ws_plugin__s2member_user_access::user_access_role($user);
|
145 |
+
|
146 |
+
if($current_role !== 's2member_level'.$paypal['level']) // Only if we need to.
|
147 |
+
$user->set_role('s2member_level'.$paypal['level']);
|
148 |
+
|
149 |
+
if($paypal['ccaps'] && preg_match('/^-all/', str_replace('+', '', $paypal['ccaps'])))
|
150 |
+
foreach($user->allcaps as $cap => $cap_enabled)
|
151 |
+
if(preg_match('/^access_s2member_ccap_/', $cap))
|
152 |
+
$user->remove_cap($ccap = $cap);
|
153 |
+
|
154 |
+
if($paypal['ccaps'] && preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps'])))
|
155 |
+
foreach(preg_split('/['."\r\n\t".'\s;,]+/', preg_replace('/^-all['."\r\n\t".'\s;,]*/', '', str_replace('+', '', $paypal['ccaps']))) as $ccap)
|
156 |
+
if(strlen($ccap = trim(strtolower(preg_replace('/[^a-z_0-9]/i', '', $ccap)))))
|
157 |
+
$user->add_cap('access_s2member_ccap_'.$ccap);
|
158 |
+
|
159 |
+
update_user_option($user_id, 's2member_subscr_gateway', $paypal['subscr_gateway']);
|
160 |
+
update_user_option($user_id, 's2member_subscr_id', $paypal['subscr_id']);
|
161 |
+
update_user_option($user_id, 's2member_subscr_baid', $paypal['subscr_baid']);
|
162 |
+
update_user_option($user_id, 's2member_subscr_cid', $paypal['subscr_cid']);
|
163 |
+
|
164 |
+
update_user_option($user_id, 's2member_custom', $paypal['custom']);
|
165 |
+
|
166 |
+
if(!get_user_option('s2member_registration_ip', $user_id))
|
167 |
+
update_user_option($user_id, 's2member_registration_ip', $paypal['ip']);
|
168 |
+
|
169 |
+
if(!empty($ipn_signup_vars)) // We should have these from the routines above.
|
170 |
+
update_user_option($user_id, 's2member_ipn_signup_vars', $ipn_signup_vars);
|
171 |
+
|
172 |
+
delete_user_option($user_id, 's2member_file_download_access_log');
|
173 |
+
|
174 |
+
if((preg_match('/^web_accept$/i', $paypal['txn_type']) || ($paypal['initial'] <= 0 && $paypal['regular'] <= 0)) && $paypal['eotper'])
|
175 |
+
{
|
176 |
+
// Don't update this in the return routine. Leave this for the IPN routine.
|
177 |
+
// EOT Times might be extended, and we don't want the IPN routine to extend an already-extended EOT Time.
|
178 |
+
$eot_time = c_ws_plugin__s2member_utils_time::auto_eot_time('', '', '', $paypal['eotper'], '', get_user_option('s2member_auto_eot_time', $user_id));
|
179 |
+
$paypal['s2member_log'][] = 'Automatic EOT (End Of Term) Time will be set to: '.date('D M j, Y g:i:s a T', $eot_time).'.';
|
180 |
+
}
|
181 |
+
else // Otherwise, we need to clear the Auto-EOT Time.
|
182 |
+
delete_user_option($user_id, 's2member_auto_eot_time');
|
183 |
+
|
184 |
+
$pr_times = get_user_option('s2member_paid_registration_times', $user_id);
|
185 |
+
$pr_times['level'] = (!$pr_times['level']) ? time() : $pr_times['level']; // Preserve existing.
|
186 |
+
$pr_times['level'.$paypal['level']] = (!$pr_times['level'.$paypal['level']]) ? time() : $pr_times['level'.$paypal['level']];
|
187 |
+
update_user_option($user_id, 's2member_paid_registration_times', $pr_times);
|
188 |
+
|
189 |
+
c_ws_plugin__s2member_user_notes::clear_user_note_lines($user_id, '/^Demoted by s2Member\:/');
|
190 |
+
c_ws_plugin__s2member_user_notes::clear_user_note_lines($user_id, '/^Paid Subscr\. ID @ time of demotion\:/');
|
191 |
+
|
192 |
+
$paypal['s2member_log'][] = 's2Member Level/Capabilities updated w/ advanced update routines.';
|
193 |
+
|
194 |
+
setcookie('s2member_tracking', ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['subscr_id'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_tracking', $s2member_tracking, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_tracking'] = $s2member_tracking);
|
195 |
+
|
196 |
+
$paypal['s2member_log'][] = 'Transient Tracking Cookie set on ( `web_accept|subscr_signup|subscr_payment` ) w/ update vars.';
|
197 |
+
|
198 |
+
if($processing && $tracking_properties && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['modification_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
|
199 |
+
{
|
200 |
+
if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
|
201 |
+
if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
|
202 |
+
if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
|
203 |
+
if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
|
204 |
+
if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
|
205 |
+
if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
|
206 |
+
if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
|
207 |
+
if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
|
208 |
+
{
|
209 |
+
if(($code = preg_replace('/%%user_first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->first_name), $code)) && ($code = preg_replace('/%%user_last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->last_name), $code)))
|
210 |
+
if(($code = preg_replace('/%%user_full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($user->first_name.' '.$user->last_name)), $code)))
|
211 |
+
if(($code = preg_replace('/%%user_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_email), $code)))
|
212 |
+
if(($code = preg_replace('/%%user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user->user_login), $code)))
|
213 |
+
if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_reg_ip), $code)))
|
214 |
+
if(($code = preg_replace('/%%user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($user_id), $code)))
|
215 |
+
{
|
216 |
+
if(is_array($fields) && !empty($fields))
|
217 |
+
foreach($fields as $var => $val) // Custom Registration/Profile Fields.
|
218 |
+
if(!($code = preg_replace('/%%'.preg_quote($var, '/').'%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(maybe_serialize($val)), $code)))
|
219 |
+
break;
|
220 |
+
|
221 |
+
if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
|
222 |
+
{
|
223 |
+
$paypal['s2member_log'][] = 'Storing Modification Tracking Codes into a Transient Queue. These will be processed on-site.';
|
224 |
+
set_transient('s2m_'.md5('s2member_transient_modification_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
|
225 |
+
}
|
226 |
+
}
|
227 |
+
}
|
228 |
+
}
|
229 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
230 |
+
do_action('ws_plugin__s2member_during_paypal_return_during_subscr_signup_w_update_vars', get_defined_vars());
|
231 |
+
unset($__refs, $__v); // Housekeeping.
|
232 |
+
|
233 |
+
if(($redirection_url_after_modification = apply_filters('ws_plugin__s2member_redirection_url_after_modification', FALSE, get_defined_vars())))
|
234 |
+
{
|
235 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to a custom URL after modification: '.$redirection_url_after_modification;
|
236 |
+
|
237 |
+
wp_redirect($redirection_url_after_modification);
|
238 |
+
}
|
239 |
+
else // Else, use standard/default handling in this scenario. Have the Customer log in again.
|
240 |
+
{
|
241 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to the Login Page (after displaying a quick thank-you message). They need to log back in.';
|
242 |
+
|
243 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
244 |
+
'<strong>'._x('Thank you! You\'ve been updated to:', 's2member-front', 's2member').'<br /><em>'.esc_html($paypal['item_name']).'</em></strong>',
|
245 |
+
_x('Please Log Back In (Click Here)', 's2member-front', 's2member'), wp_login_url());
|
246 |
+
}
|
247 |
+
}
|
248 |
+
else // Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here.
|
249 |
+
{
|
250 |
+
$paypal['s2member_log'][] = 'Unable to modify Subscription. The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.';
|
251 |
+
|
252 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
|
253 |
+
|
254 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
255 |
+
_x('<strong>ERROR:</strong> Unable to modify Subscription.<br />Please contact Support for assistance.<br /><br />The existing User ID is associated with an Administrator. Stopping here. Otherwise, an Administrator could lose access. Please make sure that you are NOT logged in as an Administrator while testing.', 's2member-front', 's2member'),
|
256 |
+
_x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
|
257 |
+
}
|
258 |
+
}
|
259 |
+
else // Unable to modify Subscription. Could not get the existing User ID from the DB.
|
260 |
+
{
|
261 |
+
$paypal['s2member_log'][] = 'Unable to modify Subscription. Could not get the existing User ID from the DB.';
|
262 |
+
|
263 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to the Home Page (after displaying an error message).';
|
264 |
+
|
265 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
266 |
+
_x('<strong>ERROR:</strong> Unable to modify Subscription.<br />Please contact Support for assistance.<br /><br />Could not get the existing User ID from the DB.', 's2member-front', 's2member'),
|
267 |
+
_x('Back To Home Page', 's2member-front', 's2member'), home_url('/'));
|
268 |
+
}
|
269 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
270 |
+
do_action('ws_plugin__s2member_during_paypal_return_after_subscr_signup_w_update_vars', get_defined_vars());
|
271 |
+
unset($__refs, $__v); // Housekeeping.
|
272 |
+
}
|
273 |
+
/*
|
274 |
+
New Subscription. Normal Subscription signup, we are not updating anything for a past Subscription.
|
275 |
+
*/
|
276 |
+
else // Else this is a normal Subscription signup, we are not updating an existing Subscription.
|
277 |
+
{
|
278 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
279 |
+
do_action('ws_plugin__s2member_during_paypal_return_before_subscr_signup_wo_update_vars', get_defined_vars());
|
280 |
+
unset($__refs, $__v);
|
281 |
+
|
282 |
+
$processing = $during = TRUE; // Yes, we ARE processing this new Subscription request.
|
283 |
+
|
284 |
+
$paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.';
|
285 |
+
|
286 |
+
setcookie('s2member_subscr_gateway', ($s2member_subscr_gateway = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['subscr_gateway'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_subscr_gateway', $s2member_subscr_gateway, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_subscr_gateway'] = $s2member_subscr_gateway);
|
287 |
+
setcookie('s2member_subscr_id', ($s2member_subscr_id = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['subscr_id'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_subscr_id', $s2member_subscr_id, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_subscr_id'] = $s2member_subscr_id);
|
288 |
+
setcookie('s2member_custom', ($s2member_custom = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['custom'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_custom', $s2member_custom, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_custom'] = $s2member_custom);
|
289 |
+
setcookie('s2member_item_number', ($s2member_item_number = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['item_number'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_item_number', $s2member_item_number, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_item_number'] = $s2member_item_number);
|
290 |
+
|
291 |
+
$paypal['s2member_log'][] = 'Registration Cookies set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.';
|
292 |
+
|
293 |
+
setcookie('s2member_tracking', ($s2member_tracking = c_ws_plugin__s2member_utils_encryption::encrypt($paypal['subscr_id'])), time() + 31556926, COOKIEPATH, COOKIE_DOMAIN).setcookie('s2member_tracking', $s2member_tracking, time() + 31556926, SITECOOKIEPATH, COOKIE_DOMAIN).($_COOKIE['s2member_tracking'] = $s2member_tracking);
|
294 |
+
|
295 |
+
$paypal['s2member_log'][] = 'Transient Tracking Cookie set on ( `web_accept|subscr_signup|subscr_payment` ) w/o update vars.';
|
296 |
+
|
297 |
+
if($processing && $tracking_properties && ($code = $GLOBALS['WS_PLUGIN__']['s2member']['o']['signup_tracking_codes']) && is_array($cv = preg_split('/\|/', $paypal['custom'])))
|
298 |
+
{
|
299 |
+
if(($code = preg_replace('/%%cv([0-9]+)%%/ei', 'trim(@$cv[$1])', $code)) && ($code = preg_replace('/%%subscr_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_id']), $code)))
|
300 |
+
if(($code = preg_replace('/%%subscr_baid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_baid']), $code)) && ($code = preg_replace('/%%subscr_cid%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['subscr_cid']), $code)))
|
301 |
+
if(($code = preg_replace('/%%initial%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial']), $code)) && ($code = preg_replace('/%%regular%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular']), $code)) && ($code = preg_replace('/%%recurring%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['recurring']), $code)))
|
302 |
+
if(($code = preg_replace('/%%initial_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['initial_term']), $code)) && ($code = preg_replace('/%%regular_term%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['regular_term']), $code)))
|
303 |
+
if(($code = preg_replace('/%%item_number%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_number']), $code)) && ($code = preg_replace('/%%item_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['item_name']), $code)))
|
304 |
+
if(($code = preg_replace('/%%first_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['first_name']), $code)) && ($code = preg_replace('/%%last_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['last_name']), $code)))
|
305 |
+
if(($code = preg_replace('/%%full_name%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(trim($paypal['first_name'].' '.$paypal['last_name'])), $code)))
|
306 |
+
if(($code = preg_replace('/%%payer_email%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['payer_email']), $code)))
|
307 |
+
if(($code = preg_replace('/%%user_ip%%/i', c_ws_plugin__s2member_utils_strings::esc_refs($paypal['ip']), $code)))
|
308 |
+
|
309 |
+
if(($code = trim(preg_replace('/%%(.+?)%%/i', '', $code))) /* This gets stored into a Transient Queue. */)
|
310 |
+
{
|
311 |
+
$paypal['s2member_log'][] = 'Storing Signup Tracking Codes into a Transient Queue. These will be processed on-site.';
|
312 |
+
set_transient('s2m_'.md5('s2member_transient_signup_tracking_codes_'.$paypal['subscr_id']), $code, 43200);
|
313 |
+
}
|
314 |
+
}
|
315 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
316 |
+
do_action('ws_plugin__s2member_during_paypal_return_during_subscr_signup_wo_update_vars', get_defined_vars());
|
317 |
+
unset($__refs, $__v); // Housekeeping.
|
318 |
+
|
319 |
+
if(is_multisite() && c_ws_plugin__s2member_utils_conds::is_multisite_farm() && is_main_site())
|
320 |
+
{
|
321 |
+
if(($redirection_url_after_mms_farm_signup = apply_filters('ws_plugin__s2member_redirection_url_after_mms_farm_signup', FALSE, get_defined_vars())))
|
322 |
+
{
|
323 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to a custom URL after signup: '.$redirection_url_after_mms_farm_signup;
|
324 |
+
|
325 |
+
wp_redirect($redirection_url_after_mms_farm_signup);
|
326 |
+
}
|
327 |
+
else if(!empty($custom_success_redirection)) // Using a custom success redirection URL?
|
328 |
+
{
|
329 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to a custom URL on success: '.$custom_success_redirection;
|
330 |
+
|
331 |
+
wp_redirect($custom_success_redirection);
|
332 |
+
}
|
333 |
+
else // Else use the default return URL in this scenario, which is the Signup Page.
|
334 |
+
{
|
335 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to Signup Page (after displaying a quick thank-you message). They need to Signup/Register now.';
|
336 |
+
|
337 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
338 |
+
_x('<strong>Thank you! Your account has been approved.<br />The next step is to Register a Username for immediate access.</strong>', 's2member-front', 's2member'),
|
339 |
+
_x('Please Register Now (Click Here)', 's2member-front', 's2member'), c_ws_plugin__s2member_utils_urls::wp_signup_url());
|
340 |
+
}
|
341 |
+
}
|
342 |
+
else // Otherwise, this is NOT a Multisite install. Or it is, but the Super Administrator is NOT selling Blog creation.
|
343 |
+
{
|
344 |
+
if(($redirection_url_after_signup = apply_filters('ws_plugin__s2member_redirection_url_after_signup', FALSE, get_defined_vars())))
|
345 |
+
{
|
346 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to a custom URL after signup: '.$redirection_url_after_signup;
|
347 |
+
|
348 |
+
wp_redirect($redirection_url_after_signup);
|
349 |
+
}
|
350 |
+
else if(!empty($custom_success_redirection)) // Using a custom success redirection URL?
|
351 |
+
{
|
352 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to a custom URL on success: '.$custom_success_redirection;
|
353 |
+
|
354 |
+
wp_redirect($custom_success_redirection);
|
355 |
+
}
|
356 |
+
else // Else use the default return URL in this scenario, which is the Registration Page.
|
357 |
+
{
|
358 |
+
$paypal['s2member_log'][] = 'Redirecting Customer to Registration Page (after displaying a quick thank-you message). They need to Register now.';
|
359 |
+
|
360 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
361 |
+
_x('<strong>Thank you! Your account has been approved.<br />The next step is to Register a Username for immediate access.</strong>', 's2member-front', 's2member'),
|
362 |
+
_x('Please Register Now (Click Here)', 's2member-front', 's2member'), c_ws_plugin__s2member_utils_urls::wp_register_url());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
}
|
364 |
+
}
|
365 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
366 |
+
do_action('ws_plugin__s2member_during_paypal_return_after_subscr_signup_wo_update_vars', get_defined_vars());
|
367 |
+
unset($__refs, $__v); // Housekeeping.
|
368 |
}
|
369 |
+
}
|
370 |
+
else // Page Expired. Duplicate Return-Data.
|
371 |
+
{
|
372 |
+
$paypal['s2member_log'][] = 'Page Expired. Duplicate Return-Data.';
|
373 |
+
$paypal['s2member_log'][] = 's2Member `txn_type` identified as ( `web_accept|subscr_signup|subscr_payment` ).';
|
374 |
+
$paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
|
375 |
+
|
376 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
377 |
+
'<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
|
378 |
+
_x('Return to Home Page', 's2member-front', 's2member'), home_url("/"));
|
379 |
+
}
|
380 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
381 |
+
do_action('ws_plugin__s2member_during_paypal_return_after_subscr_signup', get_defined_vars());
|
382 |
+
unset($__refs, $__v); // Housekeeping.
|
383 |
+
|
384 |
+
return apply_filters('c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level', $paypal, get_defined_vars());
|
385 |
}
|
386 |
+
else return apply_filters('c_ws_plugin__s2member_paypal_return_in_subscr_or_wa_w_level', FALSE, get_defined_vars());
|
387 |
+
}
|
388 |
+
}
|
389 |
+
}
|
includes/classes/paypal-return-in-wa-ccaps-wo-level.inc.php
CHANGED
@@ -183,11 +183,11 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_wa_ccaps_wo_level"))
|
|
183 |
{
|
184 |
$paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
|
185 |
$paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
|
186 |
-
$paypal[
|
187 |
|
188 |
-
echo c_ws_plugin__s2member_return_templates::return_template
|
189 |
-
|
190 |
-
|
191 |
}
|
192 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
193 |
do_action("ws_plugin__s2member_during_paypal_return_after_new_ccaps", get_defined_vars ());
|
183 |
{
|
184 |
$paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
|
185 |
$paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) w/ update vars for Capabilities w/o Level.";
|
186 |
+
$paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
|
187 |
|
188 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
189 |
+
'<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
|
190 |
+
_x('Return to Home Page', 's2member-front', 's2member'), home_url("/"));
|
191 |
}
|
192 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
193 |
do_action("ws_plugin__s2member_during_paypal_return_after_new_ccaps", get_defined_vars ());
|
includes/classes/paypal-return-in-web-accept-sp.inc.php
CHANGED
@@ -124,11 +124,11 @@ if (!class_exists ("c_ws_plugin__s2member_paypal_return_in_web_accept_sp"))
|
|
124 |
{
|
125 |
$paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
|
126 |
$paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.";
|
127 |
-
$paypal[
|
128 |
|
129 |
-
echo c_ws_plugin__s2member_return_templates::return_template
|
130 |
-
|
131 |
-
|
132 |
}
|
133 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
134 |
do_action("ws_plugin__s2member_during_paypal_return_after_sp_access", get_defined_vars ());
|
124 |
{
|
125 |
$paypal["s2member_log"][] = "Page Expired. Duplicate Return-Data.";
|
126 |
$paypal["s2member_log"][] = "s2Member `txn_type` identified as ( `web_accept` ) for Specific Post/Page Access.";
|
127 |
+
$paypal['s2member_log'][] = 'Page Expired. Instructing customer to check their email for further details about how to obtain access to what they purchased.';
|
128 |
|
129 |
+
echo c_ws_plugin__s2member_return_templates::return_template($paypal['subscr_gateway'],
|
130 |
+
'<strong>'._x('Thank you! Please check your email for further details regarding your purchase.', 's2member-front', 's2member').'</strong>',
|
131 |
+
_x('Return to Home Page', 's2member-front', 's2member'), home_url("/"));
|
132 |
}
|
133 |
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
134 |
do_action("ws_plugin__s2member_during_paypal_return_after_sp_access", get_defined_vars ());
|
includes/classes/posts-sp.inc.php
CHANGED
@@ -1,120 +1,135 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member's Post protection routines *(for specific Posts)*.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Posts
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit (
|
19 |
-
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
* Handles Post Level Access *(for specific Posts)*.
|
32 |
-
*
|
33 |
-
* @package s2Member\Posts
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @param int|string $post_id Numeric Post ID.
|
37 |
-
* @param bool $check_user Test permissions against the current User? Defaults to true.
|
38 |
-
* @return null|array Non-empty array(with details) if access is denied, else null if access is allowed.
|
39 |
-
*/
|
40 |
-
public static function check_specific_post_level_access ($post_id = FALSE, $check_user = TRUE)
|
41 |
-
{
|
42 |
-
do_action("ws_plugin__s2member_before_check_specific_post_level_access", get_defined_vars ());
|
43 |
-
|
44 |
-
$excluded = apply_filters("ws_plugin__s2member_check_specific_post_level_access_excluded", false, get_defined_vars ());
|
45 |
-
|
46 |
-
if (!$excluded && is_numeric ($post_id) && ($post_id = (int)$post_id) && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"])
|
47 |
-
{
|
48 |
-
$post_uri = c_ws_plugin__s2member_utils_urls::parse_uri (get_permalink ($post_id)); // Get a full valid URI for this Post now.
|
49 |
-
|
50 |
-
if (!c_ws_plugin__s2member_systematics_sp::is_wp_systematic_use_specific_page ($post_id, $post_uri)) // Do NOT touch WordPress Systematics.
|
51 |
-
{
|
52 |
-
$user = (is_user_logged_in () && is_object ($user = wp_get_current_user ()) && !empty($user->ID)) ? $user : false; // Current User's object.
|
53 |
-
|
54 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri ($user, "root-returns-false")) && preg_match ("/^" . preg_quote ($login_redirection_uri, "/") . "$/", $post_uri) && (!$check_user || !$user || !$user->has_cap ("access_s2member_level0")))
|
55 |
-
return apply_filters("ws_plugin__s2member_check_specific_post_level_access", array("s2member_level_req" => 0), get_defined_vars ());
|
56 |
-
|
57 |
-
else if (!c_ws_plugin__s2member_systematics_sp::is_systematic_use_specific_page ($post_id, $post_uri)) // Never restrict Systematics. However, there is 1 exception above.
|
58 |
-
{
|
59 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Post Level restrictions (including Custom Post Types). Go through each Level.
|
60 |
-
{
|
61 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"] === "all" && (!$check_user || !$user || !$user->has_cap ("access_s2member_level" . $n)))
|
62 |
-
return apply_filters("ws_plugin__s2member_check_specific_post_level_access", array("s2member_level_req" => $n), get_defined_vars ());
|
63 |
-
|
64 |
-
else if (strpos ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"], "all-") !== false && ($post_type = get_post_type ($post_id)) && (in_array("all-" . $post_type, preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"])) || in_array("all-" . $post_type . "s", preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"]))) && (!$check_user || !$user || !$user->has_cap ("access_s2member_level" . $n)))
|
65 |
-
return apply_filters("ws_plugin__s2member_check_specific_post_level_access", array("s2member_level_req" => $n), get_defined_vars ());
|
66 |
-
|
67 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"] && in_array($post_id, preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"])) && (!$check_user || !$user || !$user->has_cap ("access_s2member_level" . $n)))
|
68 |
-
return apply_filters("ws_plugin__s2member_check_specific_post_level_access", array("s2member_level_req" => $n), get_defined_vars ());
|
69 |
-
}
|
70 |
-
|
71 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Category Level Access against this Post. Go through each Level.
|
72 |
-
{
|
73 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_catgs"] === "all" && (!$check_user || !$user || !$user->has_cap ("access_s2member_level" . $n)))
|
74 |
-
return apply_filters("ws_plugin__s2member_check_specific_post_level_access", array("s2member_level_req" => $n), get_defined_vars ());
|
75 |
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Tag Level restrictions now. Go through each Level.
|
83 |
-
{
|
84 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ptags"] === "all" && (!$check_user || !$user || !$user->has_cap ("access_s2member_level" . $n)))
|
85 |
-
return apply_filters("ws_plugin__s2member_check_specific_post_level_access", array("s2member_level_req" => $n), get_defined_vars ());
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
}
|
|
|
|
|
118 |
}
|
|
|
|
|
119 |
}
|
120 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member's Post protection routines *(for specific Posts)*.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Posts
|
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_posts_sp'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* s2Member's Post protection routines *(for specific Posts)*.
|
24 |
+
*
|
25 |
+
* @package s2Member\Posts
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_posts_sp
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles Post Level Access *(for specific Posts)*.
|
32 |
+
*
|
33 |
+
* @package s2Member\Posts
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @param int|string $post_id Numeric Post ID.
|
37 |
+
* @param bool $check_user Test permissions against the current User? Defaults to true.
|
38 |
+
*
|
39 |
+
* @return null|array Non-empty array(with details) if access is denied, else null if access is allowed.
|
40 |
+
*/
|
41 |
+
public static function check_specific_post_level_access($post_id = 0, $check_user = TRUE)
|
42 |
+
{
|
43 |
+
do_action('ws_plugin__s2member_before_check_specific_post_level_access', get_defined_vars());
|
44 |
+
|
45 |
+
$excluded = apply_filters('ws_plugin__s2member_check_specific_post_level_access_excluded', FALSE, get_defined_vars());
|
46 |
+
|
47 |
+
if(!$excluded && is_numeric($post_id) && ($post_id = (int)$post_id) && ($post = get_post($post_id)) && $GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
48 |
{
|
49 |
+
$post_uri = c_ws_plugin__s2member_utils_urls::parse_uri(get_permalink($post->ID)); // Get a full valid URI for this Post now.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
+
if(!c_ws_plugin__s2member_systematics_sp::is_wp_systematic_use_specific_page($post->ID, $post_uri)) // Do NOT touch WordPress Systematics.
|
52 |
+
{
|
53 |
+
$user = (is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID)) ? $user : FALSE; // Current User's object.
|
54 |
|
55 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_override'] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri($user, 'root-returns-false')) && preg_match('/^'.preg_quote($login_redirection_uri, '/').'$/', $post_uri) && (!$check_user || !$user || !$user->has_cap('access_s2member_level0')))
|
56 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => 0), get_defined_vars());
|
|
|
|
|
|
|
|
|
57 |
|
58 |
+
else if(!c_ws_plugin__s2member_systematics_sp::is_systematic_use_specific_page($post->ID, $post_uri)) // However, there is the one exception above.
|
59 |
+
{
|
60 |
+
$bbpress_restrictions_enable = apply_filters('ws_plugin__s2member_bbpress_restrictions_enable', TRUE);
|
61 |
+
$bbpress_installed = c_ws_plugin__s2member_utils_conds::bbp_is_installed(); // bbPress is installed?
|
62 |
+
$bbpress_forum_post_type = $bbpress_installed ? bbp_get_forum_post_type() : ''; // Acquire the current post type for forums.
|
63 |
+
$bbpress_topic_post_type = $bbpress_installed ? bbp_get_topic_post_type() : ''; // Acquire the current post type for topics.
|
64 |
+
$bbpress_topic_forum_id = $bbpress_installed && $post->post_type === $bbpress_topic_post_type ? bbp_get_topic_forum_id($post->ID) : 0;
|
65 |
+
|
66 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Post Level restrictions.
|
67 |
+
{
|
68 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] === 'all' && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
69 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
70 |
+
|
71 |
+
else if(strpos($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'], 'all-') !== FALSE && $post->post_type && (in_array('all-'.$post->post_type, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) || in_array('all-'.$post->post_type.'s', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts']))) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
72 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
73 |
+
|
74 |
+
else if($bbpress_restrictions_enable && $bbpress_installed && $post->post_type === $bbpress_topic_post_type && strpos($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'], 'all-') !== FALSE && (in_array('all-'.$bbpress_forum_post_type, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) || in_array('all-'.$bbpress_forum_post_type.'s', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts']))) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
75 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
76 |
+
|
77 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] && in_array($post->ID, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
78 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
79 |
+
}
|
80 |
+
if($bbpress_restrictions_enable && $bbpress_installed && $post->post_type === $bbpress_topic_post_type && $bbpress_topic_forum_id)
|
81 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Forum restrictions.
|
82 |
+
{
|
83 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] && in_array($bbpress_topic_forum_id, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
84 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
85 |
}
|
86 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Category Level restrictions.
|
87 |
+
{
|
88 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'] === 'all' && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
89 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
90 |
+
|
91 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'] && (in_category(($catgs = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'])), $post->ID) || c_ws_plugin__s2member_utils_conds::in_descendant_category($catgs, $post->ID)) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
92 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
93 |
+
}
|
94 |
+
if(has_tag('', $post->ID)) // Here we take a look to see if this Post has any Tags. If so, we need to run the full set of routines against Tags also.
|
95 |
+
{
|
96 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Tag Level restrictions.
|
97 |
+
{
|
98 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] === 'all' && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
99 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
100 |
|
101 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] && has_tag(preg_split('/['."\r\n\t".';,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags']), $post->ID) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
102 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
103 |
+
}
|
104 |
+
}
|
105 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // URIs.
|
106 |
+
{
|
107 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris']) // URIs configured at this Level?
|
108 |
+
|
109 |
+
foreach(preg_split('/['."\r\n\t".']+/', c_ws_plugin__s2member_ruris::fill_ruri_level_access_rc_vars($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris'], $user)) as $str)
|
110 |
+
if($str && preg_match('/'.preg_quote($str, '/').'/', $post_uri) && (!$check_user || !$user || !$user->has_cap('access_s2member_level'.$n)))
|
111 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_level_req' => $n), get_defined_vars());
|
112 |
+
}
|
113 |
+
if(is_array($ccaps_req = get_post_meta($post->ID, 's2member_ccaps_req', TRUE)) && !empty($ccaps_req))
|
114 |
+
{
|
115 |
+
foreach($ccaps_req as $ccap) // The $user MUST satisfy ALL Custom Capabilities. Serialized array.
|
116 |
+
if(strlen($ccap) && (!$check_user || !$user || !$user->has_cap('access_s2member_ccap_'.$ccap)))
|
117 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_ccap_req' => $ccap), get_defined_vars());
|
118 |
+
}
|
119 |
+
if($bbpress_restrictions_enable && $bbpress_installed && $post->post_type === $bbpress_topic_post_type && $bbpress_topic_forum_id)
|
120 |
+
if(is_array($ccaps_req = get_post_meta($bbpress_topic_forum_id, 's2member_ccaps_req', TRUE)) && !empty($ccaps_req))
|
121 |
+
{
|
122 |
+
foreach($ccaps_req as $ccap) // The $user MUST satisfy ALL Custom Capabilities. Serialized array.
|
123 |
+
if(strlen($ccap) && (!$check_user || !$user || !$user->has_cap('access_s2member_ccap_'.$ccap)))
|
124 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_ccap_req' => $ccap), get_defined_vars());
|
125 |
+
}
|
126 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'] && in_array($post->ID, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'])) && (!$check_user || !c_ws_plugin__s2member_sp_access::sp_access($post->ID, 'read-only')))
|
127 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', array('s2member_sp_req' => $post->ID), get_defined_vars());
|
128 |
}
|
129 |
+
do_action('ws_plugin__s2member_during_check_specific_post_level_access', get_defined_vars());
|
130 |
+
}
|
131 |
}
|
132 |
+
return apply_filters('ws_plugin__s2member_check_specific_post_level_access', NULL, get_defined_vars());
|
133 |
+
}
|
134 |
}
|
135 |
+
}
|
includes/classes/posts.inc.php
CHANGED
@@ -1,120 +1,132 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member's Post protection routines *(for current Post)*.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Posts
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit (
|
19 |
-
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
* @package s2Member\Posts
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @return null Or exits script execution after redirection.
|
37 |
-
*/
|
38 |
-
public static function check_post_level_access ()
|
39 |
-
{
|
40 |
-
global $post; // ``get_the_ID()`` unavailable outside The Loop.
|
41 |
-
|
42 |
-
do_action("ws_plugin__s2member_before_check_post_level_access", get_defined_vars ());
|
43 |
|
44 |
-
|
|
|
45 |
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
{
|
48 |
-
if (
|
49 |
-
|
50 |
-
$user = (is_user_logged_in () && is_object ($user = wp_get_current_user ()) && !empty($user->ID)) ? $user : false; // Current User's object.
|
51 |
-
|
52 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri ($user, "root-returns-false")) && preg_match ("/^" . preg_quote ($login_redirection_uri, "/") . "$/", $_SERVER["REQUEST_URI"]) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level0")))
|
53 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", 0, $_SERVER["REQUEST_URI"], "sys") . exit ();
|
54 |
-
|
55 |
-
else if (!c_ws_plugin__s2member_systematics::is_systematic_use_page ()) // Do NOT protect Systematics. However, there is 1 exception above.
|
56 |
-
{
|
57 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Post Level restrictions (including Custom Post Types). Go through each Level.
|
58 |
-
{
|
59 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"] === "all" && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
60 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"]) . exit ();
|
61 |
-
|
62 |
-
else if (strpos ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"], "all-") !== false && (in_array("all-" . $post->post_type, preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"])) || in_array("all-" . $post->post_type . "s", preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"]))) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
63 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"]) . exit ();
|
64 |
-
|
65 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"] && in_array($post_id, preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"])) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
66 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"]) . exit ();
|
67 |
-
}
|
68 |
-
|
69 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Category Level restrictions. Go through each Level.
|
70 |
-
{
|
71 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_catgs"] === "all" && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
72 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"], "catg") . exit ();
|
73 |
-
|
74 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_catgs"] && (in_category (($catgs = preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_catgs"])), $post_id) || c_ws_plugin__s2member_utils_conds::in_descendant_category ($catgs, $post_id)) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
75 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"], "catg") . exit ();
|
76 |
-
}
|
77 |
-
|
78 |
-
if (has_tag ()) // Here we take a look to see if this Post has any Tags. If so, we need to run the full set of routines against Tags also.
|
79 |
-
{
|
80 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Tag Level restrictions. Go through each Level.
|
81 |
-
{
|
82 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ptags"] === "all" && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
83 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"], "ptag") . exit ();
|
84 |
-
|
85 |
-
else if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ptags"] && has_tag (preg_split ("/[\r\n\t;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ptags"])) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
86 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"], "ptag") . exit ();
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
for ($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // URIs. Go through each Level.
|
91 |
-
{
|
92 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ruris"]) // URIs configured at this Level?
|
93 |
-
|
94 |
-
foreach (preg_split ("/[\r\n\t]+/", c_ws_plugin__s2member_ruris::fill_ruri_level_access_rc_vars ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ruris"], $user)) as $str)
|
95 |
-
if ($str && preg_match ("/" . preg_quote ($str, "/") . "/", $_SERVER["REQUEST_URI"]) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
96 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "level", $n, $_SERVER["REQUEST_URI"], "ruri") . exit ();
|
97 |
-
}
|
98 |
-
|
99 |
-
if (is_array($ccaps_req = get_post_meta ($post_id, "s2member_ccaps_req", true)) && !empty($ccaps_req) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted'))
|
100 |
-
{
|
101 |
-
foreach ($ccaps_req as $ccap) // The ``$user`` MUST satisfy ALL Custom Capability requirements. Stored as an array of Custom Capabilities.
|
102 |
-
if (strlen ($ccap) && (!$user || !$user->has_cap ("access_s2member_ccap_" . $ccap)) /* Does this ``$user``, have this Custom Capability? */)
|
103 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "ccap", $ccap, $_SERVER["REQUEST_URI"], "ccap") . exit ();
|
104 |
-
}
|
105 |
-
|
106 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["specific_ids"] && in_array($post_id, preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["specific_ids"])) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && !c_ws_plugin__s2member_sp_access::sp_access ($post_id))
|
107 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("post", $post_id, "sp", $post_id, $_SERVER["REQUEST_URI"], "sp") . exit ();
|
108 |
-
}
|
109 |
-
|
110 |
-
do_action("ws_plugin__s2member_during_check_post_level_access", get_defined_vars ());
|
111 |
-
}
|
112 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
-
|
115 |
-
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
}
|
|
|
|
|
118 |
}
|
|
|
|
|
119 |
}
|
120 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member's Post protection routines *(for current Post)*.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Posts
|
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_posts'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* s2Member's Post protection routines *(for current Post)*.
|
24 |
+
*
|
25 |
+
* @package s2Member\Posts
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_posts
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles Post Level Access permissions *(for current Post)*.
|
32 |
+
*
|
33 |
+
* @package s2Member\Posts
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @return null Or exits script execution after redirection.
|
37 |
+
*/
|
38 |
+
public static function check_post_level_access()
|
39 |
+
{
|
40 |
+
global $post; // ``get_the_ID()`` unavailable outside The Loop.
|
41 |
+
|
42 |
+
do_action('ws_plugin__s2member_before_check_post_level_access', get_defined_vars());
|
43 |
+
|
44 |
+
$excluded = apply_filters('ws_plugin__s2member_check_post_level_access_excluded', FALSE, get_defined_vars());
|
45 |
+
|
46 |
+
if(!$excluded && is_single() && is_object($post) && !empty($post->ID) && ($post_id = (int)$post->ID) && $GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'])
|
47 |
{
|
48 |
+
if(!c_ws_plugin__s2member_systematics::is_wp_systematic_use_page()) // Do NOT touch WordPress Systematics. This excludes all WordPress Systematics.
|
49 |
+
{
|
50 |
+
$user = (is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID)) ? $user : FALSE; // Current User's object.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_override'] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri($user, 'root-returns-false')) && preg_match('/^'.preg_quote($login_redirection_uri, '/').'$/', $_SERVER['REQUEST_URI']) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level0')))
|
53 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', 0, $_SERVER['REQUEST_URI'], 'sys').exit ();
|
54 |
|
55 |
+
else if(!c_ws_plugin__s2member_systematics::is_systematic_use_page()) // However, there is the one exception above.
|
56 |
+
{
|
57 |
+
$bbpress_restrictions_enable = apply_filters('ws_plugin__s2member_bbpress_restrictions_enable', TRUE);
|
58 |
+
$bbpress_installed = c_ws_plugin__s2member_utils_conds::bbp_is_installed(); // bbPress is installed?
|
59 |
+
$bbpress_forum_post_type = $bbpress_installed ? bbp_get_forum_post_type() : ''; // Acquire the current post type for forums.
|
60 |
+
$bbpress_topic_post_type = $bbpress_installed ? bbp_get_topic_post_type() : ''; // Acquire the current post type for topics.
|
61 |
+
$bbpress_topic_forum_id = $bbpress_installed && $post->post_type === $bbpress_topic_post_type ? bbp_get_topic_forum_id($post->ID) : 0;
|
62 |
+
|
63 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Post Level restrictions.
|
64 |
+
{
|
65 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] === 'all' && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
66 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
67 |
+
|
68 |
+
else if(strpos($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'], 'all-') !== FALSE && (in_array('all-'.$post->post_type, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) || in_array('all-'.$post->post_type.'s', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts']))) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
69 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
70 |
+
|
71 |
+
else if($bbpress_restrictions_enable && $bbpress_installed && $post->post_type === $bbpress_topic_post_type && strpos($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'], 'all-') !== FALSE && (in_array('all-'.$bbpress_forum_post_type, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) || in_array('all-'.$bbpress_forum_post_type.'s', preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts']))) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
72 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
73 |
+
|
74 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] && in_array($post_id, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
75 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
76 |
+
}
|
77 |
+
if($bbpress_restrictions_enable && $bbpress_installed && $post->post_type === $bbpress_topic_post_type && $bbpress_topic_forum_id)
|
78 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Forum restrictions.
|
79 |
{
|
80 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] && in_array($bbpress_topic_forum_id, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
81 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $bbpress_topic_forum_id, 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
83 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Category Level restrictions.
|
84 |
+
{
|
85 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'] === 'all' && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
86 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI'], 'catg').exit ();
|
87 |
+
|
88 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'] && (in_category(($catgs = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'])), $post_id) || c_ws_plugin__s2member_utils_conds::in_descendant_category($catgs, $post_id)) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
89 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI'], 'catg').exit ();
|
90 |
+
}
|
91 |
+
if(has_tag()) // Here we take a look to see if this Post has any Tags. If so, we need to run the full set of routines against Tags also.
|
92 |
+
{
|
93 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Tag Level restrictions.
|
94 |
+
{
|
95 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] === 'all' && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
96 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI'], 'ptag').exit ();
|
97 |
|
98 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] && has_tag(preg_split('/['."\r\n\t".';,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'])) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
99 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI'], 'ptag').exit ();
|
100 |
+
}
|
101 |
+
}
|
102 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // URIs.
|
103 |
+
{
|
104 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris']) // URIs configured at this Level?
|
105 |
+
|
106 |
+
foreach(preg_split('/['."\r\n\t".']+/', c_ws_plugin__s2member_ruris::fill_ruri_level_access_rc_vars($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris'], $user)) as $str)
|
107 |
+
if($str && preg_match('/'.preg_quote($str, '/').'/', $_SERVER['REQUEST_URI']) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
108 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'level', $n, $_SERVER['REQUEST_URI'], 'ruri').exit ();
|
109 |
+
}
|
110 |
+
if(is_array($ccaps_req = get_post_meta($post_id, 's2member_ccaps_req', TRUE)) && !empty($ccaps_req) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted'))
|
111 |
+
{
|
112 |
+
foreach($ccaps_req as $ccap) // The ``$user`` MUST satisfy ALL Custom Capability requirements. Stored as an array of Custom Capabilities.
|
113 |
+
if(strlen($ccap) && (!$user || !$user->has_cap('access_s2member_ccap_'.$ccap)) /* Does this ``$user``, have this Custom Capability? */)
|
114 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'ccap', $ccap, $_SERVER['REQUEST_URI'], 'ccap').exit ();
|
115 |
+
}
|
116 |
+
if($bbpress_restrictions_enable && $bbpress_installed && $post->post_type === $bbpress_topic_post_type && $bbpress_topic_forum_id)
|
117 |
+
if(is_array($ccaps_req = get_post_meta($bbpress_topic_forum_id, 's2member_ccaps_req', TRUE)) && !empty($ccaps_req) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted'))
|
118 |
+
{
|
119 |
+
foreach($ccaps_req as $ccap) // The ``$user`` MUST satisfy ALL Custom Capability requirements. Stored as an array of Custom Capabilities.
|
120 |
+
if(strlen($ccap) && (!$user || !$user->has_cap('access_s2member_ccap_'.$ccap)) /* Does this ``$user``, have this Custom Capability? */)
|
121 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $bbpress_topic_forum_id, 'ccap', $ccap, $_SERVER['REQUEST_URI'], 'ccap').exit ();
|
122 |
+
}
|
123 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'] && in_array($post_id, preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'])) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && !c_ws_plugin__s2member_sp_access::sp_access($post_id))
|
124 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('post', $post_id, 'sp', $post_id, $_SERVER['REQUEST_URI'], 'sp').exit ();
|
125 |
}
|
126 |
+
do_action('ws_plugin__s2member_during_check_post_level_access', get_defined_vars());
|
127 |
+
}
|
128 |
}
|
129 |
+
do_action('ws_plugin__s2member_after_check_post_level_access', get_defined_vars());
|
130 |
+
}
|
131 |
}
|
132 |
+
}
|
includes/classes/querys.inc.php
CHANGED
@@ -1,403 +1,409 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* Query protection routines.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Queries
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if(realpath(__FILE__) === realpath($_SERVER[
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if(!class_exists(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
* The current WordPress query object reference.
|
32 |
-
*
|
33 |
-
* @package s2Member\Queries
|
34 |
-
* @since 110912
|
35 |
-
*
|
36 |
-
* @var null|obj
|
37 |
-
*/
|
38 |
-
public static $current_wp_query;
|
39 |
-
/**
|
40 |
-
* Forces query Filters *(on-demand)*.
|
41 |
-
*
|
42 |
-
* s2Member respects the query var: `suppress_filters`.
|
43 |
-
* If you need to make a query without it being Filtered, use ``$wp_query->set ("suppress_filters", true);``.
|
44 |
-
*
|
45 |
-
* @package s2Member\Queries
|
46 |
-
* @since 3.5
|
47 |
-
*
|
48 |
-
* @attaches-to ``add_action("pre_get_posts");``
|
49 |
-
*
|
50 |
-
* @param object $wp_query Expects ``$wp_query`` by reference.
|
51 |
-
* @return null
|
52 |
-
*/
|
53 |
-
public static function force_query_level_access(&$wp_query = FALSE)
|
54 |
-
{
|
55 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
56 |
-
do_action("ws_plugin__s2member_before_force_query_level_access", get_defined_vars());
|
57 |
-
unset($__refs, $__v);
|
58 |
-
|
59 |
-
c_ws_plugin__s2member_querys::query_level_access($wp_query, true);
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
{
|
90 |
-
|
91 |
-
|
92 |
-
c_ws_plugin__s2member_querys::$current_wp_query = &$wp_query;
|
93 |
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
|
98 |
-
|
|
|
99 |
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
102 |
|
103 |
-
|
104 |
{
|
105 |
-
|
106 |
-
|
107 |
-
$suppressing_filters = $wp_query->get("suppress_filters"); // Filter suppression on?
|
108 |
-
if(!$suppressing_filters && $force // Forcing this routine bypasses all of these other conditionals. Works with API function ``attach_s2member_query_filters()``.
|
109 |
-
|| (!$suppressing_filters && in_array("all", $o) && !($initial_query && $wp_query->is_singular())) // Don't create 404 errors. Allow Security Gate to handle these.
|
110 |
-
|| (!$suppressing_filters && (in_array("all", $o) || in_array("searches", $o)) && $wp_query->is_search()) // Or, is this a search results query, possibly via AJAX: `admin-ajax.php`?
|
111 |
-
|| (!$suppressing_filters && (in_array("all", $o) || in_array("feeds", $o)) && $wp_query->is_feed() && !$wp_query->is_comment_feed()) // Or, is this a feed; and it's NOT for comments?
|
112 |
-
|| (!$suppressing_filters && (in_array("all", $o) || in_array("comment-feeds", $o)) && $wp_query->is_feed() && $wp_query->is_comment_feed()) // Or, is this a feed; and it IS indeed for comments?
|
113 |
-
|| (($suppressing_filters !== "n/a") && (in_array("all", $o) || in_array("nav-menus", $o)) && in_array("wp_get_nav_menu_items", ($callers = (isset($callers) ? $callers : c_ws_plugin__s2member_utilities::callers())))))
|
114 |
-
{
|
115 |
-
if(!$suppressing_filters && (in_array("all", $o) || in_array("comment-feeds", $o)) && $wp_query->is_feed() && $wp_query->is_comment_feed())
|
116 |
-
add_filter("comment_feed_where", "c_ws_plugin__s2member_querys::_query_level_access_coms", 100, 2);
|
117 |
-
|
118 |
-
if($suppressing_filters !== "n/a" && (in_array("all", $o) || in_array("nav-menus", $o))) // Suppression irrelevant here.
|
119 |
-
if(in_array("wp_get_nav_menu_items", ($callers = (isset($callers) ? $callers : c_ws_plugin__s2member_utilities::callers()))))
|
120 |
-
add_filter("wp_get_nav_menu_items", "c_ws_plugin__s2member_querys::_query_level_access_navs", 100);
|
121 |
-
|
122 |
-
if($suppressing_filters !== "n/a" && (in_array("all", $o) || in_array("pages", $o)))
|
123 |
-
add_filter("wp_list_pages_excludes", "c_ws_plugin__s2member_querys::_query_level_access_list_pages", 100);
|
124 |
-
|
125 |
-
if((is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID) && ($user_id = $user->ID)) || !($user = false))
|
126 |
-
{
|
127 |
-
if(!$user && ($_lwp = (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"]))
|
128 |
-
{
|
129 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), array($_lwp))));
|
130 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), array($_lwp))));
|
131 |
-
}
|
132 |
-
|
133 |
-
if(!$user && ($_dep = (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"]))
|
134 |
-
{
|
135 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), array($_dep))));
|
136 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), array($_dep))));
|
137 |
-
}
|
138 |
-
|
139 |
-
if(is_array($_ccaps = c_ws_plugin__s2member_utils_gets::get_unavailable_singular_ids_with_ccaps($user)) && !empty($_ccaps))
|
140 |
-
{
|
141 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_ccaps)));
|
142 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), $_ccaps)));
|
143 |
-
}
|
144 |
-
|
145 |
-
if(is_array($_sps = c_ws_plugin__s2member_utils_gets::get_unavailable_singular_ids_with_sp()) && !empty($_sps))
|
146 |
-
{
|
147 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_sps)));
|
148 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), $_sps)));
|
149 |
-
}
|
150 |
-
unset /* A little housekeeping here. Ditch these temporary variables. */($_lwp, $_dep, $_ccaps, $_sps);
|
151 |
-
|
152 |
-
for($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Category Level Restrictions.
|
153 |
-
{
|
154 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_catgs"] === "all" && (!$user || !current_user_can("access_s2member_level".$n)))
|
155 |
-
{
|
156 |
-
$wp_query->set("category__in", array()); // Include no other Categories.
|
157 |
-
$wp_query->set("category__not_in", ($_catgs = c_ws_plugin__s2member_utils_gets::get_all_category_ids()));
|
158 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_catgs)))));
|
159 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_singulars)));
|
160 |
-
break; // All Categories will be locked down.
|
161 |
-
}
|
162 |
-
else if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_catgs"] && (!$user || !current_user_can("access_s2member_level".$n)))
|
163 |
-
{
|
164 |
-
foreach(($_catgs = preg_split("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_catgs"])) as $_catg)
|
165 |
-
$_catgs = array_merge($_catgs, c_ws_plugin__s2member_utils_gets::get_all_child_category_ids($_catg));
|
166 |
-
|
167 |
-
$wp_query->set("category__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("category__in")), $_catgs)));
|
168 |
-
$wp_query->set("category__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("category__not_in")), $_catgs)));
|
169 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_catgs)))));
|
170 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_singulars)));
|
171 |
-
}
|
172 |
-
}
|
173 |
-
unset /* A little housekeeping here. Ditch these temporary variables. */($_catgs, $_catg, $_singulars);
|
174 |
-
|
175 |
-
for($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Tag Level Restrictions.
|
176 |
-
{
|
177 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_ptags"] === "all" && (!$user || !current_user_can("access_s2member_level".$n)))
|
178 |
-
{
|
179 |
-
$wp_query->set("tag__in", array()); // Include no other Tags.
|
180 |
-
$wp_query->set("tag__not_in", ($_tags = c_ws_plugin__s2member_utils_gets::get_all_tag_ids()));
|
181 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_tags)))));
|
182 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_singulars)));
|
183 |
-
break; // ALL Tags will be locked down.
|
184 |
-
}
|
185 |
-
else if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_ptags"] && (!$user || !current_user_can("access_s2member_level".$n)))
|
186 |
-
{
|
187 |
-
$_tags = c_ws_plugin__s2member_utils_gets::get_tags_converted_to_ids($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_ptags"]);
|
188 |
-
|
189 |
-
$wp_query->set("tag__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("tag__in")), $_tags)));
|
190 |
-
$wp_query->set("tag__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("tag__not_in")), $_tags)));
|
191 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_tags)))));
|
192 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_singulars)));
|
193 |
-
}
|
194 |
-
}
|
195 |
-
unset /* A little housekeeping here. Ditch these temporary variables. */($_tags, $_tag, $_singulars);
|
196 |
-
|
197 |
-
for($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Post Level Restrictions.
|
198 |
-
{
|
199 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_posts"] === "all" && (!$user || !current_user_can("access_s2member_level".$n)))
|
200 |
-
{
|
201 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), ($_posts = c_ws_plugin__s2member_utils_gets::get_all_post_ids()))));
|
202 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), $_posts)));
|
203 |
-
break; // ALL Posts will be locked down.
|
204 |
-
}
|
205 |
-
else if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_posts"] && (!$user || !current_user_can("access_s2member_level".$n)))
|
206 |
-
{
|
207 |
-
foreach(($_posts = preg_split("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_posts"])) as $_p)
|
208 |
-
if(strpos($_p, "all-") === 0 && preg_match("/^all-(.+?)$/", $_p, $_m) /* Protecting `all-` of a specific Post Type? */)
|
209 |
-
if((is_array($_p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids($_m[1])) || (substr($_m[1], -1) === "s"
|
210 |
-
&& is_array($_p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids(substr($_m[1], 0, -1)))))
|
211 |
-
&& !empty($_p_of_type)) $_posts = array_merge /* Merge all Posts of this Post Type. */($_posts, $_p_of_type);
|
212 |
-
|
213 |
-
$_posts = array_unique( /* Force integers. */c_ws_plugin__s2member_utils_arrays::force_integers($_posts));
|
214 |
-
|
215 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_posts)));
|
216 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), $_posts)));
|
217 |
-
}
|
218 |
-
}
|
219 |
-
unset /* A little housekeeping here. Ditch these temporary variables. */($_posts, $_p, $_m, $_p_of_type);
|
220 |
-
|
221 |
-
for($n = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n >= 0; $n--) // Page Level Restrictions.
|
222 |
-
{
|
223 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_pages"] === "all" && (!$user || !current_user_can("access_s2member_level".$n)))
|
224 |
-
{
|
225 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), ($_pages = c_ws_plugin__s2member_utils_gets::get_all_page_ids()))));
|
226 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), $_pages)));
|
227 |
-
break; // ALL Pages will be locked down.
|
228 |
-
}
|
229 |
-
else if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_pages"] && (!$user || !current_user_can("access_s2member_level".$n)))
|
230 |
-
{
|
231 |
-
$_pages = c_ws_plugin__s2member_utils_arrays::force_integers(preg_split("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_pages"]));
|
232 |
-
|
233 |
-
$wp_query->set("post__in", array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__in")), $_pages)));
|
234 |
-
$wp_query->set("post__not_in", array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get("post__not_in")), $_pages)));
|
235 |
-
}
|
236 |
-
}
|
237 |
-
unset /* A little housekeeping here. Ditch these temporary variables. */($_pages);
|
238 |
-
}
|
239 |
-
|
240 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
241 |
-
do_action("ws_plugin__s2member_during_query_level_access", get_defined_vars());
|
242 |
-
unset($__refs, $__v);
|
243 |
-
}
|
244 |
-
}
|
245 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
$initial_query = false; // No longer.
|
252 |
-
|
253 |
-
return; // For uniformity.
|
254 |
-
}
|
255 |
-
/**
|
256 |
-
* Always filters Systematics in search results & feeds.
|
257 |
-
*
|
258 |
-
* s2Member respects the query var: `suppress_filters`.
|
259 |
-
* If you need to make a query without it being Filtered, use ``$wp_query->set ("suppress_filters", true);``.
|
260 |
-
*
|
261 |
-
* @package s2Member\Queries
|
262 |
-
* @since 3.5
|
263 |
-
*
|
264 |
-
* @param object $wp_query Expects ``$wp_query`` by reference.
|
265 |
-
* @return null
|
266 |
-
*/
|
267 |
-
public static function _query_level_access_sys(&$wp_query = FALSE)
|
268 |
-
{
|
269 |
-
global $wpdb; // Need this global DB object reference here.
|
270 |
-
|
271 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
272 |
-
do_action("_ws_plugin__s2member_before_query_level_access_sys", get_defined_vars());
|
273 |
-
unset($__refs, $__v);
|
274 |
-
|
275 |
-
if(is_object($wpdb) && is_object($wp_query) && !($suppressing_filters = $wp_query->get("suppress_filters")))
|
276 |
-
if((!is_admin() && ($wp_query->is_search() || $wp_query->is_feed())) || c_ws_plugin__s2member_querys::_is_admin_ajax_search($wp_query))
|
277 |
{
|
278 |
-
$
|
279 |
-
$
|
280 |
-
|
281 |
-
$wp_query->set(
|
282 |
-
|
|
|
|
|
|
|
|
|
|
|
283 |
|
284 |
-
|
285 |
-
|
286 |
-
|
|
|
287 |
}
|
|
|
|
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
292 |
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
*
|
301 |
-
* @attaches-to ``add_filter("wp_get_nav_menu_items");``
|
302 |
-
*
|
303 |
-
* @param array $items Expects an array of items to be passed through by the Filter.
|
304 |
-
* @return array The revised array of ``$items``.
|
305 |
-
*/
|
306 |
-
public static function _query_level_access_navs($items = FALSE)
|
307 |
-
{
|
308 |
-
global $wpdb; // Need this global DB object reference here.
|
309 |
-
$wp_query = &c_ws_plugin__s2member_querys::$current_wp_query;
|
310 |
|
311 |
-
|
312 |
{
|
313 |
-
$
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
}
|
329 |
-
|
330 |
-
return apply_filters("_ws_plugin__s2member_query_level_access_navs", $items, get_defined_vars());
|
331 |
-
}
|
332 |
-
/**
|
333 |
-
* Filters ``$cwhere`` query portion.
|
334 |
-
*
|
335 |
-
* @package s2Member\Queries
|
336 |
-
* @since 110912
|
337 |
-
*
|
338 |
-
* @attaches-to ``add_filter("comment_feed_where");``
|
339 |
-
*
|
340 |
-
* @param string $cwhere Expects the SQL `WHERE` portion to be passed through by the Filter.
|
341 |
-
* @param object $wp_query Expects ``$wp_query`` by reference, from the Filter.
|
342 |
-
* @return string The revised ``$cwhere`` string.
|
343 |
-
*/
|
344 |
-
public static function _query_level_access_coms($cwhere = FALSE, &$wp_query = FALSE)
|
345 |
-
{
|
346 |
-
global $wpdb; // Need this global DB object reference here.
|
347 |
|
348 |
-
|
349 |
{
|
350 |
-
$
|
351 |
-
|
352 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
|
354 |
-
|
355 |
-
|
|
|
356 |
}
|
357 |
-
|
358 |
-
|
|
|
|
|
|
|
359 |
}
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
*
|
366 |
-
* @param object $wp_query Expects ``$wp_query`` by reference.
|
367 |
-
* @return bool True if it's an AJAX search via `admin-ajax.php`, else false.
|
368 |
-
*/
|
369 |
-
public static function _is_admin_ajax_search(&$wp_query = FALSE)
|
370 |
-
{
|
371 |
-
global $wpdb; // Need this global DB object reference here.
|
372 |
|
373 |
-
|
374 |
-
|
375 |
-
return apply_filters("_ws_plugin__s2member_is_admin_ajax_search", true, get_defined_vars());
|
376 |
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
}
|
|
|
|
|
402 |
}
|
403 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Query protection routines.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Queries
|
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_querys'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* Query protection routines.
|
24 |
+
*
|
25 |
+
* @package s2Member\Queries
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_querys
|
29 |
{
|
30 |
/**
|
31 |
+
* The current WordPress query object reference.
|
32 |
+
*
|
33 |
+
* @package s2Member\Queries
|
34 |
+
* @since 110912
|
35 |
+
*
|
36 |
+
* @var null|object
|
37 |
+
*/
|
38 |
+
public static $current_wp_query;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
+
/**
|
41 |
+
* Forces query Filters *(on-demand)*.
|
42 |
+
*
|
43 |
+
* s2Member respects the query var: `suppress_filters`.
|
44 |
+
* If you need to make a query without it being Filtered, use ``$wp_query->set ('suppress_filters', true);``.
|
45 |
+
*
|
46 |
+
* @package s2Member\Queries
|
47 |
+
* @since 3.5
|
48 |
+
*
|
49 |
+
* @attaches-to ``add_action('pre_get_posts');``
|
50 |
+
*
|
51 |
+
* @param WP_Query $wp_query Expects ``$wp_query`` by reference.
|
52 |
+
*/
|
53 |
+
public static function force_query_level_access(&$wp_query = NULL)
|
54 |
+
{
|
55 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
56 |
+
do_action('ws_plugin__s2member_before_force_query_level_access', get_defined_vars());
|
57 |
+
unset($__refs, $__v); // Housekeeping.
|
58 |
+
|
59 |
+
c_ws_plugin__s2member_querys::query_level_access($wp_query, TRUE);
|
60 |
+
|
61 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
62 |
+
do_action('ws_plugin__s2member_after_force_query_level_access', get_defined_vars());
|
63 |
+
unset($__refs, $__v); // Housekeeping.
|
64 |
+
}
|
65 |
|
66 |
+
/**
|
67 |
+
* Filter all WordPress queries.
|
68 |
+
*
|
69 |
+
* s2Member respects the query var: `suppress_filters`.
|
70 |
+
* If you need to make a query without it being Filtered, use ``$wp_query->set ('suppress_filters', true);``.
|
71 |
+
*
|
72 |
+
* @package s2Member\Queries
|
73 |
+
* @since 3.5
|
74 |
+
*
|
75 |
+
* @attaches-to ``add_action('pre_get_posts');``
|
76 |
+
*
|
77 |
+
* @param WP_Query $wp_query Expects ``$wp_query`` by reference, from the Filter.
|
78 |
+
* @param bool $force Optional. Defaults to false. If true, we bypass all standard conditions.
|
79 |
+
* However, s2Member will NEVER bypass `supress_filters`.
|
80 |
+
*
|
81 |
+
* @todo For improved reliability, modify other query vars associated with exclusions/inclusions. Like `tag_slug__in`?
|
82 |
+
* See: {@link http://codex.wordpress.org/Class_Reference/WP_Query#Parameters WP_Query#Parameters}
|
83 |
+
*
|
84 |
+
* @todo Make it possible to force filtering, even when used in combination with Query Conditionals and ``get_posts()``, which auto-supresses.
|
85 |
+
* Or, perhaps strengthen the existing ``$force`` parameter in this regard.
|
86 |
+
*/
|
87 |
+
public static function query_level_access(&$wp_query = NULL, $force = FALSE)
|
88 |
+
{
|
89 |
+
global $wpdb; // Global DB object reference.
|
90 |
+
static $initial_query = TRUE; // Tracks the initial query.
|
91 |
+
c_ws_plugin__s2member_querys::$current_wp_query = & $wp_query;
|
92 |
+
|
93 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
94 |
+
do_action('ws_plugin__s2member_before_query_level_access', get_defined_vars());
|
95 |
+
unset($__refs, $__v); // Housekeeping.
|
96 |
+
|
97 |
+
c_ws_plugin__s2member_querys::_query_level_access_sys($wp_query); // Systematics.
|
98 |
+
|
99 |
+
remove_filter('comment_feed_where', 'c_ws_plugin__s2member_querys::_query_level_access_coms', 100, 2);
|
100 |
+
remove_filter('wp_get_nav_menu_items', 'c_ws_plugin__s2member_querys::_query_level_access_navs', 100);
|
101 |
+
|
102 |
+
if(is_object($wpdb) && is_object($wp_query) && (($o = $GLOBALS['WS_PLUGIN__']['s2member']['o']['filter_wp_query']) || $force))
|
103 |
+
{
|
104 |
+
if(!is_admin() || c_ws_plugin__s2member_querys::_is_admin_ajax_search($wp_query))
|
105 |
+
{
|
106 |
+
$suppressing_filters = $wp_query->get('suppress_filters'); // Filter suppression on?
|
107 |
+
if(!$suppressing_filters && $force // Forcing this routine bypasses all of these other conditionals. Works with API function ``attach_s2member_query_filters()``.
|
108 |
+
|| (!$suppressing_filters && in_array('all', $o) && !($initial_query && $wp_query->is_singular())) // Don't create 404 errors. Allow Security Gate to handle these.
|
109 |
+
|| (!$suppressing_filters && (in_array('all', $o) || in_array('searches', $o)) && $wp_query->is_search()) // Or, is this a search results query, possibly via AJAX: `admin-ajax.php`?
|
110 |
+
|| (!$suppressing_filters && (in_array('all', $o) || in_array('feeds', $o)) && $wp_query->is_feed() && !$wp_query->is_comment_feed()) // Or, is this a feed; and it's NOT for comments?
|
111 |
+
|| (!$suppressing_filters && (in_array('all', $o) || in_array('comment-feeds', $o)) && $wp_query->is_feed() && $wp_query->is_comment_feed()) // Or, is this a feed; and it IS indeed for comments?
|
112 |
+
|| (($suppressing_filters !== 'n/a') && (in_array('all', $o) || in_array('nav-menus', $o)) && in_array('wp_get_nav_menu_items', ($callers = (isset($callers) ? $callers : c_ws_plugin__s2member_utilities::callers()))))
|
113 |
+
)
|
114 |
{
|
115 |
+
if(!$suppressing_filters && (in_array('all', $o) || in_array('comment-feeds', $o)) && $wp_query->is_feed() && $wp_query->is_comment_feed())
|
116 |
+
add_filter('comment_feed_where', 'c_ws_plugin__s2member_querys::_query_level_access_coms', 100, 2);
|
|
|
117 |
|
118 |
+
if($suppressing_filters !== 'n/a' && (in_array('all', $o) || in_array('nav-menus', $o))) // Suppression irrelevant here.
|
119 |
+
if(in_array('wp_get_nav_menu_items', ($callers = (isset($callers) ? $callers : c_ws_plugin__s2member_utilities::callers()))))
|
120 |
+
add_filter('wp_get_nav_menu_items', 'c_ws_plugin__s2member_querys::_query_level_access_navs', 100);
|
121 |
|
122 |
+
if($suppressing_filters !== 'n/a' && (in_array('all', $o) || in_array('pages', $o)))
|
123 |
+
add_filter('wp_list_pages_excludes', 'c_ws_plugin__s2member_querys::_query_level_access_list_pages', 100);
|
124 |
|
125 |
+
if((is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID) && ($user_id = $user->ID)) || !($user = FALSE))
|
126 |
+
{
|
127 |
+
$bbpress_restrictions_enable = apply_filters('ws_plugin__s2member_bbpress_restrictions_enable', TRUE);
|
128 |
+
$bbpress_installed = c_ws_plugin__s2member_utils_conds::bbp_is_installed(); // bbPress is installed?
|
129 |
+
$bbpress_forum_post_type = $bbpress_installed ? bbp_get_forum_post_type() : ''; // Acquire the current post type for forums.
|
130 |
+
$bbpress_topic_post_type = $bbpress_installed ? bbp_get_topic_post_type() : ''; // Acquire the current post type for topics.
|
131 |
|
132 |
+
if(!$user && ($_lwp = (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page']))
|
133 |
{
|
134 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), array($_lwp))));
|
135 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), array($_lwp))));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
}
|
137 |
+
if(!$user && ($_dep = (int)$GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page']))
|
138 |
+
{
|
139 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), array($_dep))));
|
140 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), array($_dep))));
|
141 |
+
}
|
142 |
+
if(is_array($_ccaps = c_ws_plugin__s2member_utils_gets::get_unavailable_singular_ids_with_ccaps($user)) && !empty($_ccaps))
|
143 |
+
{
|
144 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_ccaps)));
|
145 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), $_ccaps)));
|
146 |
+
}
|
147 |
+
if(is_array($_sps = c_ws_plugin__s2member_utils_gets::get_unavailable_singular_ids_with_sp()) && !empty($_sps))
|
148 |
+
{
|
149 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_sps)));
|
150 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), $_sps)));
|
151 |
+
}
|
152 |
+
unset($_lwp, $_dep, $_ccaps, $_sps); // A little housekeeping here. Ditch these temporary variables.
|
153 |
|
154 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Category Level Restrictions.
|
155 |
+
{
|
156 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'] === 'all' && (!$user || !current_user_can('access_s2member_level'.$n)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
{
|
158 |
+
$wp_query->set('category__in', array()); // Include no other Categories.
|
159 |
+
$wp_query->set('category__not_in', ($_catgs = c_ws_plugin__s2member_utils_gets::get_all_category_ids()));
|
160 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_catgs)))));
|
161 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_singulars)));
|
162 |
+
break; // All Categories will be locked down.
|
163 |
+
}
|
164 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'] && (!$user || !current_user_can('access_s2member_level'.$n)))
|
165 |
+
{
|
166 |
+
foreach(($_catgs = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'])) as $_catg)
|
167 |
+
$_catgs = array_merge($_catgs, c_ws_plugin__s2member_utils_gets::get_all_child_category_ids($_catg));
|
168 |
|
169 |
+
$wp_query->set('category__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('category__in')), $_catgs)));
|
170 |
+
$wp_query->set('category__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('category__not_in')), $_catgs)));
|
171 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_catgs)))));
|
172 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_singulars)));
|
173 |
}
|
174 |
+
}
|
175 |
+
unset($_catgs, $_catg, $_singulars); // A little housekeeping here. Ditch these temporary variables.
|
176 |
|
177 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Tag Level Restrictions.
|
178 |
+
{
|
179 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] === 'all' && (!$user || !current_user_can('access_s2member_level'.$n)))
|
180 |
+
{
|
181 |
+
$wp_query->set('tag__in', array()); // Include no other Tags.
|
182 |
+
$wp_query->set('tag__not_in', ($_tags = c_ws_plugin__s2member_utils_gets::get_all_tag_ids()));
|
183 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_tags)))));
|
184 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_singulars)));
|
185 |
+
break; // ALL Tags will be locked down.
|
186 |
+
}
|
187 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] && (!$user || !current_user_can('access_s2member_level'.$n)))
|
188 |
+
{
|
189 |
+
$_tags = c_ws_plugin__s2member_utils_gets::get_tags_converted_to_ids($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags']);
|
190 |
|
191 |
+
$wp_query->set('tag__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('tag__in')), $_tags)));
|
192 |
+
$wp_query->set('tag__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('tag__not_in')), $_tags)));
|
193 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), ($_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($_tags)))));
|
194 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_singulars)));
|
195 |
+
}
|
196 |
+
}
|
197 |
+
unset($_tags, $_tag, $_singulars); // A little housekeeping here. Ditch these temporary variables.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
|
199 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Post Level Restrictions.
|
200 |
{
|
201 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] === 'all' && (!$user || !current_user_can('access_s2member_level'.$n)))
|
202 |
+
{
|
203 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), ($_posts = c_ws_plugin__s2member_utils_gets::get_all_post_ids()))));
|
204 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), $_posts)));
|
205 |
+
break; // ALL Posts will be locked down.
|
206 |
+
}
|
207 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] && (!$user || !current_user_can('access_s2member_level'.$n)))
|
208 |
+
{
|
209 |
+
foreach(($_posts = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) as $_p)
|
210 |
+
{
|
211 |
+
if(strpos($_p, 'all-') === 0 && preg_match('/^all-(.+?)$/', $_p, $_m)) // Protecting `all-` of a specific Post Type?
|
212 |
+
if((is_array($_p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids($_m[1])) || (substr($_m[1], -1) === 's' && is_array($_p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids(substr($_m[1], 0, -1))))) && !empty($_p_of_type))
|
213 |
+
$_posts = array_merge($_posts, $_p_of_type); // Merge all Posts of this Post Type.
|
214 |
+
}
|
215 |
+
if($bbpress_restrictions_enable && $bbpress_installed)
|
216 |
+
$_posts = array_merge($_posts, c_ws_plugin__s2member_utils_gets::get_all_child_post_ids($_posts, $bbpress_topic_post_type));
|
217 |
+
$_posts = array_unique(c_ws_plugin__s2member_utils_arrays::force_integers($_posts)); // Force integers.
|
218 |
+
|
219 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_posts)));
|
220 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), $_posts)));
|
221 |
+
}
|
222 |
}
|
223 |
+
unset($_posts, $_p, $_m, $_p_of_type); // A little housekeeping here. Ditch these temporary variables.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
|
225 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Page Level Restrictions.
|
226 |
{
|
227 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] === 'all' && (!$user || !current_user_can('access_s2member_level'.$n)))
|
228 |
+
{
|
229 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), ($_pages = c_ws_plugin__s2member_utils_gets::get_all_page_ids()))));
|
230 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), $_pages)));
|
231 |
+
break; // ALL Pages will be locked down.
|
232 |
+
}
|
233 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] && (!$user || !current_user_can('access_s2member_level'.$n)))
|
234 |
+
{
|
235 |
+
$_pages = c_ws_plugin__s2member_utils_arrays::force_integers(preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages']));
|
236 |
|
237 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $_pages)));
|
238 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), $_pages)));
|
239 |
+
}
|
240 |
}
|
241 |
+
unset($_pages); // A little housekeeping here. Ditch these temporary variables.
|
242 |
+
}
|
243 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
244 |
+
do_action('ws_plugin__s2member_during_query_level_access', get_defined_vars());
|
245 |
+
unset($__refs, $__v); // Housekeeping.
|
246 |
}
|
247 |
+
}
|
248 |
+
}
|
249 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
250 |
+
do_action('ws_plugin__s2member_after_query_level_access', get_defined_vars());
|
251 |
+
unset($__refs, $__v); // Housekeeping.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
|
253 |
+
$initial_query = FALSE; // No longer.
|
254 |
+
}
|
|
|
255 |
|
256 |
+
/**
|
257 |
+
* Always filters Systematics in search results & feeds.
|
258 |
+
*
|
259 |
+
* s2Member respects the query var: `suppress_filters`.
|
260 |
+
* If you need to make a query without it being Filtered, use ``$wp_query->set ('suppress_filters', true);``.
|
261 |
+
*
|
262 |
+
* @package s2Member\Queries
|
263 |
+
* @since 3.5
|
264 |
+
*
|
265 |
+
* @param object $wp_query Expects ``$wp_query`` by reference.
|
266 |
+
*/
|
267 |
+
public static function _query_level_access_sys(&$wp_query = NULL)
|
268 |
+
{
|
269 |
+
global $wpdb; // Global DB object reference.
|
270 |
+
|
271 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
272 |
+
do_action('_ws_plugin__s2member_before_query_level_access_sys', get_defined_vars());
|
273 |
+
unset($__refs, $__v); // Housekeeping.
|
274 |
+
|
275 |
+
if(is_object($wpdb) && is_object($wp_query) && !($suppressing_filters = $wp_query->get('suppress_filters')))
|
276 |
+
if((!is_admin() && ($wp_query->is_search() || $wp_query->is_feed())) || c_ws_plugin__s2member_querys::_is_admin_ajax_search($wp_query))
|
277 |
+
{
|
278 |
+
$s = $systematics = array($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'], $GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'], $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page']);
|
279 |
+
$s = $systematics = c_ws_plugin__s2member_utils_arrays::force_integers($s); // Force integer values here.
|
280 |
+
|
281 |
+
$wp_query->set('post__not_in', array_unique(array_merge(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__not_in')), $s)));
|
282 |
+
$wp_query->set('post__in', array_unique(array_diff(c_ws_plugin__s2member_utils_arrays::force_integers((array)$wp_query->get('post__in')), $s)));
|
283 |
+
|
284 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
285 |
+
do_action('_ws_plugin__s2member_during_query_level_access_sys', get_defined_vars());
|
286 |
+
unset($__refs, $__v); // Housekeeping.
|
287 |
+
}
|
288 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
289 |
+
do_action('_ws_plugin__s2member_after_query_level_access_sys', get_defined_vars());
|
290 |
+
unset($__refs, $__v); // Housekeeping.
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Filters WordPress navigation menu items.
|
295 |
+
*
|
296 |
+
* @package s2Member\Queries
|
297 |
+
* @since 110912
|
298 |
+
*
|
299 |
+
* @attaches-to ``add_filter('wp_get_nav_menu_items');``
|
300 |
+
*
|
301 |
+
* @param array $items Expects an array of items to be passed through by the Filter.
|
302 |
+
*
|
303 |
+
* @return array The revised array of ``$items``.
|
304 |
+
*/
|
305 |
+
public static function _query_level_access_navs($items = array())
|
306 |
+
{
|
307 |
+
global $wpdb; // Global DB object reference.
|
308 |
+
$wp_query = & c_ws_plugin__s2member_querys::$current_wp_query;
|
309 |
+
|
310 |
+
if(is_array($items) && !empty($items) && is_object($wpdb) && is_object($wp_query) && $wp_query->get('suppress_filters') !== 'n/a')
|
311 |
+
{
|
312 |
+
$x_post_ids = (array)$wp_query->get('post__not_in');
|
313 |
+
$x_post_ids = c_ws_plugin__s2member_utils_arrays::force_integers($x_post_ids);
|
314 |
+
|
315 |
+
$x_taxonomy_ids = array_merge((array)$wp_query->get('category__not_in'), (array)$wp_query->get('tag__not_in'));
|
316 |
+
$x_taxonomy_ids = c_ws_plugin__s2member_utils_arrays::force_integers($x_taxonomy_ids);
|
317 |
+
|
318 |
+
foreach($items as $key => $item) // Filter through all navigational menu ``$items``.
|
319 |
+
if(isset($item->ID, $item->object_id, $item->type) && (int)$item->ID !== (int)$item->object_id && in_array($item->type, array('post_type', 'category'), TRUE))
|
320 |
+
if(($item->type === 'post_type' && in_array($item->object_id, $x_post_ids)) || ($item->type === 'category' && in_array($item->object_id, $x_taxonomy_ids)))
|
321 |
+
{
|
322 |
+
foreach($items as $child_key => $child_item) // Loop back through all ``$items``, looking for children.
|
323 |
+
if(!empty($child_item->menu_item_parent) && (int)$child_item->menu_item_parent === (int)$item->ID)
|
324 |
+
unset($items[$child_key]); // Remove this ``$child_item``, belonging to an excluded parent.
|
325 |
+
unset($items[$key]); // Exclude the parent ``$item`` now.
|
326 |
+
}
|
327 |
+
}
|
328 |
+
remove_filter('wp_get_nav_menu_items', 'c_ws_plugin__s2member_querys::_query_level_access_navs', 100);
|
329 |
+
|
330 |
+
return apply_filters('_ws_plugin__s2member_query_level_access_navs', $items, get_defined_vars());
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Filters ``$cwhere`` query portion.
|
335 |
+
*
|
336 |
+
* @package s2Member\Queries
|
337 |
+
* @since 110912
|
338 |
+
*
|
339 |
+
* @attaches-to ``add_filter('comment_feed_where');``
|
340 |
+
*
|
341 |
+
* @param string $cwhere Expects the SQL `WHERE` portion to be passed through by the Filter.
|
342 |
+
* @param WP_Query $wp_query Expects ``$wp_query`` by reference, from the Filter.
|
343 |
+
*
|
344 |
+
* @return string The revised ``$cwhere`` string.
|
345 |
+
*/
|
346 |
+
public static function _query_level_access_coms($cwhere = '', &$wp_query = NULL)
|
347 |
+
{
|
348 |
+
global $wpdb; // Global DB object reference.
|
349 |
+
|
350 |
+
if(is_string($cwhere) && is_object($wpdb) && is_object($wp_query) && !$wp_query->get('suppress_filters'))
|
351 |
+
{
|
352 |
+
$x_terms = array_merge((array)$wp_query->get('category__not_in'), (array)$wp_query->get('tag__not_in'));
|
353 |
+
$x_terms = array_unique(c_ws_plugin__s2member_utils_arrays::force_integers($x_terms)); // Force integer values.
|
354 |
+
$x_singulars = c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($x_terms); // Singulars.
|
355 |
+
|
356 |
+
$cwhere .= " AND `".$wpdb->comments."`.`comment_post_ID` NOT IN('".implode("','", (array)$wp_query->get('post__not_in'))."')";
|
357 |
+
$cwhere .= " AND `".$wpdb->comments."`.`comment_post_ID` NOT IN('".implode("','", $x_singulars)."')";
|
358 |
+
}
|
359 |
+
remove_filter('comment_feed_where', 'c_ws_plugin__s2member_querys::_query_level_access_coms', 100, 2);
|
360 |
+
|
361 |
+
return apply_filters('_ws_plugin__s2member_query_level_access_coms', $cwhere, get_defined_vars());
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* AJAX search via `admin-ajax.php`?
|
366 |
+
*
|
367 |
+
* @package s2Member\Queries
|
368 |
+
* @since 110912
|
369 |
+
*
|
370 |
+
* @param WP_Query $wp_query Expects ``$wp_query`` by reference.
|
371 |
+
*
|
372 |
+
* @return bool True if it's an AJAX search via `admin-ajax.php`, else false.
|
373 |
+
*/
|
374 |
+
public static function _is_admin_ajax_search(&$wp_query = NULL)
|
375 |
+
{
|
376 |
+
global $wpdb; // Global DB object reference.
|
377 |
+
|
378 |
+
if(is_object($wpdb) && is_object($wp_query) && is_admin() && $wp_query->is_search())
|
379 |
+
if(defined('DOING_AJAX') && DOING_AJAX && !empty($_REQUEST['action']) && (did_action('wp_ajax_nopriv_'.$_REQUEST['action']) || did_action('wp_ajax_'.$_REQUEST['action'])))
|
380 |
+
return apply_filters('_ws_plugin__s2member_is_admin_ajax_search', TRUE, get_defined_vars());
|
381 |
+
|
382 |
+
return apply_filters('_ws_plugin__s2member_is_admin_ajax_search', FALSE, get_defined_vars());
|
383 |
+
}
|
384 |
+
|
385 |
+
/**
|
386 |
+
* Filters WordPress Page queries that use wp_list_pages()
|
387 |
+
*
|
388 |
+
* @package s2Member\Queries
|
389 |
+
* @since 130617
|
390 |
+
*
|
391 |
+
* @attaches-to ``add_filter('wp_list_pages_excludes');``
|
392 |
+
*
|
393 |
+
* @param array $excludes An array of any existing excludes.
|
394 |
+
*
|
395 |
+
* @return array The array of ``$excludes``.
|
396 |
+
*/
|
397 |
+
public static function _query_level_access_list_pages($excludes = array())
|
398 |
+
{
|
399 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // Here we need to exclude any Page not available to the current user.
|
400 |
+
{
|
401 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] === 'all' && !current_user_can('access_s2member_level'.$n))
|
402 |
+
$excludes = array_merge($excludes, c_ws_plugin__s2member_utils_arrays::force_integers(c_ws_plugin__s2member_utils_gets::get_all_page_ids()));
|
403 |
+
else if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] && !current_user_can('access_s2member_level'.$n))
|
404 |
+
$excludes = array_merge($excludes, c_ws_plugin__s2member_utils_arrays::force_integers(preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'])));
|
405 |
}
|
406 |
+
return $excludes;
|
407 |
+
}
|
408 |
}
|
409 |
+
}
|
includes/classes/registration-times.inc.php
CHANGED
@@ -65,7 +65,7 @@ if(!class_exists("c_ws_plugin__s2member_registration_times"))
|
|
65 |
*
|
66 |
* @return int A Unix timestamp, indicating Registration Time, else `0` on failure.
|
67 |
*/
|
68 |
-
public static function registration_time($user_id =
|
69 |
{
|
70 |
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
71 |
do_action("ws_plugin__s2member_before_registration_time", get_defined_vars());
|
65 |
*
|
66 |
* @return int A Unix timestamp, indicating Registration Time, else `0` on failure.
|
67 |
*/
|
68 |
+
public static function registration_time($user_id = 0)
|
69 |
{
|
70 |
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
71 |
do_action("ws_plugin__s2member_before_registration_time", get_defined_vars());
|
includes/classes/return-templates.inc.php
CHANGED
@@ -1,84 +1,80 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member's Return Page template handler.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Return_Templates
|
15 |
-
* @since 110720
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit (
|
19 |
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
* @return string The full HTML code of the template. All Replacement Codes inside the template file will have already been filled by this routine.
|
41 |
-
*/
|
42 |
-
public static function return_template ($template = FALSE, $response = FALSE, $continue_html = FALSE, $continue_link = FALSE)
|
43 |
-
{
|
44 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
45 |
-
do_action("ws_plugin__s2member_before_return_template", get_defined_vars ());
|
46 |
-
unset($__refs, $__v);
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
|
53 |
-
|
54 |
-
|
|
|
55 |
|
56 |
-
|
57 |
-
|
|
|
58 |
|
59 |
-
|
60 |
-
$custom_template = (!$custom_template && file_exists (TEMPLATEPATH . "/default-return.html")) ? TEMPLATEPATH . "/default-return.html" : $custom_template;
|
61 |
|
62 |
-
|
63 |
-
|
64 |
|
65 |
-
|
|
|
66 |
|
67 |
-
|
68 |
-
$code = trim (((!$custom_template || !is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? c_ws_plugin__s2member_utilities::evl ($code) : $code));
|
69 |
|
70 |
-
|
71 |
-
|
|
|
|
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
$code = preg_replace ("/%%response%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (apply_filters("ws_plugin__s2member_return_template_response", $response, get_defined_vars ())), $code);
|
76 |
-
$code = preg_replace ("/%%continue%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (apply_filters("ws_plugin__s2member_return_template_continue", '<a href="' . esc_attr ($continue_link) . '">' . $continue_html . '</a>', get_defined_vars ())), $code);
|
77 |
-
$code = preg_replace ("/%%support%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (apply_filters("ws_plugin__s2member_return_template_support", sprintf (_x ('If you need assistance, please <a href="%s" target="_blank">contact support</a>.', "s2member-front", "s2member"), esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["reg_email_support_link"])), get_defined_vars ())), $code);
|
78 |
-
$code = preg_replace ("/%%tracking%%/i", c_ws_plugin__s2member_utils_strings::esc_refs (apply_filters("ws_plugin__s2member_return_template_tracking", c_ws_plugin__s2member_tracking_codes::generate_all_tracking_codes (), get_defined_vars ())), $code);
|
79 |
-
|
80 |
-
return apply_filters("ws_plugin__s2member_return_template", $code, get_defined_vars ());
|
81 |
-
}
|
82 |
-
}
|
83 |
}
|
84 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member's Return Page template handler.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Return_Templates
|
15 |
+
* @since 110720
|
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_return_templates'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* s2Member's Return Page template handler.
|
24 |
+
*
|
25 |
+
* @package s2Member\Return_Templates
|
26 |
+
* @since 110720
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_return_templates
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles Return templates w/ response message.
|
32 |
+
*
|
33 |
+
* @package s2Member\Return_Templates
|
34 |
+
* @since 110720
|
35 |
+
*
|
36 |
+
* @param string $template Optional A Subscr. Gateway code should be used as the template name, or `default` is a multipurpose template. Defaults to `default`. Used in template selection.
|
37 |
+
* @param string $response Optional. Response message to fill template with, using the Replacement Code `%%response%%` inside the template file. Defaults to: `Thank you. Please click the link below.`.
|
38 |
+
* @param string $continue_html Optional. The HTML value of the continuation link presented within the template using Replacement Code `%%continue%%`. Defaults to: `Continue`.
|
39 |
+
* @param string $continue_link Optional. The HREF value for the continuation link presented within the template using Replacement Code `%%continue%%`. Defaults to: ``home_url ('/', 'http')``.
|
40 |
+
*
|
41 |
+
* @return string The full HTML code of the template. All Replacement Codes inside the template file will have already been filled by this routine.
|
42 |
+
*/
|
43 |
+
public static function return_template($template = '', $response = '', $continue_html = '', $continue_link = '')
|
44 |
+
{
|
45 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
46 |
+
do_action('ws_plugin__s2member_before_return_template', get_defined_vars());
|
47 |
+
unset($__refs, $__v); // Housekeeping.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
+
$template = ($template) ? $template : 'default';
|
50 |
+
$continue_link = ($continue_link) ? $continue_link : home_url('/', 'http');
|
51 |
+
$continue_html = ($continue_html) ? $continue_html : _x('Continue', 's2member-front', 's2member');
|
52 |
+
$response = ($response) ? $response : _x('Thank you. Please click the link below.', 's2member-front', 's2member');
|
53 |
|
54 |
+
$custom_template = (is_file(TEMPLATEPATH.'/'.$template.'-return.php')) ? TEMPLATEPATH.'/'.$template.'-return.php' : '';
|
55 |
+
$custom_template = (is_file(get_stylesheet_directory().'/'.$template.'-return.php')) ? get_stylesheet_directory().'/'.$template.'-return.php' : $custom_template;
|
56 |
+
$custom_template = (is_file(WP_CONTENT_DIR.'/'.$template.'-return.php')) ? WP_CONTENT_DIR.'/'.$template.'-return.php' : $custom_template;
|
57 |
|
58 |
+
$custom_template = (!$custom_template && is_file(TEMPLATEPATH.'/default-return.php')) ? TEMPLATEPATH.'/default-return.php' : $custom_template;
|
59 |
+
$custom_template = (!$custom_template && is_file(get_stylesheet_directory().'/default-return.php')) ? get_stylesheet_directory().'/default-return.php' : $custom_template;
|
60 |
+
$custom_template = (!$custom_template && is_file(WP_CONTENT_DIR.'/default-return.php')) ? WP_CONTENT_DIR.'/default-return.php' : $custom_template;
|
61 |
|
62 |
+
$specific_template = ($custom_template) ? $custom_template : ((is_file($_default_specific_template = dirname(dirname(__FILE__)).'/templates/returns/'.$template.'-return.php')) ? $_default_specific_template : '');
|
|
|
63 |
|
64 |
+
$code = trim(file_get_contents((($specific_template) ? $specific_template : ($_default_template = dirname(dirname(__FILE__)).'/templates/returns/default-return.php'))));
|
65 |
+
$code = trim(((!$custom_template || !is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? c_ws_plugin__s2member_utilities::evl($code) : $code));
|
66 |
|
67 |
+
$doctype_html_head = c_ws_plugin__s2member_utils_html::doctype_html_head(get_bloginfo('name'), 'ws_plugin__s2member_during_return_template_head_'.(($specific_template) ? basename($specific_template) : 'default-return.php'));
|
68 |
+
$code = preg_replace('/%%doctype_html_head%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(apply_filters('ws_plugin__s2member_return_template_doctype_html_head', $doctype_html_head, get_defined_vars())), $code);
|
69 |
|
70 |
+
$code = preg_replace('/%%header%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(apply_filters('ws_plugin__s2member_return_template_header', sprintf(_x('[ %s ] <strong><em>says…</em></strong>', 's2member-front', 's2member'), esc_html($_SERVER['HTTP_HOST'])), get_defined_vars())), $code);
|
|
|
71 |
|
72 |
+
$code = preg_replace('/%%response%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(apply_filters('ws_plugin__s2member_return_template_response', $response, get_defined_vars())), $code);
|
73 |
+
$code = preg_replace('/%%continue%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(apply_filters('ws_plugin__s2member_return_template_continue', '<a href="'.esc_attr($continue_link).'">'.$continue_html.'</a>', get_defined_vars())), $code);
|
74 |
+
$code = preg_replace('/%%support%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(apply_filters('ws_plugin__s2member_return_template_support', sprintf(_x('If you need assistance, please <a href="%s" target="_blank">contact support</a>.', 's2member-front', 's2member'), esc_attr($GLOBALS['WS_PLUGIN__']['s2member']['o']['reg_email_support_link'])), get_defined_vars())), $code);
|
75 |
+
$code = preg_replace('/%%tracking%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(apply_filters('ws_plugin__s2member_return_template_tracking', c_ws_plugin__s2member_tracking_codes::generate_all_tracking_codes(), get_defined_vars())), $code);
|
76 |
|
77 |
+
return apply_filters('ws_plugin__s2member_return_template', $code, get_defined_vars());
|
78 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
+
}
|
includes/classes/roles-caps.inc.php
CHANGED
@@ -14,186 +14,186 @@
|
|
14 |
* @package s2Member\Roles_Caps
|
15 |
* @since 110524RC
|
16 |
*/
|
17 |
-
if(realpath(__FILE__) === realpath($_SERVER[
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if(!class_exists(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
* Roles/Capabilities.
|
24 |
*
|
25 |
* @package s2Member\Roles_Caps
|
26 |
* @since 110524RC
|
|
|
|
|
27 |
*/
|
28 |
-
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
|
|
39 |
{
|
40 |
-
|
41 |
-
|
42 |
-
if(!apply_filters("ws_plugin__s2member_lock_roles_caps", FALSE))
|
43 |
-
{
|
44 |
-
c_ws_plugin__s2member_roles_caps::unlink_roles();
|
45 |
-
|
46 |
-
if(function_exists("bbp_get_dynamic_roles") /* bbPress v2.2+ integration. */)
|
47 |
-
{
|
48 |
-
foreach(bbp_get_caps_for_role(bbp_get_participant_role()) as $bbp_participant_cap => $bbp_participant_cap_is)
|
49 |
-
if($bbp_participant_cap_is /* Is this capability enabled? */)
|
50 |
-
$bbp_participant_caps[$bbp_participant_cap] = TRUE;
|
51 |
-
}
|
52 |
-
else if(function_exists("bbp_get_caps_for_role") /* bbPress < v2.2 integration. */)
|
53 |
-
{
|
54 |
-
foreach(bbp_get_caps_for_role(bbp_get_participant_role()) as $bbp_participant_cap)
|
55 |
-
$bbp_participant_caps[$bbp_participant_cap] = TRUE;
|
56 |
-
}
|
57 |
-
if(0 === 0) // Subscriber Role is required by s2Member.
|
58 |
-
{
|
59 |
-
$caps = array("read" => TRUE, "level_0" => TRUE);
|
60 |
-
$caps = array_merge($caps, array("access_s2member_level0" => TRUE));
|
61 |
-
$caps = (!empty($bbp_participant_caps)) ? array_merge($caps, $bbp_participant_caps) : $caps;
|
62 |
-
|
63 |
-
if(!($role = get_role("subscriber")))
|
64 |
-
{
|
65 |
-
add_role("subscriber", "Subscriber");
|
66 |
-
$role = get_role("subscriber");
|
67 |
-
}
|
68 |
-
foreach(array_keys($caps) as $cap)
|
69 |
-
$role->add_cap($cap);
|
70 |
-
}
|
71 |
-
for($n = 1; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
72 |
-
{
|
73 |
-
for($i = 0, $caps = array("read" => TRUE, "level_0" => TRUE); $i <= $n; $i++)
|
74 |
-
$caps = array_merge($caps, array("access_s2member_level".$i => TRUE));
|
75 |
-
$caps = (!empty($bbp_participant_caps)) ? array_merge($caps, $bbp_participant_caps) : $caps;
|
76 |
-
|
77 |
-
if(!($role = get_role("s2member_level".$n)))
|
78 |
-
{
|
79 |
-
add_role("s2member_level".$n, "s2Member Level ".$n);
|
80 |
-
$role = get_role("s2member_level".$n);
|
81 |
-
}
|
82 |
-
foreach(array_keys($caps) as $cap)
|
83 |
-
$role->add_cap($cap);
|
84 |
-
}
|
85 |
-
$full_access_roles = array("administrator", "editor", "author", "contributor");
|
86 |
-
|
87 |
-
if(function_exists("bbp_get_caps_for_role") && !function_exists("bbp_get_dynamic_roles") /* bbPress < v2.2 integration. */)
|
88 |
-
$full_access_roles = array_merge($full_access_roles, (array)bbp_get_moderator_role());
|
89 |
-
|
90 |
-
foreach($full_access_roles as $role)
|
91 |
-
{
|
92 |
-
if(($role = get_role($role)))
|
93 |
-
for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
94 |
-
$role->add_cap("access_s2member_level".$n);
|
95 |
-
}
|
96 |
-
}
|
97 |
-
do_action("ws_plugin__s2member_after_config_roles", get_defined_vars());
|
98 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
-
|
101 |
-
* Adds support for bbPress v2.2+ dynamic roles.
|
102 |
-
*
|
103 |
-
* @package s2Member\Roles_Caps
|
104 |
-
* @since 112512
|
105 |
-
*
|
106 |
-
* @attaches-to ``add_filter("bbp_get_caps_for_role");``
|
107 |
-
*
|
108 |
-
* @return array
|
109 |
-
*/
|
110 |
-
public static function bbp_dynamic_role_caps($caps = FALSE, $role = FALSE)
|
111 |
{
|
112 |
-
if(
|
113 |
-
|
114 |
-
|
115 |
-
$caps = array_merge($caps, array("read" => TRUE, "level_0" => TRUE));
|
116 |
-
$caps = array_merge($caps, array("access_s2member_level0" => TRUE));
|
117 |
-
|
118 |
-
if(in_array($role, array(bbp_get_keymaster_role(), bbp_get_moderator_role()), TRUE))
|
119 |
-
{
|
120 |
-
for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
121 |
-
$caps = array_merge($caps, array("access_s2member_level".$n => TRUE));
|
122 |
-
}
|
123 |
-
}
|
124 |
-
return $caps;
|
125 |
}
|
|
|
|
|
|
|
126 |
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
{
|
137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
|
144 |
-
|
145 |
-
|
|
|
|
|
146 |
|
147 |
-
|
|
|
148 |
|
149 |
-
|
150 |
-
$full_access_roles = array_merge($full_access_roles, (array)bbp_get_moderator_role());
|
151 |
|
152 |
-
|
153 |
-
|
154 |
-
if(($role = get_role($role)))
|
155 |
-
for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["max_levels"]; $n++)
|
156 |
-
$role->remove_cap("access_s2member_level".$n);
|
157 |
-
}
|
158 |
-
}
|
159 |
-
do_action("ws_plugin__s2member_after_unlink_roles", get_defined_vars());
|
160 |
-
}
|
161 |
|
162 |
-
|
163 |
-
* Updates Roles/Capabilities via AJAX.
|
164 |
-
*
|
165 |
-
* @package s2Member\Roles_Caps
|
166 |
-
* @since 110524RC
|
167 |
-
*
|
168 |
-
* @attaches-to ``add_action("wp_ajax_ws_plugin__s2member_update_roles_via_ajax");``
|
169 |
-
*
|
170 |
-
* @return null Exits script execution after output for AJAX caller.
|
171 |
-
*/
|
172 |
-
public static function update_roles_via_ajax()
|
173 |
{
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
-
|
|
|
|
|
181 |
|
182 |
-
|
183 |
-
if(($nonce = $_POST["ws_plugin__s2member_update_roles_via_ajax"]))
|
184 |
-
if(wp_verify_nonce($nonce, "ws-plugin--s2member-update-roles-via-ajax"))
|
185 |
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
$success = TRUE; // Roles updated.
|
190 |
-
}
|
191 |
-
else // Else flag as having been locked here.
|
192 |
-
$locked = TRUE;
|
193 |
|
194 |
-
|
195 |
-
|
196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
}
|
198 |
}
|
199 |
-
|
14 |
* @package s2Member\Roles_Caps
|
15 |
* @since 110524RC
|
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_roles_caps'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* Roles/Capabilities.
|
24 |
+
*
|
25 |
+
* @package s2Member\Roles_Caps
|
26 |
+
* @since 110524RC
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_roles_caps
|
29 |
{
|
30 |
/**
|
31 |
+
* Configures Roles/Capabilities.
|
32 |
*
|
33 |
* @package s2Member\Roles_Caps
|
34 |
* @since 110524RC
|
35 |
+
*
|
36 |
+
* @return null
|
37 |
*/
|
38 |
+
public static function config_roles()
|
39 |
{
|
40 |
+
do_action('ws_plugin__s2member_before_config_roles', get_defined_vars());
|
41 |
+
|
42 |
+
if(!apply_filters('ws_plugin__s2member_lock_roles_caps', FALSE))
|
43 |
+
{
|
44 |
+
c_ws_plugin__s2member_roles_caps::unlink_roles();
|
45 |
+
|
46 |
+
if(function_exists('bbp_get_dynamic_roles') && function_exists('bbp_get_caps_for_role') && function_exists('bbp_get_participant_role') /* bbPress v2.2+ integration. */)
|
47 |
+
{
|
48 |
+
foreach(bbp_get_caps_for_role(bbp_get_participant_role()) as $bbp_participant_cap => $bbp_participant_cap_is)
|
49 |
+
if($bbp_participant_cap_is /* Is this capability enabled? */)
|
50 |
+
$bbp_participant_caps[$bbp_participant_cap] = TRUE;
|
51 |
+
}
|
52 |
+
else if(function_exists('bbp_get_caps_for_role') && function_exists('bbp_get_participant_role') /* bbPress < v2.2 integration. */)
|
53 |
{
|
54 |
+
foreach(bbp_get_caps_for_role(bbp_get_participant_role()) as $bbp_participant_cap)
|
55 |
+
$bbp_participant_caps[$bbp_participant_cap] = TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
57 |
+
if(0 === 0) // Subscriber Role is required by s2Member.
|
58 |
+
{
|
59 |
+
$caps = array('read' => TRUE, 'level_0' => TRUE);
|
60 |
+
$caps = array_merge($caps, array('access_s2member_level0' => TRUE));
|
61 |
+
$caps = (!empty($bbp_participant_caps)) ? array_merge($caps, $bbp_participant_caps) : $caps;
|
62 |
+
|
63 |
+
if(!($role = get_role('subscriber')))
|
64 |
+
{
|
65 |
+
add_role('subscriber', 'Subscriber');
|
66 |
+
$role = get_role('subscriber');
|
67 |
+
}
|
68 |
+
foreach(array_keys($caps) as $cap)
|
69 |
+
$role->add_cap($cap);
|
70 |
+
}
|
71 |
+
for($n = 1; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n++)
|
72 |
+
{
|
73 |
+
for($i = 0, $caps = array('read' => TRUE, 'level_0' => TRUE); $i <= $n; $i++)
|
74 |
+
$caps = array_merge($caps, array('access_s2member_level'.$i => TRUE));
|
75 |
+
$caps = (!empty($bbp_participant_caps)) ? array_merge($caps, $bbp_participant_caps) : $caps;
|
76 |
+
|
77 |
+
if(!($role = get_role('s2member_level'.$n)))
|
78 |
+
{
|
79 |
+
add_role('s2member_level'.$n, 's2Member Level '.$n);
|
80 |
+
$role = get_role('s2member_level'.$n);
|
81 |
+
}
|
82 |
+
foreach(array_keys($caps) as $cap)
|
83 |
+
$role->add_cap($cap);
|
84 |
+
}
|
85 |
+
$full_access_roles = array('administrator', 'editor', 'author', 'contributor');
|
86 |
+
|
87 |
+
if(!function_exists('bbp_get_dynamic_roles') && function_exists('bbp_get_caps_for_role') && function_exists('bbp_get_moderator_role') /* bbPress < v2.2 integration. */)
|
88 |
+
$full_access_roles = array_merge($full_access_roles, (array)bbp_get_moderator_role());
|
89 |
|
90 |
+
foreach($full_access_roles as $role)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
{
|
92 |
+
if(($role = get_role($role)))
|
93 |
+
for($n = 0; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n++)
|
94 |
+
$role->add_cap('access_s2member_level'.$n);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
+
}
|
97 |
+
do_action('ws_plugin__s2member_after_config_roles', get_defined_vars());
|
98 |
+
}
|
99 |
|
100 |
+
/**
|
101 |
+
* Adds support for bbPress v2.2+ dynamic roles.
|
102 |
+
*
|
103 |
+
* @package s2Member\Roles_Caps
|
104 |
+
* @since 112512
|
105 |
+
*
|
106 |
+
* @param array $caps Array of BBP capabilities.
|
107 |
+
* @param string $role Role ID in WordPress.
|
108 |
+
*
|
109 |
+
* @attaches-to ``add_filter('bbp_get_caps_for_role');``
|
110 |
+
*
|
111 |
+
* @return array
|
112 |
+
*/
|
113 |
+
public static function bbp_dynamic_role_caps($caps = array(), $role = '')
|
114 |
+
{
|
115 |
+
if(function_exists('bbp_get_dynamic_roles') && function_exists('bbp_get_blocked_role') && $role !== bbp_get_blocked_role())
|
116 |
+
if(!did_action('bbp_deactivation') && !did_action('bbp_uninstall') && function_exists('bbp_get_keymaster_role') && function_exists('bbp_get_moderator_role'))
|
117 |
{
|
118 |
+
$caps = array_merge($caps, array('read' => TRUE, 'level_0' => TRUE));
|
119 |
+
$caps = array_merge($caps, array('access_s2member_level0' => TRUE));
|
120 |
+
|
121 |
+
if(in_array($role, array(bbp_get_keymaster_role(), bbp_get_moderator_role()), TRUE))
|
122 |
+
{
|
123 |
+
for($n = 0; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n++)
|
124 |
+
$caps = array_merge($caps, array('access_s2member_level'.$n => TRUE));
|
125 |
+
}
|
126 |
+
}
|
127 |
+
return $caps;
|
128 |
+
}
|
129 |
|
130 |
+
/**
|
131 |
+
* Unlinks Roles/Capabilities.
|
132 |
+
*
|
133 |
+
* @package s2Member\Roles_Caps
|
134 |
+
* @since 110524RC
|
135 |
+
*
|
136 |
+
* @return null
|
137 |
+
*/
|
138 |
+
public static function unlink_roles()
|
139 |
+
{
|
140 |
+
do_action('ws_plugin__s2member_before_unlink_roles', get_defined_vars());
|
141 |
|
142 |
+
if(!apply_filters('ws_plugin__s2member_lock_roles_caps', FALSE))
|
143 |
+
{
|
144 |
+
if(($role = get_role('subscriber')))
|
145 |
+
$role->remove_cap('access_s2member_level0');
|
146 |
|
147 |
+
for($n = 1; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['max_levels']; $n++)
|
148 |
+
remove_role('s2member_level'.$n);
|
149 |
|
150 |
+
$full_access_roles = array('administrator', 'editor', 'author', 'contributor');
|
|
|
151 |
|
152 |
+
if(!function_exists('bbp_get_dynamic_roles') && function_exists('bbp_get_caps_for_role') && function_exists('bbp_get_moderator_role'))
|
153 |
+
$full_access_roles = array_merge($full_access_roles, (array)bbp_get_moderator_role());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
|
155 |
+
foreach($full_access_roles as $role)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
{
|
157 |
+
if(($role = get_role($role)))
|
158 |
+
for($n = 0; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['max_levels']; $n++)
|
159 |
+
$role->remove_cap('access_s2member_level'.$n);
|
160 |
+
}
|
161 |
+
}
|
162 |
+
do_action('ws_plugin__s2member_after_unlink_roles', get_defined_vars());
|
163 |
+
}
|
164 |
|
165 |
+
/**
|
166 |
+
* Updates Roles/Capabilities via AJAX.
|
167 |
+
*
|
168 |
+
* @package s2Member\Roles_Caps
|
169 |
+
* @since 110524RC
|
170 |
+
*
|
171 |
+
* @attaches-to ``add_action('wp_ajax_ws_plugin__s2member_update_roles_via_ajax');``
|
172 |
+
*/
|
173 |
+
public static function update_roles_via_ajax()
|
174 |
+
{
|
175 |
+
do_action('ws_plugin__s2member_before_update_roles_via_ajax', get_defined_vars());
|
176 |
|
177 |
+
status_header(200); // Send a 200 OK status header.
|
178 |
+
header('Content-Type: text/plain; charset=UTF-8'); // Content-Type with UTF-8.
|
179 |
+
while(@ob_end_clean()) ; // Clean any existing output buffers.
|
180 |
|
181 |
+
if(current_user_can('create_users')) // Check privileges. Ability to create Users?
|
|
|
|
|
182 |
|
183 |
+
if(!empty($_POST['ws_plugin__s2member_update_roles_via_ajax']))
|
184 |
+
if(($nonce = $_POST['ws_plugin__s2member_update_roles_via_ajax']))
|
185 |
+
if(wp_verify_nonce($nonce, 'ws-plugin--s2member-update-roles-via-ajax'))
|
|
|
|
|
|
|
|
|
186 |
|
187 |
+
if(!apply_filters('ws_plugin__s2member_lock_roles_caps', FALSE))
|
188 |
+
{
|
189 |
+
c_ws_plugin__s2member_roles_caps::config_roles();
|
190 |
+
$success = TRUE; // Roles updated.
|
191 |
+
}
|
192 |
+
else // Else flag as having been locked here.
|
193 |
+
$locked = TRUE;
|
194 |
+
|
195 |
+
exit(apply_filters('ws_plugin__s2member_update_roles_via_ajax', // Also handle ``$locked`` here.
|
196 |
+
((isset($success) && $success) ? '1' : ((isset($locked) && $locked) ? 'l' : '0')), get_defined_vars()));
|
197 |
}
|
198 |
}
|
199 |
+
}
|
includes/classes/ruris.inc.php
CHANGED
@@ -1,113 +1,112 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member's URI protection routines *(for current URI)*.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\URIs
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit (
|
19 |
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
* @package s2Member\URIs
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @return null Or exits script execution after redirection.
|
37 |
-
*/
|
38 |
-
public static function check_ruri_level_access ()
|
39 |
-
{
|
40 |
-
do_action("ws_plugin__s2member_before_check_ruri_level_access", get_defined_vars ());
|
41 |
-
|
42 |
-
$excluded = apply_filters("ws_plugin__s2member_check_ruri_level_access_excluded", false, get_defined_vars ());
|
43 |
-
|
44 |
-
if (!$excluded && $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"]) // Has it been excluded?
|
45 |
-
{
|
46 |
-
if (!c_ws_plugin__s2member_systematics::is_wp_systematic_use_page ()) // Do NOT touch WordPress Systematics. This excludes all WordPress Systematics.
|
47 |
-
{
|
48 |
-
$user = (is_user_logged_in () && is_object ($user = wp_get_current_user ()) && !empty($user->ID)) ? $user : false; // Current User's object.
|
49 |
|
50 |
-
|
51 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("ruri", $_SERVER["REQUEST_URI"], "level", 0, $_SERVER["REQUEST_URI"], "sys") . exit ();
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
foreach (preg_split ("/[\r\n\t]+/", c_ws_plugin__s2member_ruris::fill_ruri_level_access_rc_vars ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ruris"], $user)) as $str)
|
60 |
-
if ($str && preg_match ("/" . preg_quote ($str, "/") . "/", $_SERVER["REQUEST_URI"]) && c_ws_plugin__s2member_no_cache::no_cache_constants ('restricted') && (!$user || !$user->has_cap ("access_s2member_level" . $n)))
|
61 |
-
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars /* Configure MOP Vars here. */ ("ruri", $_SERVER["REQUEST_URI"], "level", $n, $_SERVER["REQUEST_URI"]) . exit ();
|
62 |
-
}
|
63 |
-
}
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
}
|
68 |
|
69 |
-
|
|
|
|
|
|
|
|
|
70 |
|
71 |
-
|
|
|
|
|
|
|
72 |
}
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
-
|
90 |
-
|
91 |
|
92 |
-
|
93 |
|
94 |
-
|
95 |
-
|
|
|
96 |
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
}
|
112 |
}
|
113 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member's URI protection routines *(for current URI)*.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\URIs
|
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_ruris'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* s2Member's URI protection routines *(for current URI)*.
|
24 |
+
*
|
25 |
+
* @package s2Member\URIs
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_ruris
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles URI Level Access permissions *(for current URI)*.
|
32 |
+
*
|
33 |
+
* @package s2Member\URIs
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @return null Or exits script execution after redirection.
|
37 |
+
*/
|
38 |
+
public static function check_ruri_level_access()
|
39 |
+
{
|
40 |
+
do_action('ws_plugin__s2member_before_check_ruri_level_access', get_defined_vars());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
+
$excluded = apply_filters('ws_plugin__s2member_check_ruri_level_access_excluded', FALSE, get_defined_vars());
|
|
|
43 |
|
44 |
+
if(!$excluded && $GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page']) // Has it been excluded?
|
45 |
+
{
|
46 |
+
if(!c_ws_plugin__s2member_systematics::is_wp_systematic_use_page()) // Do NOT touch WordPress Systematics. This excludes all WordPress Systematics.
|
47 |
+
{
|
48 |
+
$user = (is_user_logged_in() && is_object($user = wp_get_current_user()) && !empty($user->ID)) ? $user : FALSE; // Current User's object.
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_redirection_override'] && ($login_redirection_uri = c_ws_plugin__s2member_login_redirects::login_redirection_uri($user, 'root-returns-false')) && preg_match('/^'.preg_quote($login_redirection_uri, '/').'$/', $_SERVER['REQUEST_URI']) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level0')))
|
51 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('ruri', $_SERVER['REQUEST_URI'], 'level', 0, $_SERVER['REQUEST_URI'], 'sys').exit ();
|
|
|
52 |
|
53 |
+
else if(!c_ws_plugin__s2member_systematics::is_systematic_use_page()) // Do NOT protect Systematics. However, there is 1 exception above ^.
|
54 |
+
{
|
55 |
+
for($n = $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n >= 0; $n--) // URIs. Go through each Level.
|
56 |
+
{
|
57 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris']) // URIs configured at this Level?
|
58 |
|
59 |
+
foreach(preg_split('/['."\r\n\t".']+/', c_ws_plugin__s2member_ruris::fill_ruri_level_access_rc_vars($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ruris'], $user)) as $str)
|
60 |
+
if($str && preg_match('/'.preg_quote($str, '/').'/', $_SERVER['REQUEST_URI']) && c_ws_plugin__s2member_no_cache::no_cache_constants('restricted') && (!$user || !$user->has_cap('access_s2member_level'.$n)))
|
61 |
+
c_ws_plugin__s2member_mo_page::wp_redirect_w_mop_vars('ruri', $_SERVER['REQUEST_URI'], 'level', $n, $_SERVER['REQUEST_URI']).exit ();
|
62 |
+
}
|
63 |
}
|
64 |
+
do_action('ws_plugin__s2member_during_check_ruri_level_access', get_defined_vars());
|
65 |
+
}
|
66 |
+
}
|
67 |
+
do_action('ws_plugin__s2member_after_check_ruri_level_access', get_defined_vars());
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Fills Replacement Code variables in URIs; collectively.
|
72 |
+
*
|
73 |
+
* @package s2Member\URIs
|
74 |
+
* @since 3.5
|
75 |
+
*
|
76 |
+
* @param string $uris A URI string, or a string of multiple URIs is also fine.
|
77 |
+
* @param object $user Optional. A `WP_User` object. Defaults to the current User, if logged-in.
|
78 |
+
*
|
79 |
+
* @return string Collective string of input URIs, with Replacement Codes having been filled.
|
80 |
+
*/
|
81 |
+
public static function fill_ruri_level_access_rc_vars($uris = '', $user = NULL)
|
82 |
+
{
|
83 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
84 |
+
do_action('ws_plugin__s2member_before_fill_ruri_level_access_rc_vars', get_defined_vars());
|
85 |
+
unset($__refs, $__v); // Housekeeping.
|
86 |
|
87 |
+
$uris = (string)$uris; // Force ``$uris`` to a string value.
|
88 |
+
$orig_uris = $uris; // Record the original URIs that were passed in; collectively.
|
89 |
|
90 |
+
$user = ((is_object($user) || is_object($user = (is_user_logged_in()) ? wp_get_current_user() : FALSE)) && !empty($user->ID)) ? $user : FALSE;
|
91 |
|
92 |
+
$user_id = ($user) ? (string)$user->ID : '';
|
93 |
+
$user_login = ($user) ? (string)strtolower($user->user_login) : '';
|
94 |
+
$user_nicename = ($user) ? (string)strtolower($user->user_nicename) : '';
|
95 |
|
96 |
+
$user_level = (string)c_ws_plugin__s2member_user_access::user_access_level($user);
|
97 |
+
$user_role = (string)c_ws_plugin__s2member_user_access::user_access_role($user);
|
98 |
+
$user_ccaps = (string)implode('-', c_ws_plugin__s2member_user_access::user_access_ccaps($user));
|
99 |
+
$user_logins = ($user) ? (string)(int)get_user_option('s2member_login_counter', $user_id) : '-1';
|
100 |
|
101 |
+
$uris = (strlen($user_login)) ? preg_replace('/%%current_user_login%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_login)), $uris) : $uris;
|
102 |
+
$uris = (strlen($user_nicename)) ? preg_replace('/%%current_user_nicename%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_nicename)), $uris) : $uris;
|
103 |
+
$uris = (strlen($user_id)) ? preg_replace('/%%current_user_id%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_id)), $uris) : $uris;
|
104 |
+
$uris = (strlen($user_level)) ? preg_replace('/%%current_user_level%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_level)), $uris) : $uris;
|
105 |
+
$uris = (strlen($user_role)) ? preg_replace('/%%current_user_role%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_role)), $uris) : $uris;
|
106 |
+
$uris = (strlen($user_ccaps)) ? preg_replace('/%%current_user_ccaps%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_ccaps)), $uris) : $uris;
|
107 |
+
$uris = (strlen($user_logins)) ? preg_replace('/%%current_user_logins%%/i', c_ws_plugin__s2member_utils_strings::esc_refs(urlencode($user_logins)), $uris) : $uris;
|
108 |
|
109 |
+
return apply_filters('ws_plugin__s2member_fill_ruri_level_access_rc_vars', $uris, get_defined_vars());
|
110 |
+
}
|
|
|
111 |
}
|
112 |
+
}
|
includes/classes/sc-files-in.inc.php
CHANGED
@@ -1,174 +1,342 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* Shortcode `[s2File /]` (inner processing routines).
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\s2File
|
15 |
-
* @since 110926
|
16 |
-
*/
|
17 |
-
if(realpath(__FILE__) === realpath($_SERVER[
|
18 |
-
exit(
|
19 |
-
|
20 |
-
if(!class_exists(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
* Handles the Shortcode for: `[s2File /]`.
|
32 |
-
*
|
33 |
-
* @package s2Member\s2File
|
34 |
-
* @since 110926
|
35 |
-
*
|
36 |
-
* @attaches-to ``add_shortcode("s2File");``
|
37 |
-
*
|
38 |
-
* @param array $attr An array of Attributes.
|
39 |
-
* @param string $content Content inside the Shortcode.
|
40 |
-
* @param string $shortcode The actual Shortcode name itself.
|
41 |
-
* @return string Value of requested File Download URL, streamer array element; or null on failure.
|
42 |
-
*/
|
43 |
-
public static function sc_get_file($attr = FALSE, $content = FALSE, $shortcode = FALSE)
|
44 |
-
{
|
45 |
-
foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
|
46 |
-
do_action("ws_plugin__s2member_before_sc_get_file", get_defined_vars());
|
47 |
-
unset($__refs, $__v);
|
48 |
|
49 |
-
|
|
|
50 |
|
51 |
-
|
|
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
-
|
62 |
-
if(strlen($value) && in_array($key, array("download", "download_key", "stream", "inline", "storage", "remote", "ssl", "rewrite", "rewrite_base")))
|
63 |
-
$config["file_".$key] = /* Set prefixed config parameter here so we can pass properly in ``$config`` array. */ $value;
|
64 |
-
else if(strlen($value) && !in_array($key, array("get_streamer_json", "get_streamer_array")))
|
65 |
-
$config[$key] = $value;
|
66 |
|
67 |
-
|
|
|
|
|
|
|
|
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
72 |
|
73 |
-
|
74 |
-
|
|
|
75 |
|
76 |
-
|
77 |
-
|
|
|
|
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
}
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
* @return string HTML markup that produces an audio/video stream for a specific player.
|
96 |
-
*/
|
97 |
-
public static function sc_get_stream($attr = FALSE, $content = FALSE, $shortcode = FALSE)
|
98 |
{
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
102 |
|
103 |
-
$
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
-
|
106 |
-
$
|
|
|
107 |
|
108 |
-
|
109 |
-
|
110 |
-
|
|
|
|
|
111 |
|
112 |
-
foreach
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
$config[$key] = $value;
|
117 |
|
118 |
-
|
|
|
119 |
|
120 |
-
|
121 |
{
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
|
124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
{
|
126 |
-
$
|
127 |
-
$
|
128 |
-
|
129 |
-
if(strpos($attr["player"], "jwplayer-v6") === 0)
|
130 |
-
{
|
131 |
-
$get = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($template)));
|
132 |
-
|
133 |
-
$get = preg_replace("/%%streamer%%/", $_get["streamer"], $get);
|
134 |
-
$get = preg_replace("/%%prefix%%/", $_get["prefix"], $get);
|
135 |
-
$get = preg_replace("/%%file%%/", $_get["file"], $get);
|
136 |
-
$get = preg_replace("/%%url%%/", $_get["url"], $get);
|
137 |
-
|
138 |
-
$get = preg_replace("/%%player_id%%/", $attr["player_id"], $get);
|
139 |
-
$get = preg_replace("/%%player_path%%/", $attr["player_path"], $get);
|
140 |
-
$get = preg_replace("/%%player_key%%/", $attr["player_key"], $get);
|
141 |
-
|
142 |
-
$get = preg_replace("/%%player_title%%/", $attr["player_title"], $get);
|
143 |
-
$get = preg_replace("/%%player_image%%/", $attr["player_image"], $get);
|
144 |
-
|
145 |
-
$get = preg_replace("/%%player_mediaid%%/", $attr["player_mediaid"], $get);
|
146 |
-
$get = preg_replace("/%%player_description%%/", $attr["player_description"], $get);
|
147 |
-
|
148 |
-
if(($attr["player_captions"] = c_ws_plugin__s2member_utils_strings::trim($attr["player_captions"], null, "[]")))
|
149 |
-
$get = preg_replace("/%%player_captions%%/", "[".((strpos($attr["player_captions"], ":") !== false) ? $attr["player_captions"] : base64_decode($attr["player_captions"]))."]", $get);
|
150 |
-
else $get = preg_replace("/%%player_captions%%/", "[]", $get);
|
151 |
-
|
152 |
-
$get = preg_replace("/%%player_controls%%/", ((filter_var($attr["player_controls"], FILTER_VALIDATE_BOOLEAN)) ? "true" : "false"), $get);
|
153 |
-
$get = preg_replace("/%%player_width%%/", ((strpos($attr["player_width"], "%") !== FALSE) ? "'".$attr["player_width"]."'" : (integer)$attr["player_width"]), $get);
|
154 |
-
$get = preg_replace("/%%player_height%%/", (($attr["player_aspectratio"]) ? "''" : ((strpos($attr["player_height"], "%") !== FALSE) ? "'".$attr["player_height"]."'" : (integer)$attr["player_height"])), $get);
|
155 |
-
$get = preg_replace("/%%player_aspectratio%%/", $attr["player_aspectratio"], $get);
|
156 |
-
$get = preg_replace("/%%player_skin%%/", $attr["player_skin"], $get);
|
157 |
-
$get = preg_replace("/%%player_stretching%%/", $attr["player_stretching"], $get);
|
158 |
-
|
159 |
-
$get = preg_replace("/%%player_autostart%%/", ((filter_var($attr["player_autostart"], FILTER_VALIDATE_BOOLEAN)) ? "true" : "false"), $get);
|
160 |
-
$get = preg_replace("/%%player_fallback%%/", ((filter_var($attr["player_fallback"], FILTER_VALIDATE_BOOLEAN)) ? "true" : "false"), $get);
|
161 |
-
$get = preg_replace("/%%player_mute%%/", ((filter_var($attr["player_mute"], FILTER_VALIDATE_BOOLEAN)) ? "true" : "false"), $get);
|
162 |
-
$get = preg_replace("/%%player_primary%%/", $attr["player_primary"], $get);
|
163 |
-
$get = preg_replace("/%%player_repeat%%/", ((filter_var($attr["player_repeat"], FILTER_VALIDATE_BOOLEAN)) ? "true" : "false"), $get);
|
164 |
-
$get = preg_replace("/%%player_startparam%%/", $attr["player_startparam"], $get);
|
165 |
-
|
166 |
-
$get = preg_replace("/%%player_option_blocks%%/", ((strpos($attr["player_option_blocks"], ":") !== false) ? $attr["player_option_blocks"] : base64_decode($attr["player_option_blocks"])), $get);
|
167 |
-
}
|
168 |
}
|
|
|
169 |
}
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
}
|
|
|
172 |
}
|
|
|
|
|
173 |
}
|
174 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Shortcode `[s2File /]` (inner processing routines).
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\s2File
|
15 |
+
* @since 110926
|
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_sc_files_in'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* Shortcode `[s2File /]` (inner processing routines).
|
24 |
+
*
|
25 |
+
* @package s2Member\s2File
|
26 |
+
* @since 110926
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_sc_files_in
|
29 |
{
|
30 |
/**
|
31 |
+
* Handles the Shortcode for: `[s2File /]`.
|
32 |
+
*
|
33 |
+
* @package s2Member\s2File
|
34 |
+
* @since 110926
|
35 |
+
*
|
36 |
+
* @attaches-to ``add_shortcode('s2File');``
|
37 |
+
*
|
38 |
+
* @param array $attr An array of Attributes.
|
39 |
+
* @param string $content Content inside the Shortcode.
|
40 |
+
* @param string $shortcode The actual Shortcode name itself.
|
41 |
+
*
|
42 |
+
* @return string Value of requested File Download URL, streamer array element; or null on failure.
|
43 |
+
*/
|
44 |
+
public static function sc_get_file($attr = array(), $content = '', $shortcode = '')
|
45 |
+
{
|
46 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
47 |
+
do_action('ws_plugin__s2member_before_sc_get_file', get_defined_vars());
|
48 |
+
unset($__refs, $__v); // Housekeeping.
|
49 |
+
|
50 |
+
$attr = c_ws_plugin__s2member_utils_strings::trim_qts_deep((array)$attr); // Force array; trim quote entities.
|
51 |
+
|
52 |
+
$attr = shortcode_atts(array('download' => '', 'download_key' => '',
|
53 |
+
'stream' => '', 'inline' => '', 'storage' => '',
|
54 |
+
'remote' => '', 'ssl' => '', 'rewrite' => '', 'rewrite_base' => '',
|
55 |
+
'skip_confirmation' => '', 'url_to_storage_source' => '',
|
56 |
+
'count_against_user' => '', 'check_user' => '',
|
57 |
+
'get_streamer_json' => '', 'get_streamer_array' => ''), $attr);
|
58 |
+
|
59 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
60 |
+
do_action('ws_plugin__s2member_before_sc_get_file_after_shortcode_atts', get_defined_vars());
|
61 |
+
unset($__refs, $__v); // Housekeeping.
|
62 |
+
|
63 |
+
$get_streamer_json = filter_var($attr['get_streamer_json'], FILTER_VALIDATE_BOOLEAN);
|
64 |
+
$get_streamer_array = filter_var($attr['get_streamer_array'], FILTER_VALIDATE_BOOLEAN);
|
65 |
+
$get_streamer_json = $get_streamer_array = ($get_streamer_array || $get_streamer_json) ? TRUE : FALSE;
|
66 |
+
|
67 |
+
foreach($attr as $key => $value) // Now we need to go through and a `file_` prefix to certain Attribute keys, for compatibility.
|
68 |
+
if(strlen($value) && in_array($key, array('download', 'download_key', 'stream', 'inline', 'storage', 'remote', 'ssl', 'rewrite', 'rewrite_base')))
|
69 |
+
$config['file_'.$key] = $value; // Set prefixed config parameter here so we can pass properly in ``$config`` array.
|
70 |
+
else if(strlen($value) && !in_array($key, array('get_streamer_json', 'get_streamer_array')))
|
71 |
+
$config[$key] = $value;
|
72 |
+
|
73 |
+
unset($key, $value); // We don't want these bleeding into Hooks/Filters anyway.
|
74 |
+
|
75 |
+
if(!empty($config) && isset($config['file_download'])) // Looking for a File Download URL?
|
76 |
{
|
77 |
+
$_get = c_ws_plugin__s2member_files::create_file_download_url($config, $get_streamer_array);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
+
if($get_streamer_array && $get_streamer_json && is_array($_get))
|
80 |
+
$get = json_encode($_get);
|
81 |
|
82 |
+
else if($get_streamer_array && $get_streamer_json)
|
83 |
+
$get = 'null'; // Null object value.
|
84 |
|
85 |
+
else if(!empty($_get))
|
86 |
+
$get = $_get;
|
87 |
+
}
|
88 |
+
return apply_filters('ws_plugin__s2member_sc_get_file', isset($get) ? $get : NULL, get_defined_vars());
|
89 |
+
}
|
90 |
|
91 |
+
/**
|
92 |
+
* Handles the Shortcode for: `[s2Stream /]`.
|
93 |
+
*
|
94 |
+
* @package s2Member\s2File
|
95 |
+
* @since 130119
|
96 |
+
*
|
97 |
+
* @attaches-to ``add_shortcode('s2Stream');``
|
98 |
+
*
|
99 |
+
* @param array $attr An array of Attributes.
|
100 |
+
* @param string $content Content inside the Shortcode.
|
101 |
+
* @param string $shortcode The actual Shortcode name itself.
|
102 |
+
*
|
103 |
+
* @return string HTML markup that produces an audio/video stream for a specific player.
|
104 |
+
*/
|
105 |
+
public static function sc_get_stream($attr = array(), $content = '', $shortcode = '')
|
106 |
+
{
|
107 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
108 |
+
do_action('ws_plugin__s2member_before_sc_get_stream', get_defined_vars());
|
109 |
+
unset($__refs, $__v); // Housekeeping.
|
110 |
|
111 |
+
$attr = c_ws_plugin__s2member_utils_strings::trim_qts_deep((array)$attr);
|
|
|
|
|
|
|
|
|
112 |
|
113 |
+
$attr = shortcode_atts(array('download' => '', 'file_download' => '', 'download_key' => '',
|
114 |
+
'stream' => 'yes', 'inline' => 'yes', 'storage' => '',
|
115 |
+
'remote' => '', 'ssl' => '', 'rewrite' => 'yes', 'rewrite_base' => '',
|
116 |
+
'skip_confirmation' => '', 'url_to_storage_source' => 'yes',
|
117 |
+
'count_against_user' => 'yes', 'check_user' => 'yes',
|
118 |
|
119 |
+
// Configuration
|
120 |
+
'player' => 'jwplayer-v6-rtmp', 'player_id' => 's2-stream-'.md5(uniqid('', TRUE)),
|
121 |
+
'player_path' => '/jwplayer/jwplayer.js', 'player_key' => '', 'player_title' => '',
|
122 |
+
'player_image' => '', 'player_mediaid' => '', 'player_description' => '', 'player_captions' => '',
|
123 |
+
'player_resolutions' => '', // A comma-delimited list of resolution options.
|
124 |
|
125 |
+
// Layout
|
126 |
+
'player_controls' => 'yes', 'player_skin' => '', 'player_stretching' => 'uniform',
|
127 |
+
'player_width' => '480', 'player_height' => '270', 'player_aspectratio' => '',
|
128 |
|
129 |
+
// Playback
|
130 |
+
'player_autostart' => 'no', 'player_fallback' => 'yes', 'player_mute' => 'no',
|
131 |
+
'player_primary' => (($attr['player'] === 'jw-player-v6') ? 'html5' : 'flash'),
|
132 |
+
'player_repeat' => 'no', 'player_startparam' => '',
|
133 |
|
134 |
+
// Advanced Option Blocks
|
135 |
+
'player_option_blocks' => ''), $attr);
|
136 |
+
|
137 |
+
$attr['download'] = (!empty($attr['file_download'])) ? $attr['file_download'] : $attr['download'];
|
138 |
+
|
139 |
+
foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v;
|
140 |
+
do_action('ws_plugin__s2member_before_sc_get_stream_after_shortcode_atts', get_defined_vars());
|
141 |
+
unset($__refs, $__v); // Housekeeping.
|
142 |
+
|
143 |
+
foreach($attr as $key => $value) // Now we need to go through and a `file_` prefix to certain Attribute keys, for compatibility.
|
144 |
+
if(strlen($value) && in_array($key, array('download', 'download_key', 'stream', 'inline', 'storage', 'remote', 'ssl', 'rewrite', 'rewrite_base')))
|
145 |
+
$config['file_'.$key] = $value; // Set prefixed config parameter here so we can pass properly in ``$config`` array.
|
146 |
+
else if(strlen($value) && !in_array($key, array('file_download', 'player')) && strpos($key, 'player_') !== 0)
|
147 |
+
$config[$key] = $value;
|
148 |
+
|
149 |
+
unset($key, $value); // Ditch these now. We don't want these bleeding into Hooks/Filters anyway.
|
150 |
+
|
151 |
+
if(!empty($config) && isset($config['file_download'])) // Looking for a File Download URL?
|
152 |
+
{
|
153 |
+
if($attr['player_resolutions'] && c_ws_plugin__s2member_utils_conds::pro_is_installed() /* Pro serves SMIL files. */)
|
154 |
+
{
|
155 |
+
$file_download_extension = strtolower(ltrim((string)strrchr(basename($config['file_download']), '.'), '.'));
|
156 |
+
$file_download_resolution_wo_extension = substr($config['file_download'], 0, -(strlen($file_download_extension) + 1) /* For the dot. */);
|
157 |
+
$file_download_wo_resolution_extension = preg_replace('/\-r[0-9]+([^.]*)$/i', '', $file_download_resolution_wo_extension); // e.g. `r720p-HD` is removed here.
|
158 |
+
|
159 |
+
$file_download_resolutions = array(); // Initialize the array of resolutions.
|
160 |
+
foreach(preg_split('/[,;\s]+/', $attr['player_resolutions'], NULL, PREG_SPLIT_NO_EMPTY) as $_player_resolution)
|
161 |
+
{
|
162 |
+
$_player_resolution = ltrim($_player_resolution, 'Rr'); // Remove R|r prefix.
|
163 |
+
$file_download_resolutions[$_player_resolution] = $file_download_wo_resolution_extension.'-r'.$_player_resolution.'.'.$file_download_extension;
|
164 |
+
}
|
165 |
+
unset($_player_resolution); // Housekeeping.
|
166 |
+
|
167 |
+
$file_download_urls = array(); // Initialize array of all file download urls.
|
168 |
+
foreach($file_download_resolutions as $_player_resolution => $_file_download_resolution) // NOTE: these ARE in a specific order.
|
169 |
+
{
|
170 |
+
$_file_download_config = array_merge($config, array('file_download' => $_file_download_resolution));
|
171 |
+
|
172 |
+
if($file_download_urls) // If this is a ANOTHER resolution, don't count it against the user.
|
173 |
+
$_file_download_config = array_merge($_file_download_config, array('check_user' => FALSE, 'count_against_user' => FALSE));
|
174 |
+
|
175 |
+
if(!($file_download_urls[str_replace(array('_', '-'), ' ', $_player_resolution)] = c_ws_plugin__s2member_files::create_file_download_url($_file_download_config, TRUE)))
|
176 |
+
return apply_filters('ws_plugin__s2member_sc_get_stream', NULL, get_defined_vars()); // Failure.
|
177 |
}
|
178 |
+
unset($_player_resolution, $_file_download_resolution, $_file_download_config); // Housekeeping.
|
179 |
+
}
|
180 |
+
else $file_download_urls = array(c_ws_plugin__s2member_files::create_file_download_url($config, TRUE)); // Default behavior.
|
181 |
+
|
182 |
+
if($file_download_urls && $attr['player'] && is_file($template = dirname(dirname(__FILE__)).'/templates/players/'.$attr['player'].'.php') && $attr['player_id'] && $attr['player_path'])
|
183 |
+
{
|
184 |
+
$template = (is_file(TEMPLATEPATH.'/'.basename($template))) ? TEMPLATEPATH.'/'.basename($template) : $template;
|
185 |
+
$template = (is_file(get_stylesheet_directory().'/'.basename($template))) ? get_stylesheet_directory().'/'.basename($template) : $template;
|
186 |
+
$template = (is_file(WP_CONTENT_DIR.'/'.basename($template))) ? WP_CONTENT_DIR.'/'.basename($template) : $template;
|
187 |
+
|
188 |
+
if(strpos($attr['player'], 'jwplayer-v6') === 0) // JW Player is currently the only supported player.
|
|
|
|
|
|
|
189 |
{
|
190 |
+
$player = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($template)));
|
191 |
+
|
192 |
+
$_first_file_download_url = array(); // Holds the first one.
|
193 |
+
$_last_file_download_url = array(); // Holds the last one.
|
194 |
+
$_uses_rtmp_streamers = FALSE; // Streamers use RTMP?
|
195 |
+
|
196 |
+
$_total_player_sources = count($file_download_urls); // Total sources.
|
197 |
+
$_player_sources_counter = 1; // Player sources counter; needed by the loop below.
|
198 |
|
199 |
+
$player_resolution_aspect_ratio_w = 16; // Default aspect ratio width.
|
200 |
+
$player_resolution_aspect_ratio_h = 9; // Default aspect ratio in height.
|
201 |
+
if($attr['player_aspectratio'] && preg_match('/^[0-9]+\:[0-9]+$/', $attr['player_aspectratio']))
|
202 |
+
list($player_resolution_aspect_ratio_w, $player_resolution_aspect_ratio_h) = explode(':', $attr['player_aspectratio']);
|
203 |
+
$player_resolution_aspect_ratio_w = (integer)$player_resolution_aspect_ratio_w; // Force integer value.
|
204 |
+
$player_resolution_aspect_ratio_h = (integer)$player_resolution_aspect_ratio_h; // Force integer value.
|
205 |
|
206 |
+
// See: <http://wsharks.com/1yzjAl6> and <http://wsharks.com/1yzkhea> regarging the SMIL bitrate hints given here.
|
207 |
+
$player_resolution_bitrates = array(2160 => '35000000', 1440 => '10000000', 1080 => '8000000', 720 => '5000000', 640 => '2500001', 480 => '2500000', 360 => '1000000', 320 => '999999', 240 => '500000', 180 => '300000');
|
208 |
+
$player_resolution_bitrates = apply_filters('ws_plugin__s2member_sc_get_stream_resolution_bitrates', $player_resolution_bitrates, get_defined_vars());
|
209 |
|
210 |
+
$player_resolution_sources_smil_file_id = md5(serialize($attr).$_SERVER['REMOTE_ADDR']); // Initialize SMIL ID.
|
211 |
+
$player_resolution_sources_smil_file_url = home_url('/s2member-rsf-file.smil?s2member_rsf_file='.urlencode($player_resolution_sources_smil_file_id).'&s2member_rsf_file_ip='.urlencode($_SERVER['REMOTE_ADDR']));
|
212 |
+
$player_resolution_sources_smil_file_url = c_ws_plugin__s2member_utils_urls::add_s2member_sig($player_resolution_sources_smil_file_url);
|
213 |
+
$player_resolution_sources_smil_file_contents = ''; // Initialize player sources SMIL file contents.
|
214 |
+
$player_sources = ''; // Initialize player sources; empty string.
|
215 |
|
216 |
+
foreach($file_download_urls as $_file_download_url_label => $_file_download_url)
|
217 |
+
{
|
218 |
+
$_is_first_file_download_url = $_player_sources_counter <= 1;
|
219 |
+
$_is_last_file_download_url = $_player_sources_counter >= $_total_player_sources;
|
|
|
220 |
|
221 |
+
if($_is_first_file_download_url) // We base this conditional on the first streamer.
|
222 |
+
$_uses_rtmp_streamers = stripos($_file_download_url['streamer'], 'rtmp') === 0;
|
223 |
|
224 |
+
switch($attr['player'])// See: <http://wsharks.com/1Bd6tKy>
|
225 |
{
|
226 |
+
case 'jwplayer-v6': // Default w/ a direct URL (very simple).
|
227 |
+
|
228 |
+
$player_sources .= ',{'; // Open this source; JSON object properties.
|
229 |
+
$player_sources .= "'file': '".c_ws_plugin__s2member_utils_strings::esc_js_sq($_file_download_url['url'])."'";
|
230 |
+
if(is_string($_file_download_url_label)) $player_sources .= ",'label': '".c_ws_plugin__s2member_utils_strings::esc_js_sq($_file_download_url_label)."'";
|
231 |
+
if($_is_first_file_download_url) $player_sources .= ",'default': 'true'";
|
232 |
+
$player_sources .= '}'; // Close this source.
|
233 |
+
|
234 |
+
break; // Break switch loop.
|
235 |
+
|
236 |
+
case 'jwplayer-v6-rtmp': // RTMP w/ downloadable fallback (mobile compatibility).
|
237 |
+
case 'jwplayer-v6-rtmp-only': // RTMP streaming only (flash player only).
|
238 |
|
239 |
+
if($attr['player_resolutions'] && $_total_player_sources > 1 && $_uses_rtmp_streamers)
|
240 |
+
{
|
241 |
+
if($_is_first_file_download_url) // The first source is the SMIL file.
|
242 |
+
{
|
243 |
+
$player_sources .= ',{'; // Open this source; JSON object properties.
|
244 |
+
$player_sources .= "'file': '".c_ws_plugin__s2member_utils_strings::esc_js_sq($player_resolution_sources_smil_file_url)."'";
|
245 |
+
if($_is_first_file_download_url) $player_sources .= ",'default': 'true'";
|
246 |
+
$player_sources .= '}'; // Close this source.
|
247 |
+
}
|
248 |
+
$_file_download_url['smil']['height'] = (integer)$_file_download_url_label; // e.g. `720p-HD` becomes `720`.
|
249 |
+
if(!$_file_download_url['smil']['height']) $_file_download_url['smil']['height'] = 720; // Use a default height if invalid.
|
250 |
+
$_file_download_url['smil']['width'] = ceil(($_file_download_url['smil']['height'] / $player_resolution_aspect_ratio_h) * $player_resolution_aspect_ratio_w);
|
251 |
+
|
252 |
+
$_file_download_url['smil']['system-bitrate'] = '1'; // Default value.
|
253 |
+
if(!empty($player_resolution_bitrates[$_file_download_url['smil']['height']]))
|
254 |
+
$_file_download_url['smil']['system-bitrate'] = $player_resolution_bitrates[$_file_download_url['smil']['height']];
|
255 |
+
|
256 |
+
$player_resolution_sources_smil_file_contents .= '<video src="'.esc_attr($_file_download_url['file']).'"'.
|
257 |
+
' width="'.esc_attr($_file_download_url['smil']['width']).'"'.
|
258 |
+
' height="'.esc_attr($_file_download_url['smil']['height']).'"'.
|
259 |
+
' system-bitrate="'.esc_attr($_file_download_url['smil']['system-bitrate']).'" />';
|
260 |
+
}
|
261 |
+
else // Build them inline; i.e. don't create a SMIL file in this case; not necessary.
|
262 |
+
{
|
263 |
+
$player_sources .= ',{'; // Open this source; JSON object properties.
|
264 |
+
$player_sources .= "'file': '".c_ws_plugin__s2member_utils_strings::esc_js_sq($_file_download_url['streamer'].'/'.$_file_download_url['prefix'].$_file_download_url['file'])."'";
|
265 |
+
if(is_string($_file_download_url_label)) $player_sources .= ",'label': '".c_ws_plugin__s2member_utils_strings::esc_js_sq($_file_download_url_label)."'";
|
266 |
+
if($_is_first_file_download_url) $player_sources .= ",'default': 'true'";
|
267 |
+
$player_sources .= '}'; // Close this source.
|
268 |
+
}
|
269 |
+
if($_is_last_file_download_url && $attr['player'] === 'jwplayer-v6-rtmp') // Provide a fallback also.
|
270 |
{
|
271 |
+
$player_sources .= ',{'; // Open this source; JSON object properties.
|
272 |
+
$player_sources .= "'file': '".c_ws_plugin__s2member_utils_strings::esc_js_sq($_file_download_url['url'])."'";
|
273 |
+
$player_sources .= '}'; // Close this source.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
}
|
275 |
+
break; // Break switch loop.
|
276 |
}
|
277 |
+
if($_is_first_file_download_url) // Record first one; also run back compat. replacements.
|
278 |
+
{
|
279 |
+
$_first_file_download_url = $_file_download_url; // Record for use later.
|
280 |
+
$player = preg_replace('/%%streamer%%/', $_file_download_url['streamer'], $player);
|
281 |
+
$player = preg_replace('/%%prefix%%/', $_file_download_url['prefix'], $player);
|
282 |
+
$player = preg_replace('/%%file%%/', $_file_download_url['file'], $player);
|
283 |
+
$player = preg_replace('/%%url%%/', $_file_download_url['url'], $player);
|
284 |
+
}
|
285 |
+
if($_is_last_file_download_url) // Record last one; which could be the same as the first one.
|
286 |
+
{
|
287 |
+
$_last_file_download_url = $_file_download_url; // Record for use later.
|
288 |
+
}
|
289 |
+
$_player_sources_counter++; // Increment the counter.
|
290 |
+
}
|
291 |
+
$player_sources = '['.trim($player_sources, ',').']'; // Build array.
|
292 |
+
|
293 |
+
if($player_resolution_sources_smil_file_contents && $_first_file_download_url) // Build SMIL file.
|
294 |
+
{
|
295 |
+
$player_resolution_sources_smil_file_contents = '<smil>'. // See: <http://wsharks.com/1ruqGVu>
|
296 |
+
' <head><meta base="'.esc_attr($_first_file_download_url['streamer']).'" /></head>'.
|
297 |
+
' <body><switch>'.$player_resolution_sources_smil_file_contents.'</switch></body>'.
|
298 |
+
'</smil>';
|
299 |
+
set_transient('s2m_rsf_'.$player_resolution_sources_smil_file_id, $player_resolution_sources_smil_file_contents, 86400);
|
300 |
+
}
|
301 |
+
unset($_first_file_download_url, $_last_file_download_url, $_uses_rtmp_streamers, // Housekeeping.
|
302 |
+
$_total_player_sources, $_player_sources_counter, $_is_first_file_download_url, $_is_last_file_download_url,
|
303 |
+
$_file_download_url_label, $_file_download_url);
|
304 |
+
|
305 |
+
$player = preg_replace('/%%player_id%%/', $attr['player_id'], $player);
|
306 |
+
$player = preg_replace('/%%player_path%%/', $attr['player_path'], $player);
|
307 |
+
$player = preg_replace('/%%player_key%%/', $attr['player_key'], $player);
|
308 |
+
|
309 |
+
$player = preg_replace('/%%player_title%%/', $attr['player_title'], $player);
|
310 |
+
$player = preg_replace('/%%player_image%%/', $attr['player_image'], $player);
|
311 |
+
|
312 |
+
$player = preg_replace('/%%player_mediaid%%/', $attr['player_mediaid'], $player);
|
313 |
+
$player = preg_replace('/%%player_description%%/', $attr['player_description'], $player);
|
314 |
+
|
315 |
+
if(($attr['player_captions'] = c_ws_plugin__s2member_utils_strings::trim($attr['player_captions'], NULL, '[]')))
|
316 |
+
$player = preg_replace('/%%player_captions%%/', '['.((strpos($attr['player_captions'], ':') !== FALSE) ? $attr['player_captions'] : base64_decode($attr['player_captions'])).']', $player);
|
317 |
+
else $player = preg_replace('/%%player_captions%%/', '[]', $player);
|
318 |
+
|
319 |
+
$player = preg_replace('/%%player_sources%%/', $player_sources, $player); // Sources are constructed dynamically.
|
320 |
+
|
321 |
+
$player = preg_replace('/%%player_controls%%/', ((filter_var($attr['player_controls'], FILTER_VALIDATE_BOOLEAN)) ? 'true' : 'false'), $player);
|
322 |
+
$player = preg_replace('/%%player_width%%/', ((strpos($attr['player_width'], '%') !== FALSE) ? "'".$attr['player_width']."'" : (integer)$attr['player_width']), $player);
|
323 |
+
$player = preg_replace('/%%player_height%%/', (($attr['player_aspectratio']) ? "''" : ((strpos($attr['player_height'], '%') !== FALSE) ? "'".$attr['player_height']."'" : (integer)$attr['player_height'])), $player);
|
324 |
+
$player = preg_replace('/%%player_aspectratio%%/', $attr['player_aspectratio'], $player);
|
325 |
+
$player = preg_replace('/%%player_stretching%%/', $attr['player_stretching'], $player);
|
326 |
+
$player = preg_replace('/%%player_skin%%/', $attr['player_skin'], $player);
|
327 |
+
|
328 |
+
$player = preg_replace('/%%player_autostart%%/', ((filter_var($attr['player_autostart'], FILTER_VALIDATE_BOOLEAN)) ? 'true' : 'false'), $player);
|
329 |
+
$player = preg_replace('/%%player_fallback%%/', ((filter_var($attr['player_fallback'], FILTER_VALIDATE_BOOLEAN)) ? 'true' : 'false'), $player);
|
330 |
+
$player = preg_replace('/%%player_mute%%/', ((filter_var($attr['player_mute'], FILTER_VALIDATE_BOOLEAN)) ? 'true' : 'false'), $player);
|
331 |
+
$player = preg_replace('/%%player_repeat%%/', ((filter_var($attr['player_repeat'], FILTER_VALIDATE_BOOLEAN)) ? 'true' : 'false'), $player);
|
332 |
+
$player = preg_replace('/%%player_startparam%%/', $attr['player_startparam'], $player);
|
333 |
+
$player = preg_replace('/%%player_primary%%/', $attr['player_primary'], $player);
|
334 |
+
|
335 |
+
$player = preg_replace('/%%player_option_blocks%%/', ((strpos($attr['player_option_blocks'], ':') !== FALSE) ? $attr['player_option_blocks'] : base64_decode($attr['player_option_blocks'])), $player);
|
336 |
}
|
337 |
+
}
|
338 |
}
|
339 |
+
return apply_filters('ws_plugin__s2member_sc_get_stream', isset($player) ? $player : NULL, get_defined_vars());
|
340 |
+
}
|
341 |
}
|
342 |
+
}
|
includes/classes/utils-arrays.inc.php
CHANGED
@@ -191,7 +191,7 @@ if (!class_exists ("c_ws_plugin__s2member_utils_arrays"))
|
|
191 |
* @param array $array An input array.
|
192 |
* @return array Returns the ``$array`` after having forced it to set of integer values.
|
193 |
*/
|
194 |
-
public static function force_integers ($array =
|
195 |
{
|
196 |
$array = (array)$array;
|
197 |
|
191 |
* @param array $array An input array.
|
192 |
* @return array Returns the ``$array`` after having forced it to set of integer values.
|
193 |
*/
|
194 |
+
public static function force_integers ($array = array())
|
195 |
{
|
196 |
$array = (array)$array;
|
197 |
|
includes/classes/utils-conds.inc.php
CHANGED
@@ -40,6 +40,35 @@ if(!class_exists("c_ws_plugin__s2member_utils_conds"))
|
|
40 |
return (defined("WS_PLUGIN__S2MEMBER_PRO_VERSION") && did_action("ws_plugin__s2member_pro_loaded"));
|
41 |
}
|
42 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
* Determines whether or not BuddyPress is installed.
|
44 |
*
|
45 |
* @package s2Member\Utilities
|
40 |
return (defined("WS_PLUGIN__S2MEMBER_PRO_VERSION") && did_action("ws_plugin__s2member_pro_loaded"));
|
41 |
}
|
42 |
/**
|
43 |
+
* Determines whether or not bbPress is installed.
|
44 |
+
*
|
45 |
+
* @package s2Member\Utilities
|
46 |
+
* @since 140807
|
47 |
+
*
|
48 |
+
* @param bool $query_active_plugins Optional. If true, this conditional will query active plugins too. Defaults to true if {@link s2Member\WS_PLUGIN__S2MEMBER_ONLY} is true, else false.
|
49 |
+
* @return bool True if bbPress is installed, else false.
|
50 |
+
*/
|
51 |
+
public static function bbp_is_installed($query_active_plugins = NULL)
|
52 |
+
{
|
53 |
+
if(function_exists('bbpress'))
|
54 |
+
return true; // Quickest/easiest way to determine.
|
55 |
+
|
56 |
+
$s2o = (defined("WS_PLUGIN__S2MEMBER_ONLY") && WS_PLUGIN__S2MEMBER_ONLY) ? true : false;
|
57 |
+
|
58 |
+
if(($query_active_plugins = (!isset($query_active_plugins) && $s2o) ? true : $query_active_plugins))
|
59 |
+
{
|
60 |
+
$bbpress = "bbpress/bbpress.php"; // bbPress.
|
61 |
+
|
62 |
+
$active_plugins = (is_multisite()) ? wp_get_active_network_plugins() : array();
|
63 |
+
$active_plugins = array_unique(array_merge($active_plugins, wp_get_active_and_valid_plugins()));
|
64 |
+
|
65 |
+
foreach($active_plugins as $active_plugin) // Search.
|
66 |
+
if(plugin_basename($active_plugin) === $bbpress)
|
67 |
+
return true; // bbPress active.
|
68 |
+
}
|
69 |
+
return false; // Default return false.
|
70 |
+
}
|
71 |
+
/**
|
72 |
* Determines whether or not BuddyPress is installed.
|
73 |
*
|
74 |
* @package s2Member\Utilities
|
includes/classes/utils-gets.inc.php
CHANGED
@@ -1,362 +1,420 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* Get utilities.
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Utilities
|
15 |
-
* @since 3.5
|
16 |
-
*/
|
17 |
-
if
|
18 |
-
exit (
|
19 |
-
|
20 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
/**
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
*
|
33 |
-
* @package s2Member\Utilities
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @uses {@link http://codex.wordpress.org/Function_Reference/get_all_category_ids get_all_category_ids()}
|
37 |
-
*
|
38 |
-
* @return array Unique array of all Category IDs *(as integers)*.
|
39 |
-
*/
|
40 |
-
public static function get_all_category_ids ()
|
41 |
-
{
|
42 |
-
if (is_array($category_ids = /* Uses the WordPress function for this. */ get_all_category_ids ()))
|
43 |
-
$category_ids = c_ws_plugin__s2member_utils_arrays::force_integers ($category_ids);
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
*
|
50 |
-
* @package s2Member\Utilities
|
51 |
-
* @since 3.5
|
52 |
-
*
|
53 |
-
* @param int|string $parent_category A numeric Category ID.
|
54 |
-
* @return array Unique array of all Category IDs *(as integers)* in ``$parent_category``.
|
55 |
-
*/
|
56 |
-
public static function get_all_child_category_ids ($parent_category = FALSE)
|
57 |
-
{
|
58 |
-
if (is_numeric ($parent_category) && is_array($child_categories = get_categories ("child_of=" . $parent_category . "&hide_empty=0")))
|
59 |
-
foreach ($child_categories as /* Go through child Categories. */ $child_category)
|
60 |
-
$child_category_ids[] = (int)$child_category->term_id;
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
* @since 3.5
|
69 |
-
*
|
70 |
-
* @return array Unique array of all Tag IDs *(as integers)*.
|
71 |
-
*/
|
72 |
-
public static function get_all_tag_ids ()
|
73 |
-
{
|
74 |
-
foreach ((array)get_tags ("hide_empty=0") as $tag)
|
75 |
-
$tag_ids[] = (int)$tag->term_id; // Collect Tag's ID.
|
76 |
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
|
|
|
|
|
|
|
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
global $wpdb; // Need this global DB object reference here.
|
119 |
|
120 |
-
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
-
|
138 |
-
|
|
|
|
|
139 |
|
140 |
-
|
141 |
-
}
|
142 |
-
/**
|
143 |
-
* Retrieves a unique array of all Singular IDs in the database that require Custom Capabilities.
|
144 |
-
*
|
145 |
-
* @package s2Member\Utilities
|
146 |
-
* @since 111101
|
147 |
-
*
|
148 |
-
* @return array Unique array of all Singular IDs *(as integers)* that require Custom Capabilities.
|
149 |
-
*/
|
150 |
-
public static function get_all_singular_ids_with_ccaps ()
|
151 |
{
|
152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
|
154 |
-
|
155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
* Only returns Singular IDs that require Custom Capabilities;
|
163 |
-
* and ONLY those which are NOT satisfied by ``$user``.
|
164 |
-
*
|
165 |
-
* @package s2Member\Utilities
|
166 |
-
* @since 111101
|
167 |
-
*
|
168 |
-
* @param object $user Optional. A `WP_User` object. If this is a valid `WP_User` object, test against this ``$user``, else all are unavailable.
|
169 |
-
* @return array Unique array of all Singular IDs *(as integers)* NOT available to ``$user``, due to Custom Capability Restrictions.
|
170 |
-
*/
|
171 |
-
public static function get_unavailable_singular_ids_with_ccaps ($user = FALSE)
|
172 |
{
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
foreach ($results as $r) // Now we need to check Custom Capabilities against ``$user``. If ``$user`` is a valid `WP_User` object, else all are unavailable.
|
177 |
-
{
|
178 |
-
if (!is_object ($user) || empty($user->ID)) // No ``$user`` object? Maybe not logged-in?.
|
179 |
-
$singular_ids[] = (int)$r->post_id; // It's NOT available. There is no ``$user``.
|
180 |
-
|
181 |
-
else if (is_array($ccaps = /* Make sure we unserialize. */ @unserialize ($r->meta_value)))
|
182 |
-
{
|
183 |
-
foreach ($ccaps as $ccap) // Test for Custom Capability Restrictions now.
|
184 |
-
if (strlen ($ccap) && !$user->has_cap ("access_s2member_ccap_" . $ccap))
|
185 |
-
{
|
186 |
-
$singular_ids[] = (int)$r->post_id; // It's NOT available.
|
187 |
-
break; // Break now, no need to continue in this loop.
|
188 |
-
}
|
189 |
-
}
|
190 |
-
}
|
191 |
-
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique ($singular_ids) : array();
|
192 |
}
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
* @return array Unique array of all Singular IDs *(as integers)* that require Specific Post/Page Access.
|
203 |
-
*/
|
204 |
-
public static function get_all_singular_ids_with_sp ($exclude_conflicts = FALSE)
|
205 |
{
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
if (!empty($singular_ids) && is_array($singular_ids) && $exclude_conflicts /* Return ONLY those which are NOT in conflict with other Restrictions? */)
|
210 |
-
{
|
211 |
-
$x_ids = array($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_welcome_page"], $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"], $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"]);
|
212 |
-
|
213 |
-
$x_ids = array_merge ($x_ids, c_ws_plugin__s2member_utils_gets::get_all_singular_ids_with_ccaps ());
|
214 |
-
|
215 |
-
for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
216 |
-
{
|
217 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_catgs"] === "all")
|
218 |
-
{
|
219 |
-
$catgs = c_ws_plugin__s2member_utils_gets::get_all_category_ids ();
|
220 |
-
$x_ids = array_merge ($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms ($catgs));
|
221 |
-
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
222 |
-
}
|
223 |
-
|
224 |
-
foreach (($catgs = preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_catgs"])) as $catg)
|
225 |
-
$catgs = array_merge ($catgs, c_ws_plugin__s2member_utils_gets::get_all_child_category_ids ($catg));
|
226 |
-
|
227 |
-
$x_ids = /* Exclude the full list. */ array_merge ($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms ($catgs));
|
228 |
-
unset /* Just a little housekeeping here. */ ($catgs, $catg);
|
229 |
-
}
|
230 |
-
|
231 |
-
for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
232 |
-
{
|
233 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ptags"] === "all")
|
234 |
-
{
|
235 |
-
$tags = c_ws_plugin__s2member_utils_gets::get_all_tag_ids ();
|
236 |
-
$x_ids = array_merge ($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms ($tags));
|
237 |
-
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
238 |
-
}
|
239 |
-
|
240 |
-
$tags = c_ws_plugin__s2member_utils_gets::get_tags_converted_to_ids ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_ptags"]);
|
241 |
-
|
242 |
-
$x_ids = /* Exclude the full list. */ array_merge ($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms ($tags));
|
243 |
-
unset /* Just a little housekeeping here. */ ($tags);
|
244 |
-
}
|
245 |
-
|
246 |
-
for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
247 |
-
{
|
248 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"] === "all")
|
249 |
-
{
|
250 |
-
$x_ids = array_merge ($x_ids, c_ws_plugin__s2member_utils_gets::get_all_post_ids ());
|
251 |
-
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
252 |
-
}
|
253 |
-
|
254 |
-
foreach (($posts = preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_posts"])) as $p)
|
255 |
-
if (strpos ($p, "all-") === 0 && preg_match ("/^all-(.+)$/", $p, $m) /* Protecting `all-` of a specific Post Type? */)
|
256 |
-
if ((is_array($p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids ($m[1])) || (substr($m[1], -1) === "s"
|
257 |
-
&& is_array($_p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids(substr($m[1], 0, -1)))))
|
258 |
-
&& !empty($p_of_type)) $x_ids = array_merge /* Merge all Posts of this Post Type. */ ($x_ids, $p_of_type);
|
259 |
-
|
260 |
-
$x_ids = /* Exclude the full list too. */ array_merge ($x_ids, $posts);
|
261 |
-
unset /* Just a little housekeeping here. */ ($posts, $p, $m, $p_of_type);
|
262 |
-
}
|
263 |
-
|
264 |
-
for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
265 |
-
{
|
266 |
-
if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_pages"] === "all")
|
267 |
-
{
|
268 |
-
$x_ids = array_merge ($x_ids, c_ws_plugin__s2member_utils_gets::get_all_page_ids ());
|
269 |
-
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
270 |
-
}
|
271 |
-
|
272 |
-
$pages = preg_split ("/[\r\n\t\s;,]+/", $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $n . "_pages"]);
|
273 |
-
|
274 |
-
$x_ids = /* Exclude the full list. */ array_merge ($x_ids, $pages);
|
275 |
-
unset /* Just a little housekeeping here. */ ($pages);
|
276 |
-
}
|
277 |
-
|
278 |
-
$x_ids = array_unique (c_ws_plugin__s2member_utils_arrays::force_integers ($x_ids));
|
279 |
-
$singular_ids = /* Exclude all of the ``$x_ids`` now. */ array_diff ($singular_ids, $x_ids);
|
280 |
-
}
|
281 |
-
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique ($singular_ids) : array();
|
282 |
}
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
*
|
292 |
-
* @param bool $exclude_conflicts Optional. Defaults to false. If true, return ONLY those which are NOT in conflict with any other Restriction Types.
|
293 |
-
* The ``$exclude_conflicts`` argument should be used whenever we introduce a list of option values to a site owner. Helping them avoid mishaps.
|
294 |
-
* Please note, the ``$exclude_conflicts`` argument implements a resource-intensive processing routine.
|
295 |
-
* @return array Unique array of all Singular IDs *(as integers)* NOT available to current Visitor, due to Specific Post/Page Restrictions.
|
296 |
-
*/
|
297 |
-
public static function get_unavailable_singular_ids_with_sp ($exclude_conflicts = FALSE)
|
298 |
{
|
299 |
-
|
300 |
-
|
301 |
-
if (is_numeric ($_singular_id) && !c_ws_plugin__s2member_sp_access::sp_access ($_singular_id, "read-only"))
|
302 |
-
$singular_ids[] = (int)$_singular_id;
|
303 |
-
|
304 |
-
if (!empty($singular_ids) && is_array($singular_ids) /* And, are we excluding conflicts in this instance? */ && $exclude_conflicts)
|
305 |
-
{
|
306 |
-
$all_singular_ids_not_conflicting = c_ws_plugin__s2member_utils_gets::get_all_singular_ids_with_sp ("exclude-conflicts");
|
307 |
-
foreach /* Weed out anything that's in conflict here. */ ($singular_ids as $s => $singular_id)
|
308 |
-
if (!in_array($singular_id, $all_singular_ids_not_conflicting))
|
309 |
-
unset($singular_ids[$s]);
|
310 |
-
}
|
311 |
-
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique ($singular_ids) : array();
|
312 |
}
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
* @return array Unique array of all Singulars *(i.e. Posts/Pages )* protected with Specific Post/Page Access.
|
325 |
-
* Includes Custom Post Types also, as specified by site owner's Specific Post/Page Restrictions.
|
326 |
-
*/
|
327 |
-
public static function get_all_singulars_with_sp ($exclude_conflicts = FALSE)
|
328 |
{
|
329 |
-
$
|
330 |
-
|
331 |
-
if (!empty($singulars) && is_array($singulars) /* And, are we excluding conflicts in this instance? */ && $exclude_conflicts)
|
332 |
-
{
|
333 |
-
$all_singular_ids_not_conflicting = c_ws_plugin__s2member_utils_gets::get_all_singular_ids_with_sp ("exclude-conflicts");
|
334 |
-
foreach /* Weed out anything that's in conflict here. */ ($singulars as $s => $singular)
|
335 |
-
if (!in_array($singular->ID, $all_singular_ids_not_conflicting))
|
336 |
-
unset($singulars[$s]);
|
337 |
-
}
|
338 |
-
return (!empty($singulars) && is_array($singulars)) ? c_ws_plugin__s2member_utils_arrays::array_unique ($singulars) : array();
|
339 |
}
|
340 |
-
|
341 |
-
* Retrieves a unique array of Singular IDs in the database, within specific term IDs.
|
342 |
-
*
|
343 |
-
* Only returns Singular IDs that are within the ``$terms`` passed through this function.
|
344 |
-
*
|
345 |
-
* @package s2Member\Utilities
|
346 |
-
* @since 110912
|
347 |
-
*
|
348 |
-
* @param array $terms Required. An array of term IDs.
|
349 |
-
* @return array Unique array of all Singular IDs *(as integers)* within the ``$terms`` passed through this function.
|
350 |
-
*/
|
351 |
-
public static function get_singular_ids_in_terms ($terms = FALSE)
|
352 |
-
{
|
353 |
-
global $wpdb; // Need this global DB object reference here.
|
354 |
|
355 |
-
|
356 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
|
358 |
-
|
359 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
}
|
362 |
-
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Get utilities.
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Utilities
|
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_gets'))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* Get utilities.
|
24 |
+
*
|
25 |
+
* @package s2Member\Utilities
|
26 |
+
* @since 3.5
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_utils_gets
|
29 |
{
|
30 |
/**
|
31 |
+
* Retrieves a unique array of all Category IDs in the database.
|
32 |
+
*
|
33 |
+
* @package s2Member\Utilities
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @uses {@link http://codex.wordpress.org/Function_Reference/get_all_category_ids get_all_category_ids()}
|
37 |
+
*
|
38 |
+
* @return array Unique array of all Category IDs *(as integers)*.
|
39 |
+
*/
|
40 |
+
public static function get_all_category_ids()
|
41 |
+
{
|
42 |
+
if(is_array($category_ids = get_all_category_ids())) // Use a WP function for this.
|
43 |
+
$category_ids = c_ws_plugin__s2member_utils_arrays::force_integers((array)$category_ids);
|
44 |
+
|
45 |
+
return (!empty($category_ids) && is_array($category_ids)) ? array_unique($category_ids) : array();
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Retrieves a unique array of all child Category IDs, within a specific parent Category.
|
50 |
+
*
|
51 |
+
* @package s2Member\Utilities
|
52 |
+
* @since 3.5
|
53 |
+
*
|
54 |
+
* @param int|string $parent_category A numeric Category ID.
|
55 |
+
*
|
56 |
+
* @return array Unique array of all Category IDs *(as integers)* in ``$parent_category``.
|
57 |
+
*/
|
58 |
+
public static function get_all_child_category_ids($parent_category = 0)
|
59 |
+
{
|
60 |
+
if(is_numeric($parent_category) && $parent_category && is_array($child_categories = get_categories('child_of='.$parent_category.'&hide_empty=0')))
|
61 |
+
foreach($child_categories as $child_category) // Go through child Categories.
|
62 |
+
$child_category_ids[] = (int)$child_category->term_id;
|
63 |
+
|
64 |
+
return (!empty($child_category_ids) && is_array($child_category_ids)) ? array_unique($child_category_ids) : array();
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Retrieves a unique array of all Tag IDs in the database.
|
69 |
+
*
|
70 |
+
* @package s2Member\Utilities
|
71 |
+
* @since 3.5
|
72 |
+
*
|
73 |
+
* @return array Unique array of all Tag IDs *(as integers)*.
|
74 |
+
*/
|
75 |
+
public static function get_all_tag_ids()
|
76 |
+
{
|
77 |
+
foreach((array)get_tags('hide_empty=0') as $tag)
|
78 |
+
$tag_ids[] = (int)$tag->term_id; // Collect Tag's ID.
|
79 |
+
|
80 |
+
return (!empty($tag_ids) && is_array($tag_ids)) ? array_unique($tag_ids) : array();
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Converts a comma-delimited list of: Tag slugs/names/ids, into a unique array of all IDs.
|
85 |
+
*
|
86 |
+
* @package s2Member\Utilities
|
87 |
+
* @since 111101
|
88 |
+
*
|
89 |
+
* @param string $tags Tag slugs/names/IDs; comma-delimited.
|
90 |
+
*
|
91 |
+
* @return array Unique array of Tag IDs *(as integers)*. With Tag slugs/names converted to IDs.
|
92 |
+
*/
|
93 |
+
public static function get_tags_converted_to_ids($tags = '')
|
94 |
+
{
|
95 |
+
foreach(preg_split('/['."\r\n\t".';,]+/', (string)$tags) as $tag)
|
96 |
{
|
97 |
+
if(($tag = trim($tag)) && is_numeric($tag)) // Force integers.
|
98 |
+
$tag_ids[] = ($tag_id = (int)$tag); // Force integer values here.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
+
else if($tag && is_string($tag)) // A string (i.e. a tag name or a tag slug)?
|
101 |
+
{
|
102 |
+
if(is_object($term = get_term_by('name', $tag, 'post_tag')))
|
103 |
+
$tag_ids[] = (int)$term->term_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
+
else if(is_object($term = get_term_by('slug', $tag, 'post_tag')))
|
106 |
+
$tag_ids[] = (int)$term->term_id;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
return (!empty($tag_ids) && is_array($tag_ids)) ? array_unique($tag_ids) : array();
|
110 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
+
/**
|
113 |
+
* Retrieves a unique array of all published Post IDs in the database.
|
114 |
+
*
|
115 |
+
* @package s2Member\Utilities
|
116 |
+
* @since 3.5
|
117 |
+
*
|
118 |
+
* @param string $post_type Optional. If provided, return all Post IDs of a specific Post Type.
|
119 |
+
* Otherwise, return all Post IDs that are NOT of these Post Types: `page|attachment|nav_menu_item|revision`.
|
120 |
+
*
|
121 |
+
* @return array Unique array of all Post IDs *(as integers)*, including Custom Post Types; or all Post IDs of a specific Post Type.
|
122 |
+
*/
|
123 |
+
public static function get_all_post_ids($post_type = '')
|
124 |
+
{
|
125 |
+
/** @var wpdb $wpdb WordPress DB object instance. */
|
126 |
+
global $wpdb; // Global DB object reference.
|
127 |
+
|
128 |
+
if(is_array($post_ids = $wpdb->get_col("SELECT `ID` FROM `".$wpdb->posts."` WHERE `post_status` = 'publish' AND ".(($post_type) ? "`post_type` = '".esc_sql((string)$post_type)."'" : "`post_type` NOT IN('page','attachment','nav_menu_item','revision')"))))
|
129 |
+
$post_ids = c_ws_plugin__s2member_utils_arrays::force_integers($post_ids);
|
130 |
+
|
131 |
+
return (!empty($post_ids) && is_array($post_ids)) ? array_unique($post_ids) : array();
|
132 |
+
}
|
133 |
|
134 |
+
/**
|
135 |
+
* Retrieves a unique array of all published Child Post IDs in the database.
|
136 |
+
*
|
137 |
+
* @package s2Member\Utilities
|
138 |
+
* @since 3.5
|
139 |
+
*
|
140 |
+
* @param int|string|array $parent_ids One or more parent IDs to collect children for.
|
141 |
+
*
|
142 |
+
* @param string $post_type Optional. If provided, return all Post IDs of a specific Post Type.
|
143 |
+
* Otherwise, return all Post IDs that are NOT of these Post Types: `page|attachment|nav_menu_item|revision`.
|
144 |
+
*
|
145 |
+
* @return array Unique array of all Child Post IDs *(as integers)*, including Custom Post Types; or all Child Post IDs of a specific Post Type.
|
146 |
+
*/
|
147 |
+
public static function get_all_child_post_ids($parent_ids = array(), $post_type = '')
|
148 |
+
{
|
149 |
+
/** @var wpdb $wpdb WordPress DB object instance. */
|
150 |
+
global $wpdb; // Global DB object reference.
|
151 |
+
|
152 |
+
if(($parent_ids = (array)$parent_ids)) // Force an array value.
|
153 |
+
if(is_array($post_ids = $wpdb->get_col("SELECT `ID` FROM `".$wpdb->posts."` WHERE `post_status` = 'publish'".
|
154 |
+
" AND ".($post_type ? "`post_type` = '".esc_sql((string)$post_type)."'" : "`post_type` NOT IN('page','attachment','nav_menu_item','revision')").
|
155 |
+
" AND `post_parent` IN('".implode("','", $parent_ids)."')"))
|
156 |
+
) $post_ids = c_ws_plugin__s2member_utils_arrays::force_integers($post_ids);
|
157 |
+
|
158 |
+
return (!empty($post_ids) && is_array($post_ids)) ? array_unique($post_ids) : array();
|
159 |
+
}
|
160 |
|
161 |
+
/**
|
162 |
+
* Retrieves a unique array of all published Page IDs in the database.
|
163 |
+
*
|
164 |
+
* @package s2Member\Utilities
|
165 |
+
* @since 3.5
|
166 |
+
*
|
167 |
+
* @return array Unique array of all Page IDs *(as integers)*.
|
168 |
+
*/
|
169 |
+
public static function get_all_page_ids()
|
170 |
+
{
|
171 |
+
/** @var wpdb $wpdb WordPress DB object instance. */
|
172 |
+
global $wpdb; // Global DB object reference.
|
173 |
+
|
174 |
+
if(is_array($page_ids = $wpdb->get_col("SELECT `ID` FROM `".$wpdb->posts."` WHERE `post_status` = 'publish' AND `post_type` = 'page'")))
|
175 |
+
$page_ids = c_ws_plugin__s2member_utils_arrays::force_integers($page_ids);
|
176 |
+
|
177 |
+
return (!empty($page_ids) && is_array($page_ids)) ? array_unique($page_ids) : array();
|
178 |
+
}
|
|
|
179 |
|
180 |
+
/**
|
181 |
+
* Retrieves a unique array of all Singular IDs in the database that require Custom Capabilities.
|
182 |
+
*
|
183 |
+
* @package s2Member\Utilities
|
184 |
+
* @since 111101
|
185 |
+
*
|
186 |
+
* @return array Unique array of all Singular IDs *(as integers)* that require Custom Capabilities.
|
187 |
+
*/
|
188 |
+
public static function get_all_singular_ids_with_ccaps()
|
189 |
+
{
|
190 |
+
/** @var wpdb $wpdb WordPress DB object instance. */
|
191 |
+
global $wpdb; // Global DB object reference.
|
192 |
+
|
193 |
+
if(is_array($singular_ids = $wpdb->get_col("SELECT `post_id` FROM `".$wpdb->postmeta."` WHERE `meta_key` = 's2member_ccaps_req' AND `meta_value` != ''")))
|
194 |
+
$singular_ids = c_ws_plugin__s2member_utils_arrays::force_integers($singular_ids);
|
195 |
+
|
196 |
+
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique($singular_ids) : array();
|
197 |
+
}
|
198 |
|
199 |
+
/**
|
200 |
+
* Retrieves a unique array of unavailable Singular IDs that require Custom Capabilities.
|
201 |
+
*
|
202 |
+
* Only returns Singular IDs that require Custom Capabilities;
|
203 |
+
* and ONLY those which are NOT satisfied by ``$user``.
|
204 |
+
*
|
205 |
+
* @package s2Member\Utilities
|
206 |
+
* @since 111101
|
207 |
+
*
|
208 |
+
* @param WP_User $user Optional. A `WP_User` object. If this is a valid `WP_User` object, test against this ``$user``, else all are unavailable.
|
209 |
+
*
|
210 |
+
* @return array Unique array of all Singular IDs *(as integers)* NOT available to ``$user``, due to Custom Capability Restrictions.
|
211 |
+
*/
|
212 |
+
public static function get_unavailable_singular_ids_with_ccaps($user = NULL)
|
213 |
+
{
|
214 |
+
/** @var wpdb $wpdb WordPress DB object instance. */
|
215 |
+
global $wpdb; // Global DB object reference.
|
216 |
+
|
217 |
+
if(is_array($results = $wpdb->get_results("SELECT `".$wpdb->postmeta."`.`post_id`, `".$wpdb->postmeta."`.`meta_value`, `".$wpdb->posts."`.`post_type`".
|
218 |
+
" FROM `".$wpdb->posts."`, `".$wpdb->postmeta."` WHERE `".$wpdb->posts."`.`ID` = `".$wpdb->postmeta."`.`post_id`".
|
219 |
+
" AND `".$wpdb->postmeta."`.`meta_key` = 's2member_ccaps_req' AND `".$wpdb->postmeta."`.`meta_value` != ''")))
|
220 |
+
{
|
221 |
+
$bbpress_restrictions_enable = apply_filters('ws_plugin__s2member_bbpress_restrictions_enable', TRUE);
|
222 |
+
$bbpress_installed = c_ws_plugin__s2member_utils_conds::bbp_is_installed(); // bbPress is installed?
|
223 |
+
$bbpress_forum_post_type = $bbpress_installed ? bbp_get_forum_post_type() : ''; // Acquire the current post type for forums.
|
224 |
+
$bbpress_topic_post_type = $bbpress_installed ? bbp_get_topic_post_type() : ''; // Acquire the current post type for topics.
|
225 |
|
226 |
+
foreach($results as $r) // Now we need to check Custom Capabilities against ``$user``. If ``$user`` is a valid `WP_User` object, else all are unavailable.
|
227 |
+
{
|
228 |
+
if(!is_object($user) || empty($user->ID)) // No ``$user`` object? Maybe not logged-in?.
|
229 |
+
$singular_ids[] = (int)$r->post_id; // It's NOT available. There is no ``$user``.
|
230 |
|
231 |
+
else if(is_array($ccaps = @unserialize($r->meta_value))) // Make sure we unserialize.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
{
|
233 |
+
foreach($ccaps as $ccap) // Test for Custom Capability Restrictions now.
|
234 |
+
if(strlen($ccap) && !$user->has_cap('access_s2member_ccap_'.$ccap))
|
235 |
+
{
|
236 |
+
$singular_ids[] = (int)$r->post_id; // It's NOT available.
|
237 |
+
break; // Break now, no need to continue in this loop.
|
238 |
+
}
|
239 |
+
}
|
240 |
+
if($bbpress_restrictions_enable && $bbpress_installed && $r->post_type === $bbpress_forum_post_type)
|
241 |
+
if(!empty($singular_ids) && in_array((int)$r->post_id, $singular_ids, TRUE))
|
242 |
+
{
|
243 |
+
if(is_array($child_results = $wpdb->get_results("SELECT `".$wpdb->posts."`.`ID` as `post_id` FROM `".$wpdb->posts."`".
|
244 |
+
" WHERE `".$wpdb->posts."`.`post_parent` = '".esc_sql($r->post_id)."'".
|
245 |
+
" AND `".$wpdb->posts."`.`post_type` = '".esc_sql($bbpress_topic_post_type)."'")))
|
246 |
+
foreach($child_results as $child_r) $singular_ids[] = (int)$child_r->post_id;
|
247 |
+
}
|
248 |
+
}
|
249 |
+
}
|
250 |
+
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique($singular_ids) : array();
|
251 |
+
}
|
252 |
|
253 |
+
/**
|
254 |
+
* Retrieves a unique array of all Singular IDs that require Specific Post/Page Access.
|
255 |
+
*
|
256 |
+
* @package s2Member\Utilities
|
257 |
+
* @since 111101
|
258 |
+
*
|
259 |
+
* @param bool $exclude_conflicts Optional. Defaults to false. If true, return ONLY those which are NOT in conflict with any other Restriction Types.
|
260 |
+
* The ``$exclude_conflicts`` argument should be used whenever we introduce a list of option values to a site owner. Helping them avoid mishaps.
|
261 |
+
* Please note, the ``$exclude_conflicts`` argument implements a resource-intensive processing routine.
|
262 |
+
*
|
263 |
+
* @return array Unique array of all Singular IDs *(as integers)* that require Specific Post/Page Access.
|
264 |
+
*/
|
265 |
+
public static function get_all_singular_ids_with_sp($exclude_conflicts = FALSE)
|
266 |
+
{
|
267 |
+
if(is_array(($singular_ids = ($GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'] && is_array($singular_ids = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids']))) ? $singular_ids : array())))
|
268 |
+
$singular_ids = c_ws_plugin__s2member_utils_arrays::force_integers($singular_ids);
|
269 |
+
|
270 |
+
if(!empty($singular_ids) && is_array($singular_ids) && $exclude_conflicts /* Return ONLY those which are NOT in conflict with other Restrictions? */)
|
271 |
+
{
|
272 |
+
$x_ids = array($GLOBALS['WS_PLUGIN__']['s2member']['o']['login_welcome_page'], $GLOBALS['WS_PLUGIN__']['s2member']['o']['membership_options_page'], $GLOBALS['WS_PLUGIN__']['s2member']['o']['file_download_limit_exceeded_page']);
|
273 |
|
274 |
+
$x_ids = array_merge($x_ids, c_ws_plugin__s2member_utils_gets::get_all_singular_ids_with_ccaps());
|
275 |
+
|
276 |
+
for($n = 0; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n++)
|
277 |
+
{
|
278 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'] === 'all')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
{
|
280 |
+
$catgs = c_ws_plugin__s2member_utils_gets::get_all_category_ids();
|
281 |
+
$x_ids = array_merge($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($catgs));
|
282 |
+
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
}
|
284 |
+
foreach(($catgs = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_catgs'])) as $catg)
|
285 |
+
$catgs = array_merge($catgs, c_ws_plugin__s2member_utils_gets::get_all_child_category_ids($catg));
|
286 |
+
|
287 |
+
$x_ids = array_merge($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($catgs));
|
288 |
+
unset ($catgs, $catg); // Just a little housekeeping here.
|
289 |
+
}
|
290 |
+
for($n = 0; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n++)
|
291 |
+
{
|
292 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags'] === 'all')
|
|
|
|
|
|
|
293 |
{
|
294 |
+
$tags = c_ws_plugin__s2member_utils_gets::get_all_tag_ids();
|
295 |
+
$x_ids = array_merge($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($tags));
|
296 |
+
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
}
|
298 |
+
$tags = c_ws_plugin__s2member_utils_gets::get_tags_converted_to_ids($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_ptags']);
|
299 |
+
|
300 |
+
$x_ids = array_merge($x_ids, c_ws_plugin__s2member_utils_gets::get_singular_ids_in_terms($tags));
|
301 |
+
unset ($tags); // Just a little housekeeping here.
|
302 |
+
}
|
303 |
+
for($n = 0; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n++)
|
304 |
+
{
|
305 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'] === 'all')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
{
|
307 |
+
$x_ids = array_merge($x_ids, c_ws_plugin__s2member_utils_gets::get_all_post_ids());
|
308 |
+
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
}
|
310 |
+
foreach(($posts = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_posts'])) as $p)
|
311 |
+
if(strpos($p, 'all-') === 0 && preg_match('/^all-(.+)$/', $p, $m) /* Protecting `all-` of a specific Post Type? */)
|
312 |
+
if((is_array($p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids($m[1])) || (substr($m[1], -1) === 's' && is_array($_p_of_type = c_ws_plugin__s2member_utils_gets::get_all_post_ids(substr($m[1], 0, -1))))) && !empty($p_of_type))
|
313 |
+
$x_ids = array_merge($x_ids, $p_of_type); // Merge all Posts of this Post Type.
|
314 |
+
|
315 |
+
$x_ids = array_merge($x_ids, $posts); // Merge together.
|
316 |
+
unset ($posts, $p, $m, $p_of_type); // Just a little housekeeping here.
|
317 |
+
}
|
318 |
+
for($n = 0; $n <= $GLOBALS['WS_PLUGIN__']['s2member']['c']['levels']; $n++)
|
319 |
+
{
|
320 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages'] === 'all')
|
|
|
|
|
|
|
|
|
321 |
{
|
322 |
+
$x_ids = array_merge($x_ids, c_ws_plugin__s2member_utils_gets::get_all_page_ids());
|
323 |
+
continue; // Continue. The `all` specification is absolute. There's nothing more.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
}
|
325 |
+
$pages = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['level'.$n.'_pages']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
|
327 |
+
$x_ids = array_merge($x_ids, $pages); // Merge.
|
328 |
+
unset ($pages); // Just a little housekeeping here.
|
329 |
+
}
|
330 |
+
$x_ids = array_unique(c_ws_plugin__s2member_utils_arrays::force_integers($x_ids));
|
331 |
+
$singular_ids = array_diff($singular_ids, $x_ids);
|
332 |
+
}
|
333 |
+
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique($singular_ids) : array();
|
334 |
+
}
|
335 |
|
336 |
+
/**
|
337 |
+
* Retrieves a unique array of unavailable Singular IDs that require Specific Post/Page Access.
|
338 |
+
*
|
339 |
+
* Only returns Singular IDs that require Specific Post/Page Access;
|
340 |
+
* and ONLY those which are NOT satisfied by the current Visitor.
|
341 |
+
*
|
342 |
+
* @package s2Member\Utilities
|
343 |
+
* @since 111101
|
344 |
+
*
|
345 |
+
* @param bool $exclude_conflicts Optional. Defaults to false. If true, return ONLY those which are NOT in conflict with any other Restriction Types.
|
346 |
+
* The ``$exclude_conflicts`` argument should be used whenever we introduce a list of option values to a site owner. Helping them avoid mishaps.
|
347 |
+
* Please note, the ``$exclude_conflicts`` argument implements a resource-intensive processing routine.
|
348 |
+
*
|
349 |
+
* @return array Unique array of all Singular IDs *(as integers)* NOT available to current Visitor, due to Specific Post/Page Restrictions.
|
350 |
+
*/
|
351 |
+
public static function get_unavailable_singular_ids_with_sp($exclude_conflicts = FALSE)
|
352 |
+
{
|
353 |
+
if($GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'] && is_array($_singular_ids = preg_split('/['."\r\n\t".'\s;,]+/', $GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'])))
|
354 |
+
foreach($_singular_ids as $_singular_id) // Now check access to this Singular, against the current Visitor, via read-only ``c_ws_plugin__s2member_sp_access::sp_access()``.
|
355 |
+
if(is_numeric($_singular_id) && !c_ws_plugin__s2member_sp_access::sp_access($_singular_id, 'read-only'))
|
356 |
+
$singular_ids[] = (int)$_singular_id;
|
357 |
+
|
358 |
+
if(!empty($singular_ids) && is_array($singular_ids) && $exclude_conflicts)
|
359 |
+
{
|
360 |
+
$all_singular_ids_not_conflicting = c_ws_plugin__s2member_utils_gets::get_all_singular_ids_with_sp('exclude-conflicts');
|
361 |
+
foreach($singular_ids as $s => $singular_id) // Weed out anything that's in conflict here.
|
362 |
+
if(!in_array($singular_id, $all_singular_ids_not_conflicting))
|
363 |
+
unset($singular_ids[$s]); // Housekeeping.
|
364 |
}
|
365 |
+
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique($singular_ids) : array();
|
366 |
+
}
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Retrieves a unique array of all published Singulars, protected with Specific Post/Page Access.
|
370 |
+
*
|
371 |
+
* @package s2Member\Utilities
|
372 |
+
* @since 111101
|
373 |
+
*
|
374 |
+
* @uses {@link http://codex.wordpress.org/Function_Reference/get_posts get_posts()}
|
375 |
+
*
|
376 |
+
* @param bool $exclude_conflicts Optional. Defaults to false. If true, return ONLY those which are NOT in conflict with any other Restriction Types.
|
377 |
+
* The ``$exclude_conflicts`` argument should be used whenever we introduce a list of option values to a site owner. Helping them avoid mishaps.
|
378 |
+
* Please note, the ``$exclude_conflicts`` argument implements a resource-intensive processing routine.
|
379 |
+
*
|
380 |
+
* @return array Unique array of all Singulars *(i.e. Posts/Pages )* protected with Specific Post/Page Access.
|
381 |
+
* Includes Custom Post Types also, as specified by site owner's Specific Post/Page Restrictions.
|
382 |
+
*/
|
383 |
+
public static function get_all_singulars_with_sp($exclude_conflicts = FALSE)
|
384 |
+
{
|
385 |
+
$singulars = ($GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids'] && is_array($singulars = get_posts('post_status=publish&post_type=any&include='.$GLOBALS['WS_PLUGIN__']['s2member']['o']['specific_ids']))) ? $singulars : array();
|
386 |
+
|
387 |
+
if(!empty($singulars) && is_array($singulars) && $exclude_conflicts)
|
388 |
+
{
|
389 |
+
$all_singular_ids_not_conflicting = c_ws_plugin__s2member_utils_gets::get_all_singular_ids_with_sp('exclude-conflicts');
|
390 |
+
foreach($singulars as $s => $singular) // Weed out anything that's in conflict here.
|
391 |
+
if(!in_array($singular->ID, $all_singular_ids_not_conflicting))
|
392 |
+
unset($singulars[$s]); // Housekeeping.
|
393 |
+
}
|
394 |
+
return (!empty($singulars) && is_array($singulars)) ? c_ws_plugin__s2member_utils_arrays::array_unique($singulars) : array();
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* Retrieves a unique array of Singular IDs in the database, within specific term IDs.
|
399 |
+
*
|
400 |
+
* Only returns Singular IDs that are within the ``$terms`` passed through this function.
|
401 |
+
*
|
402 |
+
* @package s2Member\Utilities
|
403 |
+
* @since 110912
|
404 |
+
*
|
405 |
+
* @param array $terms Required. An array of term IDs.
|
406 |
+
*
|
407 |
+
* @return array Unique array of all Singular IDs *(as integers)* within the ``$terms`` passed through this function.
|
408 |
+
*/
|
409 |
+
public static function get_singular_ids_in_terms($terms = array())
|
410 |
+
{
|
411 |
+
/** @var wpdb $wpdb WordPress DB object instance. */
|
412 |
+
global $wpdb; // Global DB object reference.
|
413 |
+
|
414 |
+
if(!empty($terms) && is_array($terms) && is_array($singular_ids = $wpdb->get_col("SELECT `object_id` FROM `".$wpdb->term_relationships."` WHERE `term_taxonomy_id` IN (SELECT `term_taxonomy_id` FROM `".$wpdb->term_taxonomy."` WHERE `term_id` IN('".implode("','", $terms)."'))")))
|
415 |
+
$singular_ids = c_ws_plugin__s2member_utils_arrays::force_integers($singular_ids);
|
416 |
+
|
417 |
+
return (!empty($singular_ids) && is_array($singular_ids)) ? array_unique($singular_ids) : array();
|
418 |
+
}
|
419 |
}
|
420 |
+
}
|
includes/classes/utils-users.inc.php
CHANGED
@@ -40,15 +40,8 @@ if(!class_exists("c_ws_plugin__s2member_utils_users"))
|
|
40 |
global $wpdb;
|
41 |
/** @var wpdb $wpdb */
|
42 |
|
43 |
-
$
|
44 |
-
|
45 |
-
|
46 |
-
$q1 = mysql_query("SELECT SQL_CALC_FOUND_ROWS `".$wpdb->users."`.`ID` FROM `".$wpdb->users."`, `".$wpdb->usermeta."` WHERE `".$wpdb->users."`.`ID` = `".$wpdb->usermeta."`.`user_id` AND `".$wpdb->usermeta."`.`meta_key` = '".esc_sql($wpdb->prefix."capabilities")."' LIMIT 1", $wpdb_handle);
|
47 |
-
$q2 = mysql_query("SELECT FOUND_ROWS()", $wpdb_handle);
|
48 |
-
$users = (int)mysql_result($q2, 0);
|
49 |
-
|
50 |
-
mysql_free_result($q2);
|
51 |
-
mysql_free_result($q1);
|
52 |
|
53 |
return $users;
|
54 |
}
|
@@ -68,8 +61,7 @@ if(!class_exists("c_ws_plugin__s2member_utils_users"))
|
|
68 |
*/
|
69 |
public static function get_user_custom_with($subscr_txn_baid_cid_id = '', $os0 = '')
|
70 |
{
|
71 |
-
global $wpdb;
|
72 |
-
/** @var wpdb $wpdb */
|
73 |
|
74 |
if($subscr_txn_baid_cid_id && $os0) // This case includes some additional routines that can use the ``$os0`` value.
|
75 |
{
|
40 |
global $wpdb;
|
41 |
/** @var wpdb $wpdb */
|
42 |
|
43 |
+
$wpdb->query("SELECT SQL_CALC_FOUND_ROWS `".$wpdb->users."`.`ID` FROM `".$wpdb->users."`, `".$wpdb->usermeta."` WHERE `".$wpdb->users."`.`ID` = `".$wpdb->usermeta."`.`user_id` AND `".$wpdb->usermeta."`.`meta_key` = '".esc_sql($wpdb->prefix."capabilities")."' LIMIT 1");
|
44 |
+
$users = (int)$wpdb->get_var("SELECT FOUND_ROWS()");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
return $users;
|
47 |
}
|
61 |
*/
|
62 |
public static function get_user_custom_with($subscr_txn_baid_cid_id = '', $os0 = '')
|
63 |
{
|
64 |
+
global $wpdb; /** @var wpdb $wpdb */
|
|
|
65 |
|
66 |
if($subscr_txn_baid_cid_id && $os0) // This case includes some additional routines that can use the ``$os0`` value.
|
67 |
{
|
includes/functions/class-autoloader.inc.php
CHANGED
@@ -1,87 +1,86 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* s2Member class autoloader.
|
4 |
-
*
|
5 |
-
* Defines the __autoload function for s2Member classes.
|
6 |
-
* This highly optimizes s2Member. Giving it a much smaller footprint.
|
7 |
-
* See: {@link http://www.php.net/manual/en/function.spl-autoload-register.php}
|
8 |
-
*
|
9 |
-
* Copyright: © 2009-2011
|
10 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
11 |
-
* (coded in the USA)
|
12 |
-
*
|
13 |
-
* Released under the terms of the GNU General Public License.
|
14 |
-
* You should have received a copy of the GNU General Public License,
|
15 |
-
* along with this software. In the main directory, see: /licensing/
|
16 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
17 |
-
*
|
18 |
-
* @package s2Member
|
19 |
-
* @since 3.5
|
20 |
-
*/
|
21 |
-
if
|
22 |
-
exit (
|
23 |
|
24 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
{
|
26 |
-
|
27 |
-
|
28 |
-
*
|
29 |
-
* The __autoload function for s2Member classes.
|
30 |
-
* This highly optimizes s2Member. Giving it a much smaller footprint.
|
31 |
-
* See: {@link http://www.php.net/manual/en/function.spl-autoload-register.php}
|
32 |
-
*
|
33 |
-
* @package s2Member
|
34 |
-
* @since 3.5
|
35 |
-
*
|
36 |
-
* @param string $class The class that needs to be loaded. Passed in by PHP itself.
|
37 |
-
* @return null
|
38 |
-
*/
|
39 |
-
function ws_plugin__s2member_classes ($class = FALSE)
|
40 |
-
{
|
41 |
-
static /* Holds the classes directory location (location is optimized with a static var). */ $c;
|
42 |
-
static /* All possible dir & sub-directory locations (with a static var). */ $c_class_dirs;
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
$class = str_replace ("_", "-", str_replace ("c_ws_plugin__s2member_", "", $class));
|
50 |
|
51 |
-
|
52 |
-
if ($class_dir === $c || strpos ($class, basename ($class_dir)) === 0)
|
53 |
-
if (file_exists ($class_dir . "/" . $class . ".inc.php"))
|
54 |
-
{
|
55 |
-
include_once $class_dir . "/" . $class . ".inc.php";
|
56 |
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
59 |
}
|
60 |
-
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Scans recursively for class sub-directories.
|
64 |
-
*
|
65 |
-
* Used by the s2Member autoloader.
|
66 |
-
*
|
67 |
-
* @package s2Member
|
68 |
-
* @since 3.5
|
69 |
-
*
|
70 |
-
* @param string $starting_dir The directory to start scanning from.
|
71 |
-
* @return str[] An array of class directories.
|
72 |
-
*/
|
73 |
-
function _ws_plugin__s2member_classes_scan_dirs_r ($starting_dir = FALSE)
|
74 |
-
{
|
75 |
-
$dirs = /* Initialize dirs array. */ array();
|
76 |
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
|
84 |
-
}
|
85 |
-
spl_autoload_register /* Register __autoload. */ ("ws_plugin__s2member_classes");
|
86 |
}
|
87 |
-
|
|
|
|
1 |
<?php
|
2 |
/**
|
3 |
+
* s2Member class autoloader.
|
4 |
+
*
|
5 |
+
* Defines the __autoload function for s2Member classes.
|
6 |
+
* This highly optimizes s2Member. Giving it a much smaller footprint.
|
7 |
+
* See: {@link http://www.php.net/manual/en/function.spl-autoload-register.php}
|
8 |
+
*
|
9 |
+
* Copyright: © 2009-2011
|
10 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
11 |
+
* (coded in the USA)
|
12 |
+
*
|
13 |
+
* Released under the terms of the GNU General Public License.
|
14 |
+
* You should have received a copy of the GNU General Public License,
|
15 |
+
* along with this software. In the main directory, see: /licensing/
|
16 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
17 |
+
*
|
18 |
+
* @package s2Member
|
19 |
+
* @since 3.5
|
20 |
+
*/
|
21 |
+
if(realpath(__FILE__) === realpath($_SERVER['SCRIPT_FILENAME']))
|
22 |
+
exit ('Do not access this file directly.');
|
23 |
|
24 |
+
if(!function_exists('ws_plugin__s2member_classes'))
|
25 |
+
{
|
26 |
+
/**
|
27 |
+
* s2Member class autoloader.
|
28 |
+
*
|
29 |
+
* The __autoload function for s2Member classes.
|
30 |
+
* This highly optimizes s2Member. Giving it a much smaller footprint.
|
31 |
+
* See: {@link http://www.php.net/manual/en/function.spl-autoload-register.php}
|
32 |
+
*
|
33 |
+
* @package s2Member
|
34 |
+
* @since 3.5
|
35 |
+
*
|
36 |
+
* @param string $class The class that needs to be loaded. Passed in by PHP itself.
|
37 |
+
*/
|
38 |
+
function ws_plugin__s2member_classes($class = '')
|
39 |
{
|
40 |
+
static $c; // Holds the classes directory location (location is optimized with a static var).
|
41 |
+
static $c_class_dirs; // All possible dir & sub-directory locations (with a static var).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
+
if(strpos($class, 'c_ws_plugin__s2member_') === 0 && strpos($class, 'c_ws_plugin__s2member_pro_') === FALSE)
|
44 |
+
{
|
45 |
+
$c = (!isset ($c)) ? dirname(dirname(__FILE__)).'/classes' : $c; // Configures location of classes.
|
46 |
+
$c_class_dirs = (!isset ($c_class_dirs)) ? array_merge(array($c), _ws_plugin__s2member_classes_scan_dirs_r($c)) : $c_class_dirs;
|
|
|
|
|
47 |
|
48 |
+
$class = str_replace('_', '-', str_replace('c_ws_plugin__s2member_', '', $class));
|
|
|
|
|
|
|
|
|
49 |
|
50 |
+
foreach($c_class_dirs as $class_dir) // Start looking for the class.
|
51 |
+
if($class_dir === $c || strpos($class, basename($class_dir)) === 0)
|
52 |
+
if(file_exists($class_dir.'/'.$class.'.inc.php'))
|
53 |
+
{
|
54 |
+
include_once $class_dir.'/'.$class.'.inc.php';
|
55 |
+
break; // Now stop looking.
|
56 |
}
|
57 |
+
}
|
58 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
+
/**
|
61 |
+
* Scans recursively for class sub-directories.
|
62 |
+
*
|
63 |
+
* Used by the s2Member autoloader.
|
64 |
+
*
|
65 |
+
* @package s2Member
|
66 |
+
* @since 3.5
|
67 |
+
*
|
68 |
+
* @param string $starting_dir The directory to start scanning from.
|
69 |
+
*
|
70 |
+
* @return string[] An array of class directories.
|
71 |
+
*/
|
72 |
+
function _ws_plugin__s2member_classes_scan_dirs_r($starting_dir = '')
|
73 |
+
{
|
74 |
+
$dirs = array(); // Initialize dirs array.
|
75 |
+
|
76 |
+
foreach(func_get_args() as $starting_dir)
|
77 |
+
if($starting_dir && is_dir($starting_dir))
|
78 |
+
foreach(scandir($starting_dir) as $dir) // Scan this directory.
|
79 |
+
if($dir !== '.' && $dir !== '..' && is_dir($dir = $starting_dir.'/'.$dir))
|
80 |
+
$dirs = array_merge($dirs, array($dir), _ws_plugin__s2member_classes_scan_dirs_r($dir));
|
81 |
|
82 |
+
return $dirs; // Return all directories.
|
|
|
|
|
83 |
}
|
84 |
+
|
85 |
+
spl_autoload_register('ws_plugin__s2member_classes');
|
86 |
+
}
|
includes/menu-pages/down-ops.inc.php
CHANGED
@@ -1,781 +1,788 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* Menu page for the s2Member plugin (File Download Options page).
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Menu_Pages
|
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 |
{
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
* @package s2Member\Menu_Pages
|
26 |
-
* @since 110531
|
27 |
-
*/
|
28 |
-
class c_ws_plugin__s2member_menu_page_down_ops
|
29 |
-
{
|
30 |
-
public function __construct()
|
31 |
-
{
|
32 |
-
echo '<div class="wrap ws-menu-page">'."\n";
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
|
38 |
-
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
|
50 |
-
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
|
56 |
-
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
62 |
|
63 |
-
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
|
69 |
-
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
|
75 |
-
|
76 |
|
77 |
-
|
78 |
-
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
|
90 |
-
|
91 |
-
|
92 |
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
|
99 |
-
|
100 |
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
103 |
|
104 |
-
|
105 |
-
echo '</table>'."\n";
|
106 |
-
echo '</div>'."\n";
|
107 |
|
108 |
-
|
|
|
|
|
|
|
|
|
109 |
|
110 |
-
|
111 |
-
}
|
112 |
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
116 |
|
117 |
-
|
|
|
|
|
118 |
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
123 |
|
124 |
-
|
125 |
-
|
126 |
-
echo '<tr>'."\n";
|
127 |
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
133 |
|
134 |
-
|
135 |
-
|
|
|
|
|
136 |
|
137 |
-
|
138 |
-
echo '<select name="ws_plugin__s2member_file_download_limit_exceeded_page" id="ws-plugin--s2member-file-download-limit-exceeded-page">'."\n";
|
139 |
-
echo '<option value="">— Select —</option>'."\n";
|
140 |
-
foreach(($ws_plugin__s2member_temp_a = array_merge((array)get_pages())) as $ws_plugin__s2member_temp_o)
|
141 |
-
echo '<option value="'.esc_attr($ws_plugin__s2member_temp_o->ID).'"'.(($ws_plugin__s2member_temp_o->ID == $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"]) ? ' selected="selected"' : '').'>'.esc_html($ws_plugin__s2member_temp_o->post_title).'</option>'."\n";
|
142 |
-
echo '</select><br />'."\n";
|
143 |
-
echo 'We recommend the following title: <code>Download Limit Exceeded</code>.'."\n";
|
144 |
-
echo '</td>'."\n";
|
145 |
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
150 |
|
151 |
-
|
152 |
|
153 |
-
|
154 |
-
|
|
|
|
|
155 |
|
156 |
-
|
157 |
-
{
|
158 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_advanced_restrictions", get_defined_vars());
|
159 |
|
160 |
-
|
161 |
|
162 |
-
|
163 |
-
echo '<h3>Advanced Download Restrictions (optional, for greater flexibility)</h3>'."\n";
|
164 |
-
echo '<p>By default, s2Member uses your Basic Download Restrictions, as configured above. However, you can force s2Member to allow File Downloads, using an extra query string parameter: <code>&s2member_file_download_key=[Key]</code>. A File Download `Key` is passed through this parameter; it tells s2Member to allow the download of this particular file, regardless of Membership Level; and WITHOUT checking any Basic Restrictions, that you may or may not have configured above. The creation of a File Download `Key`, requires a small PHP code snippet. In order to use PHP scripting inside your Posts/Pages, you\'ll need to install this handy plugin (<a href="http://wordpress.org/extend/plugins/ezphp/" target="_blank" rel="external">ezPHP</a>). There is also a Shortcode equivalent, which does NOT require PHP at all, as seen below.</p>'."\n";
|
165 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_advanced_restrictions", get_defined_vars());
|
166 |
|
167 |
-
|
168 |
|
169 |
-
|
170 |
|
171 |
-
|
172 |
|
173 |
-
|
174 |
|
175 |
-
|
|
|
|
|
176 |
|
177 |
-
|
178 |
|
179 |
-
|
180 |
|
181 |
-
|
182 |
-
|
183 |
-
|
|
|
|
|
184 |
|
185 |
-
|
186 |
|
187 |
-
|
|
|
|
|
|
|
|
|
188 |
|
189 |
-
|
190 |
-
|
|
|
191 |
|
192 |
-
|
193 |
-
|
194 |
-
|
|
|
|
|
195 |
|
196 |
-
|
|
|
197 |
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_inline_extensions", get_defined_vars());
|
203 |
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
207 |
|
208 |
-
|
209 |
-
echo '<label for="ws-plugin--s2member-file-download-inline-extensions">'."\n";
|
210 |
-
echo 'Default Inline File Extensions (comma-delimited):'."\n";
|
211 |
-
echo '</label>'."\n";
|
212 |
-
echo '</th>'."\n";
|
213 |
|
214 |
-
|
215 |
-
|
|
|
|
|
|
|
216 |
|
217 |
-
|
218 |
-
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_file_download_inline_extensions" id="ws-plugin--s2member-file-download-inline-extensions" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_inline_extensions"]).'" /><br />'."\n";
|
219 |
-
echo 'Inline extensions, comma-delimited. Ex: <code>htm,html,pdf,jpg,jpeg,jpe,gif,png,mp3,mp4,flv,ogg,webm</code>'."\n";
|
220 |
-
echo '</td>'."\n";
|
221 |
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
|
|
|
|
|
|
226 |
|
227 |
-
|
228 |
|
229 |
-
|
230 |
-
|
|
|
|
|
|
|
231 |
|
232 |
-
|
233 |
-
{
|
234 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_remote_authorization", get_defined_vars());
|
235 |
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
|
238 |
-
|
239 |
-
echo '<h3>Remote Header Authorization (optional)</h3>'."\n";
|
240 |
-
echo '<p>This can be enabled on a case-by-case basis. Just add this to the end of your download links: <code>&s2member_file_remote=yes</code>. Shortcode alternative: <code>[s2File download="example-file.zip" remote="yes" /]</code>.</p>'."\n";
|
241 |
-
echo '<p>Remote Header Authorization allows access to file downloads through an entirely different approach. Instead of asking the Member to log into your site through a browser, a Member will be prompted automatically, to log in through HTTP Header Authorization prompts; which is the same technique used in more traditional security systems via .htaccess files. In other words, Remote Header Authorization makes it possible for your Members to access files through remote applications that may NOT use a browser. This is often the case when a Member needs to access protected files through a software client like iTunes; typical with podcasts. See <a href="http://www.s2member.com/videos/71F49478D6983A9C/" target="_blank" rel="external">tutorial video here</a> for details about how to setup a Podcast for iTunes.</p>'."\n";
|
242 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_remote_authorization", get_defined_vars());
|
243 |
-
echo '</div>'."\n";
|
244 |
|
245 |
-
|
|
|
|
|
246 |
|
247 |
-
|
248 |
-
}
|
249 |
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
|
254 |
-
|
|
|
|
|
|
|
|
|
255 |
|
256 |
-
|
257 |
-
|
258 |
-
echo '<a href="http://aws.amazon.com/s3/" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/amazon-logo.png" class="ws-menu-page-right" style="width:250px; height:100px; border:0;" alt="." /></a>'."\n";
|
259 |
-
echo '<p>Please note, all of this is optional. s2Member can be configured here to ONLY use Amazon S3 <em>(i.e. without Amazon CloudFront)</em>. Or, s2Member can be configured to use BOTH Amazon S3 and Amazon CloudFront together. If you want to use Amazon S3 Storage, but you don\'t care about Amazon CloudFront, feel free to leave the entire Amazon CloudFront section empty. The configuration options in the Amazon CloudFront section are ONLY required if you are planning to use both Amazon S3 and Amazon CloudFront together.</p>'."\n";
|
260 |
-
echo '<p>Amazon Simple Storage Service (<a href="http://aws.amazon.com/s3/" target="_blank" rel="external">Amazon S3</a>). Amazon S3 is storage for the Internet. It is designed to make web-scale computing easier for developers. Amazon S3 provides a simple web services interface that can be used to store and retrieve any amount of data, at any time, from anywhere on the web. It gives developers access to the same highly scalable, reliable, secure, fast, inexpensive infrastructure that Amazon uses to run its own global network of web sites. s2Member has been integrated with Amazon S3, so that <em>(if you wish)</em>, instead of using the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory, you can store all of your protected files inside an Amazon S3 Bucket.</p>'."\n";
|
261 |
-
echo '<p>If you configure the options below, s2Member will assume all protected files are inside your Amazon S3 Bucket; and the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory is no longer used at all. That being said, all other aspects of s2Member\'s File Download protection remain the same. The only thing that changes, is the location of your protected files. In other words, Basic Download Restrictions, Download Keys, Inline Extensions, Custom Capability and/or Membership Level Files will all continue to work just as before. The only difference is that s2Member will use your Amazon S3 Bucket as a CDN <em>(i.e. Content Delivery Network)</em> instead of the local <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory.</p>'."\n";
|
262 |
-
echo '<p>s2Member assumes that you\'re creating a new Amazon S3 Bucket, specifically for this installation; and that your Bucket is NOT available publicly. In other words, if you type this URL into your browser <em>(i.e. <code>http://your-bucket-name.s3.amazonaws.com/</code>)</em>, you should get an error that says: <code>Access Denied</code>. That\'s good, that\'s exactly what you want. You can create your Amazon S3 Bucket using the <a href="https://console.aws.amazon.com/s3/home" target="_blank" rel="external">Amazon interface</a>. Or, some people prefer to use this popular Firefox extension (<a href="http://www.s3fox.net/" target="_blank" rel="external">S3 Fox Organizer</a>).</p>'."\n";
|
263 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_amazon_s3", get_defined_vars());
|
264 |
|
265 |
-
|
|
|
|
|
|
|
|
|
266 |
|
267 |
-
|
268 |
-
|
269 |
-
echo '<p><em><strong>Content Type, Disposition & Inline Files:</strong> The query string parameter <code>&s2member_file_inline=yes</code> DOES work for files served directly through Amazon S3. s2Member DOES have control over the <code>Content-Type</code> and <code>Content-Disposition</code> headers for files being served through Amazon S3. However, Amazon CloudFront servers do NOT automatically determine the MIME type for the objects they serve. If you integrate both Amazon S3 and CloudFront, s2Member will NOT have control over headers. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. Again, with the Amazon S3/CloudFront combination, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
|
270 |
|
271 |
-
|
|
|
|
|
|
|
|
|
272 |
|
273 |
-
|
274 |
-
|
275 |
-
echo '<tr>'."\n";
|
276 |
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
|
283 |
-
|
284 |
-
|
285 |
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
echo '<th>'."\n";
|
296 |
-
echo '<label for="ws-plugin--s2member-amazon-s3-files-access-key">'."\n";
|
297 |
-
echo 'Amazon Access Key (Access Key ID):'."\n";
|
298 |
-
echo '</label>'."\n";
|
299 |
-
echo '</th>'."\n";
|
300 |
-
|
301 |
-
echo '</tr>'."\n";
|
302 |
-
echo '<tr>'."\n";
|
303 |
-
|
304 |
-
echo '<td>'."\n";
|
305 |
-
echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_amazon_s3_files_access_key" id="ws-plugin--s2member-amazon-s3-files-access-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"]).'" /><br />'."\n";
|
306 |
-
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› Access Keys</code>.'."\n";
|
307 |
-
echo '</td>'."\n";
|
308 |
-
|
309 |
-
echo '</tr>'."\n";
|
310 |
-
echo '<tr>'."\n";
|
311 |
-
|
312 |
-
echo '<th>'."\n";
|
313 |
-
echo '<label for="ws-plugin--s2member-amazon-s3-files-secret-key">'."\n";
|
314 |
-
echo 'Amazon Secret Key (Secret Access Key):'."\n";
|
315 |
-
echo '</label>'."\n";
|
316 |
-
echo '</th>'."\n";
|
317 |
-
|
318 |
-
echo '</tr>'."\n";
|
319 |
-
echo '<tr>'."\n";
|
320 |
-
|
321 |
-
echo '<td>'."\n";
|
322 |
-
echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_amazon_s3_files_secret_key" id="ws-plugin--s2member-amazon-s3-files-secret-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"]).'" /><br />'."\n";
|
323 |
-
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› Access Keys (leading to: Legacy Security Credentials)</code>.<br />'."\n";
|
324 |
-
echo 'Amazon is deprecating Secret Access Keys, but they ARE still required for digitally signed URLs.'."\n";
|
325 |
-
echo '</td>'."\n";
|
326 |
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
echo '</div>'."\n";
|
333 |
-
|
334 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_amazon_s3", get_defined_vars());
|
335 |
-
}
|
336 |
-
|
337 |
-
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_amazon_cf", true, get_defined_vars()))
|
338 |
-
{
|
339 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_amazon_cf", get_defined_vars());
|
340 |
-
|
341 |
-
echo '<div class="ws-menu-page-group" title="Amazon S3/CloudFront CDN Storage Option"'.((!empty(c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"])) ? ' default-state="open"' : '').'>'."\n";
|
342 |
-
|
343 |
-
echo '<div class="ws-menu-page-section ws-plugin--s2member-amazon-cf-section">'."\n";
|
344 |
-
echo '<h3>Amazon S3/CloudFront CDN Storage & Delivery (optional)</h3>'."\n";
|
345 |
-
echo '<a href="http://aws.amazon.com/cloudfront/" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/amazon-logo.png" class="ws-menu-page-right" style="width:250px; height:100px; border:0;" alt="." /></a>'."\n";
|
346 |
-
echo '<p>Please note, all of this is optional. s2Member can be configured to ONLY use Amazon S3 <em>(i.e. without Amazon CloudFront)</em>. Or, s2Member can be configured to use BOTH Amazon S3 and Amazon CloudFront together. If you don\'t want to use Amazon CloudFront, please leave this entire section empty. The configuration options in this section are ONLY required if you are planning to use both Amazon S3 and Amazon CloudFront together.</p>'."\n";
|
347 |
-
echo '<p>Amazon Simple Storage Service (<a href="http://aws.amazon.com/s3/" target="_blank" rel="external">Amazon S3</a>) combined with <a href="http://aws.amazon.com/cloudfront/" target="_blank" rel="external">Amazon CloudFront</a>. Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services <em>(i.e. Amazon S3 Storage)</em> to give developers and businesses an easy way to distribute content to end users with low latency, and with high data transfer speeds. Amazon CloudFront delivers your static and streaming content using a global network of edge locations. Requests for your Amazon S3 Bucket Objects <em>(i.e. your protected files)</em> are automatically routed to the nearest edge location, so content is delivered with the best possible performance. s2Member has been integrated with both Amazon S3 and with Amazon CloudFront. So <em>(if you wish)</em>, instead of using the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory, you can store all of your protected files inside an Amazon S3 Bucket and serve them via Amazon CloudFront. But again, please understand, the configuration options in this section are ONLY required if you\'re going to use both Amazon S3 & CloudFront together.</p>'."\n";
|
348 |
-
echo '<p><strong>One of the great things about Amazon CloudFront</strong>, is its ability to <strong>stream/seek media files</strong> in the truest sense of the word. For sites delivering protected <em>FLV/MP4/OGG/WEBM</em> and other streaming audio/video file types over the <em>RTMP</em> protocol, Amazon CloudFront is our recommendation. Once you\'ve successfully configured s2Member to use both Amazon S3 and Amazon CloudFront together, please review the section below regarding <code>JW Player & RTMP Protocol Examples</code>. s2Member will automatically serve your protected files over the <em>RTMP</em> protocol using an Amazon CloudFront Streaming Distribution.</p>'."\n";
|
349 |
-
echo '<p>If you configure the options below, s2Member will assume all protected files are inside your Amazon S3 Bucket; and the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory is no longer used at all. That being said, all other aspects of s2Member\'s File Download protection remain the same. The only thing that changes, is the location of your protected files. In other words, Basic Download Restrictions, Download Keys, Custom Capability and/or Membership Level Files will all continue to work just as before. The only difference is that s2Member will use your Amazon S3 Bucket, automatically connecting it to both of the Amazon CloudFront Distributions, which s2Member auto-configures for you <em>(see below)</em>. In this way, s2Member uses Amazon CloudFront as a CDN <em>(i.e. Content Delivery Network)</em> for your protected files.</p>'."\n";
|
350 |
-
echo '<p>s2Member assumes that you\'re creating a new Amazon S3 Bucket, specifically for this installation; and that your Bucket is NOT available publicly. In other words, if you type this URL into your browser <em>(i.e. <code>http://your-bucket-name.s3.amazonaws.com/</code>)</em>, you should get an error that says: <code>Access Denied</code>. That\'s good, that\'s exactly what you want. You can create your Amazon S3 Bucket using the <a href="https://console.aws.amazon.com/s3/home" target="_blank" rel="external">Amazon interface</a>. Or, some people prefer to use this popular Firefox extension (<a href="http://www.s3fox.net/" target="_blank" rel="external">S3 Fox Organizer</a>). You will also need to enable CloudFront inside your Web Services account at Amazon. Don\'t worry about creating or configuring any CloudFront Distributions, s2Member will auto-create and auto-configure those for you, allowing you to serve protected files.</p>'."\n";
|
351 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_amazon_cf", get_defined_vars());
|
352 |
-
|
353 |
-
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
354 |
-
|
355 |
-
echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member\'s auto-configuration routines for Amazon CloudFront (below), are designed to create & configure various components on your Amazon Web Services account, which are all requirements for you to <a href="http://docs.amazonwebservices.com/AmazonCloudFront/2010-11-01/DeveloperGuide/index.html?HowToPrivateContent.html" target="_blank" rel="external">serve protected files through the Amazon S3/CloudFront combination</a>. These components include: an Origin Access Identity, read permissions for the Origin Access Identity, and two private content Distributions. One private content Distribution for file downloads, and another private content Distribution for streaming media files; both connected to and sourced by your Amazon S3 Bucket. In addition, s2Member will automatically configure an ACL & Policy (i.e. permissions) on your Amazon S3 Bucket to make sure your protected object/files are NOT available to the public.</em></p>'."\n";
|
356 |
-
echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member uses "Digitally Signed URLs", authenticated by the Amazon CloudFront API. Documented for developers <a href="http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html" target="_blank" rel="external">here</a>. To put it simply, s2Member will generate Amazon CloudFront URLs (internally); which allow Customers temporary access to specific files inside your S3 Bucket — via CloudFront Distributions. s2Member\'s Digitally Signed URLs leading to Amazon S3/CloudFront, give a Customer 24 hours to connect to the file inside your S3 Bucket. This connection period of 24 hours is largely irrelevant when used in combination with s2Member, because access is renewed for another 24 hours each time you make a file available to a User/Member, and they are authenticated by your configuration of s2Member. This connection period of 24 hours is just a secondary line of defense to further prevent the possibility of link sharing. If you need to change this connection timeout of <code>24 hours</code> for some reason (not likely), you can use this WordPress Filter: <code>ws_plugin__s2member_amazon_cf_file_expires_time</code>.</em></p>'."\n";
|
357 |
-
echo '<p><em><strong>Linking To Protected Files:</strong> RTMP streams are special, but nothing else changes. s2Member\'s integration with Amazon S3/CloudFront serves protected files through the same links that all s2Member site owners use. For example, you might use: <code>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'</code>, where <strong>s2member_file_download</strong> = the file, relative to the root of your Amazon S3 Bucket. In other words, just the file name in most cases. s2Member will redirect Users/Members to a digitally signed Amazon CloudFront URL, which allows them access to a particular file via Amazon CloudFront. For further details, please review this section of your Dashboard: <code>s2Member -› Download Options -› Basic Download Restrictions</code>. Also see: <code>s2Member -› Download Options -› Advanced Mod-Rewrite Linkage</code>. If you\'re streaming audio/video files over the RTMP protocol, please review the section below: <code>JW Player & RTMP Protocol Examples</code>.</em></p>'."\n";
|
358 |
-
echo '<p><em><strong>Content Type, Disposition & Inline Files:</strong> An IMPORTANT issue. The query string parameter <code>&s2member_file_inline=yes</code> does NOTHING for files served via Amazon CloudFront. s2Member has NO control over the <code>Content-Type</code> and/or <code>Content-Disposition</code> headers for a file being served through Amazon CloudFront, and CloudFront servers do NOT automatically determine the MIME type for the objects they serve. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. That is, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
|
359 |
-
echo (stripos(PHP_OS, "win") === 0 && c_ws_plugin__s2member_utils_conds::is_localhost()) ? '<p><em><strong>Localhost Developers:</strong> s2Member\'s Amazon CloudFront integration requires the <a href="http://php.net/manual/en/function.openssl-sign.php" target="_blank" rel="external">openssl_sign()</a> function in PHP so it can digitially sign CloudFront URLs. This function is sometimes problematic on localhost servers such as WAMP & EasyPHP. We recommend installing <a href="http://www.slproweb.com/products/Win32OpenSSL.html" target="_blank" rel="external">this lightweight alternative for Windows</a> while you\'re developing. s2Member will automatically find it here: <code>C:\OpenSSL-Win[32/64]\bin\openssl.exe</code>.'.((file_exists("c:\openssl-win32\bin\openssl.exe") || file_exists("c:\openssl-win64\bin\openssl.exe")) ? ' <strong class="ws-menu-page-hilite">( s2Member has detected that OpenSSL-Win[32/64] IS installed in the correct location, thank you! )</strong>' : ' <strong class="ws-menu-page-hilite">(s2Member has detected that OpenSSL-Win[32/64] is NOT currently available)</strong>').'</em></p>'."\n" : '';
|
360 |
-
|
361 |
-
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_auto_config_status"] === "configured")
|
362 |
-
echo '<p><em class="ws-menu-page-hilite"><strong>Your Amazon CloudFront Distributions are: ( ALREADY configured! )</strong></em>'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]) ? '<br /><em class="ws-menu-page-hilite">Downloads Distribution CNAME:</em> <em><code>'.esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]).' —» '.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 class="ws-menu-page-hilite">Streaming Distribution CNAME:</em> <em><code>'.esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]).' —» '.esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_dname"]).'</code></em>' : '').'</p>'."\n";
|
363 |
-
|
364 |
-
else if(!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_auto_config_status"])
|
365 |
-
echo '<p><em class="ws-menu-page-hilite"><strong>Your Amazon CloudFront Distributions are: (NOT yet auto-configured).</strong></em></p>'."\n";
|
366 |
-
|
367 |
-
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
368 |
-
|
369 |
-
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
370 |
-
echo '<tbody>'."\n";
|
371 |
-
echo '<tr>'."\n";
|
372 |
-
|
373 |
-
echo '<th style="padding-top:0;">'."\n";
|
374 |
-
echo '<label for="ws-plugin--s2member-amazon-cf-files-private-key-id">'."\n";
|
375 |
-
echo 'Amazon CloudFront Key Pair ID (your Key Pair ID):'."\n";
|
376 |
-
echo '</label>'."\n";
|
377 |
-
echo '</th>'."\n";
|
378 |
-
|
379 |
-
echo '</tr>'."\n";
|
380 |
-
echo '<tr>'."\n";
|
381 |
-
|
382 |
-
echo '<td>'."\n";
|
383 |
-
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_private_key_id" id="ws-plugin--s2member-amazon-cf-files-private-key-id" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key_id"]).'" data-s-prev-config-value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key_id"]).'" /><br />'."\n";
|
384 |
-
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› Key Pairs</code>.'."\n";
|
385 |
-
echo '</td>'."\n";
|
386 |
-
|
387 |
-
echo '</tr>'."\n";
|
388 |
-
echo '<tr>'."\n";
|
389 |
-
|
390 |
-
echo '<th>'."\n";
|
391 |
-
echo '<label for="ws-plugin--s2member-amazon-cf-files-private-key-entry">'."\n";
|
392 |
-
echo 'Amazon CloudFront Private Key (contents of your <code>pk-[***].pem</code> file):'."\n";
|
393 |
-
echo '</label>'."\n";
|
394 |
-
echo '</th>'."\n";
|
395 |
-
|
396 |
-
echo '</tr>'."\n";
|
397 |
-
echo '<tr>'."\n";
|
398 |
-
|
399 |
-
echo '<td>'."\n";
|
400 |
-
echo '<input type="hidden" name="ws_plugin__s2member_amazon_cf_files_private_key" id="ws-plugin--s2member-amazon-cf-files-private-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" data-s-prev-config-value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" />'."\n";
|
401 |
-
echo '<textarea name="ws_plugin__s2member_amazon_cf_files_private_key_entry" id="ws-plugin--s2member-amazon-cf-files-private-key-entry" rows="3" wrap="off" spellcheck="false" class="monospace">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'</textarea><br />'."\n";
|
402 |
-
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› Key Pairs</code>.<br />'."\n";
|
403 |
-
echo '<em>* Note, s2Member needs your <strong>Private Key file</strong>, NOT your Public Key file.</em>'."\n";
|
404 |
-
echo '</td>'."\n";
|
405 |
-
|
406 |
-
echo '</tr>'."\n";
|
407 |
-
echo '<tr>'."\n";
|
408 |
-
|
409 |
-
echo '<th>'."\n";
|
410 |
-
echo '<label for="ws-plugin--s2member-amazon-cf-files-auto-configure-distros">'."\n";
|
411 |
-
echo 'Auto-Configure your Amazon S3/CloudFront combination?'."\n";
|
412 |
-
echo '</label>'."\n";
|
413 |
-
echo '</th>'."\n";
|
414 |
-
|
415 |
-
echo '</tr>'."\n";
|
416 |
-
echo '<tr>'."\n";
|
417 |
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
|
423 |
-
|
424 |
-
echo '<tr>'."\n";
|
425 |
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
|
431 |
-
|
432 |
-
echo '</tbody>'."\n";
|
433 |
-
echo '</table>'."\n";
|
434 |
|
435 |
-
|
436 |
-
|
437 |
-
echo '<tbody>'."\n";
|
438 |
-
echo '<tr>'."\n";
|
439 |
|
440 |
-
|
441 |
-
|
442 |
-
echo 'Amazon CloudFront CNAME for File Downloads (optional):'."\n";
|
443 |
-
echo '</label>'."\n";
|
444 |
-
echo '</th>'."\n";
|
445 |
|
446 |
-
|
447 |
-
|
448 |
|
449 |
-
|
450 |
-
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_distro_downloads_cname" id="ws-plugin--s2member-amazon-cf-files-downloads-distro-cname" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]).'" /><br />'."\n";
|
451 |
-
echo 'Example: <code>s2-file-downloads.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
|
452 |
-
echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
|
453 |
-
echo '</td>'."\n";
|
454 |
|
455 |
-
|
456 |
-
echo '<tr>'."\n";
|
457 |
|
458 |
-
|
459 |
-
|
460 |
-
echo 'Amazon CloudFront CNAME for Streaming Files (optional):'."\n";
|
461 |
-
echo '</label>'."\n";
|
462 |
-
echo '</th>'."\n";
|
463 |
|
464 |
-
|
465 |
-
|
466 |
|
467 |
-
|
468 |
-
|
469 |
-
echo 'Example: <code>s2-streaming-files.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
|
470 |
-
echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
|
471 |
-
echo '</td>'."\n";
|
472 |
|
473 |
-
|
474 |
-
echo '</tbody>'."\n";
|
475 |
-
echo '</table>'."\n";
|
476 |
-
echo '</div>'."\n";
|
477 |
-
echo '</div>'."\n";
|
478 |
|
479 |
-
|
480 |
|
481 |
-
|
482 |
-
|
483 |
|
484 |
-
|
485 |
-
|
486 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_rtmp_streaming", get_defined_vars());
|
487 |
|
488 |
-
|
|
|
489 |
|
490 |
-
|
491 |
-
|
492 |
-
echo '<a href="http://www.longtailvideo.com/players/" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/jwplayer-logo.png" class="ws-menu-page-right" style="width:179px; height:58px; border:0; border-radius:3px; background:#FFFFFF; padding:15px;" alt="." /></a>'."\n";
|
493 |
-
echo '<p>While it is possible to serve audio/video files protected by s2Member, without needing to integrate Amazon S3 or CloudFront; we DO highly recommend that you integrate both Amazon S3 and Amazon CloudFront in order to maximize speed and compatibility across various viewing platforms. That being said, there are code samples below that will serve audio/video files both with and without Amazon S3/CloudFront. You can also check the <a href="'.esc_attr(c_ws_plugin__s2member_readmes::parse_readme_value("Forum URI")).'" target="_blank" rel="external">s2Member Support Forums</a> for tips/tricks if you like.</p>'."\n";
|
494 |
-
echo '<p><strong>One of the great things about Amazon CloudFront</strong>, is its ability to <strong>stream/seek media files</strong> in the truest sense of the word. For sites delivering protected <em>FLV/MP4/OGG/WEBM</em> and other streaming audio/video file types over the <em>RTMP</em> protocol, Amazon CloudFront is our recommendation. Once you\'ve successfully configured s2Member to use both Amazon S3 and Amazon CloudFront together, please review the code samples below. s2Member can automatically serve your protected files over the <em>RTMP</em> protocol using an Amazon CloudFront Streaming Distribution.</p>'."\n";
|
495 |
-
echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/" target="_blank" rel="external">JW Player w/ <code>[s2Stream /]</code> Shortcodes</a>.</p>'."\n";
|
496 |
-
if(stripos(wp_get_theme(), 'infocus') !== FALSE)
|
497 |
-
echo '<p><strong>Note:</strong> It appears that you\'re using the inFocus WordPress theme. If you experience trouble with the shortcodes below, try wrapping the shortcode in <code>[raw][/raw]</code> tags (e.g., <code>[raw][s2Stream ... /][/raw]</code>).</p>'."\n";
|
498 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_rtmp_streaming", get_defined_vars());
|
499 |
|
500 |
-
|
501 |
|
502 |
-
|
503 |
|
504 |
-
|
505 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
|
507 |
-
|
508 |
-
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4-rtmp" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Streams with the RTMP protocol, plus there is a full download fallback of the MP4 source file if streaming is not possible on a particular device.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp4-rtmp.x-php")).'</p>'."\n";
|
509 |
-
|
510 |
-
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4-rtmp-only\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4 only, via s2Member\'s Amazon S3/CloudFront integration)</a></p>'."\n";
|
511 |
-
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4-rtmp-only" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Streams with the RTMP protocol only, with no access to the source file, only to the RTMP stream.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp4-rtmp-only.x-php")).'</p>'."\n";
|
512 |
|
513 |
-
|
|
|
|
|
|
|
514 |
|
515 |
-
|
516 |
|
517 |
-
|
518 |
-
|
|
|
|
|
519 |
|
520 |
-
|
521 |
-
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp3-rtmp" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Streams with the RTMP protocol, plus there is a full download fallback of the MP3 source file if streaming is not possible on a particular device.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp3-rtmp.x-php")).'</p>'."\n";
|
522 |
|
523 |
-
|
524 |
-
|
|
|
525 |
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-standard-mp4" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This does NOT require s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <code>s2Member -› Download Options -› Advanced Mod Rewrite Linkage</code>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-standard-mp4.x-php")).'</p>'."\n";
|
532 |
-
|
533 |
-
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4, via s2Member\'s Amazon S3/CloudFront integration)</a></p>'."\n";
|
534 |
-
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/" target="_blank" rel="external">s2Member Codex -› API Functions</a>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-streaming-mp4.x-php")).'</p>'."\n";
|
535 |
-
|
536 |
-
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-sca\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4, via s2Member\'s JSON/Shortcode alternative)</a></p>'."\n";
|
537 |
-
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-sca" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/" target="_blank" rel="external">s2Member Codex -› API Functions</a>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-streaming-mp4-sca.x-php")).'</p>'."\n";
|
538 |
-
|
539 |
-
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-webm\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4, advanced w/ multiple fallbacks)</a></p>'."\n";
|
540 |
-
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-webm" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/" target="_blank" rel="external">s2Member Codex -› API Functions</a>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-streaming-mp4-webm.x-php")).'</p>'."\n";
|
541 |
-
|
542 |
-
echo '</div>'."\n";
|
543 |
-
|
544 |
-
echo '</div>'."\n";
|
545 |
-
|
546 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_rtmp_streaming", get_defined_vars());
|
547 |
-
}
|
548 |
-
|
549 |
-
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_rewrite_linkage", true, get_defined_vars()))
|
550 |
-
{
|
551 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_rewrite_linkage", get_defined_vars());
|
552 |
-
|
553 |
-
echo '<div class="ws-menu-page-group" title="Advanced Mod-Rewrite Linkage">'."\n";
|
554 |
-
|
555 |
-
echo '<div class="ws-menu-page-section ws-plugin--s2member-rewrite-linkage-section">'."\n";
|
556 |
-
echo '<h3>Advanced Mod-Rewrite Linkage</h3>'."\n";
|
557 |
-
echo '<p>s2Member automatically creates <code>mod_rewrite</code> rules inside your <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory, which provide additional flexibility in the way protected files can be served to your Customers. With s2Member\'s <code>mod_rewrite</code> rules, it is now possible to link directly to a protected file, avoiding the use of query string variables <em>(it\'s completely optional though, i.e. NOT required)</em>.</p>'."\n";
|
558 |
-
echo '<p>This new flexibility may come in handy for site owners serving files through media playback devices that have issues with query string variables. For instance, it is now possible to link to an s2Member-protected file directly, like this: <code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/example-file.zip</code> instead of <code>... /?s2member_file_download=example-file.zip</code>. Either way works, but the direct link might be easier for some.</p>'."\n";
|
559 |
-
echo '<p>It is also possible to pass query string parameters through a direct link:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/example-file.zip?s2member_file_inline=yes&s2member_file_download_key=[key]</code>.</p>'."\n";
|
560 |
-
echo '<p>That being said, s2Member\'s <code>mod_rewrite</code> rules allow for more advanced control over s2Member-specific parameters.</p>'."\n";
|
561 |
-
echo '<p>For example, you could just do this for inline files:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline</strong>/example-file.zip</code></p>'."\n";
|
562 |
-
echo '<p>Or, if you really want to get advanced, you could do something like this:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline-[yes|no]/s2member-file-download-key-[key]</strong>/example-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline-yes/s2member-file-download-key-xS54df5ER4d5x</strong>/example-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline-yes/s2member-skip-confirmation</strong>/example-file.zip</code></p>'."\n";
|
563 |
-
echo '<p>Or even this, if you\'re using Remote Header Authorization:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-remote</strong>/example-file.zip</code></p>'."\n";
|
564 |
-
echo '<p>Specifying storage location option dynamically:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-storage-[local|s3|cf]</strong>/example-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-storage-cf</strong>/example-cloudfront-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-storage-s3/s2member-file-inline</strong>/example-s3-file.html</code></p>'."\n";
|
565 |
-
echo '<p><em>* Note, the order of your s2Member-specific parameters with Advanced Mod-Rewrite Linkage is irrelevant. Feel free to add/remove, or even change the order. Everything discussed here is also Multisite compatible. Everything discussed here is also compatible when/if combined with Amazon S3/CDN Storage. However, NONE of this will work on servers that do NOT support <code>mod_rewrite</code>. Almost all web servers do though.</em></p>'."\n";
|
566 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_rewrite_linkage", get_defined_vars());
|
567 |
-
echo '</div>'."\n";
|
568 |
-
|
569 |
-
echo '</div>'."\n";
|
570 |
-
|
571 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_rewrite_linkage", get_defined_vars());
|
572 |
-
}
|
573 |
-
|
574 |
-
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_shortcode_attrs", true, get_defined_vars()))
|
575 |
-
{
|
576 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_shortcode_attrs", get_defined_vars());
|
577 |
-
|
578 |
-
echo '<div class="ws-menu-page-group" title="Shortcode Attributes & API Functions (Explained)">'."\n";
|
579 |
-
|
580 |
-
echo '<div class="ws-menu-page-section ws-plugin--s2member-shortcode-attrs-section">'."\n";
|
581 |
-
echo '<h3>Shortcode Attributes & API Functions (Explained In Full Detail)</h3>'."\n";
|
582 |
-
echo '<p>s2Member makes <a href="http://codex.wordpress.org/Shortcode_API#Overview" target="_blank" rel="external">Shortcodes</a> available to you, which allow you to generate File Download URLs and/or File Download Keys. Like most Shortcodes for WordPress, s2Member reads Attributes in your Shortcode. Many site owners like to know exactly how these Shortcode Attributes work. Below, is a brief overview of each possible Shortcode Attribute.</p>'."\n";
|
583 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs", get_defined_vars());
|
584 |
-
|
585 |
-
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
586 |
-
|
587 |
-
echo '<h4 style="margin:0;"><code>[s2File /]</code> & <code>[s2Stream /]</code> Shortcode Attributes:</h4>'."\n";
|
588 |
-
echo '<p style="margin:0;"><strong>See also:</strong> API Function <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_s2member_file_download_url()" target="_blank" rel="external">s2member_file_download_url()</a> for PHP integration.</p>'."\n";
|
589 |
-
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
590 |
-
echo '<tbody>'."\n";
|
591 |
-
echo '<tr style="padding-top:0;">'."\n";
|
592 |
-
|
593 |
-
echo '<td style="padding-top:0;">'."\n";
|
594 |
-
echo '<ul class="ws-menu-page-li-margins">'."\n";
|
595 |
-
echo '<li><code>download="file.zip"</code> Location of the file, relative to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; or, relative to the root of your Amazon S3 Bucket, when applicable.</li>'."\n";
|
596 |
-
echo '<li><code>download_key="no"</code> Defaults to <code>no</code>. If <code>download_key="1|on|yes|true|ip-forever|universal"</code>, s2Member will return a URL with an s2Member-generated File Download Key. You don\'t need to generate the File Download Key yourself, s2Member does it for you. If you set <code>download_key="ip-forever"</code>, the File Download Key that s2Member generates will last forever, for a specific IP Address; otherwise, by default, all File Download Keys expire after 24 hours automatically. If you set <code>download_key="universal"</code>, s2Member will generate a File Download Key that is good for anyone/everyone forever, with NO restrictions on who/where/when a file is accessed <em>(e.g. be careful with this one)</em>.</li>'."\n";
|
597 |
-
echo '<li><code>stream="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>stream="1|on|yes|true"</code>, s2Member will return a URL containing a parameter/directive, which forces the File Download to take place over the RTMP protocol if at all possible. This ONLY works when/if s2Member is configured to run with both Amazon S3/CloudFront. Please note however, it\'s better to use the example code provided in the section above, regarding: <code>JW Player and the RTMP Protocol</code>. Also note, if <code>get_streamer_json="1|on|yes|true"</code>, s2Member will automatically force <code>stream="yes"</code> for you.</li>'."\n";
|
598 |
-
echo '<li><code>inline=""</code> Defaults to <code>[empty]</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>inline="1|on|yes|true"</code>, s2Member will serve the file inline, instead of as an actual File Download. If empty, s2Member will look at your <code>Inline File Extensions</code> configuration above, and serve the file inline; if, and only if, its extension matches one found in your configuration. By default, s2Member serves all files as attachments <em>(i.e. downloads)</em>, except in the case of the <code>[s2Stream /]</code> Shortcode where this defaults to <code>yes</code>. Please read the section above regarding <code>Inline File Extensions</code> for further details. Also note, this Shortcode Attribute does NOTHING for files served via Amazon CloudFront. See the tech-notes listed in the Amazon CloudFront section for further details and workarounds.</li>'."\n";
|
599 |
-
echo '<li><code>storage=""</code> Defaults to <code>[empty]</code>. If <code>storage="local|s3|cf"</code>, s2Member will serve the file from a specific source location, based on the value of this Shortcode Attribute. For example, if you\'ve configured Amazon S3 and/or CloudFront; but, there are a few files that you want to upload locally to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; you can force s2Member to serve a file from local storage by setting <code>storage="local"</code> explicitly.</li>'."\n";
|
600 |
-
echo '<li><code>remote="no"</code> Defaults to <code>no</code>. If <code>remote="1|on|yes|true"</code>, s2Member will authenticate access to the File Download via Remote Header Authorization, instead of through your web site. This is similar to <code>.htaccess</code> protection routines of yester-year</code>. Please check the <code>Remote Authorization and Podcasting</code> section for further details about how this works.</li>'."\n";
|
601 |
-
echo '<li><code>ssl=""</code> Defaults to <code>[empty]</code>. If <code>ssl="1|on|yes|true"</code>, s2Member will generate a File Download URL with an SSL protocol <em>(i.e. the URL will start with <code>https://</code> or <code>rtmpe://</code>)</em>. If empty, s2Member will only generate a File Download URL with an SSL protocol, when/if the Post/Page/URL firing the Shortcode itself, is also being viewed over SSL. Otherwise, s2Member will use a non-SSL protocol by default.</li>'."\n";
|
602 |
-
echo '<li><code>rewrite="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>rewrite="1|on|yes|true"</code>, s2Member will generate a File Download URL that takes full advantage of s2Member\'s Advanced Mod Rewrite functionality. If you\'re running an Apache web server, or another server that supports <code>mod_rewrite</code>, we highly recommend turning this on. s2Member\'s <code>mod_rewrite</code> URLs do NOT contain query string parameters, making them more portable/compatible with other software applications and/or plugins for WordPress. If you\'re integrating with JW Player, you MUST use <code>rewrite="yes"</code>.</li>'."\n";
|
603 |
-
echo '<li><code>rewrite_base=""</code> Defaults to <code>[empty]</code>. If <code>rewrite_base="'.esc_attr(site_url("/")).'"</code>, s2Member will generate a File Download URL that takes full advantage of s2Member\'s Advanced Mod Rewrite functionality, and it will use the rewrite base URL as a prefix. This could be useful on some WordPress installations that use advanced directory structures. It could also be useful for site owners using virtual directories that point to <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code>. Note, if <code>rewrite_base</code> is set, s2Member will automatically force <code>rewrite="yes"</code> for you.</li>'."\n";
|
604 |
-
echo '<li><code>skip_confirmation="no"</code> Defaults to <code>no</code>. If <code>skip_confirmation="1|on|yes|true"</code>, s2Member will generate a File Download URL which contains a directive, telling s2Member NOT to introduce any JavaScript confirmation prompts on your site, for this File Download URL. Please note, s2Member will automatically detect links, anywhere in your content, and/or anywhere in your theme files, that contain <code>s2member_file_download</code> or <code>s2member-files</code>. Whenever a logged-in Member clicks a link that contains <code>s2member_file_download</code> or <code>s2member-files</code>, the system will politely ask the User to confirm the download using a very intuitive JavaScript confirmation prompt, which contains specific details about your configured download limitations. This way your Members will be aware of how many files they\'ve downloaded in the current period; and they\'ll be able to make a conscious decision about whether to proceed with a specific download or not.</li>'."\n";
|
605 |
-
echo '<li><code>url_to_storage_source="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>url_to_storage_source="1|on|yes|true"</code>, s2Member will generate a File Download URL which points directly to the storage source. This is only functional with Amazon S3 and/or CloudFront integrations. If you create a URL that points directly to the storage source <em>(i.e. points directly to Amazon S3 or CloudFront)</em>, s2Member will NOT be able to further authenticate the current User/Member; and, s2Member will NOT be able to count the File Download against the current User\'s account record, because the URL being generated does not pass back through s2Member at all, it points directly to the storage source. For this reason, if you set <code>url_to_storage_source="true"</code>, you should also set <code>check_user="true"</code> and <code>count_against_user="true"</code>, telling s2Member to authenticate the current User, and if authenticated, count this File Download URL against the current User\'s account record in real-time <em>(i.e. as the URL is being generated) </em>, while it still has a chance to do so. This Shortcode Attribute is useful when you stream files over the RTMP protocol; where an <code>http://</code> URL is not feasible. It also helps in situations where a 3rd-party software application will not work as intended, with s2Member\'s internal redirection to Amazon S3/CloudFront files. Important, when <code>check_user="true"</code> and/or <code>count_against_user="true"</code>, the Shortcode will return an empty and/or null object value in situations where the current User/Member does NOT have access to the file.</li>'."\n";
|
606 |
-
echo '<li><code>count_against_user="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>count_against_user="1|on|yes|true"</code>, it will automatically force <code>check_user="true"</code> as well. In other words, s2Member will authenticate the current User, and if authenticated, count this File Download URL against the current User\'s account record in real-time <em>(i.e. as the URL is being generated) </em>. This is off by default with the <code>[s2File /]</code> Shortcode. By default, s2Member will simply generate a File Download URL, and upon a User/Member clicking the URL, s2Member will authenticate the User/Member at that time, count the File Download against their account record, and serve the File Download. In other words, under normal circumstances, there is no reason to set <code>check_user="true"</code> and/or <code>count_against_user="true"</code> when generating the URL itself. However, this is a useful Shortcode Attribute when <code>url_to_storage_source="true"</code>. Please note, when <code>check_user="true"</code> and/or <code>count_against_user="true"</code>, the Shortcode will return an empty and/or null object value in situations where the current User/Member does NOT have access to the file.</li>'."\n";
|
607 |
-
echo '<li><code>check_user="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>check_user="1|on|yes|true"</code>, s2Member will authenticate the current User before allowing the File Download URL to be generated. This is off by default with the <code>[s2File /]</code> Shortcode. By default, s2Member will simply generate a File Download URL, and upon a User/Member clicking the URL, s2Member will authenticate the User/Member at that time, and serve the File Download to the User/Member. In other words, under normal circumstances, there is no reason to set <code>check_user="true"</code> and/or <code>count_against_user="true"</code> when generating the URL itself. However, this IS a useful Shortcode Attribute when <code>url_to_storage_source="true"</code>. Please note, when <code>check_user="true"</code> and/or <code>count_against_user="true"</code>, the Shortcode will return an empty and/or null object value in situations where the current User/Member does NOT have access to the file.</li>'."\n";
|
608 |
-
echo '<li><code>get_streamer_json="no"</code> Defaults to <code>no</code>. N/A with <code>[s2Stream /]</code> Shortcode. If <code>get_streamer_json="1|on|yes|true"</code>, the <code>[s2File /]</code> Shortcode will return a JSON object for JavaScript notation, making it possible to integrate the <code>[s2File /]</code> Shortcode into JavaScript routines that configure streaming media players. For further details, please review the section above: <code>JW Player & RTMP Protocol Examples</code>. Note, if you set <code>get_streamer_json="true"</code>, s2Member will automatically force <code>url_to_storage_source="true"</code> and <code>stream="true"</code>. For that reason, you should carefully review the details and warning above regarding <code>url_to_storage_source</code>. If you set <code>get_streamer_json="true"</code>, you should also set <code>check_user="true"</code> and <code>count_against_user="true"</code>.</li>'."\n";
|
609 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs_s2file_lis", get_defined_vars());
|
610 |
-
echo '</ul>'."\n";
|
611 |
-
echo '</td>'."\n";
|
612 |
-
|
613 |
-
echo '</tr>'."\n";
|
614 |
-
echo '</tbody>'."\n";
|
615 |
-
echo '</table>'."\n";
|
616 |
-
|
617 |
-
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
618 |
-
|
619 |
-
echo '<h4 style="margin:0;">Additional <code>[s2Stream /]</code> Shortcode Attributes:</h4>'."\n";
|
620 |
-
echo '<p style="margin:0;"><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/" target="_blank" rel="external">JW Player w/ <code>[s2Stream /]</code> Shortcodes</a>.</p>'."\n";
|
621 |
-
echo '<p style="margin:0;"><strong>See also:</strong> API Function <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_s2member_file_download_url()" target="_blank" rel="external">s2member_file_download_url()</a> for PHP integration.</p>'."\n";
|
622 |
-
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
623 |
-
echo '<tbody>'."\n";
|
624 |
-
echo '<tr style="padding-top:0;">'."\n";
|
625 |
-
|
626 |
-
echo '<td style="padding-top:0;">'."\n";
|
627 |
-
echo '<ul class="ws-menu-page-li-margins">'."\n";
|
628 |
-
echo '<li><code>file_download="video.mp4"</code> Location of the audio/video file, relative to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; or, relative to the root of your Amazon S3 Bucket, when applicable.</li>'."\n";
|
629 |
-
echo '<li><code>player="jwplayer-v6-rtmp"</code> Required. Current supported players in this Shortcode include: <code>jwplayer-v6</code> (works with any audio/video file, and you do NOT need to have Amazon S3 or CloudFront integrated for this to work), <code>jwplayer-v6-rtmp</code> (streams with the RTMP protocol, plus there is a full download fallback of the source file if streaming is not possible on a particular device; this requires both Amazon S3 and CloudFront integration), <code>jwplayer-v6-rtmp-only</code> (streams with the RTMP protocol only, with no access to the source file, only to the RTMP stream; this requires both Amazon S3 and CloudFront integration).</li>'."\n";
|
630 |
-
echo '<li><code>player_id=""</code> Optional. HTML div ID for the audio/video player. Defaults to a unique ID generated by s2Member for each instance of your Shortcode.</li>'."\n";
|
631 |
-
echo '<li><code>player_path="/jwplayer/jwplayer.js"</code> Required. Path to the player\'s JavaScript file (ex: <code>/jwplayer/jwplayer.js</code> — you should upload the <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">/jwplayer</a> folder to the root of your web directory).</li>'."\n";
|
632 |
-
echo '<li><code>player_{setting}=""</code> Optional. Any additional configuration attributes supported by your audio/video player, prefixed with <code>player_</code>. For JW Player v6, see <a href="http://www.longtailvideo.com/support/jw-player/28839/embedding-the-player" target="_blank" rel="external">this article please</a>. Examples: <code>player_width="480"</code>, <code>player_height="270"</code>, <code>player_title="My Video"</code>, <code>player_description="A video about something."</code>, <code>player_image="http://www.example.com/wp-content/uploads/video-preview.jpg"</code>, <code>player_mediaid="video_ei0wsx23"</code>, <code>player_autostart="true"</code>, <code>player_skin="/jwplayer/my-skin.xml"</code>, <code>player_key="my-license-key"</code>, <code>player_captions="{file:\'/assets/captions-en.vtt\',label:\'English\'}"</code> (<em>With <a href="http://www.longtailvideo.com/support/jw-player/28845/adding-video-captions" target="_blank" rel="external">Captions</a>, you can exclude the square array brackets to avoid Shortcode parsing issues. s2Member will automatically wrap your Caption objects with square array brackets.</em>). Please note that "Advanced Options Blocks" listed on <a href="http://www.longtailvideo.com/support/jw-player/28839/embedding-the-player" target="_blank" rel="external">this page</a> are NOT supported here. For those, please use: <code>player_option_blocks=""</code> (see below).</li>'."\n";
|
633 |
-
echo '<li><code>player_option_blocks=""</code> Optional. Any "Advanced Option Blocks" supported by your audio/video player. For JW Player v6, see <a href="http://www.longtailvideo.com/support/jw-player/28839/embedding-the-player" target="_blank" rel="external">this article please</a>. Here are some examples: <code>player_option_blocks="sharing:{}"</code>, <code>player_option_blocks="sharing:{}, logo: {file: \'/logo.png\', link: \'http://example.com\'}"</code>. Or: <code>player_option_blocks="c2hhcmluZzoge30="</code> (base64 encoded version of <code>sharing:{}</code>). Please note that "Advanced Options Blocks" can be defined in plain text or with a <a href="http://www.base64encode.org/" target="_blank" rel="external">base64 encoded string</a>. Advanced Option Blocks are JavaScript objects with properties. If you have trouble defining JavaScript object properties inside a Shortcode Attribute, please use <a href="http://www.base64encode.org/" target="_blank" rel="external">this tool</a> to base64 encode your Advanced Option Blocks, so that you end up with a string that\'s compatible with Shortcode Attributes.</li>'."\n";
|
634 |
-
echo '<li>Please check the <strong>Shortcode Attributes</strong> Tab in <a href="http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#using-s2stream-shortcodes" target="_blank" rel="external">this KB article</a> for further details on everything here.</li>'."\n";
|
635 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs_s2stream_lis", get_defined_vars());
|
636 |
-
echo '</ul>'."\n";
|
637 |
-
echo '</td>'."\n";
|
638 |
-
|
639 |
-
echo '</tr>'."\n";
|
640 |
-
echo '</tbody>'."\n";
|
641 |
-
echo '</table>'."\n";
|
642 |
-
|
643 |
-
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
644 |
-
|
645 |
-
echo '<h4 style="margin:0;"><code>[s2Key /]</code> Shortcode Attributes:</h4>'."\n";
|
646 |
-
echo '<p style="margin:0;"><strong>See also:</strong> API Function <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_s2member_file_download_key()" target="_blank" rel="external">s2member_file_download_key()</a> for PHP integration.</p>'."\n";
|
647 |
-
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
648 |
-
echo '<tbody>'."\n";
|
649 |
-
echo '<tr style="padding-top:0;">'."\n";
|
650 |
-
|
651 |
-
echo '<td style="padding-top:0;">'."\n";
|
652 |
-
echo '<ul class="ws-menu-page-li-margins">'."\n";
|
653 |
-
echo '<li><code>file_download="file.zip"</code> Location of the file, relative to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; or, relative to the root of your Amazon S3 Bucket, when applicable.</li>'."\n";
|
654 |
-
echo '<li><code>directive=""</code> Defaults to <code>[empty]</code>. If <code>directive="ip-forever|universal"</code>, s2Member will return a special File Download Key. If you set <code>directive="ip-forever"</code>, the File Download Key that s2Member generates will last forever, for a specific IP Address; otherwise, by default, all File Download Keys expire after 24 hours automatically. If you set <code>directive="universal"</code>, s2Member will generate a File Download Key that is good for anyone/everyone forever, with NO restrictions on who/where/when a file is accessed <em>(e.g. be careful with this one)</em>.</li>'."\n";
|
655 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs_s2key_lis", get_defined_vars());
|
656 |
-
echo '</ul>'."\n";
|
657 |
-
echo '</td>'."\n";
|
658 |
-
|
659 |
-
echo '</tr>'."\n";
|
660 |
-
echo '</tbody>'."\n";
|
661 |
-
echo '</table>'."\n";
|
662 |
-
echo '</div>'."\n";
|
663 |
-
|
664 |
-
echo '</div>'."\n";
|
665 |
-
|
666 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_shortcode_attrs", get_defined_vars());
|
667 |
-
}
|
668 |
-
|
669 |
-
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_gzip_conflicts", true, get_defined_vars()))
|
670 |
-
{
|
671 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_gzip_conflicts", get_defined_vars());
|
672 |
-
|
673 |
-
echo '<div class="ws-menu-page-group" title="Preventing GZIP Conflicts On Server">'."\n";
|
674 |
-
|
675 |
-
echo '<div class="ws-menu-page-section ws-plugin--s2member-gzip-conflicts-section">'."\n";
|
676 |
-
echo '<h3>Preventing GZIP Conflicts On Server (Instructions)</h3>'."\n";
|
677 |
-
echo '<p>Protected files served by s2Member through PHP scripts, are already compressed. Therefore, <a href="http://code.google.com/speed/articles/gzip.html" target="_blank" rel="nofollow external xlink">GZIP compression</a> is not needed during protected file delivery. Some web servers (i.e. Apache, LiteSpeed, and similar) include GZIP compression rules through server-side extensions, like <code>mod_deflate</code> for example. While s2Member encourages the use of extensions like <code>mod_deflate</code>, it is best to disable GZIP automatically (i.e. temporarily) during s2Member\'s delivery of a protected file through a PHP script. This avoids conflicts on the server which might otherwise lead to corrupted file downloads. s2Member makes a valiant effort to accomplish this via PHP, all on its own. However, it never hurts to add this section of code to the root <code>.htaccess</code> file for your WordPress installation. Optional, but highly recommended.</p>'."\n";
|
678 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_gzip_conflicts", get_defined_vars());
|
679 |
-
|
680 |
-
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
681 |
-
|
682 |
-
echo '<p style="margin:0; font-weight:bold;">s2Member automatically adds this to your <code>.htaccess</code> file upon activation of the plugin.</p>'."\n";
|
683 |
-
echo '<p style="margin:0;">The following <code>mod_rewrite</code> rule goes inside this file: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path(ABSPATH.".htaccess")).'</code></p>'."\n";
|
684 |
-
echo '<pre class="code"><code>'.esc_html(trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_no_gzip_htaccess"])))).'</code></pre>';
|
685 |
-
echo '<p><strong>* Tip:</strong> this covers all types of integration with s2Member File Downloads, even if you\'re using s2Member\'s Advanced Mod Rewrite Linkage.</p>'."\n";
|
686 |
-
|
687 |
-
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
688 |
-
|
689 |
-
echo '<table class="form-table">' . "\n";
|
690 |
-
echo '<tbody>' . "\n";
|
691 |
-
echo '<tr>' . "\n";
|
692 |
-
|
693 |
-
echo '<th>' . "\n";
|
694 |
-
echo '<label for="ws-plugin--s2member-file-download-content-encodong-none">' . "\n";
|
695 |
-
echo 'Also Force a <code>Content-Encoding: none</code> Header?' . "\n";
|
696 |
-
echo '</label>' . "\n";
|
697 |
-
echo '</th>' . "\n";
|
698 |
-
|
699 |
-
echo '</tr>' . "\n";
|
700 |
-
echo '<tr>' . "\n";
|
701 |
-
|
702 |
-
echo '<td>' . "\n";
|
703 |
-
echo '<select name="ws_plugin__s2member_file_download_content_encodong_none" id="ws-plugin--s2member-file-download-content-encodong-none">' . "\n";
|
704 |
-
echo '<option value="0"' . ((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_content_encodong_none"]) ? ' selected="selected"' : '') . '>No (remain standards-compliant; I will configure my server properly)</option>' . "\n";
|
705 |
-
echo '<option value="1"' . (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_content_encodong_none"]) ? ' selected="selected"' : '') . '>Yes (my web server is stubborn; downloads are corrupted without this)</option>' . "\n";
|
706 |
-
echo '</select>' . "\n";
|
707 |
-
echo '</td>' . "\n";
|
708 |
|
709 |
-
|
710 |
-
|
711 |
-
echo '</table>' . "\n";
|
712 |
|
713 |
-
|
714 |
-
|
|
|
|
|
|
|
|
|
715 |
|
716 |
-
|
|
|
|
|
717 |
|
718 |
-
|
719 |
-
|
720 |
|
721 |
-
|
722 |
-
{
|
723 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_custom_capability_files", get_defined_vars ());
|
724 |
|
725 |
-
|
|
|
|
|
|
|
|
|
726 |
|
727 |
-
|
728 |
-
echo '<h3>Restricting Files, Based On Custom Capabilities</h3>' . "\n";
|
729 |
-
echo '<p>If you\'re NOT familiar with Custom Capabilities yet, please read: <code>Dashboard -› s2Member -› API Scripting -› Custom Capability Packages</code>. Once you understand the basic concept of Custom Capabilities & Protected File Downloads, you\'ll see that (by default) s2Member does NOT handle File Download Protection with respect to Custom Capabilities. That\'s where Custom Capability Sub-directories come in.</p>' . "\n";
|
730 |
-
echo '<p>You can create Custom Capability Sub-directories under: <code>' . esc_html (c_ws_plugin__s2member_utils_dirs::doc_root_path ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '</code>. For instance, if you have a Custom Capability <code>music</code>, you can place protected files that should ONLY be accessible to Members with <code>access_s2member_ccap_music</code>, inside: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-ccap-music/</code>. Some examples are provided below.</p>' . "\n";
|
731 |
-
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_custom_capability_files", get_defined_vars ());
|
732 |
|
733 |
-
|
|
|
|
|
|
|
|
|
734 |
|
735 |
-
|
736 |
-
echo '<p>Sub-Directory: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-ccap-music</code><br />Sub-Directory: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-ccap-videos</code></p>' . "\n";
|
737 |
-
echo '<p>Protected File: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-ccap-music/file.mp3</code><br />Protected File: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-ccap-videos/file.avi</code></p>' . "\n";
|
738 |
-
echo '<p>Now, here are some link examples, using Custom Capability Sub-directories:</p>' . "\n";
|
739 |
-
echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/ccap-file-downloads.x-php")) . '</p>' . "\n";
|
740 |
-
echo '<p><em>These links will ONLY work for Members who are logged-in, with the proper Capabilities.</em></p>' . "\n";
|
741 |
|
742 |
-
|
|
|
|
|
|
|
|
|
|
|
743 |
|
744 |
-
|
745 |
-
echo '<p>Sub-Directory: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level0</code><br />Sub-Directory: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level1</code><br />Sub-Directory: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level2</code><br />Sub-Directory: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level3</code><br />Sub-Directory: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level4</code></p>' . "\n";
|
746 |
-
echo '<p>Protected File: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level0/tiger.doc</code><br />Protected File: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level1/zebra.pdf</code><br />Protected File: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level2/elephant.doc</code><br />Protected File: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level3/rhino.pdf</code><br />Protected File: <code>/' . esc_html (c_ws_plugin__s2member_utils_dirs::basename_dir_app_data ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])) . '/access-s2member-level4/lion.doc</code></p>' . "\n";
|
747 |
-
echo '<p>Now, here are some link examples, using Member Level Sub-directories:</p>' . "\n";
|
748 |
-
echo '<p>' . c_ws_plugin__s2member_utils_strings::highlight_php (file_get_contents (dirname (__FILE__) . "/code-samples/level-file-downloads.x-php")) . '</p>' . "\n";
|
749 |
-
echo '<p><em>These links will ONLY work for Members who are logged-in, with an adequate Membership Level.</em></p>' . "\n";
|
750 |
-
echo '</div>' . "\n";
|
751 |
|
752 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
753 |
|
754 |
-
|
755 |
-
}
|
756 |
|
757 |
-
|
|
|
|
|
758 |
|
759 |
-
|
760 |
|
761 |
-
|
762 |
|
763 |
-
|
764 |
|
765 |
-
|
766 |
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
|
775 |
-
|
776 |
-
|
777 |
-
}
|
778 |
}
|
|
|
779 |
|
780 |
-
new c_ws_plugin__s2member_menu_page_down_ops();
|
781 |
-
?>
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Menu page for the s2Member plugin (File Download Options page).
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Menu_Pages
|
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 |
+
{
|
22 |
+
/**
|
23 |
+
* Menu page for the s2Member plugin (File Download Options page).
|
24 |
+
*
|
25 |
+
* @package s2Member\Menu_Pages
|
26 |
+
* @since 110531
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_menu_page_down_ops
|
29 |
{
|
30 |
+
public function __construct()
|
31 |
+
{
|
32 |
+
echo '<div class="wrap ws-menu-page">'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
+
echo '<div class="ws-menu-page-toolbox">'."\n";
|
35 |
+
c_ws_plugin__s2member_menu_pages_tb::display();
|
36 |
+
echo '</div>'."\n";
|
37 |
|
38 |
+
echo '<h2>Download Options</h2>'."\n";
|
39 |
|
40 |
+
echo '<table class="ws-menu-page-table">'."\n";
|
41 |
+
echo '<tbody class="ws-menu-page-table-tbody">'."\n";
|
42 |
+
echo '<tr class="ws-menu-page-table-tr">'."\n";
|
43 |
+
echo '<td class="ws-menu-page-table-l">'."\n";
|
44 |
|
45 |
+
echo '<form method="post" name="ws_plugin__s2member_options_form" id="ws-plugin--s2member-options-form" action="'.esc_attr(remove_query_arg('ws_plugin__s2member_cf_options_reset')).'">'."\n";
|
46 |
+
echo '<input type="hidden" name="ws_plugin__s2member_options_save" id="ws-plugin--s2member-options-save" value="'.esc_attr(wp_create_nonce("ws-plugin--s2member-options-save")).'" />'."\n";
|
47 |
+
echo '<input type="hidden" name="ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" id="ws-plugin--s2member-amazon-cf-files-distros-auto-config-status" value="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_auto_config_status"]).'" />'."\n";
|
48 |
+
echo '<input type="hidden" name="ws_plugin__s2member_configured" id="ws-plugin--s2member-configured" value="1" />'."\n";
|
49 |
|
50 |
+
do_action("ws_plugin__s2member_during_down_ops_page_before_left_sections", get_defined_vars());
|
51 |
|
52 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_restrictions", TRUE, get_defined_vars()))
|
53 |
+
{
|
54 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_restrictions", get_defined_vars());
|
55 |
|
56 |
+
echo '<div class="ws-menu-page-group" title="Basic Download Restrictions">'."\n";
|
57 |
|
58 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-restrictions-section">'."\n";
|
59 |
+
echo '<h3>File Download Restrictions (required, if providing access to protected files)</h3>'."\n";
|
60 |
+
echo '<p>If your Membership offering allows access to restricted files, you\'ll want to configure these options.</p>'."\n";
|
61 |
+
echo '<p class="info" style="font-size:100%;"><strong>NOTE:</strong> If you intend to offer File Downloads in one way or another, you must configure at least one of the options below. For security purposes, s2Member\'s File Download functionality is disabled unless & until at least one of the options below have been configured; i.e. s2Member expects you to configure Basic Downloads for at least one Membership Level before any sort of download-related functionality will work. This includes functionality associated with the <code>[s2File /]</code> & <code>[s2Stream /]</code> Shortcodes also.</p>'."\n";
|
62 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_restrictions", get_defined_vars());
|
63 |
|
64 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
65 |
|
66 |
+
echo '<p><strong>Upload restricted files to this security-enabled directory:</strong><br /><code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'</code></p>'."\n";
|
67 |
+
echo '<p>- Now, you can link to any protected file, using this special format:<br /> <code>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'</code><br /> <small><em><strong>s2member_file_download</strong> = file, relative to the /'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/ directory. In other words, just the file name.</em></small></p>'."\n";
|
68 |
+
echo '<p>- Or, use: <code>[s2File download="example-file.zip" /]</code> <em>(easier Shortcode if you prefer)</em><br /> <small><em><strong>Shortcode equivalent:</strong> <code>[s2File /]</code> produces the entire URL for you, easier.</em></small></p>'."\n";
|
69 |
|
70 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
71 |
|
72 |
+
echo '<p>s2Member will allow access to these protected files, based on the configuration you specify below. Repeated downloads of the same exact file are NOT tabulated against the totals below. Once a file has been downloaded, future downloads of the same exact file, by the same exact Member will not be counted against them. In other words, if a Member downloads the same file three times, the system only counts that as one unique download. In addition, multiple variations of popular media formats are only counted once. This is because many site owners provide multiple download options to their Users/Members, for compatibility purposes. Files that have the same exact name, with one of these extensions, will only be counted ONE time: <code>'.esc_html(implode(",", $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["streaming_file_extns"])).'</code>.</p>'."\n";
|
73 |
+
echo '<p>s2Member will automatically detect links, anywhere in your content, and/or anywhere in your theme files, that contain <code>s2member_file_download</code> or <code>s2member-files</code>. Whenever a logged-in Member clicks a link that contains <code>s2member_file_download</code> or <code>s2member-files</code>, the system will politely ask the user to confirm the download using a very intuitive JavaScript confirmation prompt, which contains specific details about your configured download limitations. This way your Members will be aware of how many files they\'ve downloaded in the current period; and they\'ll be able to make a conscious decision about whether to proceed with a specific download or not. If you want to suppress this JavaScript confirmation prompt, you can add this to the end of your links: <code>&s2member_skip_confirmation</code>. Shortcode alternative: <code>[s2File skip_confirmation="yes" /]</code>.</p>'."\n";
|
74 |
+
echo '<p><em>* The above only applies to Users who are logged in as Members. For all other visitors in the general public, the <code>?s2member_file_download</code> links will redirect them your Membership Options Page, so that new visitors can signup, in order to gain access, by becoming a Member. You may also want to have a look down below at s2Member\'s "Advanced Download Restrictions", which provides a greater degree of flexibility.</em></p>'."\n";
|
75 |
|
76 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
77 |
|
78 |
+
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
79 |
+
echo '<tbody>'."\n";
|
80 |
|
81 |
+
for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++)
|
82 |
+
{
|
83 |
+
echo '<tr>'."\n";
|
84 |
|
85 |
+
echo '<th style="padding-top:0;">'."\n";
|
86 |
+
echo '<label for="ws-plugin--s2member-level'.$n.'-file-downloads-allowed">'."\n";
|
87 |
+
echo ($n === $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]) ? 'File Downloads ( Highest Level #'.$n.' ):'."\n" : 'File Downloads (Level #'.$n.' Or Higher):'."\n";
|
88 |
+
echo '</label>'."\n";
|
89 |
+
echo '</th>'."\n";
|
90 |
|
91 |
+
echo '</tr>'."\n";
|
92 |
+
echo '<tr>'."\n";
|
93 |
|
94 |
+
echo '<td>'."\n";
|
95 |
+
echo '<input type="text" maxlength="9" autocomplete="off" name="ws_plugin__s2member_level'.$n.'_file_downloads_allowed" id="ws-plugin--s2member-level'.$n.'-file-downloads-allowed" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_file_downloads_allowed"]).'" style="width:200px;" /> every <input type="text" maxlength="3" autocomplete="off" name="ws_plugin__s2member_level'.$n.'_file_downloads_allowed_days" id="ws-plugin--s2member-level'.$n.'-file-downloads-allowed-days" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level".$n."_file_downloads_allowed_days"]).'" style="width:200px;" onkeyup="if(this.value > 365){ alert(\'(365 days is the maximum).\\nThis keeps the logs optimized.\'); this.value = 365; }" /> day(s).<br />'."\n";
|
96 |
+
echo 'Only this many unique downloads will be permitted every X day(s), at '.(($n === $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]) ? 'highest Level #'.$n : 'Level #'.$n.' or higher').'.<br />'."\n";
|
97 |
+
echo '<em>* To allow UNLIMITED downloads, use: <code>999999999</code> (i.e. <code>999999999</code> = unlimited).</em>'."\n";
|
98 |
+
echo '</td>'."\n";
|
99 |
|
100 |
+
echo '</tr>'."\n";
|
101 |
|
102 |
+
echo ($n < $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]) ? '<tr><td><div class="ws-menu-page-hr" style="margin:10px 0 10px 0;"></div></td></tr>' : '';
|
103 |
+
}
|
104 |
+
echo '</tbody>'."\n";
|
105 |
+
echo '</table>'."\n";
|
106 |
+
echo '</div>'."\n";
|
107 |
|
108 |
+
echo '</div>'."\n";
|
|
|
|
|
109 |
|
110 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_restrictions", get_defined_vars());
|
111 |
+
}
|
112 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_limit_exceeded_page", TRUE, get_defined_vars()))
|
113 |
+
{
|
114 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_limit_exceeded_page", get_defined_vars());
|
115 |
|
116 |
+
echo '<div class="ws-menu-page-group" title="Download Limit Exceeded Page">'."\n";
|
|
|
117 |
|
118 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-limit-exceeded-page-section">'."\n";
|
119 |
+
echo '<h3>Download Limit Exceeded Page (required, if providing access to protected files)</h3>'."\n";
|
120 |
+
echo '<p>This Page will be shown when/if a Member reaches their download limit, based on your configuration of <strong>Basic Download Restrictions</strong> above. This Page should be created by you, in WordPress. This Page should provide an informative message to the Member, describing your file access restrictions. Just tell them a little bit about your policy on file downloads, and why they might have reached this Page.</p>'."\n";
|
121 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_limit_exceeded_page", get_defined_vars());
|
122 |
|
123 |
+
echo '<table class="form-table">'."\n";
|
124 |
+
echo '<tbody>'."\n";
|
125 |
+
echo '<tr>'."\n";
|
126 |
|
127 |
+
echo '<th>'."\n";
|
128 |
+
echo '<label for="ws-plugin--s2member-file-download-limit-exceeded-page">'."\n";
|
129 |
+
echo 'Download Limit Exceeded Page:'."\n";
|
130 |
+
echo '</label>'."\n";
|
131 |
+
echo '</th>'."\n";
|
132 |
|
133 |
+
echo '</tr>'."\n";
|
134 |
+
echo '<tr>'."\n";
|
|
|
135 |
|
136 |
+
echo '<td>'."\n";
|
137 |
+
echo '<select name="ws_plugin__s2member_file_download_limit_exceeded_page" id="ws-plugin--s2member-file-download-limit-exceeded-page">'."\n";
|
138 |
+
echo '<option value="">— Select —</option>'."\n";
|
139 |
+
foreach(($ws_plugin__s2member_temp_a = array_merge((array)get_pages())) as $ws_plugin__s2member_temp_o)
|
140 |
+
echo '<option value="'.esc_attr($ws_plugin__s2member_temp_o->ID).'"'.(($ws_plugin__s2member_temp_o->ID == $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_limit_exceeded_page"]) ? ' selected="selected"' : '').'>'.esc_html($ws_plugin__s2member_temp_o->post_title).'</option>'."\n";
|
141 |
+
echo '</select><br />'."\n";
|
142 |
+
echo 'We recommend the following title: <code>Download Limit Exceeded</code>.'."\n";
|
143 |
+
echo '</td>'."\n";
|
144 |
|
145 |
+
echo '</tr>'."\n";
|
146 |
+
echo '</tbody>'."\n";
|
147 |
+
echo '</table>'."\n";
|
148 |
+
echo '</div>'."\n";
|
149 |
|
150 |
+
echo '</div>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
|
152 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_limit_exceeded_page", get_defined_vars());
|
153 |
+
}
|
154 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_advanced_restrictions", TRUE, get_defined_vars()))
|
155 |
+
{
|
156 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_advanced_restrictions", get_defined_vars());
|
157 |
|
158 |
+
echo '<div class="ws-menu-page-group" title="Advanced Download Restrictions">'."\n";
|
159 |
|
160 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-restrictions-section">'."\n";
|
161 |
+
echo '<h3>Advanced Download Restrictions (optional, for greater flexibility)</h3>'."\n";
|
162 |
+
echo '<p>By default, s2Member uses your Basic Download Restrictions, as configured above. However, you can force s2Member to allow File Downloads, using an extra query string parameter: <code>&s2member_file_download_key=[Key]</code>. A File Download `Key` is passed through this parameter; it tells s2Member to allow the download of this particular file, regardless of Membership Level; and WITHOUT checking any Basic Restrictions, that you may or may not have configured above. The creation of a File Download `Key`, requires a small PHP code snippet. In order to use PHP scripting inside your Posts/Pages, you\'ll need to install this handy plugin (<a href="http://wordpress.org/extend/plugins/ezphp/" target="_blank" rel="external">ezPHP</a>). There is also a Shortcode equivalent, which does NOT require PHP at all, as seen below.</p>'."\n";
|
163 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_advanced_restrictions", get_defined_vars());
|
164 |
|
165 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
166 |
|
167 |
+
echo '<p>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'<code>&s2member_file_download_key=<?php echo s2member_file_download_key("example-file.zip"); ?></code><br /> <small><em><strong>s2member_file_download_key</strong> = <?php echo s2member_file_download_key("file, relative to the /'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/ directory"); ?></em></small></p>'."\n";
|
168 |
|
169 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
|
|
170 |
|
171 |
+
echo '<p>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'<code>&s2member_file_download_key=[s2Key file_download="example-file.zip" /]</code><br /> <small><em><strong>Shortcode equivalent:</strong> <code>[s2Key file_download="example-file.zip" /]</code></em></small></p>'."\n";
|
172 |
|
173 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
174 |
|
175 |
+
echo '<p><code>[s2File download="example-file.zip" download_key="true" /]</code> <em>(Key is auto-generated in this case)</em><br /> <small><em><strong>Shortcode equivalent:</strong> <code>[s2File /]</code> produces the entire URL, no need to generate a Key yourself.</em></small></p>'."\n";
|
176 |
|
177 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
178 |
|
179 |
+
echo '<p>The function <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_s2member_file_download_key()" target="_blank" rel="external">s2member_file_download_key()</a>, is part of the s2Member API. It produces a time-sensitive File Download Key that is unique to each and every visitor. Each Key it produces <em>(at the time it is produced)</em>, will be valid for the current day, and only for a specific IP address and User-Agent string; as detected by s2Member. This makes it possible for you to create links on your site, which provide access to protected file downloads; and without having to worry about one visitor sharing their link with another. So let\'s take a quick look at what <code>s2member_file_download_key()</code> actually produces.</p>'."\n";
|
180 |
+
echo '<p><code>s2member_file_download_key("example-file.zip")</code> = a site-specific hash of: <code>date("Y-m-d").$_SERVER["REMOTE_ADDR"].$_SERVER["HTTP_USER_AGENT"].$file</code></p>'."\n";
|
181 |
+
echo '<p>When <code>s2member_file_download_key = <em>a valid Key</em></code>, it works independently from Member Level Access. That is, a visitor does NOT have to be logged in to receive access; they just need a valid Key. Using this advanced technique, you could extend s2Member\'s file protection routines, or even combine them with Specific Post/Page Access, and more. The possibilities are limitless really.</p>'."\n";
|
182 |
|
183 |
+
echo '</div>'."\n";
|
184 |
|
185 |
+
echo '</div>'."\n";
|
186 |
|
187 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_advanced_restrictions", get_defined_vars());
|
188 |
+
}
|
189 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_inline_extensions", TRUE, get_defined_vars()))
|
190 |
+
{
|
191 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_inline_extensions", get_defined_vars());
|
192 |
|
193 |
+
echo '<div class="ws-menu-page-group" title="Inline File Extensions">'."\n";
|
194 |
|
195 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-inline-extensions-section">'."\n";
|
196 |
+
echo '<h3>Inline File Extensions (optional, for content-disposition)</h3>'."\n";
|
197 |
+
echo '<p>There are two ways to serve files. Inline, or as an Attachment. By default, s2Member will serve all of your protected files, as downloadable attachments. Meaning, visitors will be given a file download prompt. Otherwise known as <code>Content-Disposition: attachment</code>. In some cases though, you may wish to serve files inline. For example, PDF files and images should usually be served inline. When you serve a file inline, it is displayed in your browser immediately, rather than your browser prompting you to download the file as an attachment.</p>'."\n";
|
198 |
+
echo '<p>Using the field below, you can list all of the extensions that you want s2Member to serve inline (ex: <code>htm,html,pdf,jpg,jpeg,jpe,gif,png,mp3,mp4,flv,ogg,webm</code>). Please understand, some files just cannot be displayed inline. For instance, there is no way to display an <code>exe</code> file inline. So only specify extensions that can, and should be displayed inline by a web browser. Alternatively, if you would rather handle this on a case-by-case basis, you can simply add the following to the end of your download links: <code>&s2member_file_inline=yes</code>. Shortcode alternative: <code>[s2File download="example-file.zip" inline="yes" /]</code>.</p>'."\n";
|
199 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_inline_extensions", get_defined_vars());
|
200 |
|
201 |
+
echo '<table class="form-table">'."\n";
|
202 |
+
echo '<tbody>'."\n";
|
203 |
+
echo '<tr>'."\n";
|
204 |
|
205 |
+
echo '<th>'."\n";
|
206 |
+
echo '<label for="ws-plugin--s2member-file-download-inline-extensions">'."\n";
|
207 |
+
echo 'Default Inline File Extensions (comma-delimited):'."\n";
|
208 |
+
echo '</label>'."\n";
|
209 |
+
echo '</th>'."\n";
|
210 |
|
211 |
+
echo '</tr>'."\n";
|
212 |
+
echo '<tr>'."\n";
|
213 |
|
214 |
+
echo '<td>'."\n";
|
215 |
+
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_file_download_inline_extensions" id="ws-plugin--s2member-file-download-inline-extensions" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_inline_extensions"]).'" /><br />'."\n";
|
216 |
+
echo 'Inline extensions, comma-delimited. Ex: <code>htm,html,pdf,jpg,jpeg,jpe,gif,png,mp3,mp4,flv,ogg,webm</code>'."\n";
|
217 |
+
echo '</td>'."\n";
|
|
|
218 |
|
219 |
+
echo '</tr>'."\n";
|
220 |
+
echo '</tbody>'."\n";
|
221 |
+
echo '</table>'."\n";
|
222 |
+
echo '</div>'."\n";
|
223 |
|
224 |
+
echo '</div>'."\n";
|
|
|
|
|
|
|
|
|
225 |
|
226 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_inline_extensions", get_defined_vars());
|
227 |
+
}
|
228 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_remote_authorization", TRUE, get_defined_vars()))
|
229 |
+
{
|
230 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_remote_authorization", get_defined_vars());
|
231 |
|
232 |
+
echo '<div class="ws-menu-page-group" title="Remote Auth / Podcasting">'."\n";
|
|
|
|
|
|
|
233 |
|
234 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-remote-authorization-section">'."\n";
|
235 |
+
echo '<h3>Remote Header Authorization (optional)</h3>'."\n";
|
236 |
+
echo '<p>This can be enabled on a case-by-case basis. Just add this to the end of your download links: <code>&s2member_file_remote=yes</code></p>'."\n";
|
237 |
+
echo '<p>Shortcode alternative: <code>[s2File download="example-file.zip" remote="yes" /]</code></p>'."\n";
|
238 |
+
echo '<p>Remote Header Authorization allows access to file downloads through an entirely different approach. Instead of asking the Member to log into your site through a browser, a Member will be prompted automatically, to log in through HTTP Header Authorization prompts; which is the same technique used in more traditional security systems via .htaccess files. In other words, Remote Header Authorization makes it possible for your Members to access files through remote applications that may NOT use a browser. This is often the case when a Member needs to access protected files through a software client like iTunes; typical with podcasts. See <a href="http://www.s2member.com/videos/71F49478D6983A9C/" target="_blank" rel="external">tutorial video here</a> for details about how to setup a Podcast for iTunes.</p>'."\n";
|
239 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_remote_authorization", get_defined_vars());
|
240 |
+
echo '</div>'."\n";
|
241 |
|
242 |
+
echo '</div>'."\n";
|
243 |
|
244 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_remote_authorization", get_defined_vars());
|
245 |
+
}
|
246 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_amazon_s3", TRUE, get_defined_vars()))
|
247 |
+
{
|
248 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_amazon_s3", get_defined_vars());
|
249 |
|
250 |
+
echo '<div class="ws-menu-page-group" title="Amazon S3/CDN Storage Option"'.((!empty(c_ws_plugin__s2member_menu_pages::$pre_display_errors["cf_files_auto_configure_distros"])) ? ' default-state="open"' : '').'>'."\n";
|
|
|
|
|
251 |
|
252 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-amazon-s3-section">'."\n";
|
253 |
+
echo '<h3>Amazon S3/CDN Storage & Delivery (optional)</h3>'."\n";
|
254 |
+
echo '<a href="http://aws.amazon.com/s3/" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/amazon-logo.png" class="ws-menu-page-right" style="width:250px; height:100px; border:0;" alt="." /></a>'."\n";
|
255 |
+
echo '<p>Please note, all of this is optional. s2Member can be configured here to ONLY use Amazon S3 <em>(i.e. without Amazon CloudFront)</em>. Or, s2Member can be configured to use BOTH Amazon S3 and Amazon CloudFront together. If you want to use Amazon S3 Storage, but you don\'t care about Amazon CloudFront, feel free to leave the entire Amazon CloudFront section empty. The configuration options in the Amazon CloudFront section are ONLY required if you are planning to use both Amazon S3 and Amazon CloudFront together.</p>'."\n";
|
256 |
+
echo '<p>Amazon Simple Storage Service (<a href="http://aws.amazon.com/s3/" target="_blank" rel="external">Amazon S3</a>). Amazon S3 is storage for the Internet. It is designed to make web-scale computing easier for developers. Amazon S3 provides a simple web services interface that can be used to store and retrieve any amount of data, at any time, from anywhere on the web. It gives developers access to the same highly scalable, reliable, secure, fast, inexpensive infrastructure that Amazon uses to run its own global network of web sites. s2Member has been integrated with Amazon S3, so that <em>(if you wish)</em>, instead of using the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory, you can store all of your protected files inside an Amazon S3 Bucket.</p>'."\n";
|
257 |
+
echo '<p>If you configure the options below, s2Member will assume all protected files are inside your Amazon S3 Bucket; and the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory is no longer used at all. That being said, all other aspects of s2Member\'s File Download protection remain the same. The only thing that changes, is the location of your protected files. In other words, Basic Download Restrictions, Download Keys, Inline Extensions, Custom Capability and/or Membership Level Files will all continue to work just as before. The only difference is that s2Member will use your Amazon S3 Bucket as a CDN <em>(i.e. Content Delivery Network)</em> instead of the local <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory.</p>'."\n";
|
258 |
+
echo '<p>s2Member assumes that you\'re creating a new Amazon S3 Bucket, specifically for this installation; and that your Bucket is NOT available publicly. In other words, if you type this URL into your browser <em>(i.e. <code>http://your-bucket-name.s3.amazonaws.com/</code>)</em>, you should get an error that says: <code>Access Denied</code>. That\'s good, that\'s exactly what you want. You can create your Amazon S3 Bucket using the <a href="https://console.aws.amazon.com/s3/home" target="_blank" rel="external">Amazon interface</a>. Or, some people prefer to use this popular Firefox extension (<a href="http://www.s3fox.net/" target="_blank" rel="external">S3 Fox Organizer</a>).</p>'."\n";
|
259 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_amazon_s3", get_defined_vars());
|
260 |
|
261 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
|
|
|
|
|
|
262 |
|
263 |
+
echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member uses "Digitally Signed URLs", authenticated by the Amazon S3 API. Documented for developers <a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAuthentication.html" target="_blank" rel="external">here</a>. To put it simply, s2Member will generate Amazon S3 URLs (internally); which allow Customers temporary access to specific files inside your S3 Bucket. s2Member\'s Digitally Signed URLs leading to Amazon S3, give a Customer 24 hours to connect to the file inside your S3 Bucket. This connection period of 24 hours is largely irrelevant when used in combination with s2Member, because access is renewed for another 24 hours each time you make a file available to a User/Member, and they are authenticated by your configuration of s2Member. This connection period of 24 hours is just a secondary line of defense to further prevent the possibility of link sharing. If you need to change this connection timeout of <code>24 hours</code> for some reason (not likely), you can use this WordPress Filter: <code>ws_plugin__s2member_amazon_s3_file_expires_time</code>.</em></p>'."\n";
|
264 |
+
echo '<p><em><strong>Linking To Protected Files:</strong> Nothing changes. s2Member\'s integration with Amazon S3 serves protected files through the same links that all s2Member site owners use. For example, you might use: <code>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'</code>, where <strong>s2member_file_download</strong> = the file, relative to the root of your Amazon S3 Bucket. In other words, just the file name in most cases. s2Member will redirect Users/Members to a digitally signed Amazon S3 URL, which allows them access to a particular file via Amazon S3. For further details, please review this section of your Dashboard: <code>s2Member -› Download Options -› Basic Download Restrictions</code>. Also see: <code>s2Member -› Download Options -› Advanced Mod-Rewrite Linkage</code>.</em></p>'."\n";
|
265 |
+
echo '<p><em><strong>Content Type, Disposition & Inline Files:</strong> The query string parameter <code>&s2member_file_inline=yes</code> DOES work for files served directly through Amazon S3. s2Member DOES have control over the <code>Content-Type</code> and <code>Content-Disposition</code> headers for files being served through Amazon S3. However, Amazon CloudFront servers do NOT automatically determine the MIME type for the objects they serve. If you integrate both Amazon S3 and CloudFront, s2Member will NOT have control over headers. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. Again, with the Amazon S3/CloudFront combination, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
|
266 |
|
267 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
268 |
|
269 |
+
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
270 |
+
echo '<tbody>'."\n";
|
271 |
+
echo '<tr>'."\n";
|
272 |
|
273 |
+
echo '<th style="padding-top:0;">'."\n";
|
274 |
+
echo '<label for="ws-plugin--s2member-amazon-s3-files-bucket">'."\n";
|
275 |
+
echo 'Amazon S3 File Bucket Name (where protected files are):'."\n";
|
276 |
+
echo '</label>'."\n";
|
277 |
+
echo '</th>'."\n";
|
278 |
|
279 |
+
echo '</tr>'."\n";
|
280 |
+
echo '<tr>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
|
282 |
+
echo '<td>'."\n";
|
283 |
+
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_s3_files_bucket" id="ws-plugin--s2member-amazon-s3-files-bucket" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"]).'" /><br />'."\n";
|
284 |
+
echo 'Your Amazon S3 Bucket will be used, instead of the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory.<br />'."\n";
|
285 |
+
echo 'Please type the name of your Bucket. Ex: <code>mys3bucket</code>'."\n";
|
286 |
+
echo '</td>'."\n";
|
287 |
|
288 |
+
echo '</tr>'."\n";
|
289 |
+
echo '<tr>'."\n";
|
|
|
290 |
|
291 |
+
echo '<th>'."\n";
|
292 |
+
echo '<label for="ws-plugin--s2member-amazon-s3-files-access-key">'."\n";
|
293 |
+
echo 'Amazon Access Key (Access Key ID):'."\n";
|
294 |
+
echo '</label>'."\n";
|
295 |
+
echo '</th>'."\n";
|
296 |
|
297 |
+
echo '</tr>'."\n";
|
298 |
+
echo '<tr>'."\n";
|
|
|
299 |
|
300 |
+
echo '<td>'."\n";
|
301 |
+
echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_amazon_s3_files_access_key" id="ws-plugin--s2member-amazon-s3-files-access-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"]).'" /><br />'."\n";
|
302 |
+
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› Access Keys</code><br />'."\n";
|
303 |
+
echo '<em><small>Amazon suggests creating a new IAM user. Use the Keys for that IAM user here.</small></em>'."\n";
|
304 |
+
echo '</td>'."\n";
|
305 |
|
306 |
+
echo '</tr>'."\n";
|
307 |
+
echo '<tr>'."\n";
|
308 |
|
309 |
+
echo '<th>'."\n";
|
310 |
+
echo '<label for="ws-plugin--s2member-amazon-s3-files-secret-key">'."\n";
|
311 |
+
echo 'Amazon Secret Key (Secret Access Key):'."\n";
|
312 |
+
echo '</label>'."\n";
|
313 |
+
echo '</th>'."\n";
|
314 |
|
315 |
+
echo '</tr>'."\n";
|
316 |
+
echo '<tr>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
|
318 |
+
echo '<td>'."\n";
|
319 |
+
echo '<input type="password" autocomplete="off" name="ws_plugin__s2member_amazon_s3_files_secret_key" id="ws-plugin--s2member-amazon-s3-files-secret-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"]).'" /><br />'."\n";
|
320 |
+
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› Access Keys</code><br />'."\n";
|
321 |
+
echo '</td>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
|
323 |
+
echo '</tr>'."\n";
|
324 |
+
echo '</tbody>'."\n";
|
325 |
+
echo '</table>'."\n";
|
326 |
+
echo '</div>'."\n";
|
327 |
|
328 |
+
echo '</div>'."\n";
|
|
|
329 |
|
330 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_amazon_s3", get_defined_vars());
|
331 |
+
}
|
332 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_amazon_cf", TRUE, get_defined_vars()))
|
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"'.((!empty(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 & Delivery (optional)</h3>'."\n";
|
340 |
+
echo '<a href="http://aws.amazon.com/cloudfront/" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/amazon-logo.png" class="ws-menu-page-right" style="width:250px; height:100px; border:0;" alt="." /></a>'."\n";
|
341 |
+
echo '<p>Please note, all of this is optional. s2Member can be configured to ONLY use Amazon S3 <em>(i.e. without Amazon CloudFront)</em>. Or, s2Member can be configured to use BOTH Amazon S3 and Amazon CloudFront together. If you don\'t want to use Amazon CloudFront, please leave this entire section empty. The configuration options in this section are ONLY required if you are planning to use both Amazon S3 and Amazon CloudFront together.</p>'."\n";
|
342 |
+
echo '<p>Amazon Simple Storage Service (<a href="http://aws.amazon.com/s3/" target="_blank" rel="external">Amazon S3</a>) combined with <a href="http://aws.amazon.com/cloudfront/" target="_blank" rel="external">Amazon CloudFront</a>. Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services <em>(i.e. Amazon S3 Storage)</em> to give developers and businesses an easy way to distribute content to end users with low latency, and with high data transfer speeds. Amazon CloudFront delivers your static and streaming content using a global network of edge locations. Requests for your Amazon S3 Bucket Objects <em>(i.e. your protected files)</em> are automatically routed to the nearest edge location, so content is delivered with the best possible performance. s2Member has been integrated with both Amazon S3 and with Amazon CloudFront. So <em>(if you wish)</em>, instead of using the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory, you can store all of your protected files inside an Amazon S3 Bucket and serve them via Amazon CloudFront. But again, please understand, the configuration options in this section are ONLY required if you\'re going to use both Amazon S3 & CloudFront together.</p>'."\n";
|
343 |
+
echo '<p><strong>One of the great things about Amazon CloudFront</strong>, is its ability to <strong>stream/seek media files</strong> in the truest sense of the word. For sites delivering protected <em>FLV/MP4/OGG/WEBM</em> and other streaming audio/video file types over the <em>RTMP</em> protocol, Amazon CloudFront is our recommendation. Once you\'ve successfully configured s2Member to use both Amazon S3 and Amazon CloudFront together, please review the section below regarding <code>JW Player & RTMP Protocol Examples</code>. s2Member will automatically serve your protected files over the <em>RTMP</em> protocol using an Amazon CloudFront Streaming Distribution.</p>'."\n";
|
344 |
+
echo '<p>If you configure the options below, s2Member will assume all protected files are inside your Amazon S3 Bucket; and the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory is no longer used at all. That being said, all other aspects of s2Member\'s File Download protection remain the same. The only thing that changes, is the location of your protected files. In other words, Basic Download Restrictions, Download Keys, Custom Capability and/or Membership Level Files will all continue to work just as before. The only difference is that s2Member will use your Amazon S3 Bucket, automatically connecting it to both of the Amazon CloudFront Distributions, which s2Member auto-configures for you <em>(see below)</em>. In this way, s2Member uses Amazon CloudFront as a CDN <em>(i.e. Content Delivery Network)</em> for your protected files.</p>'."\n";
|
345 |
+
echo '<p>s2Member assumes that you\'re creating a new Amazon S3 Bucket, specifically for this installation; and that your Bucket is NOT available publicly. In other words, if you type this URL into your browser <em>(i.e. <code>http://your-bucket-name.s3.amazonaws.com/</code>)</em>, you should get an error that says: <code>Access Denied</code>. That\'s good, that\'s exactly what you want. You can create your Amazon S3 Bucket using the <a href="https://console.aws.amazon.com/s3/home" target="_blank" rel="external">Amazon interface</a>. Or, some people prefer to use this popular Firefox extension (<a href="http://www.s3fox.net/" target="_blank" rel="external">S3 Fox Organizer</a>). You will also need to enable CloudFront inside your Web Services account at Amazon. Don\'t worry about creating or configuring any CloudFront Distributions, s2Member will auto-create and auto-configure those for you, allowing you to serve protected files.</p>'."\n";
|
346 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_amazon_cf", get_defined_vars());
|
347 |
+
|
348 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
349 |
+
|
350 |
+
echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member\'s auto-configuration routines for Amazon CloudFront (below), are designed to create & configure various components on your Amazon Web Services account, which are all requirements for you to <a href="http://docs.amazonwebservices.com/AmazonCloudFront/2010-11-01/DeveloperGuide/index.html?HowToPrivateContent.html" target="_blank" rel="external">serve protected files through the Amazon S3/CloudFront combination</a>. These components include: an Origin Access Identity, read permissions for the Origin Access Identity, and two private content Distributions. One private content Distribution for file downloads, and another private content Distribution for streaming media files; both connected to and sourced by your Amazon S3 Bucket. In addition, s2Member will automatically configure an ACL & Policy (i.e. permissions) on your Amazon S3 Bucket to make sure your protected object/files are NOT available to the public.</em></p>'."\n";
|
351 |
+
echo '<p><em><strong>Dev Note w/Technical Details:</strong> s2Member uses "Digitally Signed URLs", authenticated by the Amazon CloudFront API. Documented for developers <a href="http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html" target="_blank" rel="external">here</a>. To put it simply, s2Member will generate Amazon CloudFront URLs (internally); which allow Customers temporary access to specific files inside your S3 Bucket — via CloudFront Distributions. s2Member\'s Digitally Signed URLs leading to Amazon S3/CloudFront, give a Customer 24 hours to connect to the file inside your S3 Bucket. This connection period of 24 hours is largely irrelevant when used in combination with s2Member, because access is renewed for another 24 hours each time you make a file available to a User/Member, and they are authenticated by your configuration of s2Member. This connection period of 24 hours is just a secondary line of defense to further prevent the possibility of link sharing. If you need to change this connection timeout of <code>24 hours</code> for some reason (not likely), you can use this WordPress Filter: <code>ws_plugin__s2member_amazon_cf_file_expires_time</code>.</em></p>'."\n";
|
352 |
+
echo '<p><em><strong>Linking To Protected Files:</strong> RTMP streams are special, but nothing else changes. s2Member\'s integration with Amazon S3/CloudFront serves protected files through the same links that all s2Member site owners use. For example, you might use: <code>'.esc_html(site_url("/?s2member_file_download=example-file.zip")).'</code>, where <strong>s2member_file_download</strong> = the file, relative to the root of your Amazon S3 Bucket. In other words, just the file name in most cases. s2Member will redirect Users/Members to a digitally signed Amazon CloudFront URL, which allows them access to a particular file via Amazon CloudFront. For further details, please review this section of your Dashboard: <code>s2Member -› Download Options -› Basic Download Restrictions</code>. Also see: <code>s2Member -› Download Options -› Advanced Mod-Rewrite Linkage</code>. If you\'re streaming audio/video files over the RTMP protocol, please review the section below: <code>JW Player & RTMP Protocol Examples</code>.</em></p>'."\n";
|
353 |
+
echo '<p><em><strong>Content Type, Disposition & Inline Files:</strong> An IMPORTANT issue. The query string parameter <code>&s2member_file_inline=yes</code> does NOTHING for files served via Amazon CloudFront. s2Member has NO control over the <code>Content-Type</code> and/or <code>Content-Disposition</code> headers for a file being served through Amazon CloudFront, and CloudFront servers do NOT automatically determine the MIME type for the objects they serve. Therefore, when you upload a file to your Amazon S3 Bucket, you should set its Content-Type header. That is, you MUST configure headers yourself (such as <code>Content-Type: video/webm</code>, or <code>Content-Disposition: inline|attachment</code>) that you want Amazon CloudFront to send for a particular file. It\'s quite easy. You do this by setting <code>Properties -› Metadata (i.e. headers)</code> on a per-file basis, from inside your Amazon S3 Management Console. In short, when you upload a file to your Amazon S3 Bucket, if you want that file to be served a certain way, be sure to configure its <code>Properties -› Metadata</code> accordingly.</em></p>'."\n";
|
354 |
+
echo (stripos(PHP_OS, "win") === 0 && c_ws_plugin__s2member_utils_conds::is_localhost()) ? '<p><em><strong>Localhost Developers:</strong> s2Member\'s Amazon CloudFront integration requires the <a href="http://php.net/manual/en/function.openssl-sign.php" target="_blank" rel="external">openssl_sign()</a> function in PHP so it can digitially sign CloudFront URLs. This function is sometimes problematic on localhost servers such as WAMP & EasyPHP. We recommend installing <a href="http://www.slproweb.com/products/Win32OpenSSL.html" target="_blank" rel="external">this lightweight alternative for Windows</a> while you\'re developing. s2Member will automatically find it here: <code>C:\OpenSSL-Win[32/64]\bin\openssl.exe</code>.'.((file_exists("c:\openssl-win32\bin\openssl.exe") || file_exists("c:\openssl-win64\bin\openssl.exe")) ? ' <strong class="ws-menu-page-hilite">( s2Member has detected that OpenSSL-Win[32/64] IS installed in the correct location, thank you! )</strong>' : ' <strong class="ws-menu-page-hilite">(s2Member has detected that OpenSSL-Win[32/64] is NOT currently available)</strong>').'</em></p>'."\n" : '';
|
355 |
+
|
356 |
+
if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_auto_config_status"] === "configured")
|
357 |
+
echo '<p><em class="ws-menu-page-hilite"><strong>Your Amazon CloudFront Distributions are: ( ALREADY configured! )</strong></em>'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]) ? '<br /><em class="ws-menu-page-hilite">Downloads Distribution CNAME:</em> <em><code>'.esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]).' —» '.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 class="ws-menu-page-hilite">Streaming Distribution CNAME:</em> <em><code>'.esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]).' —» '.esc_html($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_dname"]).'</code></em>' : '').'</p>'."\n";
|
358 |
+
|
359 |
+
else if(!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_auto_config_status"])
|
360 |
+
echo '<p><em class="ws-menu-page-hilite"><strong>Your Amazon CloudFront Distributions are: (NOT yet auto-configured).</strong></em></p>'."\n";
|
361 |
+
|
362 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
363 |
+
|
364 |
+
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
365 |
+
echo '<tbody>'."\n";
|
366 |
+
echo '<tr>'."\n";
|
367 |
+
|
368 |
+
echo '<th style="padding-top:0;">'."\n";
|
369 |
+
echo '<label for="ws-plugin--s2member-amazon-cf-files-private-key-id">'."\n";
|
370 |
+
echo 'Amazon CloudFront Key Pair ID (your Key Pair ID):'."\n";
|
371 |
+
echo '</label>'."\n";
|
372 |
+
echo '</th>'."\n";
|
373 |
+
|
374 |
+
echo '</tr>'."\n";
|
375 |
+
echo '<tr>'."\n";
|
376 |
+
|
377 |
+
echo '<td>'."\n";
|
378 |
+
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_private_key_id" id="ws-plugin--s2member-amazon-cf-files-private-key-id" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key_id"]).'" data-s-prev-config-value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key_id"]).'" /><br />'."\n";
|
379 |
+
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› CloudFront Key Pairs</code>'."\n";
|
380 |
+
echo '</td>'."\n";
|
381 |
+
|
382 |
+
echo '</tr>'."\n";
|
383 |
+
echo '<tr>'."\n";
|
384 |
+
|
385 |
+
echo '<th>'."\n";
|
386 |
+
echo '<label for="ws-plugin--s2member-amazon-cf-files-private-key-entry">'."\n";
|
387 |
+
echo 'Amazon CloudFront Private Key (contents of your <code>pk-[***].pem</code> file):'."\n";
|
388 |
+
echo '</label>'."\n";
|
389 |
+
echo '</th>'."\n";
|
390 |
+
|
391 |
+
echo '</tr>'."\n";
|
392 |
+
echo '<tr>'."\n";
|
393 |
+
|
394 |
+
echo '<td>'."\n";
|
395 |
+
echo '<input type="hidden" name="ws_plugin__s2member_amazon_cf_files_private_key" id="ws-plugin--s2member-amazon-cf-files-private-key" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" data-s-prev-config-value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'" />'."\n";
|
396 |
+
echo '<textarea name="ws_plugin__s2member_amazon_cf_files_private_key_entry" id="ws-plugin--s2member-amazon-cf-files-private-key-entry" rows="3" wrap="off" spellcheck="false" class="monospace">'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"]).'</textarea><br />'."\n";
|
397 |
+
echo 'See: <code>Amazon Web Services Account -› Security Credentials -› CloudFront Key Pairs</code><br />'."\n";
|
398 |
+
echo '<em>* Note, s2Member needs your <strong>Private Key file</strong>, NOT your Public Key file.</em>'."\n";
|
399 |
+
echo '</td>'."\n";
|
400 |
+
|
401 |
+
echo '</tr>'."\n";
|
402 |
+
echo '<tr>'."\n";
|
403 |
+
|
404 |
+
echo '<th>'."\n";
|
405 |
+
echo '<label for="ws-plugin--s2member-amazon-cf-files-auto-configure-distros">'."\n";
|
406 |
+
echo 'Auto-Configure your Amazon S3/CloudFront combination?'."\n";
|
407 |
+
echo '</label>'."\n";
|
408 |
+
echo '</th>'."\n";
|
409 |
+
|
410 |
+
echo '</tr>'."\n";
|
411 |
+
echo '<tr>'."\n";
|
412 |
+
|
413 |
+
echo '<td>'."\n";
|
414 |
+
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")).'"'.((!empty(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 & Amazon S3 ACLs for me.</label><br />'."\n";
|
415 |
+
echo '<em>s2Member will auto-configure and/or delete & re-configure your Amazon CloudFront Distributions for you.</em>'."\n";
|
416 |
+
echo '</td>'."\n";
|
417 |
+
|
418 |
+
echo '</tr>'."\n";
|
419 |
+
echo '<tr>'."\n";
|
420 |
+
|
421 |
+
echo '<td>'."\n";
|
422 |
+
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")).'"'.((!empty(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";
|
423 |
+
echo '<em>* Optional, do NOT check this box unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
|
424 |
+
echo '</td>'."\n";
|
425 |
+
|
426 |
+
echo '</tr>'."\n";
|
427 |
+
echo '</tbody>'."\n";
|
428 |
+
echo '</table>'."\n";
|
429 |
+
|
430 |
+
echo '<div id="ws-plugin--s2member-amazon-cf-files-auto-configure-distro-cnames" style="display:none;">'."\n";
|
431 |
+
echo '<table class="form-table">'."\n";
|
432 |
+
echo '<tbody>'."\n";
|
433 |
+
echo '<tr>'."\n";
|
434 |
+
|
435 |
+
echo '<th>'."\n";
|
436 |
+
echo '<label for="ws-plugin--s2member-amazon-cf-files-downloads-distro-cname">'."\n";
|
437 |
+
echo 'Amazon CloudFront CNAME for File Downloads (optional):'."\n";
|
438 |
+
echo '</label>'."\n";
|
439 |
+
echo '</th>'."\n";
|
440 |
+
|
441 |
+
echo '</tr>'."\n";
|
442 |
+
echo '<tr>'."\n";
|
443 |
+
|
444 |
+
echo '<td>'."\n";
|
445 |
+
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_distro_downloads_cname" id="ws-plugin--s2member-amazon-cf-files-downloads-distro-cname" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_downloads_cname"]).'" /><br />'."\n";
|
446 |
+
echo 'Example: <code>s2-file-downloads.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
|
447 |
+
echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
|
448 |
+
echo '</td>'."\n";
|
449 |
+
|
450 |
+
echo '</tr>'."\n";
|
451 |
+
echo '<tr>'."\n";
|
452 |
+
|
453 |
+
echo '<th>'."\n";
|
454 |
+
echo '<label for="ws-plugin--s2member-amazon-cf-files-streaming-distro-cname">'."\n";
|
455 |
+
echo 'Amazon CloudFront CNAME for Streaming Files (optional):'."\n";
|
456 |
+
echo '</label>'."\n";
|
457 |
+
echo '</th>'."\n";
|
458 |
+
|
459 |
+
echo '</tr>'."\n";
|
460 |
+
echo '<tr>'."\n";
|
461 |
+
|
462 |
+
echo '<td>'."\n";
|
463 |
+
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_amazon_cf_files_distro_streaming_cname" id="ws-plugin--s2member-amazon-cf-files-streaming-distro-cname" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distro_streaming_cname"]).'" /><br />'."\n";
|
464 |
+
echo 'Example: <code>s2-streaming-files.'.esc_html(c_ws_plugin__s2member_utils_urls::parse_url(site_url(), PHP_URL_HOST)).'</code>.<br />'."\n";
|
465 |
+
echo '<em>* Optional, do NOT fill this in unless you know what you\'re doing. This requires DNS changes.</em>'."\n";
|
466 |
+
echo '</td>'."\n";
|
467 |
+
|
468 |
+
echo '</tr>'."\n";
|
469 |
+
echo '</tbody>'."\n";
|
470 |
+
echo '</table>'."\n";
|
471 |
+
echo '</div>'."\n";
|
472 |
+
|
473 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
474 |
+
|
475 |
+
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
476 |
+
echo '<tbody>'."\n";
|
477 |
+
echo '<tr>'."\n";
|
478 |
+
|
479 |
+
echo '<td>'."\n";
|
480 |
+
echo '<h3>Completely Reset CloudFront Configuration?</h3>'."\n";
|
481 |
+
echo '<div style="float:right; margin:0 0 0 25px;">'."\n";
|
482 |
+
echo ' <button type="button" onclick="if(confirm(\'Are you sure?\')) location.href = \''.c_ws_plugin__s2member_utils_strings::esc_js_sq(add_query_arg(urlencode_deep(array('ws_plugin__s2member_cf_options_reset' => wp_create_nonce('ws-plugin--s2member-cf-options-reset'))))).'\';">Reset CloudFront Configuration</button>'."\n";
|
483 |
+
echo '</div>'."\n";
|
484 |
+
echo '<p>If you need to start all over again, you can click this button to reset your existing s2Member/CloudFront configuration. <em><strong>However, please note:</strong> you will still need to log into your AWS CloudFront Console (at some point) and remove any existing CloudFront Distributions and/or Origin Access Identities that were previously generated with s2Member; i.e. resetting your configuration here will allow you to start over with s2Member using a new set of CF Distros, but it does NOT delete anything on the AWS side.</em></p>'."\n";
|
485 |
+
echo '</td>'."\n";
|
486 |
+
|
487 |
+
echo '</tr>'."\n";
|
488 |
+
echo '</tbody>'."\n";
|
489 |
+
echo '</table>'."\n";
|
490 |
+
|
491 |
+
echo '</div>'."\n";
|
492 |
+
echo '</div>'."\n";
|
493 |
+
|
494 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_amazon_cf", get_defined_vars());
|
495 |
+
}
|
496 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_rtmp_streaming", TRUE, get_defined_vars()))
|
497 |
+
{
|
498 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_rtmp_streaming", get_defined_vars());
|
499 |
+
|
500 |
+
echo '<div class="ws-menu-page-group" title="JW Player v6 & RTMP Protocol Examples">'."\n";
|
501 |
+
|
502 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-rtmp-streaming-section">'."\n";
|
503 |
+
echo '<h3>JW Player v6 & RTMP Protocol Examples</h3>'."\n";
|
504 |
+
echo '<a href="http://www.longtailvideo.com/players/" target="_blank"><img src="'.esc_attr($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"]).'/images/jwplayer-logo.png" class="ws-menu-page-right" style="width:179px; height:58px; border:0; border-radius:3px; background:#FFFFFF; padding:15px;" alt="." /></a>'."\n";
|
505 |
+
echo '<p>While it is possible to serve audio/video files protected by s2Member, without needing to integrate Amazon S3 or CloudFront; we DO highly recommend that you integrate both Amazon S3 and Amazon CloudFront in order to maximize speed and compatibility across various viewing platforms. That being said, there are code samples below that will serve audio/video files both with and without Amazon S3/CloudFront. You can also check the <a href="'.esc_attr(c_ws_plugin__s2member_readmes::parse_readme_value("Forum URI")).'" target="_blank" rel="external">s2Member Support Forums</a> for tips/tricks if you like.</p>'."\n";
|
506 |
+
echo '<p><strong>One of the great things about Amazon CloudFront</strong>, is its ability to <strong>stream/seek media files</strong> in the truest sense of the word. For sites delivering protected <em>FLV/MP4/OGG/WEBM</em> and other streaming audio/video file types over the <em>RTMP</em> protocol, Amazon CloudFront is our recommendation. Once you\'ve successfully configured s2Member to use both Amazon S3 and Amazon CloudFront together, please review the code samples below. s2Member can automatically serve your protected files over the <em>RTMP</em> protocol using an Amazon CloudFront Streaming Distribution.</p>'."\n";
|
507 |
+
echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/" target="_blank" rel="external">JW Player w/ <code>[s2Stream /]</code> Shortcodes</a>.</p>'."\n";
|
508 |
+
if(stripos(wp_get_theme(), 'infocus') !== FALSE)
|
509 |
+
echo '<p><strong>Note:</strong> It appears that you\'re using the inFocus WordPress theme. If you experience trouble with the shortcodes below, try wrapping the shortcode in <code>[raw][/raw]</code> tags (e.g., <code>[raw][s2Stream ... /][/raw]</code>).</p>'."\n";
|
510 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_rtmp_streaming", get_defined_vars());
|
511 |
+
|
512 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
513 |
|
514 |
+
echo '<h3><code>[s2Stream /]</code> Video Shortcode Examples (recommended — it\'s the easiest way)</h3>'."\n";
|
|
|
|
|
515 |
|
516 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4\').toggle(); return false;" class="ws-dotted-link">JW Player (MP4 file, via Rewrite URLs. Amazon S3/CloudFront NOT required)</a></p>'."\n";
|
517 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Works with any audio/video file. This does NOT require s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp4.x-php")).'</p>'."\n";
|
|
|
|
|
518 |
|
519 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4-rtmp\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4, via s2Member\'s Amazon S3/CloudFront integration)</a></p>'."\n";
|
520 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4-rtmp" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Streams with the RTMP protocol, plus there is a full download fallback of the MP4 source file if streaming is not possible on a particular device.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp4-rtmp.x-php")).'</p>'."\n";
|
|
|
|
|
|
|
521 |
|
522 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4-rtmp-only\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4 only, via s2Member\'s Amazon S3/CloudFront integration)</a></p>'."\n";
|
523 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp4-rtmp-only" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Streams with the RTMP protocol only, with no access to the source file, only to the RTMP stream.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp4-rtmp-only.x-php")).'</p>'."\n";
|
524 |
|
525 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
|
|
|
|
526 |
|
527 |
+
echo '<h3><code>[s2Stream /]</code> Audio Shortcode Examples (recommended — it\'s the easiest way)</h3>'."\n";
|
|
|
528 |
|
529 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp3\').toggle(); return false;" class="ws-dotted-link">JW Player (MP3 file, via Rewrite URLs. Amazon S3/CloudFront NOT required)</a></p>'."\n";
|
530 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp3" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Works with any audio/video file. This does NOT require s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp3.x-php")).'</p>'."\n";
|
|
|
|
|
|
|
531 |
|
532 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp3-rtmp\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP3, via s2Member\'s Amazon S3/CloudFront integration)</a></p>'."\n";
|
533 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp3-rtmp" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Streams with the RTMP protocol, plus there is a full download fallback of the MP3 source file if streaming is not possible on a particular device.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp3-rtmp.x-php")).'</p>'."\n";
|
534 |
|
535 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp3-rtmp-only\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP3 only, via s2Member\'s Amazon S3/CloudFront integration)</a></p>'."\n";
|
536 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-s2stream-mp3-rtmp-only" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />Streams with the RTMP protocol only, with no access to the source file, only to the RTMP stream.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-s2stream-mp3-rtmp-only.x-php")).'</p>'."\n";
|
|
|
|
|
|
|
537 |
|
538 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
|
|
|
|
539 |
|
540 |
+
echo '<h3>PHP Code Examples (for more advanced integrations via PHP — in WordPress themes)</h3>'."\n";
|
541 |
|
542 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-standard-mp4\').toggle(); return false;" class="ws-dotted-link">JW Player (MP4 file, via Rewrite URLs. Amazon S3/CloudFront NOT required)</a></p>'."\n";
|
543 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-standard-mp4" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This does NOT require s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <code>s2Member -› Download Options -› Advanced Mod Rewrite Linkage</code>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-standard-mp4.x-php")).'</p>'."\n";
|
544 |
|
545 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4, via s2Member\'s Amazon S3/CloudFront integration)</a></p>'."\n";
|
546 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/" target="_blank" rel="external">s2Member Codex -› API Functions</a>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-streaming-mp4.x-php")).'</p>'."\n";
|
|
|
547 |
|
548 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-sca\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4, via s2Member\'s JSON/Shortcode alternative)</a></p>'."\n";
|
549 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-sca" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/" target="_blank" rel="external">s2Member Codex -› API Functions</a>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-streaming-mp4-sca.x-php")).'</p>'."\n";
|
550 |
|
551 |
+
echo '<p style="font-size:110%;"><a href="#" onclick="jQuery(\'p#ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-webm\').toggle(); return false;" class="ws-dotted-link">JW Player (RTMP streaming MP4, advanced w/ multiple fallbacks)</a></p>'."\n";
|
552 |
+
echo '<p id="ws-plugin--s2member-rtmp-streaming-details-jwplayer-streaming-mp4-webm" style="display:none;">Download <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">JW Player here</a>, and upload <code>/jwplayer/</code> to your website\'s root directory.<br />This requires s2Member to be integrated with Amazon S3/CloudFront.<br />Also see: <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-summary/" target="_blank" rel="external">s2Member Codex -› API Functions</a>.<br /><br />'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/jwplayer-streaming-mp4-webm.x-php")).'</p>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
553 |
|
554 |
+
echo '</div>'."\n";
|
555 |
|
556 |
+
echo '</div>'."\n";
|
557 |
|
558 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_rtmp_streaming", get_defined_vars());
|
559 |
+
}
|
560 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_rewrite_linkage", TRUE, get_defined_vars()))
|
561 |
+
{
|
562 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_rewrite_linkage", get_defined_vars());
|
563 |
+
|
564 |
+
echo '<div class="ws-menu-page-group" title="Advanced Mod-Rewrite Linkage">'."\n";
|
565 |
+
|
566 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-rewrite-linkage-section">'."\n";
|
567 |
+
echo '<h3>Advanced Mod-Rewrite Linkage</h3>'."\n";
|
568 |
+
echo '<p>s2Member automatically creates <code>mod_rewrite</code> rules inside your <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory, which provide additional flexibility in the way protected files can be served to your Customers. With s2Member\'s <code>mod_rewrite</code> rules, it is now possible to link directly to a protected file, avoiding the use of query string variables <em>(it\'s completely optional though, i.e. NOT required)</em>.</p>'."\n";
|
569 |
+
echo '<p>This new flexibility may come in handy for site owners serving files through media playback devices that have issues with query string variables. For instance, it is now possible to link to an s2Member-protected file directly, like this: <code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/example-file.zip</code> instead of <code>... /?s2member_file_download=example-file.zip</code>. Either way works, but the direct link might be easier for some.</p>'."\n";
|
570 |
+
echo '<p>It is also possible to pass query string parameters through a direct link:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/example-file.zip?s2member_file_inline=yes&s2member_file_download_key=[key]</code>.</p>'."\n";
|
571 |
+
echo '<p>That being said, s2Member\'s <code>mod_rewrite</code> rules allow for more advanced control over s2Member-specific parameters.</p>'."\n";
|
572 |
+
echo '<p>For example, you could just do this for inline files:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline</strong>/example-file.zip</code></p>'."\n";
|
573 |
+
echo '<p>Or, if you really want to get advanced, you could do something like this:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline-[yes|no]/s2member-file-download-key-[key]</strong>/example-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline-yes/s2member-file-download-key-xS54df5ER4d5x</strong>/example-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-inline-yes/s2member-skip-confirmation</strong>/example-file.zip</code></p>'."\n";
|
574 |
+
echo '<p>Or even this, if you\'re using Remote Header Authorization:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-remote</strong>/example-file.zip</code></p>'."\n";
|
575 |
+
echo '<p>Specifying storage location option dynamically:<br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-storage-[local|s3|cf]</strong>/example-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-storage-cf</strong>/example-cloudfront-file.zip</code><br /><code>... /wp-content/plugins/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'<strong class="ws-menu-page-hilite">/s2member-file-storage-s3/s2member-file-inline</strong>/example-s3-file.html</code></p>'."\n";
|
576 |
+
echo '<p><em>* Note, the order of your s2Member-specific parameters with Advanced Mod-Rewrite Linkage is irrelevant. Feel free to add/remove, or even change the order. Everything discussed here is also Multisite compatible. Everything discussed here is also compatible when/if combined with Amazon S3/CDN Storage. However, NONE of this will work on servers that do NOT support <code>mod_rewrite</code>. Almost all web servers do though.</em></p>'."\n";
|
577 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_rewrite_linkage", get_defined_vars());
|
578 |
+
echo '</div>'."\n";
|
579 |
+
|
580 |
+
echo '</div>'."\n";
|
581 |
+
|
582 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_rewrite_linkage", get_defined_vars());
|
583 |
+
}
|
584 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_shortcode_attrs", TRUE, get_defined_vars()))
|
585 |
+
{
|
586 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_shortcode_attrs", get_defined_vars());
|
587 |
+
|
588 |
+
echo '<div class="ws-menu-page-group" title="Shortcode Attributes & API Functions (Explained)">'."\n";
|
589 |
+
|
590 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-shortcode-attrs-section">'."\n";
|
591 |
+
echo '<h3>Shortcode Attributes & API Functions (Explained In Full Detail)</h3>'."\n";
|
592 |
+
echo '<p>s2Member makes <a href="http://codex.wordpress.org/Shortcode_API#Overview" target="_blank" rel="external">Shortcodes</a> available to you, which allow you to generate File Download URLs and/or File Download Keys. Like most Shortcodes for WordPress, s2Member reads Attributes in your Shortcode. Many site owners like to know exactly how these Shortcode Attributes work. Below, is a brief overview of each possible Shortcode Attribute.</p>'."\n";
|
593 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs", get_defined_vars());
|
594 |
+
|
595 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
596 |
+
|
597 |
+
echo '<h4 style="margin:0;"><code>[s2File /]</code> & <code>[s2Stream /]</code> Shortcode Attributes:</h4>'."\n";
|
598 |
+
echo '<p style="margin:0;"><strong>See also:</strong> API Function <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_s2member_file_download_url()" target="_blank" rel="external">s2member_file_download_url()</a> for PHP integration.</p>'."\n";
|
599 |
+
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
600 |
+
echo '<tbody>'."\n";
|
601 |
+
echo '<tr style="padding-top:0;">'."\n";
|
602 |
+
|
603 |
+
echo '<td style="padding-top:0;">'."\n";
|
604 |
+
echo '<ul class="ws-menu-page-li-margins">'."\n";
|
605 |
+
echo '<li><code>download="file.zip"</code> Location of the file, relative to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; or, relative to the root of your Amazon S3 Bucket, when applicable.</li>'."\n";
|
606 |
+
echo '<li><code>download_key="no"</code> Defaults to <code>no</code>. If <code>download_key="1|on|yes|true|ip-forever|universal"</code>, s2Member will return a URL with an s2Member-generated File Download Key. You don\'t need to generate the File Download Key yourself, s2Member does it for you. If you set <code>download_key="ip-forever"</code>, the File Download Key that s2Member generates will last forever, for a specific IP Address; otherwise, by default, all File Download Keys expire after 24 hours automatically. If you set <code>download_key="universal"</code>, s2Member will generate a File Download Key that is good for anyone/everyone forever, with NO restrictions on who/where/when a file is accessed <em>(e.g. be careful with this one)</em>.</li>'."\n";
|
607 |
+
echo '<li><code>stream="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>stream="1|on|yes|true"</code>, s2Member will return a URL containing a parameter/directive, which forces the File Download to take place over the RTMP protocol if at all possible. This ONLY works when/if s2Member is configured to run with both Amazon S3/CloudFront. Please note however, it\'s better to use the example code provided in the section above, regarding: <code>JW Player and the RTMP Protocol</code>. Also note, if <code>get_streamer_json="1|on|yes|true"</code>, s2Member will automatically force <code>stream="yes"</code> for you.</li>'."\n";
|
608 |
+
echo '<li><code>inline=""</code> Defaults to <code>[empty]</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>inline="1|on|yes|true"</code>, s2Member will serve the file inline, instead of as an actual File Download. If empty, s2Member will look at your <code>Inline File Extensions</code> configuration above, and serve the file inline; if, and only if, its extension matches one found in your configuration. By default, s2Member serves all files as attachments <em>(i.e. downloads)</em>, except in the case of the <code>[s2Stream /]</code> Shortcode where this defaults to <code>yes</code>. Please read the section above regarding <code>Inline File Extensions</code> for further details. Also note, this Shortcode Attribute does NOTHING for files served via Amazon CloudFront. See the tech-notes listed in the Amazon CloudFront section for further details and workarounds.</li>'."\n";
|
609 |
+
echo '<li><code>storage=""</code> Defaults to <code>[empty]</code>. If <code>storage="local|s3|cf"</code>, s2Member will serve the file from a specific source location, based on the value of this Shortcode Attribute. For example, if you\'ve configured Amazon S3 and/or CloudFront; but, there are a few files that you want to upload locally to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; you can force s2Member to serve a file from local storage by setting <code>storage="local"</code> explicitly.</li>'."\n";
|
610 |
+
echo '<li><code>remote="no"</code> Defaults to <code>no</code>. If <code>remote="1|on|yes|true"</code>, s2Member will authenticate access to the File Download via Remote Header Authorization, instead of through your web site. This is similar to <code>.htaccess</code> protection routines of yester-year</code>. Please check the <code>Remote Authorization and Podcasting</code> section for further details about how this works.</li>'."\n";
|
611 |
+
echo '<li><code>ssl=""</code> Defaults to <code>[empty]</code>. If <code>ssl="1|on|yes|true"</code>, s2Member will generate a File Download URL with an SSL protocol <em>(i.e. the URL will start with <code>https://</code> or <code>rtmpe://</code>)</em>. If empty, s2Member will only generate a File Download URL with an SSL protocol, when/if the Post/Page/URL firing the Shortcode itself, is also being viewed over SSL. Otherwise, s2Member will use a non-SSL protocol by default.</li>'."\n";
|
612 |
+
echo '<li><code>rewrite="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>rewrite="1|on|yes|true"</code>, s2Member will generate a File Download URL that takes full advantage of s2Member\'s Advanced Mod Rewrite functionality. If you\'re running an Apache web server, or another server that supports <code>mod_rewrite</code>, we highly recommend turning this on. s2Member\'s <code>mod_rewrite</code> URLs do NOT contain query string parameters, making them more portable/compatible with other software applications and/or plugins for WordPress. If you\'re integrating with JW Player, you MUST use <code>rewrite="yes"</code>.</li>'."\n";
|
613 |
+
echo '<li><code>rewrite_base=""</code> Defaults to <code>[empty]</code>. If <code>rewrite_base="'.esc_attr(site_url("/")).'"</code>, s2Member will generate a File Download URL that takes full advantage of s2Member\'s Advanced Mod Rewrite functionality, and it will use the rewrite base URL as a prefix. This could be useful on some WordPress installations that use advanced directory structures. It could also be useful for site owners using virtual directories that point to <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code>. Note, if <code>rewrite_base</code> is set, s2Member will automatically force <code>rewrite="yes"</code> for you.</li>'."\n";
|
614 |
+
echo '<li><code>skip_confirmation="no"</code> Defaults to <code>no</code>. If <code>skip_confirmation="1|on|yes|true"</code>, s2Member will generate a File Download URL which contains a directive, telling s2Member NOT to introduce any JavaScript confirmation prompts on your site, for this File Download URL. Please note, s2Member will automatically detect links, anywhere in your content, and/or anywhere in your theme files, that contain <code>s2member_file_download</code> or <code>s2member-files</code>. Whenever a logged-in Member clicks a link that contains <code>s2member_file_download</code> or <code>s2member-files</code>, the system will politely ask the User to confirm the download using a very intuitive JavaScript confirmation prompt, which contains specific details about your configured download limitations. This way your Members will be aware of how many files they\'ve downloaded in the current period; and they\'ll be able to make a conscious decision about whether to proceed with a specific download or not.</li>'."\n";
|
615 |
+
echo '<li><code>url_to_storage_source="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>url_to_storage_source="1|on|yes|true"</code>, s2Member will generate a File Download URL which points directly to the storage source. This is only functional with Amazon S3 and/or CloudFront integrations. If you create a URL that points directly to the storage source <em>(i.e. points directly to Amazon S3 or CloudFront)</em>, s2Member will NOT be able to further authenticate the current User/Member; and, s2Member will NOT be able to count the File Download against the current User\'s account record, because the URL being generated does not pass back through s2Member at all, it points directly to the storage source. For this reason, if you set <code>url_to_storage_source="true"</code>, you should also set <code>check_user="true"</code> and <code>count_against_user="true"</code>, telling s2Member to authenticate the current User, and if authenticated, count this File Download URL against the current User\'s account record in real-time <em>(i.e. as the URL is being generated) </em>, while it still has a chance to do so. This Shortcode Attribute is useful when you stream files over the RTMP protocol; where an <code>http://</code> URL is not feasible. It also helps in situations where a 3rd-party software application will not work as intended, with s2Member\'s internal redirection to Amazon S3/CloudFront files. Important, when <code>check_user="true"</code> and/or <code>count_against_user="true"</code>, the Shortcode will return an empty and/or null object value in situations where the current User/Member does NOT have access to the file.</li>'."\n";
|
616 |
+
echo '<li><code>count_against_user="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>count_against_user="1|on|yes|true"</code>, it will automatically force <code>check_user="true"</code> as well. In other words, s2Member will authenticate the current User, and if authenticated, count this File Download URL against the current User\'s account record in real-time <em>(i.e. as the URL is being generated) </em>. This is off by default with the <code>[s2File /]</code> Shortcode. By default, s2Member will simply generate a File Download URL, and upon a User/Member clicking the URL, s2Member will authenticate the User/Member at that time, count the File Download against their account record, and serve the File Download. In other words, under normal circumstances, there is no reason to set <code>check_user="true"</code> and/or <code>count_against_user="true"</code> when generating the URL itself. However, this is a useful Shortcode Attribute when <code>url_to_storage_source="true"</code>. Please note, when <code>check_user="true"</code> and/or <code>count_against_user="true"</code>, the Shortcode will return an empty and/or null object value in situations where the current User/Member does NOT have access to the file.</li>'."\n";
|
617 |
+
echo '<li><code>check_user="no"</code> Defaults to <code>no</code> with <code>[s2File /]</code> Shortcode. Defaults to <code>yes</code> with <code>[s2Stream /]</code> Shortcode. If <code>check_user="1|on|yes|true"</code>, s2Member will authenticate the current User before allowing the File Download URL to be generated. This is off by default with the <code>[s2File /]</code> Shortcode. By default, s2Member will simply generate a File Download URL, and upon a User/Member clicking the URL, s2Member will authenticate the User/Member at that time, and serve the File Download to the User/Member. In other words, under normal circumstances, there is no reason to set <code>check_user="true"</code> and/or <code>count_against_user="true"</code> when generating the URL itself. However, this IS a useful Shortcode Attribute when <code>url_to_storage_source="true"</code>. Please note, when <code>check_user="true"</code> and/or <code>count_against_user="true"</code>, the Shortcode will return an empty and/or null object value in situations where the current User/Member does NOT have access to the file.</li>'."\n";
|
618 |
+
echo '<li><code>get_streamer_json="no"</code> Defaults to <code>no</code>. N/A with <code>[s2Stream /]</code> Shortcode. If <code>get_streamer_json="1|on|yes|true"</code>, the <code>[s2File /]</code> Shortcode will return a JSON object for JavaScript notation, making it possible to integrate the <code>[s2File /]</code> Shortcode into JavaScript routines that configure streaming media players. For further details, please review the section above: <code>JW Player & RTMP Protocol Examples</code>. Note, if you set <code>get_streamer_json="true"</code>, s2Member will automatically force <code>url_to_storage_source="true"</code> and <code>stream="true"</code>. For that reason, you should carefully review the details and warning above regarding <code>url_to_storage_source</code>. If you set <code>get_streamer_json="true"</code>, you should also set <code>check_user="true"</code> and <code>count_against_user="true"</code>.</li>'."\n";
|
619 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs_s2file_lis", get_defined_vars());
|
620 |
+
echo '</ul>'."\n";
|
621 |
+
echo '</td>'."\n";
|
622 |
+
|
623 |
+
echo '</tr>'."\n";
|
624 |
+
echo '</tbody>'."\n";
|
625 |
+
echo '</table>'."\n";
|
626 |
+
|
627 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
628 |
+
|
629 |
+
echo '<h4 style="margin:0;">Additional <code>[s2Stream /]</code> Shortcode Attributes:</h4>'."\n";
|
630 |
+
echo '<p style="margin:0;"><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/" target="_blank" rel="external">JW Player w/ <code>[s2Stream /]</code> Shortcodes</a>.</p>'."\n";
|
631 |
+
echo '<p style="margin:0;"><strong>See also:</strong> API Function <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_s2member_file_download_url()" target="_blank" rel="external">s2member_file_download_url()</a> for PHP integration.</p>'."\n";
|
632 |
+
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
633 |
+
echo '<tbody>'."\n";
|
634 |
+
echo '<tr style="padding-top:0;">'."\n";
|
635 |
+
|
636 |
+
echo '<td style="padding-top:0;">'."\n";
|
637 |
+
echo '<ul class="ws-menu-page-li-margins">'."\n";
|
638 |
+
echo '<li><code>file_download="video.mp4"</code> Location of the audio/video file, relative to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; or, relative to the root of your Amazon S3 Bucket, when applicable.</li>'."\n";
|
639 |
+
echo '<li><code>player="jwplayer-v6-rtmp"</code> Required. Current supported players in this Shortcode include: <code>jwplayer-v6</code> (works with any audio/video file, and you do NOT need to have Amazon S3 or CloudFront integrated for this to work), <code>jwplayer-v6-rtmp</code> (streams with the RTMP protocol, plus there is a full download fallback of the source file if streaming is not possible on a particular device; this requires both Amazon S3 and CloudFront integration), <code>jwplayer-v6-rtmp-only</code> (streams with the RTMP protocol only, with no access to the source file, only to the RTMP stream; this requires both Amazon S3 and CloudFront integration).</li>'."\n";
|
640 |
+
echo '<li><code>player_id=""</code> Optional. HTML div ID for the audio/video player. Defaults to a unique ID generated by s2Member for each instance of your Shortcode.</li>'."\n";
|
641 |
+
echo '<li><code>player_path="/jwplayer/jwplayer.js"</code> Required. Path to the player\'s JavaScript file (ex: <code>/jwplayer/jwplayer.js</code> — you should upload the <a href="http://www.longtailvideo.com/players/" target="_blank" rel="external">/jwplayer</a> folder to the root of your web directory).</li>'."\n";
|
642 |
+
echo '<li><code>player_resolutions=""</code> Optional (requires s2Member Pro). This is a comma-delimited list of all available resolution options (should you decide to offer more than just one file download at a single resolution). Please review the full list of Shortcode Attributes (i.e. click the "Shortcode Attributes (Explained)" tab) in <a href="http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#using-s2stream-shortcodes" target="_blank" rel="external">this KB article</a> for further details, requirements, and an example of use.</li>'."\n";
|
643 |
+
echo '<li><code>player_{setting}=""</code> Optional. Any additional configuration attributes supported by your audio/video player, prefixed with <code>player_</code>. For JW Player v6, see <a href="http://www.longtailvideo.com/support/jw-player/28839/embedding-the-player" target="_blank" rel="external">this article please</a>. Examples: <code>player_width="480"</code>, <code>player_height="270"</code>, <code>player_title="My Video"</code>, <code>player_description="A video about something."</code>, <code>player_image="http://www.example.com/wp-content/uploads/video-preview.jpg"</code>, <code>player_mediaid="video_ei0wsx23"</code>, <code>player_autostart="true"</code>, <code>player_skin="/jwplayer/my-skin.xml"</code>, <code>player_key="my-license-key"</code>, <code>player_captions="{file:\'/assets/captions-en.vtt\',label:\'English\'}"</code> (<em>With <a href="http://www.longtailvideo.com/support/jw-player/28845/adding-video-captions" target="_blank" rel="external">Captions</a>, you can exclude the square array brackets to avoid Shortcode parsing issues. s2Member will automatically wrap your Caption objects with square array brackets.</em>). Please note that "Advanced Options Blocks" listed on <a href="http://www.longtailvideo.com/support/jw-player/28839/embedding-the-player" target="_blank" rel="external">this page</a> are NOT supported here. For those, please use: <code>player_option_blocks=""</code> (see below).</li>'."\n";
|
644 |
+
echo '<li><code>player_option_blocks=""</code> Optional. Any "Advanced Option Blocks" supported by your audio/video player. For JW Player v6, see <a href="http://www.longtailvideo.com/support/jw-player/28839/embedding-the-player" target="_blank" rel="external">this article please</a>. Here are some examples: <code>player_option_blocks="sharing:{}"</code>, <code>player_option_blocks="sharing:{}, logo: {file: \'/logo.png\', link: \'http://example.com\'}"</code>. Or: <code>player_option_blocks="c2hhcmluZzoge30="</code> (base64 encoded version of <code>sharing:{}</code>). Please note that "Advanced Options Blocks" can be defined in plain text or with a <a href="http://www.base64encode.org/" target="_blank" rel="external">base64 encoded string</a>. Advanced Option Blocks are JavaScript objects with properties. If you have trouble defining JavaScript object properties inside a Shortcode Attribute, please use <a href="http://www.base64encode.org/" target="_blank" rel="external">this tool</a> to base64 encode your Advanced Option Blocks, so that you end up with a string that\'s compatible with Shortcode Attributes.</li>'."\n";
|
645 |
+
echo '<li>Please check the <strong>Shortcode Attributes</strong> Tab in <a href="http://www.s2member.com/kb/jwplayer-s2stream-shortcodes/#using-s2stream-shortcodes" target="_blank" rel="external">this KB article</a> for further details on everything here.</li>'."\n";
|
646 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs_s2stream_lis", get_defined_vars());
|
647 |
+
echo '</ul>'."\n";
|
648 |
+
echo '</td>'."\n";
|
649 |
+
|
650 |
+
echo '</tr>'."\n";
|
651 |
+
echo '</tbody>'."\n";
|
652 |
+
echo '</table>'."\n";
|
653 |
+
|
654 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
655 |
+
|
656 |
+
echo '<h4 style="margin:0;"><code>[s2Key /]</code> Shortcode Attributes:</h4>'."\n";
|
657 |
+
echo '<p style="margin:0;"><strong>See also:</strong> API Function <a href="http://www.s2member.com/codex/stable/s2member/api_functions/package-functions/#src_doc_s2member_file_download_key()" target="_blank" rel="external">s2member_file_download_key()</a> for PHP integration.</p>'."\n";
|
658 |
+
echo '<table class="form-table" style="margin-top:0;">'."\n";
|
659 |
+
echo '<tbody>'."\n";
|
660 |
+
echo '<tr style="padding-top:0;">'."\n";
|
661 |
+
|
662 |
+
echo '<td style="padding-top:0;">'."\n";
|
663 |
+
echo '<ul class="ws-menu-page-li-margins">'."\n";
|
664 |
+
echo '<li><code>file_download="file.zip"</code> Location of the file, relative to the <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/</code> directory; or, relative to the root of your Amazon S3 Bucket, when applicable.</li>'."\n";
|
665 |
+
echo '<li><code>directive=""</code> Defaults to <code>[empty]</code>. If <code>directive="ip-forever|universal"</code>, s2Member will return a special File Download Key. If you set <code>directive="ip-forever"</code>, the File Download Key that s2Member generates will last forever, for a specific IP Address; otherwise, by default, all File Download Keys expire after 24 hours automatically. If you set <code>directive="universal"</code>, s2Member will generate a File Download Key that is good for anyone/everyone forever, with NO restrictions on who/where/when a file is accessed <em>(be careful with this one)</em>.</li>'."\n";
|
666 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_shortcode_attrs_s2key_lis", get_defined_vars());
|
667 |
+
echo '</ul>'."\n";
|
668 |
+
echo '</td>'."\n";
|
669 |
+
|
670 |
+
echo '</tr>'."\n";
|
671 |
+
echo '</tbody>'."\n";
|
672 |
+
echo '</table>'."\n";
|
673 |
+
echo '</div>'."\n";
|
674 |
+
|
675 |
+
echo '</div>'."\n";
|
676 |
+
|
677 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_shortcode_attrs", get_defined_vars());
|
678 |
+
}
|
679 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_gzip_conflicts", TRUE, get_defined_vars()))
|
680 |
+
{
|
681 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_gzip_conflicts", get_defined_vars());
|
682 |
|
683 |
+
echo '<div class="ws-menu-page-group" title="Preventing GZIP Conflicts On Server">'."\n";
|
|
|
|
|
|
|
|
|
684 |
|
685 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-gzip-conflicts-section">'."\n";
|
686 |
+
echo '<h3>Preventing GZIP Conflicts On Server (Instructions)</h3>'."\n";
|
687 |
+
echo '<p>Protected files served by s2Member through PHP scripts, are already compressed. Therefore, <a href="http://code.google.com/speed/articles/gzip.html" target="_blank" rel="nofollow external xlink">GZIP compression</a> is not needed during protected file delivery. Some web servers (i.e. Apache, LiteSpeed, and similar) include GZIP compression rules through server-side extensions, like <code>mod_deflate</code> for example. While s2Member encourages the use of extensions like <code>mod_deflate</code>, it is best to disable GZIP automatically (i.e. temporarily) during s2Member\'s delivery of a protected file through a PHP script. This avoids conflicts on the server which might otherwise lead to corrupted file downloads. s2Member makes a valiant effort to accomplish this via PHP, all on its own. However, it never hurts to add this section of code to the root <code>.htaccess</code> file for your WordPress installation. Optional, but highly recommended.</p>'."\n";
|
688 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_gzip_conflicts", get_defined_vars());
|
689 |
|
690 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
691 |
|
692 |
+
echo '<p style="margin:0; font-weight:bold;">s2Member automatically adds this to your <code>.htaccess</code> file upon activation of the plugin.</p>'."\n";
|
693 |
+
echo '<p style="margin:0;">The following <code>mod_rewrite</code> rule goes inside this file: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path(ABSPATH.".htaccess")).'</code></p>'."\n";
|
694 |
+
echo '<pre class="code"><code>'.esc_html(trim(c_ws_plugin__s2member_utilities::evl(file_get_contents($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_no_gzip_htaccess"])))).'</code></pre>';
|
695 |
+
echo '<p><strong>* Tip:</strong> this covers all types of integration with s2Member File Downloads, even if you\'re using s2Member\'s Advanced Mod Rewrite Linkage.</p>'."\n";
|
696 |
|
697 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
698 |
|
699 |
+
echo '<table class="form-table">'."\n";
|
700 |
+
echo '<tbody>'."\n";
|
701 |
+
echo '<tr>'."\n";
|
702 |
|
703 |
+
echo '<th>'."\n";
|
704 |
+
echo '<label for="ws-plugin--s2member-file-download-content-encodong-none">'."\n";
|
705 |
+
echo 'Also Force a <code>Content-Encoding: none</code> Header?'."\n";
|
706 |
+
echo '</label>'."\n";
|
707 |
+
echo '</th>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
708 |
|
709 |
+
echo '</tr>'."\n";
|
710 |
+
echo '<tr>'."\n";
|
|
|
711 |
|
712 |
+
echo '<td>'."\n";
|
713 |
+
echo '<select name="ws_plugin__s2member_file_download_content_encodong_none" id="ws-plugin--s2member-file-download-content-encodong-none">'."\n";
|
714 |
+
echo '<option value="0"'.((!$GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_content_encodong_none"]) ? ' selected="selected"' : '').'>No (remain standards-compliant; I will configure my server properly)</option>'."\n";
|
715 |
+
echo '<option value="1"'.(($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["file_download_content_encodong_none"]) ? ' selected="selected"' : '').'>Yes (my web server is stubborn; downloads are corrupted without this)</option>'."\n";
|
716 |
+
echo '</select>'."\n";
|
717 |
+
echo '</td>'."\n";
|
718 |
|
719 |
+
echo '</tr>'."\n";
|
720 |
+
echo '</tbody>'."\n";
|
721 |
+
echo '</table>'."\n";
|
722 |
|
723 |
+
echo '<p><code>Content-Encoding: none</code> can be forced by s2Member in order to workaround stubborn web server configurations. However, please note that <code>Content-Encoding: none</code> is an invalid header (NOT standards compliant), so don\'t enable this unless you absolutely need to. For instance, if files downloaded via s2Member are always corrupt, you could enable this to workaround the issue. The issue being... that your web server is ignoring all of s2Member\'s attempts to serve a file without Content-Encoding. While <code>Content-Encoding: none</code> is indeed a hack, it\'s a relatively common hack that most modern browsers will understand just fine; making this a viable solution when/if necessary.</p>'."\n";
|
724 |
+
echo '</div>'."\n";
|
725 |
|
726 |
+
echo '</div>'."\n";
|
|
|
|
|
727 |
|
728 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_gzip_conflicts", get_defined_vars());
|
729 |
+
}
|
730 |
+
if(apply_filters("ws_plugin__s2member_during_down_ops_page_during_left_sections_display_custom_capability_files", (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars()))
|
731 |
+
{
|
732 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_before_custom_capability_files", get_defined_vars());
|
733 |
|
734 |
+
echo '<div class="ws-menu-page-group" title="Custom Capability & Member Level Files">'."\n";
|
|
|
|
|
|
|
|
|
735 |
|
736 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-custom-capability-files-section">'."\n";
|
737 |
+
echo '<h3>Restricting Files, Based On Custom Capabilities</h3>'."\n";
|
738 |
+
echo '<p>If you\'re NOT familiar with Custom Capabilities yet, please read: <code>Dashboard -› s2Member -› API Scripting -› Custom Capability Packages</code>. Once you understand the basic concept of Custom Capabilities & Protected File Downloads, you\'ll see that (by default) s2Member does NOT handle File Download Protection with respect to Custom Capabilities. That\'s where Custom Capability Sub-directories come in.</p>'."\n";
|
739 |
+
echo '<p>You can create Custom Capability Sub-directories under: <code>'.esc_html(c_ws_plugin__s2member_utils_dirs::doc_root_path($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'</code>. For instance, if you have a Custom Capability <code>music</code>, you can place protected files that should ONLY be accessible to Members with <code>access_s2member_ccap_music</code>, inside: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-ccap-music/</code>. Some examples are provided below.</p>'."\n";
|
740 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_during_custom_capability_files", get_defined_vars());
|
741 |
|
742 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
|
|
|
|
|
|
743 |
|
744 |
+
echo '<p><strong>Custom Capabilities:</strong> (music,videos)</p>'."\n";
|
745 |
+
echo '<p>Sub-Directory: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-ccap-music</code><br />Sub-Directory: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-ccap-videos</code></p>'."\n";
|
746 |
+
echo '<p>Protected File: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-ccap-music/file.mp3</code><br />Protected File: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-ccap-videos/file.avi</code></p>'."\n";
|
747 |
+
echo '<p>Now, here are some link examples, using Custom Capability Sub-directories:</p>'."\n";
|
748 |
+
echo '<p>'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/ccap-file-downloads.x-php")).'</p>'."\n";
|
749 |
+
echo '<p><em>These links will ONLY work for Members who are logged-in, with the proper Capabilities.</em></p>'."\n";
|
750 |
|
751 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
752 |
|
753 |
+
echo '<p><strong>Membership Levels:</strong> (this also works fine)</p>'."\n";
|
754 |
+
echo '<p>Sub-Directory: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level0</code><br />Sub-Directory: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level1</code><br />Sub-Directory: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level2</code><br />Sub-Directory: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level3</code><br />Sub-Directory: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level4</code></p>'."\n";
|
755 |
+
echo '<p>Protected File: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level0/tiger.doc</code><br />Protected File: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level1/zebra.pdf</code><br />Protected File: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level2/elephant.doc</code><br />Protected File: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level3/rhino.pdf</code><br />Protected File: <code>/'.esc_html(c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"])).'/access-s2member-level4/lion.doc</code></p>'."\n";
|
756 |
+
echo '<p>Now, here are some link examples, using Member Level Sub-directories:</p>'."\n";
|
757 |
+
echo '<p>'.c_ws_plugin__s2member_utils_strings::highlight_php(file_get_contents(dirname(__FILE__)."/code-samples/level-file-downloads.x-php")).'</p>'."\n";
|
758 |
+
echo '<p><em>These links will ONLY work for Members who are logged-in, with an adequate Membership Level.</em></p>'."\n";
|
759 |
+
echo '</div>'."\n";
|
760 |
|
761 |
+
echo '</div>'."\n";
|
|
|
762 |
|
763 |
+
do_action("ws_plugin__s2member_during_down_ops_page_during_left_sections_after_custom_capability_files", get_defined_vars());
|
764 |
+
}
|
765 |
+
do_action("ws_plugin__s2member_during_down_ops_page_after_left_sections", get_defined_vars());
|
766 |
|
767 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
768 |
|
769 |
+
echo '<p class="submit"><input type="submit" value="Save All Changes" /></p>'."\n";
|
770 |
|
771 |
+
echo '</form>'."\n";
|
772 |
|
773 |
+
echo '</td>'."\n";
|
774 |
|
775 |
+
echo '<td class="ws-menu-page-table-r">'."\n";
|
776 |
+
c_ws_plugin__s2member_menu_pages_rs::display();
|
777 |
+
echo '</td>'."\n";
|
778 |
|
779 |
+
echo '</tr>'."\n";
|
780 |
+
echo '</tbody>'."\n";
|
781 |
+
echo '</table>'."\n";
|
782 |
|
783 |
+
echo '</div>'."\n";
|
784 |
+
}
|
|
|
785 |
}
|
786 |
+
}
|
787 |
|
788 |
+
new c_ws_plugin__s2member_menu_page_down_ops();
|
|
includes/menu-pages/gen-ops.inc.php
CHANGED
@@ -125,6 +125,13 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
|
|
125 |
echo '</tr>'."\n";
|
126 |
echo '</tbody>'."\n";
|
127 |
echo '</table>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
echo '</div>'."\n";
|
129 |
|
130 |
echo '</div>'."\n";
|
@@ -1264,7 +1271,7 @@ if(!class_exists("c_ws_plugin__s2member_menu_page_gen_ops"))
|
|
1264 |
|
1265 |
echo '<td>'."\n";
|
1266 |
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_login_redirection_override" id="ws-plugin--s2member-login-redirection-override" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"]).'" /><br />'."\n";
|
1267 |
-
echo 'Or, you may configure a Special Redirection URL, if you prefer. You\'ll need to type in the full URL, starting with: <code>http://</code>. <em>A few <a href="#" onclick="alert(\'Replacement Codes:\\n\\n%%current_user_login%% = The current User\\\'s Username, lowercase.\\n%%current_user_id%% = The current User\\\'s ID.\\n%%current_user_level%% = The current User\\\'s s2Member Level.\\n%%current_user_role%% = The current User\\\'s WordPress Role.'.((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? '\\n%%current_user_ccaps%% = The current User\\\'s Custom Capabilities.' : '').'\\n%%current_user_logins%% = Number of times the current User has logged in.\\n\\nFor example, if you\\\'re using BuddyPress, and you want to redirect Members to their BuddyPress Profile page after logging in, you would setup a Special Redirection URL, like this: '.site_url("/members/%%
|
1268 |
echo '</td>'."\n";
|
1269 |
|
1270 |
echo '</tr>'."\n";
|
125 |
echo '</tr>'."\n";
|
126 |
echo '</tbody>'."\n";
|
127 |
echo '</table>'."\n";
|
128 |
+
|
129 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
130 |
+
|
131 |
+
echo '<h3>Additional Details Regarding this Key:</h3>'."\n";
|
132 |
+
echo '<p>Your Security Encryption Key is used throughout s2Member\'s source code for many different things. However, MOST (not all, but most) uses of this Key are related to transactional processing within a particular session; so changing the Key won\'t really impact these scenarios in any significant way. Your Security Encryption Key is simply there to enhance security of data that is being transmitted in these cases.</p>'."\n";
|
133 |
+
echo '<p>That said, there are a few scenarios where use of your Security Encryption Key is more long-term. These include: Specific Post/Page Access Links, Registration Access Links, and it can also have a long-term impact on IPN communication because some data analyzed by s2Member includes a checksum that depends on your Key. If the Key changes, it could cause future IPN data (i.e. data from your payment gateway) to fail validation.</p>'."\n";
|
134 |
+
|
135 |
echo '</div>'."\n";
|
136 |
|
137 |
echo '</div>'."\n";
|
1271 |
|
1272 |
echo '<td>'."\n";
|
1273 |
echo '<input type="text" autocomplete="off" name="ws_plugin__s2member_login_redirection_override" id="ws-plugin--s2member-login-redirection-override" value="'.format_to_edit($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["login_redirection_override"]).'" /><br />'."\n";
|
1274 |
+
echo 'Or, you may configure a Special Redirection URL, if you prefer. You\'ll need to type in the full URL, starting with: <code>http://</code>. <em>A few <a href="#" onclick="alert(\'Replacement Codes:\\n\\n%%current_user_login%% = The current User\\\'s Username, lowercase (deprecated, please use %%current_user_nicename%%).\\n\\n%%current_user_nicename%% = The current User\\\'s Nicename in lowercase format (i.e. a cleaner version of the username for URLs; recommended for best compatibility).\\n\\n%%current_user_id%% = The current User\\\'s ID.\\n\\n%%current_user_level%% = The current User\\\'s s2Member Level.\\n\\n%%current_user_role%% = The current User\\\'s WordPress Role.'.((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? '\\n\\n%%current_user_ccaps%% = The current User\\\'s Custom Capabilities.' : '').'\\n\\n%%current_user_logins%% = Number of times the current User has logged in.\\n\\nFor example, if you\\\'re using BuddyPress, and you want to redirect Members to their BuddyPress Profile page after logging in, you would setup a Special Redirection URL, like this: '.site_url("/members/%%current_user_nicename%%/profile/").'\\n\\nOr ... using %%current_user_level%%, you could have a separate Login Welcome Page for each Membership Level that you plan to offer. BuddyPress not required.\'); return false;">Replacement Codes</a> are also supported here.</em>'."\n";
|
1275 |
echo '</td>'."\n";
|
1276 |
|
1277 |
echo '</tr>'."\n";
|
includes/menu-pages/integrations.inc.php
CHANGED
@@ -1,101 +1,99 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* Menu page for the s2Member plugin (Integrations page).
|
4 |
-
*
|
5 |
-
* Copyright: © 2009-2011
|
6 |
-
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
-
* (coded in the USA)
|
8 |
-
*
|
9 |
-
* Released under the terms of the GNU General Public License.
|
10 |
-
* You should have received a copy of the GNU General Public License,
|
11 |
-
* along with this software. In the main directory, see: /licensing/
|
12 |
-
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
-
*
|
14 |
-
* @package s2Member\Menu_Pages
|
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_integrations"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
{
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
* @package s2Member\Menu_Pages
|
26 |
-
* @since 110531
|
27 |
-
*/
|
28 |
-
class c_ws_plugin__s2member_menu_page_integrations
|
29 |
-
{
|
30 |
-
public function __construct()
|
31 |
-
{
|
32 |
-
echo '<div class="wrap ws-menu-page">'."\n";
|
33 |
-
|
34 |
-
echo '<div class="ws-menu-page-toolbox">'."\n";
|
35 |
-
c_ws_plugin__s2member_menu_pages_tb::display ();
|
36 |
-
echo '</div>'."\n";
|
37 |
|
38 |
-
|
|
|
|
|
39 |
|
40 |
-
|
41 |
-
echo '<tbody class="ws-menu-page-table-tbody">'."\n";
|
42 |
-
echo '<tr class="ws-menu-page-table-tr">'."\n";
|
43 |
-
echo '<td class="ws-menu-page-table-l">'."\n";
|
44 |
|
45 |
-
|
|
|
|
|
|
|
46 |
|
47 |
-
|
48 |
-
{
|
49 |
-
do_action("ws_plugin__s2member_during_integrations_page_during_left_sections_before_bbpress", get_defined_vars());
|
50 |
|
51 |
-
|
|
|
|
|
52 |
|
53 |
-
|
54 |
-
echo '<h3>bbPress Plugin Integration (easy peasy)</h3>'."\n";
|
55 |
-
echo '<input type="button" value="Update Roles/Capabilities" class="ws-menu-page-right ws-plugin--s2member-update-roles-button" style="min-width:175px;" />'."\n";
|
56 |
-
echo '<p>The plugin version of <a href="http://www.s2member.com/bbpress-plugin" target="_blank" rel="external">bbPress 2.0+</a> integrates seamlessly with WordPress. If bbPress was already installed when you activated s2Member, your s2Member Roles/Capabilities are already configured to work in harmony with bbPress. If you didn\'t, you can simply click the "Update Roles/Capabilities" button here. That\'s all it takes. Once your Roles/Capbilities are updated, s2Member and bbPress are fully integrated with each other.</p>'."\n";
|
57 |
-
echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/roles-caps/#s2-roles-caps" target="_blank" rel="external">s2Member Roles/Capabilities (Including <strong>bbPress</strong> Support)</a>.</p>'."\n";
|
58 |
|
59 |
-
|
|
|
|
|
|
|
|
|
60 |
|
61 |
-
|
62 |
-
echo '<p>s2Member configures your Membership Roles (by default, these include: <em>s2Member Level 1</em>, <em>s2Member Level 2</em>, <em>s2Member Level 3</em>, <em>s2Member Level 4</em>), with a default set of bbPress permissions that allow all Members to both spectate and particpate in your forums, just as if they were a WordPress Subscriber Role (or a bbPress Participant Role).</p>'."\n";
|
63 |
-
echo '<p>bbPress also adds some new Roles (dynamic Roles in bbPress 2.2+) to your WordPress installation. These include but are not limited to: <em>Keymaster</em> and <em>Moderator</em>. s2Member allows Forum Keymasters & Moderators full access to the highest Membership Level you offer; just like it does with <em>Administrators</em>, <em>Editors</em>, <em>Authors</em>, and <em>Contributors</em>.</p>'."\n";
|
64 |
-
echo '<p><strong>Membership Levels provide incremental access:</strong></p>'."\n";
|
65 |
-
echo '<p>* A Member with Level 4 access, will also be able to access Levels 0, 1, 2 & 3 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Member with Level 3 access, will also be able to access Levels 0, 1 & 2 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Member with Level 2 access, will also be able to access Levels 0 & 1 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Member with Level 1 access, will also be able to access Level 0 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Subscriber with Level 0 access, will ONLY be able to access Level 0 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A public Visitor will have NO access to protected content <em>(and no special access to bbPress Forums)</em>.</p>'."\n";
|
66 |
-
echo '<p><em>* WordPress Subscribers <strong class="ws-menu-page-hilite">and bbPress Spectators/Participants</strong> are at Membership Level 0. If you\'re allowing Open Registration via s2Member, Subscribers will be at Level 0 (a Free Subscriber).</em></p>'."\n";
|
67 |
-
echo '<p><em>* WordPress Administrators, Editors, Authors, Contributors, <strong class="ws-menu-page-hilite">and bbPress Keymasters/Moderators</strong> have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>'."\n";
|
68 |
|
69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
|
71 |
-
|
72 |
-
echo '<p>You can protect individual Forum Topics/Posts/Replies at different Levels with s2Member, or even with Custom Capabilities. Forum Topics/Posts/Replies are integrated by bbPress internally as "Custom Post Types", which can be protected by s2Member either through Post Level Access Restrictions, or through URI Level Access Restrictions (recommended). If you choose to use Post Level Access Restrictions, please remember that s2Member will provide you with drop-down menus whenever you add or edit Forum Topics/Posts/Replies to make things easier for you.</p>'."\n";
|
73 |
-
echo '<p>Regarding s2Member\'s Post Level Access Restrictions with bbPress. Before you decide to use Post Level Access Restrictions, please take a look at: <code>s2Member -› Restriction Options -› URI Access Restrictions</code> and consider the following limitations in the current release of s2Member. It is currently NOT possible to protect a Forum, and have all Topics inside that Forum protected automatically. In order to accomplish that, you\'ll need to use s2Member\'s URI Access Restrictions. Also, s2Member is currently NOT capable of protecting Topic Tags; but you can use URI Restrictions for these also.</p>'."\n";
|
74 |
|
75 |
-
|
76 |
-
|
|
|
77 |
|
78 |
-
|
|
|
79 |
|
80 |
-
|
81 |
-
}
|
82 |
|
83 |
-
|
|
|
|
|
84 |
|
85 |
-
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
}
|
98 |
}
|
|
|
99 |
|
100 |
-
new c_ws_plugin__s2member_menu_page_integrations();
|
101 |
-
?>
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Menu page for the s2Member plugin (Integrations page).
|
4 |
+
*
|
5 |
+
* Copyright: © 2009-2011
|
6 |
+
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
|
7 |
+
* (coded in the USA)
|
8 |
+
*
|
9 |
+
* Released under the terms of the GNU General Public License.
|
10 |
+
* You should have received a copy of the GNU General Public License,
|
11 |
+
* along with this software. In the main directory, see: /licensing/
|
12 |
+
* If not, see: {@link http://www.gnu.org/licenses/}.
|
13 |
+
*
|
14 |
+
* @package s2Member\Menu_Pages
|
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_integrations"))
|
21 |
+
{
|
22 |
+
/**
|
23 |
+
* Menu page for the s2Member plugin (Integrations page).
|
24 |
+
*
|
25 |
+
* @package s2Member\Menu_Pages
|
26 |
+
* @since 110531
|
27 |
+
*/
|
28 |
+
class c_ws_plugin__s2member_menu_page_integrations
|
29 |
{
|
30 |
+
public function __construct()
|
31 |
+
{
|
32 |
+
echo '<div class="wrap ws-menu-page">'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
+
echo '<div class="ws-menu-page-toolbox">'."\n";
|
35 |
+
c_ws_plugin__s2member_menu_pages_tb::display();
|
36 |
+
echo '</div>'."\n";
|
37 |
|
38 |
+
echo '<h2>Other Integrations</h2>'."\n";
|
|
|
|
|
|
|
39 |
|
40 |
+
echo '<table class="ws-menu-page-table">'."\n";
|
41 |
+
echo '<tbody class="ws-menu-page-table-tbody">'."\n";
|
42 |
+
echo '<tr class="ws-menu-page-table-tr">'."\n";
|
43 |
+
echo '<td class="ws-menu-page-table-l">'."\n";
|
44 |
|
45 |
+
do_action("ws_plugin__s2member_during_integrations_page_before_left_sections", get_defined_vars());
|
|
|
|
|
46 |
|
47 |
+
if(apply_filters("ws_plugin__s2member_during_integrations_page_during_left_sections_display_bbpress", TRUE, get_defined_vars()))
|
48 |
+
{
|
49 |
+
do_action("ws_plugin__s2member_during_integrations_page_during_left_sections_before_bbpress", get_defined_vars());
|
50 |
|
51 |
+
echo '<div class="ws-menu-page-group" title="bbPress Plugin Integration (2.0+ plugin version)" default-state="open">'."\n";
|
|
|
|
|
|
|
|
|
52 |
|
53 |
+
echo '<div class="ws-menu-page-section ws-plugin--s2member-bbpress-section">'."\n";
|
54 |
+
echo '<h3>bbPress Plugin Integration (easy peasy)</h3>'."\n";
|
55 |
+
echo '<input type="button" value="Update Roles/Capabilities" class="ws-menu-page-right ws-plugin--s2member-update-roles-button" style="min-width:175px;" />'."\n";
|
56 |
+
echo '<p>The plugin version of <a href="http://www.s2member.com/bbpress-plugin" target="_blank" rel="external">bbPress 2.0+</a> integrates seamlessly with WordPress. If bbPress was already installed when you activated s2Member, your s2Member Roles/Capabilities are already configured to work in harmony with bbPress. If you didn\'t, you can simply click the "Update Roles/Capabilities" button here. That\'s all it takes. Once your Roles/Capbilities are updated, s2Member and bbPress are fully integrated with each other.</p>'."\n";
|
57 |
+
echo '<p><strong>See also:</strong> This KB article: <a href="http://www.s2member.com/kb/roles-caps/#s2-roles-caps" target="_blank" rel="external">s2Member Roles/Capabilities (Including <strong>bbPress</strong> Support)</a>.</p>'."\n";
|
58 |
|
59 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
+
echo '<h3>bbPress Forums and s2Member Roles/Capabilities</h3>'."\n";
|
62 |
+
echo '<p>s2Member configures your Membership Roles (by default, these include: <em>s2Member Level 1</em>, <em>s2Member Level 2</em>, <em>s2Member Level 3</em>, <em>s2Member Level 4</em>), with a default set of bbPress permissions that allow all Members to both spectate and particpate in your forums, just as if they were a WordPress Subscriber Role (or a bbPress Participant Role).</p>'."\n";
|
63 |
+
echo '<p>bbPress also adds some new Roles (dynamic Roles in bbPress 2.2+) to your WordPress installation. These include but are not limited to: <em>Keymaster</em> and <em>Moderator</em>. s2Member allows Forum Keymasters & Moderators full access to the highest Membership Level you offer; just like it does with <em>Administrators</em>, <em>Editors</em>, <em>Authors</em>, and <em>Contributors</em>.</p>'."\n";
|
64 |
+
echo '<p><strong>Membership Levels provide incremental access:</strong></p>'."\n";
|
65 |
+
echo '<p>* A Member with Level 4 access, will also be able to access Levels 0, 1, 2 & 3 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Member with Level 3 access, will also be able to access Levels 0, 1 & 2 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Member with Level 2 access, will also be able to access Levels 0 & 1 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Member with Level 1 access, will also be able to access Level 0 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A Subscriber with Level 0 access, will ONLY be able to access Level 0 <em>(plus spectate/participate in bbPress Forums)</em>.<br />* A public Visitor will have NO access to protected content <em>(and no special access to bbPress Forums)</em>.</p>'."\n";
|
66 |
+
echo '<p><em>* WordPress Subscribers <strong class="ws-menu-page-hilite">and bbPress Spectators/Participants</strong> are at Membership Level 0. If you\'re allowing Open Registration via s2Member, Subscribers will be at Level 0 (a Free Subscriber).</em></p>'."\n";
|
67 |
+
echo '<p><em>* WordPress Administrators, Editors, Authors, Contributors, <strong class="ws-menu-page-hilite">and bbPress Keymasters/Moderators</strong> have Level 4 access, with respect to s2Member. All of their other Roles/Capabilities are left untouched.</em></p>'."\n";
|
68 |
|
69 |
+
echo '<div class="ws-menu-page-hr"></div>'."\n";
|
|
|
|
|
70 |
|
71 |
+
echo '<h3>Protecting Content Introduced by bbPress</h3>'."\n";
|
72 |
+
echo '<p>You can protect individual Forum Topics/Posts/Replies at different Levels with s2Member, or even with Custom Capabilities. Forum Topics/Posts/Replies are integrated by bbPress internally as "Custom Post Types", which can be protected by s2Member either through Post Level Access Restrictions, or through URI Level Access Restrictions. If you choose to use Post Level Access Restrictions, please remember that s2Member will provide you with drop-down menus whenever you add or edit Forum Topics/Posts/Replies to make things easier for you.</p>'."\n";
|
73 |
+
echo '<p>You\'ll be happy to know that protecting a bbPress Forum will also (automatically) protect all Topics within that Forum. In other words, if you require a certain Membership Level to access a particular bbPress Forum (or if you require a certain Custom Capability to access a particular Forum), all Topics in that Forum will also require the same.</p>'."\n";
|
74 |
|
75 |
+
do_action("ws_plugin__s2member_during_integrations_page_during_left_sections_during_bbpress", get_defined_vars());
|
76 |
+
echo '</div>'."\n";
|
77 |
|
78 |
+
echo '</div>'."\n";
|
|
|
79 |
|
80 |
+
do_action("ws_plugin__s2member_during_integrations_page_during_left_sections_after_bbpress", get_defined_vars());
|
81 |
+
}
|
82 |
+
do_action("ws_plugin__s2member_during_integrations_page_after_left_sections", get_defined_vars());
|
83 |
|
84 |
+
echo '</td>'."\n";
|
85 |
|
86 |
+
echo '<td class="ws-menu-page-table-r">'."\n";
|
87 |
+
c_ws_plugin__s2member_menu_pages_rs::display();
|
88 |
+
echo '</td>'."\n";
|
89 |
|
90 |
+
echo '</tr>'."\n";
|
91 |
+
echo '</tbody>'."\n";
|
92 |
+
echo '</table>'."\n";
|
93 |
|
94 |
+
echo '</div>'."\n";
|
95 |
+
}
|
|
|
96 |
}
|
97 |
+
}
|
98 |
|
99 |
+
new c_ws_plugin__s2member_menu_page_integrations();
|
|
includes/menu-pages/menu-pages-s-min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
jQuery(document).ready(function($){var esc_attr=esc_html=function(string){if(/[&\<\>"']/.test(string=String(string))){string=string.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),string=string.replace(/"/g,""").replace(/'/g,"'")}return string};if(location.href.match(/page\=ws-plugin--s2member/)){$("input.ws-plugin--s2member-update-roles-button, input.ws-plugin--s2member-reset-roles-button").click(function(){var $this=$(this);$this.val("one moment please ...");var levels='<?php echo (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; ?>';var resetUpdate=($this.hasClass("ws-plugin--s2member-reset-roles-button"))?"Reset":"Update";$.post(ajaxurl,{action:"ws_plugin__s2member_update_roles_via_ajax",ws_plugin__s2member_update_roles_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-update-roles-via-ajax")); ?>'},function(response){if(response==="1"){alert("s2Member's Roles/Capabilities "+((resetUpdate.toLowerCase()==="reset")?"have been successfully reset":"updated successfully")+".\nYour installation of s2Member has Membership Levels 0-"+levels+"."),$this.val(resetUpdate+" Roles/Capabilities")}else{if(response==="l"){alert("Sorry, your request failed.\ns2Member's Roles/Capabilities are locked by Filter:\nws_plugin__s2member_lock_roles_caps"),$this.val(resetUpdate+" Roles/Capabilities")}else{alert("Sorry, your request failed.\nAccess denied. Do you have the ability to `create_users`?"),$this.val(resetUpdate+" Roles/Capabilities")}}});return false})}if(location.href.match(/page\=ws-plugin--s2member-logs/)){$("input#ws-plugin--s2member-gateway-debug-logs-extensive-1").click(function(){var $this=$(this),thisChecked=(this.checked)?true:false;if(thisChecked){$("input#ws-plugin--s2member-gateway-debug-logs-1").attr("checked","checked")}});var $toggles=$("a.ws-plugin--s2member-log-file-viewport-toggle");$toggles.click(function(){$("textarea#ws-plugin--s2member-log-file-viewer").each(function(){var $viewer=$(this);if($viewer.attr("data-state")!=="expanded"){$viewer.css({height:($viewer.prop("scrollHeight")+50)+"px","overflow-y":"auto"});$toggles.html("⇑ normalize viewport ❙");$viewer.attr("data-state","expanded")}else{$viewer.css({height:"auto","overflow-y":"scroll"});$toggles.html("⇓ expand viewport ⇓");$viewer.attr("data-state","scrolling")}});return false})}if(location.href.match(/page\=ws-plugin--s2member-mms-ops/)){$("select#ws-plugin--s2member-mms-registration-file").change(function(){if($(this).val()==="wp-signup"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").show(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").hide(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").show();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0")[((gv==="all")?"show":"hide")]();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val(((gv==="all")?((l0v>0)?l0v:"1"):"0"))}else{if($(this).val()==="wp-login"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").hide(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").show(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").hide();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0").hide();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val("0")}}}).trigger("change");$("select#ws-plugin--s2member-mms-registration-grants").change(function(){$("select#ws-plugin--s2member-mms-registration-file").trigger("change")})}if(location.href.match(/page\=ws-plugin--s2member-gen-ops/)){ws_plugin__s2member_generateSecurityKey=function(){var mt_rand=function(min,max){min=(arguments.length<1)?0:min;max=(arguments.length<2)?2147483647:max;return Math.floor(Math.random()*(max-min+1))+min};var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()";for(var i=0,key="";i<64;i++){key+=chars.substr(mt_rand(0,chars.length-1),1)}$("input#ws-plugin--s2member-sec-encryption-key").val(key);return false};ws_plugin__s2member_enableSecurityKey=function(){if(confirm("Edit Key? Are you sure?\nThis could break your installation!\n\n*Note* If you've been testing s2Member, feel free to change this Key before you go live. Just don't go live, and then change it. You'll have unhappy Customers. Data corruption WILL occur! For your safety, s2Member keeps a history of the last 10 Keys that you've used. If you get yourself into a real situation, s2Member will let you revert back to a previous Key.")){$("input#ws-plugin--s2member-sec-encryption-key").removeAttr("disabled")}return false};ws_plugin__s2member_securityKeyHistory=function(){$("div#ws-plugin--s2member-sec-encryption-key-history").toggle();return false};$("select#ws-plugin--s2member-new-user-emails-enabled").change(function(){var $pluggable=$("input#ws-plugin--s2member-pluggables-wp-new-user-notification"),$this=$(this),$newUserEmails=$("div#ws-plugin--s2member-new-user-emails");if($pluggable.val()==="0"||$this.val()==="0"){($pluggable.val()==="0")?$this.attr("disabled","disabled"):$this.removeAttr("disabled");$(":input",$newUserEmails).attr("disabled","disabled"),$newUserEmails.css("opacity","0.5")}else{$this.removeAttr("disabled"),$(":input",$newUserEmails).removeAttr("disabled"),$newUserEmails.css("opacity","")}}).trigger("change");$("select#ws-plugin--s2member-login-reg-design-enabled").change(function(){var $this=$(this),$loginRegDesign=$("div#ws-plugin--s2member-login-reg-design");if($this.val()==="0"){$(":input",$loginRegDesign).attr("disabled","disabled"),$loginRegDesign.css("opacity","0.5"),$loginRegDesign.hide()}else{$(":input",$loginRegDesign).removeAttr("disabled"),$loginRegDesign.css("opacity",""),$loginRegDesign.show()}}).trigger("change");if($("input#ws-plugin--s2member-custom-reg-fields").length&&$("div#ws-plugin--s2member-custom-reg-field-configuration").length){(function(){var i,fieldDefaults,tools,table,$tools,$table;var $fields=$("input#ws-plugin--s2member-custom-reg-fields");var $configuration=$("div#ws-plugin--s2member-custom-reg-field-configuration");var fields=($fields.val())?$.JSON.parse($fields.val()):[];fields=(fields instanceof Array)?fields:[];fieldDefaults={section:"no",sectitle:"",id:"",label:"",type:"text",deflt:"",options:"",expected:"",required:"yes",levels:"all",editable:"yes",classes:"",styles:"",attrs:""};for(i=0;i<fields.length;i++){fields[i]=$.extend(true,{},fieldDefaults,fields[i])}tools='<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>',table='<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';$configuration.html(tools+table);$tools=$("div#ws-plugin--s2member-custom-reg-field-configuration-tools"),$table=$("table#ws-plugin--s2member-custom-reg-field-configuration-table");ws_plugin__s2member_customRegFieldSectionChange=function(select){var section=$(select).val();var sectitle_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle";(section==="yes")?$(sectitle_trs).css("display",""):$(sectitle_trs).css("display","none")};ws_plugin__s2member_customRegFieldTypeChange=function(select){var type=$(select).val();var deflt_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt",options_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options",expected_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected";(type.match(/^(text|textarea)$/))?$(deflt_trs).css("display",""):$(deflt_trs).css("display","none");(type.match(/^(select|selects|checkboxes|radios)$/))?$(options_trs).css("display",""):$(options_trs).css("display","none");(type.match(/^(text|textarea)$/))?$(expected_trs).css("display",""):$(expected_trs).css("display","none")};ws_plugin__s2member_customRegFieldDelete=function(index){var newFields=new Array();for(var i=0;i<fields.length;i++){if(i!==index){newFields.push(fields[i])}}fields=newFields,updateFields(),buildTable()};ws_plugin__s2member_customRegFieldMoveUp=function(index){if(typeof fields[index]==="object"&&typeof fields[index-1]==="object"){var prevFieldObj=fields[index-1],thisFieldObj=fields[index];fields[index-1]=thisFieldObj,fields[index]=prevFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldMoveDown=function(index){if(typeof fields[index]==="object"&&typeof fields[index+1]==="object"){var nextFieldObj=fields[index+1],thisFieldObj=fields[index];fields[index+1]=thisFieldObj,fields[index]=nextFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldCreate=function(){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field))){fields.push(field),updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+(fields.length-1);alert('Field created successfully.\n* Remember to "Save All Changes".')},500)}};ws_plugin__s2member_customRegFieldUpdate=function(index){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field,index))){fields[index]=field,updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+index;alert('Field updated successfully.\n* Remember to "Save All Changes".')},500)}};ws_plugin__s2member_customRegFieldAdd=function(){buildTools(true)};ws_plugin__s2member_customRegFieldEdit=function(index){buildTools(false,index),scrollReset()};ws_plugin__s2member_customRegFieldCancel=function(){buildTools(),scrollReset()};var validateField=function(field,index){var editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,errors=[],options,i;if(typeof field!=="object"||typeof(field=$.extend(true,{},fieldDefaults,field))!=="object"){alert("Invalid field object. Please try again.");return false}field.sectitle=(field.section==="yes")?field.sectitle:"";field.deflt=(field.type.match(/^(text|textarea)$/))?field.deflt:"";field.deflt=(field.type.match(/^(text)$/))?field.deflt.replace(/[\r\n\t ]+/g," "):field.deflt;field.options=(field.type.match(/^(select|selects|checkboxes|radios)$/))?field.options:"";field.expected=(field.type.match(/^(text|textarea)$/))?field.expected:"";if(!field.id){errors.push("Unique Field ID:\nThis is required. Please try again.")}else{if(fieldIdExists(field.id)&&(!editing||field.id!==fields[index].id)){errors.push("Unique Field ID:\nThat Field ID already exists. Please try again.")}}if(!field.label){errors.push("Field Label/Description:\nThis is required. Please try again.")}if(field.type.match(/^(select|selects|checkboxes|radios)$/)&&!field.options){errors.push("Option Configuration File:\nThis is required. Please try again.")}else{if(field.type.match(/^(select|selects|checkboxes|radios)$/)){for(i=0;i<(options=field.options.split(/[\r\n]+/)).length;i++){if(!(options[i]=$.trim(options[i])).match(/^([^\|]*)(\|)([^\|]*)(\|default)?$/)){errors.push("Option Configuration File:\nInvalid configuration at line #"+(i+1)+".");break}}field.options=$.trim(options.join("\n"))}}if(!(field.levels=field.levels.replace(/ /g,""))){errors.push("Applicable Levels:\nThis is required. Please try again.")}else{if(!field.levels.match(/^(all|[0-9,]+)$/)){errors.push("Applicable Levels:\nShould be comma-delimited Levels, or just type: all.\n(examples: 0,1,2,3,4 or type the word: all)")}}if(field.classes&&field.classes.match(/[^a-z 0-9 _ \-]/i)){errors.push("CSS Classes:\nContains invalid characters. Please try again.\n(only: alphanumerics, underscores, hyphens, spaces)")}if(field.styles&&field.styles.match(/["\=\>\<]/)){errors.push('CSS Styles:\nContains invalid characters. Please try again.\n(do NOT use these characters: = " < >)')}if(field.attrs&&field.attrs.match(/[\>\<]/)){errors.push("Other Attributes:\nContains invalid characters. Please try again.\n(do NOT use these characters: < >)")}if(errors.length>0){alert(errors.join("\n\n"));return false}else{return field}};var updateFields=function(){$fields.val(((fields.length>0)?$.JSON.stringify(fields):""))};var fieldId2Var=function(fieldId){return(typeof fieldId==="string")?$.trim(fieldId).toLowerCase().replace(/[^a-z0-9]/g,"_"):""};var fieldTypeDesc=function(type){var types={text:"Text (single line)",textarea:"Textarea (multi-line)",select:"Select Menu (drop-down)",selects:"Select Menu (multi-option)",checkbox:"Checkbox (single)",pre_checkbox:"Checkbox (pre-checked)",checkboxes:"Checkboxes (multi-option)",radios:"Radio Buttons (multi-option)"};if(typeof types[type]==="string"){return types[type]}return""};var fieldIdExists=function(fieldId){for(var i=0;i<fields.length;i++){if(fields[i].id===fieldId){return true}}};var scrollReset=function(){scrollTo(0,$("div.ws-plugin--s2member-custom-reg-fields-section").offset()["top"]-100)};var buildTools=function(adding,index){var i=0,html="",form="",w=0,h=0,editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,displayForm=(adding||editing)?true:false,field=(editing)?$.extend(true,{},fieldDefaults,fields[index]):fieldDefaults;html+='<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';tb_remove(),$("div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form").remove();if(displayForm){form+='<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';form+='<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';form+="<tbody>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">Starts A New Section?</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<select property="section" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section" onchange="ws_plugin__s2member_customRegFieldSectionChange(this);">';form+='<option value="no"'+((field.section==="no")?' selected="selected"':"")+'">No (this Field flows normally)</option>';form+='<option value="yes"'+((field.section==="yes")?' selected="selected"':"")+'">Yes (this Field begins a new section)</option>';form+="</select><br />";form+="<small>Optional. Allows Fields to be grouped into sections.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+'><td colspan="2"><hr /></td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+">";form+='<td colspan="2">';form+="Title for this new section? (optional)<br />";form+='<input type="text" property="sectitle" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle" value="'+esc_attr(field.sectitle)+'" /><br />';form+="<small>If empty, a simple divider will be used by default.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-type"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<select property="type" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);">';form+='<option value="text"'+((field.type==="text")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("text"))+"</option>";form+='<option value="textarea"'+((field.type==="textarea")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("textarea"))+"</option>";form+='<option value="select"'+((field.type==="select")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("select"))+"</option>";form+='<option value="selects"'+((field.type==="selects")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("selects"))+"</option>";form+='<option value="checkbox"'+((field.type==="checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkbox"))+"</option>";form+='<option value="pre_checkbox"'+((field.type==="pre_checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("pre_checkbox"))+"</option>";form+='<option value="checkboxes"'+((field.type==="checkboxes")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkboxes"))+"</option>";form+='<option value="radios"'+((field.type==="radios")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("radios"))+"</option>";form+="</select><br />";form+="<small>The options below may change, based on the Field Type you choose here.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-label"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<input type="text" property="label" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" value="'+esc_attr(field.label)+'" /><br />';form+="<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-id"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<input type="text" property="id" maxlength="25" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" value="'+esc_attr(field.id)+'" /><br />';form+="<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />";form+='<small>e.g. <code>[s2Get user_field="country_code" /]</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-required"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<option value="yes"'+((field.required==="yes")?' selected="selected"':"")+'">Yes (required)</option>';form+='<option value="no"'+((field.required==="no")?' selected="selected"':"")+'">No (optional)</option>';form+="</select><br />";form+='<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';form+="<small>* Administrators are exempt from this requirement.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">Default Text Value: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="deflt" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt" rows="1">'+esc_html(field.deflt)+"</textarea><br />";form+="<small>Default value before user input is received.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+'><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * (one option per line)</label><br />';form+="<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="options" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options" rows="3">'+esc_html(field.options)+"</textarea><br />";form+="Here is a quick example:<br />";form+="<small>You can also specify a <em>default</em> option:</small><br />";form+="<code>US|United States|default</code><br />";form+="<code>CA|Canada</code><br />";form+="<code>VI|Virgin Islands (U.S.)</code>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';form+='<option value=""'+((field.expected==="")?' selected="selected"':"")+'">Anything Goes</option>';form+='<option disabled="disabled"></option>';form+='<optgroup label="Specific Input Types">';form+='<option value="numeric-wp-commas"'+((field.expected==="numeric-wp-commas")?' selected="selected"':"")+'">Numeric (with or without decimals, commas allowed)</option>';form+='<option value="numeric"'+((field.expected==="numeric")?' selected="selected"':"")+'">Numeric (with or without decimals, no commas)</option>';form+='<option value="integer"'+((field.expected==="integer")?' selected="selected"':"")+'">Integer (whole number, without any decimals)</option>';form+='<option value="integer-gt-0"'+((field.expected==="integer-gt-0")?' selected="selected"':"")+'">Integer > 0 (whole number, no decimals, greater than 0)</option>';form+='<option value="float"'+((field.expected==="float")?' selected="selected"':"")+'">Float (floating point number, decimals required)</option>';form+='<option value="float-gt-0"'+((field.expected==="float-gt-0")?' selected="selected"':"")+'">Float > 0 (floating point number, decimals required, greater than 0)</option>';form+='<option value="date"'+((field.expected==="date")?' selected="selected"':"")+'">Date (required date format: dd/mm/yyyy)</option>';form+='<option value="email"'+((field.expected==="email")?' selected="selected"':"")+'">Email (require valid email)</option>';form+='<option value="url"'+((field.expected==="url")?' selected="selected"':"")+'">Full URL (starting with http or https)</option>';form+='<option value="domain"'+((field.expected==="domain")?' selected="selected"':"")+'">Domain Name (domain name only, without http)</option>';form+='<option value="phone"'+((field.expected==="phone")?' selected="selected"':"")+'">Phone # (10 digits w/possible hyphens,spaces,brackets)</option>';form+='<option value="uszip"'+((field.expected==="uszip")?' selected="selected"':"")+'">US Zipcode (5-9 digits w/possible hyphen)</option>';form+='<option value="cazip"'+((field.expected==="cazip")?' selected="selected"':"")+'">Canadian Zipcode (6 alpha-numerics w/possible space)</option>';form+='<option value="uczip"'+((field.expected==="uczip")?' selected="selected"':"")+'">US/Canadian Zipcode (either a US or Canadian zipcode)</option>';form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Any Character Combination">';for(i=1;i<=25;i++){form+='<option value="any-'+i+'"'+((field.expected==="any-"+i)?' selected="selected"':"")+'">Any Character Combination ('+i+" character minimum)</option>";form+='<option value="any-'+i+'-e"'+((field.expected==="any-"+i+"-e")?' selected="selected"':"")+'">Any Character Combination (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics, Spaces & Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-punctuation-'+i+'"'+((field.expected==="alphanumerics-spaces-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics, Spaces & Punctuation ('+i+" character minimum)</option>";form+='<option value="alphanumerics-spaces-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-spaces-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics, Spaces & Punctuation (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics & Spaces Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-'+i+'"'+((field.expected==="alphanumerics-spaces-"+i)?' selected="selected"':"")+'">Alphanumerics & Spaces ('+i+" character minimum)</option>";form+='<option value="alphanumerics-spaces-'+i+'-e"'+((field.expected==="alphanumerics-spaces-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics & Spaces (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics & Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-punctuation-'+i+'"'+((field.expected==="alphanumerics-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics & Punctuation ('+i+" character minimum)</option>";form+='<option value="alphanumerics-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics & Punctuation (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-'+i+'"'+((field.expected==="alphanumerics-"+i)?' selected="selected"':"")+'">Alphanumerics ('+i+" character minimum)</option>";form+='<option value="alphanumerics-'+i+'-e"'+((field.expected==="alphanumerics-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphabetics Only">';for(i=1;i<=25;i++){form+='<option value="alphabetics-'+i+'"'+((field.expected==="alphabetics-"+i)?' selected="selected"':"")+'">Alphabetics ('+i+" character minimum)</option>";form+='<option value="alphabetics-'+i+'-e"'+((field.expected==="alphabetics-"+i+"-e")?' selected="selected"':"")+'">Alphabetics (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Numeric Digits Only">';for(i=1;i<=25;i++){form+='<option value="numerics-'+i+'"'+((field.expected==="numerics-"+i)?' selected="selected"':"")+'">Numeric Digits ('+i+" digit minimum)</option>";form+='<option value="numerics-'+i+'-e"'+((field.expected==="numerics-"+i+"-e")?' selected="selected"':"")+'">Numeric Digits (exactly '+i+" digit"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+="</select><br />";form+="<small>Only Users/Members will be required to meet this criteria.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<input type="text" property="levels" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" value="'+esc_attr(field.levels)+'" /><br />';form+="<small>Please use comma-delimited Level #'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />";form+="<small>This allows you to enable this field - only at specific Membership Levels.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<option value="yes"'+((field.editable==="yes")?' selected="selected"':"")+'">Yes (editable)</option>';form+='<option value="no"'+((field.editable==="no")?' selected="selected"':"")+'">No (uneditable after registration)</option>';form+='<option value="no-invisible"'+((field.editable==="no-invisible")?' selected="selected"':"")+'">No (uneditable & totally invisible after registration)</option>';form+='<option value="no-always-invisible"'+((field.editable==="no-always-invisible")?' selected="selected"':"")+'">No (uneditable & totally invisible, both during & after registration)</option>';form+='<option value="yes-invisible"'+((field.editable==="yes-invisible")?' selected="selected"':"")+'">Yes (editable after registration / invisible during registration)</option>';form+="</select><br />";form+="<small>If <code>No</code>, this field will be un-editable after registration.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<input type="text" property="classes" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" value="'+esc_attr(field.classes)+'" /><br />';form+="<small>Example: <code>my-style-1 my-style-2</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<input type="text" property="styles" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" value="'+esc_attr(field.styles)+'" /><br />';form+="<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<input type="text" property="attrs" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" value="'+esc_attr(field.attrs)+'" /><br />';form+='<small>Example: <code>onkeyup="" onblur=""</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';form+='<td align="left">';form+='<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';form+="</td>";form+='<td align="right">';form+='<input type="button" value="'+((editing)?"Update This Field":"Create Registration Field")+'" onclick="'+((editing)?"ws_plugin__s2member_customRegFieldUpdate("+index+");":"ws_plugin__s2member_customRegFieldCreate();")+'" />';form+="</td>";form+="</tr>";form+="</tbody>";form+="</table>";form+="<div>";$("body").append(form);tb_show(((editing)?"Editing Registration/Profile Field":"New Custom Registration/Profile Field"),"#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form");$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form").show()}$tools.html(html)};var buildTable=function(){var l=fields.length,i=0,html="",eo="o";html+="<tbody>";html+="<tr>";html+="<th>Order</th>";html+="<th>Field Type</th>";html+="<th>Unique ID</th>";html+="<th>Required</th>";html+="<th>Levels</th>";html+="<th>- Tools -</th>";html+="</tr>";if(fields.length>0){for(i=0;i<fields.length;i++){html+='<tr class="'+esc_attr((eo=(eo==="o")?"e":"o"))+((fields[i].section==="yes")?" s":"")+" ws-plugin--s2member-custom-reg-field-configuration-table-row-"+i+'">';html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+i+'); return false;"></a></td>';html+='<td nowrap="nowrap">'+esc_html(fieldTypeDesc(fields[i].type))+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].id)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].required)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].levels)+"</td>";html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+i+'); return false;"></a></td>';html+="</tr>"}}else{html+="<tr>";html+='<td colspan="6">No Custom Fields are configured.</td>';html+="</tr>"}html+="</tbody>";$table.html(html)};buildTools(),buildTable()})()}}if(location.href.match(/page\=ws-plugin--s2member-res-ops/)){$("input#ws-plugin--s2member-brute-force-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's Brute Force Restriction Logs have all been reset."),$this.val("Reset Brute Force Logs")});return false});$("input#ws-plugin--s2member-ip-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's IP Restriction Logs have all been reset."),$this.val("Reset IP Restriction Logs")});return false});$('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query[]"]').change(function(){var thisChange=$(this).val();$('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query[]"]').each(function(){var $this=$(this),val=$this.val(),checkboxes='input[type="checkbox"]';if(val==="all"&&this.checked){$this.nextAll(checkboxes).attr({checked:"checked",disabled:"disabled"})}else{if(val==="all"&&!this.checked){$this.nextAll(checkboxes).removeAttr("disabled");(thisChange==="all")?$this.nextAll(checkboxes).removeAttr("checked"):null}}})}).last().trigger("change")}if(location.href.match(/page\=ws-plugin--s2member-down-ops/)){var updateCloudFrontPrivateKey=function(){var $hiddenPrivateKey=$("input#ws-plugin--s2member-amazon-cf-files-private-key");var $visiblePrivateKeyEntry=$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry");var hiddenPrivateKeyValue=$.trim($hiddenPrivateKey.val()),visiblePrivateKeyEntryValue=$.trim($visiblePrivateKeyEntry.val());if((hiddenPrivateKeyValue&&!visiblePrivateKeyEntryValue)||visiblePrivateKeyEntryValue.match(/[^\r\n\u25CF]/)){$hiddenPrivateKey.val(visiblePrivateKeyEntryValue),$visiblePrivateKeyEntry.val(visiblePrivateKeyEntryValue.replace(/[^\r\n]/g,String.fromCharCode(9679)))}};$("form#ws-plugin--s2member-options-form").submit(updateCloudFrontPrivateKey);$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry").change(updateCloudFrontPrivateKey).trigger("change");var updateCloudFrontDistroCfgs=function(){var $hiddenPrivateKey=$("input#ws-plugin--s2member-amazon-cf-files-private-key");var $visiblePrivateKeyId=$("input#ws-plugin--s2member-amazon-cf-files-private-key-id");var $autoConfigDistros=$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros");var $autoConfigDistrosStatus=$("input#ws-plugin--s2member-amazon-cf-files-distros-auto-config-status");var autoConfigDistrosStatusValue=$.trim($autoConfigDistrosStatus.val());var hiddenPrivateKeyValue=$.trim($hiddenPrivateKey.val()),visiblePrivateKeyIdValue=$.trim($visiblePrivateKeyId.val());var hiddenPrivateKeyPrevConfigValue=$.trim($hiddenPrivateKey.attr("data-s-prev-config-value")),visiblePrivateKeyIdPrevConfigValue=$.trim($visiblePrivateKeyId.attr("data-s-prev-config-value"));if(autoConfigDistrosStatusValue==="configured"&&((visiblePrivateKeyIdPrevConfigValue&&visiblePrivateKeyIdValue!==visiblePrivateKeyIdPrevConfigValue)||(hiddenPrivateKeyPrevConfigValue&&hiddenPrivateKeyValue!==hiddenPrivateKeyPrevConfigValue))){alert("s2Member will need to delete and re-configure your Amazon CloudFront distributions if you change this. When you're done editing, click (Save All Changes) below.");$autoConfigDistros.attr("checked","checked")}else{if(autoConfigDistrosStatusValue!=="configured"&&visiblePrivateKeyIdValue&&hiddenPrivateKeyValue){alert("s2Member will need to auto-configure your Amazon CloudFront distributions for you. When you're done editing, click (Save All Changes) below.");$autoConfigDistros.attr("checked","checked")}}};$("input#ws-plugin--s2member-amazon-cf-files-private-key-id").change(updateCloudFrontDistroCfgs);$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry").change(updateCloudFrontDistroCfgs);$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames").change(function(){var $this=$(this),thisChecked=(this.checked)?true:false;var $autoConfigDistros=$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros");var $autoConfigDistroCnames=$("div#ws-plugin--s2member-amazon-cf-files-auto-configure-distro-cnames");(thisChecked)?$autoConfigDistroCnames.show():$autoConfigDistroCnames.hide();(thisChecked)?$autoConfigDistros.attr("checked","checked"):null}).trigger("change")}if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/)){$("select#ws-plugin--s2member-auto-eot-system-enabled").change(function(){var $this=$(this),val=$this.val();var $viaCron=$("p#ws-plugin--s2member-auto-eot-system-enabled-via-cron");if(val==2){$viaCron.show()}else{$viaCron.hide()}})}if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/)){$("div.ws-menu-page select[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-term$/)}).change(function(){var button=this.id.replace(/^ws-plugin--s2member-(.+?)-term$/g,"$1");var trialDisabled=($(this).val().split("-")[2].replace(/[^0-1BN]/g,"")==="BN")?1:0;$("p#ws-plugin--s2member-"+button+"-trial-line").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-trial-then").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-20p-rule").css("display",(trialDisabled?"none":""));(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-period").val(0):null;(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-amount").val("0.00"):null});$("div.ws-menu-page input[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification|ccap)-ccaps$/)}).keyup(function(){var value=this.value.replace(/^(-all|-al|-a|-)[;,]*/gi,""),_all=(this.value.match(/^(-all|-al|-a|-)[;,]*/i))?"-all,":"";if(value.match(/[^a-z_0-9,]/)){this.value=_all+$.trim($.trim(value).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase())}});ws_plugin__s2member_paypalButtonGenerate=function(button){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="",labels={};eval("<?php echo c_ws_plugin__s2member_utils_strings::esc_dq($labels); ?>");var shortCode=$("input#ws-plugin--s2member-"+button+"-shortcode");var code=$("textarea#ws-plugin--s2member-"+button+"-button");var modLevel=$("select#ws-plugin--s2member-modification-level");var level=(button==="modification")?modLevel.val().split(":",2)[1]:button.replace(/^level/,"");var label=labels["level"+level].replace(/"/g,"");var desc=$.trim($("input#ws-plugin--s2member-"+button+"-desc").val().replace(/"/g,""));var trialAmount=$("input#ws-plugin--s2member-"+button+"-trial-amount").val().replace(/[^0-9\.]/g,"");var trialPeriod=$("input#ws-plugin--s2member-"+button+"-trial-period").val().replace(/[^0-9]/g,"");var trialTerm=$("select#ws-plugin--s2member-"+button+"-trial-term").val().replace(/[^A-Z]/g,"");var regAmount=$("input#ws-plugin--s2member-"+button+"-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var regRecurTimes="",regRecurRetry="1";var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-"+button+"-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-"+button+"-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();trialPeriod=(regRecur==="BN")?"0":trialPeriod;trialAmount=(!trialAmount||isNaN(trialAmount)||trialAmount<0.01||trialPeriod<=0)?"0":trialAmount;var levelCcapsPer=(regRecur==="BN"&®Term!=="L")?level+":"+cCaps+":"+regPeriod+" "+regTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(trialAmount!=="0"&&(isNaN(trialAmount)||trialAmount<0)){alert("— Oops, a slight problem: —\n\nWhen provided, Trial Amount must be >= 0.00");return false}else{if(trialAmount!=="0"&&trialAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Trial Amount is: 10000.00");return false}else{if(trialTerm==="D"&&trialPeriod>90){alert("— Oops, a slight problem: —\n\nMaximum Trial Days is: 90.\nIf you want to offer more than 90 days, please choose Weeks or Months from the drop-down.");return false}else{if(trialTerm==="W"&&trialPeriod>52){alert("— Oops, a slight problem: —\n\nMaximum Trial Weeks is: 52.\nIf you want to offer more than 52 weeks, please choose Months from the drop-down.");return false}else{if(trialTerm==="M"&&trialPeriod>24){alert("— Oops, a slight problem: —\n\nMaximum Trial Months is: 24.\nIf you want to offer more than 24 months, please choose Years from the drop-down.");return false}else{if(trialTerm==="Y"&&trialPeriod>5){alert("— Oops, a slight problem: —\n\nMax Trial Period Years is: 5.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}}}}}}code.html(code.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g," $1"));(parseInt(trialPeriod)<=0)?code.html(code.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick$3")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick-subscriptions$3")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g," <!--$1-->")):null;shortCodeTemplateAttrs+=(button==="modification")?'modify="1" ':"";shortCodeTemplateAttrs+='level="'+esc_attr(level)+'" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';shortCodeTemplateAttrs+=' ta="'+esc_attr(trialAmount)+'" tp="'+esc_attr(trialPeriod)+'" tt="'+esc_attr(trialTerm)+'" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'" rrt="'+esc_attr(regRecurTimes)+'" rra="'+esc_attr(regRecurRetry)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="modify" value\="(.*?)"/,' name="modify" value="'+((button==="modification")?"1":"0")+'"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="src" value\="(.*?)"/,' name="src" value="'+esc_attr(regRecur)+'"'));code.html(code.val().replace(/ name\="srt" value\="(.*?)"/,' name="srt" value="'+esc_attr(regRecurTimes)+'"'));code.html(code.val().replace(/ name\="sra" value\="(.*?)"/,' name="sra" value="'+esc_attr(regRecurRetry)+'"'));code.html(code.val().replace(/ name\="a1" value\="(.*?)"/,' name="a1" value="'+esc_attr(trialAmount)+'"'));code.html(code.val().replace(/ name\="p1" value\="(.*?)"/,' name="p1" value="'+esc_attr(trialPeriod)+'"'));code.html(code.val().replace(/ name\="t1" value\="(.*?)"/,' name="t1" value="'+esc_attr(trialTerm)+'"'));code.html(code.val().replace(/ name\="a3" value\="(.*?)"/,' name="a3" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="p3" value\="(.*?)"/,' name="p3" value="'+esc_attr(regPeriod)+'"'));code.html(code.val().replace(/ name\="t3" value\="(.*?)"/,' name="t3" value="'+esc_attr(regTerm)+'"'));$("div#ws-plugin--s2member-"+button+"-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));(button==="modification")?alert("Your Modification Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Modification Buttons should be displayed to existing Users/Members, and they should be logged-in, BEFORE clicking this Button."):alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalCcapButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-ccap-shortcode");var code=$("textarea#ws-plugin--s2member-ccap-button");var desc=$.trim($("input#ws-plugin--s2member-ccap-desc").val().replace(/"/g,""));var regAmount=$("input#ws-plugin--s2member-ccap-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-ccap-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-ccap-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-ccap-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-ccap-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-ccap-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();var levelCcapsPer=(regRecur==="BN"&®Term!=="L")?"*:"+cCaps+":"+regPeriod+" "+regTerm:"*:"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(!cCaps||cCaps==="-all"){alert("— Oops, a slight problem: —\n\nPlease provide at least one Custom Capability.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}shortCodeTemplateAttrs+='level="*" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-ccap-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Independent Custom Capability Buttons should ONLY be displayed to existing Users/Members, and they MUST be logged-in, BEFORE clicking this Button.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalSpButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-sp-shortcode");var code=$("textarea#ws-plugin--s2member-sp-button");var leading=$("select#ws-plugin--s2member-sp-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-hours").val().replace(/[^0-9]/g,"");var regAmount=$("input#ws-plugin--s2member-sp-amount").val().replace(/[^0-9\.]/g,"");var desc=$.trim($("input#ws-plugin--s2member-sp-desc").val().replace(/"/g,""));var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-sp-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-sp-currency").val().replace(/[^A-Z]/g,"");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it's because you've not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}var spIdsHours="sp:"+ids+":"+hours;shortCodeTemplateAttrs+='sp="1" ids="'+esc_attr(ids)+'" exp="'+esc_attr(hours)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(spIdsHours)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-sp-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode into your WordPress Editor.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalRegLinkGenerate=function(){var level=$("select#ws-plugin--s2member-reg-link-level").val().replace(/[^0-9]/g,"");var subscrID=$.trim($("input#ws-plugin--s2member-reg-link-subscr-id").val());var custom=$.trim($("input#ws-plugin--s2member-reg-link-custom").val());var cCaps=$.trim($.trim($("input#ws-plugin--s2member-reg-link-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());var fixedTerm=$.trim($("input#ws-plugin--s2member-reg-link-fixed-term").val().replace(/[^A-Z 0-9]/gi,"").toUpperCase());var $link=$("p#ws-plugin--s2member-reg-link"),$loading=$("img#ws-plugin--s2member-reg-link-loading");var levelCcapsPer=(fixedTerm&&!fixedTerm.match(/L$/))?level+":"+cCaps+":"+fixedTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(!subscrID){alert("— Oops, a slight problem: —\n\nPaid Subscr. ID is a required value.");return false}else{if(!custom||custom.indexOf('<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq ($_SERVER["HTTP_HOST"]); ?>')!==0){alert("— Oops, a slight problem: —\n\nThe Custom Value MUST start with your domain name.");return false}else{if(fixedTerm&&!fixedTerm.match(/^[1-9]+ (D|W|M|Y|L)$/)){alert("— Oops, a slight problem: —\n\nThe Fixed Term Length is not formatted properly.");return false}}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_reg_access_link_via_ajax",ws_plugin__s2member_reg_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-reg-access-link-via-ajax")); ?>',s2member_reg_access_link_subscr_gateway:"paypal",s2member_reg_access_link_subscr_id:subscrID,s2member_reg_access_link_custom:custom,s2member_reg_access_link_item_number:levelCcapsPer},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false};ws_plugin__s2member_paypalSpLinkGenerate=function(){var leading=$("select#ws-plugin--s2member-sp-link-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-link-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-link-hours").val().replace(/[^0-9]/g,"");var $link=$("p#ws-plugin--s2member-sp-link"),$loading=$("img#ws-plugin--s2member-sp-link-loading");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it's because you've not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.");return false}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_sp_access_link_via_ajax",ws_plugin__s2member_sp_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-sp-access-link-via-ajax")); ?>',s2member_sp_access_link_ids:ids,s2member_sp_access_link_hours:hours},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false}}if(location.href.match(/page\=ws-plugin--s2member-els-ops/)){$("select#ws-plugin--s2member-custom-reg-opt-in").change(function(){var $this=$(this),val=$this.val();var $rows=$("tr.ws-plugin--s2member-custom-reg-opt-in-label-row");var $prevImg=$("img.ws-plugin--s2member-custom-reg-opt-in-label-prev-img");if(val<=0){$rows.css("display","none"),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}else{if(val==1){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/unchecked\.png$/,"/checked.png"))}else{if(val==2){$rows.css("display",""),$prevImg.attr("src",$prevImg.attr("src").replace(/\/checked\.png$/,"/unchecked.png"))}}}});$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').change(function(){var thisChange=$(this).val(),checkedIndexes=[];$('div.ws-plugin--s2member-opt-out-section input[type="checkbox"][name="ws_plugin__s2member_custom_reg_auto_opt_outs[]"]').each(function(){var $this=$(this),val=$this.val(),checkboxes='input[type="checkbox"]';if(val==="removal-deletion"&&this.checked){$this.nextAll(checkboxes).slice(0,2).attr({checked:"checked",disabled:"disabled"})}else{if(val==="removal-deletion"&&!this.checked){$this.nextAll(checkboxes).slice(0,2).removeAttr("disabled");(thisChange==="removal-deletion")?$this.nextAll(checkboxes).slice(0,2).removeAttr("checked"):null}else{if(val==="modification"&&this.checked){$this.nextAll(checkboxes).slice(0,3).attr({checked:"checked",disabled:"disabled"})}else{if(val==="modification"&&!this.checked){(thisChange==="modification")?$this.nextAll(checkboxes).slice(0,3).removeAttr("checked"):null;$this.nextAll(checkboxes).slice(0,3).removeAttr("disabled")}}}}}).each(function(index){(this.checked)?checkedIndexes.push(index):null});$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").removeAttr("disabled");if($.inArray(3,checkedIndexes)===-1&&$.inArray(4,checkedIndexes)===-1&&$.inArray(5,checkedIndexes)===-1&&$.inArray(6,checkedIndexes)===-1){$("select#ws-plugin--s2member-custom-reg-auto-opt-out-transitions").attr("disabled","disabled")}}).last().trigger("change")}});
|
1 |
+
jQuery(document).ready(function($){var esc_attr=esc_html=function(string){if(/[&\<\>"']/.test(string=String(string))){string=string.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),string=string.replace(/"/g,""").replace(/'/g,"'")}return string};ws_plugin__s2member_generateSecurityKey=function(obj){if(!obj){obj="#ws-plugin--s2member-sec-encryption-key"}var mt_rand=function(min,max){min=(arguments.length<1)?0:min;max=(arguments.length<2)?2147483647:max;return Math.floor(Math.random()*(max-min+1))+min};var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#%^&*()";for(var i=0,key="";i<64;i++){key+=chars.substr(mt_rand(0,chars.length-1),1)}$(obj).val(key);return false};if(location.href.match(/page\=ws-plugin--s2member/)){$("input.ws-plugin--s2member-update-roles-button, input.ws-plugin--s2member-reset-roles-button").click(function(){var $this=$(this);$this.val("one moment please ...");var levels='<?php echo (int)$GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; ?>';var resetUpdate=($this.hasClass("ws-plugin--s2member-reset-roles-button"))?"Reset":"Update";$.post(ajaxurl,{action:"ws_plugin__s2member_update_roles_via_ajax",ws_plugin__s2member_update_roles_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-update-roles-via-ajax")); ?>'},function(response){if(response==="1"){alert("s2Member's Roles/Capabilities "+((resetUpdate.toLowerCase()==="reset")?"have been successfully reset":"updated successfully")+".\nYour installation of s2Member has Membership Levels 0-"+levels+"."),$this.val(resetUpdate+" Roles/Capabilities")}else{if(response==="l"){alert("Sorry, your request failed.\ns2Member's Roles/Capabilities are locked by Filter:\nws_plugin__s2member_lock_roles_caps"),$this.val(resetUpdate+" Roles/Capabilities")}else{alert("Sorry, your request failed.\nAccess denied. Do you have the ability to `create_users`?"),$this.val(resetUpdate+" Roles/Capabilities")}}});return false})}if(location.href.match(/page\=ws-plugin--s2member-logs/)){$("input#ws-plugin--s2member-gateway-debug-logs-extensive-1").click(function(){var $this=$(this),thisChecked=(this.checked)?true:false;if(thisChecked){$("input#ws-plugin--s2member-gateway-debug-logs-1").attr("checked","checked")}});var $toggles=$("a.ws-plugin--s2member-log-file-viewport-toggle");$toggles.click(function(){$("textarea#ws-plugin--s2member-log-file-viewer").each(function(){var $viewer=$(this);if($viewer.attr("data-state")!=="expanded"){$viewer.css({height:($viewer.prop("scrollHeight")+50)+"px","overflow-y":"auto"});$toggles.html("⇑ normalize viewport ❙");$viewer.attr("data-state","expanded")}else{$viewer.css({height:"auto","overflow-y":"scroll"});$toggles.html("⇓ expand viewport ⇓");$viewer.attr("data-state","scrolling")}});return false})}if(location.href.match(/page\=ws-plugin--s2member-mms-ops/)){$("select#ws-plugin--s2member-mms-registration-file").change(function(){if($(this).val()==="wp-signup"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").show(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").hide(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").show();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0")[((gv==="all")?"show":"hide")]();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val(((gv==="all")?((l0v>0)?l0v:"1"):"0"))}else{if($(this).val()==="wp-login"){var gv=$("select#ws-plugin--s2member-mms-registration-grants").val(),l0v=$("input#ws-plugin--s2member-mms-registration-blogs-level0").val();$("div#ws-plugin--s2member-mms-registration-support-package-details-wrapper").hide(),$("div.ws-plugin--s2member-mms-registration-wp-login, table.ws-plugin--s2member-mms-registration-wp-login").show(),$("div.ws-plugin--s2member-mms-registration-wp-signup, table.ws-plugin--s2member-mms-registration-wp-signup").hide();$("div.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0, table.ws-plugin--s2member-mms-registration-wp-signup-blogs-level0").hide();$("input#ws-plugin--s2member-mms-registration-blogs-level0").val("0")}}}).trigger("change");$("select#ws-plugin--s2member-mms-registration-grants").change(function(){$("select#ws-plugin--s2member-mms-registration-file").trigger("change")})}if(location.href.match(/page\=ws-plugin--s2member-gen-ops/)){ws_plugin__s2member_enableSecurityKey=function(){if(confirm("Edit Key? Are you sure?\nThis could break your installation!\n\n*Note* If you've been testing s2Member, feel free to change this Key before you go live. Just don't go live, and then change it. You'll have unhappy Customers. Data corruption WILL occur! For your safety, s2Member keeps a history of the last 10 Keys that you've used. If you get yourself into a real situation, s2Member will let you revert back to a previous Key.")){$("input#ws-plugin--s2member-sec-encryption-key").removeAttr("disabled")}return false};ws_plugin__s2member_securityKeyHistory=function(){$("div#ws-plugin--s2member-sec-encryption-key-history").toggle();return false};$("select#ws-plugin--s2member-new-user-emails-enabled").change(function(){var $pluggable=$("input#ws-plugin--s2member-pluggables-wp-new-user-notification"),$this=$(this),$newUserEmails=$("div#ws-plugin--s2member-new-user-emails");if($pluggable.val()==="0"||$this.val()==="0"){($pluggable.val()==="0")?$this.attr("disabled","disabled"):$this.removeAttr("disabled");$(":input",$newUserEmails).attr("disabled","disabled"),$newUserEmails.css("opacity","0.5")}else{$this.removeAttr("disabled"),$(":input",$newUserEmails).removeAttr("disabled"),$newUserEmails.css("opacity","")}}).trigger("change");$("select#ws-plugin--s2member-login-reg-design-enabled").change(function(){var $this=$(this),$loginRegDesign=$("div#ws-plugin--s2member-login-reg-design");if($this.val()==="0"){$(":input",$loginRegDesign).attr("disabled","disabled"),$loginRegDesign.css("opacity","0.5"),$loginRegDesign.hide()}else{$(":input",$loginRegDesign).removeAttr("disabled"),$loginRegDesign.css("opacity",""),$loginRegDesign.show()}}).trigger("change");if($("input#ws-plugin--s2member-custom-reg-fields").length&&$("div#ws-plugin--s2member-custom-reg-field-configuration").length){(function(){var i,fieldDefaults,tools,table,$tools,$table;var $fields=$("input#ws-plugin--s2member-custom-reg-fields");var $configuration=$("div#ws-plugin--s2member-custom-reg-field-configuration");var fields=($fields.val())?$.JSON.parse($fields.val()):[];fields=(fields instanceof Array)?fields:[];fieldDefaults={section:"no",sectitle:"",id:"",label:"",type:"text",deflt:"",options:"",expected:"",required:"yes",levels:"all",editable:"yes",classes:"",styles:"",attrs:""};for(i=0;i<fields.length;i++){fields[i]=$.extend(true,{},fieldDefaults,fields[i])}tools='<div id="ws-plugin--s2member-custom-reg-field-configuration-tools"></div>',table='<table id="ws-plugin--s2member-custom-reg-field-configuration-table"></table>';$configuration.html(tools+table);$tools=$("div#ws-plugin--s2member-custom-reg-field-configuration-tools"),$table=$("table#ws-plugin--s2member-custom-reg-field-configuration-table");ws_plugin__s2member_customRegFieldSectionChange=function(select){var section=$(select).val();var sectitle_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle";(section==="yes")?$(sectitle_trs).css("display",""):$(sectitle_trs).css("display","none")};ws_plugin__s2member_customRegFieldTypeChange=function(select){var type=$(select).val();var deflt_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt",options_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-options",expected_trs="tr.ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected";(type.match(/^(text|textarea)$/))?$(deflt_trs).css("display",""):$(deflt_trs).css("display","none");(type.match(/^(select|selects|checkboxes|radios)$/))?$(options_trs).css("display",""):$(options_trs).css("display","none");(type.match(/^(text|textarea)$/))?$(expected_trs).css("display",""):$(expected_trs).css("display","none")};ws_plugin__s2member_customRegFieldDelete=function(index){var newFields=new Array();for(var i=0;i<fields.length;i++){if(i!==index){newFields.push(fields[i])}}fields=newFields,updateFields(),buildTable()};ws_plugin__s2member_customRegFieldMoveUp=function(index){if(typeof fields[index]==="object"&&typeof fields[index-1]==="object"){var prevFieldObj=fields[index-1],thisFieldObj=fields[index];fields[index-1]=thisFieldObj,fields[index]=prevFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldMoveDown=function(index){if(typeof fields[index]==="object"&&typeof fields[index+1]==="object"){var nextFieldObj=fields[index+1],thisFieldObj=fields[index];fields[index+1]=thisFieldObj,fields[index]=nextFieldObj;updateFields(),buildTable()}};ws_plugin__s2member_customRegFieldCreate=function(){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field))){fields.push(field),updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+(fields.length-1);alert('Field created successfully.\n* Remember to "Save All Changes".')},500)}};ws_plugin__s2member_customRegFieldUpdate=function(index){var $table=$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form"),field={};$(":input[property]",$table).each(function(){var $this=$(this),property=$this.attr("property"),val=$.trim($this.val());field[property]=val});if((field=validateField(field,index))){fields[index]=field,updateFields(),buildTools(),buildTable(),scrollReset();setTimeout(function(){var row="tr.ws-plugin--s2member-custom-reg-field-configuration-table-row-"+index;alert('Field updated successfully.\n* Remember to "Save All Changes".')},500)}};ws_plugin__s2member_customRegFieldAdd=function(){buildTools(true)};ws_plugin__s2member_customRegFieldEdit=function(index){buildTools(false,index),scrollReset()};ws_plugin__s2member_customRegFieldCancel=function(){buildTools(),scrollReset()};var validateField=function(field,index){var editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,errors=[],options,i;if(typeof field!=="object"||typeof(field=$.extend(true,{},fieldDefaults,field))!=="object"){alert("Invalid field object. Please try again.");return false}field.sectitle=(field.section==="yes")?field.sectitle:"";field.deflt=(field.type.match(/^(text|textarea)$/))?field.deflt:"";field.deflt=(field.type.match(/^(text)$/))?field.deflt.replace(/[\r\n\t ]+/g," "):field.deflt;field.options=(field.type.match(/^(select|selects|checkboxes|radios)$/))?field.options:"";field.expected=(field.type.match(/^(text|textarea)$/))?field.expected:"";if(!field.id){errors.push("Unique Field ID:\nThis is required. Please try again.")}else{if(fieldIdExists(field.id)&&(!editing||field.id!==fields[index].id)){errors.push("Unique Field ID:\nThat Field ID already exists. Please try again.")}}if(!field.label){errors.push("Field Label/Description:\nThis is required. Please try again.")}if(field.type.match(/^(select|selects|checkboxes|radios)$/)&&!field.options){errors.push("Option Configuration File:\nThis is required. Please try again.")}else{if(field.type.match(/^(select|selects|checkboxes|radios)$/)){for(i=0;i<(options=field.options.split(/[\r\n]+/)).length;i++){if(!(options[i]=$.trim(options[i])).match(/^([^\|]*)(\|)([^\|]*)(\|default)?$/)){errors.push("Option Configuration File:\nInvalid configuration at line #"+(i+1)+".");break}}field.options=$.trim(options.join("\n"))}}if(!(field.levels=field.levels.replace(/ /g,""))){errors.push("Applicable Levels:\nThis is required. Please try again.")}else{if(!field.levels.match(/^(all|[0-9,]+)$/)){errors.push("Applicable Levels:\nShould be comma-delimited Levels, or just type: all.\n(examples: 0,1,2,3,4 or type the word: all)")}}if(field.classes&&field.classes.match(/[^a-z 0-9 _ \-]/i)){errors.push("CSS Classes:\nContains invalid characters. Please try again.\n(only: alphanumerics, underscores, hyphens, spaces)")}if(field.styles&&field.styles.match(/["\=\>\<]/)){errors.push('CSS Styles:\nContains invalid characters. Please try again.\n(do NOT use these characters: = " < >)')}if(field.attrs&&field.attrs.match(/[\>\<]/)){errors.push("Other Attributes:\nContains invalid characters. Please try again.\n(do NOT use these characters: < >)")}if(errors.length>0){alert(errors.join("\n\n"));return false}else{return field}};var updateFields=function(){$fields.val(((fields.length>0)?$.JSON.stringify(fields):""))};var fieldId2Var=function(fieldId){return(typeof fieldId==="string")?$.trim(fieldId).toLowerCase().replace(/[^a-z0-9]/g,"_"):""};var fieldTypeDesc=function(type){var types={text:"Text (single line)",textarea:"Textarea (multi-line)",select:"Select Menu (drop-down)",selects:"Select Menu (multi-option)",checkbox:"Checkbox (single)",pre_checkbox:"Checkbox (pre-checked)",checkboxes:"Checkboxes (multi-option)",radios:"Radio Buttons (multi-option)"};if(typeof types[type]==="string"){return types[type]}return""};var fieldIdExists=function(fieldId){for(var i=0;i<fields.length;i++){if(fields[i].id===fieldId){return true}}};var scrollReset=function(){scrollTo(0,$("div.ws-plugin--s2member-custom-reg-fields-section").offset()["top"]-100)};var buildTools=function(adding,index){var i=0,html="",form="",w=0,h=0,editing=(typeof index==="number"&&typeof fields[index]==="object")?true:false,displayForm=(adding||editing)?true:false,field=(editing)?$.extend(true,{},fieldDefaults,fields[index]):fieldDefaults;html+='<a href="#" onclick="ws_plugin__s2member_customRegFieldAdd(); return false;">Add New Field</a>';tb_remove(),$("div#ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form").remove();if(displayForm){form+='<div id="ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form">';form+='<table id="ws-plugin--s2member-custom-reg-field-configuration-tools-form">';form+="<tbody>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">Starts A New Section?</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section">';form+='<td colspan="2">';form+='<select property="section" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-section" onchange="ws_plugin__s2member_customRegFieldSectionChange(this);">';form+='<option value="no"'+((field.section==="no")?' selected="selected"':"")+'">No (this Field flows normally)</option>';form+='<option value="yes"'+((field.section==="yes")?' selected="selected"':"")+'">Yes (this Field begins a new section)</option>';form+="</select><br />";form+="<small>Optional. Allows Fields to be grouped into sections.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+'><td colspan="2"><hr /></td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle ws-plugin--s2member-custom-reg-field-configuration-tools-form-section"'+((field.section==="yes")?"":' style="display:none;"')+">";form+='<td colspan="2">';form+="Title for this new section? (optional)<br />";form+='<input type="text" property="sectitle" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-sectitle" value="'+esc_attr(field.sectitle)+'" /><br />';form+="<small>If empty, a simple divider will be used by default.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-type"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">Form Field Type: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type">';form+='<td colspan="2">';form+='<select property="type" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-type" onchange="ws_plugin__s2member_customRegFieldTypeChange(this);">';form+='<option value="text"'+((field.type==="text")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("text"))+"</option>";form+='<option value="textarea"'+((field.type==="textarea")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("textarea"))+"</option>";form+='<option value="select"'+((field.type==="select")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("select"))+"</option>";form+='<option value="selects"'+((field.type==="selects")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("selects"))+"</option>";form+='<option value="checkbox"'+((field.type==="checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkbox"))+"</option>";form+='<option value="pre_checkbox"'+((field.type==="pre_checkbox")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("pre_checkbox"))+"</option>";form+='<option value="checkboxes"'+((field.type==="checkboxes")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("checkboxes"))+"</option>";form+='<option value="radios"'+((field.type==="radios")?' selected="selected"':"")+'">'+esc_html(fieldTypeDesc("radios"))+"</option>";form+="</select><br />";form+="<small>The options below may change, based on the Field Type you choose here.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-label"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">Field Label/Desc: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label">';form+='<td colspan="2">';form+='<input type="text" property="label" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-label" value="'+esc_attr(field.label)+'" /><br />';form+="<small>Examples: <code>Choose Country</code>, <code>Street Address</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-id"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">Unique Field ID: *</label></label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id">';form+='<td colspan="2">';form+='<input type="text" property="id" maxlength="25" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-id" value="'+esc_attr(field.id)+'" /><br />';form+="<small>Examples: <code>country_code</code>, <code>street_address</code></small><br />";form+='<small>e.g. <code>[s2Get user_field="country_code" /]</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-required"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">Field Required: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<td colspan="2">';form+='<select property="required" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-required">';form+='<option value="yes"'+((field.required==="yes")?' selected="selected"':"")+'">Yes (required)</option>';form+='<option value="no"'+((field.required==="no")?' selected="selected"':"")+'">No (optional)</option>';form+="</select><br />";form+='<small>If <code>yes</code>, only Users/Members will be "required" to enter this field.</small><br />';form+="<small>* Administrators are exempt from this requirement.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt">Default Text Value: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="deflt" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-deflt" rows="1">'+esc_html(field.deflt)+"</textarea><br />";form+="<small>Default value before user input is received.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+'><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options">Option Configuration File: * (one option per line)</label><br />';form+="<small>Use a pipe <code>|</code> delimited format: <code>option value|option label</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options"'+((field.type.match(/^(select|selects|checkboxes|radios)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<textarea property="options" wrap="off" spellcheck="false" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-options" rows="3">'+esc_html(field.options)+"</textarea><br />";form+="Here is a quick example:<br />";form+="<small>You can also specify a <em>default</em> option:</small><br />";form+="<code>US|United States|default</code><br />";form+="<code>CA|Canada</code><br />";form+="<code>VI|Virgin Islands (U.S.)</code>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+'><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">Expected Format: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected"'+((field.type.match(/^(text|textarea)$/))?"":' style="display:none;"')+">";form+='<td colspan="2">';form+='<select property="expected" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-expected">';form+='<option value=""'+((field.expected==="")?' selected="selected"':"")+'">Anything Goes</option>';form+='<option disabled="disabled"></option>';form+='<optgroup label="Specific Input Types">';form+='<option value="numeric-wp-commas"'+((field.expected==="numeric-wp-commas")?' selected="selected"':"")+'">Numeric (with or without decimals, commas allowed)</option>';form+='<option value="numeric"'+((field.expected==="numeric")?' selected="selected"':"")+'">Numeric (with or without decimals, no commas)</option>';form+='<option value="integer"'+((field.expected==="integer")?' selected="selected"':"")+'">Integer (whole number, without any decimals)</option>';form+='<option value="integer-gt-0"'+((field.expected==="integer-gt-0")?' selected="selected"':"")+'">Integer > 0 (whole number, no decimals, greater than 0)</option>';form+='<option value="float"'+((field.expected==="float")?' selected="selected"':"")+'">Float (floating point number, decimals required)</option>';form+='<option value="float-gt-0"'+((field.expected==="float-gt-0")?' selected="selected"':"")+'">Float > 0 (floating point number, decimals required, greater than 0)</option>';form+='<option value="date"'+((field.expected==="date")?' selected="selected"':"")+'">Date (required date format: dd/mm/yyyy)</option>';form+='<option value="email"'+((field.expected==="email")?' selected="selected"':"")+'">Email (require valid email)</option>';form+='<option value="url"'+((field.expected==="url")?' selected="selected"':"")+'">Full URL (starting with http or https)</option>';form+='<option value="domain"'+((field.expected==="domain")?' selected="selected"':"")+'">Domain Name (domain name only, without http)</option>';form+='<option value="phone"'+((field.expected==="phone")?' selected="selected"':"")+'">Phone # (10 digits w/possible hyphens,spaces,brackets)</option>';form+='<option value="uszip"'+((field.expected==="uszip")?' selected="selected"':"")+'">US Zipcode (5-9 digits w/possible hyphen)</option>';form+='<option value="cazip"'+((field.expected==="cazip")?' selected="selected"':"")+'">Canadian Zipcode (6 alpha-numerics w/possible space)</option>';form+='<option value="uczip"'+((field.expected==="uczip")?' selected="selected"':"")+'">US/Canadian Zipcode (either a US or Canadian zipcode)</option>';form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Any Character Combination">';for(i=1;i<=25;i++){form+='<option value="any-'+i+'"'+((field.expected==="any-"+i)?' selected="selected"':"")+'">Any Character Combination ('+i+" character minimum)</option>";form+='<option value="any-'+i+'-e"'+((field.expected==="any-"+i+"-e")?' selected="selected"':"")+'">Any Character Combination (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics, Spaces & Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-punctuation-'+i+'"'+((field.expected==="alphanumerics-spaces-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics, Spaces & Punctuation ('+i+" character minimum)</option>";form+='<option value="alphanumerics-spaces-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-spaces-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics, Spaces & Punctuation (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics & Spaces Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-spaces-'+i+'"'+((field.expected==="alphanumerics-spaces-"+i)?' selected="selected"':"")+'">Alphanumerics & Spaces ('+i+" character minimum)</option>";form+='<option value="alphanumerics-spaces-'+i+'-e"'+((field.expected==="alphanumerics-spaces-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics & Spaces (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics & Punctuation Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-punctuation-'+i+'"'+((field.expected==="alphanumerics-punctuation-"+i)?' selected="selected"':"")+'">Alphanumerics & Punctuation ('+i+" character minimum)</option>";form+='<option value="alphanumerics-punctuation-'+i+'-e"'+((field.expected==="alphanumerics-punctuation-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics & Punctuation (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphanumerics Only">';for(i=1;i<=25;i++){form+='<option value="alphanumerics-'+i+'"'+((field.expected==="alphanumerics-"+i)?' selected="selected"':"")+'">Alphanumerics ('+i+" character minimum)</option>";form+='<option value="alphanumerics-'+i+'-e"'+((field.expected==="alphanumerics-"+i+"-e")?' selected="selected"':"")+'">Alphanumerics (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Alphabetics Only">';for(i=1;i<=25;i++){form+='<option value="alphabetics-'+i+'"'+((field.expected==="alphabetics-"+i)?' selected="selected"':"")+'">Alphabetics ('+i+" character minimum)</option>";form+='<option value="alphabetics-'+i+'-e"'+((field.expected==="alphabetics-"+i+"-e")?' selected="selected"':"")+'">Alphabetics (exactly '+i+" character"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+='<option disabled="disabled"></option>';form+='<optgroup label="Numeric Digits Only">';for(i=1;i<=25;i++){form+='<option value="numerics-'+i+'"'+((field.expected==="numerics-"+i)?' selected="selected"':"")+'">Numeric Digits ('+i+" digit minimum)</option>";form+='<option value="numerics-'+i+'-e"'+((field.expected==="numerics-"+i+"-e")?' selected="selected"':"")+'">Numeric Digits (exactly '+i+" digit"+((i>1)?"s":"")+")</option>"}form+="</optgroup>";form+="</select><br />";form+="<small>Only Users/Members will be required to meet this criteria.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">Applicable Membership Levels: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels">';form+='<td colspan="2">';form+='<input type="text" property="levels" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-levels" value="'+esc_attr(field.levels)+'" /><br />';form+="<small>Please use comma-delimited Level #'s: <code>0,1,2,3,4</code> or type: <code>all</code>.</small><br />";form+="<small>This allows you to enable this field - only at specific Membership Levels.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">Allow Profile Edits: *</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<td colspan="2">';form+='<select property="editable" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-editable">';form+='<option value="yes"'+((field.editable==="yes")?' selected="selected"':"")+'">Yes (editable)</option>';form+='<option value="no"'+((field.editable==="no")?' selected="selected"':"")+'">No (uneditable after registration)</option>';form+='<option value="no-invisible"'+((field.editable==="no-invisible")?' selected="selected"':"")+'">No (uneditable & totally invisible after registration)</option>';form+='<option value="no-always-invisible"'+((field.editable==="no-always-invisible")?' selected="selected"':"")+'">No (uneditable & totally invisible, both during & after registration)</option>';form+='<option value="yes-invisible"'+((field.editable==="yes-invisible")?' selected="selected"':"")+'">Yes (editable after registration / invisible during registration)</option>';form+="</select><br />";form+="<small>If <code>No</code>, this field will be un-editable after registration.</small><br />";form+="<small>* Administrators are exempt from this.</small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">CSS Classes: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes">';form+='<td colspan="2">';form+='<input type="text" property="classes" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-classes" value="'+esc_attr(field.classes)+'" /><br />';form+="<small>Example: <code>my-style-1 my-style-2</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">CSS Styles: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles">';form+='<td colspan="2">';form+='<input type="text" property="styles" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-styles" value="'+esc_attr(field.styles)+'" /><br />';form+="<small>Example: <code>color:#000000; background:#FFFFFF;</code></small>";form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<label for="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">Other Attributes: (optional)</label>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs">';form+='<td colspan="2">';form+='<input type="text" property="attrs" autocomplete="off" id="ws-plugin--s2member-custom-reg-field-configuration-tools-form-attrs" value="'+esc_attr(field.attrs)+'" /><br />';form+='<small>Example: <code>onkeyup="" onblur=""</code></small>';form+="</td>";form+="</tr>";form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-spacer ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons"><td colspan="2"> </td></tr>';form+='<tr class="ws-plugin--s2member-custom-reg-field-configuration-tools-form-buttons">';form+='<td align="left">';form+='<input type="button" value="Cancel" onclick="ws_plugin__s2member_customRegFieldCancel();" />';form+="</td>";form+='<td align="right">';form+='<input type="button" value="'+((editing)?"Update This Field":"Create Registration Field")+'" onclick="'+((editing)?"ws_plugin__s2member_customRegFieldUpdate("+index+");":"ws_plugin__s2member_customRegFieldCreate();")+'" />';form+="</td>";form+="</tr>";form+="</tbody>";form+="</table>";form+="<div>";$("body").append(form);tb_show(((editing)?"Editing Registration/Profile Field":"New Custom Registration/Profile Field"),"#TB_inline?inlineId=ws-plugin--s2member-custom-reg-field-configuration-thickbox-tools-form");$("table#ws-plugin--s2member-custom-reg-field-configuration-tools-form").show()}$tools.html(html)};var buildTable=function(){var l=fields.length,i=0,html="",eo="o";html+="<tbody>";html+="<tr>";html+="<th>Order</th>";html+="<th>Field Type</th>";html+="<th>Unique ID</th>";html+="<th>Required</th>";html+="<th>Levels</th>";html+="<th>- Tools -</th>";html+="</tr>";if(fields.length>0){for(i=0;i<fields.length;i++){html+='<tr class="'+esc_attr((eo=(eo==="o")?"e":"o"))+((fields[i].section==="yes")?" s":"")+" ws-plugin--s2member-custom-reg-field-configuration-table-row-"+i+'">';html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-move-up" href="#" onclick="ws_plugin__s2member_customRegFieldMoveUp('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-move-down" href="#" onclick="ws_plugin__s2member_customRegFieldMoveDown('+i+'); return false;"></a></td>';html+='<td nowrap="nowrap">'+esc_html(fieldTypeDesc(fields[i].type))+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].id)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].required)+"</td>";html+='<td nowrap="nowrap">'+esc_html(fields[i].levels)+"</td>";html+='<td nowrap="nowrap"><a class="ws-plugin--s2member-custom-reg-field-configuration-edit" href="#" onclick="ws_plugin__s2member_customRegFieldEdit('+i+'); return false;"></a><a class="ws-plugin--s2member-custom-reg-field-configuration-delete" href="#" onclick="ws_plugin__s2member_customRegFieldDelete('+i+'); return false;"></a></td>';html+="</tr>"}}else{html+="<tr>";html+='<td colspan="6">No Custom Fields are configured.</td>';html+="</tr>"}html+="</tbody>";$table.html(html)};buildTools(),buildTable()})()}}if(location.href.match(/page\=ws-plugin--s2member-res-ops/)){$("input#ws-plugin--s2member-brute-force-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's Brute Force Restriction Logs have all been reset."),$this.val("Reset Brute Force Logs")});return false});$("input#ws-plugin--s2member-ip-restrictions-reset-button").click(function(){var $this=$(this);$this.val("one moment please ...");$.post(ajaxurl,{action:"ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax",ws_plugin__s2member_delete_reset_all_ip_restrictions_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-delete-reset-all-ip-restrictions-via-ajax")); ?>'},function(response){alert("s2Member's IP Restriction Logs have all been reset."),$this.val("Reset IP Restriction Logs")});return false});$('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query[]"]').change(function(){var thisChange=$(this).val();$('div.ws-plugin--s2member-query-level-access-section input[type="checkbox"][name="ws_plugin__s2member_filter_wp_query[]"]').each(function(){var $this=$(this),val=$this.val(),checkboxes='input[type="checkbox"]';if(val==="all"&&this.checked){$this.nextAll(checkboxes).attr({checked:"checked",disabled:"disabled"})}else{if(val==="all"&&!this.checked){$this.nextAll(checkboxes).removeAttr("disabled");(thisChange==="all")?$this.nextAll(checkboxes).removeAttr("checked"):null}}})}).last().trigger("change")}if(location.href.match(/page\=ws-plugin--s2member-down-ops/)){var updateCloudFrontPrivateKey=function(){var $hiddenPrivateKey=$("input#ws-plugin--s2member-amazon-cf-files-private-key");var $visiblePrivateKeyEntry=$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry");var hiddenPrivateKeyValue=$.trim($hiddenPrivateKey.val()),visiblePrivateKeyEntryValue=$.trim($visiblePrivateKeyEntry.val());if((hiddenPrivateKeyValue&&!visiblePrivateKeyEntryValue)||visiblePrivateKeyEntryValue.match(/[^\r\n\u25CF]/)){$hiddenPrivateKey.val(visiblePrivateKeyEntryValue),$visiblePrivateKeyEntry.val(visiblePrivateKeyEntryValue.replace(/[^\r\n]/g,String.fromCharCode(9679)))}};$("form#ws-plugin--s2member-options-form").submit(updateCloudFrontPrivateKey);$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry").change(updateCloudFrontPrivateKey).trigger("change");var updateCloudFrontDistroCfgs=function(){var $hiddenPrivateKey=$("input#ws-plugin--s2member-amazon-cf-files-private-key");var $visiblePrivateKeyId=$("input#ws-plugin--s2member-amazon-cf-files-private-key-id");var $autoConfigDistros=$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros");var $autoConfigDistrosStatus=$("input#ws-plugin--s2member-amazon-cf-files-distros-auto-config-status");var autoConfigDistrosStatusValue=$.trim($autoConfigDistrosStatus.val());var hiddenPrivateKeyValue=$.trim($hiddenPrivateKey.val()),visiblePrivateKeyIdValue=$.trim($visiblePrivateKeyId.val());var hiddenPrivateKeyPrevConfigValue=$.trim($hiddenPrivateKey.attr("data-s-prev-config-value")),visiblePrivateKeyIdPrevConfigValue=$.trim($visiblePrivateKeyId.attr("data-s-prev-config-value"));if(autoConfigDistrosStatusValue==="configured"&&((visiblePrivateKeyIdPrevConfigValue&&visiblePrivateKeyIdValue!==visiblePrivateKeyIdPrevConfigValue)||(hiddenPrivateKeyPrevConfigValue&&hiddenPrivateKeyValue!==hiddenPrivateKeyPrevConfigValue))){alert("s2Member will need to delete and re-configure your Amazon CloudFront distributions if you change this. When you're done editing, click (Save All Changes) below.");$autoConfigDistros.attr("checked","checked")}else{if(autoConfigDistrosStatusValue!=="configured"&&visiblePrivateKeyIdValue&&hiddenPrivateKeyValue){alert("s2Member will need to auto-configure your Amazon CloudFront distributions for you. When you're done editing, click (Save All Changes) below.");$autoConfigDistros.attr("checked","checked")}}};$("input#ws-plugin--s2member-amazon-cf-files-private-key-id").change(updateCloudFrontDistroCfgs);$("textarea#ws-plugin--s2member-amazon-cf-files-private-key-entry").change(updateCloudFrontDistroCfgs);$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros-w-cnames").change(function(){var $this=$(this),thisChecked=(this.checked)?true:false;var $autoConfigDistros=$("input#ws-plugin--s2member-amazon-cf-files-auto-configure-distros");var $autoConfigDistroCnames=$("div#ws-plugin--s2member-amazon-cf-files-auto-configure-distro-cnames");(thisChecked)?$autoConfigDistroCnames.show():$autoConfigDistroCnames.hide();(thisChecked)?$autoConfigDistros.attr("checked","checked"):null}).trigger("change")}if(location.href.match(/page\=ws-plugin--s2member-paypal-ops/)){$("select#ws-plugin--s2member-auto-eot-system-enabled").change(function(){var $this=$(this),val=$this.val();var $viaCron=$("p#ws-plugin--s2member-auto-eot-system-enabled-via-cron");if(val==2){$viaCron.show()}else{$viaCron.hide()}})}if(location.href.match(/page\=ws-plugin--s2member-paypal-buttons/)){$("div.ws-menu-page select[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification)-term$/)}).change(function(){var button=this.id.replace(/^ws-plugin--s2member-(.+?)-term$/g,"$1");var trialDisabled=($(this).val().split("-")[2].replace(/[^0-1BN]/g,"")==="BN")?1:0;$("p#ws-plugin--s2member-"+button+"-trial-line").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-trial-then").css("display",(trialDisabled?"none":""));$("span#ws-plugin--s2member-"+button+"-20p-rule").css("display",(trialDisabled?"none":""));(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-period").val(0):null;(trialDisabled)?$("input#ws-plugin--s2member-"+button+"-trial-amount").val("0.00"):null});$("div.ws-menu-page input[id]").filter(function(){return this.id.match(/^ws-plugin--s2member-(level[1-9][0-9]*|modification|ccap)-ccaps$/)}).keyup(function(){var value=this.value.replace(/^(-all|-al|-a|-)[;,]*/gi,""),_all=(this.value.match(/^(-all|-al|-a|-)[;,]*/i))?"-all,":"";if(value.match(/[^a-z_0-9,]/)){this.value=_all+$.trim($.trim(value).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase())}});ws_plugin__s2member_paypalButtonGenerate=function(button){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="",labels={};eval("<?php echo c_ws_plugin__s2member_utils_strings::esc_dq($labels); ?>");var shortCode=$("input#ws-plugin--s2member-"+button+"-shortcode");var code=$("textarea#ws-plugin--s2member-"+button+"-button");var modLevel=$("select#ws-plugin--s2member-modification-level");var level=(button==="modification")?modLevel.val().split(":",2)[1]:button.replace(/^level/,"");var label=labels["level"+level].replace(/"/g,"");var desc=$.trim($("input#ws-plugin--s2member-"+button+"-desc").val().replace(/"/g,""));var trialAmount=$("input#ws-plugin--s2member-"+button+"-trial-amount").val().replace(/[^0-9\.]/g,"");var trialPeriod=$("input#ws-plugin--s2member-"+button+"-trial-period").val().replace(/[^0-9]/g,"");var trialTerm=$("select#ws-plugin--s2member-"+button+"-trial-term").val().replace(/[^A-Z]/g,"");var regAmount=$("input#ws-plugin--s2member-"+button+"-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-"+button+"-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var regRecurTimes="",regRecurRetry="1";var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-"+button+"-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-"+button+"-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-"+button+"-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();trialPeriod=(regRecur==="BN")?"0":trialPeriod;trialAmount=(!trialAmount||isNaN(trialAmount)||trialAmount<0.01||trialPeriod<=0)?"0":trialAmount;var levelCcapsPer=(regRecur==="BN"&®Term!=="L")?level+":"+cCaps+":"+regPeriod+" "+regTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(trialAmount!=="0"&&(isNaN(trialAmount)||trialAmount<0)){alert("— Oops, a slight problem: —\n\nWhen provided, Trial Amount must be >= 0.00");return false}else{if(trialAmount!=="0"&&trialAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Trial Amount is: 10000.00");return false}else{if(trialTerm==="D"&&trialPeriod>90){alert("— Oops, a slight problem: —\n\nMaximum Trial Days is: 90.\nIf you want to offer more than 90 days, please choose Weeks or Months from the drop-down.");return false}else{if(trialTerm==="W"&&trialPeriod>52){alert("— Oops, a slight problem: —\n\nMaximum Trial Weeks is: 52.\nIf you want to offer more than 52 weeks, please choose Months from the drop-down.");return false}else{if(trialTerm==="M"&&trialPeriod>24){alert("— Oops, a slight problem: —\n\nMaximum Trial Months is: 24.\nIf you want to offer more than 24 months, please choose Years from the drop-down.");return false}else{if(trialTerm==="Y"&&trialPeriod>5){alert("— Oops, a slight problem: —\n\nMax Trial Period Years is: 5.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}}}}}}code.html(code.val().replace(/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/g," $1"));(parseInt(trialPeriod)<=0)?code.html(code.val().replace(/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick$3")):null;(regRecur==="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/g," <!--$1-->")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/g," $1_xclick-subscriptions$3")):null;(regRecur!=="BN")?code.html(code.val().replace(/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/g," <!--$1-->")):null;shortCodeTemplateAttrs+=(button==="modification")?'modify="1" ':"";shortCodeTemplateAttrs+='level="'+esc_attr(level)+'" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'" custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"';shortCodeTemplateAttrs+=' ta="'+esc_attr(trialAmount)+'" tp="'+esc_attr(trialPeriod)+'" tt="'+esc_attr(trialTerm)+'" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'" rrt="'+esc_attr(regRecurTimes)+'" rra="'+esc_attr(regRecurRetry)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="modify" value\="(.*?)"/,' name="modify" value="'+((button==="modification")?"1":"0")+'"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="src" value\="(.*?)"/,' name="src" value="'+esc_attr(regRecur)+'"'));code.html(code.val().replace(/ name\="srt" value\="(.*?)"/,' name="srt" value="'+esc_attr(regRecurTimes)+'"'));code.html(code.val().replace(/ name\="sra" value\="(.*?)"/,' name="sra" value="'+esc_attr(regRecurRetry)+'"'));code.html(code.val().replace(/ name\="a1" value\="(.*?)"/,' name="a1" value="'+esc_attr(trialAmount)+'"'));code.html(code.val().replace(/ name\="p1" value\="(.*?)"/,' name="p1" value="'+esc_attr(trialPeriod)+'"'));code.html(code.val().replace(/ name\="t1" value\="(.*?)"/,' name="t1" value="'+esc_attr(trialTerm)+'"'));code.html(code.val().replace(/ name\="a3" value\="(.*?)"/,' name="a3" value="'+esc_attr(regAmount)+'"'));code.html(code.val().replace(/ name\="p3" value\="(.*?)"/,' name="p3" value="'+esc_attr(regPeriod)+'"'));code.html(code.val().replace(/ name\="t3" value\="(.*?)"/,' name="t3" value="'+esc_attr(regTerm)+'"'));$("div#ws-plugin--s2member-"+button+"-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));(button==="modification")?alert("Your Modification Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Modification Buttons should be displayed to existing Users/Members, and they should be logged-in, BEFORE clicking this Button."):alert("Your Button has been generated.\nPlease copy/paste the Shortcode Format into your Membership Options Page.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalCcapButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-ccap-shortcode");var code=$("textarea#ws-plugin--s2member-ccap-button");var desc=$.trim($("input#ws-plugin--s2member-ccap-desc").val().replace(/"/g,""));var regAmount=$("input#ws-plugin--s2member-ccap-amount").val().replace(/[^0-9\.]/g,"");var regPeriod=$("select#ws-plugin--s2member-ccap-term").val().split("-")[0].replace(/[^0-9]/g,"");var regTerm=$("select#ws-plugin--s2member-ccap-term").val().split("-")[1].replace(/[^A-Z]/g,"");var regRecur=$("select#ws-plugin--s2member-ccap-term").val().split("-")[2].replace(/[^0-1BN]/g,"");var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-ccap-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-ccap-currency").val().replace(/[^A-Z]/g,"");var cCaps=$.trim($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).replace(/^(-all|-al|-a|-)[;,]*/gi,"").replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());cCaps=($.trim($("input#ws-plugin--s2member-ccap-ccaps").val()).match(/^(-all|-al|-a|-)[;,]*/i))?((cCaps)?"-all,":"-all")+cCaps.toLowerCase():cCaps.toLowerCase();var levelCcapsPer=(regRecur==="BN"&®Term!=="L")?"*:"+cCaps+":"+regPeriod+" "+regTerm:"*:"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(!cCaps||cCaps==="-all"){alert("— Oops, a slight problem: —\n\nPlease provide at least one Custom Capability.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}shortCodeTemplateAttrs+='level="*" ccaps="'+esc_attr(cCaps)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'" rp="'+esc_attr(regPeriod)+'" rt="'+esc_attr(regTerm)+'" rr="'+esc_attr(regRecur)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(levelCcapsPer)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-ccap-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode into your Login Welcome Page, or wherever you feel it would be most appropriate.\n\n* Remember, Independent Custom Capability Buttons should ONLY be displayed to existing Users/Members, and they MUST be logged-in, BEFORE clicking this Button.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalSpButtonGenerate=function(){var shortCodeTemplate='[s2Member-PayPal-Button %%attrs%% image="default" output="button" /]',shortCodeTemplateAttrs="";var shortCode=$("input#ws-plugin--s2member-sp-shortcode");var code=$("textarea#ws-plugin--s2member-sp-button");var leading=$("select#ws-plugin--s2member-sp-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-hours").val().replace(/[^0-9]/g,"");var regAmount=$("input#ws-plugin--s2member-sp-amount").val().replace(/[^0-9\.]/g,"");var desc=$.trim($("input#ws-plugin--s2member-sp-desc").val().replace(/"/g,""));var localeCode="",digital="0",noShipping="1";var pageStyle=$.trim($("input#ws-plugin--s2member-sp-page-style").val().replace(/"/g,""));var currencyCode=$("select#ws-plugin--s2member-sp-currency").val().replace(/[^A-Z]/g,"");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it's because you've not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.");return false}else{if(!regAmount||isNaN(regAmount)||regAmount<0.01){alert("— Oops, a slight problem: —\n\nAmount must be >= 0.01");return false}else{if(regAmount>10000&¤cyCode.toUpperCase()==="USD"){alert("— Oops, a slight problem: —\n\nMaximum Amount is: 10000.00");return false}else{if(!desc){alert("— Oops, a slight problem: —\n\nPlease type a Description for this Button.");return false}}}}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}var spIdsHours="sp:"+ids+":"+hours;shortCodeTemplateAttrs+='sp="1" ids="'+esc_attr(ids)+'" exp="'+esc_attr(hours)+'" desc="'+esc_attr(desc)+'" ps="'+esc_attr(pageStyle)+'" lc="'+esc_attr(localeCode)+'" cc="'+esc_attr(currencyCode)+'" dg="'+esc_attr(digital)+'" ns="'+esc_attr(noShipping)+'"';shortCodeTemplateAttrs+=' custom="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>" ra="'+esc_attr(regAmount)+'"';shortCode.val(shortCodeTemplate.replace(/%%attrs%%/,shortCodeTemplateAttrs));code.html(code.val().replace(/ name\="lc" value\="(.*?)"/,' name="lc" value="'+esc_attr(localeCode)+'"'));code.html(code.val().replace(/ name\="no_shipping" value\="(.*?)"/,' name="no_shipping" value="'+esc_attr(noShipping)+'"'));code.html(code.val().replace(/ name\="item_name" value\="(.*?)"/,' name="item_name" value="'+esc_attr(desc)+'"'));code.html(code.val().replace(/ name\="item_number" value\="(.*?)"/,' name="item_number" value="'+esc_attr(spIdsHours)+'"'));code.html(code.val().replace(/ name\="page_style" value\="(.*?)"/,' name="page_style" value="'+esc_attr(pageStyle)+'"'));code.html(code.val().replace(/ name\="currency_code" value\="(.*?)"/,' name="currency_code" value="'+esc_attr(currencyCode)+'"'));code.html(code.val().replace(/ name\="custom" value\="(.*?)"/,' name="custom" value="<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["HTTP_HOST"])); ?>"'));code.html(code.val().replace(/ name\="amount" value\="(.*?)"/,' name="amount" value="'+esc_attr(regAmount)+'"'));$("div#ws-plugin--s2member-sp-button-prev").html(code.val().replace(/\<form/,'<form target="_blank"').replace(/\<\?php echo S2MEMBER_VALUE_FOR_PP_INV\(\); \?\>/g,Math.round(new Date().getTime())+'~<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (esc_attr ($_SERVER["REMOTE_ADDR"])); ?>').replace(/\<\?php echo S2MEMBER_CURRENT_USER_VALUE_FOR_PP_(ON0|OS0|ON1|OS1); \?\>/g,""));alert("Your Button has been generated.\nPlease copy/paste the Shortcode into your WordPress Editor.");shortCode.each(function(){this.focus(),this.select()});return false};ws_plugin__s2member_paypalRegLinkGenerate=function(){var level=$("select#ws-plugin--s2member-reg-link-level").val().replace(/[^0-9]/g,"");var subscrID=$.trim($("input#ws-plugin--s2member-reg-link-subscr-id").val());var custom=$.trim($("input#ws-plugin--s2member-reg-link-custom").val());var cCaps=$.trim($.trim($("input#ws-plugin--s2member-reg-link-ccaps").val()).replace(/[ \-]/g,"_").replace(/[^a-z_0-9,]/gi,"").toLowerCase());var fixedTerm=$.trim($("input#ws-plugin--s2member-reg-link-fixed-term").val().replace(/[^A-Z 0-9]/gi,"").toUpperCase());var $link=$("p#ws-plugin--s2member-reg-link"),$loading=$("img#ws-plugin--s2member-reg-link-loading");var levelCcapsPer=(fixedTerm&&!fixedTerm.match(/L$/))?level+":"+cCaps+":"+fixedTerm:level+":"+cCaps;levelCcapsPer=levelCcapsPer.replace(/\:+$/g,"");if(!subscrID){alert("— Oops, a slight problem: —\n\nPaid Subscr. ID is a required value.");return false}else{if(!custom||custom.indexOf('<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq ($_SERVER["HTTP_HOST"]); ?>')!==0){alert("— Oops, a slight problem: —\n\nThe Custom Value MUST start with your domain name.");return false}else{if(fixedTerm&&!fixedTerm.match(/^[1-9]+ (D|W|M|Y|L)$/)){alert("— Oops, a slight problem: —\n\nThe Fixed Term Length is not formatted properly.");return false}}}$link.hide(),$loading.show(),$.post(ajaxurl,{action:"ws_plugin__s2member_reg_access_link_via_ajax",ws_plugin__s2member_reg_access_link_via_ajax:'<?php echo c_ws_plugin__s2member_utils_strings::esc_js_sq (wp_create_nonce ("ws-plugin--s2member-reg-access-link-via-ajax")); ?>',s2member_reg_access_link_subscr_gateway:"paypal",s2member_reg_access_link_subscr_id:subscrID,s2member_reg_access_link_custom:custom,s2member_reg_access_link_item_number:levelCcapsPer},function(response){$link.show().html('<a href="'+esc_attr(response)+'" target="_blank" rel="external">'+esc_html(response)+"</a>"),$loading.hide()});return false};ws_plugin__s2member_paypalSpLinkGenerate=function(){var leading=$("select#ws-plugin--s2member-sp-link-leading-id").val().replace(/[^0-9]/g,"");var additionals=$("select#ws-plugin--s2member-sp-link-additional-ids").val()||[];var hours=$("select#ws-plugin--s2member-sp-link-hours").val().replace(/[^0-9]/g,"");var $link=$("p#ws-plugin--s2member-sp-link"),$loading=$("img#ws-plugin--s2member-sp-link-loading");if(!leading){alert("— Oops, a slight problem: —\n\nPlease select a Leading Post/Page.\n\n*Tip* If there are no Posts/Pages in the menu, it's because you've not configured s2Member for Specific Post/Page Access yet. See: s2Member -› Restriction Options -› Specific Post/Page Access.");return false}for(var i=0,ids=leading;i<additionals.length;i++){if(additionals[i]&&additionals[i]!==leading){ids+=","+additionals[i]}}$link.hide(),$lo
|