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
46 public function __construct($Heading, $Fields, $ItemsPerPage, $BaseLink,
47 $SchemaId = TransportControlsUI::NO_ITEM_TYPE)
48 {
49 # normalize and save field info
50 if ($SchemaId == TransportControlsUI::NO_ITEM_TYPE)
51 {
52 $this->Fields = $Fields;
53 }
54 else
55 {
56 $this->Fields = array();
57 foreach ($Fields as $FieldId => $FieldInfo)
58 {
59 $CanonicalId = MetadataSchema::GetCanonicalFieldIdentifier($FieldId);
60 $this->Fields[$CanonicalId] = $FieldInfo;
61 }
62 }
63
64 # save other supplied settings for later use
65 $this->BaseLink = $BaseLink;
66 $this->Heading = $Heading;
67 $this->ItemsPerPage = $ItemsPerPage;
68 $this->SchemaId = $SchemaId;
69
70 # set up transport controls
71 foreach ($this->Fields as $FieldId => $FieldInfo)
72 {
73 if (isset($FieldInfo["DefaultSortField"]))
74 {
75 TransportControlsUI::DefaultSortField($FieldId);
76 }
77 }
78 $this->TransportUI = new TransportControlsUI(
79 $this->SchemaId, $this->ItemsPerPage);
80 }
81
89 public function AddTopButton($Label, $Link, $Icon = NULL)
90 {
91 $this->Buttons[] = array(
92 "Label" => $Label,
93 "Link" => $Link,
94 "Icon" => $Icon);
95 }
96
108 public function AddTopCheckbox($Label, $Checked, $VarName, $Link)
109 {
110 if (strpos($Link, $VarName."=") !== FALSE)
111 {
112 $Link = preg_replace("/(&|&amp;)".preg_quote($VarName)."=[^&]*/",
113 "", $Link);
114 }
115 $this->Buttons[] = array(
116 "Label" => $Label,
117 "Checked" => $Checked,
118 "VarName" => $VarName,
119 "Link" => $Link);
120 }
121
139 public function AddActionButton(
140 $Label, $Link, $Icon = NULL, $DisplayTestFunc = NULL,
141 $AdditionalAttributes = array())
142 {
143 $this->Actions[] = array(
144 "Label" => $Label,
145 "Link" => $Link,
146 "Icon" => $Icon,
147 "TestFunc" => $DisplayTestFunc,
148 "AddAttribs" => $AdditionalAttributes);
149 }
150
156 public function NoItemsMessage($NewValue = NULL)
157 {
158 if ($NewValue !== NULL)
159 {
160 $this->NoItemsMsg = $NewValue;
161 }
162 return $this->NoItemsMsg;
163 }
164
169 public function &TransportUI()
170 {
171 return $this->TransportUI;
172 }
173
188 public function Display($Items, $TotalItemCount = NULL,
189 $StartingIndex = NULL, $TransportMsg = NULL)
190 {
191 # retrieve context values from transport controls
192 $StartingIndex = $this->TransportUI->StartingIndex($StartingIndex);
193 $SortFieldId = $this->TransportUI->SortField();
194 $ReverseSort = $this->TransportUI->ReverseSortFlag();
195
196 # display buttons above list
197 $this->DisplayTopButtons();
198
199 # display heading
200 if ($this->Heading !== NULL)
201 {
202 if ($this->Heading == strip_tags($this->Heading))
203 {
204 print "<h1>".$this->Heading."</h1>\n";
205 }
206 else
207 {
208 print $this->Heading."\n";
209 }
210 }
211
212 # display "no items" message and exit if no items
213 if (count($Items) == 0)
214 {
215 $this->DisplayNoItemsMessage();
216 return;
217 }
218
219 # begin item table
220 print '<table class="cw-table cw-table-sideheaders cw-table-fullsize
221 cw-table-padded cw-table-striped">';
222
223 # begin header row
224 print "<thead><tr>";
225
226 # for each field
227 foreach ($this->Fields as $FieldId => $FieldInfo)
228 {
229 # if header value supplied
230 if (isset($FieldInfo["Heading"]))
231 {
232 # use supplied value
233 $Heading = $FieldInfo["Heading"];
234 }
235 # else if we can get header from schema
236 elseif ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
237 {
238 # use name of field (with any leading schema name stripped)
239 $Heading = MetadataSchema::GetPrintableFieldName($FieldId);
240 $Heading = preg_replace("/.+\: /", "", $Heading);
241 }
242 # else if field ID appears like it may be a name
243 elseif (is_string($FieldId) && !is_numeric($FieldId))
244 {
245 $Heading = $FieldId;
246 }
247 else
248 {
249 $Heading = "(NO HEADER SET)";
250 }
251
252 # if sorting is disabled for field
253 if (isset($FieldInfo["NoSorting"]))
254 {
255 # print header
256 print "<th>".$Heading."</th>\n";
257 }
258 else
259 {
260 # build sort link
261 $SortLink = $this->BaseLink."&amp;SF=".$FieldId
262 .$this->TransportUI->UrlParameterString(TRUE, array("SF", "RS"));
263
264 # determine current sort direction
265 if (isset($FieldInfo["DefaultToDescendingSort"]))
266 {
267 $SortAscending = $ReverseSort ? TRUE : FALSE;
268 }
269 else
270 {
271 $SortAscending = $ReverseSort ? FALSE : TRUE;
272 }
273
274 # set sort direction indicator (if any)
275 if ($FieldId == $SortFieldId)
276 {
277 $DirIndicator = ($SortAscending) ? "&uarr;" : "&darr;";
278 if (!$ReverseSort)
279 {
280 $SortLink .= "&amp;RS=1";
281 }
282 }
283 else
284 {
285 $DirIndicator = "";
286 }
287
288 # print header
289 print "<th><a href=\"".$SortLink."\">".$Heading."</a>"
290 .$DirIndicator."</th>\n";
291 }
292 }
293
294 # add action header if needed
295 if (is_array($this->Actions) && count($this->Actions))
296 {
297 print "<th>Actions</th>\n";
298 }
299
300 # end header row
301 print "</tr></thead>\n";
302
303 # for each item
304 print "<tbody>\n";
305 foreach ($Items as $ItemId => $Item)
306 {
307 # start row
308 print "<tr>\n";
309
310 # for each field
311 foreach ($this->Fields as $FieldId => $FieldInfo)
312 {
313 # if there is value function defined for field
314 if (isset($FieldInfo["ValueFunction"]))
315 {
316 # call function for value
317 $Value = $FieldInfo["ValueFunction"]($Item, $FieldId);
318 }
319 else
320 {
321 # if item is associative array
322 if (is_array($Item))
323 {
324 # retrieve value for field (if any) from item
325 $Value = isset($Item[$FieldId])
326 ? $Item[$FieldId] : "";
327 }
328 # else if field ID is item method
329 elseif (method_exists($Item, $FieldId))
330 {
331 # get field value via item method
332 $Value = $Item->$FieldId();
333 }
334 else
335 {
336 # get field value from item via Get()
337 $Values = $Item->Get($FieldId);
338 $Value = is_array($Values) ? array_shift($Values) : $Values;
339 }
340
341 # if max length specified for field
342 if (isset($FieldInfo["MaxLength"]))
343 {
344 $Value = StdLib::NeatlyTruncateString(
345 $Value, $FieldInfo["MaxLength"]);
346 }
347
348 # encode any HTML-significant chars in value
349 if (!isset($FieldInfo["AllowHTML"]))
350 {
351 $Value = htmlspecialchars($Value);
352 }
353 }
354
355 # get link value (if any)
356 if (isset($FieldInfo["Link"]))
357 {
358 if (method_exists($Item, "Id"))
359 {
360 $Link = preg_replace('/\$ID/', $Item->Id(),
361 $FieldInfo["Link"]);
362 }
363 else
364 {
365 $Link = preg_replace('/\$ID/', $ItemId,
366 $FieldInfo["Link"]);
367 }
368 $LinkStart = '<a href="'.$Link.'">';
369 $LinkEnd = "</a>";
370 }
371 elseif (isset($FieldInfo["LinkFunction"]))
372 {
373 $Link = $FieldInfo["LinkFunction"]($Item);
374 if (!strlen($Link))
375 {
376 $LinkStart = "";
377 $LinkEnd = "";
378 }
379 else
380 {
381 if (method_exists($Item, "Id"))
382 {
383 $Link = preg_replace('/\$ID/', $Item->Id(),
384 $Link);
385 }
386 else
387 {
388 $Link = preg_replace('/\$ID/', $ItemId,
389 $Link);
390 }
391 $LinkStart = '<a href="'.$Link.'">';
392 $LinkEnd = "</a>";
393 }
394 }
395 else
396 {
397 $LinkStart = "";
398 $LinkEnd = "";
399 }
400
401 # display cell with value
402 print "<td>".$LinkStart.$Value.$LinkEnd."</td>\n";
403 }
404
405 # add action buttons
406 if (is_array($this->Actions) && count($this->Actions))
407 {
408 print "<td>";
409 $this->DisplayActionButtons($ItemId, $Item);
410 print "</td>\n";
411 }
412
413 # end row
414 print "</tr>\n";
415 }
416 print "</tbody>\n";
417
418 # end item table
419 print "</table>\n";
420
421 # if there are more items than are displayed
422 if ($TotalItemCount > count($Items))
423 {
424 # craft transport control message (if not supplied)
425 if ($TransportMsg === NULL)
426 {
427 $ItemsLabel = ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
428 ? StdLib::Pluralize(
429 $Item->Schema()->ResourceName())
430 : "Items";
431 $TransportMsg = $ItemsLabel
432 ." <b>".($this->TransportUI->StartingIndex() + 1)
433 ."</b> - <b>"
434 .min(($this->TransportUI->StartingIndex() + $this->ItemsPerPage),
435 $TotalItemCount)
436 ."</b> of <b>".$TotalItemCount."</b>";
437 }
438
439 # display transport controls
440 $this->TransportUI->StartingIndex($StartingIndex);
441 $this->TransportUI->ItemCount($TotalItemCount);
442 $this->TransportUI->PrintControls(
443 $this->SchemaId, $this->BaseLink, $TransportMsg);
444 }
445 }
446
447
448 # ---- PRIVATE INTERFACE -------------------------------------------------
449
450 private $Actions;
451 private $BaseLink;
452 private $Buttons;
453 private $Fields;
454 private $Heading;
455 private $ItemsPerPage;
456 private $NoItemsMsg;
457 private $SchemaId;
458 private $TransportUI;
459
463 private function DisplayTopButtons()
464 {
465 if (is_array($this->Buttons) && count($this->Buttons))
466 {
467 print '<span style="float: right; padding-top: 1.5em;">';
468 foreach ($this->Buttons as $Info)
469 {
470 if (isset($Info["Icon"]) && strlen($Info["Icon"]))
471 {
472 $IconFile = $GLOBALS["AF"]->GUIFile($Info["Icon"]);
473 $IconTag = $IconFile
474 ? '<img class="cw-button-icon" src="'
475 .$IconFile.'" alt=""> '
476 : "";
477 $IconButtonClass = " cw-button-iconed";
478 }
479 else
480 {
481 $IconTag = "";
482 $IconButtonClass = "";
483 }
484 if (isset($Info["Checked"]))
485 {
486 $CheckboxState = $Info["Checked"] ? "checked" : "";
487 $OnChangeLinkBase = $Info["Link"]."&amp;".$Info["VarName"]."=";
488 $OnChangeAction = "if (this.checked) {"
489 ." window.location = '".$OnChangeLinkBase."1';"
490 ."} else {"
491 ." window.location = '".$OnChangeLinkBase."0';"
492 ."}";
493 ?> <input type="checkbox" name="<?= $Info["VarName"]
494 ?>" <?= $CheckboxState
495 ?> onchange="<?= $OnChangeAction ?>">
496 <?= $Info["Label"] ?><?PHP
497 }
498 else
499 {
500 ?> <a class="cw-button cw-button-elegant cw-button-constrained<?=
501 $IconButtonClass ?>"
502 href="<?= $Info["Link"] ?>"><?= $IconTag ?><?=
503 htmlspecialchars($Info["Label"]) ?></a><?PHP
504 }
505 }
506 print "</span>";
507 }
508 }
509
513 private function DisplayNoItemsMessage()
514 {
515 print "<span class=\"cw-itemlist-empty\">";
516 if (strlen($this->NoItemsMsg))
517 {
518 print $this->NoItemsMsg;
519 }
520 elseif ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
521 {
522 $Schema = new MetadataSchema($this->SchemaId);
523 print "(no ".strtolower(StdLib::Pluralize(
524 $Schema->ResourceName()))." to display)";
525 }
526 else
527 {
528 print "(no items to display)";
529 }
530 print "</span>";
531 }
532
538 private function DisplayActionButtons($ItemId, $Item)
539 {
540 foreach ($this->Actions as $ActionInfo)
541 {
542 if ($ActionInfo["TestFunc"] !== NULL)
543 {
544 $DisplayButton = $ActionInfo["TestFunc"]($Item);
545 }
546 elseif (method_exists($Item, "UserCanEdit"))
547 {
548 $DisplayButton = $Item->UserCanEdit($GLOBALS["G_User"]);
549 }
550 else
551 {
552 $DisplayButton = TRUE;
553 }
554 if ($DisplayButton)
555 {
556 $ButtonClasses = "cw-button cw-button-elegant"
557 ." cw-button-constrained";
558 $ExtraAttribs = "";
559 foreach ($ActionInfo["AddAttribs"]
560 as $AttribName => $AttribValue)
561 {
562 $AttribValue = htmlspecialchars($AttribValue);
563 if (strtolower($AttribName) == "class")
564 {
565 $ButtonClasses .= " ".$AttribValue;
566 }
567 else
568 {
569 $ExtraAttribs .= " ".$AttribName
570 .'="'.$AttribValue.'"';
571 }
572 }
573 if ($ActionInfo["Icon"])
574 {
575 $IconFile = $GLOBALS["AF"]->GUIFile($ActionInfo["Icon"]);
576 $IconTag = $IconFile
577 ? '<img class="cw-button-icon" src="'
578 .$IconFile.'" alt=""> '
579 : "";
580 $ButtonClasses .= " cw-button-iconed";
581 }
582 else
583 {
584 $IconTag = "";
585 }
586 if (is_callable($ActionInfo["Link"]))
587 {
588 $Link = $ActionInfo["Link"]($Item);
589 }
590 elseif (method_exists($Item, "Id"))
591 {
592 $Link = preg_replace('/\$ID/', $Item->Id(),
593 $ActionInfo["Link"]);
594 }
595 else
596 {
597 $Link = preg_replace('/\$ID/', $ItemId,
598 $ActionInfo["Link"]);
599 }
600 print '<a class="'.$ButtonClasses.'"'.$ExtraAttribs
601 .' href="'.$Link.'">'.$IconTag
602 .htmlspecialchars($ActionInfo["Label"]).'</a>';
603 }
604 }
605 if ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
606 {
607 $GLOBALS["AF"]->SignalEvent("EVENT_HTML_INSERTION_POINT",
608 array($GLOBALS["AF"]->GetPageName(),
609 "Resource Summary Buttons", array(
610 "Resource" => $Item)));
611 }
612 }
613 }
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:1688
TransportControlsUI_Base\DefaultSortField
static DefaultSortField($NewValue=NULL)
Get/set default sort field value.
Definition: TransportControlsUI_Base.php:276
ItemListUI\TransportUI
& TransportUI()
Get the transport controls UI component used by the item list.
Definition: ItemListUI.php:169
ItemListUI\__construct
__construct($Heading, $Fields, $ItemsPerPage, $BaseLink, $SchemaId=TransportControlsUI::NO_ITEM_TYPE)
Constructor for item list UI class.
Definition: ItemListUI.php:46
MetadataSchema\GetCanonicalFieldIdentifier
static GetCanonicalFieldIdentifier($Field, $SchemaId=NULL)
Retrieve canonical identifier for field.
Definition: MetadataSchema.php:1565
StdLib\Pluralize
static Pluralize($Word)
Pluralize an English word.
Definition: StdLib.php:162
ItemListUI\AddTopCheckbox
AddTopCheckbox($Label, $Checked, $VarName, $Link)
Add "checkbox" above list.
Definition: ItemListUI.php:108
ItemListUI\Display
Display($Items, $TotalItemCount=NULL, $StartingIndex=NULL, $TransportMsg=NULL)
Print list HTML with specified items.
Definition: ItemListUI.php:188
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:89
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:237
ItemListUI\AddActionButton
AddActionButton($Label, $Link, $Icon=NULL, $DisplayTestFunc=NULL, $AdditionalAttributes=array())
Add action "button" to each item in list.
Definition: ItemListUI.php:139
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:156
$Items
$Items
Definition: RSSClient--Test.php:26