Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- Search for |

- File List
- File Members

# 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 ?>