CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

Classification.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: Classification.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2002-2016 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9
13 class Classification extends Item
14 {
15 # ---- PUBLIC INTERFACE --------------------------------------------------
16
18 const NOPARENT = -1;
19
31 public static function Create($Name, $FieldId, $ParentId = NULL)
32 {
33 static $IdCache;
34
35 # initialize state for creation
36 self::$SegmentsCreated = 0;
37
38 # if parent class supplied
39 $DB = new Database();
40 if ($ParentId !== NULL)
41 {
42 # error out if parent ID is invalid
43 if ($ParentId != self::NOPARENT)
44 {
45 if ($DB->Query("SELECT COUNT(*) AS NumberFound"
46 ." FROM Classifications"
47 ." WHERE ClassificationId = ".intval($ParentId),
48 "NumberFound") < 1)
49 {
50 throw new InvalidArgumentException("Invalid parent ID"
51 ." specified (".$ParentId.").");
52 }
53 }
54
55 # error out if name already exists
56 $Name = trim($Name);
57 $Count = $DB->Query("SELECT COUNT(*) AS NumberFound"
58 ." FROM Classifications"
59 ." WHERE ParentId = ".intval($ParentId)
60 ." AND FieldId = ".intval($FieldId)
61 ." AND LOWER(SegmentName) = '"
62 .addslashes(strtolower($Name))."'",
63 "NumberFound");
64 if ($Count > 0)
65 {
66 throw new Exception("Duplicate name specified for"
67 ." new classification (".$Name.").");
68 }
69
70 # determine full name and depth for new classification
71 if ($ParentId == self::NOPARENT)
72 {
73 $NewName = $Name;
74 $NewDepth = 0;
75 }
76 else
77 {
78 $DB->Query("SELECT ClassificationName, Depth"
79 ." FROM Classifications"
80 ." WHERE ClassificationId = ".intval($ParentId));
81 $ParentInfo = $DB->FetchRow();
82 $NewName = $ParentInfo["ClassificationName"]." -- ".$Name;
83 $NewDepth = $ParentInfo["Depth"] + 1;
84 }
85
86 # add classification to database
87 $InitialValues = array(
88 "FieldId" => $FieldId,
89 "ParentId" => $ParentId,
90 "SegmentName" => $Name,
91 "ResourceCount" => 0,
92 "Depth" => $NewDepth,
93 "ClassificationName" => $NewName);
94 $NewItem = parent::CreateWithValues($InitialValues);
95 }
96 else
97 {
98 # parse classification name into separate segments
99 $Segments = preg_split("/--/", $Name);
100
101 # start out with top as parent
102 $ParentId = self::NOPARENT;
103
104 # for each segment
105 $CurrentDepth = -1;
106 $CurrentFullName = "";
107 foreach ($Segments as $Segment)
108 {
109 # track segment depth and full classification name for use
110 # in adding new entries
111 $Segment = trim($Segment);
112 $CurrentDepth++;
113 $CurrentFullName .= (($CurrentFullName == "") ? "" : " -- ").$Segment;
114
115 # if we have added classifications
116 $Segment = addslashes($Segment);
117 if (self::$SegmentsCreated)
118 {
119 # we know that current segment will not be found
120 $ClassId = NULL;
121 }
122 else
123 {
124 # look up classification with current parent and segment name
125 if (!isset($IdCache[$FieldId][$ParentId][$Segment]))
126 {
127 if ($ParentId == self::NOPARENT)
128 {
129 $IdCache[$FieldId][$ParentId][$Segment] = $DB->Query(
130 "SELECT ClassificationId FROM Classifications"
131 ." WHERE ParentId = ".self::NOPARENT
132 ." AND SegmentName = '".addslashes($Segment)."'"
133 ." AND FieldId = ".intval($FieldId),
134 "ClassificationId");
135 }
136 else
137 {
138 $IdCache[$FieldId][$ParentId][$Segment] = $DB->Query(
139 "SELECT ClassificationId FROM Classifications "
140 ."WHERE ParentId = ".intval($ParentId)
141 ." AND SegmentName = '".addslashes($Segment)."'",
142 "ClassificationId");
143 }
144 }
145 $ClassId = $IdCache[$FieldId][$ParentId][$Segment];
146 }
147
148 # if classification not found
149 if ($ClassId === NULL)
150 {
151 # add new classification
152 $InitialValues = array(
153 "FieldId" => $FieldId,
154 "ParentId" => $ParentId,
155 "SegmentName" => $Segment,
156 "ResourceCount" => 0,
157 "Depth" => $CurrentDepth,
158 "ClassificationName" => $CurrentFullName);
159 $NewItem = parent::CreateWithValues($InitialValues);
160 $ClassId = $NewItem->Id();
161 $IdCache[$FieldId][$ParentId][$Segment] = $ClassId;
162
163 # track total number of new classification segments created
164 self::$SegmentsCreated++;
165 }
166
167 # set parent to created or found class
168 $ParentId = $ClassId;
169 }
170 }
171
172 # return new classification to caller
173 return new self($NewItem->Id());
174 }
175
180 public function Id()
181 {
182 return $this->Id;
183 }
184
189 public function FullName()
190 {
191 return $this->ValueCache["ClassificationName"];
192 }
193
198 public function Name()
199 {
200 return $this->FullName();
201 }
202
207 public function VariantName()
208 {
209 return NULL;
210 }
211
216 public function Depth()
217 {
218 return $this->ValueCache["Depth"];
219 }
220
226 public function ResourceCount()
227 {
228 return $this->ValueCache["ResourceCount"];
229 }
230
237 public function FullResourceCount()
238 {
239 return $this->ValueCache["FullResourceCount"];
240 }
241
246 public static function SegmentsCreated()
247 {
248 return self::$SegmentsCreated;
249 }
250
255 public function ParentId()
256 {
257 return $this->ValueCache["ParentId"];
258 }
259
265 public function SegmentName($NewValue = DB_NOVALUE)
266 {
267 return $this->UpdateValue("SegmentName", $NewValue);
268 }
269
277 public function LinkString($NewValue = DB_NOVALUE)
278 {
279 return $this->UpdateValue("LinkString", $NewValue);
280 }
281
288 public function QualifierId($NewValue = DB_NOVALUE)
289 {
290 return $this->UpdateValue("QualifierId", $NewValue);
291 }
292
298 public function FieldId($NewValue = DB_NOVALUE)
299 {
300 return $this->UpdateValue("FieldId", $NewValue);
301 }
302
309 public function Qualifier($NewValue = DB_NOVALUE)
310 {
311 # if new qualifier supplied
312 if ($NewValue !== DB_NOVALUE)
313 {
314 # set new qualifier ID
315 $this->QualifierId($NewValue->Id());
316
317 # use new qualifier for return value
318 $Qualifier = $NewValue;
319 }
320 else
321 {
322 # if qualifier is available
323 if ($this->QualifierId() !== NULL)
324 {
325 # create qualifier object using stored ID
326 $Qualifier = new Qualifier($this->QualifierId());
327 }
328 else
329 {
330 # return NULL to indicate no qualifier
331 $Qualifier = NULL;
332 }
333 }
334
335 # return qualifier to caller
336 return $Qualifier;
337 }
338
344 public function RecalcDepthAndFullName()
345 {
346 # start with full classification name set to our segment name
347 $FullClassName = $this->ValueCache["SegmentName"];
348
349 # assume to begin with that we're at the top of the hierarchy
350 $Depth = 0;
351
352 # while parent available
353 $ParentId = $this->ValueCache["ParentId"];
354 while ($ParentId != self::NOPARENT)
355 {
356 # retrieve classification information
357 $this->DB->Query("SELECT SegmentName, ParentId "
358 ."FROM Classifications "
359 ."WHERE ClassificationId=".$ParentId);
360 $Record = $this->DB->FetchRow();
361
362 # prepend segment name to full classification name
363 $FullClassName = $Record["SegmentName"]." -- ".$FullClassName;
364
365 # increment depth value
366 $Depth++;
367
368 # move to parent of current classification
369 $ParentId = $Record["ParentId"];
370 }
371
372 # for each child
373 $this->DB->Query("SELECT ClassificationId FROM Classifications"
374 ." WHERE ParentId = ".intval($this->Id));
375 while ($Record = $this->DB->FetchRow())
376 {
377 # perform depth and name recalc
378 $Child = new Classification($Record["ClassificationId"]);
379 $Child->RecalcDepthAndFullName();
380 }
381
382 # save new depth and full classification name
383 $this->UpdateValue("Depth", $Depth);
384 $this->UpdateValue("ClassificationName", $FullClassName);
385 }
386
390 public function UpdateLastAssigned()
391 {
392 $this->DB->Query("UPDATE Classifications SET LastAssigned=NOW() "
393 ."WHERE ClassificationId=".intval($this->Id));
394 }
395
403 public function RecalcResourceCount($IdsToSkip = NULL)
404 {
405 $IdsUpdated = array();
406
407 # if we don't have a skip list or we aren't in the skip list
408 if (!$IdsToSkip || !in_array($this->Id, $IdsToSkip))
409 {
410 # retrieve new count of resources directly associated with class
411 $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
412 ." FROM ResourceClassInts, Resources"
413 ." WHERE ClassificationId=".intval($this->Id)
414 ." AND ResourceClassInts.ResourceId = Resources.ResourceId"
415 ." AND Resources.ResourceId > 0"
416 ." AND ReleaseFlag = 1");
417 $Record = $this->DB->FetchRow();
418 $ResourceCount = $Record["ResourceCount"];
419
420 # add on resources associated with all children
421 $ResourceCount += $this->DB->Query(
422 "SELECT SUM(ResourceCount) AS ResourceCountTotal "
423 ."FROM Classifications "
424 ."WHERE ParentId = ".intval($this->Id),
425 "ResourceCountTotal");
426
427 # save new count
428 $this->UpdateValue("ResourceCount", $ResourceCount);
429
430 # add our ID to list of IDs that have been recalculated
431 $IdsUpdated[] = $this->Id;
432 }
433
434 # update resource count for our parent (if any)
435 if (($this->ValueCache["ParentId"] != self::NOPARENT)
436 && (!$IdsToSkip || !in_array($this->ValueCache["ParentId"], $IdsToSkip)) )
437 {
438 $Class = new Classification($this->ValueCache["ParentId"]);
439 $IdsUpdated = array_merge($IdsUpdated, $Class->RecalcResourceCount());
440 }
441
442 # retrieve new count of all resources directly associated with class
443 $FullCount = $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
444 ." FROM ResourceClassInts I, Resources R"
445 ." WHERE I.ClassificationId = ".intval($this->Id)
446 ." AND R.ResourceId > 0"
447 ." AND I.ResourceId = R.ResourceId",
448 "ResourceCount");
449
450 # add on resources associated with all children
451 $FullCount += $this->DB->Query(
452 "SELECT SUM(ResourceCount) AS ResourceCountTotal"
453 ." FROM Classifications"
454 ." WHERE ParentId = ".intval($this->Id),
455 "ResourceCountTotal");
456
457 # save new full count
458 $this->UpdateValue("FullResourceCount", $ResourceCount);
459
460 # return list of IDs of updated classifications to caller
461 return $IdsUpdated;
462 }
463
468 public function ChildCount()
469 {
470 # return count of classifications that have this one as parent
471 return $this->DB->Query("SELECT COUNT(*) AS ClassCount "
472 ."FROM Classifications "
473 ."WHERE ParentId=".intval($this->Id),
474 "ClassCount");
475 }
476
482 public function ChildList()
483 {
484 $ChildList = array();
485
486 $this->DB->Query("SELECT ClassificationId "
487 ."FROM Classifications "
488 ."WHERE ParentId=".intval($this->Id));
489
490 while ($Entry = $this->DB->FetchRow())
491 {
492 $ChildList[] = $Entry["ClassificationId"];
493 $Child = new Classification($Entry["ClassificationId"]);
494 if($Child->ChildCount() > 0)
495 {
496 $GrandChildList = $Child->ChildList();
497 $ChildList = array_merge($GrandChildList, $ChildList);
498 }
499 }
500 return array_unique($ChildList);
501 }
502
516 public function Delete($DeleteParents = FALSE,
517 $DeleteIfHasResources = FALSE, $DeleteIfHasChildren = FALSE)
518 {
519 # if no resources or okay to delete with resources
520 # and no children or okay to delete with children
521 $DeleteCount = 0;
522 if (($DeleteIfHasResources || ($this->ResourceCount() == 0))
523 && ($DeleteIfHasChildren || ($this->ChildCount() == 0)))
524 {
525 if ($this->ResourceCount() != 0)
526 {
527 $this->DB->Query("DELETE FROM ResourceClassInts"
528 ." WHERE ClassificationId = ".intval($this->Id));
529 $this->RecalcResourceCount();
530 }
531
532 # delete this classification
533 parent::Delete();
534 $DeleteCount++;
535
536 # delete parent classification (if requested)
537 $ParentId = $this->ValueCache["ParentId"];
538 if (($DeleteParents) && ($ParentId != self::NOPARENT))
539 {
540 $Parent = new Classification($ParentId);
541 $DeleteCount += $Parent->Delete(
542 TRUE, $DeleteIfHasResources, $DeleteIfHasChildren);
543 }
544 }
545
546 # return total number of classifications deleted to caller
547 return $DeleteCount;
548 }
549
550
551 # ---- PRIVATE INTERFACE -------------------------------------------------
552
553 static private $SegmentsCreated;
554 }
Classification\LinkString
LinkString($NewValue=DB_NOVALUE)
Get or set the stored link string for the Classification.
Definition: Classification.php:277
Classification\SegmentsCreated
static SegmentsCreated()
Get number of new segments (Classifications) generated when creating a new Classification with a full...
Definition: Classification.php:246
Classification\FullName
FullName()
Get full classification name (all segments).
Definition: Classification.php:189
Classification\FullResourceCount
FullResourceCount()
Get number of all resources (minus temporary ones) having this classification assigned to them...
Definition: Classification.php:237
Item\UpdateValue
UpdateValue($ColumnName, $NewValue=DB_NOVALUE)
Convenience function to supply parameters to Database->UpdateValue().
Definition: Item.php:189
Database
SQL database abstraction object with smart query caching.
Definition: Database.php:22
Classification\Create
static Create($Name, $FieldId, $ParentId=NULL)
Add new classification to the hierarchy.
Definition: Classification.php:31
Classification\FieldId
FieldId($NewValue=DB_NOVALUE)
Get or set the ID of the MetadataField for the Classification.
Definition: Classification.php:298
Classification\VariantName
VariantName()
Get variant name of classification, if any.
Definition: Classification.php:207
Item\$DB
$DB
Definition: Item.php:115
Classification\Qualifier
Qualifier($NewValue=DB_NOVALUE)
Get or set the Qualifier associated with the Classification.
Definition: Classification.php:309
Classification\ChildCount
ChildCount()
Get number of classifications that have this Classification as their direct parent.
Definition: Classification.php:468
Classification\RecalcResourceCount
RecalcResourceCount($IdsToSkip=NULL)
Recalculate number of resources assigned to class and any parent classes.
Definition: Classification.php:403
Classification\NOPARENT
const NOPARENT
Parent value for classifications with no parent.
Definition: Classification.php:18
Classification\Name
Name()
Get name of classification segment.
Definition: Classification.php:198
Classification\ParentId
ParentId()
Get ID of parent Classification.
Definition: Classification.php:255
Classification\RecalcDepthAndFullName
RecalcDepthAndFullName()
Rebuild classification full name and recalculate depth in hierarchy.
Definition: Classification.php:344
PHP
PHP
Definition: RSSClient--Test.php:12
Item
Common base class for persistent items store in database.
Definition: Item.php:13
DB_NOVALUE
const DB_NOVALUE
Definition: Database.php:1541
Classification\Depth
Depth()
Get depth of classification in hierarchy.
Definition: Classification.php:216
Classification\ResourceCount
ResourceCount()
Get number of released resources having this classification assigned to them.
Definition: Classification.php:226
Item\$Id
$Id
Definition: Item.php:116
Classification\Delete
Delete($DeleteParents=FALSE, $DeleteIfHasResources=FALSE, $DeleteIfHasChildren=FALSE)
Remove Classification (and accompanying associations) from database.
Definition: Classification.php:516
Classification\UpdateLastAssigned
UpdateLastAssigned()
Update the LastAssigned timestamp for this classification.
Definition: Classification.php:390
Classification
Metadata type representing hierarchical ("Tree") controlled vocabulary values.
Definition: Classification.php:13
Classification\QualifierId
QualifierId($NewValue=DB_NOVALUE)
Get or set the Qualifier associated with the Classification by ID.
Definition: Classification.php:288
Classification\ChildList
ChildList()
Get list of IDs of Classifications that have this class as an "ancestor" (parent, grandparent...
Definition: Classification.php:482
Classification\SegmentName
SegmentName($NewValue=DB_NOVALUE)
Get or set the segment name.
Definition: Classification.php:265
Classification\Id
Id()
Get Classification ID.
Definition: Classification.php:180