ItemFactory.php

Go to the documentation of this file.
00001 <?PHP
00002 
00003 #
00004 #   FILE:  ItemFactory.php
00005 #
00006 #   NOTES:
00007 #       - for a derived class to use the temp methods the item record in the
00008 #             database must include "DateLastModified" and "LastModifiedById"
00009 #             fields, and the item object must include a "Delete()" method
00010 #
00011 #   Copyright 2007-2010 Edward Almasy and Internet Scout
00012 #   http://scout.wisc.edu
00013 #
00014 
00015 class ItemFactory {
00016 
00017     # ---- PUBLIC INTERFACE --------------------------------------------------
00018 
00019     # object constructor
00020     function ItemFactory($ItemClassName, $ItemTableName, $ItemIdFieldName,
00021             $ItemNameFieldName = NULL, $FieldId = NULL, $OrderOpsAllowed = FALSE)
00022     {
00023         # save item access names
00024         $this->ItemClassName = $ItemClassName;
00025         $this->ItemTableName = $ItemTableName;
00026         $this->ItemIdFieldName = $ItemIdFieldName;
00027         $this->ItemNameFieldName = $ItemNameFieldName;
00028 
00029         # save field ID (if specified)
00030         if ($FieldId !== NULL) {  $this->FieldId = intval($FieldId);  }
00031 
00032         # save flag indicating whether item type allows ordering operations
00033         $this->OrderOpsAllowed = $OrderOpsAllowed;
00034         if ($OrderOpsAllowed)
00035         {
00036             $this->OrderList = new DoublyLinkedItemList(
00037                     $ItemTableName, $ItemIdFieldName);
00038             $this->SetOrderOpsCondition(NULL);
00039         }
00040 
00041         # grab our own database handle
00042         $this->DB = new Database();
00043 
00044         # assume everything will be okay
00045         $this->ErrorStatus = 0;
00046     }
00047 
00048     # return current error status
00049     function Status() {  return $this->ErrorStatus;  }
00050 
00051     # get ID of currently edited item
00052     function GetCurrentEditedItemId()
00053     {
00054         # if ID available in session variable
00055         global $Session;
00056         if ($EditedIds = $Session->Get($this->ItemClassName."EditedIds"))
00057         {
00058             # look up value in session variable
00059             $ItemId = $EditedIds[0];
00060         }
00061         else
00062         {
00063             # attempt to look up last temp item ID
00064             $ItemId = $this->GetLastTempItemId();
00065 
00066             # store it in session variable
00067             $EditedIds = array($ItemId);
00068             $Session->RegisterVariable($this->ItemClassName."EditedIds", $EditedIds);
00069         }
00070 
00071         # return ID (if any) to caller
00072         return $ItemId;
00073     }
00074 
00075     # set ID of currently edited item
00076     function SetCurrentEditedItemId($NewId)
00077     {
00078         # if edited ID array already stored for session
00079         global $Session;
00080         if ($EditedIds = $Session->Get($this->ItemClassName."EditedIds"))
00081         {
00082             # prepend new value to array
00083             array_unshift($EditedIds, $NewId);
00084         }
00085         else
00086         {
00087             # start with fresh array
00088             $EditedIds = array($NewId);
00089         }
00090 
00091         # save in session variable
00092         $Session->RegisterVariable($this->ItemClassName."EditedIds", $EditedIds);
00093     }
00094 
00095     # clear currently edited item ID
00096     function ClearCurrentEditedItemId()
00097     {
00098         # if edited item IDs available in a session variable
00099         global $Session;
00100         $SessionVarName = $this->ItemClassName."EditedIds";
00101         if ($EditedIds = $Session->Get($SessionVarName))
00102         {
00103             # remove current item from edited item ID array
00104             array_shift($EditedIds);
00105 
00106             # if no further edited items
00107             if (count($EditedIds) < 1)
00108             {
00109                 # destroy session variable
00110                 $Session->UnregisterVariable($SessionVarName);
00111             }
00112             else
00113             {
00114                 # save new shorter edited item ID array to session variable
00115                 $Session->RegisterVariable($SessionVarName, $EditedIds);
00116             }
00117         }
00118     }
00119 
00120     # clear currently edited item ID and item
00121     function ClearCurrentEditedItem()
00122     {
00123         # if current edited item is temp item
00124         $CurrentEditedItemId = $this->GetCurrentEditedItemId();
00125         if ($CurrentEditedItemId < 0)
00126         {
00127             # delete temp item from DB
00128             $this->DB->Query("DELETE FROM ".$this->ItemTableName
00129                              ." WHERE ".$this->ItemIdFieldName." = ".$CurrentEditedItemId);
00130         }
00131 
00132         # clear current edited item ID
00133         $this->ClearCurrentEditedItemId();
00134     }
00135 
00143     function CleanOutStaleTempItems($MinutesUntilStale = 10080)
00144     {
00145         # load array of stale items
00146         $MinutesUntilStale = max($MinutesUntilStale, 1);
00147         $this->DB->Query("SELECT ".$this->ItemIdFieldName." FROM ".$this->ItemTableName
00148                    ." WHERE ".$this->ItemIdFieldName." < 0"
00149                    ." AND DateLastModified < DATE_SUB(NOW(), "
00150                             ." INTERVAL ".intval($MinutesUntilStale)." MINUTE)");
00151         $ItemIds = $this->DB->FetchColumn($this->ItemIdFieldName);
00152 
00153         # delete stale items
00154         foreach ($ItemIds as $ItemId)
00155         {
00156             $Item = new $this->ItemClassName($ItemId);
00157             $Item->Delete();
00158         }
00159 
00160         # report number of items deleted to caller
00161         return count($ItemIds);
00162     }
00163 
00164     # retrieve most recent temp item ID based on user ID
00165     # (returns NULL if no temp item found for that user ID)
00166     function GetLastTempItemId()
00167     {
00168         # retrieve ID of most recently modified temp item for this user
00169         global $User;
00170         $ItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName." FROM ".$this->ItemTableName
00171                                  ." WHERE LastModifiedById = '".$User->Get("UserId")."'"
00172                                  ." AND ".$this->ItemIdFieldName." < 0"
00173                                  ." ORDER BY ".$this->ItemIdFieldName." ASC"
00174                                  ." LIMIT 1",
00175                                  $this->ItemIdFieldName);
00176 
00177         # return item to caller (or NULL if none found)
00178         return $ItemId;
00179     }
00180 
00181     # return next item ID
00182     function GetNextItemId()
00183     {
00184         # if no highest item ID found
00185         $HighestItemId = $this->GetHighestItemId();
00186         if ($HighestItemId <= 0)
00187         {
00188             # start with item ID 1
00189             $ItemId = 1;
00190         }
00191         else
00192         {
00193             # else use next ID available after highest
00194             $ItemId = $HighestItemId + 1;
00195         }
00196 
00197         # return next ID to caller
00198         return $ItemId;
00199     }
00200 
00201     # return highest item ID ($Condition should not include "WHERE")
00202     function GetHighestItemId($Condition = NULL, $IncludeTempItems = FALSE)
00203     {
00204         # if temp items are supposed to be included
00205         if ($IncludeTempItems)
00206         {
00207             # condition is only as supplied
00208             $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
00209         }
00210         else
00211         {
00212             # condition is non-negative IDs plus supplied condition
00213             $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0"
00214                        .(($Condition == NULL) ? "" : " AND ".$Condition);
00215         }
00216 
00217         # return highest item ID to caller
00218         return $this->DB->Query("SELECT ".$this->ItemIdFieldName
00219                                     ." FROM ".$this->ItemTableName
00220                                     .$ConditionString
00221                                     ." ORDER BY ".$this->ItemIdFieldName
00222                                     ." DESC LIMIT 1",
00223                                 $this->ItemIdFieldName);
00224     }
00225 
00226     # return next temp item ID
00227     function GetNextTempItemId()
00228     {
00229         $LowestItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName
00230                                          ." FROM ".$this->ItemTableName
00231                                          ." ORDER BY ".$this->ItemIdFieldName
00232                                          ." ASC LIMIT 1",
00233                                          $this->ItemIdFieldName);
00234         if ($LowestItemId > 0)
00235         {
00236             $ItemId = -1;
00237         }
00238         else
00239         {
00240             $ItemId = $LowestItemId - 1;
00241         }
00242         return $ItemId;
00243     }
00244 
00245     # return count of items
00246     function GetItemCount($Condition = NULL, $IncludeTempItems = FALSE)
00247     {
00248         # if condition was supplied
00249         if ($Condition != NULL)
00250         {
00251             # use condition
00252             $ConditionString = " WHERE ".$Condition;
00253         }
00254         else
00255         {
00256             # if field ID is available
00257             if (isset($this->FieldId))
00258             {
00259                 # use condition for matching field ID
00260                 $ConditionString = " WHERE FieldId = ".intval($this->FieldId);
00261             }
00262             else
00263             {
00264                 # use no condition
00265                 $ConditionString = "";
00266             }
00267         }
00268 
00269         # if temp items are to be excluded
00270         if (!$IncludeTempItems)
00271         {
00272             # if a condition was previously set
00273             if (strlen($ConditionString))
00274             {
00275                 # add in condition to exclude temp items
00276                 $ConditionString .= " AND (".$this->ItemIdFieldName." >= 0)";
00277             }
00278             else
00279             {
00280                 # use condition to exclude temp items
00281                 $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0";
00282             }
00283         }
00284 
00285         # retrieve item count
00286         $Count = $this->DB->Query("SELECT COUNT(*) AS RecordCount"
00287                                       ." FROM ".$this->ItemTableName
00288                                       .$ConditionString,
00289                                   "RecordCount");
00290 
00291         # return count to caller
00292         return $Count;
00293     }
00294 
00295     # return array of item IDs ($Condition should not include "WHERE")
00296     function GetItemIds($Condition = NULL, $IncludeTempItems = FALSE)
00297     {
00298         # if temp items are supposed to be included
00299         if ($IncludeTempItems)
00300         {
00301             # condition is only as supplied
00302             $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
00303         }
00304         else
00305         {
00306             # condition is non-negative IDs plus supplied condition
00307             $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0"
00308                        .(($Condition == NULL) ? "" : " AND ".$Condition);
00309         }
00310 
00311         # get item IDs
00312         $this->DB->Query("SELECT ".$this->ItemIdFieldName
00313                                       ." FROM ".$this->ItemTableName
00314                                       .$ConditionString);
00315         $ItemIds = $this->DB->FetchColumn($this->ItemIdFieldName);
00316 
00317         # return IDs to caller
00318         return $ItemIds;
00319     }
00320 
00321     # return latest modification date ($Condition should not include "WHERE")
00322     function GetLatestModificationDate($Condition = NULL)
00323     {
00324         # return modification date for item most recently changed
00325         $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
00326         return $this->DB->Query("SELECT MAX(DateLastModified) AS LastChangeDate"
00327                                     ." FROM ".$this->ItemTableName.$ConditionString,
00328                                 "LastChangeDate");
00329     }
00330 
00331     # retrieve item by item ID
00332     function GetItem($ItemId)
00333     {
00334         return new $this->ItemClassName($ItemId);
00335     }
00336 
00341     function ItemExists($ItemId)
00342     {
00343         return $this->DB->Query("SELECT COUNT(*) AS ItemCount"
00344                 ." FROM ".$this->ItemTableName
00345                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId), "ItemCount")
00346                 > 0 ? TRUE : FALSE;
00347     }
00348 
00349     # retrieve item by name
00350     function GetItemByName($Name, $IgnoreCase = FALSE)
00351     {
00352         # error out if this is an illegal operation for this item type
00353         if ($this->ItemNameFieldName == NULL)
00354         {
00355             exit("<br>ERROR: attempt to get item by name on item type"
00356                     ."(".$this->ItemClassName.") that has no name field specified<br>\n");
00357         }
00358 
00359         # query database for item ID
00360         $Comparison = $IgnoreCase
00361                 ? "LOWER(".$this->ItemNameFieldName.") = '"
00362                         .addslashes(strtolower($Name))."'"
00363                 : $this->ItemNameFieldName." = '" .addslashes($Name)."'";
00364         $ItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName
00365                                       ." FROM ".$this->ItemTableName
00366                                       ." WHERE ".$Comparison
00367                                             .(isset($this->FieldId)
00368                                                     ? " AND FieldId = ".$this->FieldId
00369                                                     : ""),
00370                                    $this->ItemIdFieldName);
00371 
00372         # if item ID was not found
00373         if ($ItemId === NULL)
00374         {
00375             # return NULL to caller
00376             $Item = NULL;
00377         }
00378         else
00379         {
00380             # generate new item object
00381             $Item = $this->GetItem($ItemId);
00382         }
00383 
00384         # return new object to caller
00385         return $Item;
00386     }
00387 
00393     function GetItemNames($SqlCondition = NULL)
00394     {
00395         # error out if this is an illegal operation for this item type
00396         if ($this->ItemNameFieldName == NULL)
00397         {
00398             exit("<br>ERROR: attempt to get array of item names on item type"
00399                     ."(".$this->ItemClassName.") that has no name field specified<br>\n");
00400         }
00401 
00402         # query database for item names
00403         $Condition = "";
00404         if ($this->FieldId || $SqlCondition)
00405         {
00406             $Condition = "WHERE ";
00407             if ($this->FieldId)
00408                 $Condition .= "FieldId = ".intval($this->FieldId);
00409             if ($this->FieldId && $SqlCondition)
00410                 $Condition .= " AND ";
00411             if ($SqlCondition)
00412                 $Condition .= $SqlCondition;
00413         }
00414         $this->DB->Query("SELECT ".$this->ItemIdFieldName
00415                                             .", ".$this->ItemNameFieldName
00416                                         ." FROM ".$this->ItemTableName." "
00417                                         .$Condition
00418                                         ." ORDER BY ".$this->ItemNameFieldName);
00419         $Names = $this->DB->FetchColumn(
00420                 $this->ItemNameFieldName, $this->ItemIdFieldName);
00421 
00422         # return item names to caller
00423         return $Names;
00424     }
00425 
00431     function GetItems($SqlCondition = NULL)
00432     {
00433         $Items = array();
00434         $Names = $this->GetItemNames($SqlCondition);
00435         foreach ($Names as $Id => $Name)
00436         {
00437             $Items[$Id] = $this->GetItem($Id);
00438         }
00439         return $Items;
00440     }
00441 
00455     function GetItemsAsOptionList($OptionListName, $SelectedItemId = NULL, 
00456             $SqlCondition = NULL, $DisplaySize = 1, $SubmitOnChange = FALSE)
00457     {
00458         # retrieve requested fields
00459         $ItemNames = $this->GetItemNames($SqlCondition);
00460 
00461         # if multiple selections are allowed
00462         if ($DisplaySize > 1)
00463         {
00464             # begin multi-selection HTML option list
00465             $Html = "<select name=\"".htmlspecialchars($OptionListName)."[]\""
00466                     .($SubmitOnChange ? " onChange=\"submit()\"" : "")
00467                     ." multiple=\"multiple\" size=\"".$DisplaySize."\">\n";
00468         }
00469         else
00470         {
00471             # begin single-selection HTML option list
00472             $Html = "<select name=\"".htmlspecialchars($OptionListName)."\""
00473                     .($SubmitOnChange ? " onChange=\"submit()\"" : "")
00474                     ." size=\"1\">\n";
00475             $Html .= "<option value=\"-1\">--</option>\n";
00476         }
00477 
00478         # for each metadata field
00479         foreach ($ItemNames as $Id => $Name)
00480         {
00481             # add entry for field to option list
00482             $Html .= "<option value=\"".$Id."\"";
00483             if (($Id == $SelectedItemId)
00484                     || (is_array($SelectedItemId) && in_array($Id, $SelectedItemId)))
00485             {
00486                 $Html .= " selected";  
00487             }
00488             $Html .= ">".htmlspecialchars($Name)."</option>\n";
00489         }
00490 
00491         # end HTML option list
00492         $Html .= "</select>\n";
00493 
00494         # return constructed HTML to caller
00495         return $Html;
00496     }
00503     function NameIsInUse($Name, $IgnoreCase = FALSE)
00504     {
00505         $Condition = $IgnoreCase
00506                 ? "LOWER(".$this->ItemNameFieldName.")"
00507                         ." = '".addslashes(strtolower($Name))."'"
00508                 : $this->ItemNameFieldName." = '".addslashes($Name)."'";
00509         $NameCount = $this->DB->Query("SELECT COUNT(*) AS RecordCount FROM "
00510                 .$this->ItemTableName." WHERE ".$Condition, "RecordCount");
00511         return ($NameCount > 0) ? TRUE : FALSE;
00512     }
00513 
00514     # retrieve names of items matching search string (array index is IDs)
00515     # (NOTE:  IncludeVariants parameter is NOT YET SUPPORTED!)
00516     function SearchForItemNames($SearchString, $NumberOfResults = 100,
00517             $IncludeVariants = FALSE, $UseBooleanMode = TRUE, $Offset=0)
00518     {
00519         # error out if this is an illegal operation for this item type
00520         if ($this->ItemNameFieldName == NULL)
00521         {
00522             exit("<br>ERROR: attempt to search for item names on item type"
00523                     ."(".$this->ItemClassName.") that has no name field specified<br>\n");
00524         }
00525 
00526         # return no results if empty search string passed in
00527         if (!strlen(trim($SearchString))) {  return array();  }
00528 
00529         # construct SQL query
00530         $DB = new Database();
00531         $QueryString = "SELECT ".$this->ItemIdFieldName.",".$this->ItemNameFieldName
00532                 ." FROM ".$this->ItemTableName." WHERE";
00533         if ($this->FieldId)
00534         {
00535             $QueryString .= " FieldId = ".$this->FieldId." AND";
00536         }
00537         if ($UseBooleanMode)
00538         {
00539             $SearchString = preg_replace("/[)\(><]+/", "", $SearchString);
00540             $Words = preg_split("/[\s]+/", trim($SearchString));
00541             $NewSearchString = "";
00542             $InQuotedString = FALSE;
00543             $SqlVarObj = new MysqlSystemVariables($DB);
00544             $StopWordList = $SqlVarObj->GetStopWords();
00545             $MinWordLen = $SqlVarObj->Get("ft_min_word_len");
00546             foreach ($Words as $Word)
00547             {
00548                 # remove any query-specific terms, punctuation, etc.
00549                 $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word);
00550 
00551                 # require (boolean AND) certain words
00552                 if ($InQuotedString == FALSE
00553                     && !in_array($JustTheWord, $StopWordList)
00554                     && strlen($JustTheWord) >= $MinWordLen
00555                     && $Word{0} != "+"
00556                     && $Word{0} != "-")
00557                 {
00558                     $NewSearchString .= "+";
00559                 }
00560 
00561                 if (preg_match("/^\"/", $Word)) {  $InQuotedString = TRUE;  }
00562                 if (preg_match("/\"$/", $Word)) {  $InQuotedString = FALSE;  }
00563                 $NewSearchString .= $Word." ";
00564             }
00565 
00566             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00567                     ." AGAINST ('".addslashes(trim($NewSearchString))."'"
00568                     ." IN BOOLEAN MODE)";
00569         }
00570         else
00571         {
00572             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00573                     ." AGAINST ('".addslashes(trim($SearchString))."')";
00574         }
00575         $QueryString .= " LIMIT ".intval($NumberOfResults)." OFFSET "
00576             .intval($Offset);
00577 
00578         # perform query and retrieve names and IDs of items found by query
00579         $DB->Query($QueryString);
00580         $Names = $DB->FetchColumn($this->ItemNameFieldName, $this->ItemIdFieldName);
00581 
00582         if ($UseBooleanMode)
00583         {
00584             foreach ($Words as $Word)
00585             {
00586                 $TgtWord = preg_replace("/[^a-zA-Z]/", "", $Word);
00587                 if ($Word{0} == "-" && strlen($TgtWord) < $MinWordLen)
00588                 {
00589                     $NewNames = array();
00590                     foreach ($Names as $Id => $Name)
00591                     {
00592                         if (! preg_match('/\b'.$TgtWord.'/i', $Name))
00593                         {
00594                             $NewNames[$Id] = $Name;
00595                         }
00596                     }
00597                     $Names = $NewNames;
00598                 }
00599             }
00600         }
00601 
00602         # return names to caller
00603         return $Names;
00604     }
00605 
00606     # retrieve the count of names of items matching search string (array index
00607     # is IDs) (NOTE:  IncludeVariants parameter is NOT YET SUPPORTED!)
00608     function GetCountForItemNames($SearchString, $IncludeVariants = FALSE,
00609         $UseBooleanMode = TRUE)
00610     {
00611         # return no results if empty search string passed in
00612         if (!strlen(trim($SearchString))) {  return 0;  }
00613 
00614         # construct SQL query
00615         $DB = new Database();
00616         $QueryString = "SELECT COUNT(*) as ItemCount FROM "
00617             .$this->ItemTableName." WHERE";
00618         if ($this->FieldId)
00619         {
00620             $QueryString .= " FieldId = ".$this->FieldId." AND";
00621         }
00622         if ($UseBooleanMode)
00623         {
00624             $SearchString = preg_replace("/[)\(><]+/", "", $SearchString);
00625             $Words = preg_split("/[\s]+/", trim($SearchString));
00626             $NewSearchString = "";
00627             $InQuotedString = FALSE;
00628             $SqlVarObj = new MysqlSystemVariables($DB);
00629             $StopWordList = $SqlVarObj->GetStopWords();
00630             $MinWordLen = $SqlVarObj->Get("ft_min_word_len");
00631             foreach ($Words as $Word)
00632             {
00633                 # remove any query-specific terms, punctuation, etc.
00634                 $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word);
00635 
00636                 # require (boolean AND) certain words
00637                 if ($InQuotedString == FALSE
00638                     && !in_array($JustTheWord, $StopWordList)
00639                     && strlen($JustTheWord) >= $MinWordLen
00640                     && $Word{0} != "+"
00641                     && $Word{0} != "-")
00642                 {
00643                     $NewSearchString .= "+";
00644                 }
00645 
00646                 if (preg_match("/^\"/", $Word)) {  $InQuotedString = TRUE;  }
00647                 if (preg_match("/\"$/", $Word)) {  $InQuotedString = FALSE;  }
00648                 $NewSearchString .= $Word." ";
00649             }
00650 
00651             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00652                     ." AGAINST ('".addslashes(trim($NewSearchString))."'"
00653                     ." IN BOOLEAN MODE)";
00654         }
00655         else
00656         {
00657             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00658                     ." AGAINST ('".addslashes(trim($SearchString))."')";
00659         }
00660 
00661         # perform query and retrieve names and IDs of items found by query
00662         $DB->Query($QueryString);
00663         return intval($DB->FetchField("ItemCount"));
00664     }
00665 
00674     function AddItems($ItemNames, $Qualifier = NULL)
00675     {
00676         # for each supplied item name
00677         $ItemCount = 0;
00678         foreach ($ItemNames as $Name)
00679         {
00680             # if item does not exist with this name
00681             $Name = trim($Name);
00682             if ($this->GetItemByName($Name) === NULL)
00683             {
00684                 # add item
00685                 $NewItem = new $this->ItemClassName(NULL, $Name, $this->FieldId);
00686                 $ItemCount++;
00687 
00688                 # assign qualifier to item if supplied
00689                 if ($Qualifier !== NULL)
00690                 {
00691                     $NewItem->Qualifier($Qualifier);
00692                 }
00693             }
00694         }
00695 
00696         # return count of items added to caller
00697         return $ItemCount;
00698     }
00699 
00700     # ---- order operations --------------------------------------------------
00701 
00702     # set SQL condition (added to WHERE clause) used to select items for ordering ops
00703     # (use NULL to clear any previous condition)
00704     function SetOrderOpsCondition($Condition)
00705     {
00706         # condition is non-negative IDs (non-temp items) plus supplied condition
00707         $NewCondition = $this->ItemIdFieldName." >= 0"
00708                    .(($Condition) ? " AND ".$Condition : "");
00709         $this->OrderList->SqlCondition($NewCondition);
00710     }
00711 
00712     # insert/move item to before specified item
00713     function InsertBefore($SourceItemOrItemId, $TargetItemOrItemId)
00714     {
00715         # error out if ordering operations are not allowed for this item type
00716         if (!$this->OrderOpsAllowed)
00717         {
00718             exit("<br>ERROR: attempt to perform ordering operation"
00719                     ." (InsertBefore()) on item type"
00720                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00721         }
00722 
00723         # insert/move item
00724         $this->OrderList->InsertBefore($SourceItemOrItemId, $TargetItemOrItemId);
00725     }
00726 
00727     # insert/move item to after specified item
00728     function InsertAfter($SourceItemOrItemId, $TargetItemOrItemId)
00729     {
00730         # error out if ordering operations are not allowed for this item type
00731         if (!$this->OrderOpsAllowed)
00732         {
00733             exit("<br>ERROR: attempt to perform ordering operation"
00734                     ." (InsertAfter()) on item type"
00735                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00736         }
00737 
00738         # insert/move item
00739         $this->OrderList->InsertAfter($SourceItemOrItemId, $TargetItemOrItemId);
00740     }
00741 
00742     # add/move item to beginning of list
00743     function Prepend($ItemOrItemId)
00744     {
00745         # error out if ordering operations are not allowed for this item type
00746         if (!$this->OrderOpsAllowed)
00747         {
00748             exit("<br>ERROR: attempt to perform ordering operation"
00749                     ." (Prepend()) on item type"
00750                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00751         }
00752 
00753         # prepend item
00754         $this->OrderList->Prepend($ItemOrItemId);
00755     }
00756 
00757     # add/move item to end of list
00758     function Append($ItemOrItemId)
00759     {
00760         # error out if ordering operations are not allowed for this item type
00761         if (!$this->OrderOpsAllowed)
00762         {
00763             exit("<br>ERROR: attempt to perform ordering operation"
00764                     ." (Append()) on item type"
00765                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00766         }
00767 
00768         # add/move item
00769         $this->OrderList->Append($ItemOrItemId);
00770     }
00771 
00772     # retrieve list of item IDs in order
00773     function GetItemIdsInOrder($AddStrayItemsToOrder = TRUE)
00774     {
00775         # error out if ordering operations are not allowed for this item type
00776         if (!$this->OrderOpsAllowed)
00777         {
00778             exit("<br>ERROR: attempt to perform ordering operation"
00779                     ." (GetItemIdsInOrder()) on item type"
00780                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00781         }
00782 
00783         # retrieve list of IDs
00784         return $this->OrderList->GetIds($AddStrayItemsToOrder);
00785     }
00786 
00787     # remove item from existing order
00788     function RemoveItemFromOrder($ItemId)
00789     {
00790         # error out if ordering operations are not allowed for this item type
00791         if (!$this->OrderOpsAllowed)
00792         {
00793             exit("<br>ERROR: attempt to perform ordering operation"
00794                     ." (RemoveItemFromOrder()) on item type"
00795                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00796         }
00797 
00798         # remove item
00799         $this->OrderList->Remove($ItemId);
00800     }
00801 
00802 
00803     # ---- PRIVATE INTERFACE -------------------------------------------------
00804 
00805     protected $DB;
00806     protected $FieldId;
00807 
00808     private $ItemClassName;
00809     private $ItemTableName;
00810     private $ItemIdFieldName;
00811     private $ItemNameFieldName;
00812     private $ErrorStatus;
00813     private $OrderOpsAllowed;
00814     private $OrderList;
00815 
00816     # get/set ordering values
00817     private function GetPreviousItemId($ItemId)
00818     {
00819         return $this->DB->Query("SELECT Previous".$this->ItemIdFieldName
00820                     ." FROM ".$this->ItemTableName
00821                     ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId),
00822                 "Previous".$this->ItemIdFieldName);
00823     }
00824     private function GetNextItemIdInOrder($ItemId)
00825     {
00826         return $this->DB->Query("SELECT Next".$this->ItemIdFieldName
00827                     ." FROM ".$this->ItemTableName
00828                     ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId),
00829                 "Next".$this->ItemIdFieldName);
00830     }
00831     private function SetPreviousItemId($ItemId, $NewValue)
00832     {
00833         $this->DB->Query("UPDATE ".$this->ItemTableName
00834                 ." SET Previous".$this->ItemIdFieldName." = ".intval($NewValue)
00835                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId));
00836     }
00837     private function SetNextItemId($ItemId, $NewValue)
00838     {
00839         $this->DB->Query("UPDATE ".$this->ItemTableName
00840                 ." SET Next".$this->ItemIdFieldName." = ".intval($NewValue)
00841                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId));
00842     }
00843     private function SetPreviousAndNextItemIds($ItemId, $NewPreviousId, $NewNextId)
00844     {
00845         $this->DB->Query("UPDATE ".$this->ItemTableName
00846                 ." SET Previous".$this->ItemIdFieldName." = ".intval($NewPreviousId)
00847                         .", Next".$this->ItemIdFieldName." = ".intval($NewNextId)
00848                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId));
00849     }
00850 }
00851 
00852 ?>