1 <?php
2 /**
3 * Bootstrap class file.
4 * @author Christoffer Niska <ChristofferNiska@gmail.com>
5 * @copyright Copyright © Christoffer Niska 2011-
6 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
7 * @version 1.0.0
8 */
9
10 /**
11 * Bootstrap application component.
12 */
13 class Bootstrap extends CApplicationComponent
14 {
15 // Bootstrap plugins.
16 const PLUGIN_ALERT = 'alert';
17 const PLUGIN_BUTTON = 'button';
18 const PLUGIN_CAROUSEL = 'carousel';
19 const PLUGIN_COLLAPSE = 'collapse';
20 const PLUGIN_DROPDOWN = 'dropdown';
21 const PLUGIN_MODAL = 'modal';
22 const PLUGIN_POPOVER = 'popover';
23 const PLUGIN_SCROLLSPY = 'scrollspy';
24 const PLUGIN_TAB = 'tab';
25 const PLUGIN_TOOLTIP = 'tooltip';
26 const PLUGIN_TRANSITION = 'transition';
27 const PLUGIN_TYPEAHEAD = 'typeahead';
28 // todo: add the affix plugin in version 2.1.0
29
30 /**
31 * @var boolean whether to register the Bootstrap core CSS (bootstrap.min.css).
32 * Defaults to true.
33 */
34 public $coreCss = true;
35 /**
36 * @var boolean whether to register the Bootstrap responsive CSS (bootstrap-responsive.min.css).
37 * Defaults to false.
38 */
39 public $responsiveCss = false;
40 /**
41 * @var boolean whether to register the Yii-specific CSS missing from Bootstrap.
42 * @since 0.9.12
43 */
44 public $yiiCss = true;
45 /**
46 * @var boolean whether to register jQuery and the Bootstrap JavaScript.
47 * @since 0.9.10
48 */
49 public $enableJS = true;
50 /**
51 * @var array plugin initial options (name=>options).
52 * Each array key-value pair represents the initial options for a single plugin class,
53 * with the array key being the plugin name, and array value being the initial options array.
54 * @since 0.9.8
55 */
56 public $plugins = array();
57 /**
58 * @var string default popover CSS selector.
59 * @since 0.10.0
60 */
61 public $popoverSelector = 'a[rel="popover"]';
62 /**
63 * @var string default tooltip CSS selector.
64 * @since 0.10.0
65 */
66 public $tooltipSelector = 'a[rel="tooltip"]';
67
68 protected $_assetsUrl;
69
70 /**
71 * Initializes the component.
72 */
73 public function init()
74 {
75 // Register the bootstrap path alias.
76 if (Yii::getPathOfAlias('bootstrap') === false)
77 Yii::setPathOfAlias('bootstrap', realpath(dirname(__FILE__).'/..'));
78
79 // Prevents the extension from registering scripts and publishing assets when ran from the command line.
80 if (Yii::app() instanceof CConsoleApplication)
81 return;
82
83 if ($this->coreCss !== false)
84 $this->registerCoreCss();
85
86 if ($this->responsiveCss !== false)
87 $this->registerResponsiveCss();
88
89 if ($this->yiiCss !== false)
90 $this->registerYiiCss();
91
92 if ($this->enableJS !== false)
93 $this->registerCoreScripts();
94
95 parent::init();
96 }
97
98 /**
99 * Registers the Bootstrap CSS.
100 */
101 public function registerCoreCss()
102 {
103 Yii::app()->clientScript->registerCssFile($this->getAssetsUrl().'/css/bootstrap.css');
104 }
105
106 /**
107 * Registers the Bootstrap responsive CSS.
108 * @since 0.9.8
109 */
110 public function registerResponsiveCss()
111 {
112 /** @var CClientScript $cs */
113 $cs = Yii::app()->getClientScript();
114 $cs->registerMetaTag('width=device-width, initial-scale=1.0', 'viewport');
115 $cs->registerCssFile($this->getAssetsUrl().'/css/bootstrap-responsive.css');
116 }
117
118 /**
119 * Registers the Yii-specific CSS missing from Bootstrap.
120 * @since 0.9.11
121 */
122 public function registerYiiCss()
123 {
124 Yii::app()->clientScript->registerCssFile($this->getAssetsUrl().'/css/bootstrap-yii.css');
125 }
126
127 /**
128 * Registers the core JavaScript.
129 * @since 0.9.8
130 */
131 public function registerCoreScripts()
132 {
133 $this->registerJS(Yii::app()->clientScript->coreScriptPosition);
134 $this->registerTooltip();
135 $this->registerPopover();
136 }
137
138 /**
139 * Registers the Bootstrap JavaScript.
140 * @param int $position the position of the JavaScript code.
141 * @see CClientScript::registerScriptFile
142 */
143 public function registerJS($position = CClientScript::POS_HEAD)
144 {
145 /** @var CClientScript $cs */
146 $cs = Yii::app()->getClientScript();
147 $cs->registerCoreScript('jquery');
148 $cs->registerScriptFile($this->getAssetsUrl().'/js/bootstrap.js', $position);
149 }
150
151 /**
152 * Registers the Bootstrap alert plugin.
153 * @param string $selector the CSS selector
154 * @param array $options the plugin options
155 * @see http://twitter.github.com/bootstrap/javascript.html#alerts
156 * @since 0.9.8
157 */
158 public function registerAlert($selector = null, $options = array())
159 {
160 $this->registerPlugin(self::PLUGIN_ALERT, $selector, $options);
161 }
162
163 /**
164 * Registers the Bootstrap buttons plugin.
165 * @param string $selector the CSS selector
166 * @param array $options the plugin options
167 * @see http://twitter.github.com/bootstrap/javascript.html#buttons
168 * @since 0.9.8
169 */
170 public function registerButton($selector = null, $options = array())
171 {
172 $this->registerPlugin(self::PLUGIN_BUTTON, $selector, $options);
173 }
174
175 /**
176 * Registers the Bootstrap carousel plugin.
177 * @param string $selector the CSS selector
178 * @param array $options the plugin options
179 * @see http://twitter.github.com/bootstrap/javascript.html#carousel
180 * @since 0.9.8
181 */
182 public function registerCarousel($selector = null, $options = array())
183 {
184 $this->registerPlugin(self::PLUGIN_CAROUSEL, $selector, $options);
185 }
186
187 /**
188 * Registers the Bootstrap collapse plugin.
189 * @param string $selector the CSS selector
190 * @param array $options the plugin options
191 * @see http://twitter.github.com/bootstrap/javascript.html#collapse
192 * @since 0.9.8
193 */
194 public function registerCollapse($selector = null, $options = array())
195 {
196 $this->registerPlugin(self::PLUGIN_COLLAPSE, $selector, $options, '.collapse');
197 }
198
199 /**
200 * Registers the Bootstrap dropdowns plugin.
201 * @param string $selector the CSS selector
202 * @param array $options the plugin options
203 * @see http://twitter.github.com/bootstrap/javascript.html#dropdowns
204 * @since 0.9.8
205 */
206 public function registerDropdown($selector = null, $options = array())
207 {
208 $this->registerPlugin(self::PLUGIN_DROPDOWN, $selector, $options, '.dropdown-toggle[data-dropdown="dropdown"]');
209 }
210
211 /**
212 * Registers the Bootstrap modal plugin.
213 * @param string $selector the CSS selector
214 * @param array $options the plugin options
215 * @see http://twitter.github.com/bootstrap/javascript.html#modal
216 * @since 0.9.8
217 */
218 public function registerModal($selector = null, $options = array())
219 {
220 $this->registerPlugin(self::PLUGIN_MODAL, $selector, $options);
221 }
222
223 /**
224 * Registers the Bootstrap scrollspy plugin.
225 * @param string $selector the CSS selector
226 * @param array $options the plugin options
227 * @see http://twitter.github.com/bootstrap/javascript.html#scrollspy
228 * @since 0.9.8
229 */
230 public function registerScrollSpy($selector = null, $options = array())
231 {
232 $this->registerPlugin(self::PLUGIN_SCROLLSPY, $selector, $options);
233 }
234
235 /**
236 * Registers the Bootstrap popover plugin.
237 * @param string $selector the CSS selector
238 * @param array $options the plugin options
239 * @see http://twitter.github.com/bootstrap/javascript.html#popover
240 * @since 0.9.8
241 */
242 public function registerPopover($selector = null, $options = array())
243 {
244 $this->registerTooltip(); // Popover requires the tooltip plugin
245 $this->registerPlugin(self::PLUGIN_POPOVER, $selector, $options, $this->popoverSelector);
246 }
247
248 /**
249 * Registers the Bootstrap tabs plugin.
250 * @param string $selector the CSS selector
251 * @param array $options the plugin options
252 * @see http://twitter.github.com/bootstrap/javascript.html#tabs
253 * @since 0.9.8
254 */
255 public function registerTabs($selector = null, $options = array())
256 {
257 $this->registerPlugin(self::PLUGIN_TAB, $selector, $options);
258 }
259
260 /**
261 * Registers the Bootstrap tooltip plugin.
262 * @param string $selector the CSS selector
263 * @param array $options the plugin options
264 * @see http://twitter.github.com/bootstrap/javascript.html#tooltip
265 * @since 0.9.8
266 */
267 public function registerTooltip($selector = null, $options = array())
268 {
269 $this->registerPlugin(self::PLUGIN_TOOLTIP, $selector, $options, $this->tooltipSelector);
270 }
271
272 /**
273 * Registers the Bootstrap typeahead plugin.
274 * @param string $selector the CSS selector
275 * @param array $options the plugin options
276 * @see http://twitter.github.com/bootstrap/javascript.html#typeahead
277 * @since 0.9.8
278 */
279 public function registerTypeahead($selector = null, $options = array())
280 {
281 $this->registerPlugin(self::PLUGIN_TYPEAHEAD, $selector, $options);
282 }
283
284 /**
285 * Registers a Bootstrap JavaScript plugin.
286 * @param string $name the name of the plugin
287 * @param string $selector the CSS selector
288 * @param array $options the plugin options
289 * @param string $defaultSelector the default CSS selector
290 * @since 0.9.8
291 */
292 protected function registerPlugin($name, $selector = null, $options = array(), $defaultSelector = null)
293 {
294 if (!isset($selector) && empty($options))
295 {
296 // Initialization from extension configuration.
297 $config = isset($this->plugins[$name]) ? $this->plugins[$name] : array();
298
299 if (isset($config['selector']))
300 $selector = $config['selector'];
301
302 if (isset($config['options']))
303 $options = $config['options'];
304
305 if (!isset($selector))
306 $selector = $defaultSelector;
307 }
308
309 if (isset($selector))
310 {
311 $key = __CLASS__.'.'.md5($name.$selector.serialize($options).$defaultSelector);
312 $options = !empty($options) ? CJavaScript::encode($options) : '';
313 Yii::app()->clientScript->registerScript($key, "jQuery('{$selector}').{$name}({$options});");
314 }
315 }
316
317 /**
318 * Returns the URL to the published assets folder.
319 * @return string the URL
320 */
321 protected function getAssetsUrl()
322 {
323 if (isset($this->_assetsUrl))
324 return $this->_assetsUrl;
325 else
326 {
327 $assetsPath = Yii::getPathOfAlias('bootstrap.assets');
328 $assetsUrl = Yii::app()->assetManager->publish($assetsPath, false, -1, YII_DEBUG);
329 return $this->_assetsUrl = $assetsUrl;
330 }
331 }
332
333 /**
334 * Returns the extension version number.
335 * @return string the version
336 */
337 public function getVersion()
338 {
339 return '1.0.0';
340 }
341 }
342