Commit 02c92fea by Suralc

Merge remote-tracking branch 'upstream/master' into add-tests

parents bae79cd7 90ddea11
......@@ -9,7 +9,10 @@ If you are looking for a production-ready PHP framework, please use
Yii 2.0 is still under heavy development. We may make significant changes
without prior notices. **Yii 2.0 is not ready for production use yet.**
[![Build Status](https://secure.travis-ci.org/yiisoft/yii2.png)](http://travis-ci.org/yiisoft/yii2) [![Dependency Status](https://www.versioneye.com/php/yiisoft:yii2/dev-master/badge.png)](https://www.versioneye.com/php/yiisoft:yii2/dev-master)
[![Latest Stable Version](https://poser.pugx.org/yiisoft/yii2/v/stable.png)](https://packagist.org/packages/yiisoft/yii2)
[![Total Downloads](https://poser.pugx.org/yiisoft/yii2/downloads.png)](https://packagist.org/packages/yiisoft/yii2)
[![Build Status](https://secure.travis-ci.org/yiisoft/yii2.png)](http://travis-ci.org/yiisoft/yii2)
[![Dependency Status](https://www.versioneye.com/php/yiisoft:yii2/dev-master/badge.png)](https://www.versioneye.com/php/yiisoft:yii2/dev-master)
DIRECTORY STRUCTURE
......
......@@ -6,6 +6,7 @@
*/
namespace backend\config;
use yii\web\AssetBundle;
/**
......@@ -23,6 +24,6 @@ class AppAsset extends AssetBundle
);
public $depends = array(
'yii\web\YiiAsset',
'yii\bootstrap\ResponsiveAsset',
'yii\bootstrap\BootstrapAsset',
);
}
<?php
return array(
'adminEmail' => 'admin@example.com',
);
\ No newline at end of file
);
......@@ -17,7 +17,7 @@ class SiteController extends Controller
{
$model = new LoginForm();
if ($model->load($_POST) && $model->login()) {
return $this->redirect(array('site/index'));
return $this->goHome();
} else {
return $this->render('login', array(
'model' => $model,
......@@ -28,6 +28,6 @@ class SiteController extends Controller
public function actionLogout()
{
Yii::$app->user->logout();
return $this->redirect(array('site/index'));
return $this->goHome();
}
}
<?php
use backend\config\AppAsset;
use yii\helpers\Html;
use yii\widgets\Menu;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
/**
......@@ -19,45 +20,45 @@ AppAsset::register($this);
<?php $this->head(); ?>
</head>
<body>
<div class="container">
<?php $this->beginBody(); ?>
<div class="masthead">
<h3 class="muted">My Company</h3>
<div class="navbar fullwidth">
<div class="navbar-inner">
<div class="container">
<?php echo Menu::widget(array(
'options' => array('class' => 'nav'),
'items' => array(
array('label' => 'Home', 'url' => array('/site/index')),
Yii::$app->user->isGuest ?
array('label' => 'Login', 'url' => array('/site/login')) :
array('label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => array('/site/logout')),
),
)); ?>
</div>
</div>
</div>
<!-- /.navbar -->
</div>
<?php
NavBar::begin(array(
'brandLabel' => 'My Company',
'brandUrl' => Yii::$app->homeUrl,
'options' => array(
'class' => 'navbar-inverse navbar-fixed-top',
),
));
$menuItems = array(
array('label' => 'Home', 'url' => array('/site/index')),
);
if (Yii::$app->user->isGuest) {
$menuItems[] = array('label' => 'Login', 'url' => array('/site/login'));
} else {
$menuItems[] = array('label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => array('/site/logout'));
}
echo Nav::widget(array(
'options' => array('class' => 'navbar-nav pull-right'),
'items' => $menuItems,
));
NavBar::end();
?>
<div class="container">
<?php echo Breadcrumbs::widget(array(
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : array(),
)); ?>
<?php echo $content; ?>
</div>
<hr>
<footer class="footer">
<div class="container">
<p class="pull-left">&copy; My Company <?php echo date('Y'); ?></p>
<p class="pull-right"><?php echo Yii::powered(); ?></p>
</div>
</footer>
<div class="footer">
<p>&copy; My Company <?php echo date('Y'); ?></p>
<p>
<?php echo Yii::powered(); ?>
Template by <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>
</p>
</div>
<?php $this->endBody(); ?>
</div>
</body>
</html>
<?php $this->endPage(); ?>
......@@ -2,46 +2,52 @@
/**
* @var yii\base\View $this
*/
$this->title = 'Welcome';
$this->title = 'My Yii Application';
?>
<div class="jumbotron">
<h1>Welcome!</h1>
<div class="site-index">
<p class="lead">Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus
commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a>
</div>
<div class="jumbotron">
<h1>Congratulations!</h1>
<hr>
<p class="lead">You have successfully created your Yii-powered application.</p>
<!-- Example row of columns -->
<div class="row-fluid">
<div class="span4">
<h2>Heading</h2>
<p><a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a></p>
</div>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui. </p>
<div class="body-content">
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<div class="row">
<div class="col-lg-4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<p><a class="btn btn-default" href="http://www.yiiframework.com/doc/">Yii Documentation &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta
felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum
massa.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn btn-default" href="http://www.yiiframework.com/forum/">Yii Forum &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn btn-default" href="http://www.yiiframework.com/extensions/">Yii Extensions &raquo;</a></p>
</div>
</div>
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
</div>
......@@ -10,15 +10,21 @@ use yii\widgets\ActiveForm;
$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-login">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>Please fill out the following fields to login:</p>
<p>Please fill out the following fields to login:</p>
<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(array('id' => 'login-form')); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
\ No newline at end of file
body {
padding-top: 20px;
padding-bottom: 60px;
padding-top: 70px;
}
/* Custom container */
.container {
margin: 0 auto;
max-width: 1000px;
.footer {
border-top: 1px solid #ddd;
margin-top: 30px;
padding-top: 15px;
padding-bottom: 30px;
}
.container > hr {
margin: 60px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
margin: 80px 0;
text-align: center;
}
.jumbotron h1 {
font-size: 100px;
line-height: 1;
}
.jumbotron .lead {
font-size: 24px;
line-height: 1.25;
text-align: center;
background-color: transparent;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
margin: 60px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
/* Customize the navbar links to be fill the entire space of the .navbar */
.navbar.fullwidth .navbar-inner {
padding: 0;
}
.navbar.fullwidth .nav {
margin: 0;
display: table;
width: 100%;
}
.navbar.fullwidth .nav li {
display: table-cell;
width: 1%;
float: none;
}
.navbar.fullwidth .nav li a {
font-weight: bold;
text-align: center;
border-left: 1px solid rgba(255, 255, 255, .75);
border-right: 1px solid rgba(0, 0, 0, .1);
}
.navbar.fullwidth .nav li:first-child a {
border-left: 0;
border-radius: 3px 0 0 3px;
}
.navbar.fullwidth .nav li:last-child a {
border-right: 0;
border-radius: 0 3px 3px 0;
font-size: 21px;
padding: 14px 24px;
}
<?php
return array(
'adminEmail' => 'admin@example.com',
);
\ No newline at end of file
);
......@@ -6,6 +6,7 @@
*/
namespace frontend\config;
use yii\web\AssetBundle;
/**
......@@ -23,6 +24,6 @@ class AppAsset extends AssetBundle
);
public $depends = array(
'yii\web\YiiAsset',
'yii\bootstrap\ResponsiveAsset',
'yii\bootstrap\BootstrapAsset',
);
}
<?php
return array(
'adminEmail' => 'admin@example.com',
);
\ No newline at end of file
);
......@@ -30,7 +30,7 @@ class SiteController extends Controller
{
$model = new LoginForm();
if ($model->load($_POST) && $model->login()) {
return $this->redirect(array('site/index'));
return $this->goHome();
} else {
return $this->render('login', array(
'model' => $model,
......@@ -41,7 +41,7 @@ class SiteController extends Controller
public function actionLogout()
{
Yii::$app->user->logout();
return $this->redirect(array('site/index'));
return $this->goHome();
}
public function actionContact()
......@@ -68,7 +68,7 @@ class SiteController extends Controller
$model->setScenario('signup');
if ($model->load($_POST) && $model->save()) {
if (Yii::$app->getUser()->login($model)) {
$this->redirect('index');
return $this->goHome();
}
}
......@@ -84,7 +84,7 @@ class SiteController extends Controller
if ($model->load($_POST) && $model->validate()) {
if ($this->sendPasswordResetEmail($model->email)) {
Yii::$app->getSession()->setFlash('success', 'Check your email for further instructions.');
$this->redirect('index');
return $this->goHome();
} else {
Yii::$app->getSession()->setFlash('error', 'There was an error sending email.');
}
......@@ -108,7 +108,7 @@ class SiteController extends Controller
$model->scenario = 'resetPassword';
if ($model->load($_POST) && $model->save()) {
Yii::$app->getSession()->setFlash('success', 'New password was saved.');
$this->redirect('index');
return $this->goHome();
}
return $this->render('resetPassword', array(
......
<?php
use frontend\config\AppAsset;
use yii\helpers\Html;
use yii\widgets\Menu;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
use frontend\widgets\Alert;
......@@ -20,57 +21,49 @@ AppAsset::register($this);
<?php $this->head(); ?>
</head>
<body>
<div class="container">
<?php $this->beginBody(); ?>
<div class="masthead">
<h3 class="muted">My Company</h3>
<div class="navbar fullwidth">
<div class="navbar-inner">
<div class="container">
<?php
$menuItems = array(
array('label' => 'Home', 'url' => array('/site/index')),
array('label' => 'About', 'url' => array('/site/about')),
array('label' => 'Contact', 'url' => array('/site/contact')),
);
if (Yii::$app->user->isGuest) {
$menuItems[] = array('label' => 'Signup', 'url' => array('/site/signup'));
$menuItems[] = array('label' => 'Login', 'url' => array('/site/login'));
}
else {
$menuItems[] = array('label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => array('/site/logout'));
}
echo Menu::widget(array(
'options' => array('class' => 'nav'),
'items' => $menuItems,
));
?>
</div>
</div>
</div>
<!-- /.navbar -->
</div>
<?php
NavBar::begin(array(
'brandLabel' => 'My Company',
'brandUrl' => Yii::$app->homeUrl,
'options' => array(
'class' => 'navbar-inverse navbar-fixed-top',
),
));
$menuItems = array(
array('label' => 'Home', 'url' => array('/site/index')),
array('label' => 'About', 'url' => array('/site/about')),
array('label' => 'Contact', 'url' => array('/site/contact')),
);
if (Yii::$app->user->isGuest) {
$menuItems[] = array('label' => 'Signup', 'url' => array('/site/signup'));
$menuItems[] = array('label' => 'Login', 'url' => array('/site/login'));
} else {
$menuItems[] = array('label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => array('/site/logout'));
}
echo Nav::widget(array(
'options' => array('class' => 'navbar-nav pull-right'),
'items' => $menuItems,
));
NavBar::end();
?>
<div class="container">
<?php echo Breadcrumbs::widget(array(
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : array(),
)); ?>
<?php echo Alert::widget()?>
<?php echo $content; ?>
</div>
<hr>
<footer class="footer">
<div class="container">
<p class="pull-left">&copy; My Company <?php echo date('Y'); ?></p>
<p class="pull-right"><?php echo Yii::powered(); ?></p>
</div>
</footer>
<div class="footer">
<p>&copy; My Company <?php echo date('Y'); ?></p>
<p>
<?php echo Yii::powered(); ?>
Template by <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>
</p>
</div>
<?php $this->endBody(); ?>
</div>
</body>
</html>
<?php $this->endPage(); ?>
<?php
use yii\helpers\Html;
/**
* @var yii\base\View $this
*/
$this->title = 'About';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<p>
This is the About page. You may modify the following file to customize its content:
</p>
<div class="site-about">
<h1><?php echo Html::encode($this->title); ?></h1>
<code><?php echo __FILE__; ?></code>
<p>This is the About page. You may modify the following file to customize its content:</p>
<code><?php echo __FILE__; ?></code>
</div>
......@@ -11,24 +11,29 @@ use yii\captcha\Captcha;
$this->title = 'Contact';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-contact">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>
<p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>
<?php $form = ActiveForm::begin(array(
'options' => array('class' => 'form-horizontal'),
'fieldConfig' => array('inputOptions' => array('class' => 'input-xlarge')),
)); ?>
<?php echo $form->field($model, 'name')->textInput(); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<?php echo $form->field($model, 'subject')->textInput(); ?>
<?php echo $form->field($model, 'body')->textArea(array('rows' => 6)); ?>
<?php echo $form->field($model, 'verifyCode')->widget(Captcha::className(), array(
'options' => array('class' => 'input-medium'),
)); ?>
<div class="form-actions">
<?php echo Html::submitButton('Submit', array('class' => 'btn btn-primary')); ?>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(array('id' => 'contact-form')); ?>
<?php echo $form->field($model, 'name')->textInput(); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<?php echo $form->field($model, 'subject')->textInput(); ?>
<?php echo $form->field($model, 'body')->textArea(array('rows' => 6)); ?>
<?php echo $form->field($model, 'verifyCode')->widget(Captcha::className(), array(
'options' => array('class' => 'form-control'),
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
)); ?>
<div class="form-actions">
<?php echo Html::submitButton('Submit', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
......@@ -2,46 +2,52 @@
/**
* @var yii\base\View $this
*/
$this->title = 'Welcome';
$this->title = 'My Yii Application';
?>
<div class="jumbotron">
<h1>Welcome!</h1>
<div class="site-index">
<p class="lead">Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus
commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a>
</div>
<div class="jumbotron">
<h1>Congratulations!</h1>
<hr>
<p class="lead">You have successfully created your Yii-powered application.</p>
<!-- Example row of columns -->
<div class="row-fluid">
<div class="span4">
<h2>Heading</h2>
<p><a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a></p>
</div>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui. </p>
<div class="body-content">
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<div class="row">
<div class="col-lg-4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<p><a class="btn btn-default" href="http://www.yiiframework.com/doc/">Yii Documentation &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta
felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum
massa.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn btn-default" href="http://www.yiiframework.com/forum/">Yii Forum &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn btn-default" href="http://www.yiiframework.com/extensions/">Yii Extensions &raquo;</a></p>
</div>
</div>
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
</div>
......@@ -10,17 +10,24 @@ use yii\widgets\ActiveForm;
$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-login">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>Please fill out the following fields to login:</p>
<p>Please fill out the following fields to login:</p>
<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(array('id' => 'login-form')); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
<div style="color:#999;margin:1em 0">
If you forgot your password you can <?php echo Html::a('reset it', array('site/request-password-reset'))?>.
</div>
<div class="form-actions">
<?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
<p>If you forgot your password you can <?php echo Html::a('reset it', array('site/request-password-reset'))?>.</p>
\ No newline at end of file
</div>
\ No newline at end of file
......@@ -5,18 +5,24 @@ use yii\widgets\ActiveForm;
/**
* @var yii\base\View $this
* @var yii\widgets\ActiveForm $form
* @var frontend\models\User $model
* @var common\models\User $model
*/
$this->title = 'Request password reset';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-request-password-reset">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>Please fill out your email. A link to reset password will be sent there.</p>
<p>Please fill out your email. A link to reset password will be sent there.</p>
<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Send', array('class' => 'btn btn-primary')); ?>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(array('id' => 'request-password-reset-form')); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Send', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
......@@ -10,13 +10,19 @@ use yii\widgets\ActiveForm;
$this->title = 'Reset password';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-reset-password">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>Please choose your new password:</p>
<p>Please choose your new password:</p>
<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Save', array('class' => 'btn btn-primary')); ?>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(array('id' => 'reset-password-form')); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Save', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
\ No newline at end of file
......@@ -10,15 +10,21 @@ use yii\widgets\ActiveForm;
$this->title = 'Signup';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-signup">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>Please fill out the following fields to signup:</p>
<p>Please fill out the following fields to signup:</p>
<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal'))); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Signup', array('class' => 'btn btn-primary')); ?>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(array('id' => 'form-signup')); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Signup', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
body {
padding-top: 20px;
padding-bottom: 60px;
padding-top: 70px;
}
/* Custom container */
.container {
margin: 0 auto;
max-width: 1000px;
.footer {
border-top: 1px solid #ddd;
margin-top: 30px;
padding-top: 15px;
padding-bottom: 30px;
}
.container > hr {
margin: 60px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
margin: 80px 0;
text-align: center;
}
.jumbotron h1 {
font-size: 100px;
line-height: 1;
}
.jumbotron .lead {
font-size: 24px;
line-height: 1.25;
text-align: center;
background-color: transparent;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
margin: 60px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
/* Customize the navbar links to be fill the entire space of the .navbar */
.navbar.fullwidth .navbar-inner {
padding: 0;
}
.navbar.fullwidth .nav {
margin: 0;
display: table;
width: 100%;
}
.navbar.fullwidth .nav li {
display: table-cell;
width: 1%;
float: none;
}
.navbar.fullwidth .nav li a {
font-weight: bold;
text-align: center;
border-left: 1px solid rgba(255, 255, 255, .75);
border-right: 1px solid rgba(0, 0, 0, .1);
}
.navbar.fullwidth .nav li:first-child a {
border-left: 0;
border-radius: 3px 0 0 3px;
}
.navbar.fullwidth .nav li:last-child a {
border-right: 0;
border-radius: 0 3px 3px 0;
font-size: 21px;
padding: 14px 24px;
}
......@@ -24,6 +24,6 @@ class AppAsset extends AssetBundle
);
public $depends = array(
'yii\web\YiiAsset',
'yii\bootstrap\ResponsiveAsset',
'yii\bootstrap\BootstrapAsset',
);
}
<?php
return array(
$config = array(
'id' => 'bootstrap',
'basePath' => dirname(__DIR__),
'preload' => array('debug'),
'modules' => array(
'debug' => array(
'class' => 'yii\debug\Module',
'enabled' => YII_DEBUG && YII_ENV_DEV,
),
),
'components' => array(
'cache' => array(
'class' => 'yii\caching\FileCache',
),
'user' => array(
'class' => 'yii\web\User',
'identityClass' => 'app\models\User',
),
'errorHandler' => array(
'errorAction' => 'site/error',
),
'log' => array(
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => array(
......@@ -30,3 +25,11 @@ return array(
),
'params' => require(__DIR__ . '/params.php'),
);
if (YII_ENV_DEV) {
$config['preload'][] = 'debug';
$config['modules']['debug'] = 'yii\debug\Module';
$config['modules']['gii'] = 'yii\gii\Module';
}
return $config;
......@@ -12,9 +12,12 @@ class SiteController extends Controller
public function actions()
{
return array(
'error' => array(
'class' => 'yii\web\ErrorAction',
),
'captcha' => array(
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_DEV ? 'testme' : null,
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
),
);
}
......@@ -28,7 +31,7 @@ class SiteController extends Controller
{
$model = new LoginForm();
if ($model->load($_POST) && $model->login()) {
return $this->redirect(array('site/index'));
return $this->goHome();
} else {
return $this->render('login', array(
'model' => $model,
......@@ -39,7 +42,7 @@ class SiteController extends Controller
public function actionLogout()
{
Yii::$app->user->logout();
return $this->redirect(array('site/index'));
return $this->goHome();
}
public function actionContact()
......
<?php
use yii\helpers\Html;
use yii\widgets\Menu;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
/**
......@@ -19,45 +20,42 @@ app\config\AppAsset::register($this);
</head>
<body>
<?php $this->beginBody(); ?>
<div class="container">
<div class="masthead">
<h3 class="muted">My Company</h3>
<?php
NavBar::begin(array(
'brandLabel' => 'My Company',
'brandUrl' => Yii::$app->homeUrl,
'options' => array(
'class' => 'navbar-inverse navbar-fixed-top',
),
));
echo Nav::widget(array(
'options' => array('class' => 'navbar-nav pull-right'),
'items' => array(
array('label' => 'Home', 'url' => array('/site/index')),
array('label' => 'About', 'url' => array('/site/about')),
array('label' => 'Contact', 'url' => array('/site/contact')),
Yii::$app->user->isGuest ?
array('label' => 'Login', 'url' => array('/site/login')) :
array('label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => array('/site/logout')),
),
));
NavBar::end();
?>
<div class="navbar fullwidth">
<div class="navbar-inner">
<div class="container">
<?php echo Menu::widget(array(
'options' => array('class' => 'nav'),
'items' => array(
array('label' => 'Home', 'url' => array('/site/index')),
array('label' => 'About', 'url' => array('/site/about')),
array('label' => 'Contact', 'url' => array('/site/contact')),
Yii::$app->user->isGuest ?
array('label' => 'Login', 'url' => array('/site/login')) :
array('label' => 'Logout (' . Yii::$app->user->identity->username .')' , 'url' => array('/site/logout')),
),
)); ?>
</div>
</div>
</div>
<!-- /.navbar -->
<div class="container">
<?php echo Breadcrumbs::widget(array(
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : array(),
)); ?>
<?php echo $content; ?>
</div>
<?php echo Breadcrumbs::widget(array(
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : array(),
)); ?>
<?php echo $content; ?>
<hr>
<footer class="footer">
<div class="container">
<p class="pull-left">&copy; My Company <?php echo date('Y'); ?></p>
<p class="pull-right"><?php echo Yii::powered(); ?></p>
</div>
</footer>
<div class="footer">
<p>&copy; My Company <?php echo date('Y'); ?></p>
<p>
<?php echo Yii::powered(); ?>
Template by <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>
</p>
</div>
</div>
<?php $this->endBody(); ?>
</body>
</html>
......
......@@ -7,11 +7,12 @@ use yii\helpers\Html;
$this->title = 'About';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-about">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>
This is the About page. You may modify the following file to customize its content:
</p>
<code><?php echo __FILE__; ?></code>
<p>
This is the About page. You may modify the following file to customize its content:
</p>
<code><?php echo __FILE__; ?></code>
</div>
......@@ -11,30 +11,38 @@ use yii\captcha\Captcha;
$this->title = 'Contact';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-contact">
<h1><?php echo Html::encode($this->title); ?></h1>
<?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
<div class="alert alert-success">
Thank you for contacting us. We will respond to you as soon as possible.
</div>
<?php return; endif; ?>
<?php if (Yii::$app->session->hasFlash('contactFormSubmitted')): ?>
<div class="alert alert-success">
Thank you for contacting us. We will respond to you as soon as possible.
</div>
<p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>
<?php else: ?>
<?php $form = ActiveForm::begin(array(
'options' => array('class' => 'form-horizontal', 'id' => 'contact-form'),
'fieldConfig' => array('inputOptions' => array('class' => 'input-xlarge')),
)); ?>
<?php echo $form->field($model, 'name')->textInput(); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<?php echo $form->field($model, 'subject')->textInput(); ?>
<?php echo $form->field($model, 'body')->textArea(array('rows' => 6)); ?>
<?php echo $form->field($model, 'verifyCode')->widget(Captcha::className(), array(
'options' => array('class' => 'input-medium'),
)); ?>
<div class="form-actions">
<?php echo Html::submitButton('Submit', array('class' => 'btn btn-primary')); ?>
<p>
If you have business inquiries or other questions, please fill out the following form to contact us. Thank you.
</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(array('id' => 'contact-form')); ?>
<?php echo $form->field($model, 'name')->textInput(); ?>
<?php echo $form->field($model, 'email')->textInput(); ?>
<?php echo $form->field($model, 'subject')->textInput(); ?>
<?php echo $form->field($model, 'body')->textArea(array('rows' => 6)); ?>
<?php echo $form->field($model, 'verifyCode')->widget(Captcha::className(), array(
'options' => array('class' => 'form-control'),
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
)); ?>
<div class="form-actions">
<?php echo Html::submitButton('Submit', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
<?php ActiveForm::end(); ?>
<?php endif; ?>
</div>
<?php
use yii\helpers\Html;
/**
* @var yii\base\View $this
* @var string $name
* @var string $message
* @var Exception $exception
*/
$this->title = $name;
?>
<div class="site-error">
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="alert alert-danger">
<?php echo nl2br(Html::encode($message)); ?>
</div>
<p>
The above error occurred while the Web server was processing your request.
</p>
<p>
Please contact us if you think this is a server error. Thank you.
</p>
</div>
......@@ -2,46 +2,52 @@
/**
* @var yii\base\View $this
*/
$this->title = 'Welcome';
$this->title = 'My Yii Application';
?>
<div class="jumbotron">
<h1>Welcome!</h1>
<div class="site-index">
<p class="lead">Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus
commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a>
</div>
<div class="jumbotron">
<h1>Congratulations!</h1>
<hr>
<p class="lead">You have successfully created your Yii-powered application.</p>
<!-- Example row of columns -->
<div class="row-fluid">
<div class="span4">
<h2>Heading</h2>
<p><a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a></p>
</div>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui. </p>
<div class="body-content">
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<div class="row">
<div class="col-lg-4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris
condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.
Donec sed odio dui. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
<div class="span4">
<h2>Heading</h2>
<p><a class="btn btn-default" href="http://www.yiiframework.com/doc/">Yii Documentation &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta
felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum
massa.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn btn-default" href="http://www.yiiframework.com/forum/">Yii Forum &raquo;</a></p>
</div>
<div class="col-lg-4">
<h2>Heading</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</p>
<p><a class="btn btn-default" href="http://www.yiiframework.com/extensions/">Yii Extensions &raquo;</a></p>
</div>
</div>
<p><a class="btn" href="#">View details &raquo;</a></p>
</div>
</div>
......@@ -10,15 +10,25 @@ use yii\widgets\ActiveForm;
$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<div class="site-login">
<h1><?php echo Html::encode($this->title); ?></h1>
<p>Please fill out the following fields to login:</p>
<p>Please fill out the following fields to login:</p>
<?php $form = ActiveForm::begin(array('options' => array('class' => 'form-horizontal', 'id' => 'login-form'))); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?>
<div class="row">
<div class="col-lg-3">
<?php $form = ActiveForm::begin(array('id' => 'login-form')); ?>
<?php echo $form->field($model, 'username')->textInput(); ?>
<?php echo $form->field($model, 'password')->passwordInput(); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
<div class="form-actions">
<?php echo Html::submitButton('Login', array('class' => 'btn btn-primary')); ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<div class="col-lg-5" style="color:#999;margin:1em;padding-top:60px">
You may login with <strong>admin/admin</strong> or <strong>demo/demo</strong>.<br>
To modify the username/password, please check out the code <code>app\models\User::$users</code>.
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
body {
padding-top: 20px;
padding-bottom: 60px;
padding-top: 70px;
}
/* Custom container */
.container {
margin: 0 auto;
max-width: 1000px;
.footer {
border-top: 1px solid #ddd;
margin-top: 30px;
padding-top: 15px;
padding-bottom: 30px;
}
.container > hr {
margin: 60px 0;
}
/* Main marketing message and sign up button */
.jumbotron {
margin: 80px 0;
text-align: center;
}
.jumbotron h1 {
font-size: 100px;
line-height: 1;
}
.jumbotron .lead {
font-size: 24px;
line-height: 1.25;
background-color: transparent;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
/* Supporting marketing content */
.marketing {
margin: 60px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
/* Customize the navbar links to be fill the entire space of the .navbar */
.navbar.fullwidth .navbar-inner {
padding: 0;
}
.navbar.fullwidth .nav {
margin: 0;
display: table;
width: 100%;
}
.navbar.fullwidth .nav li {
display: table-cell;
width: 1%;
float: none;
}
.navbar.fullwidth .nav li a {
font-weight: bold;
text-align: center;
border-left: 1px solid rgba(255, 255, 255, .75);
border-right: 1px solid rgba(0, 0, 0, .1);
}
.navbar.fullwidth .nav li:first-child a {
border-left: 0;
border-radius: 3px 0 0 3px;
}
.navbar.fullwidth .nav li:last-child a {
border-right: 0;
border-radius: 0 3px 3px 0;
}
<?php
// comment out the following line to disable debug mode
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
......
......@@ -33,7 +33,7 @@ class ClassmapController extends Controller
$mapFile = YII_PATH . '/classes.php';
}
$options = array(
'filter' => function($path) {
'filter' => function ($path) {
if (is_file($path)) {
$file = basename($path);
if ($file[0] < 'A' || $file[0] > 'Z') {
......
Advanced application template
=============================
This template is for large projects developed in teams where backend is divided from frontend, application is deployed
to multiple servers etc. This application template also goes a bit further regarding features and provides essential
database, signup and password restore out of the box.
Directory structure
-------------------
The root directory contains the following subdirectories:
- `backend` - backend web application.
- `common` - files common to all applications.
- `console` - console application.
- `environments` - environment configs.
- `frontend` - frontend web application.
Root directory contains a set of files.
- `.gitignore` contains a list of directories ignored by git version system. If you need something never get to your source
code repository, add it there.
- `composer.json` - Composer config described in detail below.
- `init` - initialization script described in "Composer config described in detail below".
- `init.bat` - same for Windows.
- `LICENSE.md` - license info. Put your project license there. Especially when opensourcing.
- `README.md` - basic info about installing template. Consider replacing it with information about your project and its
installation.
- `requirements.php` - Yii requirements checker.
- `yii` - console application bootstrap.
- `yii.bat` - same for Windows.
Applications
------------
There are three applications in advanced template: frontend, backend and console. Frontend is typically what is presented
to end user, the project itself. Backend is admin panel, analytics and such functionality. Console is typically used for
cron jobs and low-level server management. Also it's used during application deployment and handles migrations and assets.
There's also a `common` directory that contains files used by more than one application. For example, `User` model.
frontend and backend are both web applications and both contain `web` directory. That's the webroot you should point your
webserver to.
Each application has its own namespace and alias corresponding to its name. Same applies to common directory.
Configuration and environments
------------------------------
There are multiple problems with straightforward approach to configuration:
- Each team member has its own configuration options. Commiting such config will affect other team members.
- Production database password and API keys should not end up in repository.
- There are multiple servers: development, testing, production. Each should have its own configuration.
- Defining all configuration options for each case is very repetitive and takes too much time to maintain.
In order to solve these issues Yii introduces environments concept that is very simple. Each environment is represented
by a set of files under `environments` directory. `init` command is used to switch between these. What is really does is
just copying everything from environment directory over the root directory where all applications are.
Typically environment contains application bootstrap files such as `index.php` and config files postfixed with
`-local.php`. These are added to `.gitignore` and never added to source code repository.
In order to avoid duplication configurations are overrding each other. For example, frontend reads configuration in the
following order:
- `frontend/config/main.php`
- `frontend/config/main-local.php`
Parameters are read in the following order:
- `common/config/params.php`
- `common/config/params-local.php`
- `frontend/config/params.php`
- `frontend/config/params-local.php`
The later config file overrides the former.
Another difference is that most application component configurations are moved to params. Since params are read from
`common` as well it allows you to specify database connection in one file and it will be then used for all applications.
Configuring Composer
--------------------
After application template is installed it's a good idea to adjust defaul `composer.json` that can be found in the root
directory:
```javascript
{
"name": "yiisoft/yii2-app-advanced",
"description": "Yii 2 Advanced Application Template",
"keywords": ["yii", "framework", "advanced", "application template"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?state=open",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"minimum-stability": "dev",
"require": {
"php": ">=5.3.0",
"yiisoft/yii2": "dev-master",
"yiisoft/yii2-composer": "dev-master"
},
"scripts": {
"post-create-project-cmd": [
"yii\\composer\\InstallHandler::setPermissions"
]
},
"extra": {
"yii-install-writable": [
"backend/runtime",
"backend/web/assets",
"console/runtime",
"console/migrations",
"frontend/runtime",
"frontend/web/assets"
]
}
}
```
First we're updating basic information. Change `name`, `description`, `keywords`, `homepage` and `support` to match
your project.
Now the interesting part. You can add more packages your application needs to `require` section.
For example, to use markdown helper you need to add `michelf/php-markdown`. All these packages are coming from
[packagist.org](https://packagist.org/) so feel free to browse the website for useful code.
After your `composer.json` is changed you can run `php composer.phar update`, wait till packages are downloaded and
installed and then just use them. Autoloading of classes will be handled automatically.
Basic application template
==========================
This template is a perfect fit for small projects or learning Yii2.
The application has four pages: the homepage, the about page, the contact page and the login page.
The contact page displays a contact form that users can fill in to submit their inquiries to the webmaster,
and the login page allows users to be authenticated before accessing privileged contents.
Directory structure
-------------------
The basic application does not divide application directories much. Here's the basic structure:
- `commands` - console controllers.
- `config` - configuration.
- `controllers` - web controllers.
- `models` - application models.
- `runtime` - logs, states, file cache.
- `views` - view templates.
- `web` - webroot.
Root directory contains a set of files.
- `.gitignore` contains a list of directories ignored by git version system. If you need something never get to your source
code repository, add it there.
- `codeception.yml` - Codeception config.
- `composer.json` - Composer config described in detail below.
- `LICENSE.md` - license info. Put your project license there. Especially when opensourcing.
- `README.md` - basic info about installing template. Consider replacing it with information about your project and its
installation.
- `requirements.php` - Yii requirements checker.
- `yii` - console application bootstrap.
- `yii.bat` - same for Windows.
### config
This directory contains configuration files:
- `AppAsset.php` - definition of application assets such as CSS, JavaScript etc. Check [Managing assets](assets.md) for
details.
- `console.php` - console application configuration.
- `params.php` - common application parameters.
- `web.php` - web application configuration.
- `web-test.php` - web application configuration used when running functional tests.
All these files except `AppAsset.php` are returning arrays used to configure corresponding application properties. Check
[Configuration](configuration.md) guide section for details.
### views
Views directory contains templates your application is using. In the basic template there are:
```
layouts
main.php
site
about.php
contact.php
error.php
index.php
login.php
```
`layouts` contains HTML layouts i.e. page markup except content: doctype, head section, main menu, footer etc.
The rest are typically controller views. By convention these are located in subdirectories matching controller id. For
`SiteController` views are under `site`. Names of the views themselves are typically match controller action names.
Partials are often named starting with underscore.
### web
Directory is a webroot. Typically a webserver is pointed into it.
```
assets
css
index.php
index-test.php
```
`assets` contains published asset files such as CSS, JavaScript etc. Publishing process is automatic so you don't need
to do anything with this directory other than making sure Yii has enough permissions to write to it.
`css` contains plain CSS files and is useful for global CSS that isn't going to be compressed or merged by assets manager.
`index.php` is the main web application bootstrap and is the central entry point for it. `index-test.php` is the entry
point for functional testing.
Configuring Composer
--------------------
After application template is installed it's a good idea to adjust defaul `composer.json` that can be found in the root
directory:
```javascript
{
"name": "yiisoft/yii2-app-basic",
"description": "Yii 2 Basic Application Template",
"keywords": ["yii", "framework", "basic", "application template"],
"homepage": "http://www.yiiframework.com/",
"type": "project",
"license": "BSD-3-Clause",
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?state=open",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"minimum-stability": "dev",
"require": {
"php": ">=5.3.0",
"yiisoft/yii2": "dev-master",
"yiisoft/yii2-composer": "dev-master"
},
"scripts": {
"post-create-project-cmd": [
"yii\\composer\\InstallHandler::setPermissions"
]
},
"extra": {
"yii-install-writable": [
"runtime",
"web/assets"
],
"yii-install-executable": [
"yii"
]
}
}
```
First we're updating basic information. Change `name`, `description`, `keywords`, `homepage` and `support` to match
your project.
Now the interesting part. You can add more packages your application needs to `require` section.
For example, to use markdown helper you need to add `michelf/php-markdown`. All these packages are coming from
[packagist.org](https://packagist.org/) so feel free to browse the website for useful code.
After your `composer.json` is changed you can run `php composer.phar update`, wait till packages are downloaded and
installed and then just use them. Autoloading of classes will be handled automatically.
\ No newline at end of file
Twitter Bootstrap widgets
=========================
Overview
--------
Bootstrap with Yii
==================
Yii provides a few ready-to-use application templates. Based on your needs, you may
choose one of them to bootstrap your project.
In the following, we describe how to get started with the "Yii 2 Basic Application Template".
### Install via Composer
If you do not have [Composer](http://getcomposer.org/), you may download it from
[http://getcomposer.org/](http://getcomposer.org/) or run the following command on Linux/Unix/MacOS:
~~~
curl -s http://getcomposer.org/installer | php
~~~
You can then install the Bootstrap Application using the following command:
~~~
php composer.phar create-project --stability=dev yiisoft/yii2-app-basic yii-basic
~~~
Now you should be able to access the Bootstrap Application using the URL `http://localhost/yii-basic/web/`,
assuming `yii-basic` is directly under the document root of your Web server.
As you can see, the application has four pages: the homepage, the about page,
the contact page and the login page. The contact page displays a contact
form that users can fill in to submit their inquiries to the webmaster,
and the login page allows users to be authenticated before accessing privileged contents.
The following diagram shows the directory structure of this application.
~~~
yii-basic/
yii yii command line script for Unix/Linux
yii.bat yii command line script for Windows
requirements.php the requirement checker script
commands/ containing customized yii console commands
config/ containing configuration files
console.php the console application configuration
main.php the Web application configuration
controllers/ containing controller class files
SiteController.php the default controller class
vendor/ containing third-party extensions and libraries
models/ containing model class files
User.php the User model
LoginForm.php the form model for 'login' action
ContactForm.php the form model for 'contact' action
runtime/ containing temporarily generated files
views/ containing controller view and layout files
layouts/ containing layout view files
main.php the base layout shared by all pages
site/ containing view files for the 'site' controller
about.php the view for the 'about' action
contact.php the view for the 'contact' action
index.php the view for the 'index' action
login.php the view for the 'login' action
web/ containing Web-accessible resources
index.php Web application entry script file
assets/ containing published resource files
css/ containing CSS files
~~~
TBD
Configuration
=============
In Yii application and majority of components have sensible defaults so it's unlikely you spend lots of time configuring
it. Still there are some mandatory options such as database connection you should set up.
How application is configured depends on application template but there are some genral principles applying in any case.
Configuring options in bootstrap file
-------------------------------------
For each application in Yii there is at least one bootstrap file. For web applications it's typically `index.php`, for
console applications it's `yii`. Both are doing nearly the same job:
1. Setting common constants.
2. Including Yii itself.
3. Including Composer autoloader.
4. Reading config file into `$config`.
5. Creating new application instance using `$config` and running it.
Bootstrap file is not the part of framework but your application so it's OK to adjust it to fit your application. Typical
adjustments are the value of `YII_DEBUG` that should never be `true` on production and the way config is read.
Configuring application instance
--------------------------------
It was mentioned above that application is configured in bootstrap file when its instance is created. Config is typically
stored in a PHP file in `/config` directory of the application and looks like the following:
```php
<?php
return array(
'id' => 'applicationId',
'basePath' => dirname(__DIR__),
'components' => array(
// ...
),
'params' => require(__DIR__ . '/params.php'),
);
```
In the above array keys are names of application properties. Depending on application type you can check properies of
either `\yii\web\Application` or `\yii\console\Application`. Both are extended from `\yii\base\Application`.
> Note that you can configure not only public class properties but anything accessible via setter. For example, to
configure runtime path you can use key named `runtimePath`. There's no such property in the application class but
since there's a corresponding setter named `setRuntimePath` it will be properly configured.
Configuring application components
----------------------------------
Majority of Yii functionality are application components. These are attached to application via its `components` property:
```php
<?php
return array(
'id' => 'applicationId',
'basePath' => dirname(__DIR__),
'components' => array(
'cache' => array(
'class' => 'yii\caching\FileCache',
),
'user' => array(
'identityClass' => 'app\models\User',
),
'errorHandler' => array(
'errorAction' => 'site/error',
),
'log' => array(
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => array(
array(
'class' => 'yii\log\FileTarget',
'levels' => array('error', 'warning'),
),
),
),
),
// ...
);
```
In the above four components are configured: `cache`, `user`, `errorHandler`, `log`. Each entry key is a component ID
and the value is the configuration array. ID is used to access the component like `\Yii::$app->myComponent`.
Configuration array has one special key named `class` that sets component class. The rest of the keys and values are used
to configure component properties in the same way as top-level keys are used to configure application properties.
Each application has predefined set of the components. In case of configuring one of these `class` key is omitted and
application default class is used instead. You can check `registerCoreComponents` method of the application you are using
to get a list of component IDs and corresponding classes.
Note that Yii is smart enough to configure the component when it's actually used i.e. if `cache` is never used it will
not be instantiated and configured at all.
Setting component defaults classwide
------------------------------------
TBD
\ No newline at end of file
Debug toolbar and debugger
==========================
Overview
--------
Creating your own panels
------------------------
......@@ -7,9 +7,15 @@ Getting started
===============
- [Installation](installation.md)
- [Bootstrap with Yii](bootstrap.md)
- [Configuration](configuration.md)
Application templates
=====================
- [Basic](apps-basic.md)
- [Advanced](apps-advanced.md)
- [Creating your own application template](apps-own.md)
Base concepts
=============
......@@ -41,17 +47,26 @@ Security and access control
- [Security](security.md)
- Role based access control
Data providers, lists and grids
===============================
- Overview
- Data providers
- Grids
- Lists
Toolbox
=======
- [Automatic Code Generation](gii.md)
- Debug toolbar
- [Debug toolbar and debugger](debugger.md)
- [Error Handling](error.md)
- [Logging](logging.md)
More
====
- [Bootstrap widgets](bootstrap-widgets.md)
- [Form](form.md)
- [Model validation reference](validation.md)
- [Caching](caching.md)
......@@ -60,5 +75,6 @@ More
- [Theming](theming.md)
- [Console Application](console.md)
- [Performance Tuning](performance.md)
- [Managing assets](assets.md)
- [Testing](testing.md)
- [Upgrading from 1.1 to 2.0](upgrade-from-v1.md)
......@@ -4,7 +4,15 @@ Installation
Installing via Composer
-----------------------
The recommended way of installing Yii is by using Composer package manager.
The recommended way of installing Yii is by using [Composer](http://getcomposer.org/) package manager. If you do not
have it, you may download it from [http://getcomposer.org/](http://getcomposer.org/) or run the following command:
```
curl -s http://getcomposer.org/installer | php
```
Yii provides a few ready-to-use application templates. Based on your needs, you may choose one of them to bootstrap
your project.
There are two application templates available:
......@@ -12,7 +20,8 @@ There are two application templates available:
- [advanced](https://github.com/yiisoft/yii2-app-advanced) that is a set of frontend, backend, console, common
(shared code) and environments support.
Please refer to installation instructions on these pages.
Please refer to installation instructions on these pages. To read more about ideas behing these application templates and
proposed usage refer to [basic application template](apps-basic.md) and [advanced application template](apps-advanced.md).
Installing from zip
-------------------
......
......@@ -22,6 +22,6 @@ class DialogAsset extends AssetBundle
'yii\jui\CoreAsset',
'yii\jui\ButtonAsset',
'yii\jui\DraggableAsset',
'yii\jui\Resizable',
'yii\jui\ResizableAsset',
);
}
......@@ -46,7 +46,7 @@ class ViewRenderer extends BaseViewRenderer
'cache' => Yii::getAlias($this->cachePath),
), $this->options));
$this->twig->addFunction('path', new \Twig_Function_Function(function($path, $args = array()){
$this->twig->addFunction('path', new \Twig_Function_Function(function ($path, $args = array()) {
return Html::url(array_merge(array($path), $args));
}));
......
......@@ -9,7 +9,6 @@ namespace yii;
use yii\base\Exception;
use yii\base\InvalidConfigException;
use yii\base\InvalidParamException;
use yii\base\UnknownClassException;
use yii\log\Logger;
/**
......@@ -69,11 +68,6 @@ class YiiBase
*/
public static $classMap = array();
/**
* @var boolean whether to search PHP include_path when autoloading unknown classes.
* You may want to turn this off if you are also using autoloaders from other libraries.
*/
public static $enableIncludePath = false;
/**
* @var \yii\console\Application|\yii\web\Application the application instance
*/
public static $app;
......@@ -338,23 +332,17 @@ class YiiBase
* 3. If the class is named in PEAR style (e.g. `PHPUnit_Framework_TestCase`),
* it will attempt to include the file associated with the corresponding path alias
* (e.g. `@PHPUnit/Framework/TestCase.php`);
* 4. Search PHP include_path for the actual class file if [[enableIncludePath]] is true;
* 5. Return false so that other autoloaders have chance to include the class file.
*
* @param string $className class name
* @return boolean whether the class has been loaded successfully
* @throws InvalidConfigException if the class file does not exist
* @throws UnknownClassException if the class does not exist in the class file
* @param string $className the fully qualified class name without a leading backslash "\"
*/
public static function autoload($className)
{
$className = ltrim($className, '\\');
if (isset(self::$classMap[$className])) {
$classFile = self::$classMap[$className];
if ($classFile[0] === '@') {
$classFile = static::getAlias($classFile);
}
include($classFile);
} else {
// follow PSR-0 to determine the class file
if (($pos = strrpos($className, '\\')) !== false) {
......@@ -365,32 +353,13 @@ class YiiBase
$path = str_replace('_', '/', $className) . '.php';
}
// try via path alias first
// try loading via path alias
if (strpos($path, '/') !== false) {
$fullPath = static::getAlias('@' . $path, false);
if ($fullPath !== false && is_file($fullPath)) {
$classFile = $fullPath;
$classFile = static::getAlias('@' . $path, false);
if ($classFile !== false && is_file($classFile)) {
include($classFile);
}
}
// search include_path
if (!isset($classFile) && self::$enableIncludePath && ($fullPath = stream_resolve_include_path($path)) !== false) {
$classFile = $fullPath;
}
if (!isset($classFile)) {
// return false to let other autoloaders to try loading the class
return false;
}
}
include($classFile);
if (class_exists($className, false) || interface_exists($className, false) ||
function_exists('trait_exists') && trait_exists($className, false)) {
return true;
} else {
throw new UnknownClassException("Unable to find '$className' in file: $classFile");
}
}
......@@ -567,7 +536,7 @@ class YiiBase
*/
public static function powered()
{
return 'Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a>.';
return 'Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a>';
}
/**
......
......@@ -83,7 +83,7 @@
var settings = $.extend({}, defaults, options || {});
if (settings.validationUrl === undefined) {
settings.validationUrl = $form.attr('action');
settings.validationUrl = $form.prop('action');
}
$.each(attributes, function (i) {
attributes[i] = $.extend({value: getValue($form, this)}, attributeDefaults, this);
......@@ -291,13 +291,13 @@
// If the validation is triggered by form submission, ajax validation
// should be done only when all inputs pass client validation
var $button = data.submitObject,
extData = '&' + data.settings.ajaxVar + '=' + $form.attr('id');
if ($button && $button.length && $button.attr('name')) {
extData += '&' + $button.attr('name') + '=' + $button.attr('value');
extData = '&' + data.settings.ajaxVar + '=' + $form.prop('id');
if ($button && $button.length && $button.prop('name')) {
extData += '&' + $button.prop('name') + '=' + $button.prop('value');
}
$.ajax({
url: data.settings.validationUrl,
type: $form.attr('method'),
type: $form.prop('method'),
data: $form.serialize() + extData,
dataType: 'json',
success: function (msgs) {
......@@ -380,7 +380,7 @@
var getValue = function ($form, attribute) {
var $input = findInput($form, attribute);
var type = $input.attr('type');
var type = $input.prop('type');
if (type === 'checkbox' || type === 'radio') {
return $input.filter(':checked').val();
} else {
......
/**
* Yii GridView widget.
*
* This is the JavaScript widget used by the yii\grid\GridView widget.
*
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
(function ($) {
$.fn.yiiGridView = function (method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.yiiGridView');
return false;
}
};
var defaults = {
};
var methods = {
init: function (options) {
return this.each(function () {
var $e = $(this);
var settings = $.extend({}, defaults, options || {});
$e.data('yiiGridView', {
settings: settings
});
});
},
setSelectionColumn: function (options) {
var $grid = $(this);
var data = $grid.data('yiiGridView');
data.selectionColumn = options.name;
if (!options.multiple) {
return;
}
$grid.on('click.yiiGridView', "input[name='" + options.checkAll + "']", function () {
$grid.find("input[name='" + options.name + "']:enabled").prop('checked', this.checked);
});
$grid.on('click.yiiGridView', "input[name='" + options.name + "']:enabled", function () {
var all = $grid.find("input[name='" + options.name + "']").length == $grid.find("input[name='" + options.name + "']:checked").length;
$grid.find("input[name='" + options.checkAll + "']").prop('checked', all);
});
},
getSelectedRows: function () {
var $grid = $(this);
var data = $grid.data('yiiGridView');
var keys = [];
if (data.selectionColumn) {
$grid.find("input[name='" + data.selectionColumn + "']:checked").each(function () {
keys.push($(this).parent().closest('tr').data('key'));
});
}
return keys;
},
destroy: function () {
return this.each(function () {
$(window).unbind('.yiiGridView');
$(this).removeData('yiiGridView');
});
},
data: function() {
return this.data('yiiGridView');
}
};
})(window.jQuery);
......@@ -77,7 +77,7 @@ class Action extends Component
throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
}
$args = $this->controller->bindActionParams($this, $params);
Yii::info('Running action: ' . get_class($this) . '::run()', __METHOD__);
Yii::trace('Running action: ' . get_class($this) . '::run()', __METHOD__);
if (Yii::$app->requestedParams === null) {
Yii::$app->requestedParams = $args;
}
......
......@@ -169,7 +169,7 @@ abstract class Application extends Module
public function registerErrorHandlers()
{
if (YII_ENABLE_ERROR_HANDLER) {
ini_set('display_errors', 0);
//ini_set('display_errors', 0);
set_exception_handler(array($this, 'handleException'));
set_error_handler(array($this, 'handleError'), error_reporting());
if ($this->memoryReserveSize > 0) {
......
......@@ -281,7 +281,7 @@ class Controller extends Component
* - an absolute path (e.g. "/main"): the layout name starts with a slash. The actual layout file will be
* looked for under the [[Application::layoutPath|layout path]] of the application;
* - a relative path (e.g. "main"): the actual layout layout file will be looked for under the
* [[Module::viewPath|view path]] of the context module.
* [[Module::layoutPath|layout path]] of the context module.
*
* If the layout name does not contain a file extension, it will use the default one `.php`.
*
......
......@@ -46,7 +46,7 @@ class InlineAction extends Action
public function runWithParams($params)
{
$args = $this->controller->bindActionParams($this, $params);
Yii::info('Running action: ' . get_class($this->controller) . '::' . $this->actionMethod . '()', __METHOD__);
Yii::trace('Running action: ' . get_class($this->controller) . '::' . $this->actionMethod . '()', __METHOD__);
if (Yii::$app->requestedParams === null) {
Yii::$app->requestedParams = $args;
}
......
......@@ -8,8 +8,11 @@
namespace yii\base;
use Yii;
use ArrayAccess;
use ArrayObject;
use ArrayIterator;
use ReflectionClass;
use IteratorAggregate;
use yii\helpers\Inflector;
use yii\validators\RequiredValidator;
use yii\validators\Validator;
......@@ -42,7 +45,7 @@ use yii\validators\Validator;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Model extends Component implements \IteratorAggregate, \ArrayAccess
class Model extends Component implements IteratorAggregate, ArrayAccess
{
/**
* @event ModelEvent an event raised at the beginning of [[validate()]]. You may set
......@@ -184,7 +187,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
*/
public function formName()
{
$reflector = new \ReflectionClass($this);
$reflector = new ReflectionClass($this);
return $reflector->getShortName();
}
......@@ -196,7 +199,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
*/
public function attributes()
{
$class = new \ReflectionClass($this);
$class = new ReflectionClass($this);
$names = array();
foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
$name = $property->getName();
......@@ -568,7 +571,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
public function onUnsafeAttribute($name, $value)
{
if (YII_DEBUG) {
\Yii::info("Failed to set unsafe attribute '$name' in '" . get_class($this) . "'.", __METHOD__);
Yii::trace("Failed to set unsafe attribute '$name' in '" . get_class($this) . "'.", __METHOD__);
}
}
......@@ -608,9 +611,6 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
return array();
}
$attributes = array();
if (isset($scenarios[$scenario]['attributes']) && is_array($scenarios[$scenario]['attributes'])) {
$scenarios[$scenario] = $scenarios[$scenario]['attributes'];
}
foreach ($scenarios[$scenario] as $attribute) {
if ($attribute[0] !== '!') {
$attributes[] = $attribute;
......@@ -630,11 +630,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
if (!isset($scenarios[$scenario])) {
return array();
}
if (isset($scenarios[$scenario]['attributes']) && is_array($scenarios[$scenario]['attributes'])) {
$attributes = $scenarios[$scenario]['attributes'];
} else {
$attributes = $scenarios[$scenario];
}
$attributes = $scenarios[$scenario];
foreach ($attributes as $i => $attribute) {
if ($attribute[0] === '!') {
$attributes[$i] = substr($attribute, 1);
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* UnknownClassException represents an exception caused by accessing an unknown class.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class UnknownClassException extends Exception
{
/**
* @return string the user-friendly name of this exception
*/
public function getName()
{
return \Yii::t('yii', 'Unknown Class');
}
}
......@@ -269,7 +269,7 @@ class View extends Component
$renderer = $this->renderers[$ext];
$output = $renderer->render($this, $viewFile, $params);
} else {
Yii::info("Rendering view file: $viewFile", __METHOD__);
Yii::trace("Rendering view file: $viewFile", __METHOD__);
$output = $this->renderPhpFile($viewFile, $params);
}
$this->afterRender($viewFile, $output);
......@@ -577,7 +577,7 @@ class View extends Component
$bundle = $am->getBundle($name);
$this->assetBundles[$name] = false;
$bundle->registerAssets($this);
$this->assetBundles[$name] = true;
$this->assetBundles[$name] = $bundle;
} elseif ($this->assetBundles[$name] === false) {
throw new InvalidConfigException("A circular dependency is detected for bundle '$name'.");
}
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class AffixAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-affix.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class AlertAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-alert.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
......@@ -6,6 +6,7 @@
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
......@@ -17,5 +18,6 @@ class BootstrapAsset extends AssetBundle
public $sourcePath = '@yii/bootstrap/assets';
public $css = array(
'css/bootstrap.css',
'css/bootstrap-glyphicons.css',
);
}
......@@ -6,20 +6,22 @@
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class TransitionAsset extends AssetBundle
class BootstrapPluginAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-transition.js',
'js/bootstrap.js',
);
public $depends = array(
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
'yii\bootstrap\BootstrapAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ButtonAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-button.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
......@@ -46,7 +46,7 @@ class ButtonDropdown extends Widget
/**
* @var array the HTML attributes of the button.
*/
public $buttonOptions = array();
public $options = array();
/**
* @var array the configuration array for [[Dropdown]].
*/
......@@ -58,24 +58,11 @@ class ButtonDropdown extends Widget
/**
* Initializes the widget.
* If you override this method, make sure you call the parent implementation first.
*/
public function init()
{
parent::init();
Html::addCssClass($this->options, 'btn-group');
}
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderButton() . "\n";
echo $this->renderDropdown() . "\n";
echo Html::endTag('div') . "\n";
echo $this->renderButton() . "\n" . $this->renderDropdown();
$this->registerPlugin('button');
}
......@@ -85,21 +72,21 @@ class ButtonDropdown extends Widget
*/
protected function renderButton()
{
Html::addCssClass($this->buttonOptions, 'btn');
Html::addCssClass($this->options, 'btn');
if ($this->split) {
$tag = 'button';
$options = $this->buttonOptions;
$this->buttonOptions['data-toggle'] = 'dropdown';
Html::addCssClass($this->buttonOptions, 'dropdown-toggle');
$options = $this->options;
$this->options['data-toggle'] = 'dropdown';
Html::addCssClass($this->options, 'dropdown-toggle');
$splitButton = Button::widget(array(
'label' => '<span class="caret"></span>',
'encodeLabel' => false,
'options' => $this->buttonOptions,
'options' => $this->options,
));
} else {
$tag = 'a';
$this->label .= ' <span class="caret"></span>';
$options = $this->buttonOptions;
$options = $this->options;
if (!isset($options['href'])) {
$options['href'] = '#';
}
......
......@@ -18,7 +18,7 @@ use yii\helpers\Html;
* ```php
* // a button group with items configuration
* echo ButtonGroup::::widget(array(
* 'items' => array(
* 'buttons' => array(
* array('label' => 'A'),
* array('label' => 'B'),
* )
......@@ -26,7 +26,7 @@ use yii\helpers\Html;
*
* // button group with an item as a string
* echo ButtonGroup::::widget(array(
* 'items' => array(
* 'buttons' => array(
* Button::widget(array('label' => 'A')),
* array('label' => 'B'),
* )
......@@ -60,7 +60,6 @@ class ButtonGroup extends Widget
public function init()
{
parent::init();
$this->clientOptions = false;
Html::addCssClass($this->options, 'btn-group');
}
......@@ -70,7 +69,7 @@ class ButtonGroup extends Widget
public function run()
{
echo Html::tag('div', $this->renderButtons(), $this->options);
$this->registerPlugin('button');
BootstrapAsset::register($this->getView());
}
/**
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class CarouselAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-carousel.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class CollapseAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-collapse.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class DropdownAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-dropdown.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
......@@ -88,6 +88,8 @@ class Modal extends Widget
echo $this->renderToggleButton() . "\n";
echo Html::beginTag('div', $this->options) . "\n";
echo Html::beginTag('div', array('class' => 'modal-dialog')) . "\n";
echo Html::beginTag('div', array('class' => 'modal-content')) . "\n";
echo $this->renderHeader() . "\n";
echo $this->renderBodyBegin() . "\n";
}
......@@ -99,6 +101,8 @@ class Modal extends Widget
{
echo "\n" . $this->renderBodyEnd();
echo "\n" . $this->renderFooter();
echo "\n" . Html::endTag('div'); // modal-content
echo "\n" . Html::endTag('div'); // modal-dialog
echo "\n" . Html::endTag('div');
$this->registerPlugin('modal');
......@@ -195,7 +199,7 @@ class Modal extends Widget
protected function initOptions()
{
$this->options = array_merge(array(
'class' => 'modal hide',
'class' => 'modal fade',
), $this->options);
Html::addCssClass($this->options, 'modal');
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ModalAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-modal.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
......@@ -7,6 +7,7 @@
namespace yii\bootstrap;
use Yii;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
......@@ -21,9 +22,8 @@ use yii\helpers\Html;
* 'items' => array(
* array(
* 'label' => 'Home',
* 'url' => '/',
* 'url' => array('site/index'),
* 'linkOptions' => array(...),
* 'active' => true,
* ),
* array(
* 'label' => 'Dropdown',
......@@ -63,7 +63,7 @@ class Nav extends Widget
* - linkOptions: array, optional, the HTML attributes of the item's link.
* - options: array, optional, the HTML attributes of the item container (LI).
* - active: boolean, optional, whether the item should be on active state or not.
* - dropdown: array|string, optional, the configuration array for creating a [[Dropdown]] widget,
* - items: array|string, optional, the configuration array for creating a [[Dropdown]] widget,
* or a string representing the dropdown menu. Note that Bootstrap does not support sub-dropdown menus.
*/
public $items = array();
......@@ -71,6 +71,26 @@ class Nav extends Widget
* @var boolean whether the nav items labels should be HTML-encoded.
*/
public $encodeLabels = true;
/**
* @var boolean whether to automatically activate items according to whether their route setting
* matches the currently requested route.
* @see isItemActive
*/
public $activateItems = true;
/**
* @var string the route used to determine if a menu item is active or not.
* If not set, it will use the route of the current request.
* @see params
* @see isItemActive
*/
public $route;
/**
* @var array the parameters used to determine if a menu item is active or not.
* If not set, it will use `$_GET`.
* @see route
* @see isItemActive
*/
public $params;
/**
......@@ -79,6 +99,12 @@ class Nav extends Widget
public function init()
{
parent::init();
if ($this->route === null && Yii::$app->controller !== null) {
$this->route = Yii::$app->controller->getRoute();
}
if ($this->params === null) {
$this->params = $_GET;
}
Html::addCssClass($this->options, 'nav');
}
......@@ -124,7 +150,13 @@ class Nav extends Widget
$url = Html::url(ArrayHelper::getValue($item, 'url', '#'));
$linkOptions = ArrayHelper::getValue($item, 'linkOptions', array());
if (ArrayHelper::getValue($item, 'active')) {
if (isset($item['active'])) {
$active = ArrayHelper::remove($item, 'active', false);
} else {
$active = $this->isItemActive($item);
}
if ($active) {
Html::addCssClass($options, 'active');
}
......@@ -144,4 +176,38 @@ class Nav extends Widget
return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options);
}
/**
* Checks whether a menu item is active.
* This is done by checking if [[route]] and [[params]] match that specified in the `url` option of the menu item.
* When the `url` option of a menu item is specified in terms of an array, its first element is treated
* as the route for the item and the rest of the elements are the associated parameters.
* Only when its route and parameters match [[route]] and [[params]], respectively, will a menu item
* be considered active.
* @param array $item the menu item to be checked
* @return boolean whether the menu item is active
*/
protected function isItemActive($item)
{
if (isset($item['url']) && is_array($item['url']) && isset($item['url'][0])) {
$route = $item['url'][0];
if ($route[0] !== '/' && Yii::$app->controller) {
$route = Yii::$app->controller->module->getUniqueId() . '/' . $route;
}
if (ltrim($route, '/') !== $this->route) {
return false;
}
unset($item['url']['#']);
if (count($item['url']) > 1) {
foreach (array_splice($item['url'], 1) as $name => $value) {
if (!isset($this->params[$name]) || $this->params[$name] != $value) {
return false;
}
}
}
return true;
}
return false;
}
}
......@@ -7,55 +7,27 @@
namespace yii\bootstrap;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
/**
* NavBar renders a navbar HTML component.
*
* For example:
* Any content enclosed between the [[begin()]] and [[end()]] calls of NavBar
* is treated as the content of the navbar. You may use widgets such as [[Nav]]
* or [[\yii\widgets\Menu]] to build up such content. For example,
*
* ```php
* echo NavBar::widget(array(
* 'brandLabel' => 'NavBar Test',
* use yii\bootstrap\NavBar;
* use yii\widgets\Menu;
*
* NavBar::begin(array('brandLabel' => 'NavBar Test'));
* echo Nav::widget(array(
* 'items' => array(
* // a Nav widget
* array(
* // defaults to Nav anyway.
* 'class' => 'yii\bootstrap\Nav',
* // widget configuration
* 'options' => array(
* 'items' => array(
* array(
* 'label' => 'Home',
* 'url' => '/',
* 'options' => array('class' => 'active'),
* ),
* array(
* 'label' => 'Dropdown',
* 'content' => new Dropdown(array(
* 'items' => array(
* array(
* 'label' => 'DropdownA',
* 'url' => '#',
* ),
* array(
* 'label' => 'DropdownB',
* 'url' => '#'
* ),
* )
* ),
* ),
* )
* ),
* ),
* // you can also use strings
* '<form class="navbar-search pull-left" action="">' .
* '<input type="text" class="search-query" placeholder="Search">' .
* '</form>',
* array('label' => 'Home', 'url' => array('/site/index')),
* array('label' => 'About', 'url' => array('/site/about')),
* ),
* ));
* NavBar::end();
* ```
*
* @see http://twitter.github.io/bootstrap/components.html#navbar
......@@ -65,7 +37,11 @@ use yii\helpers\Html;
class NavBar extends Widget
{
/**
* @var string the text of the brand.
* @var boolean whether to enable a collapsing responsive navbar.
*/
public $responsive = true;
/**
* @var string the text of the brand. Note that this is not HTML-encoded.
* @see http://twitter.github.io/bootstrap/components.html#navbar
*/
public $brandLabel;
......@@ -78,26 +54,6 @@ class NavBar extends Widget
* @var array the HTML attributes of the brand link.
*/
public $brandOptions = array();
/**
* @var array list of menu items in the navbar widget. Each array element represents a single
* menu item with the following structure:
*
* ```php
* array(
* // optional, the menu item class type of the widget to render. Defaults to "Nav" widget.
* 'class' => 'Menu item class type',
* // required, the configuration options of the widget.
* 'options' => array(...),
* ),
* // optionally, you can pass a string
* '<form class="navbar-search pull-left" action="">' .
* '<input type="text" class="search-query span2" placeholder="Search">' .
* '</form>',
* ```
*
* Optionally, you can also use a plain string instead of an array element.
*/
public $items = array();
/**
......@@ -108,69 +64,30 @@ class NavBar extends Widget
parent::init();
$this->clientOptions = false;
Html::addCssClass($this->options, 'navbar');
Html::addCssClass($this->brandOptions, 'brand');
}
Html::addCssClass($this->brandOptions, 'navbar-brand');
/**
* Renders the widget.
*/
public function run()
{
echo Html::beginTag('div', $this->options);
echo $this->renderItems();
echo Html::endTag('div');
if (self::$responsive) {
ResponsiveAsset::register($this->getView());
} else {
BootstrapAsset::register($this->getView());
}
}
/**
* Renders the items.
* @return string the rendering items.
*/
protected function renderItems()
{
$items = array();
foreach ($this->items as $item) {
$items[] = $this->renderItem($item);
if ($this->responsive) {
echo Html::beginTag('div', array('class' => 'container'));
echo $this->renderToggleButton();
echo Html::beginTag('div', array('class' => 'nav-collapse collapse navbar-responsive-collapse'));
}
$contents = implode("\n", $items);
$brand = Html::a($this->brandLabel, $this->brandUrl, $this->brandOptions);
if (self::$responsive) {
CollapseAsset::register($this->getView());
$contents = Html::tag('div',
$this->renderToggleButton() .
$brand . "\n" .
Html::tag('div', $contents, array('class' => 'nav-collapse collapse navbar-collapse')),
array('class' => 'container'));
} else {
$contents = $brand . "\n" . $contents;
if ($this->brandLabel !== null) {
echo Html::a($this->brandLabel, $this->brandUrl, $this->brandOptions);
}
return Html::tag('div', $contents, array('class' => 'navbar-inner'));
}
/**
* Renders a item. The item can be a string, a custom class or a Nav widget (defaults if no class specified.
* @param mixed $item the item to render. If array, it is assumed the configuration of a widget being `class`
* required and if not specified, then defaults to `yii\bootstrap\Nav`.
* @return string the rendering result.
* @throws InvalidConfigException
* Renders the widget.
*/
protected function renderItem($item)
public function run()
{
if (is_string($item)) {
return $item;
if ($this->responsive) {
echo Html::endTag('div');
echo Html::endTag('div');
}
$config = ArrayHelper::getValue($item, 'options', array());
$config['clientOptions'] = false;
$class = ArrayHelper::getValue($item, 'class', 'yii\bootstrap\Nav');
return $class::widget($config);
echo Html::endTag('div');
BootstrapPluginAsset::register($this->getView());
}
/**
......@@ -179,14 +96,11 @@ class NavBar extends Widget
*/
protected function renderToggleButton()
{
$items = array();
for ($i = 0; $i < 3; $i++) {
$items[] = Html::tag('span', '', array('class' => 'icon-bar'));
}
return Html::a(implode("\n", $items), null, array(
'class' => 'btn btn-navbar',
$bar = Html::tag('span', '', array('class' => 'icon-bar'));
return Html::button("{$bar}\n{$bar}\n{$bar}", array(
'class' => 'navbar-toggle',
'data-toggle' => 'collapse',
'data-target' => 'div.navbar-collapse',
'data-target' => '.navbar-responsive-collapse',
));
}
}
......@@ -105,11 +105,7 @@ class Progress extends Widget
echo Html::beginTag('div', $this->options) . "\n";
echo $this->renderProgress() . "\n";
echo Html::endTag('div') . "\n";
if (self::$responsive) {
ResponsiveAsset::register($this->getView());
} else {
BootstrapAsset::register($this->getView());
}
BootstrapAsset::register($this->getView());
}
/**
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ResponsiveAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $css = array(
'css/bootstrap-responsive.css',
);
public $depends = array(
'yii\bootstrap\BootstrapAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ScrollspyAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-scrollspy.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class TabAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-tab.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class TooltipAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-tooltip.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\bootstrap;
use yii\web\AssetBundle;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class TypeaheadAsset extends AssetBundle
{
public $sourcePath = '@yii/bootstrap/assets';
public $js = array(
'js/bootstrap-typeahead.js',
);
public $depends = array(
'yii\bootstrap\TransitionAsset',
'yii\bootstrap\BootstrapAsset',
'yii\web\JqueryAsset',
);
}
......@@ -21,10 +21,6 @@ use yii\helpers\Json;
class Widget extends \yii\base\Widget
{
/**
* @var boolean whether to use the responsive version of Bootstrap.
*/
public static $responsive = true;
/**
* @var array the HTML attributes for the widget container tag.
*/
public $options = array();
......@@ -63,16 +59,11 @@ class Widget extends \yii\base\Widget
*/
protected function registerPlugin($name)
{
$id = $this->options['id'];
$view = $this->getView();
if (self::$responsive) {
ResponsiveAsset::register($view);
} else {
BootstrapAsset::register($view);
}
/** @var \yii\web\AssetBundle $assetClass */
$assetClass = 'yii\bootstrap\\' . ucfirst($name) . 'Asset';
$assetClass::register($view);
BootstrapPluginAsset::register($view);
$id = $this->options['id'];
if ($this->clientOptions !== false) {
$options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions);
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
return array(
yii\bootstrap\BootstrapAsset::className(),
yii\bootstrap\ResponsiveAsset::className(),
yii\bootstrap\DropdownAsset::className(),
yii\bootstrap\TransitionAsset::className(),
yii\bootstrap\AffixAsset::className(),
yii\bootstrap\AlertAsset::className(),
yii\bootstrap\ButtonAsset::className(),
yii\bootstrap\CarouselAsset::className(),
yii\bootstrap\CollapseAsset::className(),
yii\bootstrap\ModalAsset::className(),
yii\bootstrap\PopoverAsset::className(),
yii\bootstrap\TooltipAsset::className(),
yii\bootstrap\ScrollspyAsset::className(),
yii\bootstrap\TabAsset::className(),
yii\bootstrap\TypeaheadAsset::className(),
);
@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphiconshalflings-regular.eot');src:url('../fonts/glyphiconshalflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphiconshalflings-regular.woff') format('woff'),url('../fonts/glyphiconshalflings-regular.ttf') format('truetype'),url('../fonts/glyphiconshalflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon:before{font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-plus:before{content:"\002b"}.glyphicon-minus:before{content:"\2212"}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse:before{content:"\e159"}.glyphicon-collapse-top:before{content:"\e160"}
/* This beautiful CSS-File has been crafted with LESS (lesscss.org) and compiled by simpLESS (wearekiss.com/simpless) */
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/* ==========================================================
* bootstrap-affix.js v2.3.2
* http://twitter.github.com/bootstrap/javascript.html#affix
* ==========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* AFFIX CLASS DEFINITION
* ====================== */
var Affix = function (element, options) {
this.options = $.extend({}, $.fn.affix.defaults, options)
this.$window = $(window)
.on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
.on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
this.$element = $(element)
this.checkPosition()
}
Affix.prototype.checkPosition = function () {
if (!this.$element.is(':visible')) return
var scrollHeight = $(document).height()
, scrollTop = this.$window.scrollTop()
, position = this.$element.offset()
, offset = this.options.offset
, offsetBottom = offset.bottom
, offsetTop = offset.top
, reset = 'affix affix-top affix-bottom'
, affix
if (typeof offset != 'object') offsetBottom = offsetTop = offset
if (typeof offsetTop == 'function') offsetTop = offset.top()
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
'bottom' : offsetTop != null && scrollTop <= offsetTop ?
'top' : false
if (this.affixed === affix) return
this.affixed = affix
this.unpin = affix == 'bottom' ? position.top - scrollTop : null
this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
}
/* AFFIX PLUGIN DEFINITION
* ======================= */
var old = $.fn.affix
$.fn.affix = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('affix')
, options = typeof option == 'object' && option
if (!data) $this.data('affix', (data = new Affix(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.affix.Constructor = Affix
$.fn.affix.defaults = {
offset: 0
}
/* AFFIX NO CONFLICT
* ================= */
$.fn.affix.noConflict = function () {
$.fn.affix = old
return this
}
/* AFFIX DATA-API
* ============== */
$(window).on('load', function () {
$('[data-spy="affix"]').each(function () {
var $spy = $(this)
, data = $spy.data()
data.offset = data.offset || {}
data.offsetBottom && (data.offset.bottom = data.offsetBottom)
data.offsetTop && (data.offset.top = data.offsetTop)
$spy.affix(data)
})
})
}(window.jQuery);
\ No newline at end of file
/* ==========================================================
* bootstrap-alert.js v2.3.2
* http://twitter.github.com/bootstrap/javascript.html#alerts
* ==========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* ALERT CLASS DEFINITION
* ====================== */
var dismiss = '[data-dismiss="alert"]'
, Alert = function (el) {
$(el).on('click', dismiss, this.close)
}
Alert.prototype.close = function (e) {
var $this = $(this)
, selector = $this.attr('data-target')
, $parent
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
$parent = $(selector)
e && e.preventDefault()
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
$parent.trigger(e = $.Event('close'))
if (e.isDefaultPrevented()) return
$parent.removeClass('in')
function removeElement() {
$parent
.trigger('closed')
.remove()
}
$.support.transition && $parent.hasClass('fade') ?
$parent.on($.support.transition.end, removeElement) :
removeElement()
}
/* ALERT PLUGIN DEFINITION
* ======================= */
var old = $.fn.alert
$.fn.alert = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('alert')
if (!data) $this.data('alert', (data = new Alert(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.alert.Constructor = Alert
/* ALERT NO CONFLICT
* ================= */
$.fn.alert.noConflict = function () {
$.fn.alert = old
return this
}
/* ALERT DATA-API
* ============== */
$(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
}(window.jQuery);
\ No newline at end of file
/* ============================================================
* bootstrap-button.js v2.3.2
* http://twitter.github.com/bootstrap/javascript.html#buttons
* ============================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
!function ($) {
"use strict"; // jshint ;_;
/* BUTTON PUBLIC CLASS DEFINITION
* ============================== */
var Button = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, $.fn.button.defaults, options)
}
Button.prototype.setState = function (state) {
var d = 'disabled'
, $el = this.$element
, data = $el.data()
, val = $el.is('input') ? 'val' : 'html'
state = state + 'Text'
data.resetText || $el.data('resetText', $el[val]())
$el[val](data[state] || this.options[state])
// push to event loop to allow forms to submit
setTimeout(function () {
state == 'loadingText' ?
$el.addClass(d).attr(d, d) :
$el.removeClass(d).removeAttr(d)
}, 0)
}
Button.prototype.toggle = function () {
var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
$parent && $parent
.find('.active')
.removeClass('active')
this.$element.toggleClass('active')
}
/* BUTTON PLUGIN DEFINITION
* ======================== */
var old = $.fn.button
$.fn.button = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('button')
, options = typeof option == 'object' && option
if (!data) $this.data('button', (data = new Button(this, options)))
if (option == 'toggle') data.toggle()
else if (option) data.setState(option)
})
}
$.fn.button.defaults = {
loadingText: 'loading...'
}
$.fn.button.Constructor = Button
/* BUTTON NO CONFLICT
* ================== */
$.fn.button.noConflict = function () {
$.fn.button = old
return this
}
/* BUTTON DATA-API
* =============== */
$(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
var $btn = $(e.target)
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
$btn.button('toggle')
})
}(window.jQuery);
\ No newline at end of file
/* ==========================================================
* bootstrap-carousel.js v2.3.2
* http://twitter.github.com/bootstrap/javascript.html#carousel
* ==========================================================
* Copyright 2012 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* CAROUSEL CLASS DEFINITION
* ========================= */
var Carousel = function (element, options) {
this.$element = $(element)
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.options.pause == 'hover' && this.$element
.on('mouseenter', $.proxy(this.pause, this))
.on('mouseleave', $.proxy(this.cycle, this))
}
Carousel.prototype = {
cycle: function (e) {
if (!e) this.paused = false
if (this.interval) clearInterval(this.interval);
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
return this
}
, getActiveIndex: function () {
this.$active = this.$element.find('.item.active')
this.$items = this.$active.parent().children()
return this.$items.index(this.$active)
}
, to: function (pos) {
var activeIndex = this.getActiveIndex()
, that = this
if (pos > (this.$items.length - 1) || pos < 0) return
if (this.sliding) {
return this.$element.one('slid', function () {
that.to(pos)
})
}
if (activeIndex == pos) {
return this.pause().cycle()
}
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
}
, pause: function (e) {
if (!e) this.paused = true
if (this.$element.find('.next, .prev').length && $.support.transition.end) {
this.$element.trigger($.support.transition.end)
this.cycle(true)
}
clearInterval(this.interval)
this.interval = null
return this
}
, next: function () {
if (this.sliding) return
return this.slide('next')
}
, prev: function () {
if (this.sliding) return
return this.slide('prev')
}
, slide: function (type, next) {
var $active = this.$element.find('.item.active')
, $next = next || $active[type]()
, isCycling = this.interval
, direction = type == 'next' ? 'left' : 'right'
, fallback = type == 'next' ? 'first' : 'last'
, that = this
, e
this.sliding = true
isCycling && this.pause()
$next = $next.length ? $next : this.$element.find('.item')[fallback]()
e = $.Event('slide', {
relatedTarget: $next[0]
, direction: direction
})
if ($next.hasClass('active')) return
if (this.$indicators.length) {
this.$indicators.find('.active').removeClass('active')
this.$element.one('slid', function () {
var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
$nextIndicator && $nextIndicator.addClass('active')
})
}
if ($.support.transition && this.$element.hasClass('slide')) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
this.$element.one($.support.transition.end, function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function () { that.$element.trigger('slid') }, 0)
})
} else {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger('slid')
}
isCycling && this.cycle()
return this
}
}
/* CAROUSEL PLUGIN DEFINITION
* ========================== */
var old = $.fn.carousel
$.fn.carousel = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('carousel')
, options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
, action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.pause().cycle()
})
}
$.fn.carousel.defaults = {
interval: 5000
, pause: 'hover'
}
$.fn.carousel.Constructor = Carousel
/* CAROUSEL NO CONFLICT
* ==================== */
$.fn.carousel.noConflict = function () {
$.fn.carousel = old
return this
}
/* CAROUSEL DATA-API
* ================= */
$(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
var $this = $(this), href
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
, options = $.extend({}, $target.data(), $this.data())
, slideIndex
$target.carousel(options)
if (slideIndex = $this.attr('data-slide-to')) {
$target.data('carousel').pause().to(slideIndex).cycle()
}
e.preventDefault()
})
}(window.jQuery);
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment