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 
00136     # clear out any temp items more than one week old
00137     function CleanOutStaleTempItems()
00138     {
00139         # load array of stale items
00140         $this->DB->Query("SELECT ".$this->ItemIdFieldName." FROM ".$this->ItemTableName
00141                    ." WHERE ".$this->ItemIdFieldName." < 0"
00142                    ." AND DateLastModified < DATE_SUB(NOW(), INTERVAL 7 DAY)");
00143         $ItemIds = $this->DB->FetchColumn($this->ItemIdFieldName);
00144 
00145         # delete stale items
00146         foreach ($ItemIds as $ItemId)
00147         {
00148             $Item = new $this->ItemClassName($ItemId);
00149             $Item->Delete();
00150         }
00151     }
00152 
00153     # retrieve most recent temp item ID based on user ID
00154     # (returns NULL if no temp item found for that user ID)
00155     function GetLastTempItemId()
00156     {
00157         # retrieve ID of most recently modified temp item for this user
00158         global $User;
00159         $ItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName." FROM ".$this->ItemTableName
00160                                  ." WHERE LastModifiedById = '".$User->Get("UserId")."'"
00161                                  ." AND ".$this->ItemIdFieldName." < 0"
00162                                  ." ORDER BY ".$this->ItemIdFieldName." ASC"
00163                                  ." LIMIT 1",
00164                                  $this->ItemIdFieldName);
00165 
00166         # return item to caller (or NULL if none found)
00167         return $ItemId;
00168     }
00169 
00170     # return next item ID
00171     function GetNextItemId()
00172     {
00173         # if no highest item ID found
00174         $HighestItemId = $this->GetHighestItemId();
00175         if ($HighestItemId <= 0)
00176         {
00177             # start with item ID 1
00178             $ItemId = 1;
00179         }
00180         else
00181         {
00182             # else use next ID available after highest
00183             $ItemId = $HighestItemId + 1;
00184         }
00185 
00186         # return next ID to caller
00187         return $ItemId;
00188     }
00189 
00190     # return highest item ID ($Condition should not include "WHERE")
00191     function GetHighestItemId($Condition = NULL, $IncludeTempItems = FALSE)
00192     {
00193         # if temp items are supposed to be included
00194         if ($IncludeTempItems)
00195         {
00196             # condition is only as supplied
00197             $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
00198         }
00199         else
00200         {
00201             # condition is non-negative IDs plus supplied condition
00202             $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0"
00203                        .(($Condition == NULL) ? "" : " AND ".$Condition);
00204         }
00205 
00206         # return highest item ID to caller
00207         return $this->DB->Query("SELECT ".$this->ItemIdFieldName
00208                                     ." FROM ".$this->ItemTableName
00209                                     .$ConditionString
00210                                     ." ORDER BY ".$this->ItemIdFieldName
00211                                     ." DESC LIMIT 1",
00212                                 $this->ItemIdFieldName);
00213     }
00214 
00215     # return next temp item ID
00216     function GetNextTempItemId()
00217     {
00218         $LowestItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName
00219                                          ." FROM ".$this->ItemTableName
00220                                          ." ORDER BY ".$this->ItemIdFieldName
00221                                          ." ASC LIMIT 1",
00222                                          $this->ItemIdFieldName);
00223         if ($LowestItemId > 0)
00224         {
00225             $ItemId = -1;
00226         }
00227         else
00228         {
00229             $ItemId = $LowestItemId - 1;
00230         }
00231         return $ItemId;
00232     }
00233 
00234     # return count of items
00235     function GetItemCount($Condition = NULL, $IncludeTempItems = FALSE)
00236     {
00237         # if condition was supplied
00238         if ($Condition != NULL)
00239         {
00240             # use condition
00241             $ConditionString = " WHERE ".$Condition;
00242         }
00243         else
00244         {
00245             # if field ID is available
00246             if (isset($this->FieldId))
00247             {
00248                 # use condition for matching field ID
00249                 $ConditionString = " WHERE FieldId = ".intval($this->FieldId);
00250             }
00251             else
00252             {
00253                 # use no condition
00254                 $ConditionString = "";
00255             }
00256         }
00257 
00258         # if temp items are to be excluded
00259         if (!$IncludeTempItems)
00260         {
00261             # if a condition was previously set
00262             if (strlen($ConditionString))
00263             {
00264                 # add in condition to exclude temp items
00265                 $ConditionString .= " AND (".$this->ItemIdFieldName." >= 0)";
00266             }
00267             else
00268             {
00269                 # use condition to exclude temp items
00270                 $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0";
00271             }
00272         }
00273 
00274         # retrieve item count
00275         $Count = $this->DB->Query("SELECT COUNT(*) AS RecordCount"
00276                                       ." FROM ".$this->ItemTableName
00277                                       .$ConditionString,
00278                                   "RecordCount");
00279 
00280         # return count to caller
00281         return $Count;
00282     }
00283 
00284     # return array of item IDs ($Condition should not include "WHERE")
00285     function GetItemIds($Condition = NULL, $IncludeTempItems = FALSE)
00286     {
00287         # if temp items are supposed to be included
00288         if ($IncludeTempItems)
00289         {
00290             # condition is only as supplied
00291             $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
00292         }
00293         else
00294         {
00295             # condition is non-negative IDs plus supplied condition
00296             $ConditionString = " WHERE ".$this->ItemIdFieldName." >= 0"
00297                        .(($Condition == NULL) ? "" : " AND ".$Condition);
00298         }
00299 
00300         # get item IDs
00301         $this->DB->Query("SELECT ".$this->ItemIdFieldName
00302                                       ." FROM ".$this->ItemTableName
00303                                       .$ConditionString);
00304         $ItemIds = $this->DB->FetchColumn($this->ItemIdFieldName);
00305 
00306         # return IDs to caller
00307         return $ItemIds;
00308     }
00309 
00310     # return latest modification date ($Condition should not include "WHERE")
00311     function GetLatestModificationDate($Condition = NULL)
00312     {
00313         # return modification date for item most recently changed
00314         $ConditionString = ($Condition == NULL) ? "" : " WHERE ".$Condition;
00315         return $this->DB->Query("SELECT MAX(DateLastModified) AS LastChangeDate"
00316                                     ." FROM ".$this->ItemTableName.$ConditionString,
00317                                 "LastChangeDate");
00318     }
00319 
00320     # retrieve item by item ID
00321     function GetItem($ItemId)
00322     {
00323         return new $this->ItemClassName($ItemId);
00324     }
00325 
00330     function ItemExists($ItemId)
00331     {
00332         return $this->DB->Query("SELECT COUNT(*) AS ItemCount"
00333                 ." FROM ".$this->ItemTableName
00334                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId), "ItemCount")
00335                 > 0 ? TRUE : FALSE;
00336     }
00337 
00338     # retrieve item by name
00339     function GetItemByName($Name, $IgnoreCase = FALSE)
00340     {
00341         # error out if this is an illegal operation for this item type
00342         if ($this->ItemNameFieldName == NULL)
00343         {
00344             exit("<br>ERROR: attempt to get item by name on item type"
00345                     ."(".$this->ItemClassName.") that has no name field specified<br>\n");
00346         }
00347 
00348         # query database for item ID
00349         $Comparison = $IgnoreCase
00350                 ? "LOWER(".$this->ItemNameFieldName.") = '"
00351                         .addslashes(strtolower($Name))."'"
00352                 : $this->ItemNameFieldName." = '" .addslashes($Name)."'";
00353         $ItemId = $this->DB->Query("SELECT ".$this->ItemIdFieldName
00354                                       ." FROM ".$this->ItemTableName
00355                                       ." WHERE ".$Comparison
00356                                             .(isset($this->FieldId)
00357                                                     ? " AND FieldId = ".$this->FieldId
00358                                                     : ""),
00359                                    $this->ItemIdFieldName);
00360 
00361         # if item ID was not found
00362         if ($ItemId === NULL)
00363         {
00364             # return NULL to caller
00365             $Item = NULL;
00366         }
00367         else
00368         {
00369             # generate new item object
00370             $Item = $this->GetItem($ItemId);
00371         }
00372 
00373         # return new object to caller
00374         return $Item;
00375     }
00376 
00382     function GetItemNames($SqlCondition = NULL)
00383     {
00384         # error out if this is an illegal operation for this item type
00385         if ($this->ItemNameFieldName == NULL)
00386         {
00387             exit("<br>ERROR: attempt to get array of item names on item type"
00388                     ."(".$this->ItemClassName.") that has no name field specified<br>\n");
00389         }
00390 
00391         # query database for item names
00392         $Condition = "";
00393         if ($this->FieldId || $SqlCondition)
00394         {
00395             $Condition = "WHERE ";
00396             if ($this->FieldId)
00397                 $Condition .= "FieldId = ".intval($this->FieldId);
00398             if ($this->FieldId && $SqlCondition)
00399                 $Condition .= " AND ";
00400             if ($SqlCondition)
00401                 $Condition .= $SqlCondition;
00402         }
00403         $this->DB->Query("SELECT ".$this->ItemIdFieldName
00404                                             .", ".$this->ItemNameFieldName
00405                                         ." FROM ".$this->ItemTableName." "
00406                                         .$Condition
00407                                         ." ORDER BY ".$this->ItemNameFieldName);
00408         $Names = $this->DB->FetchColumn(
00409                 $this->ItemNameFieldName, $this->ItemIdFieldName);
00410 
00411         # return item names to caller
00412         return $Names;
00413     }
00414 
00420     function GetItems($SqlCondition = NULL)
00421     {
00422         $Items = array();
00423         $Names = $this->GetItemNames($SqlCondition);
00424         foreach ($Names as $Id => $Name)
00425         {
00426             $Items[$Id] = $this->GetItem($Id);
00427         }
00428         return $Items;
00429     }
00430 
00440     function GetItemsAsOptionList(
00441             $OptionListName, $SelectedItemId = NULL, $SqlCondition = NULL)
00442     {
00443         # retrieve requested fields
00444         $ItemNames = $this->GetItemNames($SqlCondition);
00445 
00446         # begin HTML option list
00447         $Html = "<select name=\"".htmlspecialchars($OptionListName)."\">\n";
00448         $Html .= "<option value=\"-1\">--</option>\n";
00449 
00450         # for each metadata field
00451         foreach ($ItemNames as $Id => $Name)
00452         {
00453             # add entry for field to option list
00454             $Html .= "<option value=\"".$Id."\"";
00455             if ($Id == $SelectedItemId) {  $Html .= " selected";  }
00456             $Html .= ">".htmlspecialchars($Name)."</option>\n";
00457         }
00458 
00459         # end HTML option list
00460         $Html .= "</select>\n";
00461 
00462         # return constructed HTML to caller
00463         return $Html;
00464     }
00471     function NameIsInUse($Name, $IgnoreCase = FALSE)
00472     {
00473         $Condition = $IgnoreCase
00474                 ? "LOWER(".$this->ItemNameFieldName.")"
00475                         ." = '".addslashes(strtolower($Name))."'"
00476                 : $this->ItemNameFieldName." = '".addslashes($Name)."'";
00477         $NameCount = $this->DB->Query("SELECT COUNT(*) AS RecordCount FROM "
00478                 .$this->ItemTableName." WHERE ".$Condition, "RecordCount");
00479         return ($NameCount > 0) ? TRUE : FALSE;
00480     }
00481 
00482     # retrieve names of items matching search string (array index is IDs)
00483     # (NOTE:  IncludeVariants parameter is NOT YET SUPPORTED!)
00484     function SearchForItemNames($SearchString, $NumberOfResults = 100,
00485             $IncludeVariants = FALSE, $UseBooleanMode = TRUE, $Offset=0)
00486     {
00487         # error out if this is an illegal operation for this item type
00488         if ($this->ItemNameFieldName == NULL)
00489         {
00490             exit("<br>ERROR: attempt to search for item names on item type"
00491                     ."(".$this->ItemClassName.") that has no name field specified<br>\n");
00492         }
00493 
00494         # return no results if empty search string passed in
00495         if (!strlen(trim($SearchString))) {  return array();  }
00496 
00497         # construct SQL query
00498         $DB = new Database();
00499         $QueryString = "SELECT ".$this->ItemIdFieldName.",".$this->ItemNameFieldName
00500                 ." FROM ".$this->ItemTableName." WHERE";
00501         if ($this->FieldId)
00502         {
00503             $QueryString .= " FieldId = ".$this->FieldId." AND";
00504         }
00505         if ($UseBooleanMode)
00506         {
00507             $SearchString = preg_replace("/[)\(><]+/", "", $SearchString);
00508             $Words = preg_split("/[\s]+/", trim($SearchString));
00509             $NewSearchString = "";
00510             $InQuotedString = FALSE;
00511             $SqlVarObj = new MysqlSystemVariables($DB);
00512             $StopWordList = $SqlVarObj->GetStopWords();
00513             $MinWordLen = $SqlVarObj->Get("ft_min_word_len");
00514             foreach ($Words as $Word)
00515             {
00516                 # remove any query-specific terms, punctuation, etc.
00517                 $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word);
00518 
00519                 # require (boolean AND) certain words
00520                 if ($InQuotedString == FALSE
00521                     && !in_array($JustTheWord, $StopWordList)
00522                     && strlen($JustTheWord) >= $MinWordLen
00523                     && $Word{0} != "+"
00524                     && $Word{0} != "-")
00525                 {
00526                     $NewSearchString .= "+";
00527                 }
00528 
00529                 if (preg_match("/^\"/", $Word)) {  $InQuotedString = TRUE;  }
00530                 if (preg_match("/\"$/", $Word)) {  $InQuotedString = FALSE;  }
00531                 $NewSearchString .= $Word." ";
00532             }
00533 
00534             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00535                     ." AGAINST ('".addslashes(trim($NewSearchString))."'"
00536                     ." IN BOOLEAN MODE)";
00537         }
00538         else
00539         {
00540             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00541                     ." AGAINST ('".addslashes(trim($SearchString))."')";
00542         }
00543         $QueryString .= " LIMIT ".intval($NumberOfResults)." OFFSET "
00544             .intval($Offset);
00545 
00546         # perform query and retrieve names and IDs of items found by query
00547         $DB->Query($QueryString);
00548         $Names = $DB->FetchColumn($this->ItemNameFieldName, $this->ItemIdFieldName);
00549 
00550         if ($UseBooleanMode)
00551         {
00552             foreach ($Words as $Word)
00553             {
00554                 $TgtWord = preg_replace("/[^a-zA-Z]/", "", $Word);
00555                 if ($Word{0} == "-" && strlen($TgtWord) < $MinWordLen)
00556                 {
00557                     $NewNames = array();
00558                     foreach ($Names as $Id => $Name)
00559                     {
00560                         if (! preg_match('/\b'.$TgtWord.'/i', $Name))
00561                         {
00562                             $NewNames[$Id] = $Name;
00563                         }
00564                     }
00565                     $Names = $NewNames;
00566                 }
00567             }
00568         }
00569 
00570         # return names to caller
00571         return $Names;
00572     }
00573 
00574     # retrieve the count of names of items matching search string (array index
00575     # is IDs) (NOTE:  IncludeVariants parameter is NOT YET SUPPORTED!)
00576     function GetCountForItemNames($SearchString, $IncludeVariants = FALSE,
00577         $UseBooleanMode = TRUE)
00578     {
00579         # return no results if empty search string passed in
00580         if (!strlen(trim($SearchString))) {  return 0;  }
00581 
00582         # construct SQL query
00583         $DB = new Database();
00584         $QueryString = "SELECT COUNT(*) as ItemCount FROM "
00585             .$this->ItemTableName." WHERE";
00586         if ($this->FieldId)
00587         {
00588             $QueryString .= " FieldId = ".$this->FieldId." AND";
00589         }
00590         if ($UseBooleanMode)
00591         {
00592             $SearchString = preg_replace("/[)\(><]+/", "", $SearchString);
00593             $Words = preg_split("/[\s]+/", trim($SearchString));
00594             $NewSearchString = "";
00595             $InQuotedString = FALSE;
00596             $SqlVarObj = new MysqlSystemVariables($DB);
00597             $StopWordList = $SqlVarObj->GetStopWords();
00598             $MinWordLen = $SqlVarObj->Get("ft_min_word_len");
00599             foreach ($Words as $Word)
00600             {
00601                 # remove any query-specific terms, punctuation, etc.
00602                 $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word);
00603 
00604                 # require (boolean AND) certain words
00605                 if ($InQuotedString == FALSE
00606                     && !in_array($JustTheWord, $StopWordList)
00607                     && strlen($JustTheWord) >= $MinWordLen
00608                     && $Word{0} != "+"
00609                     && $Word{0} != "-")
00610                 {
00611                     $NewSearchString .= "+";
00612                 }
00613 
00614                 if (preg_match("/^\"/", $Word)) {  $InQuotedString = TRUE;  }
00615                 if (preg_match("/\"$/", $Word)) {  $InQuotedString = FALSE;  }
00616                 $NewSearchString .= $Word." ";
00617             }
00618 
00619             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00620                     ." AGAINST ('".addslashes(trim($NewSearchString))."'"
00621                     ." IN BOOLEAN MODE)";
00622         }
00623         else
00624         {
00625             $QueryString .= " MATCH (".$this->ItemNameFieldName.")"
00626                     ." AGAINST ('".addslashes(trim($SearchString))."')";
00627         }
00628 
00629         # perform query and retrieve names and IDs of items found by query
00630         $DB->Query($QueryString);
00631         return intval($DB->FetchField("ItemCount"));
00632     }
00633 
00642     function AddItems($ItemNames, $Qualifier = NULL)
00643     {
00644         # for each supplied item name
00645         $ItemCount = 0;
00646         foreach ($ItemNames as $Name)
00647         {
00648             # if item does not exist with this name
00649             $Name = trim($Name);
00650             if ($this->GetItemByName($Name) === NULL)
00651             {
00652                 # add item
00653                 $NewItem = new $this->ItemClassName(NULL, $Name, $this->FieldId);
00654                 $ItemCount++;
00655 
00656                 # assign qualifier to item if supplied
00657                 if ($Qualifier !== NULL)
00658                 {
00659                     $NewItem->Qualifier($Qualifier);
00660                 }
00661             }
00662         }
00663 
00664         # return count of items added to caller
00665         return $ItemCount;
00666     }
00667 
00668     # ---- order operations --------------------------------------------------
00669 
00670     # set SQL condition (added to WHERE clause) used to select items for ordering ops
00671     # (use NULL to clear any previous condition)
00672     function SetOrderOpsCondition($Condition)
00673     {
00674         # condition is non-negative IDs (non-temp items) plus supplied condition
00675         $NewCondition = $this->ItemIdFieldName." >= 0"
00676                    .(($Condition) ? " AND ".$Condition : "");
00677         $this->OrderList->SqlCondition($NewCondition);
00678     }
00679 
00680     # insert/move item to before specified item
00681     function InsertBefore($SourceItemOrItemId, $TargetItemOrItemId)
00682     {
00683         # error out if ordering operations are not allowed for this item type
00684         if (!$this->OrderOpsAllowed)
00685         {
00686             exit("<br>ERROR: attempt to perform ordering operation"
00687                     ." (InsertBefore()) on item type"
00688                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00689         }
00690 
00691         # insert/move item
00692         $this->OrderList->InsertBefore($SourceItemOrItemId, $TargetItemOrItemId);
00693     }
00694 
00695     # insert/move item to after specified item
00696     function InsertAfter($SourceItemOrItemId, $TargetItemOrItemId)
00697     {
00698         # error out if ordering operations are not allowed for this item type
00699         if (!$this->OrderOpsAllowed)
00700         {
00701             exit("<br>ERROR: attempt to perform ordering operation"
00702                     ." (InsertAfter()) on item type"
00703                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00704         }
00705 
00706         # insert/move item
00707         $this->OrderList->InsertAfter($SourceItemOrItemId, $TargetItemOrItemId);
00708     }
00709 
00710     # add/move item to beginning of list
00711     function Prepend($ItemOrItemId)
00712     {
00713         # error out if ordering operations are not allowed for this item type
00714         if (!$this->OrderOpsAllowed)
00715         {
00716             exit("<br>ERROR: attempt to perform ordering operation"
00717                     ." (Prepend()) on item type"
00718                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00719         }
00720 
00721         # prepend item
00722         $this->OrderList->Prepend($ItemOrItemId);
00723     }
00724 
00725     # add/move item to end of list
00726     function Append($ItemOrItemId)
00727     {
00728         # error out if ordering operations are not allowed for this item type
00729         if (!$this->OrderOpsAllowed)
00730         {
00731             exit("<br>ERROR: attempt to perform ordering operation"
00732                     ." (Append()) on item type"
00733                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00734         }
00735 
00736         # add/move item
00737         $this->OrderList->Append($ItemOrItemId);
00738     }
00739 
00740     # retrieve list of item IDs in order
00741     function GetItemIdsInOrder($AddStrayItemsToOrder = TRUE)
00742     {
00743         # error out if ordering operations are not allowed for this item type
00744         if (!$this->OrderOpsAllowed)
00745         {
00746             exit("<br>ERROR: attempt to perform ordering operation"
00747                     ." (GetItemIdsInOrder()) on item type"
00748                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00749         }
00750 
00751         # retrieve list of IDs
00752         return $this->OrderList->GetIds($AddStrayItemsToOrder);
00753     }
00754 
00755     # remove item from existing order
00756     function RemoveItemFromOrder($ItemId)
00757     {
00758         # error out if ordering operations are not allowed for this item type
00759         if (!$this->OrderOpsAllowed)
00760         {
00761             exit("<br>ERROR: attempt to perform ordering operation"
00762                     ." (RemoveItemFromOrder()) on item type"
00763                     ."(".$this->ItemClassName.") that does not support ordering<br>\n");
00764         }
00765 
00766         # remove item
00767         $this->OrderList->Remove($ItemId);
00768     }
00769 
00770 
00771     # ---- PRIVATE INTERFACE -------------------------------------------------
00772 
00773     protected $DB;
00774     protected $FieldId;
00775 
00776     private $ItemClassName;
00777     private $ItemTableName;
00778     private $ItemIdFieldName;
00779     private $ItemNameFieldName;
00780     private $ErrorStatus;
00781     private $OrderOpsAllowed;
00782     private $OrderList;
00783 
00784     # get/set ordering values
00785     private function GetPreviousItemId($ItemId)
00786     {
00787         return $this->DB->Query("SELECT Previous".$this->ItemIdFieldName
00788                     ." FROM ".$this->ItemTableName
00789                     ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId),
00790                 "Previous".$this->ItemIdFieldName);
00791     }
00792     private function GetNextItemIdInOrder($ItemId)
00793     {
00794         return $this->DB->Query("SELECT Next".$this->ItemIdFieldName
00795                     ." FROM ".$this->ItemTableName
00796                     ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId),
00797                 "Next".$this->ItemIdFieldName);
00798     }
00799     private function SetPreviousItemId($ItemId, $NewValue)
00800     {
00801         $this->DB->Query("UPDATE ".$this->ItemTableName
00802                 ." SET Previous".$this->ItemIdFieldName." = ".intval($NewValue)
00803                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId));
00804     }
00805     private function SetNextItemId($ItemId, $NewValue)
00806     {
00807         $this->DB->Query("UPDATE ".$this->ItemTableName
00808                 ." SET Next".$this->ItemIdFieldName." = ".intval($NewValue)
00809                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId));
00810     }
00811     private function SetPreviousAndNextItemIds($ItemId, $NewPreviousId, $NewNextId)
00812     {
00813         $this->DB->Query("UPDATE ".$this->ItemTableName
00814                 ." SET Previous".$this->ItemIdFieldName." = ".intval($NewPreviousId)
00815                         .", Next".$this->ItemIdFieldName." = ".intval($NewNextId)
00816                 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId));
00817     }
00818 }
00819 
00820 ?>