├── CHANGELOG.md ├── README.md ├── composer.json ├── composer.lock ├── phpspec.yml └── src ├── Bootstrapper ├── Accordion.php ├── Alert.php ├── Attributes.php ├── Badge.php ├── BootstrapperL5ServiceProvider.php ├── Breadcrumb.php ├── Bridges │ └── Config │ │ ├── ConfigInterface.php │ │ ├── Laravel4Config.php │ │ └── Laravel5Config.php ├── Button.php ├── ButtonGroup.php ├── Carousel.php ├── ControlGroup.php ├── DropdownButton.php ├── Exceptions │ ├── AccordionException.php │ ├── ButtonGroupException.php │ ├── CarouselException.php │ ├── ControlGroupException.php │ ├── IconException.php │ ├── ImageException.php │ ├── MediaObjectException.php │ ├── ModalException.php │ └── ThumbnailException.php ├── Facades │ ├── Accordion.php │ ├── Alert.php │ ├── Badge.php │ ├── BootstrapperFacade.php │ ├── Breadcrumb.php │ ├── Button.php │ ├── ButtonGroup.php │ ├── Carousel.php │ ├── ControlGroup.php │ ├── DropdownButton.php │ ├── Form.php │ ├── Helpers.php │ ├── Icon.php │ ├── Image.php │ ├── InputGroup.php │ ├── Label.php │ ├── MediaObject.php │ ├── Modal.php │ ├── Navbar.php │ ├── Navigation.php │ ├── Panel.php │ ├── ProgressBar.php │ ├── Tabbable.php │ ├── Table.php │ └── Thumbnail.php ├── Form.php ├── Helpers.php ├── Icon.php ├── Image.php ├── InputGroup.php ├── Interfaces │ └── TableInterface.php ├── Label.php ├── MediaObject.php ├── Modal.php ├── Navbar.php ├── Navigation.php ├── Panel.php ├── ProgressBar.php ├── RenderedObject.php ├── Tabbable.php ├── Table.php └── Thumbnail.php └── config ├── bootstrapper.php └── config.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Bootstrapper 2 | ------------ 3 | 4 | 5.3.0 5 | ===== 6 | 7 | * Add `Table::withFooter()` 8 | * `Table::setType()` is now fluid 9 | 10 | 5.2.0 11 | ===== 12 | 13 | * Add docblocks 14 | * `withAttributes` is now a method on the `RenderedObject` class 15 | * `Helpers::generateId()` created, to generate unique ids per object 16 | 17 | 5.0.0 18 | ===== 19 | 20 | * Rewrite application to use facades 21 | * Require Laravel 4.2 (and thus PHP 5.4) 22 | * Change test suite to use PHPSpec 23 | * Update to use PSR-4 24 | * Remove Form::append* etc in favour of an InputGroup class 25 | * Remove Form::control_group in favour of a ControlGroup class 26 | * Rename Progress to ProgressBar 27 | 28 | 4.0.0 29 | ===== 30 | 31 | - Compatibility with Laravel 4 32 | - _more_ 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bootstrapper 2 | 3 | Latest stable version: [![Latest Stable Version](https://poser.pugx.org/patricktalmadge/bootstrapper/v/stable.svg)](https://packagist.org/packages/patricktalmadge/bootstrapper) 4 | 5 | Travis status : [![Build Status](https://travis-ci.org/patricktalmadge/bootstrapper.svg?branch=develop)](https://travis-ci.org/patricktalmadge/bootstrapper) 6 | 7 | Current supported Bootstrap version: 3.2.0 8 | 9 | Bootstrapper is a set of classes that allow you to quickly create Twitter 10 | Bootstrap 3 style markup. 11 | 12 | ## Installation 13 | 14 | Add the following to your `composer.json` file : 15 | 16 | ```json 17 | "require": { 18 | "patricktalmadge/bootstrapper": "~5", 19 | }, 20 | ``` 21 | 22 | or execute 23 | 24 | ```bash 25 | composer require patricktalmadge/bootstrapper 26 | ``` 27 | 28 | Then register Bootstrapper's service provider with Laravel: 29 | 30 | ```php 31 | 'Bootstrapper\BootstrapperServiceProvider', 32 | ``` 33 | 34 | If you are using Laravel 5, then you should instead use the Laravel 5 service 35 | provider. 36 | 37 | ```php 38 | 'Bootstrapper\BootstrapperL5ServiceProvider', 39 | ``` 40 | 41 | You can then (if you want to) add the following aliases to your `aliases` 42 | array in your `config/app.php` file. 43 | 44 | ```php 45 | 'Accordion' => 'Bootstrapper\Facades\Accordion', 46 | 'Alert' => 'Bootstrapper\Facades\Alert', 47 | 'Badge' => 'Bootstrapper\Facades\Badge', 48 | 'Breadcrumb' => 'Bootstrapper\Facades\Breadcrumb', 49 | 'Button' => 'Bootstrapper\Facades\Button', 50 | 'ButtonGroup' => 'Bootstrapper\Facades\ButtonGroup', 51 | 'Carousel' => 'Bootstrapper\Facades\Carousel', 52 | 'ControlGroup' => 'Bootstrapper\Facades\ControlGroup', 53 | 'DropdownButton' => 'Bootstrapper\Facades\DropdownButton', 54 | 'Form' => 'Bootstrapper\Facades\Form', 55 | 'Helpers' => 'Bootstrapper\Facades\Helpers', 56 | 'Icon' => 'Bootstrapper\Facades\Icon', 57 | 'InputGroup' => 'Bootstrapper\Facades\InputGroup', 58 | 'Image' => 'Bootstrapper\Facades\Image', 59 | 'Label' => 'Bootstrapper\Facades\Label', 60 | 'MediaObject' => 'Bootstrapper\Facades\MediaObject', 61 | 'Modal' => 'Bootstrapper\Facades\Modal', 62 | 'Navbar' => 'Bootstrapper\Facades\Navbar', 63 | 'Navigation' => 'Bootstrapper\Facades\Navigation', 64 | 'Panel' => 'Bootstrapper\Facades\Panel', 65 | 'ProgressBar' => 'Bootstrapper\Facades\ProgressBar', 66 | 'Tabbable' => 'Bootstrapper\Facades\Tabbable', 67 | 'Table' => 'Bootstrapper\Facades\Table', 68 | 'Thumbnail' => 'Bootstrapper\Facades\Thumbnail', 69 | ``` 70 | 71 | ## Including Bootstrap 72 | 73 | Include the Bootstrap files just like any other css and js files! Download 74 | Bootstrap and JQuery from the [Bootstrap site](http://getbootstrap.com), 75 | place them in your public folder and then include them like so: 76 | 77 | ```php 78 | {{ HTML::style('path/to/bootstrap.css') }} 79 | {{ HTML::script('path/to/jquery.js') }} 80 | {{ HTML::script('path/to/bootstrap.js') }} 81 | ``` 82 | 83 | Feel free to use a CDN, but bear in mind that you may get unexpected 84 | functionality if the version you use isn't the version Bootstrapper currently 85 | supports (but open an issue to let us know!). 86 | 87 | ```html 88 | 89 | 90 | 91 | ``` 92 | 93 | If you want to get the latest Bootstrap that Bootstrapper supports, 94 | then use the helper function: 95 | 96 | ```php 97 | Helpers::css() 98 | Helpers::js() 99 | ``` 100 | 101 | If you want to stick at a certain version then use 102 | 103 | ``` 104 | artisan config:publish patricktalmadge/bootstrapper 105 | ``` 106 | 107 | And update your config file in app/config/packages. 108 | 109 | We also have Twitter Bootstrap as a dependency, so you can grab the files from 110 | your vendor directory. 111 | 112 | ## Documentation 113 | 114 | - [Bootstrapper documentation](http://bootstrapper.patrickrosemusic.co.uk/) 115 | - [Twitter Bootstrap documentation](http://getbootstrap.com/) 116 | - [Twitter Bootstrap on Github](https://github.com/twitter/bootstrap) 117 | 118 | 119 | ## Contributing 120 | 121 | Contributing is easy! Just fork the repo, make your changes then send a pull 122 | request on GitHub. If your PR is languishing in the queue and nothing seems 123 | to be happening, then send Patrick an 124 | [email](mailto:pjr0911025@googlemail.com) or a 125 | [tweet](http://twitter.com/DrugCrazed). 126 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patricktalmadge/bootstrapper", 3 | "description": "Twitter Bootstrap markup generator", 4 | "license": "MIT", 5 | "keywords": [ 6 | "bootstrap", 7 | "laravel" 8 | ], 9 | "authors": [ 10 | { 11 | "name": "Patrick Talmadge", 12 | "email": "ptalmadge@gmail.com" 13 | }, 14 | { 15 | "name": "Maxime Fabre", 16 | "email": "ehtnam6@gmail.com" 17 | }, 18 | { 19 | "name": "Patrick Rose", 20 | "email": "pjr0911025@gmail.com" 21 | } 22 | ], 23 | "require": { 24 | "php": ">=7.2.0", 25 | "laravelcollective/html": "^6.2.0", 26 | "illuminate/support": "^6.0||^7.0||^8.0", 27 | "illuminate/config": "^6.0||^7.0||^8.0", 28 | "illuminate/routing": "^6.0||^7.0||^8.0", 29 | "twbs/bootstrap": "~3" 30 | }, 31 | "require-dev": { 32 | "mockery/mockery": "~1.3.3||^1.4.2", 33 | "phpspec/phpspec": "^6.3|^7.0", 34 | "graham-campbell/phpspec-skip-example-extension": "^5.1", 35 | "squizlabs/php_codesniffer": "^3.5" 36 | }, 37 | "autoload": { 38 | "psr-4": { 39 | "Bootstrapper\\": "src\\Bootstrapper", 40 | "DummyClasses\\": "tests\\DummyClasses" 41 | } 42 | }, 43 | "extra": { 44 | "laravel": { 45 | "providers": [ 46 | "Bootstrapper\\BootstrapperL5ServiceProvider" 47 | ] 48 | } 49 | }, 50 | "minimum-stability": "stable" 51 | } 52 | -------------------------------------------------------------------------------- /phpspec.yml: -------------------------------------------------------------------------------- 1 | suites: 2 | bootstrapper_suite: 3 | namespace: Bootstrapper 4 | src_path: src 5 | spec_path: tests 6 | spec_prefix: spec 7 | abstract_suite: 8 | namespace: DummyClasses 9 | src_path: tests 10 | spec_path: tests 11 | spec_prefix: spec 12 | extensions: 13 | Akeneo\SkipExampleExtension: ~ 14 | -------------------------------------------------------------------------------- /src/Bootstrapper/Accordion.php: -------------------------------------------------------------------------------- 1 | name = $name; 41 | 42 | return $this; 43 | } 44 | 45 | /** 46 | * Add the contents for the accordion. Should be an array of arrays 47 | * Expected Keys: 48 | * 53 | * 54 | * @param array $contents 55 | * @return $this 56 | */ 57 | public function withContents(array $contents) 58 | { 59 | $this->contents = $contents; 60 | 61 | return $this; 62 | } 63 | 64 | /** 65 | * Sets which panel should be opened. Numbering begins from 0. 66 | * 67 | * @param $integer int 68 | * @return $this 69 | */ 70 | public function open($integer) 71 | { 72 | $this->opened = $integer; 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * Renders the accordion 79 | * 80 | * @return string 81 | */ 82 | public function render() 83 | { 84 | if (!$this->name) { 85 | $this->name = Helpers::generateId($this); 86 | } 87 | 88 | $attributes = new Attributes( 89 | $this->attributes, 90 | ['class' => 'panel-group', 'id' => $this->name] 91 | ); 92 | 93 | $string = "
"; 94 | $count = 0; 95 | foreach ($this->contents as $item) { 96 | $itemAttributes = array_key_exists( 97 | 'attributes', 98 | $item 99 | ) ? $item['attributes'] : []; 100 | 101 | $itemAttributes = new Attributes( 102 | $itemAttributes, 103 | ['class' => 'panel panel-default'] 104 | ); 105 | 106 | $string .= "
"; 107 | $string .= "
"; 108 | $string .= "

"; 109 | $string .= "{$item['title']}"; 111 | $string .= "

"; 112 | $string .= "
"; 113 | 114 | $bodyAttributes = new Attributes( 115 | [ 116 | 'id' => "{$this->name}-{$count}", 117 | 'class' => 'panel-collapse collapse' 118 | ] 119 | ); 120 | 121 | if ($this->opened == $count) { 122 | $bodyAttributes->addClass('in'); 123 | } 124 | 125 | $string .= "
"; 126 | $string .= "
{$item['contents']}
"; 127 | $string .= "
"; 128 | $string .= "
"; 129 | $count++; 130 | } 131 | $string .= "
"; 132 | 133 | return $string; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/Bootstrapper/Alert.php: -------------------------------------------------------------------------------- 1 | type = $type; 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * Renders the alert 67 | * 68 | * @return string 69 | */ 70 | public function render() 71 | { 72 | $attributes = new Attributes( 73 | $this->attributes, 74 | ['class' => "alert {$this->type}"] 75 | ); 76 | 77 | if ($this->closer) { 78 | $attributes->addClass('alert-dismissable'); 79 | $this->contents = "{$this->contents}"; 82 | } 83 | 84 | return "
{$this->contents}
"; 85 | } 86 | 87 | /** 88 | * Creates an info alert box 89 | * 90 | * @param string $contents 91 | * @return $this 92 | */ 93 | public function info($contents = '') 94 | { 95 | return $this->setType(self::INFO)->withContents($contents); 96 | } 97 | 98 | /** 99 | * Creates a success alert box 100 | * 101 | * @param string $contents 102 | * @return $this 103 | */ 104 | public function success($contents = '') 105 | { 106 | return $this->setType(self::SUCCESS)->withContents($contents); 107 | } 108 | 109 | /** 110 | * Creates a warning alert box 111 | * 112 | * @param string $contents 113 | * @return $this 114 | */ 115 | public function warning($contents = '') 116 | { 117 | return $this->setType(self::WARNING)->withContents($contents); 118 | } 119 | 120 | /** 121 | * Creates a danger alert box 122 | * 123 | * @param string $contents 124 | * @return $this 125 | */ 126 | public function danger($contents = '') 127 | { 128 | return $this->setType(self::DANGER)->withContents($contents); 129 | } 130 | 131 | /** 132 | * Sets the contents of the alert box 133 | * 134 | * @param $contents 135 | * @return $this 136 | */ 137 | public function withContents($contents) 138 | { 139 | $this->contents = $contents; 140 | 141 | return $this; 142 | } 143 | 144 | /** 145 | * Adds a close button with the given text 146 | * 147 | * @param string $closer 148 | * @return $this 149 | */ 150 | public function close($closer = '×') 151 | { 152 | $this->closer = $closer; 153 | 154 | return $this; 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/Bootstrapper/Attributes.php: -------------------------------------------------------------------------------- 1 | attributes = array_merge($defaults, $attributes); 32 | if (isset($attributes['class']) && isset($defaults['class'])) { 33 | $this->attributes['class'] = trim( 34 | "{$defaults['class']} {$attributes['class']}" 35 | ); 36 | } 37 | } 38 | 39 | /** 40 | * Renders the HTML attributes 41 | * 42 | * @return string 43 | */ 44 | public function __toString() 45 | { 46 | $string = ""; 47 | foreach ($this->attributes as $param => $value) { 48 | if ($value == '') { 49 | continue; 50 | } 51 | if (is_string($param)) { 52 | $value = str_replace("'", "\'", $value); 53 | $value = htmlentities(trim($value)); 54 | $string .= "{$param}='{$value}' "; 55 | } else { 56 | $value = htmlentities(trim($value)); 57 | $string .= "{$value} "; 58 | } 59 | } 60 | 61 | return trim($string); 62 | } 63 | 64 | /** 65 | * (PHP 5 >= 5.0.0)
66 | * Whether a offset exists 67 | * 68 | * @link http://php.net/manual/en/arrayaccess.offsetexists.php 69 | * @param mixed $offset

70 | * An offset to check for. 71 | *

72 | * @return boolean true on success or false on failure. 73 | *

74 | *

75 | * The return value will be casted to boolean if 76 | * non-boolean was returned. 77 | */ 78 | public function offsetExists($offset) 79 | { 80 | return array_key_exists($offset, $this->attributes); 81 | } 82 | 83 | /** 84 | * (PHP 5 >= 5.0.0)
85 | * Offset to retrieve 86 | * 87 | * @link http://php.net/manual/en/arrayaccess.offsetget.php 88 | * @param mixed $offset

89 | * The offset to retrieve. 90 | *

91 | * @return mixed Can return all value types. 92 | */ 93 | public function offsetGet($offset) 94 | { 95 | return $this->attributes[$offset]; 96 | } 97 | 98 | /** 99 | * (PHP 5 >= 5.0.0)
100 | * Offset to set 101 | * 102 | * @link http://php.net/manual/en/arrayaccess.offsetset.php 103 | * @param mixed $offset

104 | * The offset to assign the value to. 105 | *

106 | * @param mixed $value

107 | * The value to set. 108 | *

109 | * @return void 110 | */ 111 | public function offsetSet($offset, $value) 112 | { 113 | $this->attributes[$offset] = $value; 114 | } 115 | 116 | /** 117 | * (PHP 5 >= 5.0.0)
118 | * Offset to unset 119 | * 120 | * @link http://php.net/manual/en/arrayaccess.offsetunset.php 121 | * @param mixed $offset

122 | * The offset to unset. 123 | *

124 | * @return void 125 | */ 126 | public function offsetUnset($offset) 127 | { 128 | unset($this->attributes[$offset]); 129 | } 130 | 131 | /** 132 | * Adds to to the class attributes 133 | * 134 | * @param $class string The class to add 135 | * @return $this 136 | */ 137 | public function addClass($class) 138 | { 139 | $this->attributes['class'] = isset($this->attributes['class']) ? 140 | trim($this->attributes['class']) . " {$class}" : 141 | $class; 142 | 143 | return $this; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/Bootstrapper/Badge.php: -------------------------------------------------------------------------------- 1 | attributes, ['class' => 'badge']); 29 | 30 | $string = "{$this->contents}"; 31 | 32 | return $string; 33 | } 34 | 35 | /** 36 | * Adds contents to the badge 37 | * 38 | * @param $contents 39 | * @return $this 40 | */ 41 | public function withContents($contents) 42 | { 43 | $this->contents = $contents; 44 | 45 | return $this; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Bootstrapper/BootstrapperL5ServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes( 26 | [ 27 | __DIR__ . '/../config/config.php' => config_path( 28 | 'bootstrapper.php' 29 | ) 30 | ] 31 | ); 32 | $this->mergeConfigFrom( 33 | __DIR__ . '/../config/bootstrapper.php', 34 | 'bootstrapper' 35 | ); 36 | 37 | 38 | $this->registerAccordion(); 39 | $this->registerAlert(); 40 | $this->registerBadge(); 41 | $this->registerBreadcrumb(); 42 | $this->registerButtonGroup(); 43 | $this->registerButton(); 44 | $this->registerCarousel(); 45 | $this->registerConfig(); 46 | $this->registerControlGroup(); 47 | $this->registerDropdownButton(); 48 | $this->registerFormBuilder(); 49 | $this->registerIcon(); 50 | $this->registerImage(); 51 | $this->registerInputGroup(); 52 | $this->registerHelpers(); 53 | $this->registerLabel(); 54 | $this->registerMediaObject(); 55 | $this->registerModal(); 56 | $this->registerNavbar(); 57 | $this->registerNavigation(); 58 | $this->registerPanel(); 59 | $this->registerProgressBar(); 60 | $this->registerTabbable(); 61 | $this->registerTable(); 62 | $this->registerThumbnail(); 63 | } 64 | 65 | /** 66 | * Registers the Accordion class in the IoC 67 | */ 68 | private function registerAccordion() 69 | { 70 | $this->app->bind( 71 | 'bootstrapper::accordion', 72 | function () { 73 | return new Accordion(); 74 | } 75 | ); 76 | } 77 | 78 | /** 79 | * Registers the Alert class in the IoC 80 | */ 81 | private function registerAlert() 82 | { 83 | $this->app->bind( 84 | 'bootstrapper::alert', 85 | function () { 86 | return new Alert(); 87 | } 88 | ); 89 | } 90 | 91 | /** 92 | * Registers the Badge class into the IoC 93 | */ 94 | private function registerBadge() 95 | { 96 | $this->app->bind( 97 | 'bootstrapper::badge', 98 | function () { 99 | return new Badge; 100 | } 101 | ); 102 | } 103 | 104 | /** 105 | * Registers the Breadcrumb class into the IoC 106 | */ 107 | private function registerBreadcrumb() 108 | { 109 | $this->app->bind( 110 | 'bootstrapper::breadcrumb', 111 | function () { 112 | return new Breadcrumb; 113 | } 114 | ); 115 | } 116 | 117 | /** 118 | * Registers the ButtonGroup class into the IoC 119 | */ 120 | private function registerButtonGroup() 121 | { 122 | $this->app->bind( 123 | 'bootstrapper::buttongroup', 124 | function () { 125 | return new ButtonGroup; 126 | } 127 | ); 128 | } 129 | 130 | /** 131 | * Registers the Button class into the IoC 132 | */ 133 | private function registerButton() 134 | { 135 | $this->app->bind( 136 | 'bootstrapper::button', 137 | function () { 138 | return new Button; 139 | } 140 | ); 141 | } 142 | 143 | /** 144 | * Registers the Carousel class into the IoC 145 | */ 146 | private function registerCarousel() 147 | { 148 | $this->app->bind( 149 | 'bootstrapper::carousel', 150 | function () { 151 | return new Carousel; 152 | } 153 | ); 154 | } 155 | 156 | private function registerConfig() 157 | { 158 | $this->app->bind( 159 | 'bootstrapper::config', 160 | function ($app) { 161 | return new Laravel5Config($app->make('config')); 162 | } 163 | ); 164 | } 165 | 166 | /** 167 | * Registers the ControlGroup class into the IoC 168 | */ 169 | private function registerControlGroup() 170 | { 171 | $this->app->bind( 172 | 'bootstrapper::controlgroup', 173 | function ($app) { 174 | return new ControlGroup($app['bootstrapper::form']); 175 | } 176 | ); 177 | } 178 | 179 | /** 180 | * Registers the DropdownButton class into the IoC 181 | */ 182 | private function registerDropdownButton() 183 | { 184 | $this->app->bind( 185 | 'bootstrapper::dropdownbutton', 186 | function () { 187 | return new DropdownButton; 188 | } 189 | ); 190 | } 191 | 192 | /** 193 | * Registers the FormBuilder class into the IoC 194 | */ 195 | private function registerFormBuilder() 196 | { 197 | $this->app->bind( 198 | 'collective::html', 199 | function ($app) { 200 | return new HtmlBuilder($app->make('url'), $app->make('view')); 201 | } 202 | ); 203 | $this->app->bind( 204 | 'bootstrapper::form', 205 | function ($app) { 206 | $form = new Form( 207 | $app->make('collective::html'), 208 | $app->make('url'), 209 | $app->make('view'), 210 | $app['session.store']->token() 211 | ); 212 | 213 | return $form->setSessionStore($app['session.store']); 214 | }, 215 | true 216 | ); 217 | } 218 | 219 | /** 220 | * Registers the Icon class into the IoC 221 | */ 222 | private function registerIcon() 223 | { 224 | $this->app->bind( 225 | 'bootstrapper::icon', 226 | function ($app) { 227 | return new Icon($app['bootstrapper::config']); 228 | } 229 | ); 230 | } 231 | 232 | /** 233 | * Registers the Image class into the IoC 234 | */ 235 | private function registerImage() 236 | { 237 | $this->app->bind( 238 | 'bootstrapper::image', 239 | function () { 240 | return new Image; 241 | } 242 | ); 243 | } 244 | 245 | /** 246 | * Registers the InputGroup class into the IoC 247 | */ 248 | private function registerInputGroup() 249 | { 250 | $this->app->bind( 251 | 'bootstrapper::inputgroup', 252 | function () { 253 | return new InputGroup; 254 | } 255 | ); 256 | } 257 | 258 | /** 259 | * Registers the Label class into the IoC 260 | */ 261 | private function registerLabel() 262 | { 263 | $this->app->bind( 264 | 'bootstrapper::label', 265 | function () { 266 | return new Label; 267 | } 268 | ); 269 | } 270 | 271 | /** 272 | * Registers the Helpers class into the IoC 273 | */ 274 | private function registerHelpers() 275 | { 276 | $this->app->bind( 277 | 'bootstrapper::helpers', 278 | function ($app) { 279 | return new Helpers($app['bootstrapper::config']); 280 | } 281 | ); 282 | } 283 | 284 | /** 285 | * Registers the MediaObject class into the IoC 286 | */ 287 | private function registerMediaObject() 288 | { 289 | $this->app->bind( 290 | 'bootstrapper::mediaobject', 291 | function () { 292 | return new MediaObject; 293 | } 294 | ); 295 | } 296 | 297 | /** 298 | * Registers the Modal class into the IoC 299 | */ 300 | private function registerModal() 301 | { 302 | $this->app->bind( 303 | 'bootstrapper::modal', 304 | function () { 305 | return new Modal; 306 | } 307 | ); 308 | } 309 | 310 | /** 311 | * Registers the Navbar class into the IoC 312 | */ 313 | private function registerNavbar() 314 | { 315 | $this->app->bind( 316 | 'bootstrapper::navbar', 317 | function ($app) { 318 | return new Navbar($app->make('url')); 319 | } 320 | ); 321 | } 322 | 323 | /** 324 | * Registers the Navigation class into the IoC 325 | */ 326 | private function registerNavigation() 327 | { 328 | $this->app->bind( 329 | 'bootstrapper::navigation', 330 | function ($app) { 331 | return new Navigation($app->make('url')); 332 | } 333 | ); 334 | } 335 | 336 | /** 337 | * Registers the Panel class into the IoC 338 | */ 339 | private function registerPanel() 340 | { 341 | $this->app->bind( 342 | 'bootstrapper::panel', 343 | function () { 344 | return new Panel; 345 | } 346 | ); 347 | } 348 | 349 | /** 350 | * Registers the ProgressBar class into the IoC 351 | */ 352 | private function registerProgressBar() 353 | { 354 | $this->app->bind( 355 | 'bootstrapper::progressbar', 356 | function () { 357 | return new ProgressBar; 358 | } 359 | ); 360 | } 361 | 362 | /** 363 | * Registers the Tabbable class into the IoC 364 | */ 365 | private function registerTabbable() 366 | { 367 | $this->app->bind( 368 | 'bootstrapper::tabbable', 369 | function ($app) { 370 | return new Tabbable($app['bootstrapper::navigation']); 371 | } 372 | ); 373 | } 374 | 375 | /** 376 | * Registers the Table class into the IoC 377 | */ 378 | private function registerTable() 379 | { 380 | $this->app->bind( 381 | 'bootstrapper::table', 382 | function () { 383 | return new Table; 384 | } 385 | ); 386 | } 387 | 388 | /** 389 | * Registers the Thumbnail class into the IoC 390 | */ 391 | private function registerThumbnail() 392 | { 393 | $this->app->bind( 394 | 'bootstrapper::thumbnail', 395 | function () { 396 | return new Thumbnail; 397 | } 398 | ); 399 | } 400 | } 401 | -------------------------------------------------------------------------------- /src/Bootstrapper/Breadcrumb.php: -------------------------------------------------------------------------------- 1 | attributes, 29 | ['class' => 'breadcrumb'] 30 | ); 31 | 32 | $string = "
    "; 33 | foreach ($this->links as $text => $link) { 34 | $string .= $this->renderLink($text, $link); 35 | } 36 | $string .= "
