CWIS Developer Documentation
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 
14 {
15 
16  # ---- PUBLIC INTERFACE --------------------------------------------------
17 
44  public function __construct($Heading, $Fields, $ItemsPerPage, $BaseLink,
46  {
47  # normalize and save field info
48  if ($SchemaId == TransportControlsUI::NO_ITEM_TYPE)
49  {
50  $this->Fields = $Fields;
51  }
52  else
53  {
54  $this->Fields = array();
55  foreach ($Fields as $FieldId => $FieldInfo)
56  {
57  $CanonicalId = MetadataSchema::GetCanonicalFieldIdentifier($FieldId);
58  $this->Fields[$CanonicalId] = $FieldInfo;
59  }
60  }
61 
62  # save other supplied settings for later use
63  $this->BaseLink = $BaseLink;
64  $this->Heading = $Heading;
65  $this->ItemsPerPage = $ItemsPerPage;
66  $this->SchemaId = $SchemaId;
67 
68  # set up transport controls
69  foreach ($this->Fields as $FieldId => $FieldInfo)
70  {
71  if (isset($FieldInfo["DefaultSortField"]))
72  {
74  }
75  }
76  $this->TransportUI = new TransportControlsUI(
77  $this->SchemaId, $this->ItemsPerPage);
78  }
79 
87  public function AddTopButton($Label, $Link, $Icon = NULL)
88  {
89  $this->Buttons[] = array(
90  "Label" => $Label,
91  "Link" => $Link,
92  "Icon" => $Icon);
93  }
94 
112  public function AddActionButton(
113  $Label, $Link, $Icon = NULL, $DisplayTestFunc = NULL,
114  $AdditionalAttributes = array())
115  {
116  $this->Actions[] = array(
117  "Label" => $Label,
118  "Link" => $Link,
119  "Icon" => $Icon,
120  "TestFunc" => $DisplayTestFunc,
121  "AddAttribs" => $AdditionalAttributes);
122  }
123 
129  public function NoItemsMessage($NewValue = NULL)
130  {
131  if ($NewValue !== NULL)
132  {
133  $this->NoItemsMsg = $NewValue;
134  }
135  return $this->NoItemsMsg;
136  }
137 
142  public function &TransportUI()
143  {
144  return $this->TransportUI;
145  }
146 
161  public function Display($Items, $TotalItemCount = NULL,
162  $StartingIndex = NULL, $TransportMsg = NULL)
163  {
164  # retrieve context values from transport controls
165  $StartingIndex = $this->TransportUI->StartingIndex($StartingIndex);
166  $SortFieldId = $this->TransportUI->SortField();
167  $ReverseSort = $this->TransportUI->ReverseSortFlag();
168 
169  # display buttons above list
170  if (count($this->Buttons))
171  {
172  print '<span style="float: right; padding-top: 1.5em;">';
173  foreach ($this->Buttons as $Info)
174  {
175  if ($Info["Icon"])
176  {
177  $IconFile = $GLOBALS["AF"]->GUIFile($Info["Icon"]);
178  $IconTag = $IconFile
179  ? '<img class="cw-button-icon" src="'
180  .$IconFile.'" alt=""> '
181  : "";
182  $IconButtonClass = " cw-button-iconed";
183  }
184  else
185  {
186  $IconTag = "";
187  $IconButtonClass = "";
188  }
189  ?><a class="cw-button cw-button-elegant cw-button-constrained<?=
190  $IconButtonClass ?>"
191  href="<?= $Info["Link"] ?>"><?= $IconTag ?><?=
192  htmlspecialchars($Info["Label"]) ?></a><?PHP
193  }
194  print "</span>";
195  }
196 
197  # display heading
198  if ($this->Heading !== NULL)
199  {
200  if ($this->Heading == strip_tags($this->Heading))
201  {
202  print "<h1>".$this->Heading."</h1>\n";
203  }
204  else
205  {
206  print $this->Heading."\n";
207  }
208  }
209 
210  # display "no items" message and exit if no items
211  if (count($Items) == 0)
212  {
213  print "<span class=\"cw-itemlist-empty\">";
214  if (strlen($this->NoItemsMsg))
215  {
216  print $this->NoItemsMsg;
217  }
218  elseif ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
219  {
220  $Schema = new MetadataSchema($this->SchemaId);
221  print "(no ".strtolower(StdLib::Pluralize(
222  $Schema->ResourceName()))." to display)";
223  }
224  else
225  {
226  print "(no items to display)";
227  }
228  print "</span>";
229  return;
230  }
231 
232  # begin item table
233  print '<table class="cw-table cw-table-sideheaders cw-table-fullsize
234  cw-table-padded cw-table-striped">';
235 
236  # begin header row
237  print "<thead><tr>";
238 
239  # for each field
240  foreach ($this->Fields as $FieldId => $FieldInfo)
241  {
242  # if header value supplied
243  if (isset($FieldInfo["Heading"]))
244  {
245  # use supplied value
246  $Heading = $FieldInfo["Heading"];
247  }
248  # else if we can get header from schema
249  elseif ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
250  {
251  # use name of field (with any leading schema name stripped)
252  $Heading = MetadataSchema::GetPrintableFieldName($FieldId);
253  $Heading = preg_replace("/.+\: /", "", $Heading);
254  }
255  # else if field ID appears like it may be a name
256  elseif (is_string($FieldId) && !is_numeric($FieldId))
257  {
258  $Heading = $FieldId;
259  }
260  else
261  {
262  $Heading = "(NO HEADER SET)";
263  }
264 
265  # if sorting is disabled for field
266  if (isset($FieldInfo["NoSorting"]))
267  {
268  # print header
269  print "<th>".$Heading."</th>\n";
270  }
271  else
272  {
273  # build sort link
274  $SortLink = $this->BaseLink."&amp;SF=".$FieldId
275  .$this->TransportUI->UrlParameterString(TRUE, array("SF", "RS"));
276 
277  # determine current sort direction
278  if (isset($FieldInfo["DefaultToDescendingSort"]))
279  {
280  $SortAscending = $ReverseSort ? TRUE : FALSE;
281  }
282  else
283  {
284  $SortAscending = $ReverseSort ? FALSE : TRUE;
285  }
286 
287  # set sort direction indicator (if any)
288  if ($FieldId == $SortFieldId)
289  {
290  $DirIndicator = ($SortAscending) ? "&uarr;" : "&darr;";
291  if (!$ReverseSort)
292  {
293  $SortLink .= "&amp;RS=1";
294  }
295  }
296  else
297  {
298  $DirIndicator = "";
299  }
300 
301  # print header
302  print "<th><a href=\"".$SortLink."\">".$Heading."</a>"
303  .$DirIndicator."</th>\n";
304  }
305  }
306 
307  # add action header if needed
308  if (count($this->Actions))
309  {
310  print "<th>Actions</th>\n";
311  }
312 
313  # end header row
314  print "</tr></thead>\n";
315 
316  # for each item
317  print "<tbody>\n";
318  foreach ($Items as $ItemId => $Item)
319  {
320  # start row
321  print "<tr>\n";
322 
323  # for each field
324  foreach ($this->Fields as $FieldId => $FieldInfo)
325  {
326  # if there is value function defined for field
327  if (isset($FieldInfo["ValueFunction"]))
328  {
329  # call function for value
330  $Value = $FieldInfo["ValueFunction"]($Item, $FieldId);
331  }
332  else
333  {
334  # if item is associative array
335  if (is_array($Item))
336  {
337  # retrieve value for field (if any) from item
338  $Value = isset($Item[$FieldId])
339  ? $Item[$FieldId] : "";
340  }
341  # else if field ID is item method
342  elseif (method_exists($Item, $FieldId))
343  {
344  # get field value via item method
345  $Value = $Item->$FieldId();
346  }
347  else
348  {
349  # get field value from item via Get()
350  $Values = $Item->Get($FieldId);
351  $Value = is_array($Values) ? array_shift($Values) : $Values;
352  }
353 
354  # if max length specified for field
355  if (isset($FieldInfo["MaxLength"]))
356  {
357  $Value = NeatlyTruncateString(
358  $Value, $FieldInfo["MaxLength"]);
359  }
360 
361  # encode any HTML-significant chars in value
362  if (!isset($FieldInfo["AllowHTML"]))
363  {
364  $Value = htmlspecialchars($Value);
365  }
366  }
367 
368  # get link value (if any)
369  if (isset($FieldInfo["Link"]))
370  {
371  if (method_exists($Item, "Id"))
372  {
373  $Link = preg_replace('/\$ID/', $Item->Id(),
374  $FieldInfo["Link"]);
375  }
376  else
377  {
378  $Link = preg_replace('/\$ID/', $ItemId,
379  $FieldInfo["Link"]);
380  }
381  $LinkStart = '<a href="'.$Link.'">';
382  $LinkEnd = "</a>";
383  }
384  else
385  {
386  $LinkStart = "";
387  $LinkEnd = "";
388  }
389 
390  # display cell with value
391  print "<td>".$LinkStart.$Value.$LinkEnd."</td>\n";
392  }
393 
394  # add action buttons
395  if (count($this->Actions))
396  {
397  print "<td>";
398  foreach ($this->Actions as $ActionInfo)
399  {
400  if ($ActionInfo["TestFunc"] !== NULL)
401  {
402  $DisplayButton = $ActionInfo["TestFunc"]($Item);
403  }
404  elseif (method_exists($Item, "UserCanEdit"))
405  {
406  $DisplayButton = $Item->UserCanEdit($GLOBALS["G_User"]);
407  }
408  else
409  {
410  $DisplayButton = TRUE;
411  }
412  if ($DisplayButton)
413  {
414  $ButtonClasses = "cw-button cw-button-elegant"
415  ." cw-button-constrained";
416  $ExtraAttribs = "";
417  foreach ($ActionInfo["AddAttribs"]
418  as $AttribName => $AttribValue)
419  {
420  $AttribValue = htmlspecialchars($AttribValue);
421  if (strtolower($AttribName) == "class")
422  {
423  $ButtonClasses .= " ".$AttribValue;
424  }
425  else
426  {
427  $ExtraAttribs .= " ".$AttribName
428  .'="'.$AttribValue.'"';
429  }
430  }
431  if ($ActionInfo["Icon"])
432  {
433  $IconFile = $GLOBALS["AF"]->GUIFile($ActionInfo["Icon"]);
434  $IconTag = $IconFile
435  ? '<img class="cw-button-icon" src="'
436  .$IconFile.'" alt=""> '
437  : "";
438  $ButtonClasses .= " cw-button-iconed";
439  }
440  else
441  {
442  $IconTag = "";
443  }
444  if (is_callable($ActionInfo["Link"]))
445  {
446  $Link = $ActionInfo["Link"]($Item);
447  }
448  elseif (method_exists($Item, "Id"))
449  {
450  $Link = preg_replace('/\$ID/', $Item->Id(),
451  $ActionInfo["Link"]);
452  }
453  else
454  {
455  $Link = preg_replace('/\$ID/', $ItemId,
456  $ActionInfo["Link"]);
457  }
458  print '<a class="'.$ButtonClasses.'"'.$ExtraAttribs
459  .' href="'.$Link.'">'.$IconTag
460  .htmlspecialchars($ActionInfo["Label"]).'</a>';
461  }
462  }
463  if ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
464  {
465  $GLOBALS["AF"]->SignalEvent("EVENT_HTML_INSERTION_POINT",
466  array($GLOBALS["AF"]->GetPageName(),
467  "Resource Summary Buttons", array(
468  "Resource" => $Item)));
469  }
470  print "</td>\n";
471  }
472 
473  # end row
474  print "</tr>\n";
475  }
476  print "</tbody>\n";
477 
478  # end item table
479  print "</table>\n";
480 
481  # if there are more items than are displayed
482  if ($TotalItemCount > count($Items))
483  {
484  # craft transport control message (if not supplied)
485  if ($TransportMsg === NULL)
486  {
487  $ItemsLabel = ($this->SchemaId !== TransportControlsUI::NO_ITEM_TYPE)
489  $Item->Schema()->ResourceName())
490  : "Items";
491  $TransportMsg = $ItemsLabel
492  ." <b>".($this->TransportUI->StartingIndex() + 1)
493  ."</b> - <b>"
494  .min(($this->TransportUI->StartingIndex() + $this->ItemsPerPage),
495  $TotalItemCount)
496  ."</b> of <b>".$TotalItemCount."</b>";
497  }
498 
499  # display transport controls
500  $this->TransportUI->StartingIndex($StartingIndex);
501  $this->TransportUI->ItemCount($TotalItemCount);
502  $this->TransportUI->PrintControls(
503  $this->SchemaId, $this->BaseLink, $TransportMsg);
504  }
505  }
506 
507 
508  # ---- PRIVATE INTERFACE -------------------------------------------------
509 
510  private $Actions;
511  private $BaseLink;
512  private $Buttons;
513  private $Fields;
514  private $Heading;
515  private $ItemsPerPage;
516  private $NoItemsMsg;
517  private $SchemaId;
518  private $TransportUI;
519 }
Metadata schema (in effect a Factory class for MetadataField).
Class to provide a user interface for displaying a list of items.
Definition: ItemListUI.php:13
static GetPrintableFieldName($Field)
Retrieve label for field.
static DefaultSortField($NewValue=NULL)
Get/set default sort field value.
& TransportUI()
Get the transport controls UI component used by the item list.
Definition: ItemListUI.php:142
__construct($Heading, $Fields, $ItemsPerPage, $BaseLink, $SchemaId=TransportControlsUI::NO_ITEM_TYPE)
Constructor for item list UI class.
Definition: ItemListUI.php:44
static GetCanonicalFieldIdentifier($Field, $SchemaId=NULL)
Retrieve canonical identifier for field.
static Pluralize($Word)
Pluralize an English word.
Definition: StdLib.php:162
Display($Items, $TotalItemCount=NULL, $StartingIndex=NULL, $TransportMsg=NULL)
Print list HTML with specified items.
Definition: ItemListUI.php:161
Class to provide support for transport controls (used for paging back and forth through a list) in th...
AddTopButton($Label, $Link, $Icon=NULL)
Add "button" above list.
Definition: ItemListUI.php:87
AddActionButton($Label, $Link, $Icon=NULL, $DisplayTestFunc=NULL, $AdditionalAttributes=array())
Add action "button" to each item in list.
Definition: ItemListUI.php:112
const NO_ITEM_TYPE
Constant to use when no item types available.
NoItemsMessage($NewValue=NULL)
Get/set message to display when there are no items to list.
Definition: ItemListUI.php:129