CWIS Developer Documentation

- Home
- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

ItemListUI.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: ItemListUI.php
4 #
5 # Part of the Collection Workflow Integration System (CWIS)
6 # Copyright 2016 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu/cwis/
8 #
9
13 class ItemListUI
14 {
15
16 # ---- PUBLIC INTERFACE --------------------------------------------------
17
42 public function __construct($Fields, $SchemaId = TransportControlsUI::NO_ITEM_TYPE)
43 {
44 # normalize and save field info
45 if ($SchemaId == TransportControlsUI::NO_ITEM_TYPE)
46 {
47 $this->Fields = $Fields;
48 }
49 else
50 {
51 $this->Fields = array();
52 foreach ($Fields as $FieldId => $FieldInfo)
53 {
54 $CanonicalId = MetadataSchema::GetCanonicalFieldIdentifier($FieldId);
55 $this->Fields[$CanonicalId] = $FieldInfo;
56 }
57 }
58
59 # set default base link
60 $this->BaseLink = "index.php?P=".$GLOBALS["AF"]->GetPageName();
61
62 # save schema ID for later use
63 $this->SchemaId = $SchemaId;
64
65 # set up transport controls
66 foreach ($this->Fields as $FieldId => $FieldInfo)
67 {
68 if (isset($FieldInfo["DefaultSortField"]))
69 {
70 TransportControlsUI::DefaultSortField($FieldId);
71 }
72 }
73 $this->TransportUI = new TransportControlsUI($this->SchemaId);
74 $this->TransportUI->ItemsPerPage($this->ItemsPerPage);
75 }
76
84 public function BaseLink($NewValue = NULL)
85 {
86 if ($NewValue !== NULL)
87 {
88 $this->BaseLink = $NewValue;
89 }
90 return $this->BaseLink;
91 }
92
99 public function VariablesToPreserve($NewValue = NULL)
100 {
101 if ($NewValue !== NULL)
102 {
103 $this->VariablesToPreserve = $NewValue;
104 }
105 return $this->VariablesToPreserve;
106 }
107
112 public function GetFullBaseLink()
113 {
114 $Link = $this->BaseLink;
115 foreach ($this->VariablesToPreserve as $VarName)
116 {
117 if (isset($_GET[$VarName]))
118 {
119 $Link .= "&amp;".$VarName."=".urlencode($_GET[$VarName]);
120 }
121 }
122 return $Link;
123 }
124
130 public function Heading($NewValue = NULL)
131 {
132 if ($NewValue !== NULL)
133 {
134 $this->Heading = $NewValue;
135 }
136 return $this->Heading;
137 }
138
144 public function ItemsPerPage($NewValue = NULL)
145 {
146 if ($NewValue !== NULL)
147 {
148 $this->ItemsPerPage = $NewValue;
149 $this->TransportUI->ItemsPerPage($this->ItemsPerPage);
150 }
151 return $this->ItemsPerPage;
152 }
153
161 public function AddTopButton($Label, $Link, $Icon = NULL)
162 {
163 $this->Buttons[] = array(
164 "Label" => $Label,
165 "Link" => $Link,
166 "Icon" => $Icon);
167 }
168
180 public function AddTopCheckbox($Label, $Checked, $VarName, $Link)
181 {
182 if (strpos($Link, $VarName."=") !== FALSE)
183 {
184 $Link = preg_replace("/(&|&amp;)".preg_quote($VarName)."=[^&]*/",
185 "", $Link);
186 }
187 $this->Buttons[] = array(
188 "Label" => $Label,
189 "Checked" => $Checked,
190 "VarName" => $VarName,
191 "Link" => $Link);
192 }
193
211 public function AddActionButton(
212 $Label, $Link, $Icon = NULL, $DisplayTestFunc = NULL,
213 $AdditionalAttributes = array())
214 {
215 $this->Actions[] = array(
216 "Label" => $Label,
217 "Link" => $Link,
218 "Icon" => $Icon,
219 "TestFunc" => $DisplayTestFunc,
220 "AddAttribs" => $AdditionalAttributes);
221 }
222
228 public function NoItemsMessage($NewValue = NULL)
229 {
230 if ($NewValue !== NULL)
231 {
232 $this->NoItemsMsg = $NewValue;
233 }
234 return $this->NoItemsMsg;
235 }
236
241 public function &TransportUI()
242 {
243 return $this->TransportUI;
244 }
245
260 public function Display($Items, $TotalItemCount = NULL,
261 $StartingIndex = NULL, $TransportMsg = NULL)
262 {
263 # retrieve context values from transport controls
264 $StartingIndex = $this->TransportUI->StartingIndex($StartingIndex);
265 $SortFieldId = $this->TransportUI->SortField();
266 $ReverseSort = $this->TransportUI->ReverseSortFlag();
267
268 # display buttons above list
269 $this->DisplayTopButtons();
270
271 # display heading
272 if (isset($this->Heading) && ($this->Heading !== NULL))
273 {
274 if ($this->Heading == strip_tags($this->Heading))
275 {
276 print "<h1>".$this->Heading."</h1>\n";
277 }
278 else
279 {
280 print $this->Heading."\n";
281 }
282 }
283
284 # display "no items" message and exit if no items
285 if (count($Items) == 0)
286 {
287 $this->DisplayNoItemsMessage();
288 return;
289 }
290
291 # begin item table
292 print '<table class="cw-table cw-table-sideheaders cw-table-fullsize
293 cw-table-padded cw-table-striped">';
294
295 # begin header row
296 print "<thead><tr>";
297
298 # for each field
299 foreach ($this->Fields as $FieldId => $FieldInfo)
300 {
301 # if header value supplied
302 if (isset($FieldInfo["Heading"]))
303 {
304 # use supplied value
305 $Heading = $FieldInfo["Heading"];
306 }
307 # else if we can get header from schema
308 elseif ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
309 {
310 # use name of field (with any leading schema name stripped)
311 $Heading = MetadataSchema::GetPrintableFieldName($FieldId);
312 $Heading = preg_replace("/.+\: /", "", $Heading);
313 }
314 # else if field ID appears like it may be a name
315 elseif (is_string($FieldId) && !is_numeric($FieldId))
316 {
317 $Heading = $FieldId;
318 }
319 else
320 {
321 $Heading = "(NO HEADER SET)";
322 }
323
324 # if sorting is disabled for field
325 if (isset($FieldInfo["NoSorting"]))
326 {
327 # print header
328 print "<th>".$Heading."</th>\n";
329 }
330 else
331 {
332 # build sort link
333 $SortLink = $this->GetFullBaseLink()."&amp;SF=".$FieldId
334 .$this->TransportUI->UrlParameterString(TRUE, array("SF", "RS"));
335
336 # determine current sort direction
337 if (isset($FieldInfo["DefaultToDescendingSort"]))
338 {
339 $SortAscending = $ReverseSort ? TRUE : FALSE;
340 }
341 else
342 {
343 $SortAscending = $ReverseSort ? FALSE : TRUE;
344 }
345
346 # set sort direction indicator (if any)
347 if ($FieldId == $SortFieldId)
348 {
349 $DirIndicator = ($SortAscending) ? "&uarr;" : "&darr;";
350 if (!$ReverseSort)
351 {
352 $SortLink .= "&amp;RS=1";
353 }
354 }
355 else
356 {
357 $DirIndicator = "";
358 }
359
360 # print header
361 print "<th><a href=\"".$SortLink."\">".$Heading."</a>"
362 .$DirIndicator."</th>\n";
363 }
364 }
365
366 # add action header if needed
367 if (is_array($this->Actions) && count($this->Actions))
368 {
369 print "<th>Actions</th>\n";
370 }
371
372 # end header row
373 print "</tr></thead>\n";
374
375 # for each item
376 print "<tbody>\n";
377 foreach ($Items as $ItemId => $Item)
378 {
379 # start row
380 print "<tr>\n";
381
382 # for each field
383 foreach ($this->Fields as $FieldId => $FieldInfo)
384 {
385 # if there is value function defined for field
386 if (isset($FieldInfo["ValueFunction"]))
387 {
388 # call function for value
389 $Value = $FieldInfo["ValueFunction"]($Item, $FieldId);
390 }
391 else
392 {
393 # if item is associative array
394 if (is_array($Item))
395 {
396 # retrieve value for field (if any) from item
397 $Value = isset($Item[$FieldId])
398 ? $Item[$FieldId] : "";
399 }
400 # else if field ID is item method
401 elseif (method_exists($Item, $FieldId))
402 {
403 # get field value via item method
404 $Value = $Item->$FieldId();
405 }
406 else
407 {
408 # get field value from item via Get()
409 $Values = $Item->Get($FieldId);
410 $Value = is_array($Values) ? array_shift($Values) : $Values;
411 }
412
413 # if max length specified for field
414 if (isset($FieldInfo["MaxLength"]))
415 {
416 $Value = StdLib::NeatlyTruncateString(
417 $Value, $FieldInfo["MaxLength"]);
418 }
419
420 # encode any HTML-significant chars in value
421 if (!isset($FieldInfo["AllowHTML"]))
422 {
423 $Value = htmlspecialchars($Value);
424 }
425 }
426
427 # get link value (if any)
428 if (isset($FieldInfo["Link"]))
429 {
430 if (method_exists($Item, "Id"))
431 {
432 $Link = preg_replace('/\$ID/', $Item->Id(),
433 $FieldInfo["Link"]);
434 }
435 else
436 {
437 $Link = preg_replace('/\$ID/', $ItemId,
438 $FieldInfo["Link"]);
439 }
440 $LinkStart = '<a href="'.$Link.'">';
441 $LinkEnd = "</a>";
442 }
443 elseif (isset($FieldInfo["LinkFunction"]))
444 {
445 $Link = $FieldInfo["LinkFunction"]($Item);
446 if (!strlen($Link))
447 {
448 $LinkStart = "";
449 $LinkEnd = "";
450 }
451 else
452 {
453 if (method_exists($Item, "Id"))
454 {
455 $Link = preg_replace('/\$ID/', $Item->Id(),
456 $Link);
457 }
458 else
459 {
460 $Link = preg_replace('/\$ID/', $ItemId,
461 $Link);
462 }
463 $LinkStart = '<a href="'.$Link.'">';
464 $LinkEnd = "</a>";
465 }
466 }
467 else
468 {
469 $LinkStart = "";
470 $LinkEnd = "";
471 }
472
473 # display cell with value
474 print "<td>".$LinkStart.$Value.$LinkEnd."</td>\n";
475 }
476
477 # add action buttons
478 if (is_array($this->Actions) && count($this->Actions))
479 {
480 print "<td>";
481 $this->DisplayActionButtons($ItemId, $Item);
482 print "</td>\n";
483 }
484
485 # end row
486 print "</tr>\n";
487 }
488 print "</tbody>\n";
489
490 # end item table
491 print "</table>\n";
492
493 # if there are more items than are displayed
494 if ($TotalItemCount > count($Items))
495 {
496 # craft transport control message (if not supplied)
497 if ($TransportMsg === NULL)
498 {
499 $ItemsLabel = ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
500 ? StdLib::Pluralize(
501 $Item->Schema()->ResourceName())
502 : "Items";
503 $TransportMsg = $ItemsLabel
504 ." <b>".($this->TransportUI->StartingIndex() + 1)
505 ."</b> - <b>"
506 .min(($this->TransportUI->StartingIndex() + $this->ItemsPerPage),
507 $TotalItemCount)
508 ."</b> of <b>".$TotalItemCount."</b>";
509 }
510
511 # display transport controls
512 $this->TransportUI->StartingIndex($StartingIndex);
513 $this->TransportUI->ItemCount($TotalItemCount);
514 $this->TransportUI->PrintControls(
515 $this->SchemaId, $this->GetFullBaseLink(), $TransportMsg);
516 }
517 }
518
519
520 # ---- PRIVATE INTERFACE -------------------------------------------------
521
522 private $Actions;
523 private $BaseLink;
524 private $Buttons;
525 private $Fields;
526 private $Heading;
527 private $ItemsPerPage = 25;
528 private $NoItemsMsg;
529 private $SchemaId;
530 private $TransportUI;
531 private $VariablesToPreserve = array();
532
536 private function DisplayTopButtons()
537 {
538 if (is_array($this->Buttons) && count($this->Buttons))
539 {
540 print '<span style="float: right; padding-top: 1.5em;">';
541 foreach ($this->Buttons as $Info)
542 {
543 if (isset($Info["Icon"]) && strlen($Info["Icon"]))
544 {
545 $IconFile = $GLOBALS["AF"]->GUIFile($Info["Icon"]);
546 $IconTag = $IconFile
547 ? '<img class="cw-button-icon" src="'
548 .$IconFile.'" alt=""> '
549 : "";
550 $IconButtonClass = " cw-button-iconed";
551 }
552 else
553 {
554 $IconTag = "";
555 $IconButtonClass = "";
556 }
557 if (isset($Info["Checked"]))
558 {
559 $CheckboxState = $Info["Checked"] ? "checked" : "";
560 $OnChangeLinkBase = $Info["Link"]."&amp;".$Info["VarName"]."=";
561 $OnChangeAction = "if (this.checked) {"
562 ." window.location = '".$OnChangeLinkBase."1';"
563 ."} else {"
564 ." window.location = '".$OnChangeLinkBase."0';"
565 ."}";
566 ?> <input type="checkbox" name="<?= $Info["VarName"]
567 ?>" <?= $CheckboxState
568 ?> onchange="<?= $OnChangeAction ?>">
569 <?= $Info["Label"] ?><?PHP
570 }
571 else
572 {
573 ?> <a class="cw-button cw-button-elegant cw-button-constrained<?=
574 $IconButtonClass ?>"
575 href="<?= $Info["Link"] ?>"><?= $IconTag ?><?=
576 htmlspecialchars($Info["Label"]) ?></a><?PHP
577 }
578 }
579 print "</span>";
580 }
581 }
582
586 private function DisplayNoItemsMessage()
587 {
588 print "<span class=\"cw-itemlist-empty\">";
589 if (strlen($this->NoItemsMsg))
590 {
591 print $this->NoItemsMsg;
592 }
593 elseif ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
594 {
595 $Schema = new MetadataSchema($this->SchemaId);
596 print "(no ".strtolower(StdLib::Pluralize(
597 $Schema->ResourceName()))." to display)";
598 }
599 else
600 {
601 print "(no items to display)";
602 }
603 print "</span>";
604 }
605
611 private function DisplayActionButtons($ItemId, $Item)
612 {
613 foreach ($this->Actions as $ActionInfo)
614 {
615 if ($ActionInfo["TestFunc"] !== NULL)
616 {
617 $DisplayButton = $ActionInfo["TestFunc"]($Item);
618 }
619 elseif (method_exists($Item, "UserCanEdit"))
620 {
621 $DisplayButton = $Item->UserCanEdit($GLOBALS["G_User"]);
622 }
623 else
624 {
625 $DisplayButton = TRUE;
626 }
627 if ($DisplayButton)
628 {
629 $ButtonClasses = "cw-button cw-button-elegant"
630 ." cw-button-constrained";
631 $ExtraAttribs = "";
632 foreach ($ActionInfo["AddAttribs"]
633 as $AttribName => $AttribValue)
634 {
635 $AttribValue = htmlspecialchars($AttribValue);
636 if (strtolower($AttribName) == "class")
637 {
638 $ButtonClasses .= " ".$AttribValue;
639 }
640 else
641 {
642 $ExtraAttribs .= " ".$AttribName
643 .'="'.$AttribValue.'"';
644 }
645 }
646 if ($ActionInfo["Icon"])
647 {
648 $IconFile = $GLOBALS["AF"]->GUIFile($ActionInfo["Icon"]);
649 $IconTag = $IconFile
650 ? '<img class="cw-button-icon" src="'
651 .$IconFile.'" alt=""> '
652 : "";
653 $ButtonClasses .= " cw-button-iconed";
654 }
655 else
656 {
657 $IconTag = "";
658 }
659 if (is_callable($ActionInfo["Link"]))
660 {
661 $Link = $ActionInfo["Link"]($Item);
662 }
663 elseif (method_exists($Item, "Id"))
664 {
665 $Link = preg_replace('/\$ID/', $Item->Id(),
666 $ActionInfo["Link"]);
667 }
668 else
669 {
670 $Link = preg_replace('/\$ID/', $ItemId,
671 $ActionInfo["Link"]);
672 }
673 print '<a class="'.$ButtonClasses.'"'.$ExtraAttribs
674 .' href="'.$Link.'">'.$IconTag
675 .htmlspecialchars($ActionInfo["Label"]).'</a>';
676 }
677 }
678 if ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
679 {
680 $GLOBALS["AF"]->SignalEvent("EVENT_HTML_INSERTION_POINT",
681 array($GLOBALS["AF"]->GetPageName(),
682 "Resource Summary Buttons", array(
683 "Resource" => $Item)));
684 }
685 }
686 }
MetadataSchema
Metadata schema (in effect a Factory class for MetadataField).
Definition: MetadataSchema.php:13
ItemListUI
Class to provide a user interface for displaying a list of items.
Definition: ItemListUI.php:13
MetadataSchema\GetPrintableFieldName
static GetPrintableFieldName($Field)
Retrieve label for field.
Definition: MetadataSchema.php:1704
TransportControlsUI_Base\DefaultSortField
static DefaultSortField($NewValue=NULL)
Get/set default sort field value.
Definition: TransportControlsUI_Base.php:302
ItemListUI\TransportUI
& TransportUI()
Get the transport controls UI component used by the item list.
Definition: ItemListUI.php:241
ItemListUI\BaseLink
BaseLink($NewValue=NULL)
Get/set base URL for current page, for any links that need to be constructed.
Definition: ItemListUI.php:84
MetadataSchema\GetCanonicalFieldIdentifier
static GetCanonicalFieldIdentifier($Field, $SchemaId=NULL)
Retrieve canonical identifier for field.
Definition: MetadataSchema.php:1581
ItemListUI\__construct
__construct($Fields, $SchemaId=TransportControlsUI::NO_ITEM_TYPE)
Constructor for item list UI class.
Definition: ItemListUI.php:42
StdLib\Pluralize
static Pluralize($Word)
Pluralize an English word.
Definition: StdLib.php:164
ItemListUI\AddTopCheckbox
AddTopCheckbox($Label, $Checked, $VarName, $Link)
Add "checkbox" above list.
Definition: ItemListUI.php:180
ItemListUI\Display
Display($Items, $TotalItemCount=NULL, $StartingIndex=NULL, $TransportMsg=NULL)
Print list HTML with specified items.
Definition: ItemListUI.php:260
ItemListUI\Heading
Heading($NewValue=NULL)
Get/set heading text to be printed above list.
Definition: ItemListUI.php:130
ItemListUI\ItemsPerPage
ItemsPerPage($NewValue=NULL)
Get/set maximum number of items per page.
Definition: ItemListUI.php:144
PHP
PHP
Definition: RSSClient--Test.php:12
TransportControlsUI
Class to provide support for transport controls (used for paging back and forth through a list) in th...
Definition: TransportControlsUI.php:18
ItemListUI\AddTopButton
AddTopButton($Label, $Link, $Icon=NULL)
Add "button" above list.
Definition: ItemListUI.php:161
StdLib\NeatlyTruncateString
static NeatlyTruncateString($String, $MaxLength, $BreakAnywhere=FALSE)
Attempt to truncate a string as neatly as possible with respect to word breaks, punctuation, and HTML tags.
Definition: StdLib.php:239
ItemListUI\VariablesToPreserve
VariablesToPreserve($NewValue=NULL)
Get/set list of $_GET variables to preserve by adding them to base link whenever it is used...
Definition: ItemListUI.php:99
ItemListUI\AddActionButton
AddActionButton($Label, $Link, $Icon=NULL, $DisplayTestFunc=NULL, $AdditionalAttributes=array())
Add action "button" to each item in list.
Definition: ItemListUI.php:211
TransportControlsUI_Base\NO_ITEM_TYPE
const NO_ITEM_TYPE
Constant to use when no item types available.
Definition: TransportControlsUI_Base.php:23
ItemListUI\NoItemsMessage
NoItemsMessage($NewValue=NULL)
Get/set message to display when there are no items to list.
Definition: ItemListUI.php:228
ItemListUI\GetFullBaseLink
GetFullBaseLink()
Get full base link, including any variables to preserve.
Definition: ItemListUI.php:112
$Items
$Items
Definition: RSSClient--Test.php:26