"; 37 | 38 | return $string; 39 | } 40 | 41 | /** 42 | * Set the links for the breadcrumbs. Expects an array of the following: 43 | * 47 | * 48 | * @param $links array 49 | * @return $this 50 | */ 51 | public function withLinks(array $links) 52 | { 53 | 54 | $this->links = $links; 55 | 56 | return $this; 57 | } 58 | 59 | /** 60 | * Renders the link 61 | * 62 | * @param $text 63 | * @param $link 64 | * @return string 65 | */ 66 | protected function renderLink($text, $link) 67 | { 68 | $string = ""; 69 | if (is_string($text)) { 70 | $string .= "
  • "; 71 | $string .= "{$text}"; 72 | } else { 73 | $string .= "
  • "; 74 | $string .= $link; 75 | } 76 | $string .= "
  • "; 77 | 78 | return $string; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Bootstrapper/Bridges/Config/ConfigInterface.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 21 | } 22 | 23 | public function getIconPrefix() 24 | { 25 | return $this->repository->get('bootstrapper::icon_prefix'); 26 | } 27 | 28 | public function getIconTag() 29 | { 30 | return $this->repository->get('bootstrapper::icon_tag'); 31 | } 32 | 33 | public function getBootstrapperVersion() 34 | { 35 | return $this->repository->get('bootstrapper::bootstrapVersion'); 36 | } 37 | 38 | public function getJQueryVersion() 39 | { 40 | return $this->repository->get('bootstrapper::jqueryVersion'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Bootstrapper/Bridges/Config/Laravel5Config.php: -------------------------------------------------------------------------------- 1 | repository = $repository; 18 | } 19 | 20 | public function getIconPrefix() 21 | { 22 | return $this->repository->get('bootstrapper.icon_prefix'); 23 | } 24 | 25 | public function getIconTag() 26 | { 27 | return $this->repository->get('bootstrapper.icon_tag'); 28 | } 29 | 30 | public function getBootstrapperVersion() 31 | { 32 | return $this->repository->get('bootstrapper.bootstrapVersion'); 33 | } 34 | 35 | public function getJQueryVersion() 36 | { 37 | return $this->repository->get('bootstrapper.jqueryVersion'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Bootstrapper/Button.php: -------------------------------------------------------------------------------- 1 | type = $type; 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * Sets the size of the button 127 | * 128 | * @param $size string The new size of the button. Assumes that the btn- 129 | * prefix is there 130 | * @return $this 131 | */ 132 | public function setSize($size) 133 | { 134 | $this->size = $size; 135 | 136 | return $this; 137 | } 138 | 139 | /** 140 | * Renders the button 141 | * 142 | * @return string as a string 143 | */ 144 | public function render() 145 | { 146 | // Set up sensible defaults 147 | $defaults = ['type' => 'button', 'class' => "btn {$this->type}"]; 148 | 149 | if ($this->url) { 150 | // An tag should not have a type attribute 151 | unset($defaults['type']); 152 | } 153 | 154 | $attributes = new Attributes($this->attributes, $defaults); 155 | 156 | // Add size and block status if needed 157 | if ($this->size) { 158 | $attributes->addClass($this->size); 159 | } 160 | 161 | if ($this->block) { 162 | $attributes->addClass(self::BLOCK); 163 | } 164 | 165 | // Add the icon if needed 166 | $value = $this->icon ? $this->getValueWithIcon() : $this->value; 167 | 168 | // Set disabled and url 169 | if ($this->disabled) { 170 | $attributes['disabled'] = 'disabled'; 171 | } 172 | 173 | if ($this->url) { 174 | $attributes['href'] = $this->url; 175 | } 176 | 177 | // Create the right tag 178 | $tag = $this->url ? 'a' : 'button'; 179 | 180 | return "<{$tag} {$attributes}>{$value}"; 181 | } 182 | 183 | /** 184 | * Creates a button with class .btn-default and the given contents 185 | * 186 | * @param string $contents The contents of the button The contents of the 187 | * button 188 | * @return Button 189 | */ 190 | public function normal($contents = '') 191 | { 192 | return $this->setType(self::NORMAL) 193 | ->withValue($contents); 194 | } 195 | 196 | /** 197 | * Creates an button with class .btn-primary and the given contents 198 | * 199 | * @param string $contents The contents of the button The contents of the 200 | * button 201 | * @return Button 202 | */ 203 | public function primary($contents = '') 204 | { 205 | return $this->setType(self::PRIMARY) 206 | ->withValue($contents); 207 | } 208 | 209 | /** 210 | * Creates an button with class .btn-success and the given contents 211 | * 212 | * @param string $contents The contents of the button The contents of the 213 | * button 214 | * @return Button 215 | */ 216 | public function success($contents = '') 217 | { 218 | return $this->setType(self::SUCCESS) 219 | ->withValue($contents); 220 | } 221 | 222 | /** 223 | * Creates an button with class .btn-info and the given contents 224 | * 225 | * @param string $contents The contents of the button 226 | * @return Button 227 | */ 228 | public function info($contents = '') 229 | { 230 | return $this->setType(self::INFO) 231 | ->withValue($contents); 232 | } 233 | 234 | /** 235 | * Creates an button with class .btn-warning and the given contents 236 | * 237 | * @param string $contents The contents of the button 238 | * @return Button 239 | */ 240 | public function warning($contents = '') 241 | { 242 | return $this->setType(self::WARNING) 243 | ->withValue($contents); 244 | } 245 | 246 | /** 247 | * Creates an button with class .btn-danger and the given contents 248 | * 249 | * @param string $contents The contents of the button 250 | * @return Button 251 | */ 252 | public function danger($contents = '') 253 | { 254 | return $this->setType(self::DANGER) 255 | ->withValue($contents); 256 | } 257 | 258 | /** 259 | * Creates an button with class .btn-link and the given contents 260 | * 261 | * @param string $contents The contents of the button 262 | * @return Button 263 | */ 264 | public function link($contents = '') 265 | { 266 | return $this->setType(self::LINK) 267 | ->withValue($contents); 268 | } 269 | 270 | /** 271 | * Sets the button to be a block button 272 | * 273 | * @return $this 274 | */ 275 | public function block() 276 | { 277 | $this->block = true; 278 | 279 | return $this; 280 | } 281 | 282 | /** 283 | * Makes the button a submit button 284 | * 285 | * @return $this 286 | */ 287 | public function submit() 288 | { 289 | $this->attributes['type'] = 'submit'; 290 | 291 | return $this; 292 | } 293 | 294 | /** 295 | * Makes the button a reset button 296 | * 297 | * @return $this 298 | */ 299 | public function reset() 300 | { 301 | $this->attributes['type'] = 'reset'; 302 | 303 | return $this; 304 | } 305 | 306 | /** 307 | * Sets the value of the button 308 | * 309 | * @param $value string The new value of the button 310 | * @return $this 311 | */ 312 | public function withValue($value = '') 313 | { 314 | $this->value = $value; 315 | 316 | return $this; 317 | } 318 | 319 | /** 320 | * Sets the button to be a large button 321 | * 322 | * @return $this 323 | */ 324 | public function large() 325 | { 326 | return $this->setSize(self::LARGE); 327 | } 328 | 329 | /** 330 | * Sets the button to be a small button 331 | * 332 | * @return $this 333 | */ 334 | public function small() 335 | { 336 | return $this->setSize(self::SMALL); 337 | } 338 | 339 | /** 340 | * Sets the button to be an extra small button 341 | * 342 | * @return $this 343 | */ 344 | public function extraSmall() 345 | { 346 | return $this->setSize(self::EXTRA_SMALL); 347 | } 348 | 349 | /** 350 | * More descriptive version of withAttributes 351 | * 352 | * @see withAttributes 353 | * @param array $attributes The attributes to add 354 | * @return $this 355 | */ 356 | public function addAttributes(array $attributes) 357 | { 358 | return $this->withAttributes($attributes); 359 | } 360 | 361 | /** 362 | * Disables the button 363 | * 364 | * @return $this 365 | */ 366 | public function disable() 367 | { 368 | $this->disabled = true; 369 | 370 | return $this; 371 | } 372 | 373 | /** 374 | * Adds an icon to the button 375 | * 376 | * @param $icon string The icon to add 377 | * @param bool $append Whether the icon should be added after the text or 378 | * before 379 | * @return $this 380 | */ 381 | public function withIcon($icon, $append = true) 382 | { 383 | $this->icon = $icon; 384 | $this->appendIcon = $append; 385 | 386 | return $this; 387 | } 388 | 389 | /** 390 | * Descriptive version of withIcon(). Adds the icon after the text 391 | * 392 | * @see withIcon 393 | * @param $icon string The icon to add 394 | * @return $this 395 | */ 396 | public function appendIcon($icon) 397 | { 398 | return $this->withIcon($icon, true); 399 | } 400 | 401 | /** 402 | * Descriptive version of withIcon(). Adds the icon before the text 403 | * 404 | * @param $icon string The icon to add 405 | * @return $this 406 | */ 407 | public function prependIcon($icon) 408 | { 409 | return $this->withIcon($icon, false); 410 | } 411 | 412 | /** 413 | * Adds a url to the button, making it a link. This will generate an tag 414 | * 415 | * @param $url string The url to link to 416 | * @return $this 417 | */ 418 | public function asLinkTo($url) 419 | { 420 | $this->url = $url; 421 | 422 | return $this; 423 | } 424 | 425 | /** 426 | * Get the type of the button 427 | * 428 | * @return string 429 | */ 430 | public function getType() 431 | { 432 | return $this->type; 433 | } 434 | 435 | /** 436 | * Get the value of the button. Does not return the value with the icon 437 | * 438 | * @return string 439 | */ 440 | public function getValue() 441 | { 442 | return $this->value; 443 | } 444 | 445 | /** 446 | * Gets the attributes of the button 447 | * 448 | * @return array 449 | */ 450 | public function getAttributes() 451 | { 452 | return $this->attributes; 453 | } 454 | 455 | /** 456 | * Gets the value with the icon 457 | * 458 | * @return string The new value 459 | */ 460 | protected function getValueWithIcon() 461 | { 462 | if ($this->appendIcon) { 463 | return $this->value ? "{$this->value} {$this->icon}" : $this->icon; 464 | } else { 465 | return $this->value ? "{$this->icon} {$this->value}" : $this->icon; 466 | } 467 | } 468 | } 469 | -------------------------------------------------------------------------------- /src/Bootstrapper/ButtonGroup.php: -------------------------------------------------------------------------------- 1 | attributes, 112 | [ 113 | 'class' => $this->vertical ? 'btn-group-vertical' : 'btn-group', 114 | ] 115 | ); 116 | 117 | if (!$this->links) { 118 | $attributes['data-toggle'] = 'buttons'; 119 | } 120 | 121 | if ($this->size) { 122 | $attributes->addClass($this->size); 123 | } 124 | 125 | $contents = $this->renderContents(); 126 | 127 | return "
    {$contents}
    "; 128 | } 129 | 130 | /** 131 | * Sets the size of the button group 132 | * 133 | * @param $size 134 | */ 135 | public function setSize($size) 136 | { 137 | $this->size = $size; 138 | } 139 | 140 | /** 141 | * Sets the button group to be large 142 | * 143 | * @return $this 144 | */ 145 | public function large() 146 | { 147 | $this->setSize(self::LARGE); 148 | 149 | return $this; 150 | } 151 | 152 | /** 153 | * Sets the button group to be small 154 | * 155 | * @return $this 156 | */ 157 | public function small() 158 | { 159 | $this->setSize(self::SMALL); 160 | 161 | return $this; 162 | } 163 | 164 | /** 165 | * Sets the button group to be extra small 166 | * 167 | * @return $this 168 | */ 169 | public function extraSmall() 170 | { 171 | $this->setSize(self::EXTRA_SMALL); 172 | 173 | return $this; 174 | } 175 | 176 | /** 177 | * Sets the button group to be radio 178 | * 179 | * @param array $contents 180 | * @return $this 181 | */ 182 | public function radio(array $contents) 183 | { 184 | return $this->asType(self::RADIO)->withContents($contents); 185 | } 186 | 187 | /** 188 | * Sets the button group to be a checkbox 189 | * 190 | * @param array $contents 191 | * @return $this 192 | */ 193 | public function checkbox(array $contents) 194 | { 195 | return $this->asType(self::CHECKBOX)->withContents($contents); 196 | } 197 | 198 | /** 199 | * Sets the contents of the button group 200 | * 201 | * @param array $contents 202 | * @return $this 203 | */ 204 | public function withContents(array $contents) 205 | { 206 | $this->contents = $contents; 207 | 208 | return $this; 209 | } 210 | 211 | /** 212 | * Sets the button group to be vertical 213 | * 214 | * @return $this 215 | */ 216 | public function vertical() 217 | { 218 | $this->vertical = true; 219 | 220 | return $this; 221 | } 222 | 223 | /** 224 | * Sets the type of the button group 225 | * 226 | * @param $type 227 | * @return $this 228 | */ 229 | public function asType($type) 230 | { 231 | $this->type = $type; 232 | 233 | return $this; 234 | } 235 | 236 | /** 237 | * Renders the contents of the button group 238 | * 239 | * @return string 240 | * @throws ButtonGroupException if a string should be activated 241 | */ 242 | public function renderContents() 243 | { 244 | $contents = ''; 245 | 246 | if ($this->type == 'button') { 247 | foreach ($this->contents as $item) { 248 | $contents .= $item; 249 | } 250 | } else { 251 | foreach ($this->contents as $index => $item) { 252 | $active = in_array($index + 1, $this->activated); 253 | if ($item instanceof Button) { 254 | $class = $item->getType() . ($active ? ' active' : ''); 255 | $value = $item->getValue(); 256 | $attributes = new Attributes( 257 | $item->getAttributes(), 258 | ['type' => $this->type] 259 | ); 260 | 261 | $contents .= ""; 262 | } else { 263 | if ($active) { 264 | throw ButtonGroupException::activatedAString(); 265 | } 266 | $contents .= $item; 267 | } 268 | } 269 | } 270 | 271 | return $contents; 272 | } 273 | 274 | 275 | public function links(array $contents = []) 276 | { 277 | $this->links = true; 278 | 279 | return $this->withContents($contents); 280 | } 281 | 282 | /** 283 | * Sets a link to be activated 284 | * 285 | * @param $toActivate 286 | * @return $this 287 | */ 288 | public function activate($toActivate) 289 | { 290 | $this->activated = is_array($toActivate) ? $toActivate : [$toActivate]; 291 | 292 | return $this; 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /src/Bootstrapper/Carousel.php: -------------------------------------------------------------------------------- 1 | "; 25 | /** 26 | * @var string The icon or text for the control's next slide 27 | */ 28 | protected $nextButton = ""; 29 | 30 | /** 31 | * @var array The contents of the carousel. Should be an array of arrays, 32 | * with the inner arrays having the following keys: 33 | *
    image
    A path to the image
    alt
    The alt 34 | * text for the image
    caption (optional)
    The caption for 35 | * that slide
    36 | */ 37 | protected $contents = []; 38 | 39 | /** 40 | * @var int Which slide should be active at the beginning 41 | */ 42 | protected $active = 0; 43 | 44 | /** 45 | * Names the carousel 46 | * 47 | * @param string $name The name of the carousel 48 | * @return $this 49 | */ 50 | public function named($name) 51 | { 52 | $this->name = $name; 53 | 54 | return $this; 55 | } 56 | 57 | /** 58 | * Set the control icons or text 59 | * 60 | * @param string $previousButton Left arrorw, previous text 61 | * @param string $nextButton right arrow, next string 62 | * @return this 63 | */ 64 | public function withControls($previousButton, $nextButton) 65 | { 66 | $this->previousButton = $previousButton; 67 | $this->nextButton = $nextButton; 68 | return $this; 69 | } 70 | 71 | /** 72 | * Sets the contents of the carousel 73 | * 74 | * @param array $contents The new contents. Should be an array of arrays, 75 | * with the inner keys being "image", "alt" and 76 | * (optionally) "caption" 77 | * @return $this 78 | */ 79 | public function withContents(array $contents) 80 | { 81 | $this->contents = $contents; 82 | 83 | return $this; 84 | } 85 | 86 | /** 87 | * Renders the carousel 88 | * 89 | * @return string 90 | */ 91 | public function render() 92 | { 93 | if (!$this->name) { 94 | $this->name = Helpers::generateId($this); 95 | } 96 | 97 | $attributes = new Attributes( 98 | $this->attributes, 99 | [ 100 | 'id' => $this->name, 101 | 'class' => 'carousel slide', 102 | 'data-ride' => 'carousel' 103 | ] 104 | ); 105 | 106 | $string = "
    "; 107 | $string .= $this->renderIndicators(); 108 | $string .= $this->renderItems(); 109 | $string .= $this->renderControls(); 110 | $string .= "
    "; 111 | 112 | return $string; 113 | } 114 | 115 | /** 116 | * Renders the indicators 117 | * 118 | * @return string 119 | */ 120 | protected function renderIndicators() 121 | { 122 | $string = ""; 132 | 133 | return $string; 134 | } 135 | 136 | /** 137 | * Renders the items of the carousel 138 | * 139 | * @return string 140 | */ 141 | protected function renderItems() 142 | { 143 | $string = "
    "; 92 | 93 | return $string; 94 | } 95 | 96 | /** 97 | * Set the attributes of the control group 98 | * 99 | * @param array $attributes The attributes array 100 | * @return $this 101 | */ 102 | public function withAttributes(array $attributes) 103 | { 104 | $this->attributes = $attributes; 105 | 106 | return $this; 107 | } 108 | 109 | /** 110 | * Adds the contents to the control group 111 | * 112 | * @param string $contents The contents of the control group 113 | * @param null $controlSize |int The size of the form control 114 | * @return $this 115 | * @throws ControlGroupException If is $controlSize set and not between 1 116 | * and 12 117 | */ 118 | public function withContents($contents, $controlSize = null) 119 | { 120 | if (isset($controlSize) && $this->sizeIsInvalid($controlSize)) { 121 | throw new ControlGroupException( 122 | 'That content size is incorrect - it must be between 1 and 12' 123 | ); 124 | } 125 | 126 | $this->contents = $contents; 127 | $this->controlSize = $controlSize; 128 | 129 | return $this; 130 | } 131 | 132 | /** 133 | * Sets the label of the control group 134 | * 135 | * @param string $label The label 136 | * @param null $labelSize |int The size of the label 137 | * @return $this 138 | * @throws ControlGroupException If is $labelSize set and not between 1 139 | * and 12 140 | */ 141 | public function withLabel($label, $labelSize = null) 142 | { 143 | if (isset($labelSize) && $this->sizeIsInvalid($labelSize)) { 144 | throw new ControlGroupException( 145 | 'That label size is incorrect - it must be between 1 and 12' 146 | ); 147 | } 148 | 149 | $this->label = $label; 150 | $this->labelSize = $labelSize; 151 | 152 | return $this; 153 | } 154 | 155 | /** 156 | * Adds a help block 157 | * 158 | * @param string $help The help information 159 | * @return $this 160 | */ 161 | public function withHelp($help) 162 | { 163 | $this->help = $help; 164 | 165 | return $this; 166 | } 167 | 168 | /** 169 | * Adds validation error if occured 170 | * 171 | * @param string $name 172 | * @return $this 173 | */ 174 | public function withValidation($name) 175 | { 176 | if ($this->formBuilder->hasErrors($name)) { 177 | $this->addClass(['has-error']); 178 | $this->withHelp($this->formBuilder->getFormattedError($name)); 179 | } 180 | return $this; 181 | } 182 | 183 | /** 184 | * Generates a full control group with a label, control and help block 185 | * 186 | * @param string $label The label 187 | * @param string $control The form control 188 | * @param string $help The help text 189 | * @param int $labelSize The size of the label 190 | * @param int $controlSize The size of the form control 191 | * @return $this 192 | * @throws ControlGroupException if the sizes are invalid 193 | */ 194 | public function generate( 195 | $label, 196 | $control, 197 | $help = null, 198 | $labelSize = null, 199 | $controlSize = null 200 | ) { 201 | if ($this->sizesAreInvalid($labelSize, $controlSize)) { 202 | throw new ControlGroupException( 203 | 'The label size + control size must be between 1 and 12' 204 | ); 205 | } 206 | 207 | return $this->withLabel($label, $labelSize) 208 | ->withContents($control, $controlSize) 209 | ->withHelp($help); 210 | } 211 | 212 | /** 213 | * Renders the contents if given as an array 214 | * 215 | * @return string 216 | */ 217 | protected function renderArrayContents() 218 | { 219 | $string = ''; 220 | foreach ($this->contents as $item) { 221 | if (isset($item['label'])) { 222 | $string .= call_user_func_array( 223 | [$this->formBuilder, 'label'], 224 | $item['label'] 225 | ) . ' '; 226 | } 227 | 228 | $input_args = $item['input']; 229 | $type = $input_args['type']; 230 | unset($input_args['type']); 231 | 232 | $string .= call_user_func_array( 233 | [$this->formBuilder, $type], 234 | $input_args 235 | ); 236 | 237 | $string .= '
    '; 238 | } 239 | 240 | return $string; 241 | } 242 | 243 | /** 244 | * Renders the label 245 | * 246 | * @return string 247 | */ 248 | public function renderLabel() 249 | { 250 | $string = ''; 251 | 252 | if ($this->labelSize) { 253 | $this->controlSize = $this->controlSize ?: 12 - $this->labelSize; 254 | 255 | $this->label = preg_replace( 256 | "/class=('|\")(.*)('|\")/i", 257 | sprintf('class=${1}${2} col-sm-%s${3}', $this->labelSize), 258 | $this->label 259 | ); 260 | } 261 | 262 | $string .= $this->label; 263 | return $string; 264 | } 265 | 266 | /** 267 | * Creates the div to surround the form control 268 | * 269 | * @return string 270 | */ 271 | public function createControlDiv() 272 | { 273 | return sprintf("
    ", $this->controlSize); 274 | } 275 | 276 | /** 277 | * Checks if both the label size and control size are invalid 278 | * 279 | * @param int $labelSize The size of the label 280 | * @param int $controlSize The size of the control group 281 | * @return bool 282 | */ 283 | protected function sizesAreInvalid($labelSize = null, $controlSize = null) 284 | { 285 | // If both are null then we have a valid size 286 | if (!isset($labelSize) && !isset($controlSize)) { 287 | return false; 288 | } 289 | 290 | // So at least one of these is null 291 | if (isset($labelSize)) { 292 | if ($this->sizeIsInvalid($labelSize)) { 293 | return true; 294 | } 295 | } else { 296 | $labelSize = 0; 297 | } 298 | 299 | if (isset($controlSize)) { 300 | if ($this->sizeIsInvalid($controlSize)) { 301 | return true; 302 | } 303 | } else { 304 | $controlSize = 0; 305 | } 306 | 307 | return $this->sizeIsInvalid($labelSize + $controlSize); 308 | } 309 | 310 | /** 311 | * Checks if the size is invalid 312 | * 313 | * @param int $size The size 314 | * @return bool True if the size is below 1 or greater than 11, 315 | * false otherwise 316 | */ 317 | protected function sizeIsInvalid($size) 318 | { 319 | return $size < 1 || $size > 12; 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /src/Bootstrapper/DropdownButton.php: -------------------------------------------------------------------------------- 1 | "; 19 | 20 | /** 21 | * Constant for primary buttons 22 | */ 23 | const PRIMARY = 'btn-primary'; 24 | 25 | /** 26 | * Constant for danger buttons 27 | */ 28 | const DANGER = 'btn-danger'; 29 | 30 | /** 31 | * Constant for warning buttons 32 | */ 33 | const WARNING = 'btn-warning'; 34 | 35 | /** 36 | * Constant for success buttons 37 | */ 38 | const SUCCESS = 'btn-success'; 39 | 40 | /** 41 | * Constant for default buttons 42 | */ 43 | const NORMAL = 'btn-default'; 44 | 45 | /** 46 | * Constant for info buttons 47 | */ 48 | const INFO = 'btn-info'; 49 | 50 | /** 51 | * Constant for large buttons 52 | */ 53 | const LARGE = 'btn-lg'; 54 | 55 | /** 56 | * Constant for small buttons 57 | */ 58 | const SMALL = 'btn-sm'; 59 | 60 | /** 61 | * Constant for extra small buttons 62 | */ 63 | const EXTRA_SMALL = 'btn-xs'; 64 | 65 | /** 66 | * @var string The label for this button 67 | */ 68 | protected $label; 69 | 70 | /** 71 | * @var array The contents of the dropdown button 72 | */ 73 | protected $contents = []; 74 | 75 | /** 76 | * @var string The type of the button 77 | */ 78 | protected $type = 'btn-default'; 79 | 80 | /** 81 | * @var string The size of the button 82 | */ 83 | protected $size; 84 | 85 | /** 86 | * @var bool Whether the drop icon should be a seperate button 87 | */ 88 | protected $split = false; 89 | 90 | /** 91 | * @var bool Whether the button should drop up 92 | */ 93 | protected $dropup = false; 94 | 95 | /** 96 | * Set the label of the button 97 | * 98 | * @param $label 99 | * @return $this 100 | */ 101 | public function labelled($label) 102 | { 103 | $this->label = $label; 104 | 105 | return $this; 106 | } 107 | 108 | /** 109 | * Set the contents of the button 110 | * 111 | * @param array $contents The contents of the dropdown button 112 | * @return $this 113 | */ 114 | public function withContents(array $contents) 115 | { 116 | $this->contents = $contents; 117 | 118 | return $this; 119 | } 120 | 121 | /** 122 | * Sets the type of the button 123 | * 124 | * @param string $type The type of the button 125 | * @return $this 126 | */ 127 | public function setType($type) 128 | { 129 | $this->type = $type; 130 | 131 | return $this; 132 | } 133 | 134 | /** 135 | * Sets the size of the button 136 | * 137 | * @param string $size The size of the button 138 | * @return $this 139 | */ 140 | public function setSize($size) 141 | { 142 | $this->size = $size; 143 | 144 | return $this; 145 | } 146 | 147 | /** 148 | * Splits the button 149 | * 150 | * @return $this 151 | */ 152 | public function split() 153 | { 154 | $this->split = true; 155 | 156 | return $this; 157 | } 158 | 159 | /** 160 | * Sets the button to drop up 161 | * 162 | * @return $this 163 | */ 164 | public function dropup() 165 | { 166 | $this->dropup = true; 167 | 168 | return $this; 169 | } 170 | 171 | /** 172 | * Creates a normal dropdown button 173 | * 174 | * @param string $label The label 175 | * @return $this 176 | */ 177 | public function normal($label = '') 178 | { 179 | $this->setType(self::NORMAL); 180 | 181 | return $this->labelled($label); 182 | } 183 | 184 | /** 185 | * Creates a primary dropdown button 186 | * 187 | * @param string $label The label 188 | * @return $this 189 | */ 190 | public function primary($label = '') 191 | { 192 | $this->setType(self::PRIMARY); 193 | 194 | return $this->labelled($label); 195 | } 196 | 197 | /** 198 | * Creates a danger dropdown button 199 | * 200 | * @param string $label The label 201 | * @return $this 202 | */ 203 | public function danger($label = '') 204 | { 205 | $this->setType(self::DANGER); 206 | 207 | return $this->labelled($label); 208 | } 209 | 210 | /** 211 | * Creates a warning dropdown button 212 | * 213 | * @param string $label The label 214 | * @return $this 215 | */ 216 | public function warning($label = '') 217 | { 218 | $this->setType(self::WARNING); 219 | 220 | return $this->labelled($label); 221 | } 222 | 223 | /** 224 | * Creates a success dropdown button 225 | * 226 | * @param string $label The label 227 | * @return $this 228 | */ 229 | public function success($label = '') 230 | { 231 | $this->setType(self::SUCCESS); 232 | 233 | return $this->labelled($label); 234 | } 235 | 236 | /** 237 | * Creates a info dropdown button 238 | * 239 | * @param string $label The label 240 | * @return $this 241 | */ 242 | public function info($label = '') 243 | { 244 | $this->setType(self::INFO); 245 | 246 | return $this->labelled($label); 247 | } 248 | 249 | /** 250 | * Sets the size to large 251 | * 252 | * @return $this 253 | */ 254 | public function large() 255 | { 256 | $this->setSize(self::LARGE); 257 | 258 | return $this; 259 | } 260 | 261 | 262 | /** 263 | * Sets the size to small 264 | * 265 | * @return $this 266 | */ 267 | public function small() 268 | { 269 | $this->setSize(self::SMALL); 270 | 271 | return $this; 272 | } 273 | 274 | /** 275 | * Sets the size to extra small 276 | * 277 | * @return $this 278 | */ 279 | public function extraSmall() 280 | { 281 | $this->setSize(self::EXTRA_SMALL); 282 | 283 | return $this; 284 | } 285 | 286 | /** 287 | * Renders the dropdown button 288 | * 289 | * @return string 290 | */ 291 | public function render() 292 | { 293 | if ($this->dropup) { 294 | $string = "
    "; 295 | } else { 296 | $string = "
    "; 297 | } 298 | $attributes = new Attributes( 299 | $this->attributes, 300 | [ 301 | 'class' => "btn {$this->type} dropdown-toggle", 302 | 'data-toggle' => 'dropdown', 303 | 'type' => 'button' 304 | ] 305 | ); 306 | 307 | if ($this->size) { 308 | $attributes->addClass($this->size); 309 | } 310 | 311 | if ($this->split) { 312 | $splitAttributes = new Attributes( 313 | ['class' => $attributes['class'], 'type' => 'button'] 314 | ); 315 | $splitAttributes['class'] = str_replace( 316 | ' dropdown-toggle', 317 | '', 318 | $splitAttributes['class'] 319 | ); 320 | $string .= ""; 321 | $string .= ""; 322 | } else { 323 | $string .= ""; 324 | } 325 | 326 | $string .= ""; 329 | $string .= "
    "; 330 | 331 | return $string; 332 | } 333 | 334 | /** 335 | * Render the inner items 336 | * 337 | * @return string 338 | */ 339 | protected function renderItems() 340 | { 341 | $string = ''; 342 | foreach ($this->contents as $item) { 343 | if (is_array($item)) { 344 | $string .= "
  • {$item['label']}
  • "; 345 | } else { 346 | $string .= $item; 347 | } 348 | } 349 | 350 | return $string; 351 | } 352 | } 353 | -------------------------------------------------------------------------------- /src/Bootstrapper/Exceptions/AccordionException.php: -------------------------------------------------------------------------------- 1 | $method(); 41 | 42 | case 1: 43 | return $instance->$method($args[0]); 44 | 45 | case 2: 46 | return $instance->$method($args[0], $args[1]); 47 | 48 | case 3: 49 | return $instance->$method($args[0], $args[1], $args[2]); 50 | 51 | case 4: 52 | return $instance->$method( 53 | $args[0], 54 | $args[1], 55 | $args[2], 56 | $args[3] 57 | ); 58 | 59 | default: 60 | return call_user_func_array(array($instance, $method), $args); 61 | } 62 | } 63 | 64 | /** 65 | * Get an instance out of the IoC, or the cached instance 66 | * 67 | * @param string $facade The facade accessor 68 | * @return mixed The Bootstrapper object 69 | */ 70 | private static function getInstance($facade) 71 | { 72 | if (!isset(static::$instances[$facade])) { 73 | static::$instances[$facade] = static::getFacadeRoot(); 74 | } 75 | 76 | return static::$instances[$facade]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Bootstrapper/Facades/Breadcrumb.php: -------------------------------------------------------------------------------- 1 | "; 17 | const PRIMARY = 'btn-primary'; 18 | const DANGER = 'btn-danger'; 19 | const WARNING = 'btn-warning'; 20 | const SUCCESS = 'btn-success'; 21 | const INFO = 'btn-info'; 22 | const LARGE = 'btn-lg'; 23 | const SMALL = 'btn-sm'; 24 | const EXTRA_SMALL = 'btn-xs'; 25 | 26 | /** 27 | * {@inheritdoc} 28 | * @return string 29 | */ 30 | protected static function getFacadeAccessor() 31 | { 32 | return 'bootstrapper::dropdownbutton'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Bootstrapper/Facades/Form.php: -------------------------------------------------------------------------------- 1 | open($attributes); 102 | } 103 | 104 | /** 105 | * Opens a horizontal form 106 | * 107 | * @param array $attributes 108 | * @return string 109 | */ 110 | public function horizontal($attributes = []) 111 | { 112 | $attributes['class'] = isset($attributes['class']) ? 113 | self::FORM_HORIZONTAL . ' ' . $attributes['class'] : 114 | self::FORM_HORIZONTAL; 115 | 116 | return $this->open($attributes); 117 | } 118 | 119 | /** 120 | * Creates a validation block 121 | * 122 | * @param string $type The type of validation 123 | * @param string $label The label 124 | * @param string $input The input 125 | * @param array $attributes The attributes of the validation block 126 | * @return string 127 | */ 128 | public function validation($type, $label, $input, $attributes = []) 129 | { 130 | $attributes['class'] = isset($attributes['class']) ? 131 | "form-group {$type} " . $attributes['class'] : 132 | "form-group {$type} "; 133 | $attributes = new Attributes($attributes); 134 | 135 | return "
    {$label}{$input}
    "; 136 | } 137 | 138 | /** 139 | * Creates a success validation block 140 | * 141 | * @param string $label The label 142 | * @param string $input The input 143 | * @param array $attributes The attributes of the validation block 144 | * @return string 145 | * @see Bootstrapper\\Form::validation() 146 | */ 147 | public function success($label, $input, $attributes = []) 148 | { 149 | return ($this->validation( 150 | self::FORM_SUCCESS, 151 | $label, 152 | $input, 153 | $attributes 154 | )); 155 | } 156 | 157 | /** 158 | * Creates a warning validation block 159 | * 160 | * @param string $label The label 161 | * @param string $input The input 162 | * @param array $attributes The attributes of the validation block 163 | * @return string 164 | * @see Bootstrapper\\Form::validation() 165 | */ 166 | public function warning($label, $input, $attributes = []) 167 | { 168 | return ($this->validation( 169 | Form::FORM_WARNING, 170 | $label, 171 | $input, 172 | $attributes 173 | )); 174 | } 175 | 176 | /** 177 | * Creates an error validation block 178 | * 179 | * @param string $label The label 180 | * @param string $input The input 181 | * @param array $attributes The attributes of the validation block 182 | * @return string 183 | * @see Bootstrapper\\Form::validation() 184 | */ 185 | public function error($label, $input, $attributes = []) 186 | { 187 | return ($this->validation( 188 | Form::FORM_ERROR, 189 | $label, 190 | $input, 191 | $attributes 192 | )); 193 | } 194 | 195 | /** 196 | * Creates a feedback block with an icon 197 | * 198 | * @param string $label The label 199 | * @param string $input The input 200 | * @param string $icon The icon 201 | * @param array $attributes The attributes of the block 202 | * @return string 203 | */ 204 | public function feedback($label, $input, $icon, $attributes = []) 205 | { 206 | $attributes['class'] = isset($attributes['class']) ? 207 | 'form-group has-feedback ' . $attributes['class'] : 208 | 'form-group has-feedback'; 209 | $attributes = new Attributes($attributes); 210 | $icon = ""; 211 | 212 | return "
    {$label}{$input}{$icon}
    "; 213 | } 214 | 215 | /** 216 | * Creates a help block 217 | * 218 | * @param string $helpText The help text 219 | * @param array $attributes 220 | * @return string 221 | */ 222 | public function help($helpText, $attributes = []) 223 | { 224 | $attributes['class'] = isset($attributes['class']) ? 225 | 'help-block ' . $attributes['class'] : 226 | 'help-block'; 227 | $attributes = new Attributes($attributes); 228 | 229 | return "{$helpText}"; 230 | } 231 | 232 | /** 233 | * Opens a horizontal form with a given model 234 | * 235 | * @param mixed $model 236 | * @param array $attributes 237 | * @return string 238 | * @see Bootstrapper\Form::horizontal() 239 | * @see Illuminate\Html::model() 240 | */ 241 | public function horizontalModel($model, $attributes = []) 242 | { 243 | $attributes['class'] = isset($attributes['class']) ? 244 | self::FORM_HORIZONTAL . ' ' . $attributes['class'] : 245 | self::FORM_HORIZONTAL; 246 | 247 | return $this->model($model, $attributes); 248 | } 249 | 250 | /** 251 | * Opens a inline form with a given model 252 | * 253 | * @param mixed $model 254 | * @param array $attributes 255 | * @return string 256 | * @see Bootstrapper\Form::inline() 257 | * @see Illuminate\Html::model() 258 | */ 259 | public function inlineModel($model, $attributes = []) 260 | { 261 | $attributes['class'] = isset($attributes['class']) ? 262 | self::FORM_INLINE . ' ' . $attributes['class'] : 263 | self::FORM_INLINE; 264 | 265 | return $this->model($model, $attributes); 266 | } 267 | 268 | /** 269 | * {@inheritdoc} 270 | * @param string $name 271 | * @param array $list 272 | * @param null $selected 273 | * @param array $selectAttributes 274 | * @param array $optionsAttributes 275 | * @return string 276 | */ 277 | public function select( 278 | $name, 279 | $list = [], 280 | $selected = null, 281 | array $selectAttributes = [], 282 | array $optionsAttributes = [], 283 | array $optgroupsAttributes = [] 284 | ) { 285 | $selectAttributes['class'] = isset($selectAttributes['class']) ? 286 | self::FORM_CONTROL . ' ' . $selectAttributes['class'] : 287 | self::FORM_CONTROL; 288 | 289 | return parent::select($name, $list, $selected, $selectAttributes, $optionsAttributes, $optgroupsAttributes); 290 | } 291 | 292 | /** 293 | * {@inheritdoc} 294 | * @param string $name The name of the text area 295 | * @param string|null $value The default value 296 | * @param array $attributes The attributes of the text area 297 | * @return string 298 | */ 299 | public function textarea($name, $value = null, $attributes = array()) 300 | { 301 | $attributes['class'] = isset($attributes['class']) ? 302 | self::FORM_CONTROL . ' ' . $attributes['class'] : 303 | self::FORM_CONTROL; 304 | 305 | return parent::textarea($name, $value, $attributes); 306 | } 307 | 308 | /** 309 | * {@inheritdoc} 310 | * @param string $name The name of the password input 311 | * @param array $attributes The attributes of the input 312 | * @return string 313 | */ 314 | public function password($name, $attributes = array()) 315 | { 316 | $attributes['class'] = isset($attributes['class']) ? 317 | self::FORM_CONTROL . ' ' . $attributes['class'] : 318 | self::FORM_CONTROL; 319 | 320 | return parent::password($name, $attributes); 321 | } 322 | 323 | /** 324 | * {@inheritdoc} 325 | * @param string $name The name of the text input 326 | * @param string|null $value The default value 327 | * @param array $attributes The attributes of the input 328 | * @return string 329 | */ 330 | public function text($name, $value = null, $attributes = array()) 331 | { 332 | $attributes['class'] = isset($attributes['class']) ? 333 | self::FORM_CONTROL . ' ' . $attributes['class'] : 334 | self::FORM_CONTROL; 335 | 336 | return parent::text($name, $value, $attributes); 337 | } 338 | 339 | /** 340 | * {@inheritdoc} 341 | * @param string $name The name of the email input 342 | * @param string|null $value The default value of the input 343 | * @param array $attributes The attributes of the email input 344 | * @return string 345 | */ 346 | public function email($name, $value = null, $attributes = array()) 347 | { 348 | $attributes['class'] = isset($attributes['class']) ? 349 | self::FORM_CONTROL . ' ' . $attributes['class'] : 350 | self::FORM_CONTROL; 351 | 352 | return parent::email($name, $value, $attributes); 353 | } 354 | 355 | /** 356 | * Creates a datetime form element 357 | * 358 | * @param string $name The name of the element 359 | * @param null $value The value 360 | * @param array $attributes The attributes 361 | * @return string 362 | * @see Illuminate\FormBuilder\input() 363 | */ 364 | public function datetime($name, $value = null, $attributes = array()) 365 | { 366 | $attributes['class'] = isset($attributes['class']) ? 367 | self::FORM_CONTROL . ' ' . $attributes['class'] : 368 | self::FORM_CONTROL; 369 | 370 | return parent::input('datetime', $name, $value, $attributes); 371 | } 372 | 373 | /** 374 | * Creates a datetime local element 375 | * 376 | * @param string $name The name of the element 377 | * @param null $value 378 | * @param array $attributes 379 | * @return string 380 | * @see Illuminate\FormBuilder\input() 381 | */ 382 | public function datetimelocal($name, $value = null, $attributes = array()) 383 | { 384 | $attributes['class'] = isset($attributes['class']) ? 385 | self::FORM_CONTROL . ' ' . $attributes['class'] : 386 | self::FORM_CONTROL; 387 | 388 | return parent::input('datetime-local', $name, $value, $attributes); 389 | } 390 | 391 | /** 392 | * Creates a date input 393 | * 394 | * @param string $name The name of the element 395 | * @param null $value 396 | * @param array $attributes 397 | * @return string 398 | */ 399 | public function date($name, $value = null, $attributes = array()) 400 | { 401 | $attributes['class'] = isset($attributes['class']) ? 402 | self::FORM_CONTROL . ' ' . $attributes['class'] : 403 | self::FORM_CONTROL; 404 | 405 | return parent::input('date', $name, $value, $attributes); 406 | } 407 | 408 | /** 409 | * Creates a month input 410 | * 411 | * @param string $name The name of the element 412 | * @param null $value 413 | * @param array $attributes 414 | * @return string 415 | */ 416 | public function month($name, $value = null, $attributes = array()) 417 | { 418 | $attributes['class'] = isset($attributes['class']) ? 419 | self::FORM_CONTROL . ' ' . $attributes['class'] : 420 | self::FORM_CONTROL; 421 | 422 | return parent::input('month', $name, $value, $attributes); 423 | } 424 | 425 | /** 426 | * Creates a week form element 427 | * 428 | * @param string $name The name of the element 429 | * @param null $value 430 | * @param array $attributes 431 | * @return string 432 | */ 433 | public function week($name, $value = null, $attributes = array()) 434 | { 435 | $attributes['class'] = isset($attributes['class']) ? 436 | self::FORM_CONTROL . ' ' . $attributes['class'] : 437 | self::FORM_CONTROL; 438 | 439 | return parent::input('week', $name, $value, $attributes); 440 | } 441 | 442 | /** 443 | * Creates a time form element 444 | * 445 | * @param string $name The name of the element 446 | * @param null $value 447 | * @param array $attributes 448 | * @return string 449 | */ 450 | public function time($name, $value = null, $attributes = array()) 451 | { 452 | $attributes['class'] = isset($attributes['class']) ? 453 | self::FORM_CONTROL . ' ' . $attributes['class'] : 454 | self::FORM_CONTROL; 455 | 456 | return parent::input('time', $name, $value, $attributes); 457 | } 458 | 459 | /** 460 | * Creates a number form element 461 | * 462 | * @param string $name The name of the element 463 | * @param null $value 464 | * @param array $attributes 465 | * @return string 466 | */ 467 | public function number($name, $value = null, $attributes = array()) 468 | { 469 | $attributes['class'] = isset($attributes['class']) ? 470 | self::FORM_CONTROL . ' ' . $attributes['class'] : 471 | self::FORM_CONTROL; 472 | 473 | return parent::input('number', $name, $value, $attributes); 474 | } 475 | 476 | /** 477 | * Creates a url form element 478 | * 479 | * @param string $name The name of the element 480 | * @param null $value 481 | * @param array $attributes 482 | * @return string 483 | */ 484 | public function url($name, $value = null, $attributes = array()) 485 | { 486 | $attributes['class'] = isset($attributes['class']) ? 487 | self::FORM_CONTROL . ' ' . $attributes['class'] : 488 | self::FORM_CONTROL; 489 | 490 | return parent::input('url', $name, $value, $attributes); 491 | } 492 | 493 | /** 494 | * Creates a search element 495 | * 496 | * @param string $name The name of the element 497 | * @param null $value 498 | * @param array $attributes 499 | * @return string 500 | */ 501 | public function search($name, $value = null, $attributes = array()) 502 | { 503 | $attributes['class'] = isset($attributes['class']) ? 504 | self::FORM_CONTROL . ' ' . $attributes['class'] : 505 | self::FORM_CONTROL; 506 | 507 | return parent::input('search', $name, $value, $attributes); 508 | } 509 | 510 | /** 511 | * Creates a tel element 512 | * 513 | * @param string $name The name of the element 514 | * @param null $value 515 | * @param array $attributes 516 | * @return string 517 | */ 518 | public function tel($name, $value = null, $attributes = array()) 519 | { 520 | $attributes['class'] = isset($attributes['class']) ? 521 | self::FORM_CONTROL . ' ' . $attributes['class'] : 522 | self::FORM_CONTROL; 523 | 524 | return parent::input('tel', $name, $value, $attributes); 525 | } 526 | 527 | /** 528 | * Creates a color element 529 | * 530 | * @param string $name The name of the element 531 | * @param null $value 532 | * @param array $attributes 533 | * @return string 534 | */ 535 | public function color($name, $value = null, $attributes = array()) 536 | { 537 | $attributes['class'] = isset($attributes['class']) ? 538 | self::FORM_CONTROL . ' ' . $attributes['class'] : 539 | self::FORM_CONTROL; 540 | 541 | return parent::input('color', $name, $value, $attributes); 542 | } 543 | 544 | /** 545 | * Determine whether the form element with the given name 546 | * has any validation errors. 547 | * 548 | * @param string $name 549 | * @return bool 550 | */ 551 | public function hasErrors($name) 552 | { 553 | $session = $this->getSessionStore(); 554 | if (is_null($session) || !$session->has('errors')) { 555 | // If the session is not set, or the session doesn't contain 556 | // any errors, the form element does not have any errors 557 | // applied to it. 558 | return false; 559 | } 560 | // Get the errors from the session. 561 | $errors = $session->get('errors'); 562 | // Check if the errors contain the form element with the given name. 563 | return $errors->has($this->transformKey($name)); 564 | } 565 | 566 | /** 567 | * Get the formatted errors for the form element with the given name. 568 | * 569 | * @param string $name 570 | * @return string 571 | */ 572 | public function getFormattedError($name) 573 | { 574 | if (!$this->hasErrors($name)) { 575 | // If the form element does not have any errors, return 576 | // an emptry string. 577 | return ''; 578 | } 579 | // Get the errors from the session. 580 | $errors = $this->getSessionStore()->get('errors'); 581 | 582 | // Return the formatted error message, if the form element has any. 583 | return $errors->first($this->transformKey($name), $this->help(':message')); 584 | } 585 | } 586 | -------------------------------------------------------------------------------- /src/Bootstrapper/Helpers.php: -------------------------------------------------------------------------------- 1 | config = $config; 39 | } 40 | 41 | /** 42 | * Slugifies a string 43 | * 44 | * @param string $string 45 | * @return mixed 46 | */ 47 | public static function slug($string) 48 | { 49 | return preg_replace('/[^A-Za-z0-9-]+/', '-', strtolower($string)); 50 | } 51 | 52 | /** 53 | * Outputs a link to the Bootstrap CDN 54 | * 55 | * @param bool $withTheme Gets the bootstrap theme as well 56 | * @return string 57 | */ 58 | public function css($withTheme = true) 59 | { 60 | $version = $this->config->getBootstrapperVersion(); 61 | $string = ""; 62 | if ($withTheme) { 63 | $string .= ""; 65 | } 66 | 67 | return $string; 68 | } 69 | 70 | /** 71 | * Outputs a link to the Jquery and Bootstrap CDN 72 | * 73 | * @return string 74 | */ 75 | public function js() 76 | { 77 | $jquery = $this->config->getJQueryVersion(); 78 | $bootstrap = $this->config->getBootstrapperVersion(); 79 | 80 | return "" 81 | . ""; 82 | } 83 | 84 | /** 85 | * Generate an id of the form "x-class-name-x". These should always be 86 | * unique. 87 | * 88 | * @param RenderedObject $caller The object that called this 89 | * @return string A unique id 90 | */ 91 | public static function generateId(RenderedObject $caller) 92 | { 93 | $class = get_class($caller); 94 | 95 | if (isset(self::$counts[$class])) { 96 | $count = self::$counts[$class]; 97 | self::$counts[$class] += 1; 98 | } else { 99 | $count = 1; 100 | self::$counts[$class] = 2; 101 | } 102 | 103 | return static::slug(implode(' ', [$count, $class, $count])); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Bootstrapper/Icon.php: -------------------------------------------------------------------------------- 1 | config = $config; 37 | } 38 | 39 | /** 40 | * Renders the object 41 | * 42 | * @return string 43 | * @throws IconException 44 | */ 45 | public function render() 46 | { 47 | if (is_null($this->icon)) { 48 | throw IconException::noIconSpecified(); 49 | } 50 | 51 | $baseClass = $this->config->getIconPrefix(); 52 | $icon = $this->icon; 53 | $attributes = new Attributes( 54 | $this->attributes, 55 | [ 56 | 'class' => "$baseClass $baseClass-$icon" 57 | ] 58 | ); 59 | 60 | $tag = $this->config->getIconTag(); 61 | 62 | return "<$tag $attributes>"; 63 | } 64 | 65 | /** 66 | * Creates a span link with the correct icon link 67 | * 68 | * @param string $icon The icon name 69 | * @return string 70 | */ 71 | public function create($icon) 72 | { 73 | $this->icon = $this->normaliseIconString($icon); 74 | 75 | return $this; 76 | } 77 | 78 | /** 79 | * Magic method to create icons. Meaning the $icon->test is the same as 80 | * $icon->create('test') 81 | * 82 | * @param $method The icon name 83 | * @param $parameters The parameters. Not used 84 | * @return string 85 | */ 86 | public function __call($method, $parameters) 87 | { 88 | return $this->create($method); 89 | } 90 | 91 | /** 92 | * Replaces underscores with a minus sign, and convert camelCase to dash 93 | * separated 94 | * 95 | * @param string $icon 96 | * @return string 97 | */ 98 | private function normaliseIconString($icon) 99 | { 100 | // replace underscores with minus sign 101 | // and transform from camelCaseString to camel-case-string 102 | $icon = strtolower( 103 | preg_replace( 104 | '/(?<=\\w)(?=[A-Z])/', 105 | "-$1", 106 | str_replace('_', '-', $icon) 107 | ) 108 | ); 109 | 110 | return $icon; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Bootstrapper/Image.php: -------------------------------------------------------------------------------- 1 | src) { 57 | throw new ImageException("You must specify the source"); 58 | } 59 | 60 | $attributes = new Attributes( 61 | $this->attributes, 62 | ['src' => $this->src, 'alt' => $this->alt] 63 | ); 64 | 65 | return ""; 66 | } 67 | 68 | /** 69 | * Sets the source of the image 70 | * 71 | * @param string $source The source of the image 72 | * @return $this 73 | */ 74 | public function withSource($source) 75 | { 76 | $this->src = $source; 77 | 78 | return $this; 79 | } 80 | 81 | /** 82 | * Sets the alt text of the image 83 | * 84 | * @param string $alt The alt text of the image 85 | * @return $this 86 | */ 87 | public function withAlt($alt) 88 | { 89 | $this->alt = $alt; 90 | 91 | return $this; 92 | } 93 | 94 | /** 95 | * Sets the image to be responsive 96 | * 97 | * @return $this 98 | */ 99 | public function responsive() 100 | { 101 | $this->addClass([self::IMAGE_RESPONSIVE]); 102 | 103 | return $this; 104 | } 105 | 106 | /** 107 | * Creates a rounded image 108 | * 109 | * @param null|string $src The source of the image. Pass null to use the 110 | * previous value of the source 111 | * @param null|string $alt The alt text of the image. Pass null to use 112 | * the previous value 113 | * @return $this 114 | */ 115 | public function rounded($src = null, $alt = null) 116 | { 117 | $this->addClass([self::IMAGE_ROUNDED]); 118 | 119 | if (!isset($src)) { 120 | $src = $this->src; 121 | } 122 | if (!isset($alt)) { 123 | $alt = $this->alt; 124 | } 125 | 126 | return $this->withSource($src)->withAlt($alt); 127 | } 128 | 129 | /** 130 | * Creates a circle image 131 | * 132 | * @param null|string $src The source of the image. Pass null to use the 133 | * previous value of the source 134 | * @param null|string $alt The alt text of the image. Pass null to use 135 | * the previous value 136 | * @return $this 137 | */ 138 | public function circle($src = null, $alt = null) 139 | { 140 | $this->addClass([self::IMAGE_CIRCLE]); 141 | 142 | if (!isset($src)) { 143 | $src = $this->src; 144 | } 145 | if (!isset($alt)) { 146 | $alt = $this->alt; 147 | } 148 | 149 | return $this->withSource($src)->withAlt($alt); 150 | } 151 | 152 | /** 153 | * Creates a thumbnail image 154 | * 155 | * @param null|string $src The source of the image. Pass null to use the 156 | * previous value of the source 157 | * @param null|string $alt The alt text of the image. Pass null to use 158 | * the previous value 159 | * @return $this 160 | */ 161 | public function thumbnail($src = null, $alt = null) 162 | { 163 | $this->addClass([self::IMAGE_THUMBNAIL]); 164 | 165 | if (!isset($src)) { 166 | $src = $this->src; 167 | } 168 | if (!isset($alt)) { 169 | $alt = $this->alt; 170 | } 171 | 172 | return $this->withSource($src)->withAlt($alt); 173 | } 174 | 175 | /** 176 | * BC version of Image::addClass() 177 | * 178 | * @param string|array $class 179 | * @return $this 180 | */ 181 | public function addClass($class) 182 | { 183 | if (is_string($class)) { 184 | trigger_error( 185 | 'Passing strings to Image::getClass ' . 186 | 'is depreciated, and will be removed in a future version of ' . 187 | 'Bootstrapper', 188 | E_USER_DEPRECATED 189 | ); 190 | $class = [$class]; 191 | } 192 | 193 | return parent::addClass($class); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/Bootstrapper/InputGroup.php: -------------------------------------------------------------------------------- 1 | "input-group {$this->size}"]; 54 | $attributes = new Attributes($this->attributes, $attributes); 55 | 56 | $string = "
    "; 57 | if (is_array($this->prepend)) { 58 | $string .= $this->renderAddon($this->prepend); 59 | } 60 | 61 | $string .= $this->contents; 62 | 63 | if (is_array($this->append)) { 64 | $string .= $this->renderAddon($this->append); 65 | } 66 | 67 | $string .= "
    "; 68 | 69 | return $string; 70 | } 71 | 72 | /** 73 | * Renders an addon 74 | * 75 | * @param array $addon The addon to render 76 | * @return string 77 | */ 78 | protected function renderAddon(array $addon) 79 | { 80 | $string = ""; 81 | if ($addon['isButton']) { 82 | $string .= ""; 83 | } else { 84 | $string .= ""; 85 | } 86 | $string .= $addon['value']; 87 | $string .= ""; 88 | 89 | return $string; 90 | } 91 | 92 | 93 | /** 94 | * Sets the contents of the input group 95 | * 96 | * @param string $contents The new contents 97 | * @return $this 98 | */ 99 | public function withContents($contents) 100 | { 101 | $this->contents = $contents; 102 | 103 | return $this; 104 | } 105 | 106 | /** 107 | * Sets the size of the input group 108 | * 109 | * @param string $size The new size 110 | * @return $this 111 | */ 112 | public function setSize($size) 113 | { 114 | $this->size = $size; 115 | 116 | return $this; 117 | } 118 | 119 | /** 120 | * Prepends something to the input 121 | * 122 | * @param string $prepend The value to prepend 123 | * @param bool $isButton Whether the value is a button 124 | * @return $this 125 | */ 126 | public function prepend($prepend, $isButton = false) 127 | { 128 | $this->prepend = ['value' => $prepend, 'isButton' => $isButton]; 129 | 130 | return $this; 131 | } 132 | 133 | /** 134 | * Prepend a button 135 | * 136 | * @param string $button The button to prepend 137 | * @return $this 138 | */ 139 | public function prependButton($button) 140 | { 141 | return $this->prepend($button, true); 142 | } 143 | 144 | /** 145 | * Appends something to the input 146 | * 147 | * @param string $append The value to append 148 | * @param bool $isButton Whether the value is a button 149 | * @return $this 150 | */ 151 | public function append($append, $isButton = false) 152 | { 153 | $this->append = ['value' => $append, 'isButton' => $isButton]; 154 | 155 | return $this; 156 | } 157 | 158 | /** 159 | * Append a button 160 | * 161 | * @param string $button The button to append 162 | * @return $this 163 | */ 164 | public function appendButton($button) 165 | { 166 | return $this->append($button, true); 167 | } 168 | 169 | /** 170 | * Makes the input group large 171 | * 172 | * @return $this 173 | */ 174 | public function large() 175 | { 176 | $this->setSize(self::LARGE); 177 | 178 | return $this; 179 | } 180 | 181 | /** 182 | * Makes the input group small 183 | * 184 | * @return $this 185 | */ 186 | public function small() 187 | { 188 | $this->setSize(self::SMALL); 189 | 190 | return $this; 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/Bootstrapper/Interfaces/TableInterface.php: -------------------------------------------------------------------------------- 1 | attributes, 65 | [ 66 | 'class' => "label {$this->type}" 67 | ] 68 | ); 69 | 70 | return "{$this->contents}"; 71 | } 72 | 73 | /** 74 | * Sets the contents of the label 75 | * 76 | * @param string $contents The new contents of the label 77 | * @return $this 78 | */ 79 | public function withContents($contents) 80 | { 81 | $this->contents = $contents; 82 | 83 | return $this; 84 | } 85 | 86 | /** 87 | * Sets the type of the label. Assumes that the label- prefix is already set 88 | * 89 | * @param string $type The new type 90 | * @return $this 91 | */ 92 | public function setType($type) 93 | { 94 | $this->type = $type; 95 | 96 | return $this; 97 | } 98 | 99 | /** 100 | * Creates a primary label 101 | * 102 | * @param string $contents The contents of the label 103 | * @return $this 104 | */ 105 | public function primary($contents = '') 106 | { 107 | $this->setType(self::LABEL_PRIMARY); 108 | 109 | return $this->withContents($contents); 110 | } 111 | 112 | /** 113 | * Creates a success label 114 | * 115 | * @param string $contents The contents of the label 116 | * @return $this 117 | */ 118 | public function success($contents = '') 119 | { 120 | $this->setType(self::LABEL_SUCCESS); 121 | 122 | return $this->withContents($contents); 123 | } 124 | 125 | /** 126 | * Creates an info label 127 | * 128 | * @param string $contents The contents of the label 129 | * @return $this 130 | */ 131 | public function info($contents = '') 132 | { 133 | $this->setType(self::LABEL_INFO); 134 | 135 | return $this->withContents($contents); 136 | } 137 | 138 | /** 139 | * Creates a warning label 140 | * 141 | * @param string $contents The contents of the label 142 | * @return $this 143 | */ 144 | public function warning($contents = '') 145 | { 146 | $this->setType(self::LABEL_WARNING); 147 | 148 | return $this->withContents($contents); 149 | } 150 | 151 | /** 152 | * Creates a danger label 153 | * 154 | * @param string $contents The contents of the label 155 | * @return $this 156 | */ 157 | public function danger($contents = '') 158 | { 159 | $this->setType(self::LABEL_DANGER); 160 | 161 | return $this->withContents($contents); 162 | } 163 | 164 | /** 165 | * Creates a label 166 | * 167 | * @param string $contents The contents of the label 168 | * @param string $type The type to use 169 | * @return $this 170 | */ 171 | public function create($contents, $type = self::LABEL_DEFAULT) 172 | { 173 | $this->setType($type); 174 | 175 | return $this->withContents($contents); 176 | } 177 | 178 | /** 179 | * Creates a normal label 180 | * 181 | * @param string $contents The contents of the label 182 | * @return $this 183 | */ 184 | public function normal($contents = '') 185 | { 186 | $this->setType(self::LABEL_DEFAULT); 187 | 188 | return $this->withContents($contents); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/Bootstrapper/MediaObject.php: -------------------------------------------------------------------------------- 1 | list) { 37 | return $this->renderList(); 38 | } 39 | 40 | if (!$this->contents) { 41 | throw new MediaObjectException( 42 | "You need to give the object some contents" 43 | ); 44 | } 45 | 46 | return $this->renderItem($this->contents, 'div'); 47 | } 48 | 49 | /** 50 | * Sets the contents of the media object 51 | * 52 | * @param array $contents The contents of the media object 53 | * @return $this 54 | */ 55 | public function withContents(array $contents) 56 | { 57 | $this->contents = $contents; 58 | 59 | // Check if it's an array of arrays 60 | $this->list = isset($contents[0]); 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * Force the media object to become a list 67 | * 68 | * @return $this 69 | */ 70 | public function asList() 71 | { 72 | $this->list = true; 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * Renders a list 79 | * 80 | * @return string 81 | */ 82 | protected function renderList() 83 | { 84 | $attributes = new Attributes( 85 | $this->attributes, 86 | ['class' => 'media-list'] 87 | ); 88 | 89 | $this->attributes = []; 90 | 91 | $string = "
      "; 92 | foreach ($this->contents as $item) { 93 | $string .= $this->renderItem($item, 'li'); 94 | } 95 | $string .= "
    "; 96 | 97 | return $string; 98 | } 99 | 100 | /** 101 | * Renders an item in the string 102 | * 103 | * @param array $contents 104 | * @param string $tag The tag to wrap the item in 105 | * @return string 106 | * @throws MediaObjectException 107 | */ 108 | protected function renderItem(array $contents, $tag) 109 | { 110 | $position = $this->getPosition($contents); 111 | $heading = $this->getHeading($contents); 112 | $image = $this->getImage($contents, $heading); 113 | $link = $this->getLink($contents, $image, $position); 114 | $body = $this->getBody($contents); 115 | 116 | $attributes = new Attributes($this->attributes, ['class' => 'media']); 117 | 118 | $string = "<{$tag} {$attributes}>"; 119 | $string .= $link; 120 | $string .= "
    "; 121 | 122 | if ($heading) { 123 | $string .= "

    {$heading}

    "; 124 | } 125 | 126 | $string .= $body; 127 | $string .= "
    "; 128 | 129 | return $string; 130 | } 131 | 132 | /** 133 | * Get the position 134 | * 135 | * @param array $contents 136 | * @return string pull-right if the position key equals right. pull-left 137 | * otherwise 138 | */ 139 | protected function getPosition(array $contents) 140 | { 141 | if (isset($contents['position']) && $contents['position'] == 'right') { 142 | return 'pull-right'; 143 | } 144 | 145 | return 'pull-left'; 146 | } 147 | 148 | /** 149 | * Get the image of the media object 150 | * 151 | * @param array $contents 152 | * @param string $alt The alt text of the image 153 | * @return string 154 | * @throws MediaObjectException if there is no image set 155 | */ 156 | protected function getImage(array $contents, $alt) 157 | { 158 | if (!isset($contents['image'])) { 159 | throw new MediaObjectException( 160 | "You must pass in an image to each object" 161 | ); 162 | } 163 | $image = $contents['image']; 164 | 165 | $attributes = new Attributes( 166 | ['class' => 'media-object', 'src' => $image, 'alt' => $alt] 167 | ); 168 | 169 | return ""; 170 | } 171 | 172 | /** 173 | * Get the heading of the media object 174 | * 175 | * @param array $contents 176 | * @return string 177 | */ 178 | protected function getHeading(array $contents) 179 | { 180 | return isset($contents['heading']) ? $contents['heading'] : ''; 181 | } 182 | 183 | /** 184 | * Turn the image into a link/div 185 | * 186 | * @param array $contents The contents array 187 | * @param string $image The image 188 | * @param string $position The position 189 | * @return string 190 | */ 191 | protected function getLink(array $contents, $image, $position) 192 | { 193 | if (isset($contents['link'])) { 194 | return "{$image}"; 195 | } 196 | 197 | return "
    {$image}
    "; 198 | } 199 | 200 | /** 201 | * Get the body of the contents array 202 | * 203 | * @param array $contents 204 | * @return string 205 | * @throws MediaObjectException if the body key has not been set 206 | */ 207 | protected function getBody(array $contents) 208 | { 209 | if (!isset($contents['body'])) { 210 | throw new MediaObjectException( 211 | 'You must pass in the body to each object' 212 | ); 213 | } 214 | 215 | $string = $contents['body']; 216 | 217 | if (isset($contents['nest'])) { 218 | $object = new MediaObject(); 219 | $string .= $object->withContents($contents['nest']); 220 | } 221 | 222 | return $string; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/Bootstrapper/Modal.php: -------------------------------------------------------------------------------- 1 | attributes, ['class' => 'modal']); 49 | 50 | $string = $this->renderButton($attributes); 51 | 52 | $string .= "
    "; 59 | 60 | return $string; 61 | } 62 | 63 | /** 64 | * Sets the title of the modal 65 | * 66 | * @param string $title 67 | * @return $this 68 | */ 69 | public function withTitle($title) 70 | { 71 | $this->title = $title; 72 | 73 | return $this; 74 | } 75 | 76 | /** 77 | * Renders the header of the modal 78 | * 79 | * @return string 80 | */ 81 | protected function renderHeader() 82 | { 83 | $title = ''; 84 | if ($this->title) { 85 | $title .= ""; 86 | } 87 | 88 | return ""; 90 | } 91 | 92 | /** 93 | * Sets the body of the modal 94 | * 95 | * @param string $body The new body of the modal 96 | * @return $this 97 | */ 98 | public function withBody($body) 99 | { 100 | $this->body = $body; 101 | 102 | return $this; 103 | } 104 | 105 | /** 106 | * Renders the body 107 | * 108 | * @return string 109 | */ 110 | protected function renderBody() 111 | { 112 | return $this->body ? "" : ''; 113 | } 114 | 115 | /** 116 | * Renders the footer 117 | * 118 | * @return string 119 | */ 120 | protected function renderFooter() 121 | { 122 | return $this->footer ? "" : ''; 123 | } 124 | 125 | /** 126 | * Set the footer of the modal 127 | * 128 | * @param string $footer The footer 129 | * @return $this 130 | */ 131 | public function withFooter($footer) 132 | { 133 | $this->footer = $footer; 134 | 135 | return $this; 136 | } 137 | 138 | /** 139 | * Sets the name of the modal 140 | * 141 | * @param string $name The name of the modal 142 | * @return $this 143 | */ 144 | public function named($name) 145 | { 146 | $this->name = $name; 147 | $this->attributes['id'] = $name; 148 | 149 | return $this; 150 | } 151 | 152 | /** 153 | * Sets the button 154 | * 155 | * @param Button $button The button to open the modal with 156 | * @return $this 157 | */ 158 | public function withButton(Button $button = null) 159 | { 160 | if ($button) { 161 | $this->button = $button; 162 | } else { 163 | $button = new Button(); 164 | 165 | $this->button = $button->withValue('Open Modal'); 166 | } 167 | 168 | return $this; 169 | } 170 | 171 | /** 172 | * Renders the button 173 | * 174 | * @param Attributes $attributes The attributes of the modal 175 | * @return string 176 | */ 177 | protected function renderButton(Attributes $attributes) 178 | { 179 | if (!$this->button) { 180 | return ''; 181 | } 182 | 183 | if (!isset($attributes['id'])) { 184 | $attributes['id'] = Helpers::generateId($this); 185 | } 186 | 187 | $this->button->addAttributes( 188 | ['data-toggle' => 'modal', 'data-target' => "#{$attributes['id']}"] 189 | )->render(); 190 | 191 | return $this->button->render(); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/Bootstrapper/Navbar.php: -------------------------------------------------------------------------------- 1 | url = $url; 76 | } 77 | 78 | /** 79 | * Renders the navbar 80 | * 81 | * @return string 82 | */ 83 | public function render() 84 | { 85 | $attributes = new Attributes( 86 | $this->attributes, 87 | [ 88 | 'class' => "navbar {$this->type} {$this->position}", 89 | 'role' => 'navigation' 90 | ] 91 | ); 92 | 93 | $string = "
    "; 94 | $string .= $this->fluid ? 95 | "
    " : 96 | "
    "; 97 | $string .= $this->renderHeader(); 98 | $string .= $this->renderContent(); 99 | $string .= "
    "; 100 | 101 | return $string; 102 | } 103 | 104 | /** 105 | * Renders the inner content 106 | * 107 | * @return string 108 | */ 109 | protected function renderContent() 110 | { 111 | $string = ""; 121 | 122 | return $string; 123 | } 124 | 125 | /** 126 | * Renders the header 127 | * 128 | * @return string 129 | */ 130 | protected function renderHeader() 131 | { 132 | $string = ""; 141 | 142 | return $string; 143 | } 144 | 145 | /** 146 | * Sets the brand of the navbar 147 | * 148 | * @param string $brand The brand 149 | * @param null|string $link The link. If not set we default to linking to 150 | * '/' using the UrlGenerator 151 | * @return $this 152 | */ 153 | public function withBrand($brand, $link = null) 154 | { 155 | if (!isset($link)) { 156 | $link = $this->url->to('/'); 157 | } 158 | 159 | $this->brand = compact('brand', 'link'); 160 | 161 | return $this; 162 | } 163 | 164 | /** 165 | * Sets the brand of the navbar 166 | * 167 | * @param string $image The brand image 168 | * @param null|string $link The link. If not set we default to linking to 169 | * '/' using the UrlGenerator 170 | * @param string $altText The alt text for the image 171 | * @return $this 172 | */ 173 | public function withBrandImage($image, $link = null, $altText = '') 174 | { 175 | $altText = $altText !== '' ? " alt='{$altText}'" : ''; 176 | 177 | return $this->withBrand("", $link); 178 | } 179 | 180 | /** 181 | * Adds some content to the navbar 182 | * 183 | * @param mixed $content Anything that can become a string! If you pass in a 184 | * Bootstrapper\Navigation object we'll make sure 185 | * it's a navbar on render. 186 | * @return $this 187 | */ 188 | public function withContent($content) 189 | { 190 | $this->content[] = $content; 191 | 192 | return $this; 193 | } 194 | 195 | /** 196 | * Sets the navbar to be inverse 197 | * 198 | * @param string $position 199 | * @param array $attributes 200 | * @return $this 201 | */ 202 | public function inverse($position = null, $attributes = []) 203 | { 204 | if (isset($position)) { 205 | $this->setPosition($position); 206 | $this->withAttributes($attributes); 207 | } 208 | 209 | $this->setType(self::NAVBAR_INVERSE); 210 | 211 | return $this; 212 | } 213 | 214 | /** 215 | * Sets the position to top 216 | * 217 | * @return $this 218 | */ 219 | public function staticTop() 220 | { 221 | $this->setPosition(self::NAVBAR_STATIC); 222 | 223 | return $this; 224 | } 225 | 226 | /** 227 | * Sets the type of the navbar 228 | * 229 | * @param string $type The type of the navbar. Assumes that the navbar- 230 | * prefix is there 231 | * @return $this 232 | */ 233 | public function setType($type) 234 | { 235 | $this->type = $type; 236 | 237 | return $this; 238 | } 239 | 240 | /** 241 | * Sets the position of the navbar 242 | * 243 | * @param string $position The position of the navbar. Assumes that the 244 | * navbar- prefix is there 245 | * @return $this 246 | */ 247 | public function setPosition($position) 248 | { 249 | $this->position = $position; 250 | 251 | return $this; 252 | } 253 | 254 | /** 255 | * Sets the position of the navbar to the top 256 | * 257 | * @return $this 258 | */ 259 | public function top() 260 | { 261 | $this->setPosition(self::NAVBAR_TOP); 262 | 263 | return $this; 264 | } 265 | 266 | /** 267 | * Sets the position of the navbar to the bottom 268 | * 269 | * @return $this 270 | */ 271 | public function bottom() 272 | { 273 | $this->setPosition(self::NAVBAR_BOTTOM); 274 | 275 | return $this; 276 | } 277 | 278 | /** 279 | * Creates a navbar with a position and attributes 280 | * 281 | * @param string $position The position of the navbar 282 | * @param array $attributes The attributes of the navbar 283 | * @return $this 284 | */ 285 | public function create($position, $attributes = []) 286 | { 287 | $this->setPosition($position); 288 | 289 | return $this->withAttributes($attributes); 290 | } 291 | 292 | /** 293 | * Sets the navbar to be fluid 294 | * 295 | * @return $this 296 | */ 297 | public function fluid() 298 | { 299 | $this->fluid = true; 300 | 301 | return $this; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /src/Bootstrapper/Navigation.php: -------------------------------------------------------------------------------- 1 | 56 | *
  • title - The text to show
  • 57 | *
  • link - The link
  • 58 | *
  • active - (optional) Forces the link to be active
  • 59 | *
  • disabled - (optional) Forces the link to be disabled. Note that 60 | * active has priority over this
  • 61 | *
  • linkAttributes - The attributes for the link
  • 62 | *
  • callback - A callback. If it return a result that is EXACTLY 63 | * equal to false then the link won't be shown
  • 64 | * 65 | * To create a dropdown, the inner array should instead be [$title, $links], 66 | * where $links is an array of arrays for links 67 | */ 68 | protected $links = []; 69 | 70 | /** 71 | * @var UrlGenerator A laravel URL generator 72 | */ 73 | protected $url; 74 | 75 | /** 76 | * @var bool Whether we should automatically activate links 77 | */ 78 | protected $autoroute = true; 79 | 80 | /** 81 | * @var bool Whether the links are justified or not 82 | */ 83 | protected $justified = false; 84 | 85 | /** 86 | * @var bool Whether the navigation links are stacked or not 87 | */ 88 | protected $stacked = false; 89 | 90 | /** 91 | * @var string Whether the navigation should be floated 92 | */ 93 | protected $float; 94 | 95 | /** 96 | * Creates a new instance of Navigation 97 | * 98 | * @param UrlGenerator $urlGenerator 99 | */ 100 | public function __construct(UrlGenerator $urlGenerator) 101 | { 102 | $this->url = $urlGenerator; 103 | } 104 | 105 | /** 106 | * Renders the navigation object 107 | * 108 | * @return string 109 | */ 110 | public function render() 111 | { 112 | $attributes = new Attributes( 113 | $this->attributes, 114 | ['class' => "nav {$this->type}"] 115 | ); 116 | 117 | if ($this->justified) { 118 | $attributes->addClass('nav-justified'); 119 | } 120 | 121 | if ($this->stacked) { 122 | $attributes->addClass('nav-stacked'); 123 | } 124 | 125 | if ($this->float) { 126 | $attributes->addClass($this->float); 127 | } 128 | 129 | $string = "
      "; 130 | 131 | foreach ($this->links as $link) { 132 | $string .= $this->renderItem($link); 133 | } 134 | 135 | $string .= "
    "; 136 | 137 | return $string; 138 | } 139 | 140 | /** 141 | * Creates a pills navigation block 142 | * 143 | * @param array $links The links 144 | * @param array $attributes The attributes. Does not overwrite the 145 | * previous values if not set 146 | * @see Bootstrapper\Navigatation::$links 147 | * @return $this 148 | */ 149 | public function pills(array $links = [], array $attributes = null) 150 | { 151 | $this->type = self::NAVIGATION_PILLS; 152 | 153 | if (!isset($attributes)) { 154 | $attributes = $this->attributes; 155 | } 156 | 157 | return $this->links($links)->withAttributes($attributes); 158 | } 159 | 160 | /** 161 | * Sets the links of the navigation object 162 | * 163 | * @param array $links The links 164 | * @return $this 165 | * @see Bootstrapper\Navigation::$links 166 | */ 167 | public function links(array $links) 168 | { 169 | $this->links = $links; 170 | 171 | return $this; 172 | } 173 | 174 | /** 175 | * Creates a navigation tab object. 176 | * 177 | * @param array $links The links to be passed in 178 | * @param array $attributes The attributes of the navigation object. Will 179 | * overwrite unless not set. 180 | * @return $this 181 | */ 182 | public function tabs(array $links = [], array $attributes = null) 183 | { 184 | $this->type = self::NAVIGATION_TABS; 185 | if (!isset($attributes)) { 186 | $attributes = $this->attributes; 187 | } 188 | 189 | return $this->links($links)->withAttributes($attributes); 190 | } 191 | 192 | /** 193 | * Renders a link 194 | * 195 | * @param array $link A link to be rendered 196 | * @return string 197 | */ 198 | protected function renderLink(array $link) 199 | { 200 | $string = ''; 201 | 202 | if (isset($link['callback'])) { 203 | $callback = $link['callback']; 204 | 205 | if ($callback() === false) { 206 | return $string; 207 | } 208 | } 209 | 210 | if ($this->itemShouldBeActive($link)) { 211 | $string .= '
  • '; 212 | } elseif (isset($link['disabled']) && $link['disabled']) { 213 | $string .= '
  • '; 214 | } else { 215 | $string .= '
  • '; 216 | } 217 | 218 | if (isset($link['linkAttributes'])) { 219 | $linkAttributes = $link['linkAttributes']; 220 | } else { 221 | $linkAttributes = []; 222 | } 223 | 224 | $linkAttributes = new Attributes( 225 | $linkAttributes, 226 | ['href' => $link['link']] 227 | ); 228 | 229 | $string .= "{$link['title']}
  • "; 230 | 231 | return $string; 232 | } 233 | 234 | /** 235 | * Sets the autorouting. Pass false to turn it off, true to turn it on 236 | * 237 | * @param bool $autoroute Whether the autorouting should be on 238 | * @return $this 239 | */ 240 | public function autoroute($autoroute) 241 | { 242 | $this->autoroute = $autoroute; 243 | 244 | return $this; 245 | } 246 | 247 | /** 248 | * Renders the dropdown 249 | * 250 | * @param array $link The link to render 251 | * @return string 252 | */ 253 | protected function renderDropdown(array $link) 254 | { 255 | if ($this->dropdownShouldBeActive($link)) { 256 | $string = '
  • '; 257 | } else { 258 | $string = '
  • '; 259 | } 260 | 261 | $string .= ""; 262 | $string .= "{$link[0]} "; 263 | $string .= '
      '; 264 | 265 | foreach ($link[1] as $item) { 266 | $string .= $this->renderItem($item); 267 | } 268 | 269 | $string .= '
    '; 270 | $string .= '
  • '; 271 | 272 | return $string; 273 | } 274 | 275 | /** 276 | * Checks to see if the dropdown should be active 277 | * 278 | * @param array $dropdown The dropdown array 279 | * @return bool 280 | */ 281 | protected function dropdownShouldBeActive(array $dropdown) 282 | { 283 | if ($this->autoroute) { 284 | foreach ($dropdown[1] as $item) { 285 | if ($this->itemShouldBeActive($item)) { 286 | return true; 287 | } 288 | } 289 | } 290 | return false; 291 | } 292 | 293 | /** 294 | * Checks to see if the given item should be active 295 | * 296 | * @param mixed $link A link to check whether it should be active 297 | * @return bool 298 | */ 299 | protected function itemShouldBeActive($link) 300 | { 301 | if (is_string($link)) { 302 | return false; 303 | } 304 | $auto = $this->autoroute && $this->url->current() == $link['link']; 305 | $manual = isset($link['active']) && $link['active']; 306 | 307 | return $auto || $manual; 308 | } 309 | 310 | /** 311 | * Turns the navigation object into one for navbars 312 | * 313 | * @return $this 314 | */ 315 | public function navbar() 316 | { 317 | $this->type = self::NAVIGATION_NAVBAR; 318 | 319 | return $this; 320 | } 321 | 322 | /** 323 | * Makes the navigation links justified 324 | * 325 | * @return $this 326 | */ 327 | public function justified() 328 | { 329 | $this->justified = true; 330 | 331 | return $this; 332 | } 333 | 334 | /** 335 | * Makes the navigation stacked 336 | * 337 | * @return $this 338 | */ 339 | public function stacked() 340 | { 341 | $this->stacked = true; 342 | 343 | return $this; 344 | } 345 | 346 | /** 347 | * Makes the navigation links float right 348 | * 349 | * @return $this 350 | */ 351 | public function right() 352 | { 353 | $this->float = self::NAVBAR_RIGHT; 354 | 355 | return $this; 356 | } 357 | 358 | /** 359 | * Makes the navigation links float left 360 | * 361 | * @return $this 362 | */ 363 | public function left() 364 | { 365 | $this->float = self::NAVBAR_LEFT; 366 | 367 | return $this; 368 | } 369 | 370 | /** 371 | * Renders a separator 372 | * 373 | * @param string $separator 374 | * @return string 375 | */ 376 | protected function renderSeparator($separator) 377 | { 378 | return "
  • "; 379 | } 380 | 381 | /** 382 | * Renders an item 383 | * 384 | * @param string|array $link The item to render 385 | * @return string 386 | */ 387 | private function renderItem($link) 388 | { 389 | if (!is_array($link)) { 390 | $string = $this->renderSeparator($link); 391 | } elseif (isset($link['link'])) { 392 | $string = $this->renderLink($link); 393 | } else { 394 | $string = $this->renderDropdown($link); 395 | } 396 | 397 | return $string; 398 | } 399 | } 400 | -------------------------------------------------------------------------------- /src/Bootstrapper/Panel.php: -------------------------------------------------------------------------------- 1 | attributes, 80 | ['class' => "panel {$this->type}"] 81 | ); 82 | $string = "
    "; 83 | 84 | if ($this->header) { 85 | $string .= $this->renderHeader(); 86 | } 87 | 88 | if ($this->body) { 89 | $string .= $this->renderBody(); 90 | } 91 | 92 | if ($this->table) { 93 | $string .= $this->renderTable(); 94 | } 95 | 96 | if ($this->footer) { 97 | $string .= $this->renderFooter(); 98 | } 99 | 100 | $string .= "
    "; 101 | 102 | return $string; 103 | } 104 | 105 | /** 106 | * Creates a primary panel 107 | * 108 | * @return $this 109 | */ 110 | public function primary() 111 | { 112 | $this->setType(self::PRIMARY); 113 | 114 | return $this; 115 | } 116 | 117 | /** 118 | * Creates a success panel 119 | * 120 | * @return $this 121 | */ 122 | public function success() 123 | { 124 | $this->setType(self::SUCCESS); 125 | 126 | return $this; 127 | } 128 | 129 | /** 130 | * Creates an info panel 131 | * 132 | * @return $this 133 | */ 134 | public function info() 135 | { 136 | $this->setType(self::INFO); 137 | 138 | return $this; 139 | } 140 | 141 | /** 142 | * Creates an warning panel 143 | * 144 | * @return $this 145 | */ 146 | public function warning() 147 | { 148 | $this->setType(self::WARNING); 149 | 150 | return $this; 151 | } 152 | 153 | /** 154 | * Creates an danger panel 155 | * 156 | * @return $this 157 | */ 158 | public function danger() 159 | { 160 | $this->setType(self::DANGER); 161 | 162 | return $this; 163 | } 164 | 165 | /** 166 | * Sets the type of the panel 167 | * 168 | * @param string $type The new type. Assume the panel- prefix 169 | * @return $this 170 | */ 171 | public function setType($type) 172 | { 173 | $this->type = $type; 174 | 175 | return $this; 176 | } 177 | 178 | /** 179 | * Sets the header of the panel 180 | * 181 | * @param string $header The header 182 | * @return $this 183 | */ 184 | public function withHeader($header) 185 | { 186 | $this->header = $header; 187 | 188 | return $this; 189 | } 190 | 191 | /** 192 | * Renders the header 193 | * 194 | * @return string 195 | */ 196 | protected function renderHeader() 197 | { 198 | $string = "
    "; 199 | $string .= "

    {$this->header}

    "; 200 | $string .= '
    '; 201 | 202 | return $string; 203 | } 204 | 205 | /** 206 | * Sets the body of the panel 207 | * 208 | * @param string $body The body 209 | * @return $this 210 | */ 211 | public function withBody($body) 212 | { 213 | $this->body = $body; 214 | 215 | return $this; 216 | } 217 | 218 | /** 219 | * Renders the body 220 | * 221 | * @return string 222 | */ 223 | protected function renderBody() 224 | { 225 | return "
    {$this->body}
    "; 226 | } 227 | 228 | /** 229 | * Sets the table of the panel 230 | * 231 | * @param string|Table $table The table 232 | * @return $this 233 | */ 234 | public function withTable($table) 235 | { 236 | $this->table = $table; 237 | 238 | return $this; 239 | } 240 | 241 | /** 242 | * Renders the body 243 | * 244 | * @return string 245 | */ 246 | protected function renderTable() 247 | { 248 | if ($this->table instanceof Table) { 249 | return $this->table->render(); 250 | } else { 251 | return $this->table; 252 | } 253 | } 254 | 255 | /** 256 | * Sets the footer 257 | * 258 | * @param string $footer The new footer 259 | * @return $this 260 | */ 261 | public function withFooter($footer) 262 | { 263 | $this->footer = $footer; 264 | 265 | return $this; 266 | } 267 | 268 | /** 269 | * Renders the footer 270 | * 271 | * @return string 272 | */ 273 | protected function renderFooter() 274 | { 275 | return ""; 276 | } 277 | 278 | /** 279 | * Creates a normal panel 280 | * 281 | * @return $this 282 | */ 283 | public function normal() 284 | { 285 | $this->setType(self::NORMAL); 286 | 287 | return $this; 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /src/Bootstrapper/ProgressBar.php: -------------------------------------------------------------------------------- 1 | "; 79 | 80 | $attributes = new Attributes( 81 | $this->attributes, 82 | [ 83 | 'class' => "progress-bar {$this->type}", 84 | 'role' => 'progressbar', 85 | 'aria-valuenow' => "{$this->value}", 86 | 'aria-valuemin' => '0', 87 | 'aria-valuemax' => '100', 88 | 'style' => $this->value ? "width: {$this->value}%" : '' 89 | ] 90 | ); 91 | 92 | if ($this->striped) { 93 | $attributes->addClass('progress-bar-striped'); 94 | } 95 | 96 | if ($this->animated) { 97 | $attributes->addClass('active'); 98 | } 99 | 100 | $string .= "
    "; 101 | 102 | $string .= $this->visible ? 103 | sprintf($this->visibleString, $this->value) : 104 | "{$this->value}% complete"; 105 | 106 | $string .= "
    "; 107 | 108 | $string .= "
    "; 109 | 110 | return $string; 111 | } 112 | 113 | /** 114 | * Sets the type of the progress bar 115 | * 116 | * @param string $type The type 117 | * @return $this 118 | */ 119 | public function setType($type) 120 | { 121 | $this->type = $type; 122 | 123 | return $this; 124 | } 125 | 126 | /** 127 | * Sets the value of the progress bar 128 | * 129 | * @param int $value The value of the progress bar The value of the 130 | * progress bar 131 | * @return $this 132 | */ 133 | public function value($value) 134 | { 135 | $this->value = $value; 136 | 137 | return $this; 138 | } 139 | 140 | /** 141 | * Whether the amount should be visible 142 | * 143 | * @param string $string The string to show to the user. We internally 144 | * will use sprintf to show this, so you must 145 | * include a %s somewhere so we can add this in 146 | * @return $this 147 | */ 148 | public function visible($string = '%s%%') 149 | { 150 | $this->visible = true; 151 | $this->visibleString = $string; 152 | 153 | return $this; 154 | } 155 | 156 | /** 157 | * Creates a success progress bar 158 | * 159 | * @param int $value The value of the progress bar 160 | * @return $this 161 | */ 162 | public function success($value = 0) 163 | { 164 | $this->setType(self::PROGRESS_BAR_SUCCESS); 165 | 166 | return $this->value($value); 167 | } 168 | 169 | /** 170 | * Creates an info progress bar 171 | * 172 | * @param int $value The value of the progress bar 173 | * @return $this 174 | */ 175 | public function info($value = 0) 176 | { 177 | $this->setType(self::PROGRESS_BAR_INFO); 178 | 179 | return $this->value($value); 180 | } 181 | 182 | /** 183 | * Creates a warning progress bar 184 | * 185 | * @param int $value The value of the progress bar 186 | * @return $this 187 | */ 188 | public function warning($value = 0) 189 | { 190 | $this->setType(self::PROGRESS_BAR_WARNING); 191 | 192 | return $this->value($value); 193 | } 194 | 195 | /** 196 | * Creates a danger progress bar 197 | * 198 | * @param int $value The value of the progress bar 199 | * @return $this 200 | */ 201 | public function danger($value = 0) 202 | { 203 | $this->setType(self::PROGRESS_BAR_DANGER); 204 | 205 | return $this->value($value); 206 | } 207 | 208 | /** 209 | * Creates a normal progress bar 210 | * 211 | * @param int $value The value of the progress bar 212 | * @return $this 213 | */ 214 | public function normal($value = 0) 215 | { 216 | $this->setType(self::PROGRESS_BAR_NORMAL); 217 | 218 | return $this->value($value); 219 | } 220 | 221 | /** 222 | * Sets the progress bar to be striped 223 | * 224 | * @return $this 225 | */ 226 | public function striped() 227 | { 228 | $this->striped = true; 229 | 230 | return $this; 231 | } 232 | 233 | /** 234 | * Sets the progress bar to be animated 235 | * 236 | * @return $this 237 | */ 238 | public function animated() 239 | { 240 | $this->animated = true; 241 | 242 | return $this->striped(); 243 | } 244 | 245 | /** 246 | * Stacks several progress bars together 247 | * 248 | * @param array $items The progress bars. Should be an array of arrays, 249 | * which are a list of methods and parameters. 250 | * @return string 251 | */ 252 | public function stack(array $items) 253 | { 254 | $string = '
    '; 255 | foreach ($items as $progressBar) { 256 | $string .= $this->generateFromArray($progressBar); 257 | } 258 | $string .= '
    '; 259 | 260 | return $string; 261 | } 262 | 263 | /** 264 | * Generates a progress bar from an array 265 | * 266 | * @param array $progressBar An array of methods with variables if required, 267 | * eg 'value=2', 'animated' 268 | * @return mixed 269 | */ 270 | protected function generateFromArray(array $progressBar) 271 | { 272 | $bar = new static; 273 | 274 | foreach ($progressBar as $attribute) { 275 | $exploded = explode('=', $attribute); 276 | $method = $exploded[0]; 277 | $vars = isset($exploded[1]) ? $exploded[1] : null; 278 | if (isset($vars)) { 279 | $bar->$method($vars); 280 | } else { 281 | $bar->$method(); 282 | } 283 | } 284 | 285 | // Now to remove the outer divs 286 | $string = $bar->render(); 287 | 288 | $string = str_replace('
    ', '', $string); 289 | $string = str_replace('
    ', '
    ', $string); 290 | 291 | return $string; 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /src/Bootstrapper/RenderedObject.php: -------------------------------------------------------------------------------- 1 | render(); 30 | } catch (\Exception $e) { 31 | $class = get_class($e); 32 | return "

    An exception of" 33 | . " type {$class} was thrown with the message:" 34 | . " {$e->getMessage()}

    "; 35 | } 36 | } 37 | 38 | /** 39 | * Renders the object 40 | * 41 | * @return string 42 | */ 43 | abstract public function render(); 44 | 45 | /** 46 | * Set the attributes of the object 47 | * 48 | * @param array $attributes The attributes to use 49 | * @return $this 50 | */ 51 | public function withAttributes(array $attributes) 52 | { 53 | $this->attributes = array_merge($attributes, $this->attributes); 54 | 55 | return $this; 56 | } 57 | 58 | /** 59 | * Adds the given classes to attributes 60 | * 61 | * @param array $classes 62 | * @return $this 63 | */ 64 | public function addClass($classes) 65 | { 66 | if (!is_array($classes)) { 67 | throw new \InvalidArgumentException('Add class must take an array'); 68 | } 69 | 70 | $classes = implode(' ', $classes); 71 | 72 | if (!isset($this->attributes['class'])) { 73 | $this->attributes['class'] = $classes; 74 | } else { 75 | $this->attributes['class'] .= " $classes"; 76 | } 77 | 78 | return $this; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Bootstrapper/Tabbable.php: -------------------------------------------------------------------------------- 1 | 35 | *
  • title - the title of the content
  • 36 | *
  • content - the actual content
  • 37 | *
  • attributes (optional) - any attributes
  • 38 | * 39 | */ 40 | protected $contents = []; 41 | 42 | /** 43 | * @var int Which tab should be open first 44 | */ 45 | protected $active = 0; 46 | 47 | /** 48 | * @var string The type 49 | */ 50 | protected $type = self::TAB; 51 | 52 | /** 53 | * @var bool Whether we should fade in or not 54 | */ 55 | protected $fade = false; 56 | 57 | /** 58 | * Creates a new Tabbable object 59 | * 60 | * @param Navigation $links A navigation object 61 | */ 62 | public function __construct(Navigation $links) 63 | { 64 | $this->links = $links->autoroute(false)->withAttributes( 65 | ['role' => 'tablist'] 66 | ); 67 | } 68 | 69 | /** 70 | * Renders the tabbable object 71 | * 72 | * @return string 73 | */ 74 | public function render() 75 | { 76 | $string = $this->renderNavigation(); 77 | $string .= $this->renderContents(); 78 | 79 | return $string; 80 | } 81 | 82 | /** 83 | * Creates content with a tabbed navigation 84 | * 85 | * @param array $contents The content 86 | * @return $this 87 | * @see Bootstrapper\Navigation::$contents 88 | */ 89 | public function tabs($contents = []) 90 | { 91 | $this->links->tabs(); 92 | $this->type = self::TAB; 93 | 94 | return $this->withContents($contents); 95 | } 96 | 97 | /** 98 | * Creates content with a pill navigation 99 | * 100 | * @param array $contents 101 | * @return $this 102 | * @see Bootstrapper\Navigation::$contents 103 | */ 104 | public function pills($contents = []) 105 | { 106 | $this->links->pills(); 107 | $this->type = self::PILL; 108 | 109 | return $this->withContents($contents); 110 | } 111 | 112 | /** 113 | * Sets the contents 114 | * 115 | * @param array $contents An array of arrays 116 | * @return $this 117 | * @see Bootstrapper\Navigation::$contents 118 | */ 119 | public function withContents(array $contents) 120 | { 121 | $this->contents = $contents; 122 | 123 | return $this; 124 | } 125 | 126 | /** 127 | * Render the navigation links 128 | * 129 | * @return string 130 | */ 131 | protected function renderNavigation() 132 | { 133 | $this->links->links($this->createNavigationLinks()); 134 | 135 | return $this->links->render(); 136 | } 137 | 138 | /** 139 | * Creates the navigation links 140 | * 141 | * @return array 142 | */ 143 | protected function createNavigationLinks() 144 | { 145 | $links = []; 146 | $count = 0; 147 | foreach ($this->contents as $link) { 148 | $links[] = [ 149 | 'link' => '#' . Helpers::slug($link['title']), 150 | 'title' => $link['title'], 151 | 'linkAttributes' => [ 152 | 'role' => 'tab', 153 | 'data-toggle' => $this->type 154 | ], 155 | 'active' => $count == $this->active 156 | ]; 157 | $count += 1; 158 | } 159 | return $links; 160 | } 161 | 162 | /** 163 | * Renders the contents 164 | * 165 | * @return string 166 | */ 167 | protected function renderContents() 168 | { 169 | $tabs = $this->createContentTabs(); 170 | 171 | $string = '
    '; 172 | foreach ($tabs as $tab) { 173 | $string .= "
    {$tab['content']}
    "; 174 | } 175 | 176 | $string .= '
    '; 177 | 178 | return $string; 179 | } 180 | 181 | /** 182 | * Creates the content tabs 183 | * 184 | * @return array 185 | */ 186 | protected function createContentTabs() 187 | { 188 | $tabs = []; 189 | $count = 0; 190 | 191 | foreach ($this->contents as $item) { 192 | $itemAttributes = isset($item['attributes']) ? 193 | $item['attributes'] : 194 | []; 195 | 196 | $attributes = new Attributes( 197 | $itemAttributes, 198 | ['class' => 'tab-pane', 'id' => Helpers::slug($item['title'])] 199 | ); 200 | 201 | if ($this->fade) { 202 | $attributes->addClass('fade'); 203 | } 204 | 205 | if ($this->active == $count) { 206 | $attributes->addClass($this->fade ? 'in active' : 'active'); 207 | } 208 | 209 | $tabs[] = [ 210 | 'content' => $item['content'], 211 | 'attributes' => $attributes 212 | ]; 213 | 214 | $count += 1; 215 | } 216 | 217 | return $tabs; 218 | } 219 | 220 | /** 221 | * Sets which tab should be active 222 | * 223 | * @param int $active 224 | * @return $this 225 | */ 226 | public function active($active) 227 | { 228 | $this->active = $active; 229 | 230 | return $this; 231 | } 232 | 233 | /** 234 | * Sets the tabbable objects to fade in 235 | * 236 | * @return $this 237 | */ 238 | public function fade() 239 | { 240 | $this->fade = true; 241 | 242 | return $this; 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /src/Bootstrapper/Table.php: -------------------------------------------------------------------------------- 1 | function() 60 | */ 61 | protected $callbacks = []; 62 | 63 | /** 64 | * @var bool|array An array of columns to get. False if none. 65 | */ 66 | protected $only = []; 67 | 68 | /** 69 | * @var array An array of classes to apply to body tds 70 | */ 71 | protected $bodyCellClasses = []; 72 | 73 | /** 74 | * @var array An array of classes, of the form 'column' => 'class1 class2' (space delimitied) 75 | */ 76 | protected $columnClasses = []; 77 | 78 | /** 79 | * Renders the table 80 | * 81 | * @return string 82 | */ 83 | public function render() 84 | { 85 | $tableClasses = implode(' ', $this->types); 86 | 87 | $attributes = new Attributes( 88 | $this->attributes, 89 | [ 90 | 'class' => "table {$tableClasses}" 91 | ] 92 | ); 93 | 94 | $string = ""; 95 | 96 | $string .= $this->renderHeaders(); 97 | 98 | if ($this->footer) { 99 | $string .= $this->renderFooter(); 100 | } 101 | 102 | if ($this->contents) { 103 | $string .= $this->renderContents(); 104 | } 105 | 106 | $string .= '
    '; 107 | 108 | return $string; 109 | } 110 | 111 | /** 112 | * Adds a type to the table if not already present. 113 | * @param string $type The type to add to the table 114 | */ 115 | private function addType($type) 116 | { 117 | if (!in_array($type, $this->types, true)) { 118 | $this->types[] = $type; 119 | } 120 | 121 | return $this; 122 | } 123 | 124 | /** 125 | * Sets the table to be striped 126 | * 127 | * @return $this 128 | */ 129 | public function striped() 130 | { 131 | $this->addType(self::TABLE_STRIPED); 132 | 133 | return $this; 134 | } 135 | 136 | /** 137 | * Sets the table to be bordered 138 | * 139 | * @return $this 140 | */ 141 | public function bordered() 142 | { 143 | $this->addType(self::TABLE_BORDERED); 144 | 145 | return $this; 146 | } 147 | 148 | /** 149 | * Sets the table to have an active hover state 150 | * 151 | * @return $this 152 | */ 153 | public function hover() 154 | { 155 | $this->addType(self::TABLE_HOVER); 156 | 157 | return $this; 158 | } 159 | 160 | /** 161 | * Sets the table to be condensed 162 | * 163 | * @return $this 164 | */ 165 | public function condensed() 166 | { 167 | $this->addType(self::TABLE_CONDENSED); 168 | 169 | return $this; 170 | } 171 | 172 | /** 173 | * Sets the contents of the table 174 | * 175 | * @param array|Traversable $contents The contents of the table. We expect 176 | * either an array of arrays or an 177 | * array of eloquent models 178 | * @return $this 179 | */ 180 | public function withContents($contents) 181 | { 182 | $this->contents = $contents; 183 | 184 | return $this; 185 | } 186 | 187 | /** 188 | * Renders the contents of the table 189 | * 190 | * @return string 191 | */ 192 | private function renderContents() 193 | { 194 | $headers = $this->getHeaders(); 195 | 196 | $string = ''; 197 | foreach ($this->contents as $item) { 198 | $string .= $this->renderItem($item, $headers); 199 | } 200 | 201 | $string .= ''; 202 | 203 | return $string; 204 | } 205 | 206 | /** 207 | * Gets the headers of the contents 208 | * 209 | * @return array 210 | */ 211 | private function getHeaders() 212 | { 213 | if ($this->only) { 214 | return $this->only; 215 | } 216 | 217 | $headers = []; 218 | foreach ($this->contents as $item) { 219 | $keys = $this->getKeysForItem($item); 220 | 221 | foreach ($keys as $key) { 222 | if (in_array($key, $this->ignores)) { 223 | continue; 224 | } 225 | if ($this->only && !in_array($key, $this->only)) { 226 | continue; 227 | } 228 | if (!in_array($key, $headers)) { 229 | $headers[] = $key; 230 | } 231 | } 232 | } 233 | 234 | foreach (array_keys($this->callbacks) as $key) { 235 | if (in_array($key, $this->ignores)) { 236 | continue; 237 | } 238 | 239 | if (!in_array($key, $headers)) { 240 | $headers[] = $key; 241 | } 242 | } 243 | 244 | return $headers; 245 | } 246 | 247 | /** 248 | * Renders an item 249 | * 250 | * @param mixed $item The item to render 251 | * @param array $headers The headers to use 252 | * @return string 253 | */ 254 | private function renderItem($item, array $headers) 255 | { 256 | $string = ''; 257 | $tdClasses = implode(' ', $this->bodyCellClasses); 258 | 259 | foreach ($headers as $heading) { 260 | $value = $this->getValueForItem($item, $heading); 261 | 262 | if (isset($this->columnClasses[$heading])) { 263 | $classes = rtrim($this->columnClasses[$heading] . ' ' . $tdClasses); 264 | $string .= "{$value}"; 265 | } else { 266 | $string .= empty($tdClasses) ? "{$value}" : "{$value}"; 267 | } 268 | } 269 | $string .= ''; 270 | 271 | return $string; 272 | } 273 | 274 | 275 | /** 276 | * Creates a list of columns to ignore 277 | * 278 | * @param array $ignores The ignored columns 279 | * @return $this 280 | */ 281 | public function ignore(array $ignores) 282 | { 283 | $this->ignores = $ignores; 284 | 285 | return $this; 286 | } 287 | 288 | /** 289 | * Adds a callback 290 | * 291 | * @param string $index The column name for the callback 292 | * @param callable $function The callback function, 293 | * which should be of the form 294 | * function($column, $row). 295 | * @return $this 296 | */ 297 | public function callback($index, \Closure $function) 298 | { 299 | $this->callbacks[$index] = $function; 300 | 301 | return $this; 302 | } 303 | 304 | /** 305 | * Sets which columns we can return 306 | * 307 | * @param array $only 308 | * @return $this 309 | */ 310 | public function only(array $only) 311 | { 312 | $this->only = $only; 313 | 314 | return $this; 315 | } 316 | 317 | private function renderHeaders() 318 | { 319 | $headers = $this->getHeaders(); 320 | 321 | if (empty($headers)) { 322 | return ''; 323 | } 324 | 325 | $string = ''; 326 | foreach ($headers as $heading) { 327 | if (isset($this->columnClasses[$heading])) { 328 | $string .= "{$heading}"; 329 | } else { 330 | $string .= "{$heading}"; 331 | } 332 | } 333 | $string .= ''; 334 | 335 | return $string; 336 | } 337 | 338 | /** 339 | * Sets content to be rendered in to the table footer 340 | * 341 | * @param string $footer 342 | * @return $this 343 | */ 344 | public function withFooter($footer) 345 | { 346 | $this->footer = $footer; 347 | 348 | return $this; 349 | } 350 | 351 | /** 352 | * Renders the footer 353 | * 354 | * @return string 355 | */ 356 | private function renderFooter() 357 | { 358 | return "{$this->footer}"; 359 | } 360 | 361 | private function getKeysForItem($item) 362 | { 363 | if (is_array($item)) { 364 | return array_keys($item); 365 | } 366 | 367 | if ($item instanceof TableInterface) { 368 | return $item->getTableHeaders(); 369 | } 370 | 371 | // Let the user know that the TableInterface will soon be the 372 | // only way to use tables in a future version of Bootstrapper 373 | trigger_error( 374 | 'An object that does not implement the TableInterface ' 375 | . 'was passed to a table. This is depreciated and will be removed in ' 376 | . 'a future version of Bootstrapper', 377 | E_USER_DEPRECATED 378 | ); 379 | 380 | // Handles eloquent models 381 | if (is_callable([$item, 'getAttributes'])) { 382 | return array_keys($item->getAttributes()); 383 | } 384 | 385 | // Default fallback 386 | return get_object_vars($item); 387 | } 388 | 389 | private function getValueForItem($item, $heading) 390 | { 391 | if (is_array($item)) { 392 | $value = isset($item[$heading]) ? $item[$heading] : ''; 393 | } elseif ($item instanceof TableInterface) { 394 | $value = $item->getValueForHeader($heading); 395 | } else { 396 | $value = $item->$heading; 397 | } 398 | 399 | if (isset($this->callbacks[$heading])) { 400 | $value = $this->callbacks[$heading]($value, $item); 401 | } 402 | 403 | return $value; 404 | } 405 | 406 | /** 407 | * Uses given class(es) on body TDs. 408 | * @param mixed $classes The class(es) to apply. 409 | * @return $this 410 | */ 411 | public function withBodyCellClass($classes) 412 | { 413 | if (is_array($classes)) { 414 | $this->bodyCellClasses = $classes; 415 | } else { 416 | $this->bodyCellClasses = [ $classes ]; 417 | } 418 | 419 | return $this; 420 | } 421 | 422 | public function withClassOnCellsInColumn($columns, $classes) 423 | { 424 | if (!is_array($columns)) { 425 | $columns = [ $columns ]; 426 | } 427 | 428 | if (is_array($classes)) { 429 | $classes = implode(' ', $classes); 430 | } 431 | 432 | foreach ($columns as $column) { 433 | $this->columnClasses[$column] = $classes; 434 | } 435 | 436 | return $this; 437 | } 438 | } 439 | -------------------------------------------------------------------------------- /src/Bootstrapper/Thumbnail.php: -------------------------------------------------------------------------------- 1 | image['image'])) { 37 | throw ThumbnailException::imageNotSpecified(); 38 | } 39 | 40 | $attributes = new Attributes( 41 | $this->attributes, 42 | ['class' => 'thumbnail'] 43 | ); 44 | 45 | $string = "
    "; 46 | $string .= $this->renderImage(); 47 | 48 | if ($this->caption) { 49 | $string .= $this->renderCaption(); 50 | } 51 | $string .= '
    '; 52 | 53 | return $string; 54 | } 55 | 56 | /** 57 | * Sets the image for the thumbnail 58 | * 59 | * @param string $image The image source 60 | * @param array $attributes The attributes 61 | * @return $this 62 | */ 63 | public function image($image, $attributes = []) 64 | { 65 | $this->image = compact('image', 'attributes'); 66 | 67 | return $this; 68 | } 69 | 70 | /** 71 | * Sets the caption for the thumbnail 72 | * 73 | * @param string $caption The new caption 74 | * @return $this 75 | */ 76 | public function caption($caption) 77 | { 78 | $this->caption = $caption; 79 | 80 | return $this; 81 | } 82 | 83 | /** 84 | * Renders the image 85 | * 86 | * @return string 87 | */ 88 | protected function renderImage() 89 | { 90 | $attributes = new Attributes( 91 | $this->image['attributes'], 92 | ['src' => $this->image['image']] 93 | ); 94 | return ""; 95 | } 96 | 97 | /** 98 | * Renders the caption 99 | * 100 | * @return string 101 | */ 102 | protected function renderCaption() 103 | { 104 | return "
    {$this->caption}
    "; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/config/bootstrapper.php: -------------------------------------------------------------------------------- 1 | '3.3.0', 8 | 'jqueryVersion' => '2.1.0', 9 | 'icon_prefix' => 'glyphicon', 10 | 'icon_tag' => 'span' 11 | ]; 12 | -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | '3.3.7', 8 | 'jqueryVersion' => '2.1.0', 9 | 'icon_prefix' => 'glyphicon', 10 | 'icon_tag' => 'span' 11 | ]; 12 | --------------------------------------------------------------------------------