3 # FILE: ItemFactory.php
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/
19 # ---- PUBLIC INTERFACE --------------------------------------------------
36 function ItemFactory($ItemClassName, $ItemTableName, $ItemIdFieldName,
37 $ItemNameFieldName = NULL, $OrderOpsAllowed = FALSE, $SqlCondition = NULL)
39 # save item access names
40 $this->ItemClassName = $ItemClassName;
41 $this->ItemTableName = $ItemTableName;
42 $this->ItemIdFieldName = $ItemIdFieldName;
43 $this->ItemNameFieldName = $ItemNameFieldName;
45 # save flag indicating whether item type allows ordering operations
46 $this->OrderOpsAllowed = $OrderOpsAllowed;
50 $ItemTableName, $ItemIdFieldName);
54 # save database operation conditional
55 $this->SqlCondition = $SqlCondition;
57 # grab our own database handle
67 return $this->ItemClassName;
76 # if ID available in session variable
77 $SessionIndex = $this->ItemClassName.
"EditedIds";
78 if (isset($_SESSION[$SessionIndex]))
80 # look up value in session variable
81 $ItemId = $_SESSION[$SessionIndex][0];
85 # attempt to look up last temp item ID
88 # store it in session variable
89 $_SESSION[$SessionIndex] = array($ItemId);
92 # return ID (if any) to caller
102 # if edited ID array already stored for session
103 $SessionIndex = $this->ItemClassName.
"EditedIds";
104 if (isset($_SESSION[$SessionIndex]))
106 # prepend new value to array
107 array_unshift($_SESSION[$SessionIndex], $NewId);
111 # start with fresh array
112 $_SESSION[$SessionIndex] = array($NewId);
121 # if edited item IDs available in a session variable
122 $SessionIndex = $this->ItemClassName.
"EditedIds";
123 if (isset($_SESSION[$SessionIndex]))
125 # remove current item from edited item ID array
126 array_shift($_SESSION[$SessionIndex]);
128 # if no further edited items
129 if (count($_SESSION[$SessionIndex]) < 1)
131 # destroy session variable
132 unset($_SESSION[$SessionIndex]);
145 # if current edited item is temp item
147 if ($CurrentEditedItemId < 0)
149 # delete temp item from DB
150 if (method_exists($this->ItemClassName,
"Delete"))
152 $Item =
new $this->ItemClassName($CurrentEditedItemId);
157 $this->DB->Query(
"DELETE FROM ".$this->ItemTableName
158 .
" WHERE ".$this->ItemIdFieldName.
" = ".$CurrentEditedItemId);
162 # clear current edited item ID
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);
185 foreach ($ItemIds as $ItemId)
187 $Item =
new $this->ItemClassName($ItemId);
191 # report number of items deleted to caller
192 return count($ItemIds);
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"
211 $this->ItemIdFieldName);
213 # return item to caller (or NULL if none found)
224 # if no highest item ID found
226 if ($HighestItemId <= 0)
228 # start with item ID 1
233 # else use next ID available after highest
234 $ItemId = $HighestItemId + 1;
237 # return next ID to caller
250 # use class-wide condition if set
251 $ConditionString = ($this->SqlCondition && !$IgnoreSqlCondition)
252 ?
" WHERE ".$this->SqlCondition :
"";
254 # return highest item ID to caller
255 return $this->DB->Query(
"SELECT ".$this->ItemIdFieldName
256 .
" FROM ".$this->ItemTableName
258 .
" ORDER BY ".$this->ItemIdFieldName
260 $this->ItemIdFieldName);
269 $LowestItemId = $this->DB->Query(
"SELECT ".$this->ItemIdFieldName
270 .
" FROM ".$this->ItemTableName
271 .
" ORDER BY ".$this->ItemIdFieldName
273 $this->ItemIdFieldName);
274 if ($LowestItemId > 0)
280 $ItemId = $LowestItemId - 1;
295 # use condition if supplied
296 $ConditionString = ($Condition != NULL) ?
" WHERE ".$Condition :
"";
298 # if temp items are to be excluded
299 if (!$IncludeTempItems)
301 # if a condition was previously set
302 if (strlen($ConditionString))
304 # add in condition to exclude temp items
305 $ConditionString .=
" AND (".$this->ItemIdFieldName.
" >= 0)";
309 # use condition to exclude temp items
310 $ConditionString =
" WHERE ".$this->ItemIdFieldName.
" >= 0";
314 # add class-wide condition if set
315 if ($this->SqlCondition)
317 if (strlen($ConditionString))
319 $ConditionString .=
" AND ".$this->SqlCondition;
323 $ConditionString =
" WHERE ".$this->SqlCondition;
327 # retrieve item count
328 $Count = $this->DB->Query(
"SELECT COUNT(*) AS RecordCount"
329 .
" FROM ".$this->ItemTableName
333 # return count to caller
350 function GetItemIds($Condition = NULL, $IncludeTempItems = FALSE,
351 $SortField = NULL, $SortAscending = TRUE)
353 # if temp items are supposed to be included
354 if ($IncludeTempItems)
356 # condition is only as supplied
357 $ConditionString = ($Condition == NULL) ?
"" :
" WHERE ".$Condition;
361 # condition is non-negative IDs plus supplied condition
362 $ConditionString =
" WHERE ".$this->ItemIdFieldName.
" >= 0"
363 .(($Condition == NULL) ?
"" :
" AND ".$Condition);
366 # add class-wide condition if set
367 if ($this->SqlCondition)
369 if (strlen($ConditionString))
371 $ConditionString .=
" AND ".$this->SqlCondition;
375 $ConditionString =
" WHERE ".$this->SqlCondition;
379 # add sorting if specified
380 if ($SortField !== NULL)
382 $ConditionString .=
" ORDER BY `".addslashes($SortField).
"` "
383 .($SortAscending ?
"ASC" :
"DESC");
387 $this->DB->Query(
"SELECT ".$this->ItemIdFieldName
388 .
" FROM ".$this->ItemTableName
390 $ItemIds = $this->DB->FetchColumn($this->ItemIdFieldName);
392 # return IDs to caller
405 # set up SQL condition if supplied
406 $ConditionString = ($Condition == NULL) ?
"" :
" WHERE ".$Condition;
408 # add class-wide condition if set
409 if ($this->SqlCondition)
411 if (strlen($ConditionString))
413 $ConditionString .=
" AND ".$this->SqlCondition;
417 $ConditionString =
" WHERE ".$this->SqlCondition;
421 # return modification date for item most recently changed
422 return $this->DB->Query(
"SELECT MAX(DateLastModified) AS LastChangeDate"
423 .
" FROM ".$this->ItemTableName.$ConditionString,
435 return new $this->ItemClassName($ItemId);
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;
469 if ($ItemId === NULL)
471 # report error to caller
476 # load object and return to caller
477 return $this->
GetItem($ItemId);
490 # error out if this is an illegal operation for this item type
491 if ($this->ItemNameFieldName == NULL)
493 throw new Exception(
"Attempt to get item ID by name on item type"
494 .
"(".$this->ItemClassName.
") that has no name field specified.");
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
508 $this->ItemIdFieldName);
510 # return ID or error indicator to caller
511 return ($ItemId === FALSE) ? NULL : $ItemId;
522 # error out if this is an illegal operation for this item type
523 if ($this->ItemNameFieldName == NULL)
525 throw new Exception(
"Attempt to get array of item names"
526 .
" on item type (".$this->ItemClassName.
") that has no"
527 .
" name field specified.");
530 # query database for item names
534 $Condition =
"WHERE ".$SqlCondition;
536 if ($this->SqlCondition)
538 if (strlen($Condition))
540 $Condition .=
" AND ".$this->SqlCondition;
544 $Condition =
" WHERE ".$this->SqlCondition;
547 $this->DB->Query(
"SELECT ".$this->ItemIdFieldName
548 .
", ".$this->ItemNameFieldName
549 .
" FROM ".$this->ItemTableName.
" "
551 .
" ORDER BY ".$this->ItemNameFieldName);
552 $Names = $this->DB->FetchColumn(
553 $this->ItemNameFieldName, $this->ItemIdFieldName);
555 # return item names to caller
569 foreach ($Ids as $Id)
592 $SqlCondition = NULL, $DisplaySize = 1, $SubmitOnChange = FALSE)
594 # retrieve requested fields
597 # if multiple selections are allowed
598 if ($DisplaySize > 1)
600 # begin multi-selection HTML option list
601 $Html =
"<select name=\"".htmlspecialchars($OptionListName).
"[]\""
602 .($SubmitOnChange ?
" onChange=\"submit()\"" :
"")
603 .
" multiple=\"multiple\" size=\"".$DisplaySize.
"\">\n";
607 # begin single-selection HTML option list
608 $Html =
"<select name=\"".htmlspecialchars($OptionListName).
"\""
609 .($SubmitOnChange ?
" onChange=\"submit()\"" :
"")
611 $Html .=
"<option value=\"-1\">--</option>\n";
614 # for each metadata field
615 foreach ($ItemNames as $Id => $Name)
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)))
622 $Html .=
" selected";
624 $Html .=
">".htmlspecialchars($Name).
"</option>\n";
627 # end HTML option list
628 $Html .=
"</select>\n";
630 # return constructed HTML to caller
642 $Condition = $IgnoreCase
643 ?
"LOWER(".$this->ItemNameFieldName.
")"
644 .
" = '".addslashes(strtolower($Name)).
"'"
645 : $this->ItemNameFieldName.
" = '".addslashes($Name).
"'";
646 if ($this->SqlCondition)
648 $Condition .=
" AND ".$this->SqlCondition;
650 $NameCount = $this->DB->Query(
"SELECT COUNT(*) AS RecordCount FROM "
651 .$this->ItemTableName.
" WHERE ".$Condition,
"RecordCount");
652 return ($NameCount > 0) ? TRUE : FALSE;
672 $IncludeVariants = FALSE, $UseBooleanMode = TRUE, $Offset=0,
673 $IdExclusions = array(), $ValueExclusions=array())
675 # error out if this is an illegal operation for this item type
676 if ($this->ItemNameFieldName == NULL)
678 throw new Exception(
"Attempt to search for item names on item type"
679 .
"(".$this->ItemClassName.
") that has no name field specified.");
682 # return no results if empty search string passed in
683 if (!strlen(trim($SearchString))) {
return array(); }
685 # construct SQL query
687 $QueryString =
"SELECT ".$this->ItemIdFieldName.
",".$this->ItemNameFieldName
688 .
" FROM ".$this->ItemTableName.
" WHERE";
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)
697 $QueryString .=
" ".$this->ItemNameFieldName.
"='".addslashes($SearchString).
"'";
699 else if ($UseBooleanMode)
701 $SearchString = preg_replace(
"/[)\(><]+/",
"", $SearchString);
702 $Words = preg_split(
"/[\s]+/", trim($SearchString));
703 $NewSearchString =
"";
704 $InQuotedString = FALSE;
706 $StopWordList = $SqlVarObj->GetStopWords();
707 $MinWordLen = $SqlVarObj->Get(
"ft_min_word_len");
708 foreach ($Words as $Word)
710 # remove any query-specific terms, punctuation, etc.
711 $JustTheWord = preg_replace(
"/[^a-zA-Z-]/",
"", $Word);
713 # require (boolean AND) certain words
714 if ($InQuotedString == FALSE
715 && !in_array($JustTheWord, $StopWordList)
716 && strlen($JustTheWord) >= $MinWordLen
720 $NewSearchString .=
"+";
723 if (preg_match(
"/^\"/", $Word)) { $InQuotedString = TRUE; }
724 if (preg_match(
"/\"$/", $Word)) { $InQuotedString = FALSE; }
725 $NewSearchString .= $Word.
" ";
728 $QueryString .=
" MATCH (".$this->ItemNameFieldName.
")"
729 .
" AGAINST ('".addslashes(trim($NewSearchString)).
"'"
730 .
" IN BOOLEAN MODE)";
734 $QueryString .=
" MATCH (".$this->ItemNameFieldName.
")"
735 .
" AGAINST ('".addslashes(trim($SearchString)).
"')";
738 # add each ID exclusion
739 foreach ($IdExclusions as $IdExclusion)
741 $QueryString .=
" AND ".$this->ItemIdFieldName.
" != '"
742 .addslashes($IdExclusion).
"' ";
745 # add each value exclusion
746 foreach ($ValueExclusions as $ValueExclusion)
748 $QueryString .=
" AND ".$this->ItemNameFieldName.
" != '"
749 .addslashes($ValueExclusion).
"' ";
752 # add class-wide condition if set
753 if ($this->SqlCondition)
755 $QueryString .=
" AND ".$this->SqlCondition;
759 $QueryString .=
" LIMIT ".intval($NumberOfResults).
" OFFSET "
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);
766 # if boolean mode matching was performed
767 if (strlen($SearchString) >= $MinWordLen && $UseBooleanMode)
769 foreach ($Words as $Word)
771 $TgtWord = preg_replace(
"/[^a-zA-Z]/",
"", $Word);
772 if ($Word{0} ==
"-" && strlen($TgtWord) < $MinWordLen)
775 foreach ($Names as $Id => $Name)
777 if (! preg_match(
'/\b'.$TgtWord.
'/i', $Name))
779 $NewNames[$Id] = $Name;
787 # return names to caller
804 $UseBooleanMode = TRUE, $IdExclusions = array(), $ValueExclusions=array())
806 # return no results if empty search string passed in
807 if (!strlen(trim($SearchString))) {
return 0; }
809 # construct SQL query
811 $QueryString =
"SELECT COUNT(*) as ItemCount FROM "
812 .$this->ItemTableName.
" WHERE";
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)
821 $QueryString .=
" ".$this->ItemNameFieldName.
"='".addslashes($SearchString).
"'";
823 else if ($UseBooleanMode)
825 $SearchString = preg_replace(
"/[)\(><]+/",
"", $SearchString);
826 $Words = preg_split(
"/[\s]+/", trim($SearchString));
827 $NewSearchString =
"";
828 $InQuotedString = FALSE;
830 $StopWordList = $SqlVarObj->GetStopWords();
831 $MinWordLen = $SqlVarObj->Get(
"ft_min_word_len");
832 foreach ($Words as $Word)
834 # remove any query-specific terms, punctuation, etc.
835 $JustTheWord = preg_replace(
"/[^a-zA-Z-]/",
"", $Word);
837 # require (boolean AND) certain words
838 if ($InQuotedString == FALSE
839 && !in_array($JustTheWord, $StopWordList)
840 && strlen($JustTheWord) >= $MinWordLen
844 $NewSearchString .=
"+";
847 if (preg_match(
"/^\"/", $Word)) { $InQuotedString = TRUE; }
848 if (preg_match(
"/\"$/", $Word)) { $InQuotedString = FALSE; }
849 $NewSearchString .= $Word.
" ";
852 $QueryString .=
" MATCH (".$this->ItemNameFieldName.
")"
853 .
" AGAINST ('".addslashes(trim($NewSearchString)).
"'"
854 .
" IN BOOLEAN MODE)";
858 $QueryString .=
" MATCH (".$this->ItemNameFieldName.
")"
859 .
" AGAINST ('".addslashes(trim($SearchString)).
"')";
862 # add each ID exclusion
863 foreach ($IdExclusions as $IdExclusion)
865 $QueryString .=
" AND ".$this->ItemIdFieldName.
" != '"
866 .addslashes($IdExclusion).
"' ";
869 # add each value exclusion
870 foreach ($ValueExclusions as $ValueExclusion)
872 $QueryString .=
" AND ".$this->ItemNameFieldName.
" != '"
873 .addslashes($ValueExclusion).
"' ";
876 # add class-wide condition if set
877 if ($this->SqlCondition)
879 $QueryString .=
" AND ".$this->SqlCondition;
882 # perform query and retrieve names and IDs of items found by query
883 $DB->Query($QueryString);
884 return intval(
$DB->FetchField(
"ItemCount"));
895 function AddItem($ItemName, $AdditionalValues = NULL)
897 # build initial database query for adding item
898 $Query =
"INSERT INTO ".$this->ItemTableName.
" SET `"
899 .$this->ItemNameFieldName.
"` = '".addslashes($ItemName).
"'";
901 # add any additional values to query
902 if ($AdditionalValues)
904 foreach ($AdditionalValues as $FieldName => $Value)
906 $Query .=
", `".$FieldName.
"` = '".addslashes($Value).
"'";
910 # add item to database
911 $this->DB->Query($Query);
913 # retrieve ID of new item
914 $Id = $this->DB->LastInsertId();
916 # return ID to caller
926 # delete item from database
927 $this->DB->Query(
"DELETE FROM ".$this->ItemTableName
928 .
" WHERE ".$this->ItemIdFieldName.
" = '".addslashes($ItemId).
"'");
932 # ---- order operations --------------------------------------------------
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);
958 # error out if ordering operations are not allowed for this item type
959 if (!$this->OrderOpsAllowed)
961 throw new Exception(
"Attempt to perform order operation on item"
962 .
" type (".$this->ItemClassName.
") that does not support"
967 $this->OrderList->InsertBefore($TargetItem, $NewItem);
979 # error out if ordering operations are not allowed for this item type
980 if (!$this->OrderOpsAllowed)
982 throw new Exception(
"Attempt to perform order operation on item"
983 .
" type (".$this->ItemClassName.
") that does not support"
988 $this->OrderList->InsertAfter($TargetItem, $NewItem);
998 # error out if ordering operations are not allowed for this item type
999 if (!$this->OrderOpsAllowed)
1001 throw new Exception(
"Attempt to perform order operation on item"
1002 .
" type (".$this->ItemClassName.
") that does not support"
1007 $this->OrderList->Prepend($Item);
1017 # error out if ordering operations are not allowed for this item type
1018 if (!$this->OrderOpsAllowed)
1020 throw new Exception(
"Attempt to perform order operation on item"
1021 .
" type (".$this->ItemClassName.
") that does not support"
1026 $this->OrderList->Append($Item);
1035 # error out if ordering operations are not allowed for this item type
1036 if (!$this->OrderOpsAllowed)
1038 throw new Exception(
"Attempt to perform order operation on item"
1039 .
" type (".$this->ItemClassName.
") that does not support"
1043 # retrieve list of IDs
1044 return $this->OrderList->GetIds();
1055 # error out if ordering operations are not allowed for this item type
1056 if (!$this->OrderOpsAllowed)
1058 throw new Exception(
"Attempt to perform order operation on item"
1059 .
" type (".$this->ItemClassName.
") that does not support"
1064 $this->OrderList->Remove($ItemId);
1068 # ---- PRIVATE INTERFACE -------------------------------------------------
1072 private $ItemClassName;
1073 private $ItemTableName;
1074 private $ItemIdFieldName;
1075 private $ItemNameFieldName;
1076 private $OrderOpsAllowed;
1078 private $SqlCondition;
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.
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.
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 "DateLastModified" 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.
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.
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.
GetNextItemId()
Retrieve next available (non-temp) item ID.