123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <?php
- /** @file
- * This extension provides support for common HTML list operations.
- */
- /**
- * Provide list operations for QueryPath.
- *
- * The QPList class is an extension to QueryPath. It provides HTML list generators
- * that take lists and convert them into bulleted lists inside of QueryPath.
- *
- * @deprecated This will be removed from a subsequent version of QueryPath. It will
- * be released as a stand-alone extension.
- * @ingroup querypath_extensions
- */
- class QPList implements QueryPathExtension {
- const UL = 'ul';
- const OL = 'ol';
- const DL = 'dl';
-
- protected $qp = NULL;
- public function __construct(QueryPath $qp) {
- $this->qp = $qp;
- }
-
- public function appendTable($items, $options = array()) {
- $opts = $options + array(
- 'table class' => 'qptable',
- );
- $base = '<?xml version="1.0"?>
- <table>
- <tbody>
- <tr></tr>
- </tbody>
- </table>';
-
- $qp = qp($base, 'table')->addClass($opts['table class'])->find('tr');
- if ($items instanceof TableAble) {
- $headers = $items->getHeaders();
- $rows = $items->getRows();
- }
- elseif ($items instanceof Traversable) {
- $headers = array();
- $rows = $items;
- }
- else {
- $headers = $items['headers'];
- $rows = $items['rows'];
- }
-
- // Add Headers:
- foreach ($headers as $header) {
- $qp->append('<th>' . $header . '</th>');
- }
- $qp->top()->find('tr:last');
-
- // Add rows and cells.
- foreach ($rows as $row) {
- $qp->after('<tr/>')->next();
- foreach($row as $cell) $qp->append('<td>' . $cell . '</td>');
- }
-
- $this->qp->append($qp->top());
-
- return $this->qp;
- }
-
- /**
- * Append a list of items into an HTML DOM using one of the HTML list structures.
- * This takes a one-dimensional array and converts it into an HTML UL or OL list,
- * <b>or</b> it can take an associative array and convert that into a DL list.
- *
- * In addition to arrays, this works with any Traversable or Iterator object.
- *
- * OL/UL arrays can be nested.
- *
- * @param mixed $items
- * An indexed array for UL and OL, or an associative array for DL. Iterator and
- * Traversable objects can also be used.
- * @param string $type
- * One of ul, ol, or dl. Predefined constants are available for use.
- * @param array $options
- * An associative array of configuration options. The supported options are:
- * - 'list class': The class that will be assigned to a list.
- */
- public function appendList($items, $type = self::UL, $options = array()) {
- $opts = $options + array(
- 'list class' => 'qplist',
- );
- if ($type == self::DL) {
- $q = qp('<?xml version="1.0"?><dl></dl>', 'dl')->addClass($opts['list class']);
- foreach ($items as $dt => $dd) {
- $q->append('<dt>' . $dt . '</dt><dd>' . $dd . '</dd>');
- }
- $q->appendTo($this->qp);
- }
- else {
- $q = $this->listImpl($items, $type, $opts);
- $this->qp->append($q->find(':root'));
- }
-
- return $this->qp;
- }
-
- /**
- * Internal recursive list generator for appendList.
- */
- protected function listImpl($items, $type, $opts, $q = NULL) {
- $ele = '<' . $type . '/>';
- if (!isset($q))
- $q = qp()->append($ele)->addClass($opts['list class']);
-
- foreach ($items as $li) {
- if ($li instanceof QueryPath) {
- $q = $this->listImpl($li->get(), $type, $opts, $q);
- }
- elseif (is_array($li) || $li instanceof Traversable) {
- $q->append('<li><ul/></li>')->find('li:last > ul');
- $q = $this->listImpl($li, $type, $opts, $q);
- $q->parent();
- }
- else {
- $q->append('<li>' . $li . '</li>');
- }
- }
- return $q;
- }
-
- /**
- * Unused.
- */
- protected function isAssoc($array) {
- // A clever method from comment on is_array() doc page:
- return count(array_diff_key($array, range(0, count($array) - 1))) != 0;
- }
- }
- QueryPathExtensionRegistry::extend('QPList');
- /**
- * A TableAble object represents tabular data and can be converted to a table.
- *
- * The {@link QPList} extension to {@link QueryPath} provides a method for
- * appending a table to a DOM ({@link QPList::appendTable()}).
- *
- * Implementing classes should provide methods for getting headers, rows
- * of data, and the number of rows in the table ({@link TableAble::size()}).
- * Implementors may also choose to make classes Iterable or Traversable over
- * the rows of the table.
- *
- * Two very basic implementations of TableAble are provided in this package:
- * - {@link QPTableData} provides a generic implementation.
- * - {@link QPTableTextData} provides a generic implementation that also escapes
- * all data.
- */
- interface TableAble {
- public function getHeaders();
- public function getRows();
- public function size();
- }
- /**
- * Format data to be inserted into a simple HTML table.
- *
- * Data in the headers or rows may contain markup. If you want to
- * disallow markup, use a {@see QPTableTextData} object instead.
- */
- class QPTableData implements TableAble, IteratorAggregate {
-
- protected $headers;
- protected $rows;
- protected $caption;
- protected $p = -1;
-
- public function setHeaders($array) {$this->headers = $array; return $this;}
- public function getHeaders() {return $this->headers; }
- public function setRows($array) {$this->rows = $array; return $this;}
- public function getRows() {return $this->rows;}
- public function size() {return count($this->rows);}
- public function getIterator() {
- return new ArrayIterator($rows);
- }
- }
- /**
- * Provides a table where all of the headers and data are treated as text data.
- *
- * This provents marked-up data from being inserted into the DOM as elements.
- * Instead, the text is escaped using {@see htmlentities()}.
- *
- * @see QPTableData
- */
- class QPTableTextData extends QPTableData {
- public function setHeaders($array) {
- $headers = array();
- foreach ($array as $header) {
- $headers[] = htmlentities($header);
- }
- parent::setHeaders($headers);
- return $this;
- }
- public function setRows($array) {
- $count = count($array);
- for ($i = 0; $i < $count; ++$i) {
- $cols = array();
- foreach ($data[$i] as $datum) {
- $cols[] = htmlentities($datum);
- }
- $data[$i] = $cols;
- }
- parent::setRows($array);
- return $this;
- }
- }
|