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 00453 function GetItemsAsOptionList($OptionListName, $SelectedItemId = NULL, 00454 $SqlCondition = NULL, $DisplaySize = 1) 00455 { 00456 # retrieve requested fields 00457 $ItemNames = $this->GetItemNames($SqlCondition); 00458 00459 # if multiple selections are allowed 00460 if ($DisplaySize > 1) 00461 { 00462 # begin multi-selection HTML option list 00463 $Html = "<select name=\"".htmlspecialchars($OptionListName)."[]\"" 00464 ." multiple=\"multiple\" size=\"".$DisplaySize."\">\n"; 00465 } 00466 else 00467 { 00468 # begin single-selection HTML option list 00469 $Html = "<select name=\"".htmlspecialchars($OptionListName)."\"" 00470 ." size=\"1\">\n"; 00471 $Html .= "<option value=\"-1\">--</option>\n"; 00472 } 00473 00474 # for each metadata field 00475 foreach ($ItemNames as $Id => $Name) 00476 { 00477 # add entry for field to option list 00478 $Html .= "<option value=\"".$Id."\""; 00479 if (($Id == $SelectedItemId) 00480 || (is_array($SelectedItemId) && in_array($Id, $SelectedItemId))) 00481 { 00482 $Html .= " selected"; 00483 } 00484 $Html .= ">".htmlspecialchars($Name)."</option>\n"; 00485 } 00486 00487 # end HTML option list 00488 $Html .= "</select>\n"; 00489 00490 # return constructed HTML to caller 00491 return $Html; 00492 } 00499 function NameIsInUse($Name, $IgnoreCase = FALSE) 00500 { 00501 $Condition = $IgnoreCase 00502 ? "LOWER(".$this->ItemNameFieldName.")" 00503 ." = '".addslashes(strtolower($Name))."'" 00504 : $this->ItemNameFieldName." = '".addslashes($Name)."'"; 00505 $NameCount = $this->DB->Query("SELECT COUNT(*) AS RecordCount FROM " 00506 .$this->ItemTableName." WHERE ".$Condition, "RecordCount"); 00507 return ($NameCount > 0) ? TRUE : FALSE; 00508 } 00509 00510 # retrieve names of items matching search string (array index is IDs) 00511 # (NOTE: IncludeVariants parameter is NOT YET SUPPORTED!) 00512 function SearchForItemNames($SearchString, $NumberOfResults = 100, 00513 $IncludeVariants = FALSE, $UseBooleanMode = TRUE, $Offset=0) 00514 { 00515 # error out if this is an illegal operation for this item type 00516 if ($this->ItemNameFieldName == NULL) 00517 { 00518 exit("<br>ERROR: attempt to search for item names on item type" 00519 ."(".$this->ItemClassName.") that has no name field specified<br>\n"); 00520 } 00521 00522 # return no results if empty search string passed in 00523 if (!strlen(trim($SearchString))) { return array(); } 00524 00525 # construct SQL query 00526 $DB = new Database(); 00527 $QueryString = "SELECT ".$this->ItemIdFieldName.",".$this->ItemNameFieldName 00528 ." FROM ".$this->ItemTableName." WHERE"; 00529 if ($this->FieldId) 00530 { 00531 $QueryString .= " FieldId = ".$this->FieldId." AND"; 00532 } 00533 if ($UseBooleanMode) 00534 { 00535 $SearchString = preg_replace("/[)\(><]+/", "", $SearchString); 00536 $Words = preg_split("/[\s]+/", trim($SearchString)); 00537 $NewSearchString = ""; 00538 $InQuotedString = FALSE; 00539 $SqlVarObj = new MysqlSystemVariables($DB); 00540 $StopWordList = $SqlVarObj->GetStopWords(); 00541 $MinWordLen = $SqlVarObj->Get("ft_min_word_len"); 00542 foreach ($Words as $Word) 00543 { 00544 # remove any query-specific terms, punctuation, etc. 00545 $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word); 00546 00547 # require (boolean AND) certain words 00548 if ($InQuotedString == FALSE 00549 && !in_array($JustTheWord, $StopWordList) 00550 && strlen($JustTheWord) >= $MinWordLen 00551 && $Word{0} != "+" 00552 && $Word{0} != "-") 00553 { 00554 $NewSearchString .= "+"; 00555 } 00556 00557 if (preg_match("/^\"/", $Word)) { $InQuotedString = TRUE; } 00558 if (preg_match("/\"$/", $Word)) { $InQuotedString = FALSE; } 00559 $NewSearchString .= $Word." "; 00560 } 00561 00562 $QueryString .= " MATCH (".$this->ItemNameFieldName.")" 00563 ." AGAINST ('".addslashes(trim($NewSearchString))."'" 00564 ." IN BOOLEAN MODE)"; 00565 } 00566 else 00567 { 00568 $QueryString .= " MATCH (".$this->ItemNameFieldName.")" 00569 ." AGAINST ('".addslashes(trim($SearchString))."')"; 00570 } 00571 $QueryString .= " LIMIT ".intval($NumberOfResults)." OFFSET " 00572 .intval($Offset); 00573 00574 # perform query and retrieve names and IDs of items found by query 00575 $DB->Query($QueryString); 00576 $Names = $DB->FetchColumn($this->ItemNameFieldName, $this->ItemIdFieldName); 00577 00578 if ($UseBooleanMode) 00579 { 00580 foreach ($Words as $Word) 00581 { 00582 $TgtWord = preg_replace("/[^a-zA-Z]/", "", $Word); 00583 if ($Word{0} == "-" && strlen($TgtWord) < $MinWordLen) 00584 { 00585 $NewNames = array(); 00586 foreach ($Names as $Id => $Name) 00587 { 00588 if (! preg_match('/\b'.$TgtWord.'/i', $Name)) 00589 { 00590 $NewNames[$Id] = $Name; 00591 } 00592 } 00593 $Names = $NewNames; 00594 } 00595 } 00596 } 00597 00598 # return names to caller 00599 return $Names; 00600 } 00601 00602 # retrieve the count of names of items matching search string (array index 00603 # is IDs) (NOTE: IncludeVariants parameter is NOT YET SUPPORTED!) 00604 function GetCountForItemNames($SearchString, $IncludeVariants = FALSE, 00605 $UseBooleanMode = TRUE) 00606 { 00607 # return no results if empty search string passed in 00608 if (!strlen(trim($SearchString))) { return 0; } 00609 00610 # construct SQL query 00611 $DB = new Database(); 00612 $QueryString = "SELECT COUNT(*) as ItemCount FROM " 00613 .$this->ItemTableName." WHERE"; 00614 if ($this->FieldId) 00615 { 00616 $QueryString .= " FieldId = ".$this->FieldId." AND"; 00617 } 00618 if ($UseBooleanMode) 00619 { 00620 $SearchString = preg_replace("/[)\(><]+/", "", $SearchString); 00621 $Words = preg_split("/[\s]+/", trim($SearchString)); 00622 $NewSearchString = ""; 00623 $InQuotedString = FALSE; 00624 $SqlVarObj = new MysqlSystemVariables($DB); 00625 $StopWordList = $SqlVarObj->GetStopWords(); 00626 $MinWordLen = $SqlVarObj->Get("ft_min_word_len"); 00627 foreach ($Words as $Word) 00628 { 00629 # remove any query-specific terms, punctuation, etc. 00630 $JustTheWord = preg_replace("/[^a-zA-Z-]/", "", $Word); 00631 00632 # require (boolean AND) certain words 00633 if ($InQuotedString == FALSE 00634 && !in_array($JustTheWord, $StopWordList) 00635 && strlen($JustTheWord) >= $MinWordLen 00636 && $Word{0} != "+" 00637 && $Word{0} != "-") 00638 { 00639 $NewSearchString .= "+"; 00640 } 00641 00642 if (preg_match("/^\"/", $Word)) { $InQuotedString = TRUE; } 00643 if (preg_match("/\"$/", $Word)) { $InQuotedString = FALSE; } 00644 $NewSearchString .= $Word." "; 00645 } 00646 00647 $QueryString .= " MATCH (".$this->ItemNameFieldName.")" 00648 ." AGAINST ('".addslashes(trim($NewSearchString))."'" 00649 ." IN BOOLEAN MODE)"; 00650 } 00651 else 00652 { 00653 $QueryString .= " MATCH (".$this->ItemNameFieldName.")" 00654 ." AGAINST ('".addslashes(trim($SearchString))."')"; 00655 } 00656 00657 # perform query and retrieve names and IDs of items found by query 00658 $DB->Query($QueryString); 00659 return intval($DB->FetchField("ItemCount")); 00660 } 00661 00670 function AddItems($ItemNames, $Qualifier = NULL) 00671 { 00672 # for each supplied item name 00673 $ItemCount = 0; 00674 foreach ($ItemNames as $Name) 00675 { 00676 # if item does not exist with this name 00677 $Name = trim($Name); 00678 if ($this->GetItemByName($Name) === NULL) 00679 { 00680 # add item 00681 $NewItem = new $this->ItemClassName(NULL, $Name, $this->FieldId); 00682 $ItemCount++; 00683 00684 # assign qualifier to item if supplied 00685 if ($Qualifier !== NULL) 00686 { 00687 $NewItem->Qualifier($Qualifier); 00688 } 00689 } 00690 } 00691 00692 # return count of items added to caller 00693 return $ItemCount; 00694 } 00695 00696 # ---- order operations -------------------------------------------------- 00697 00698 # set SQL condition (added to WHERE clause) used to select items for ordering ops 00699 # (use NULL to clear any previous condition) 00700 function SetOrderOpsCondition($Condition) 00701 { 00702 # condition is non-negative IDs (non-temp items) plus supplied condition 00703 $NewCondition = $this->ItemIdFieldName." >= 0" 00704 .(($Condition) ? " AND ".$Condition : ""); 00705 $this->OrderList->SqlCondition($NewCondition); 00706 } 00707 00708 # insert/move item to before specified item 00709 function InsertBefore($SourceItemOrItemId, $TargetItemOrItemId) 00710 { 00711 # error out if ordering operations are not allowed for this item type 00712 if (!$this->OrderOpsAllowed) 00713 { 00714 exit("<br>ERROR: attempt to perform ordering operation" 00715 ." (InsertBefore()) on item type" 00716 ."(".$this->ItemClassName.") that does not support ordering<br>\n"); 00717 } 00718 00719 # insert/move item 00720 $this->OrderList->InsertBefore($SourceItemOrItemId, $TargetItemOrItemId); 00721 } 00722 00723 # insert/move item to after specified item 00724 function InsertAfter($SourceItemOrItemId, $TargetItemOrItemId) 00725 { 00726 # error out if ordering operations are not allowed for this item type 00727 if (!$this->OrderOpsAllowed) 00728 { 00729 exit("<br>ERROR: attempt to perform ordering operation" 00730 ." (InsertAfter()) on item type" 00731 ."(".$this->ItemClassName.") that does not support ordering<br>\n"); 00732 } 00733 00734 # insert/move item 00735 $this->OrderList->InsertAfter($SourceItemOrItemId, $TargetItemOrItemId); 00736 } 00737 00738 # add/move item to beginning of list 00739 function Prepend($ItemOrItemId) 00740 { 00741 # error out if ordering operations are not allowed for this item type 00742 if (!$this->OrderOpsAllowed) 00743 { 00744 exit("<br>ERROR: attempt to perform ordering operation" 00745 ." (Prepend()) on item type" 00746 ."(".$this->ItemClassName.") that does not support ordering<br>\n"); 00747 } 00748 00749 # prepend item 00750 $this->OrderList->Prepend($ItemOrItemId); 00751 } 00752 00753 # add/move item to end of list 00754 function Append($ItemOrItemId) 00755 { 00756 # error out if ordering operations are not allowed for this item type 00757 if (!$this->OrderOpsAllowed) 00758 { 00759 exit("<br>ERROR: attempt to perform ordering operation" 00760 ." (Append()) on item type" 00761 ."(".$this->ItemClassName.") that does not support ordering<br>\n"); 00762 } 00763 00764 # add/move item 00765 $this->OrderList->Append($ItemOrItemId); 00766 } 00767 00768 # retrieve list of item IDs in order 00769 function GetItemIdsInOrder($AddStrayItemsToOrder = TRUE) 00770 { 00771 # error out if ordering operations are not allowed for this item type 00772 if (!$this->OrderOpsAllowed) 00773 { 00774 exit("<br>ERROR: attempt to perform ordering operation" 00775 ." (GetItemIdsInOrder()) on item type" 00776 ."(".$this->ItemClassName.") that does not support ordering<br>\n"); 00777 } 00778 00779 # retrieve list of IDs 00780 return $this->OrderList->GetIds($AddStrayItemsToOrder); 00781 } 00782 00783 # remove item from existing order 00784 function RemoveItemFromOrder($ItemId) 00785 { 00786 # error out if ordering operations are not allowed for this item type 00787 if (!$this->OrderOpsAllowed) 00788 { 00789 exit("<br>ERROR: attempt to perform ordering operation" 00790 ." (RemoveItemFromOrder()) on item type" 00791 ."(".$this->ItemClassName.") that does not support ordering<br>\n"); 00792 } 00793 00794 # remove item 00795 $this->OrderList->Remove($ItemId); 00796 } 00797 00798 00799 # ---- PRIVATE INTERFACE ------------------------------------------------- 00800 00801 protected $DB; 00802 protected $FieldId; 00803 00804 private $ItemClassName; 00805 private $ItemTableName; 00806 private $ItemIdFieldName; 00807 private $ItemNameFieldName; 00808 private $ErrorStatus; 00809 private $OrderOpsAllowed; 00810 private $OrderList; 00811 00812 # get/set ordering values 00813 private function GetPreviousItemId($ItemId) 00814 { 00815 return $this->DB->Query("SELECT Previous".$this->ItemIdFieldName 00816 ." FROM ".$this->ItemTableName 00817 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId), 00818 "Previous".$this->ItemIdFieldName); 00819 } 00820 private function GetNextItemIdInOrder($ItemId) 00821 { 00822 return $this->DB->Query("SELECT Next".$this->ItemIdFieldName 00823 ." FROM ".$this->ItemTableName 00824 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId), 00825 "Next".$this->ItemIdFieldName); 00826 } 00827 private function SetPreviousItemId($ItemId, $NewValue) 00828 { 00829 $this->DB->Query("UPDATE ".$this->ItemTableName 00830 ." SET Previous".$this->ItemIdFieldName." = ".intval($NewValue) 00831 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId)); 00832 } 00833 private function SetNextItemId($ItemId, $NewValue) 00834 { 00835 $this->DB->Query("UPDATE ".$this->ItemTableName 00836 ." SET Next".$this->ItemIdFieldName." = ".intval($NewValue) 00837 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId)); 00838 } 00839 private function SetPreviousAndNextItemIds($ItemId, $NewPreviousId, $NewNextId) 00840 { 00841 $this->DB->Query("UPDATE ".$this->ItemTableName 00842 ." SET Previous".$this->ItemIdFieldName." = ".intval($NewPreviousId) 00843 .", Next".$this->ItemIdFieldName." = ".intval($NewNextId) 00844 ." WHERE ".$this->ItemIdFieldName." = ".intval($ItemId)); 00845 } 00846 } 00847 00848 ?>