Файл: cobisja/BootHelp/src/Table.php
Строк: 427
<?php
/**
* The MIT License
*
* Copyright 2015 cobisja.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
namespace cobisjaBootHelp;
use cobisjaBootHelpBase;
use cobisjaBootHelpHelpersContentTag;
/**
* Generates an HTML block tag that follows the Bootstrap documentation
* on how to display <strong>Table</strong> component.
*
* See {@link http://getbootstrap.com/css/#tables} for more information.
*/
class Table extends Base
{
/**
* Initializes the Table instance.
*
* @param mixed $content_or_options_with_block the display options for Table.
* @param Callable $block Block to generate customized Table's content.
*/
public function __construct($content_or_options_with_block, $block = null)
{
$num_args = $this->getFunctionNumArgs(func_get_args());
$content_block = is_callable(func_get_arg($num_args-1)) ? func_get_arg($num_args-1) : null;
if (1 === $num_args) {
$options = [];
$content = is_null($content_block) ? $content_or_options_with_block : call_user_func($content_block);
} else {
if (is_array($content_or_options_with_block) && is_array($block)) {
$content = $content_or_options_with_block;
$options = $block;
} else {
$options = $content_or_options_with_block;
$content = call_user_func($content_block);
}
}
$table = $this->buildTable($content, $options);
$this->setHtmlObject($table->getHtmlObject());
}
/**
* Builds the Table component.
*
* @param mixed $content Table's content
* @param array $options Table's options to customize the component generation.
*
* @return ContentTag a ContentTag instance that represents the Table group.
*/
private function buildTable($content, array $options)
{
!is_array($content) ? $content = [$content] : null;
$is_responsive = Base::getAndUnset('responsive', $options);
$table_content = $this->buildTableContent($content, $options);
$this->getTableClass($options);
Base::appendClass($options, 'table');
$table = new ContentTag('table', $table_content, $options);
if ($is_responsive) {
$table = new ContentTag('div', $table, ['class'=>'table-responsive']);
}
return $table;
}
/**
* Builds the Table's content
*
* @param mixed $content list of elements that makes the Table's content.
* @param array $options options for building the Table's component.
*
* @return array Table's content as array.
*/
private function buildTableContent($content, &$options)
{
return array_filter(
[
$this->buildTableCaption($options),
$this->buildTableHeading($content, $options),
$this->buildTableRows($content, $options)
],
'strlen'
);
}
/**
* Gets and builds the optional Table's caption.
*
* @param mixed $options options for building the Table's component.
*
* @return ContenTag a ContentTag instance that represents the Table's caption.
*/
private function buildTableCaption(&$options)
{
$caption = Base::getAndUnset('caption', $options);
return !is_null($caption) ? new ContentTag('caption', $caption) : null;
}
/**
* Builds the optional Table's head.
*
* @param mixed $content list of elements that makes the Table's content.
* @param array $options options for building the Table's component.
* @param mixed $heading a boolean value indicates if the first rows of the content will be the table head.
*
* @return ContentTag a ContentTag instance that represents the Table's head.
*/
private function buildTableHeading(&$content, array &$options)
{
$header_options = Base::getAndUnset('header_options', $options);
$header = Base::getAndUnset('header', $options);
if (is_bool($header) && $header) {
$header = array_shift($content);
}
if (is_null($header)) {
return null;
}
$head_object = new ContentTag(
'tr',
array_map(
function ($cell_head) {
return new ContentTag('th', $cell_head);
},
$header
)
);
return new ContentTag('thead', $head_object, $header_options);
}
/**
* Builds the Table's content.
*
* @param mixed $content list of elements that makes the Table's content.
* @param array $options options for building the Table's component.
*
* @return ContentTag a ContentTag instance that represents the Table's content.
*/
private function buildTableRows($content, array &$options)
{
$global_row_options = Base::getAndUnset('rows_options', $options);
$body_options = Base::getAndUnset('body_options', $options);
$rows = [];
foreach ($content as $row) {
$row_options = is_null($global_row_options) ? [] : $global_row_options;
$cells = [];
$local_row_options = $this->getRowOptions($row);
foreach ($row as $cell) {
if (!is_array($cell)) {
$cell_content = $cell;
$cell_options = [];
} else {
$cell_content = array_shift($cell);
$cell_options = $cell;
Base::appendClass($cell_options, Base::getAndUnset('context', $cell_options));
}
$cell_options['scope'] = Base::getAndUnset('scope', $cell_options);
$cell = new ContentTag(
(is_null($cell_options['scope']) ? 'td': 'th'),
$cell_content,
$cell_options
);
$cells[] = $cell;
}
Base::setOptions($row_options, $local_row_options);
Base::appendClass($local_row_options, Base::getAndUnset('context', $local_row_options));
$rows[] = new ContentTag('tr', $cells, $local_row_options);
}
$table_body = new ContentTag('tbody', $rows, $body_options);
return $table_body;
}
/**
* Sets the specific table's class for options 'striped', 'bordered', 'hover' and/or 'condensed'.
*
* @param array $options options for building the Table's component.
*/
private function getTableClass(array &$options)
{
foreach (['striped', 'bordered', 'hover', 'condensed'] as $klass) {
if (Base::getAndUnset($klass, $options)) {
Base::appendClass($options, 'table-' . $klass);
}
}
}
/**
* Gets the specific options for a specific table row.
*
* @param array $content list of elements that makes the Table's content.
*
* @return array row's options.
*/
private function getRowOptions(array &$content)
{
$row_options = [];
foreach ($content as $option => $value) {
if (!is_numeric($option)) {
$row_options[$option] = $value;
unset($content[$option]);
}
}
return $row_options;
}
}