CWIS Developer Documentation
PopupWindow.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: PopupWindow.php
4 #
5 # Part of the ScoutLib application support library
6 # Copyright 2002-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/
8 #
9 
14 {
15 
16  # ---- PUBLIC INTERFACE --------------------------------------------------
17 
26  public function __construct($PopupId, $DB, $UserId = NULL)
27  {
28  # save our window ID and database handle
29  $this->Id = intval($PopupId);
30  $this->DB = $DB;
31  $this->UserId = $UserId ? intval($UserId) : NULL;
32 
33  # set defaults
34  $this->Width = 400;
35  $this->Height = 200;
36  $this->ForceDisplay = FALSE;
37  $this->SeenCountThreshold = 5;
38  $this->SeenTimeThreshold = 60;
39  $this->CookieLifetimeInDays = 90;
40  }
41 
50  public function Initialize($CountThreshold, $TimeThreshold)
51  {
52  $this->SeenCountThreshold = $CountThreshold;
53  $this->SeenTimeThreshold = $TimeThreshold;
54  $this->ShouldDisplay();
55  }
56 
62  public function Width($NewWidth)
63  {
64  $this->Width = intval($NewWidth);
65  }
66 
72  public function Height($NewHeight)
73  {
74  $this->Height = intval($NewHeight);
75  }
76 
81  public function Id()
82  {
83  return $this->Id;
84  }
85 
91  public function WillDisplay()
92  {
93  return $this->ShouldDisplay();
94  }
95 
100  public function AlwaysDisplay($Display)
101  {
102  $this->ForceDisplay = $Display;
103  }
104 
109  public function PrintHeaderCode()
110  {
111  # if we should display the window
112  if ($this->ShouldDisplay())
113  {
114  ?>
115  <style type="text/css">@import 'include/thickbox.css';</style>
116  <script type="text/javascript" src="include/SPT--jQuery.js"></script>
117  <script type="text/javascript" src="include/thickbox-compressed.js"></script>
118  <script type="text/javascript">
119  $(document).ready(function(){
120  tb_show('', '#TB_inline?inlineId=PopupWindowContent<?PHP
121  print($this->Id()); ?>&width=<?PHP
122  print($this->Width); ?>&height=<?PHP
123  print($this->Height); ?>&modal=true', 'null');
124  });
125  </script>
126  <?PHP
127  }
128  }
129 
134  public function PrintBeginContentCode()
135  {
136  # if we should display the window
137  if ($this->ShouldDisplay())
138  {
139  # display code for beginning of content section
140  ?><div id="PopupWindowContent<?PHP print($this->Id());
141  ?>" style="display: none;"><span><?PHP
142  }
143  }
144 
149  public function PrintEndContentCode()
150  {
151  # if we should display the window
152  if ($this->ShouldDisplay())
153  {
154  # display code for end of content section
155  ?></span></div><?PHP
156  }
157  }
158 
159 
160  # ---- PRIVATE INTERFACE -------------------------------------------------
161 
162  private $Id;
163  private $DB;
164  private $UserId;
165  private $Width;
166  private $Height;
167  private $ForceDisplay;
168  private $SeenCountThreshold;
169  private $SeenTimeThreshold;
170  private $CookieLifetimeInDays;
171  private $DisplayStatus; # local to ShouldDisplay()
172  private $UserIdSeenCount; # local to SeenCountForUserId()
173  private $UserIdFirstSeen;
174  private $IPAddressSeenCount; # local to SeenCountForIPAddress()
175  private $IPAddressFirstSeen;
176 
184  private function ShouldDisplay()
185  {
186  # if user requested always display return TRUE to caller
187  if ($this->ForceDisplay) { return TRUE; }
188 
189  # if we have already determined status for this window
190  if (isset($this->DisplayStatus))
191  {
192  # return status to caller
193  return $this->DisplayStatus;
194  }
195 
196  # if cookie is available
197  if (isset($_COOKIE["ScoutPopupCount".$this->Id])
198  && isset($_COOKIE["ScoutPopupFirstSeen".$this->Id]))
199  {
200  # if cookie seen count is below threshold
201  $Count = $_COOKIE["ScoutPopupCount".$this->Id];
202  if ($Count < $this->SeenCountThreshold)
203  {
204  # increase cookie seen count
205  setcookie("ScoutPopupCount".$this->Id, ($Count + 1),
206  (time() + (60*60*24 * $this->CookieLifetimeInDays)));
207  setcookie("ScoutPopupFirstSeen".$this->Id,
208  $_COOKIE["ScoutPopupFirstSeen".$this->Id],
209  (time() + (60*60*24 * $this->CookieLifetimeInDays)));
210  }
211  else
212  {
213  # if enough time has elapsed and we are not sure about displaying window
214  if ((time() - $_COOKIE["ScoutPopupFirstSeen".$this->Id])
215  >= $this->SeenTimeThreshold)
216  {
217  # if cookie seen count is at threshold
218  if ($Count == $this->SeenCountThreshold)
219  {
220  # display the window
221  $Display = TRUE;
222 
223  # increase cookie seen count
224  setcookie("ScoutPopupCount".$this->Id, ($Count + 1),
225  (time() + (60*60*24 * $this->CookieLifetimeInDays)));
226  setcookie("ScoutPopupFirstSeen".$this->Id,
227  $_COOKIE["ScoutPopupFirstSeen".$this->Id],
228  (time() + (60*60*24 * $this->CookieLifetimeInDays)));
229  }
230  else
231  {
232  # do not display the window
233  $Display = FALSE;
234  }
235  }
236  }
237  }
238  else
239  {
240  # set cookie
241  setcookie("ScoutPopupFirstSeen".$this->Id, time(),
242  (time() + (60*60*24 * $this->CookieLifetimeInDays)));
243  setcookie("ScoutPopupCount".$this->Id, 1,
244  (time() + (60*60*24 * $this->CookieLifetimeInDays)));
245  }
246 
247  # if we know the user ID
248  if ($this->UserId !== NULL)
249  {
250  # if we have seen this user ID before
251  $Count = $this->SeenCountForUserId();
252  if ($Count !== NULL)
253  {
254  # if user ID seen count is below threshold
255  if ($Count < $this->SeenCountThreshold)
256  {
257  # increase user ID seen count
258  $Count = $this->SeenCountForUserId($Count + 1);
259  }
260  else
261  {
262  # if enough time has elapsed
263  if ($this->SecondsSinceUserIdFirstSeen()
264  >= $this->SeenTimeThreshold)
265  {
266  # if user ID seen count is at threshold
267  if ($Count == $this->SeenCountThreshold)
268  {
269  # display the window (if not previously disallowed)
270  if (!isset($Display)) { $Display = TRUE; }
271 
272  # increase user ID seen count
273  $Count = $this->SeenCountForUserId($Count + 1);
274  }
275  else
276  {
277  # do not display the window
278  $Display = FALSE;
279  }
280  }
281  }
282  }
283  else
284  {
285  # add user ID to database
286  $Count = $this->SeenCountForUserId(1);
287  }
288  }
289 
290  # if we have seen this IP address before
291  $Count = $this->SeenCountForIPAddress();
292  if ($Count !== NULL)
293  {
294  # if IP address seen count is below threshold
295  if ($Count < $this->SeenCountThreshold)
296  {
297  # increase IP address seen count
298  $Count = $this->SeenCountForIPAddress($Count + 1);
299  }
300  else
301  {
302  # if enough time has elapsed
303  if ($this->SecondsSinceIPAddressFirstSeen() >= $this->SeenTimeThreshold)
304  {
305  # if IP address seen count is at threshold
306  if ($Count == $this->SeenCountThreshold)
307  {
308  # display the window (if not previously disallowed)
309  if (!isset($Display)) { $Display = TRUE; }
310 
311  # increase IP address seen count
312  $Count = $this->SeenCountForIPAddress($Count + 1);
313  }
314  else
315  {
316  # do not display the window
317  $Display = FALSE;
318  }
319  }
320  }
321  }
322  else
323  {
324  # add IP address to database
325  $Count = $this->SeenCountForIPAddress(1);
326  }
327 
328  # if we are still not sure whether to display the window
329  if (!isset($Display))
330  {
331  # do not display the window
332  $Display = FALSE;
333  }
334 
335  # save window display status
336  $this->DisplayStatus = $Display;
337 
338  # return window display status to caller
339  return $Display;
340  }
341 
349  private function SeenCountForUserId($NewSeenCount = NULL)
350  {
351  # attempt to retrieve count from database
352  if (!isset($this->UserIdSeenCount))
353  {
354  $this->DB->Query("SELECT SeenCount, FirstSeen FROM PopupLog"
355  ." WHERE PopupId = ".$this->Id
356  ." AND SigOne = ".$this->UserId
357  ." AND SigTwo <= 0");
358  if( $this->DB->NumRowsSelected() )
359  {
360  $Tmp = $this->DB->FetchRow();
361  $this->UserIdSeenCount = $Tmp["SeenCount"];
362  $this->UserIdFirstSeen = $Tmp["FirstSeen"];
363  }
364  else
365  {
366  $this->UserIdSeenCount = NULL;
367  $this->UserIdFirstSeen = NULL;
368  }
369  }
370  $Count = $this->UserIdSeenCount;
371 
372  # if new count supplied
373  if ($NewSeenCount !== NULL)
374  {
375  # if count is already in database
376  if ($Count !== NULL)
377  {
378  # update count in database
379  $this->DB->Query("UPDATE PopupLog SET SeenCount = ".$NewSeenCount
380  ." WHERE PopupId = ".intval($this->Id)
381  ." AND SigOne = ".$this->UserId
382  ." AND SigTwo <= 0");
383  }
384  else
385  {
386  # add count to database
387  $this->DB->Query("INSERT INTO PopupLog"
388  ." (PopupId, SigOne, SigTwo, FirstSeen, SeenCount) VALUES "
389  ." (".$this->Id.", ".$this->UserId.", -1, NOW(), "
390  .$NewSeenCount.")");
391  }
392 
393  # set current count to new count
394  $Count = $NewSeenCount;
395  }
396 
397  # return current count to caller
398  return $Count;
399  }
400 
401 
410  private function SeenCountForIPAddress($NewSeenCount = NULL)
411  {
412  # attempt to retrieve count from database
413  if (!isset($this->IPAddressSeenCount))
414  {
415  $this->DB->Query("SELECT SeenCount, FirstSeen FROM PopupLog"
416  ." WHERE PopupId = ".$this->Id
417  ." AND SigOne = ".$this->UserIPSigOne()
418  ." AND SigTwo = ".$this->UserIPSigTwo());
419  if( $this->DB->NumRowsSelected() )
420  {
421  $Tmp = $this->DB->FetchRow();
422  $this->IPAddressSeenCount = $Tmp["SeenCount"];
423  $this->IPAddressFirstSeen = $Tmp["FirstSeen"];
424  }
425  else
426  {
427  $this->IPAddressSeenCount = NULL;
428  $this->IPAddressFirstSeen = NULL;
429  }
430  }
431  $Count = $this->IPAddressSeenCount;
432 
433  # if new count supplied
434  if ($NewSeenCount !== NULL)
435  {
436  # if count is already in database
437  if ($Count !== NULL)
438  {
439  # update count in database
440  $this->DB->Query("UPDATE PopupLog SET SeenCount = ".$NewSeenCount
441  ." WHERE SigOne = ".$this->UserIPSigOne()
442  ." AND SigTwo = ".$this->UserIPSigTwo());
443  }
444  else
445  {
446  # add count to database
447  $this->DB->Query("INSERT INTO PopupLog"
448  ." (PopupId, SigOne, SigTwo, SeenCount, FirstSeen)"
449  ." VALUES (".$this->Id.", "
450  .$this->UserIPSigOne().", "
451  .$this->UserIPSigTwo().", "
452  .$NewSeenCount.", NOW())");
453  }
454 
455  # set current count to new count
456  $Count = $NewSeenCount;
457  }
458 
459  # return current count to caller
460  return $Count;
461  }
462 
468  private function SecondsSinceUserIdFirstSeen()
469  {
470  if (!isset($this->UserIdFirstSeen)) { $this->SeenCountForUserId(); }
471  return time() - strtotime($this->UserIdFirstSeen);
472  }
473 
480  private function SecondsSinceIPAddressFirstSeen()
481  {
482  if (!isset($this->IPAddressFirstSeen)) { $this->SeenCountForIPAddress(); }
483  return time() - strtotime($this->IPAddressFirstSeen);
484  }
485 
492  private function UserIPSigOne()
493  {
494  $Bytes = explode(".", $_SERVER["REMOTE_ADDR"]);
495  return (count($Bytes) != 4) ? 0
496  : (intval($Bytes[0]) * 256) + intval($Bytes[1]);
497  }
498 
505  private function UserIPSigTwo()
506  {
507  $Bytes = explode(".", $_SERVER["REMOTE_ADDR"]);
508  return (count($Bytes) != 4) ? 0
509  : (intval($Bytes[2]) * 256) + intval($Bytes[3]);
510  }
511 }
Lightboxed pop-up window with repeat prevention.
Definition: PopupWindow.php:13
PrintBeginContentCode()
Print the beginning code wrapper for the pop-up window content section in page body if appropriate...
AlwaysDisplay($Display)
Sets the flag that forces the pop-up window to display.
Width($NewWidth)
Set the width of the pop-up window.
Definition: PopupWindow.php:62
PrintHeaderCode()
Print header code if appropriate.
WillDisplay()
Report whether the pop-up window will display if code printing methods are called.
Definition: PopupWindow.php:91
Initialize($CountThreshold, $TimeThreshold)
Initialize pop-up window tracking.
Definition: PopupWindow.php:50
Height($NewHeight)
Set the height of the pop-up window.
Definition: PopupWindow.php:72
__construct($PopupId, $DB, $UserId=NULL)
Object constructor.
Definition: PopupWindow.php:26
Id()
Get the integer ID of window.
Definition: PopupWindow.php:81
PrintEndContentCode()
Print the ending code wrapper for the pop-up window content section in page body if appropriate...