Вход Регистрация
Файл: cobisja/BootHelp/src/Carousel.php
Строк: 541
<?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;
use 
cobisjaBootHelpIcon;

/**
 * Generates an HTML block tag that follows the Bootstrap documentation
 * on how to display <strong>Carousel</strong> component.
 *
 * See {@link http://getbootstrap.com/javascript/#carousel} for more information.
 */
class Carousel extends Base
{
    
/**
     * Initializes the Carousel instance.
     *
     * @param mixed    $content_or_options_with_block the display options for the carousel.
     * @param Callable $block Block to generate customized carousel 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 (
=== $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);
            }
        }

        
Base::setCarouselId(
            isset(
$options['id']) ? Base::getAndUnset('id'$options) : ('carousel-' . (string)(mt_rand(1pow(107))))
        );        
        
$carousel $this->buildCarousel($content$options);
        
Base::setCarouselId('');
        
        
$this->setHtmlObject($carousel->getHtmlObject());
    }
    
    
/**
     * Builds the Carousel component.
     * 
     * @param mixed $content Carousel's content
     * @param array $options Carousel's options to customize the component generation.
     * 
     * @return ContentTag a ContentTag instance that represents the Carousel.
     */
    
private function buildCarousel($content, array $options)
    {
        
$indicators null;
        
$controls = [];
        
$active_item = isset($options['active_item']) ? Base::getAndUnset('active_item'$options) : 0;
        
        
$indicators_options Base::getAndUnset('indicators_options'$options);
        
$content_options Base::getAndUnset('content_options'$options);
        
$controls_options Base::getAndUnset('controls_options'$options);
        
$show_indicators Base::getAndUnset('show_indicators'$options);
        
$show_controls Base::getAndUnset('show_controls'$options);
        
$items_number count($content);
        
        
Base::appendClass($content_options'carousel-inner');
        
$content_options['role'] = 'listbox';
        
        (
is_null($show_indicators) || !is_null($show_indicators) && $show_indicators)
            && (
$indicators $this->buildCarouselIndicators($items_number$indicators_options$active_item));
        (
is_null($show_controls) || !is_null($show_controls) && $show_controls
            && (
$controls $this->buildCarouselControls($controls_options));
        
$content $this->buildCarouselItems($content$content_options$active_item);
        
        
Base::appendClass($options'carousel slide');
        
$options['id'] = Base::getCarouselId();
        
$options['data-ride'] = 'carousel';
        
        
$carousel = new ContentTag('div'$options, function () use ($indicators$content$controls) {
            return 
array_filter(array_merge([$indicators$content], $controls), 'strlen');
        });
        
        return 
$carousel;
    }
    
    
/**
     * Builds the Carousel's controls.
     * 
     * @param int   $quantity number of controls that must be generated.
     * @param array $options options to be passed to the control's html tags.
     * @param int   $active_control control that will be initially active.
     * 
     * @return ContentTag ContenTag instance that represents the Carousel's controls.
     */
    
private function buildCarouselIndicators($quantity$options$active_control)
    {
        
Base::appendClass($options'carousel-indicators');
        
        
$indicators_object = new ContentTag('ol'$options, function () use ($quantity$active_control) {
            
$indicators = [];
            
            for (
$idx=0$idx $quantity$idx++) {
                
$indicator = new ContentTag(
                    
'li',
                    
'',
                    [
                        
'data-target'=>'#' Base::getCarouselId(),
                        
'data-slide-to'=>(string)$idx,
                        
'class'=> $idx === $active_control 'active' null
                    
]
                );
                
                
array_push($indicators$indicator);
            }
            
            return 
$indicators;
        });
        
        return 
$indicators_object;
    }
    
    
/**
     * Builds the Carousel's content
     * 
     * @param array $content array of items associates to the Carousel's content.
     * @param array $options options to be passed to the html tags associated with Carousel's content.
     * @param int   $active_item_id active item that wiil be initially active.
     * 
     * @return ContentTag ContentTag instance that represents the Carousel's content.
     */
    
private function buildCarouselItems(array $content, array $options$active_item_id)
    {
        
$carousel_items = [];
        for (
$item_id 0$item_id count($content); $item_id++) {
            
$element $this->getItemAndCaption($content[$item_id]);
            
$item $element['item'];
            
$caption $element['caption'];
            
$item_class 'item' . ($item_id === $active_item_id ' active' '');
            !
is_null($caption) ? $caption = new ContentTag('div'$caption, ['class'=>'carousel-caption']) : null;
            
            
$carousel_items[] = new ContentTag(
                
'div',
                (!
is_null($caption) ? [$item$caption] : $item),
                [
'class'=>$item_class]
            );
        }
        
        
$carousel_content = new ContentTag('div'$carousel_items$options);
        
        return 
$carousel_content;
    }
    
    
/**
     * Builds the Carouse's nav controls.
     * 
     * @param array $options options to be passed to the html tags associated with Carousel's nav controls.
     * 
     * @return array Left and Right navigation controls.
     */
    
private function buildCarouselControls($options)
    {
        
$href '#' Base::getCarouselId();
        
$default_left_control_options = [
            
'caption'=>'Previous',
            
'icon'=>'chevron-left',
            
'href'=>$href,
            
'role'=>'button',
            
'data-slide'=>'prev'
        
];
        
        
$default_right_control_options = [
            
'caption'=>'Next',
            
'icon'=>'chevron-right',
            
'href'=>$href,
            
'role'=>'button',
            
'data-slide'=>'next'
        
];
        
        
$left_control_options = isset($options['left']) ? Base::getAndUnset('left'$options) : [];
        
$right_control_options = isset($options['right']) ? Base::getAndUnset('right'$options) : [];
        
        
Base::appendClass($left_control_options'left carousel-control');
        
Base::appendClass($right_control_options'right carousel-control');
        
        
Base::setOptions($default_left_control_options$left_control_options);
        
Base::setOptions($default_right_control_options$right_control_options);
        
        return [
            
$this->buildControl($left_control_options),
            
$this->buildControl($right_control_options)
        ];
    }
    
    
/**
     * Helper method to build icon associated with the Carousel's nav control.
     * 
     * @param array  $options options that allows to customized the nav control generation.
     * 
     * @return ContentTag ContenTag instance that represents the Carousel's nav control.
     */
    
private function buildControl(array $options)
    {
        
$icon Base::getAndUnset('icon'$options);
        
$caption Base::getAndUnset('caption'$options);
        
        
$control = new ContentTag(
            
'a',
            
$options,
            function () use (
$icon$caption) {
                return [
                    new 
Icon($icon, ['aria-hidden'=>true]),
                    new 
ContentTag('span'$caption, ['class'=>'sr-only'])
                ];
            }
        );
        
        return 
$control;
    }
    
    
/**
     * Helper method to get an Carousel's item and its possible caption.
     * 
     * @param mixed $item_object item data.
     * 
     * @return array associativa array with the Carousel's item and its caption information.
     */
    
private function getItemAndCaption($item_object)
    {
        
$element=[];
        
        if (!
is_array($item_object)) {
            
$element = [
                
'item'=>  is_callable($item_object) ? call_user_func($item_object) : $item_object,
                
'caption'=>null
            
];
        } else {
            
$item is_callable($item_object[0]) ? call_user_func($item_object[0]) : $item_object[0];
            if (!isset(
$item_object['caption'])) {
                
$caption null;
            } else {
                if (
is_callable($item_object['caption'])) {
                    
$caption call_user_func($item_object['caption']);
                } else {
                    if (
is_array($item_object['caption'])) {
                        
$title Base::getAndUnset('title'$item_object['caption']);
                        
$content Base::getAndUnset('content'$item_object['caption']);
                    } else {
                        
$title null;
                        
$content $item_object['caption'];
                    }
                    
$caption array_filter(
                        [
                            !
is_null($title) ? new ContentTag('h3'$title) : null,
                            !
is_null($content) ? new ContentTag('p'$content) : null
                        
],
                        
'strlen'
                    
);
                }
            }
            
$element = ['item'=>$item'caption'=>$caption];
        }
        
        return 
$element;
    }
}
Онлайн: 2
Реклама