00001 <?PHP 00002 # 00003 # FILE: Scout--PopupWindow.php 00004 # Copyright 2009 Edward Almasy and Internet Scout 00005 # http://scout.wisc.edu 00006 # 00007 00011 class PopupWindow { 00012 00013 # ---- PUBLIC INTERFACE -------------------------------------------------- 00014 00021 function PopupWindow($PopupId, $DB, $UserId = NULL) 00022 { 00023 # save our window ID and database handle 00024 $this->Id = intval($PopupId); 00025 $this->DB = $DB; 00026 $this->UserId = $UserId ? intval($UserId) : NULL; 00027 00028 # set defaults 00029 $this->Width = 400; 00030 $this->Height = 200; 00031 $this->ForceDisplay = FALSE; 00032 $this->SeenCountThreshold = 5; 00033 $this->SeenTimeThreshold = 60; 00034 $this->CookieLifetimeInDays = 90; 00035 } 00036 00042 function Initialize($CountThreshold, $TimeThreshold) 00043 { 00044 $this->SeenCountThreshold = $CountThreshold; 00045 $this->SeenTimeThreshold = $TimeThreshold; 00046 $this->ShouldDisplay(); 00047 } 00048 00052 function Width($NewWidth) { $this->Width = intval($NewWidth); } 00056 function Height($NewHeight) { $this->Height = intval($NewHeight); } 00057 00062 function Id() { return $this->Id; } 00063 00068 function WillDisplay() { return $this->ShouldDisplay(); } 00069 00074 function AlwaysDisplay($Display) { $this->ForceDisplay = $Display; } 00075 00079 function PrintHeaderCode() 00080 { 00081 # if we should display the window 00082 if ($this->ShouldDisplay()) 00083 { 00084 ?> 00085 <style type="text/css">@import 'include/thickbox.css';</style> 00086 <script type="text/javascript" src="include/SPT--jQuery.js"></script> 00087 <script type="text/javascript" src="include/thickbox-compressed.js"></script> 00088 <script type="text/javascript"> 00089 $(document).ready(function(){ 00090 tb_show('', '#TB_inline?inlineId=PopupWindowContent<?PHP 00091 print($this->Id()); ?>&width=<?PHP 00092 print($this->Width); ?>&height=<?PHP 00093 print($this->Height); ?>&modal=true', 'null'); 00094 }); 00095 </script> 00096 <?PHP 00097 } 00098 } 00099 00103 function PrintBeginContentCode() 00104 { 00105 # if we should display the window 00106 if ($this->ShouldDisplay()) 00107 { 00108 # display code for beginning of content section 00109 ?><div id="PopupWindowContent<?PHP print($this->Id()); 00110 ?>" style="display: none;"><span><?PHP 00111 } 00112 } 00113 00117 function PrintEndContentCode() 00118 { 00119 # if we should display the window 00120 if ($this->ShouldDisplay()) 00121 { 00122 # display code for end of content section 00123 ?></span></div><?PHP 00124 } 00125 } 00126 00127 00128 # ---- PRIVATE INTERFACE ------------------------------------------------- 00129 00130 private $Id; 00131 private $DB; 00132 private $UserId; 00133 private $Width; 00134 private $Height; 00135 private $ForceDisplay; 00136 private $SeenCountThreshold; 00137 private $SeenTimeThreshold; 00138 private $CookieLifetimeInDays; 00139 private $DisplayStatus; # local to ShouldDisplay() 00140 private $UserIdSeenCount; # local to SeenCountForUserId() 00141 private $UserIdFirstSeen; 00142 private $IPAddressSeenCount; # local to SeenCountForIPAddress() 00143 private $IPAddressFirstSeen; 00144 00145 # determine whether pop-up window should be displayed 00146 private function ShouldDisplay() 00147 { 00148 # if user requested always display return TRUE to caller 00149 if ($this->ForceDisplay) { return TRUE; } 00150 00151 # if we have already determined status for this window 00152 if (isset($this->DisplayStatus)) 00153 { 00154 # return status to caller 00155 return $this->DisplayStatus; 00156 } 00157 00158 # if cookie is available 00159 if (isset($_COOKIE["ScoutPopupCount".$this->Id]) 00160 && isset($_COOKIE["ScoutPopupFirstSeen".$this->Id])) 00161 { 00162 # if cookie seen count is below threshold 00163 $Count = $_COOKIE["ScoutPopupCount".$this->Id]; 00164 if ($Count < $this->SeenCountThreshold) 00165 { 00166 # increase cookie seen count 00167 setcookie("ScoutPopupCount".$this->Id, ($Count + 1), 00168 (time() + (60*60*24 * $this->CookieLifetimeInDays))); 00169 setcookie("ScoutPopupFirstSeen".$this->Id, 00170 $_COOKIE["ScoutPopupFirstSeen".$this->Id], 00171 (time() + (60*60*24 * $this->CookieLifetimeInDays))); 00172 } 00173 else 00174 { 00175 # if enough time has elapsed and we are not sure about displaying window 00176 if ((time() - $_COOKIE["ScoutPopupFirstSeen".$this->Id]) 00177 >= $this->SeenTimeThreshold) 00178 { 00179 # if cookie seen count is at threshold 00180 if ($Count == $this->SeenCountThreshold) 00181 { 00182 # display the window 00183 $Display = TRUE; 00184 00185 # increase cookie seen count 00186 setcookie("ScoutPopupCount".$this->Id, ($Count + 1), 00187 (time() + (60*60*24 * $this->CookieLifetimeInDays))); 00188 setcookie("ScoutPopupFirstSeen".$this->Id, 00189 $_COOKIE["ScoutPopupFirstSeen".$this->Id], 00190 (time() + (60*60*24 * $this->CookieLifetimeInDays))); 00191 } 00192 else 00193 { 00194 # do not display the window 00195 $Display = FALSE; 00196 } 00197 } 00198 } 00199 } 00200 else 00201 { 00202 # set cookie 00203 setcookie("ScoutPopupFirstSeen".$this->Id, time(), 00204 (time() + (60*60*24 * $this->CookieLifetimeInDays))); 00205 setcookie("ScoutPopupCount".$this->Id, 1, 00206 (time() + (60*60*24 * $this->CookieLifetimeInDays))); 00207 } 00208 00209 # if we know the user ID 00210 if ($this->UserId !== NULL) 00211 { 00212 # if we have seen this user ID before 00213 $Count = $this->SeenCountForUserId(); 00214 if ($Count !== NULL) 00215 { 00216 # if user ID seen count is below threshold 00217 if ($Count < $this->SeenCountThreshold) 00218 { 00219 # increase user ID seen count 00220 $Count = $this->SeenCountForUserId($Count + 1); 00221 } 00222 else 00223 { 00224 # if enough time has elapsed 00225 if ($this->SecondsSinceUserIdFirstSeen() 00226 >= $this->SeenTimeThreshold) 00227 { 00228 # if user ID seen count is at threshold 00229 if ($Count == $this->SeenCountThreshold) 00230 { 00231 # display the window (if not previously disallowed) 00232 if (!isset($Display)) { $Display = TRUE; } 00233 00234 # increase user ID seen count 00235 $Count = $this->SeenCountForUserId($Count + 1); 00236 } 00237 else 00238 { 00239 # do not display the window 00240 $Display = FALSE; 00241 } 00242 } 00243 } 00244 } 00245 else 00246 { 00247 # add user ID to database 00248 $Count = $this->SeenCountForUserId(1); 00249 } 00250 } 00251 00252 # if we have seen this IP address before 00253 $Count = $this->SeenCountForIPAddress(); 00254 if ($Count !== NULL) 00255 { 00256 # if IP address seen count is below threshold 00257 if ($Count < $this->SeenCountThreshold) 00258 { 00259 # increase IP address seen count 00260 $Count = $this->SeenCountForIPAddress($Count + 1); 00261 } 00262 else 00263 { 00264 # if enough time has elapsed 00265 if ($this->SecondsSinceIPAddressFirstSeen() >= $this->SeenTimeThreshold) 00266 { 00267 # if IP address seen count is at threshold 00268 if ($Count == $this->SeenCountThreshold) 00269 { 00270 # display the window (if not previously disallowed) 00271 if (!isset($Display)) { $Display = TRUE; } 00272 00273 # increase IP address seen count 00274 $Count = $this->SeenCountForIPAddress($Count + 1); 00275 } 00276 else 00277 { 00278 # do not display the window 00279 $Display = FALSE; 00280 } 00281 } 00282 } 00283 } 00284 else 00285 { 00286 # add IP address to database 00287 $Count = $this->SeenCountForIPAddress(1); 00288 } 00289 00290 # if we are still not sure whether to display the window 00291 if (!isset($Display)) 00292 { 00293 # do not display the window 00294 $Display = FALSE; 00295 } 00296 00297 # save window display status 00298 $this->DisplayStatus = $Display; 00299 00300 # return window display status to caller 00301 return $Display; 00302 } 00303 00304 # get/set seen count for current user ID (returns NULL if not set) 00305 private function SeenCountForUserId($NewSeenCount = NULL) 00306 { 00307 # attempt to retrieve count from database 00308 if (!isset($this->UserIdSeenCount)) 00309 { 00310 $this->DB->Query("SELECT SeenCount, FirstSeen FROM PopupLog" 00311 ." WHERE PopupId = ".$this->Id 00312 ." AND SigOne = ".$this->UserId 00313 ." AND SigTwo <= 0"); 00314 if( $this->DB->NumRowsSelected() ) 00315 { 00316 $Tmp = $this->DB->FetchRow(); 00317 $this->UserIdSeenCount = $Tmp["SeenCount"]; 00318 $this->UserIdFirstSeen = $Tmp["FirstSeen"]; 00319 } 00320 else 00321 { 00322 $this->UserIdSeenCount = NULL; 00323 $this->UserIdFirstSeen = NULL; 00324 } 00325 } 00326 $Count = $this->UserIdSeenCount; 00327 00328 # if new count supplied 00329 if ($NewSeenCount !== NULL) 00330 { 00331 # if count is already in database 00332 if ($Count !== NULL) 00333 { 00334 # update count in database 00335 $this->DB->Query("UPDATE PopupLog SET SeenCount = ".$NewSeenCount 00336 ." WHERE PopupId = ".intval($this->Id) 00337 ." AND SigOne = ".$this->UserId 00338 ." AND SigTwo <= 0"); 00339 } 00340 else 00341 { 00342 # add count to database 00343 $this->DB->Query("INSERT INTO PopupLog" 00344 ." (PopupId, SigOne, SigTwo, FirstSeen, SeenCount) VALUES " 00345 ." (".$this->Id.", ".$this->UserId.", -1, NOW(), " 00346 .$NewSeenCount.")"); 00347 } 00348 00349 # set current count to new count 00350 $Count = $NewSeenCount; 00351 } 00352 00353 # return current count to caller 00354 return $Count; 00355 } 00356 00357 # get/set seen count for IP address of current user (returns NULL if not set) 00358 private function SeenCountForIPAddress($NewSeenCount = NULL) 00359 { 00360 # attempt to retrieve count from database 00361 if (!isset($this->IPAddressSeenCount)) 00362 { 00363 $this->DB->Query("SELECT SeenCount, FirstSeen FROM PopupLog" 00364 ." WHERE PopupId = ".$this->Id 00365 ." AND SigOne = ".$this->UserIPSigOne() 00366 ." AND SigTwo = ".$this->UserIPSigTwo()); 00367 if( $this->DB->NumRowsSelected() ) 00368 { 00369 $Tmp = $this->DB->FetchRow(); 00370 $this->IPAddressSeenCount = $Tmp["SeenCount"]; 00371 $this->IPAddressFirstSeen = $Tmp["FirstSeen"]; 00372 } 00373 else 00374 { 00375 $this->IPAddressSeenCount = NULL; 00376 $this->IPAddressFirstSeen = NULL; 00377 } 00378 } 00379 $Count = $this->IPAddressSeenCount; 00380 00381 # if new count supplied 00382 if ($NewSeenCount !== NULL) 00383 { 00384 # if count is already in database 00385 if ($Count !== NULL) 00386 { 00387 # update count in database 00388 $this->DB->Query("UPDATE PopupLog SET SeenCount = ".$NewSeenCount 00389 ." WHERE SigOne = ".$this->UserIPSigOne() 00390 ." AND SigTwo = ".$this->UserIPSigTwo()); 00391 } 00392 else 00393 { 00394 # add count to database 00395 $this->DB->Query("INSERT INTO PopupLog" 00396 ." (PopupId, SigOne, SigTwo, SeenCount, FirstSeen)" 00397 ." VALUES (".$this->Id.", " 00398 .$this->UserIPSigOne().", " 00399 .$this->UserIPSigTwo().", " 00400 .$NewSeenCount.", NOW())"); 00401 } 00402 00403 # set current count to new count 00404 $Count = $NewSeenCount; 00405 } 00406 00407 # return current count to caller 00408 return $Count; 00409 } 00410 00411 # get seconds since current user ID first seen 00412 private function SecondsSinceUserIdFirstSeen() 00413 { 00414 if (!isset($this->UserIdFirstSeen)) { $this->SeenCountForUserId(); } 00415 return time() - strtotime($this->UserIdFirstSeen); 00416 } 00417 00418 # get seconds since IP address of current user first seen 00419 private function SecondsSinceIPAddressFirstSeen() 00420 { 00421 if (!isset($this->IPAddressFirstSeen)) { $this->SeenCountForIPAddress(); } 00422 return time() - strtotime($this->IPAddressFirstSeen); 00423 } 00424 00425 # return signature values for IP address of current user 00426 private function UserIPSigOne() 00427 { 00428 $Bytes = explode(".", $_SERVER["REMOTE_ADDR"]); 00429 return (count($Bytes) != 4) ? 0 00430 : (intval($Bytes[0]) * 256) + intval($Bytes[1]); 00431 } 00432 private function UserIPSigTwo() 00433 { 00434 $Bytes = explode(".", $_SERVER["REMOTE_ADDR"]); 00435 return (count($Bytes) != 4) ? 0 00436 : (intval($Bytes[2]) * 256) + intval($Bytes[3]); 00437 } 00438 } 00439 00440 00441 ?>