5 # Part of the Collection Workflow Information System (CWIS)
6 # Copyright 2012-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
19 # ---- PUBLIC INTERFACE --------------------------------------------------
30 # create our own DB handle
34 $this->
Id = intval($FolderId);
36 # attempt to load in folder info
37 $this->DB->Query(
"SELECT * FROM Folders WHERE FolderId = ".$this->
Id);
38 $Record = $this->DB->FetchRow();
40 # if folder was not found
41 if ($Record === FALSE)
43 # bail out with exception
44 throw new Exception(
"Unknown Folder ID (".$FolderId.
").");
48 $this->
OwnerId = $Record[
"OwnerId"];
49 $this->FolderName = $Record[
"FolderName"];
51 $this->FolderNote = $Record[
"FolderNote"];
52 $this->
IsShared = $Record[
"IsShared"];
53 $this->ContentType = $Record[
"ContentType"];
54 $this->UpdateValueCache = $Record;
56 # load list of resources in folder from database
57 $this->DB->Query(
"SELECT ItemId, ItemTypeId, ItemNote FROM FolderItemInts"
58 .
" WHERE FolderId = ".$this->
Id);
60 # create internal cache for item notes
61 $this->ItemNoteCache = array();
62 while ($Record = $this->DB->FetchRow())
64 $Index = self::GetCacheIndex($Record[
"ItemId"], $Record[
"ItemTypeId"]);
65 $this->ItemNoteCache[$Index] = $Record[
"ItemNote"];
69 if ($this->ContentType == self::MIXEDCONTENT)
72 "FolderItemInts",
"ItemId",
"FolderId = ".$this->
Id,
"ItemTypeId");
77 "FolderItemInts",
"ItemId",
"FolderId = ".$this->
Id);
86 # take folder out of global folder order
88 $Factory->RemoveItemFromOrder($this->
Id);
90 # remove resource listings from DB
91 $this->DB->Query(
"DELETE FROM FolderItemInts WHERE FolderId = ".$this->
Id);
93 # remove folder listing from DB
94 $this->DB->Query(
"DELETE FROM Folders WHERE FolderId = ".$this->
Id);
98 # ------------------------------------------------------------------------
121 return $this->UpdateValue(
"FolderName", $NewValue);
133 $Name = $this->UpdateValue(
"NormalizedName", $NewValue);
134 # attempt to generate and set new normalized name if none found
137 $Name = $this->UpdateValue(
"NormalizedName",
138 self::NormalizeFolderName($this->
Name()));
150 return preg_replace(
"/[^a-z0-9]/",
"", strtolower($Name));
161 return $this->UpdateValue(
"IsShared", $NewValue);
171 if ($NewValue !==
DB_NOVALUE) { unset($this->Owner); }
172 return intval($this->UpdateValue(
"OwnerId", $NewValue));
182 return $this->UpdateValue(
"FolderNote", $NewValue);
186 # ------------------------------------------------------------------------
202 $TargetItemType = NULL, $NewItemType = NULL)
204 $this->AddItem($NewItemOrItemId, $NewItemType);
205 $this->OrderList->InsertBefore($TargetItemOrItemId, $NewItemOrItemId,
206 self::GetItemTypeId($TargetItemType),
207 self::GetItemTypeId($NewItemType));
222 $TargetItemType = NULL, $NewItemType = NULL)
224 $this->AddItem($NewItemOrItemId, $NewItemType);
225 $this->OrderList->InsertAfter($TargetItemOrItemId, $NewItemOrItemId,
226 self::GetItemTypeId($TargetItemType),
227 self::GetItemTypeId($NewItemType));
239 $this->AddItem($ItemOrItemId, $ItemType);
240 $this->OrderList->Prepend($ItemOrItemId, self::GetItemTypeId($ItemType));
252 $this->AddItem($ItemOrItemId, $ItemType);
253 $this->OrderList->Append($ItemOrItemId, self::GetItemTypeId($ItemType));
265 # retrieve item ordered list of type IDs
266 $ItemIds = $this->OrderList->GetIds();
268 # if this is a mixed-item-type folder
269 if ($this->ContentType == self::MIXEDCONTENT)
271 # convert item type IDs to corresponding type names
272 $NewItemIds = array();
273 foreach ($ItemIds as $ItemInfo)
275 $NewItemIds[] = array(
276 "ID" => $ItemInfo[
"ID"],
277 "Type" => self::GetItemTypeName($ItemInfo[
"Type"]),
280 $ItemIds = $NewItemIds;
283 # return list of item type IDs (and possibly types) to caller
295 return $this->OrderList->GetCount();
306 # if resource is in folder
309 # remove item from item order
310 $ItemTypeId = self::GetItemTypeId($ItemType);
311 $this->OrderList->Remove($ItemId, $ItemTypeId);
313 # remove resource from folder locally
314 unset($this->ItemNoteCache[self::GetCacheIndex($ItemId, $ItemTypeId)]);
316 # remove resource from folder in DB
317 $this->DB->Query(
"DELETE FROM FolderItemInts"
318 .
" WHERE FolderId = ".intval($this->
Id)
319 .
" AND ItemId = ".intval($ItemId)
320 .
" AND ItemTypeId = ".intval($ItemTypeId));
333 $ItemTypeId = self::GetItemTypeId($ItemType);
334 $Index = self::GetCacheIndex($ItemId, $ItemTypeId);
335 $DummyCache = array(
"ItemNote" => $this->ItemNoteCache[$Index]);
337 $Value = $this->DB->UpdateValue(
"FolderItemInts",
"ItemNote", $NewValue,
338 "FolderId = ".intval($this->
Id)
339 .
" AND ItemId = ".intval($ItemId)
340 .
" AND ItemTypeId = ".intval($ItemTypeId),
343 $this->ItemNoteCache[self::GetCacheIndex($ItemId, $ItemTypeId)] = $Value;
356 $ItemTypeId = self::GetItemTypeId($ItemType);
357 return array_key_exists(self::GetCacheIndex($ItemId, $ItemTypeId),
358 $this->ItemNoteCache) ? TRUE : FALSE;
363 # ---- PRIVATE INTERFACE -------------------------------------------------
368 # folder attributes - these much match field names in Folders DB table
371 private $NormalizedName;
374 private $ContentType;
376 private $ItemNoteCache;
378 private $UpdateValueCache;
380 # item type IDs (indexed by normalized type name)
381 static private $ItemTypeIds;
382 # item type names (indexed by type ID)
383 static private $ItemTypeNames;
385 # content type that indicates folder contains mixed content types
395 static function GetItemTypeId($TypeName)
397 # return "no type" ID if null passed in
398 if ($TypeName === NULL) {
return -1; }
400 # make sure item type map is loaded
401 self::LoadItemTypeMap();
403 # normalize item type name
404 $NormalizedTypeName = strtoupper(
405 preg_replace(
"/[^a-zA-Z0-9]/",
"", $TypeName));
407 # if name not already mapped
408 if (!array_key_exists($NormalizedTypeName, self::$ItemTypeIds))
410 # add name to database
411 if (!isset($DB)) { $DB =
new Database(); }
412 $DB->Query(
"INSERT INTO FolderContentTypes SET"
413 .
" TypeName = '".addslashes($TypeName).
"',"
414 .
" NormalizedTypeName = '".addslashes($NormalizedTypeName).
"'");
416 # add name to cached mappings
417 $NewTypeId = $DB->LastInsertId();
418 self::$ItemTypeIds[$NormalizedTypeName] = $NewTypeId;
419 self::$ItemTypeNames[$NewTypeId] = $TypeName;
422 # return item type ID to caller
423 return self::$ItemTypeIds[$NormalizedTypeName];
432 private static function GetItemTypeName($TypeId)
434 # make sure item type map is loaded
435 self::LoadItemTypeMap();
437 # if ID not present in mappings
438 if (!array_key_exists($TypeId, self::$ItemTypeNames))
445 # return item type name to caller
446 return self::$ItemTypeNames[$TypeId];
454 private static function LoadItemTypeMap()
456 # if name-to-number item type map not already loaded
457 if (!isset(self::$ItemTypeIds))
459 # load item type map from database
461 $DB->Query(
"SELECT * FROM FolderContentTypes");
462 self::$ItemTypeIds = array();
463 self::$ItemTypeNames = array();
464 while ($Row = $DB->FetchRow())
466 self::$ItemTypeIds[$Row[
"NormalizedTypeName"]] = $Row[
"TypeId"];
467 self::$ItemTypeNames[$Row[
"TypeId"]] = $Row[
"TypeName"];
477 private function AddItem($ItemOrItemId, $ItemType)
479 # convert item to ID if necessary
480 $ItemId = is_object($ItemOrItemId)
481 ? $ItemOrItemId->Id() : $ItemOrItemId;
483 # convert item type to item type ID
484 $ItemTypeId = self::GetItemTypeId($ItemType);
486 # convert null item type to "no type" value used in database
487 if ($ItemTypeId === NULL) { $ItemTypeId = -1; }
489 # if resource is not already in folder
492 # add resource to folder locally
493 $this->ItemNoteCache[self::GetCacheIndex($ItemId, $ItemTypeId)] = NULL;
495 # add resource to folder in DB
496 $this->DB->Query(
"INSERT INTO FolderItemInts SET"
497 .
" FolderId = ".intval($this->
Id)
498 .
", ItemId = ".intval($ItemId)
499 .
", ItemTypeId = ".intval($ItemTypeId));
509 private static function GetCacheIndex($ItemId, $ItemTypeId)
511 $ItemTypeId = ($ItemTypeId === NULL) ? -1 : $ItemTypeId;
512 return intval($ItemTypeId).
":".intval($ItemId);
522 private function UpdateValue($FieldName, $NewValue)
524 $this->$FieldName = $this->DB->UpdateValue(
"Folders", $FieldName, $NewValue,
525 "FolderId = ".$this->
Id, $this->UpdateValueCache);
526 return $this->$FieldName;
NormalizedName($NewValue=DB_NOVALUE)
Get/set normalized version of folder name.
AppendItem($ItemOrItemId, $ItemType=NULL)
Add item to folder as the last item.
NoteForItem($ItemId, $NewValue=DB_NOVALUE, $ItemType=NULL)
Get/set note text for specific item within folder.
SQL database abstraction object with smart query caching.
IsShared($NewValue=DB_NOVALUE)
Get/set whether folder is publically-viewable.
GetItemIds()
Retrieve array of IDs of items in folder, in the order that they appear in the folder.
Factory object for Folder class, used to retrieve and manage Folders and groups of Folders...
Folder object used to create and manage groups of items.
RemoveItem($ItemId, $ItemType=NULL)
Remove item from folder, if present.
static NormalizeFolderName($Name)
Convert folder name to normalized form (lower-case alphanumeric only).
InsertItemAfter($TargetItemOrItemId, $NewItemOrItemId, $TargetItemType=NULL, $NewItemType=NULL)
Insert item into folder after specified item.
Note($NewValue=DB_NOVALUE)
Get/set note text for folder.
GetItemCount()
Get number of items in folder.
ContainsItem($ItemId, $ItemType=NULL)
Check whether specified item is contained in folder.
Folder($FolderId)
Object constructor – load an existing folder.
InsertItemBefore($TargetItemOrItemId, $NewItemOrItemId, $TargetItemType=NULL, $NewItemType=NULL)
Insert item into folder before specified item.
Persistent doubly-linked-list data structure, with its data stored in a specified database table...
OwnerId($NewValue=DB_NOVALUE)
Get/set user ID of folder owner.
PrependItem($ItemOrItemId, $ItemType=NULL)
Add item to folder as the first item.
Name($NewValue=DB_NOVALUE)
Get/set folder name.