Вход Регистрация
Файл: cobisja/BootHelp/src/Dropdown.php
Строк: 524
<?php

/**
 * BootHelp - PHP Helpers for Bootstrap
 *
 * (The MIT License)
 *
 * Copyright (c) 2015 Jorge Cobis <jcobis@gmail.com / http://twitter.com/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 
cobisjaBootHelpHelpersLinkTo;

/**
 * Generates an HTML block tag that follows the Bootstrap documentation
 * on how to display <strong>Dropdown</strong> component.
 *
 * See {@link http://getbootstrap.com/components/#dropdowns} for more information.
 */
class Dropdown extends Base
{
    
/**
     * Initializes the Dropdown instance.
     *
     * @param string  $caption Dropdown caption.
     * @param array   $options options to build the Dropdown.
     * @param closure $block closure to build the Dropdown content.
     */
    
public function __construct($caption$options = [], $block null)
    {
        if (
is_callable($options)) {
            
$block $options;
            
$options = [];
        }

        
$options['id'] = isset($options['id']) ? $options['id'] : 'label-dropdown-' . (string)(mt_rand(1pow(1010)));
        
$options['caption'] = $caption Base::SPACE;
        
$options['div_class'] = $this->dropdownDivClass($options);
        
$options['button_class'] = $this->dropdownButtonClass($options);
        
$options['list_class'] = $this->dropdownListClass($options);

        
Base::setDropdownLink(true);

        
$yield is_callable($block) ? call_user_func($block) : null;

        if ((isset(
$options['into_navbar']) && $options['into_navbar']) || ('' !== Base::getNavbarId())) {
            
$dropdown $this->buildStandardDropdownIntoNavbar($options$yield);
        } elseif (isset(
$options['into_nav']) && $options['into_nav'] || Base::getNavLink()) {
            
$dropdown $this->buildStandardDropdownIntoNav($options$yield);
        } else {
            
$dropdown = isset($options['split']) && $options['split'] ?
                
$this->buildSplitDropdown($options$yield) : $this->buildStandardDropdown($options$yield);
        }
        
        
Base::setDropdownLink(false);

        
$this->setHtmlObject($dropdown->getHtmlObject());
    }

    
/**
     * Builds a Standard Dropdown.
     *
     * @param array $options Dropdown's options.
     * @param mixed $yield Dropdown's content.
     * 
     * @return ContentTag Instance that represents a Dropdown,
     * in this case a button that triggers an unordered html list.
     */
    
private function buildStandardDropdown($options$yield)
    {
        return
            new 
ContentTag('div', ['class'=>$options['div_class']], function () use ($options$yield) {
                return [
                    new 
ContentTag(
                        
'button',
                        [
'class'=>'dropdown-toggle ' $options['button_class'],
                        
'type'=>'button',
                        
'id'=>$options['id'],
                        
'data-toggle'=>'dropdown'],
                        function () use (
$options) {
                            return [
$options['caption'] , new ContentTag('span''', ['class'=>'caret'])];
                        }
                    ),
                    new 
ContentTag(
                        
'ul',
                        
$yield,
                        [
'class'=>$options['list_class'],
                        
'role'=>'menu',
                        
'aria-labelledby'=>$options['id']]
                    )
                ];
            });
    }

    
/**
     * Builds a standard Dropdown that is rendered within a Navbar, so the Button
     * is not going to be generated instead a LinkTo is generated to trigger the
     * dropdown menu.
     *
     * @param array $options Dropdown's options.
     * @param mixed $yield Dropdown's content.
     * 
     * @return ContentTag a ContentTag instance that represents a Dropdown within a NavBar.
     */
    
private function buildStandardDropdownIntoNavbar($options$yield)
    {
        return
            new 
ContentTag('div', ['class'=>$options['div_class']], function () use ($options$yield) {
                return new 
ContentTag('ul', ['class'=>'nav navbar-nav'], function () use ($options$yield) {
                    return 
$this->buildStandardDropdownIntoNav($options$yield);
                });
            });
    }

    
/**
     * Builds a standard Dropdown that is rendered within a Nav, so the Button
     * is not going to be generated instead a LinkTo is generated to trigger the
     * dropdown menu.
     *
     * @param array $options Dropdown's options.
     * @param mixed $yield Dropdown's content.
     * 
     * @return ContentTag a ContentTag instance that represents a Dropdown within a Nav.
     */
    
private function buildStandardDropdownIntoNav($options$yield)
    {
        return new 
ContentTag('li', ['class'=>'dropdown'], function () use ($options$yield) {
            
$nav_link_status Base::getNavLink();
            
$dropdown_link_status Base::getDropdownLink();
            
Base::setDropdownLink(false);
            
Base::setNavLink(false);
            
            
$link =  new LinkTo(
                [
'href'=>'#''class'=>'dropdown-toggle''data-toggle'=>'dropdown'],
                function () use (
$options) {
                    return [
                        
$options['caption'],
                        new 
ContentTag('span''', ['class'=>'caret'])
                    ];
                }
            );
            
            
Base::setNavLink($nav_link_status);
            
Base::setDropdownLink($dropdown_link_status);
            
            return [
                
$link,
                new 
ContentTag(
                    
'ul',
                    
$yield,
                    [
'class'=>$options['list_class'], 'role'=>'menu''aria-labelledby'=>$options['id']]
                )
            ];
        });
    }

    
/**
     * Builds a Split Dropdown.
     *
     * @param array $options Dropdown's options.
     * @param mixed $yield Dropdown's content.
     * 
     * @return ContentTag a Contentag instance that represents a Split Dropdown, 
     * in this case 2 buttons, one of them triggers an unordered html list.
     */
    
private function buildSplitDropdown($options$yield)
    {
        return
            new 
ContentTag(
                
'div',
                [
'class'=>$options['div_class']],
                function () use (
$options$yield) {
                    return [
                        new 
ContentTag(
                            
'button',
                            
$options['caption'],
                            [
'type'=>'button''class'=>$options['button_class']]
                        ),
                        new 
ContentTag(
                            
'button',
                            [
                                
'class'=>'dropdown-toggle ' $options['button_class'],
                                
'type'=>'button''id'=>$options['id'],
                                
'data-toggle'=>'dropdown'
                            
],
                            function () {
                                return [
                                    new 
ContentTag('span''', ['class'=>'caret']),
                                    new 
ContentTag('span''Toggle Dropdown', ['class'=>'sr-only'])
                                ];
                            }
                        ),
                        new 
ContentTag(
                            
'ul',
                            
$yield,
                            [
'class'=>$options['list_class'],
                            
'role'=>'menu',
                            
'aria-labelledby'=>$options['id']]
                        )
                    ];
                }
            );
    }

    
/**
     * Returns the class for the div that contains the Dropdown.
     *
     * @param array $options Div's class options.
     * 
     * @return string Div's class.
     */
    
private function dropdownDivClass($options = [])
    {
        
$group = (isset($options['groupable']) && $options['groupable']) ||
                 (isset(
$options['split']) && $options['split'] ) ||
                 (isset(
$options['align']) && 'right' === $options['align'] )? 'btn-group' null;

        
$direction = isset($options['direction']) && $options['direction'] === 'up' 'dropup' 'dropdown';

        return 
join(Base::SPACEarray_filter([$group$direction], 'strlen'));
    }

    
/**
     * Returns the class related with alignment.
     *
     * @param array $options alignment options.
     * 
     * @return string alignment class.
     */
    
private function dropdownListClass($options = [])
    {
        
$align = isset($options['align']) && $options['align'] === 'right' 'dropdown-menu-right' null;
        return  
join(Base::SPACEarray_filter(['dropdown-menu'$align], 'strlen'));
    }

    
/**
     * Returns the class information associated to the Button.
     *
     * @param array $options class options information.
     * 
     * @return string button's class.
     */
    
private function dropdownButtonClass($options = [])
    {
        
$base_options = [
            
'context' => null,
            
'size' => '',
        ];

        
$valid_contexts = [ 'primary''success''info''warning''danger''link' ];

        
$this->setOptions($base_options$options);
        
$context $this->contextFor($options['context'], ['valid' => $valid_contexts]);
        
$button_class = isset($options['button']['class']) ? $options['button']['class'] : null;

        switch (
$options['size']) {
            case 
'lg':
            case 
'large':
                
$size 'btn-lg';
                break;
            case 
'sm':
            case 
'small':
                
$size 'btn-sm';
                break;
            case 
'xs':
            case 
'extra_small':
                
$size 'btn-xs';
                break;
            default:
                
$size null;
        }

        unset(
$options['context']);
        unset(
$options['size']);

        return 
join(Base::SPACEarray_filter([$button_class'btn'"btn-$context"$size], 'strlen'));
    }
}
Онлайн: 0
Реклама