Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

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