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-2013 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9
13 class Classification {
14
15 # ---- PUBLIC INTERFACE --------------------------------------------------
16
18 const CLASSSTAT_OK = 0;
20 const CLASSSTAT_INVALIDID = 1;
22 const CLASSSTAT_INVALIDPARENTID = 2;
24 const CLASSSTAT_DUPLICATENAME = 3;
25
42 function Classification($ClassId, $Name = NULL, $FieldId = NULL, $ParentId = NULL)
43 {
44 static $IdCache;
45
46 # assume everything will turn out okay
47 $this->ErrorStatus = self::CLASSSTAT_OK;
48
49 # create DB handle for our use
50 $this->DB = new Database();
51 $DB = $this->DB;
52
53 # if class ID not given (indicating class must be created)
54 if ($ClassId === NULL)
55 {
56 # if parent class supplied
57 if ($ParentId !== NULL)
58 {
59 # if parent ID was invalid
60 if (($ParentId != -1)
61 && ($DB->Query("SELECT COUNT(*) AS NumberFound"
62 ." FROM Classifications"
63 ." WHERE ClassificationId = ".intval($ParentId),
64 "NumberFound") < 1))
65 {
66 # set error code for bad parent ID
67 $this->ErrorStatus = self::CLASSSTAT_INVALIDPARENTID;
68 }
69 else
70 {
71 # if name already exists
72 $Name = trim($Name);
73 if ($FieldId === NULL)
74 {
75 # If we know what field we're trying to add a classifcation for,
76 # Check just within that field
77 $Count = $DB->Query("SELECT COUNT(*) AS NumberFound FROM Classifications"
78 ." WHERE ParentId = ".intval($ParentId)
79 ." AND LOWER(SegmentName) = '"
80 .addslashes(strtolower($Name))."'",
81 "NumberFound");
82 }
83 else
84 {
85 # Otherwise, check all classifications for all fields
86 $Count = $DB->Query("SELECT COUNT(*) AS NumberFound FROM Classifications"
87 ." WHERE ParentId = ".intval($ParentId)
88 ." AND FieldId = ".intval($FieldId)
89 ." AND LOWER(SegmentName) = '"
90 .addslashes(strtolower($Name))."'",
91 "NumberFound");
92 }
93
94 if ($Count > 0)
95 {
96 # set error code for duplicate class name
97 $this->ErrorStatus = self::CLASSSTAT_DUPLICATENAME;
98 }
99 else
100 {
101 # add class to database
102 $ParentId = intval($ParentId);
103 if ($ParentId == -1)
104 {
105 $NewName = $Name;
106 $NewDepth = 0;
107 }
108 else
109 {
110 $DB->Query("SELECT ClassificationName, Depth"
111 ." FROM Classifications"
112 ." WHERE ClassificationId = ".$ParentId);
113 $ParentInfo = $DB->FetchRow();
114 $NewName = $ParentInfo["ClassificationName"]." -- ".$Name;
115 $NewDepth = $ParentInfo["Depth"] + 1;
116 }
117 $DB->Query("INSERT INTO Classifications"
118 ." (FieldId, ParentId, SegmentName, ResourceCount,"
119 ." Depth, ClassificationName) VALUES"
120 ." (".intval($FieldId).", ".$ParentId.","
121 ." '".addslashes($Name)."', 0, "
122 .$NewDepth.", '".addslashes($NewName)."')");
123
124 # retrieve ID of new class
125 $this->Id = $DB->LastInsertId();
126 }
127 }
128 }
129 else
130 {
131 # parse classification name into separate segments
132 $Segments = preg_split("/--/", $Name);
133
134 # start out with top as parent
135 $ParentId = -1;
136
137 # for each segment
138 $CurrentDepth = -1;
139 $CurrentFullName = "";
140 foreach ($Segments as $Segment)
141 {
142 # track segment depth and full classification name for use in adding new entries
143 $Segment = trim($Segment);
144 $CurrentDepth++;
145 $CurrentFullName .= (($CurrentFullName == "") ? "" : " -- ").$Segment;
146
147 # if we have added classifications
148 $Segment = addslashes($Segment);
149 if ($this->SegmentsCreated)
150 {
151 # we know that current segment will not be found
152 $ClassId = NULL;
153 }
154 else
155 {
156 # look up classification with current parent and segment name
157 if (!isset($IdCache[$FieldId][$ParentId][$Segment]))
158 {
159 if ($ParentId == -1)
160 {
161 $IdCache[$FieldId][$ParentId][$Segment] = $DB->Query(
162 "SELECT ClassificationId FROM Classifications"
163 ." WHERE ParentId = -1"
164 ." AND SegmentName = '".addslashes($Segment)."'"
165 ." AND FieldId = ".intval($FieldId),
166 "ClassificationId");
167 }
168 else
169 {
170 $IdCache[$FieldId][$ParentId][$Segment] = $DB->Query(
171 "SELECT ClassificationId FROM Classifications "
172 ."WHERE ParentId = ".intval($ParentId)
173 ." AND SegmentName = '".addslashes($Segment)."'",
174 "ClassificationId");
175 }
176 }
177 $ClassId = $IdCache[$FieldId][$ParentId][$Segment];
178 }
179
180 # if classification not found
181 if ($ClassId === NULL)
182 {
183 # add new classification
184 $DB->Query("INSERT INTO Classifications "
185 ."(FieldId, ParentId, SegmentName,"
186 ." ClassificationName, Depth, ResourceCount) "
187 ."VALUES (".intval($FieldId).", "
188 .intval($ParentId).", "
189 ."'".addslashes($Segment)."', "
190 ."'".addslashes($CurrentFullName)."', "
191 .intval($CurrentDepth).", 0)");
192 $ClassId = $DB->LastInsertId();
193 $IdCache[$FieldId][$ParentId][$Segment] = $ClassId;
194
195 # track total number of new classification segments created
196 $this->SegmentsCreated++;
197 }
198
199 # set parent to created or found class
200 $PreviousParentId = $ParentId;
201 $ParentId = $ClassId;
202 }
203
204 # our class ID is the one that was last found
205 $this->Id = $ClassId;
206 }
207 }
208 else
209 {
210 # our class ID is the one that was supplied by caller
211 $this->Id = intval($ClassId);
212 }
213
214 # if no error encountered
215 if ($this->ErrorStatus == self::CLASSSTAT_OK)
216 {
217 # load in attributes from database
218 $DB->Query("SELECT * FROM Classifications"
219 ." WHERE ClassificationId = ".intval($this->Id));
220 $this->DBFields = $DB->NumRowsSelected()>0 ? $DB->FetchRow() : NULL ;
221
222 # set error status if class info not loaded
223 if ($this->DBFields === NULL ||
224 $this->DBFields["ClassificationId"] != $this->Id)
225 {
226 $this->ErrorStatus = self::CLASSSTAT_INVALIDID;
227 }
228 }
229 }
230
235 function Status() { return $this->ErrorStatus; }
236
241 function Id() { return $this->Id; }
242
247 function FullName()
248 {
249 return $this->DBFields["ClassificationName"];
250 }
251
256 function Name() { return $this->FullName(); }
257
262 function VariantName() { return NULL; }
263
268 function Depth() { return $this->DBFields["Depth"]; }
269
275 function ResourceCount() { return $this->DBFields["ResourceCount"]; }
276
283 function FullResourceCount() { return $this->DBFields["FullResourceCount"]; }
284
289 function SegmentsCreated() { return $this->SegmentsCreated; }
290
295 function ParentId() { return $this->DBFields["ParentId"]; }
296
302 function SegmentName($NewValue = DB_NOVALUE) {
303 return $this->UpdateValue("SegmentName", $NewValue); }
304
312 function LinkString($NewValue = DB_NOVALUE) {
313 return $this->UpdateValue("LinkString", $NewValue); }
314
321 function QualifierId($NewValue = DB_NOVALUE) {
322 return $this->UpdateValue("QualifierId", $NewValue); }
323
329 function FieldId($NewValue = DB_NOVALUE) {
330 return $this->UpdateValue("FieldId", $NewValue); }
331
338 function Qualifier($NewValue = DB_NOVALUE)
339 {
340 # if new qualifier supplied
341 if ($NewValue !== DB_NOVALUE)
342 {
343 # set new qualifier ID
344 $this->QualifierId($NewValue->Id());
345
346 # use new qualifier for return value
347 $Qualifier = $NewValue;
348 }
349 else
350 {
351 # if qualifier is available
352 if ($this->QualifierId() !== NULL)
353 {
354 # create qualifier object using stored ID
355 $Qualifier = new Qualifier($this->QualifierId());
356 }
357 else
358 {
359 # return NULL to indicate no qualifier
360 $Qualifier = NULL;
361 }
362 }
363
364 # return qualifier to caller
365 return $Qualifier;
366 }
367
373 function RecalcDepthAndFullName()
374 {
375 $DB = $this->DB;
376
377 # start with full classification name set to our segment name
378 $FullClassName = $this->DBFields["SegmentName"];
379
380 # assume to begin with that we're at the top of the hierarchy
381 $Depth = 0;
382
383 # while parent available
384 $ParentId = $this->DBFields["ParentId"];
385 while ($ParentId != -1)
386 {
387 # retrieve classification information
388 $DB->Query("SELECT SegmentName, ParentId "
389 ."FROM Classifications "
390 ."WHERE ClassificationId=".$ParentId);
391 $Record = $DB->FetchRow();
392
393 # prepend segment name to full classification name
394 $FullClassName = $Record["SegmentName"]." -- ".$FullClassName;
395
396 # increment depth value
397 $Depth++;
398
399 # move to parent of current classification
400 $ParentId = $Record["ParentId"];
401 }
402
403 # for each child
404 $DB->Query("SELECT ClassificationId "
405 ."FROM Classifications "
406 ."WHERE ParentId=".intval($this->Id));
407 while ($Record = $DB->FetchRow())
408 {
409 # perform depth and name recalc
410 $Child = new Classification($Record["ClassificationId"]);
411 $Child->RecalcDepthAndFullName();
412 }
413
414 # save new depth and full classification name
415 $DB->Query("UPDATE Classifications SET "
416 ."Depth=".intval($Depth).", "
417 ."ClassificationName='".addslashes($FullClassName)."' "
418 ."WHERE ClassificationId=".intval($this->Id));
419 $this->DBFields["ClassificationName"] = $FullClassName;
420 $this->DBFields["Depth"] = $Depth;
421 }
422
426 function UpdateLastAssigned()
427 {
428 $this->DB->Query("UPDATE Classifications SET LastAssigned=NOW() "
429 ."WHERE ClassificationId=".intval($this->Id));
430 }
431
439 function RecalcResourceCount($IdsToSkip = NULL)
440 {
441 $IdsUpdated = array();
442
443 # if we don't have a skip list or we aren't in the skip list
444 if (!$IdsToSkip || !in_array($this->Id, $IdsToSkip))
445 {
446 # retrieve new count of resources directly associated with class
447 $this->DB->Query("SELECT COUNT(*) AS ResourceCount"
448 ." FROM ResourceClassInts, Resources"
449 ." WHERE ClassificationId=".intval($this->Id)
450 ." AND ResourceClassInts.ResourceId = Resources.ResourceId"
451 ." AND Resources.ResourceId > 0"
452 ." AND ReleaseFlag = 1");
453 $Record = $this->DB->FetchRow();
454 $ResourceCount = $Record["ResourceCount"];
455
456 # add on resources associated with all children
457 $ResourceCount += $this->DB->Query(
458 "SELECT SUM(ResourceCount) AS ResourceCountTotal "
459 ."FROM Classifications "
460 ."WHERE ParentId = ".intval($this->Id),
461 "ResourceCountTotal");
462
463 # save new count to database
464 $this->DB->Query("UPDATE Classifications SET "
465 ."ResourceCount=".$ResourceCount." "
466 ."WHERE ClassificationId=".intval($this->Id));
467
468 # save new count to our local cache
469 $this->DBFields["ResourceCount"] = $ResourceCount;
470
471 # add our ID to list of IDs that have been recalculated
472 $IdsUpdated[] = $this->Id;
473 }
474
475 # update resource count for our parent (if any)
476 if (($this->DBFields["ParentId"] != -1)
477 && (!$IdsToSkip || !in_array($this->DBFields["ParentId"], $IdsToSkip)) )
478 {
479 $Class = new Classification($this->DBFields["ParentId"]);
480 if ($Class->Status() == self::CLASSSTAT_OK)
481 {
482 $IdsUpdated = array_merge($IdsUpdated, $Class->RecalcResourceCount());
483 }
484 }
485
486 # retrieve new count of all resources directly associated with class
487 $FullCount = $this->DB->Query("
488 SELECT COUNT(*) AS ResourceCount
489 FROM ResourceClassInts I, Resources R
490 WHERE I.ClassificationId = '".intval($this->Id)."'
491 AND R.ResourceId > 0
492 AND I.ResourceId = R.ResourceId",
493 "ResourceCount");
494
495 # add on resources associated with all children
496 $FullCount += $this->DB->Query("
497 SELECT SUM(ResourceCount) AS ResourceCountTotal
498 FROM Classifications
499 WHERE ParentId = '".intval($this->Id)."'",
500 "ResourceCountTotal");
501
502 # save new count to database
503 $this->DB->Query("
504 UPDATE Classifications
505 SET FullResourceCount = '".intval($FullCount)."'
506 WHERE ClassificationId = '".intval($this->Id)."'");
507
508 # save new count to our local cache
509 $this->DBFields["FullResourceCount"] = $FullCount;
510
511 # return list of IDs of updated classifications to caller
512 return $IdsUpdated;
513 }
514
519 function ChildCount()
520 {
521 # return count of classifications that have this one as parent
522 return $this->DB->Query("SELECT COUNT(*) AS ClassCount "
523 ."FROM Classifications "
524 ."WHERE ParentId=".intval($this->Id),
525 "ClassCount");
526 }
527
533 function ChildList()
534 {
535 $ChildList = array();
536
537 $this->DB->Query("SELECT ClassificationId "
538 ."FROM Classifications "
539 ."WHERE ParentId=".intval($this->Id));
540
541 while ($Entry = $this->DB->FetchRow())
542 {
543 $ChildList[] = $Entry["ClassificationId"];
544 $Child = new Classification($Entry["ClassificationId"]);
545 if($Child->ChildCount() > 0)
546 {
547 $GrandChildList = $Child->ChildList();
548 $ChildList = array_merge($GrandChildList, $ChildList);
549 }
550 }
551 return array_unique($ChildList);
552 }
553
566 function Delete($DeleteParents = FALSE,
567 $DeleteIfHasResources = FALSE, $DeleteIfHasChildren = FALSE)
568 {
569 $DB = $this->DB;
570
571 # if no resources or okay to delete with resources
572 # and no children or okay to delete with children
573 if (($DeleteIfHasResources || ($this->ResourceCount() == 0))
574 && ($DeleteIfHasChildren || ($this->ChildCount() == 0)))
575 {
576 $ParentId = $this->DBFields["ParentId"];
577
578 if ($DeleteIfHasResources)
579 {
580 $DB->Query("DELETE FROM ResourceClassInts "
581 ."WHERE ClassificationId=".intval($this->Id));
582 $this->RecalcResourceCount();
583 }
584 # delete this classification
585 $DB->Query("DELETE FROM Classifications "
586 ."WHERE ClassificationId=".intval($this->Id));
587
588 # delete parent classification (if requested)
589 if (($DeleteParents) && ($this->DBFields["ParentId"] != -1))
590 {
591 $Parent = new Classification($this->DBFields["ParentId"]);
592 $Parent->Delete(
593 TRUE, $DeleteIfHasResources, $DeleteIfHasChildren);
594 }
595 }
596 }
597
598
599 # ---- PRIVATE INTERFACE -------------------------------------------------
600
601 private $DB;
602 private $DBFields;
603 private $Id;
604 private $ErrorStatus;
605 private $SegmentsCreated;
606
614 private function UpdateValue($FieldName, $NewValue)
615 {
616 return $this->DB->UpdateValue("Classifications", $FieldName, $NewValue,
617 "ClassificationId = ".intval($this->Id),
618 $this->DBFields, TRUE);
619 }
620 }
Classification\LinkString
LinkString($NewValue=DB_NOVALUE)
Get or set the stored link string for the Classification.
Definition: Classification.php:312
Classification\CLASSSTAT_INVALIDPARENTID
const CLASSSTAT_INVALIDPARENTID
Status code indicating an invalid parent classification ID was specified.
Definition: Classification.php:22
Classification\FullName
FullName()
Get full classification name (all segments).
Definition: Classification.php:247
Classification\FullResourceCount
FullResourceCount()
Get number of all resources (minus temporary ones) having this classification assigned to them...
Definition: Classification.php:283
Database
SQL database abstraction object with smart query caching.
Definition: Axis--Database.php:22
Classification\CLASSSTAT_INVALIDID
const CLASSSTAT_INVALIDID
Status code indicating an invalid classification ID was specified.
Definition: Classification.php:20
DB_NOVALUE
const DB_NOVALUE
Definition: Axis--Database.php:1331
Classification\FieldId
FieldId($NewValue=DB_NOVALUE)
Get or set the ID of the MetadataField for the Classification.
Definition: Classification.php:329
Classification\VariantName
VariantName()
Get variant name of classification, if any.
Definition: Classification.php:262
Classification\Qualifier
Qualifier($NewValue=DB_NOVALUE)
Get or set the Qualifier associated with the Classification.
Definition: Classification.php:338
Classification\ChildCount
ChildCount()
Get number of classifications that have this Classification as their direct parent.
Definition: Classification.php:519
Classification\Classification
Classification($ClassId, $Name=NULL, $FieldId=NULL, $ParentId=NULL)
Class constructor.
Definition: Classification.php:42
Classification\RecalcResourceCount
RecalcResourceCount($IdsToSkip=NULL)
Recalculate number of resources assigned to class and any parent classes.
Definition: Classification.php:439
Classification\Name
Name()
Get name of classification segment.
Definition: Classification.php:256
Classification\ParentId
ParentId()
Get ID of parent Classification.
Definition: Classification.php:295
Classification\SegmentsCreated
SegmentsCreated()
Get number of new segments (Classifications) generated when creating a new Classification with a full...
Definition: Classification.php:289
Classification\RecalcDepthAndFullName
RecalcDepthAndFullName()
Rebuild classification full name and recalculate depth in hierarchy.
Definition: Classification.php:373
PHP
PHP
Definition: RSSClient--Test.php:12
Classification\Status
Status()
Returns success/failure code for last call (where applicable).
Definition: Classification.php:235
Classification\Depth
Depth()
Get depth of classification in hierarchy.
Definition: Classification.php:268
Classification\CLASSSTAT_DUPLICATENAME
const CLASSSTAT_DUPLICATENAME
Status code indicating a duplicate classification name was specified.
Definition: Classification.php:24
Classification\ResourceCount
ResourceCount()
Get number of released resources having this classification assigned to them.
Definition: Classification.php:275
Classification\Delete
Delete($DeleteParents=FALSE, $DeleteIfHasResources=FALSE, $DeleteIfHasChildren=FALSE)
Remove Classification (and accompanying associations) from database.
Definition: Classification.php:566
Classification\CLASSSTAT_OK
const CLASSSTAT_OK
Status code indicating operation completed successfully.
Definition: Classification.php:18
Classification\UpdateLastAssigned
UpdateLastAssigned()
Update the LastAssigned timestamp for this classification.
Definition: Classification.php:426
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:321
Classification\ChildList
ChildList()
Get list of IDs of Classifications that have this class as an "ancestor" (parent, grandparent...
Definition: Classification.php:533
Classification\SegmentName
SegmentName($NewValue=DB_NOVALUE)
Get or set the segment name.
Definition: Classification.php:302
Classification\Id
Id()
Get Classification ID.
Definition: Classification.php:241