CWIS Developer Documentation
ItemFactory.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: ItemFactory.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2007-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9 
17 abstract class ItemFactory {
18 
19  # ---- PUBLIC INTERFACE --------------------------------------------------
20 
36  function ItemFactory($ItemClassName, $ItemTableName, $ItemIdFieldName,
37  $ItemNameFieldName = NULL, $OrderOpsAllowed = FALSE, $SqlCondition = NULL)
38  {
39  # save item access names
40  $this->ItemClassName = $ItemClassName;
41  $this->ItemTableName = $ItemTableName;
42  $this->ItemIdFieldName = $ItemIdFieldName;
43  $this->ItemNameFieldName = $ItemNameFieldName;
44 
45  # save flag indicating whether item type allows ordering operations
46  $this->OrderOpsAllowed = $OrderOpsAllowed;
47  if ($OrderOpsAllowed)
48  {
49  $this->OrderList = new PersistentDoublyLinkedList(
50  $ItemTableName, $ItemIdFieldName);
51  $this->SetOrderOpsCondition(NULL);
52  }
53 
54  # save database operation conditional
55  $this->SqlCondition = $SqlCondition;
56 
57  # grab our own database handle
58  $this->DB = new Database();
59  }
60 
65  function GetItemClassName()
66  {
67  return $this->ItemClassName;
68  }
69 
75  {
76  # if ID available in session variable
77  $SessionIndex = $this->ItemClassName."EditedIds";
78  if (isset($_SESSION[$SessionIndex]))
79  {
80  # look up value in session variable
81  $ItemId = $_SESSION[$SessionIndex][0];
82  }
83  else
84  {
85  # attempt to look up last temp item ID
86  $ItemId = $this->GetLastTempItemId();
87 
88  # store it in session variable
89  $_SESSION[$SessionIndex] = array($ItemId);
90  }
91 
92  # return ID (if any) to caller
93  return $ItemId;
94  }
95 
100  function SetCurrentEditedItemId($NewId)
101  {
102  # if edited ID array already stored for session
103  $SessionIndex = $this->ItemClassName."EditedIds";
104  if (isset($_SESSION[$SessionIndex]))
105  {
106  # prepend new value to array
107  array_unshift($_SESSION[$SessionIndex], $NewId);
108  }
109  else
110  {
111  # start with fresh array
112  $_SESSION[$SessionIndex] = array($NewId);
113  }
114  }
115 
120  {
121  # if edited item IDs available in a session variable
122  $SessionIndex = $this->ItemClassName."EditedIds";
123  if (isset($_SESSION[$SessionIndex]))
124  {
125  # remove current item from edited item ID array
126  array_shift($_SESSION[$SessionIndex]);
127 
128  # if no further edited items
129  if (count($_SESSION[$SessionIndex]) < 1)
130  {
131  # destroy session variable
132  unset($_SESSION[$SessionIndex]);
133  }
134  }
135  }
136 
144  {
145  # if current edited item is temp item
146  $CurrentEditedItemId = $this->GetCurrentEditedItemId();
147  if ($CurrentEditedItemId < 0)
148  {
149  # delete temp item from DB
150  if (method_exists($this->ItemClassName, "Delete"))
151  {
152  $Item = new $this->ItemClassName($CurrentEditedItemId);
153  $Item->Delete();
154  }
155  else
156  {
157  $this->DB->Query("DELETE FROM ".$this->ItemTableName
158  ." WHERE ".$this->ItemIdFieldName." = ".$CurrentEditedItemId);
159  }
160  }
161 
162  # clear current edited item ID
163  $this->ClearCurrentEditedItemId();
164  }
165 
173  function CleanOutStaleTempItems($MinutesUntilStale = 10080)
174  {
175  # load array of stale items
176  $MinutesUntilStale = max($MinutesUntilStale, 1);
177  $this->DB->Query("SELECT ".$this->ItemIdFieldName." FROM ".$this->ItemTableName
178  ." WHERE ".$this->ItemIdFieldName." < 0"
179  ." AND DateLastModified < DATE_SUB(NOW(), "
180  ." INTERVAL ".intval($MinutesUntilStale)." MINUTE)"
181  .($this->SqlCondition ? " AND ".$this->SqlCondition : ""));
182  $ItemIds = $this->DB->FetchColumn($this->ItemIdFieldName);
183 
184  # delete stale items
185  foreach ($ItemIds as $ItemId)
186  {
187  $Item = new $this->ItemClassName($ItemId);
188  $Item->Delete();
189  }
190 
191  # report number of items deleted to caller
192  return count($ItemIds);
193  }
194 
200  function GetLastTempItemId()
201  {
202  # retrieve ID of most recently modified temp item for this user
203  $ItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName
204  ." FROM ".$this->ItemTableName
205  ." WHERE LastModifiedById = '"
206  .$GLOBALS["User"]->Get("UserId")."'"
207  ." AND ".$this->ItemIdFieldName." < 0"
208  .($this->SqlCondition ? " AND ".$this->SqlCondition : "")
209  ." ORDER BY ".$this->ItemIdFieldName." ASC"
210  ." LIMIT 1",
211  $this->ItemIdFieldName);
212 
213  # return item to caller (or NULL if none found)
214  return $ItemId;
215  }
216 
222  function GetNextItemId()
223  {
224  # if no highest item ID found
225  $HighestItemId = $this->GetHighestItemId(TRUE);
226  if ($HighestItemId <= 0)
227  {
228  # start with item ID 1
229  $ItemId = 1;
230  }
231  else
232  {
233  # else use next ID available after highest
234  $ItemId = $HighestItemId + 1;
235  }
236 
237  # return next ID to caller
238  return $ItemId;
239  }
240 
248  function GetHighestItemId($IgnoreSqlCondition = FALSE)
249  {
250  # use class-wide condition if set
251  $ConditionString = ($this->SqlCondition && !$IgnoreSqlCondition)
252  ? " WHERE ".$this->SqlCondition : "";
253 
254  # return highest item ID to caller
255  return $this->DB->Query("SELECT ".$this->ItemIdFieldName
256  ." FROM ".$this->ItemTableName
257  .$ConditionString
258  ." ORDER BY ".$this->ItemIdFieldName
259  ." DESC LIMIT 1",
260  $this->ItemIdFieldName);
261  }
262 
267  function GetNextTempItemId()
268  {
269  $LowestItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName
270  ." FROM ".$this->ItemTableName
271  ." ORDER BY ".$this->ItemIdFieldName
272  ." ASC LIMIT 1",
273  $this->ItemIdFieldName);
274  if ($LowestItemId > 0)
275  {
276  $ItemId = -1;
277  }
278  else
279  {
280  $ItemId = $LowestItemId - 1;
281  }
282  return $ItemId;
283  }
284 
293  function GetItemCount($Condition = NULL, $IncludeTempItems = FALSE)
294  {
295  # use condition if supplied
296  $ConditionString = ($Condition != NULL) ? " WHERE ".$Condition : "";
297 
298  # if temp items are to be excluded
299  if (!$IncludeTempItems)
300  {
301  # if a condition was previously set
302  if (strlen($ConditionString))
303  {
304  # add in condition to exclude temp items
305  $ConditionString .= " AND (".$this->ItemIdFieldName." >= 0)";
306  }
307  else
308  {
309  # use condition to exclude temp items
310  $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0";
311  }
312  }
313 
314  # add class-wide condition if set
315  if ($this->SqlCondition)
316  {
317  if (strlen($ConditionString))
318  {
319  $ConditionString .= " AND ".$this->SqlCondition;
320  }
321  else
322  {
323  $ConditionString = " WHERE ".$this->SqlCondition;
324  }
325  }
326 
327  # retrieve item count
328  $Count = $this->DB->Query("SELECT COUNT(*) AS RecordCount"
329  ." FROM ".$this->ItemTableName
330  .$ConditionString,
331  "RecordCount");
332 
333  # return count to caller
334  return $Count;
335  }
336 
350  function GetItemIds($Condition = NULL, $IncludeTempItems = FALSE,
351  $SortField = NULL, $SortAscending = TRUE)
352  {
353  # if temp items are supposed to be included
354  if ($IncludeTempItems)
355  {
356  # condition is only as supplied
357  $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
358  }
359  else
360  {
361  # condition is non-negative IDs plus supplied condition
362  $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0"
363  .(($Condition == NULL) ? "" : " AND ".$Condition);
364  }
365 
366  # add class-wide condition if set
367  if ($this->SqlCondition)
368  {
369  if (strlen($ConditionString))
370  {
371  $ConditionString .= " AND ".$this->SqlCondition;
372  }
373  else
374  {
375  $ConditionString = " WHERE ".$this->SqlCondition;
376  }
377  }
378 
379  # add sorting if specified
380  if ($SortField !== NULL)
381  {
382  $ConditionString .= " ORDER BY `".addslashes($SortField)."` "
383  .($SortAscending ? "ASC" : "DESC");
384  }
385 
386  # get item IDs
387  $this->DB->Query("SELECT ".$this->ItemIdFieldName
388  ." FROM ".$this->ItemTableName
389  .$ConditionString);
390  $ItemIds = $this->DB->FetchColumn($this->ItemIdFieldName);
391 
392  # return IDs to caller
393  return $ItemIds;
394  }
395 
403  function GetLatestModificationDate($Condition = NULL)
404  {
405  # set up SQL condition if supplied
406  $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
407 
408  # add class-wide condition if set
409  if ($this->SqlCondition)
410  {
411  if (strlen($ConditionString))
412  {
413  $ConditionString .= " AND ".$this->SqlCondition;
414  }
415  else
416  {
417  $ConditionString = " WHERE ".$this->SqlCondition;
418  }
419  }
420 
421  # return modification date for item most recently changed
422  return $this->DB->Query("SELECT MAX(DateLastModified) AS LastChangeDate"
423  ." FROM ".$this->ItemTableName.$ConditionString,
424  "LastChangeDate");
425  }
426 
433  function GetItem($ItemId)
434  {
435  return new $this->ItemClassName($ItemId);
436  }
437 
445  function ItemExists($ItemId, $IgnoreSqlCondition = FALSE)
446  {
447  $Condition = $IgnoreSqlCondition ? ""
448  : ($this->SqlCondition ? " AND ".$this->SqlCondition : "");
449  $ItemCount = $this->DB->Query("SELECT COUNT(*) AS ItemCount"
450  ." FROM ".$this->ItemTableName
451  ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId)
452  .$Condition, "ItemCount");
453  return ($ItemCount > 0) ? TRUE : FALSE;
454  }
455 
463  function GetItemByName($Name, $IgnoreCase = FALSE)
464  {
465  # get item ID
466  $ItemId = $this->GetItemIdByName($Name, $IgnoreCase);
467 
468  # if item not found
469  if ($ItemId === NULL)
470  {
471  # report error to caller
472  return NULL;
473  }
474  else
475  {
476  # load object and return to caller
477  return $this->GetItem($ItemId);
478  }
479  }
480 
488  function GetItemIdByName($Name, $IgnoreCase = FALSE)
489  {
490  # error out if this is an illegal operation for this item type
491  if ($this->ItemNameFieldName == NULL)
492  {
493  throw new Exception("Attempt to get item ID by name on item type"
494  ."(".$this->ItemClassName.") that has no name field specified.");
495  }
496 
497  # query database for item ID
498  $Comparison = $IgnoreCase
499  ? "LOWER(".$this->ItemNameFieldName.") = '"
500  .addslashes(strtolower($Name))."'"
501  : $this->ItemNameFieldName." = '" .addslashes($Name)."'";
502  $ItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName
503  ." FROM ".$this->ItemTableName
504  ." WHERE ".$Comparison
505  .($this->SqlCondition
506  ? " AND ".$this->SqlCondition
507  : ""),
508  $this->ItemIdFieldName);
509 
510  # return ID or error indicator to caller
511  return ($ItemId === FALSE) ? NULL : $ItemId;
512  }
513 
520  function GetItemNames($SqlCondition = NULL)
521  {
522  # error out if this is an illegal operation for this item type
523  if ($this->ItemNameFieldName == NULL)
524  {
525  throw new Exception("Attempt to get array of item names"
526  ." on item type (".$this->ItemClassName.") that has no"
527  ." name field specified.");
528  }
529 
530  # query database for item names
531  $Condition = "";
532  if ($SqlCondition)
533  {
534  $Condition = "WHERE ".$SqlCondition;
535  }
536  if ($this->SqlCondition)
537  {
538  if (strlen($Condition))
539  {
540  $Condition .= " AND ".$this->SqlCondition;
541  }
542  else
543  {
544  $Condition = " WHERE ".$this->SqlCondition;
545  }
546  }
547  $this->DB->Query("SELECT ".$this->ItemIdFieldName
548  .", ".$this->ItemNameFieldName
549  ." FROM ".$this->ItemTableName." "
550  .$Condition
551  ." ORDER BY ".$this->ItemNameFieldName);
552  $Names = $this->DB->FetchColumn(
553  $this->ItemNameFieldName, $this->ItemIdFieldName);
554 
555  # return item names to caller
556  return $Names;
557  }
558 
565  function GetItems($SqlCondition = NULL)
566  {
567  $Items = array();
568  $Ids = $this->GetItemIds($SqlCondition);
569  foreach ($Ids as $Id)
570  {
571  $Items[$Id] = $this->GetItem($Id);
572  }
573  return $Items;
574  }
575 
591  function GetItemsAsOptionList($OptionListName, $SelectedItemId = NULL,
592  $SqlCondition = NULL, $DisplaySize = 1, $SubmitOnChange = FALSE)
593  {
594  # retrieve requested fields
595  $ItemNames = $this->GetItemNames($SqlCondition);
596 
597  # if multiple selections are allowed
598  if ($DisplaySize > 1)
599  {
600  # begin multi-selection HTML option list
601  $Html = "<select name=\"".htmlspecialchars($OptionListName)."[]\""
602  .($SubmitOnChange ? " onChange=\"submit()\"" : "")
603  ." multiple=\"multiple\" size=\"".$DisplaySize."\">\n";
604  }
605  else
606  {
607  # begin single-selection HTML option list
608  $Html = "<select name=\"".htmlspecialchars($OptionListName)."\""
609  .($SubmitOnChange ? " onChange=\"submit()\"" : "")
610  ." size=\"1\">\n";
611  $Html .= "<option value=\"-1\">--</option>\n";
612  }
613 
614  # for each metadata field
615  foreach ($ItemNames as $Id => $Name)
616  {
617  # add entry for field to option list
618  $Html .= "<option value=\"".$Id."\"";
619  if (($Id == $SelectedItemId)
620  || (is_array($SelectedItemId) && in_array($Id, $SelectedItemId)))
621  {
622  $Html .= " selected";
623  }
624  $Html .= ">".htmlspecialchars($Name)."</option>\n";
625  }
626 
627  # end HTML option list
628  $Html .= "</select>\n";
629 
630  # return constructed HTML to caller
631  return $Html;
632  }
633 
640  function NameIsInUse($Name, $IgnoreCase = FALSE)
641  {
642  $Condition = $IgnoreCase
643  ? "LOWER(".$this->ItemNameFieldName.")"
644  ." = '".addslashes(strtolower($Name))."'"
645  : $this->ItemNameFieldName." = '".addslashes($Name)."'";
646  if ($this->SqlCondition)
647  {
648  $Condition .= " AND ".$this->SqlCondition;
649  }
650  $NameCount = $this->DB->Query("SELECT COUNT(*) AS RecordCount FROM "
651  .$this->ItemTableName." WHERE ".$Condition, "RecordCount");
652  return ($NameCount > 0) ? TRUE : FALSE;
653  }
654 
671  function SearchForItemNames($SearchString, $NumberOfResults = 100,
672  $IncludeVariants = FALSE, $UseBooleanMode = TRUE, $Offset=0,
673  $IdExclusions = array(), $ValueExclusions=array())
674  {
675  # error out if this is an illegal operation for this item type
676  if ($this->ItemNameFieldName == NULL)
677  {
678  throw new Exception("Attempt to search for item names on item type"
679  ."(".$this->ItemClassName.") that has no name field specified.");
680  }
681 
682  # return no results if empty search string passed in
683  if (!strlen(trim($SearchString))) { return array(); }
684 
685  # construct SQL query
686  $DB = new Database();
687  $QueryString = "SELECT ".$this->ItemIdFieldName.",".$this->ItemNameFieldName
688  ." FROM ".$this->ItemTableName." WHERE";
689 
690  # If the search string is valid but shorter than the minimum word length
691  # indexed by the FTS, just do a normal equality test instead of using
692  # the index. Otherwise, FTS away.
693  $MinWordLen = $DB->Query(
694  "SHOW VARIABLES WHERE variable_name='ft_min_word_len'", "Value");
695  if (strlen($SearchString) < $MinWordLen)
696  {
697  $QueryString .= " ".$this->ItemNameFieldName."='".addslashes($SearchString)."'";
698  }
699  else if ($UseBooleanMode)
700  {
701  $SearchString = preg_replace("/[)\(><]+/", "", $SearchString);
702  $Words = preg_split("/[\s]+/", trim($SearchString));
703  $NewSearchString = "";
704  $InQuotedString = FALSE;
705  $SqlVarObj = new MysqlSystemVariables($DB);
706  $StopWordList = $SqlVarObj->GetStopWords();
707  $MinWordLen = $SqlVarObj->Get("ft_min_word_len");
708  foreach ($Words as $Word)
709  {
710  # remove any query-specific terms, punctuation, etc.
711  $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word);
712 
713  # require (boolean AND) certain words
714  if ($InQuotedString == FALSE
715  && !in_array($JustTheWord, $StopWordList)
716  && strlen($JustTheWord) >= $MinWordLen
717  && $Word{0} != "+"
718  && $Word{0} != "-")
719  {
720  $NewSearchString .= "+";
721  }
722 
723  if (preg_match("/^\"/", $Word)) { $InQuotedString = TRUE; }
724  if (preg_match("/\"$/", $Word)) { $InQuotedString = FALSE; }
725  $NewSearchString .= $Word." ";
726  }
727 
728  $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
729  ." AGAINST ('".addslashes(trim($NewSearchString))."'"
730  ." IN BOOLEAN MODE)";
731  }
732  else
733  {
734  $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
735  ." AGAINST ('".addslashes(trim($SearchString))."')";
736  }
737 
738  # add each ID exclusion
739  foreach ($IdExclusions as $IdExclusion)
740  {
741  $QueryString .= " AND ".$this->ItemIdFieldName." != '"
742  .addslashes($IdExclusion)."' ";
743  }
744 
745  # add each value exclusion
746  foreach ($ValueExclusions as $ValueExclusion)
747  {
748  $QueryString .= " AND ".$this->ItemNameFieldName." != '"
749  .addslashes($ValueExclusion)."' ";
750  }
751 
752  # add class-wide condition if set
753  if ($this->SqlCondition)
754  {
755  $QueryString .= " AND ".$this->SqlCondition;
756  }
757 
758  # limit response set
759  $QueryString .= " LIMIT ".intval($NumberOfResults)." OFFSET "
760  .intval($Offset);
761 
762  # perform query and retrieve names and IDs of items found by query
763  $DB->Query($QueryString);
764  $Names = $DB->FetchColumn($this->ItemNameFieldName, $this->ItemIdFieldName);
765 
766  # if boolean mode matching was performed
767  if (strlen($SearchString) >= $MinWordLen && $UseBooleanMode)
768  {
769  foreach ($Words as $Word)
770  {
771  $TgtWord = preg_replace("/[^a-zA-Z]/", "", $Word);
772  if ($Word{0} == "-" && strlen($TgtWord) < $MinWordLen)
773  {
774  $NewNames = array();
775  foreach ($Names as $Id => $Name)
776  {
777  if (! preg_match('/\b'.$TgtWord.'/i', $Name))
778  {
779  $NewNames[$Id] = $Name;
780  }
781  }
782  $Names = $NewNames;
783  }
784  }
785  }
786 
787  # return names to caller
788  return $Names;
789  }
790 
803  function GetCountForItemNames($SearchString, $IncludeVariants = FALSE,
804  $UseBooleanMode = TRUE, $IdExclusions = array(), $ValueExclusions=array())
805  {
806  # return no results if empty search string passed in
807  if (!strlen(trim($SearchString))) { return 0; }
808 
809  # construct SQL query
810  $DB = new Database();
811  $QueryString = "SELECT COUNT(*) as ItemCount FROM "
812  .$this->ItemTableName." WHERE";
813 
814  # If the search string is valid but shorter than the minimum word length
815  # indexed by the FTS, just do a normal equality test instead of using
816  # the index. Otherwise, FTS away.
817  $MinWordLen = $DB->Query(
818  "SHOW VARIABLES WHERE variable_name='ft_min_word_len'", "Value");
819  if (strlen($SearchString) < $MinWordLen)
820  {
821  $QueryString .= " ".$this->ItemNameFieldName."='".addslashes($SearchString)."'";
822  }
823  else if ($UseBooleanMode)
824  {
825  $SearchString = preg_replace("/[)\(><]+/", "", $SearchString);
826  $Words = preg_split("/[\s]+/", trim($SearchString));
827  $NewSearchString = "";
828  $InQuotedString = FALSE;
829  $SqlVarObj = new MysqlSystemVariables($DB);
830  $StopWordList = $SqlVarObj->GetStopWords();
831  $MinWordLen = $SqlVarObj->Get("ft_min_word_len");
832  foreach ($Words as $Word)
833  {
834  # remove any query-specific terms, punctuation, etc.
835  $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word);
836 
837  # require (boolean AND) certain words
838  if ($InQuotedString == FALSE
839  && !in_array($JustTheWord, $StopWordList)
840  && strlen($JustTheWord) >= $MinWordLen
841  && $Word{0} != "+"
842  && $Word{0} != "-")
843  {
844  $NewSearchString .= "+";
845  }
846 
847  if (preg_match("/^\"/", $Word)) { $InQuotedString = TRUE; }
848  if (preg_match("/\"$/", $Word)) { $InQuotedString = FALSE; }
849  $NewSearchString .= $Word." ";
850  }
851 
852  $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
853  ." AGAINST ('".addslashes(trim($NewSearchString))."'"
854  ." IN BOOLEAN MODE)";
855  }
856  else
857  {
858  $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
859  ." AGAINST ('".addslashes(trim($SearchString))."')";
860  }
861 
862  # add each ID exclusion
863  foreach ($IdExclusions as $IdExclusion)
864  {
865  $QueryString .= " AND ".$this->ItemIdFieldName." != '"
866  .addslashes($IdExclusion)."' ";
867  }
868 
869  # add each value exclusion
870  foreach ($ValueExclusions as $ValueExclusion)
871  {
872  $QueryString .= " AND ".$this->ItemNameFieldName." != '"
873  .addslashes($ValueExclusion)."' ";
874  }
875 
876  # add class-wide condition if set
877  if ($this->SqlCondition)
878  {
879  $QueryString .= " AND ".$this->SqlCondition;
880  }
881 
882  # perform query and retrieve names and IDs of items found by query
883  $DB->Query($QueryString);
884  return intval($DB->FetchField("ItemCount"));
885  }
886 
895  function AddItem($ItemName, $AdditionalValues = NULL)
896  {
897  # build initial database query for adding item
898  $Query = "INSERT INTO ".$this->ItemTableName." SET `"
899  .$this->ItemNameFieldName."` = '".addslashes($ItemName)."'";
900 
901  # add any additional values to query
902  if ($AdditionalValues)
903  {
904  foreach ($AdditionalValues as $FieldName => $Value)
905  {
906  $Query .= ", `".$FieldName."` = '".addslashes($Value)."'";
907  }
908  }
909 
910  # add item to database
911  $this->DB->Query($Query);
912 
913  # retrieve ID of new item
914  $Id = $this->DB->LastInsertId();
915 
916  # return ID to caller
917  return $Id;
918  }
919 
924  function DeleteItem($ItemId)
925  {
926  # delete item from database
927  $this->DB->Query("DELETE FROM ".$this->ItemTableName
928  ." WHERE ".$this->ItemIdFieldName." = '".addslashes($ItemId)."'");
929  }
930 
931 
932  # ---- order operations --------------------------------------------------
933 
940  function SetOrderOpsCondition($Condition)
941  {
942  # condition is non-negative IDs (non-temp items) plus supplied condition
943  $NewCondition = $this->ItemIdFieldName." >= 0"
944  .($Condition ? " AND ".$Condition : "")
945  .($this->SqlCondition ? " AND ".$this->SqlCondition : "");
946  $this->OrderList->SqlCondition($NewCondition);
947  }
948 
956  function InsertBefore($TargetItem, $NewItem)
957  {
958  # error out if ordering operations are not allowed for this item type
959  if (!$this->OrderOpsAllowed)
960  {
961  throw new Exception("Attempt to perform order operation on item"
962  ." type (".$this->ItemClassName.") that does not support"
963  ." ordering.");
964  }
965 
966  # insert/move item
967  $this->OrderList->InsertBefore($TargetItem, $NewItem);
968  }
969 
977  function InsertAfter($TargetItem, $NewItem)
978  {
979  # error out if ordering operations are not allowed for this item type
980  if (!$this->OrderOpsAllowed)
981  {
982  throw new Exception("Attempt to perform order operation on item"
983  ." type (".$this->ItemClassName.") that does not support"
984  ." ordering.");
985  }
986 
987  # insert/move item
988  $this->OrderList->InsertAfter($TargetItem, $NewItem);
989  }
990 
996  function Prepend($Item)
997  {
998  # error out if ordering operations are not allowed for this item type
999  if (!$this->OrderOpsAllowed)
1000  {
1001  throw new Exception("Attempt to perform order operation on item"
1002  ." type (".$this->ItemClassName.") that does not support"
1003  ." ordering.");
1004  }
1005 
1006  # prepend item
1007  $this->OrderList->Prepend($Item);
1008  }
1009 
1015  function Append($Item)
1016  {
1017  # error out if ordering operations are not allowed for this item type
1018  if (!$this->OrderOpsAllowed)
1019  {
1020  throw new Exception("Attempt to perform order operation on item"
1021  ." type (".$this->ItemClassName.") that does not support"
1022  ." ordering.");
1023  }
1024 
1025  # add/move item
1026  $this->OrderList->Append($Item);
1027  }
1028 
1034  {
1035  # error out if ordering operations are not allowed for this item type
1036  if (!$this->OrderOpsAllowed)
1037  {
1038  throw new Exception("Attempt to perform order operation on item"
1039  ." type (".$this->ItemClassName.") that does not support"
1040  ." ordering.");
1041  }
1042 
1043  # retrieve list of IDs
1044  return $this->OrderList->GetIds();
1045  }
1046 
1053  function RemoveItemFromOrder($ItemId)
1054  {
1055  # error out if ordering operations are not allowed for this item type
1056  if (!$this->OrderOpsAllowed)
1057  {
1058  throw new Exception("Attempt to perform order operation on item"
1059  ." type (".$this->ItemClassName.") that does not support"
1060  ." ordering.");
1061  }
1062 
1063  # remove item
1064  $this->OrderList->Remove($ItemId);
1065  }
1066 
1067 
1068  # ---- PRIVATE INTERFACE -------------------------------------------------
1069 
1070  protected $DB;
1071 
1072  private $ItemClassName;
1073  private $ItemTableName;
1074  private $ItemIdFieldName;
1075  private $ItemNameFieldName;
1076  private $OrderOpsAllowed;
1077  private $OrderList;
1078  private $SqlCondition;
1079 }
GetHighestItemId($IgnoreSqlCondition=FALSE)
Retrieve highest item ID in use.
GetLastTempItemId()
Retrieve most recent temp item ID for currently-logged-in user.
GetItemIdsInOrder()
Retrieve list of item IDs in order.
RemoveItemFromOrder($ItemId)
Remove item from existing order.
Prepend($Item)
Add item to beginning of order.
GetItemClassName()
Get class name of items manipulated by factory.
Definition: ItemFactory.php:65
ClearCurrentEditedItemId()
Clear currently edited item ID.
GetItemIdByName($Name, $IgnoreCase=FALSE)
Retrieve item ID by name.
SetCurrentEditedItemId($NewId)
Set ID of currently edited item.
SQL database abstraction object with smart query caching.
DeleteItem($ItemId)
Delete item.
GetItemsAsOptionList($OptionListName, $SelectedItemId=NULL, $SqlCondition=NULL, $DisplaySize=1, $SubmitOnChange=FALSE)
Retrieve items of specified type as HTML option list with item names as labels and item IDs as value ...
GetItemNames($SqlCondition=NULL)
Retrieve item names.
GetItemCount($Condition=NULL, $IncludeTempItems=FALSE)
Get count of items.
AddItem($ItemName, $AdditionalValues=NULL)
Add new item.
SearchForItemNames($SearchString, $NumberOfResults=100, $IncludeVariants=FALSE, $UseBooleanMode=TRUE, $Offset=0, $IdExclusions=array(), $ValueExclusions=array())
Retrieve items with names matching search string.
GetCurrentEditedItemId()
Get ID of currently edited item.
Definition: ItemFactory.php:74
GetItem($ItemId)
Retrieve item by item ID.
GetItemByName($Name, $IgnoreCase=FALSE)
Retrieve item by name.
GetLatestModificationDate($Condition=NULL)
Get newest modification date (based on values in &quot;DateLastModified&quot; column in database table)...
GetCountForItemNames($SearchString, $IncludeVariants=FALSE, $UseBooleanMode=TRUE, $IdExclusions=array(), $ValueExclusions=array())
Retrieve count of items with names matching search string.
CleanOutStaleTempItems($MinutesUntilStale=10080)
Clear out (call the Delete() method) for any temp items more than specified number of minutes old...
ItemExists($ItemId, $IgnoreSqlCondition=FALSE)
Check that item exists with specified ID.
Class that allows permits easier access to MySQL system variables.
InsertBefore($TargetItem, $NewItem)
Insert item into order before specified item.
InsertAfter($TargetItem, $NewItem)
Insert item into order after specified item.
PHP
Definition: OAIClient.php:39
Persistent doubly-linked-list data structure, with its data stored in a specified database table...
GetItems($SqlCondition=NULL)
Retrieve items.
GetNextTempItemId()
Return next available temporary item ID.
Append($Item)
Add item to end of order.
SetOrderOpsCondition($Condition)
Set SQL condition (added to WHERE clause) used to select items for ordering operations.
Common factory class for item manipulation.
Definition: ItemFactory.php:17
GetItemIds($Condition=NULL, $IncludeTempItems=FALSE, $SortField=NULL, $SortAscending=TRUE)
Return array of item IDs.
NameIsInUse($Name, $IgnoreCase=FALSE)
Check whether item name is currently in use.
ClearCurrentEditedItem()
Delete currently edited item and clear currently edited item ID.
ItemFactory($ItemClassName, $ItemTableName, $ItemIdFieldName, $ItemNameFieldName=NULL, $OrderOpsAllowed=FALSE, $SqlCondition=NULL)
Class constructor.
Definition: ItemFactory.php:36
GetNextItemId()
Retrieve next available (non-temp) item ID.