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