Commit 147b3155 by Qiang Xue

Added contact page. Fixed various form bugs.

parent 0d182ace
......@@ -15,4 +15,7 @@ return array(
'bundles' => require(__DIR__ . '/assets.php'),
),
),
'params' => array(
'adminEmail' => 'admin@example.com',
),
);
\ No newline at end of file
......@@ -2,6 +2,7 @@
use yii\web\Controller;
use app\models\LoginForm;
use app\models\ContactForm;
class SiteController extends Controller
{
......@@ -14,7 +15,7 @@ class SiteController extends Controller
{
$model = new LoginForm();
if ($this->populate($_POST, $model) && $model->login()) {
Yii::$app->getResponse()->redirect(array('site/index'));
Yii::$app->response->redirect(array('site/index'));
} else {
echo $this->render('login', array(
'model' => $model,
......@@ -30,7 +31,15 @@ class SiteController extends Controller
public function actionContact()
{
echo $this->render('contact');
$model = new ContactForm;
if ($this->populate($_POST, $model) && $model->contact(Yii::$app->params['adminEmail'])) {
Yii::$app->session->setFlash('contact', 'Thank you for contacting us. We will respond to you as soon as possible.');
Yii::$app->response->refresh();
} else {
echo $this->render('contact', array(
'model' => $model,
));
}
}
public function actionAbout()
......
<?php
namespace app\models;
use yii\base\Model;
/**
* ContactForm is the model behind the contact form.
*/
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
public $verifyCode;
/**
* @return array the validation rules.
*/
public function rules()
{
return array(
// name, email, subject and body are required
array('name, email, subject, body', 'required'),
// email has to be a valid email address
array('email', 'email'),
// verifyCode needs to be entered correctly
//array('verifyCode', 'captcha', 'allowEmpty' => !Captcha::checkRequirements()),
);
}
/**
* @return array customized attribute labels
*/
public function attributeLabels()
{
return array(
'verifyCode' => 'Verification Code',
);
}
/**
* Sends an email to the specified email address using the information collected by this model.
* @param string $email the target email address
* @return boolean whether the model passes validation
*/
public function contact($email)
{
if ($this->validate()) {
$name = '=?UTF-8?B?' . base64_encode($this->name) . '?=';
$subject = '=?UTF-8?B?' . base64_encode($this->subject) . '?=';
$headers = "From: $name <{$this->email}>\r\n" .
"Reply-To: {$this->email}\r\n" .
"MIME-Version: 1.0\r\n" .
"Content-type: text/plain; charset=UTF-8";
mail($email, $subject, $this->body, $headers);
return true;
} else {
return false;
}
}
}
\ No newline at end of file
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace app\models;
......@@ -11,8 +6,7 @@ use Yii;
use yii\base\Model;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
* LoginForm is the model behind the login form.
*/
class LoginForm extends Model
{
......@@ -20,16 +14,25 @@ class LoginForm extends Model
public $password;
public $rememberMe = true;
/**
* @return array the validation rules.
*/
public function rules()
{
return array(
array('username', 'required'),
array('password', 'required'),
// username and password are both required
array('username, password', 'required'),
// password is validated by validatePassword()
array('password', 'validatePassword'),
// rememberMe must be a boolean value
array('rememberMe', 'boolean'),
);
}
/**
* Validates the password.
* This method serves as the inline validation for password.
*/
public function validatePassword()
{
$user = User::findByUsername($this->username);
......@@ -38,11 +41,15 @@ class LoginForm extends Model
}
}
/**
* Logs in a user using the provided username and password.
* @return boolean whether the user is logged in successfully
*/
public function login()
{
if ($this->validate()) {
$user = User::findByUsername($this->username);
Yii::$app->getUser()->login($user, $this->rememberMe ? 3600*24*30 : 0);
Yii::$app->user->login($user, $this->rememberMe ? 3600*24*30 : 0);
return true;
} else {
return false;
......
......@@ -41,6 +41,8 @@ $this->registerAssetBundle('app');
<?php echo $content; ?>
<hr>
<div class="footer">
<p>&copy; My Company <?php echo date('Y'); ?></p>
<p>
......
......@@ -6,3 +6,10 @@ use yii\helpers\Html;
$this->title = '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>
......@@ -8,3 +8,20 @@ use yii\helpers\Html;
$this->title = 'Contact';
?>
<h1><?php echo Html::encode($this->title); ?></h1>
<p>Please fill out the following fields:</p>
<?php $form = $this->beginWidget('yii\widgets\ActiveForm', 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)); ?>
<div class="control-group">
<div class="controls">
<?php echo Html::submitButton('Submit', null, null, array('class' => 'btn btn-primary')); ?>
</div>
</div>
<?php $this->endWidget(); ?>
\ No newline at end of file
......@@ -5,11 +5,11 @@
$this->title = 'Welcome';
?>
<div class="jumbotron">
<h1>Marketing stuff!</h1>
<h1>Welcome!</h1>
<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 today</a>
<a class="btn btn-large btn-success" href="http://www.yiiframework.com">Get started with Yii</a>
</div>
<hr>
......@@ -45,5 +45,3 @@ $this->title = 'Welcome';
</div>
</div>
<hr>
......@@ -83,7 +83,7 @@
settings.validationUrl = $form.attr('action');
}
$.each(attributes, function (i) {
attributes[i] = $.extend({}, attributeDefaults, this);
attributes[i] = $.extend({value: getValue($form, this)}, attributeDefaults, this);
});
$form.data('yiiActiveForm', {
settings: settings,
......@@ -121,7 +121,7 @@
},
submitForm: function () {
var $form = this,
var $form = $(this),
data = $form.data('yiiActiveForm');
if (data.validated) {
// continue submitting the form since validation passes
......@@ -163,7 +163,7 @@
},
resetForm: function () {
var $form = this;
var $form = $(this);
var data = $form.data('yiiActiveForm');
// Because we bind directly to a form reset event instead of a reset button (that may not exist),
// when this function is executed form input values have not been reset yet.
......
......@@ -95,9 +95,9 @@ class Html
public static $attributeOrder = array(
'type',
'id',
'class',
'name',
'value',
'class',
'href',
'src',
......
......@@ -8,7 +8,6 @@
namespace yii\web;
use Yii;
use yii\helpers\Html;
/**
* Controller is the base class of Web controllers.
......
......@@ -115,6 +115,7 @@ class Response extends \yii\base\Response
* <li>forceDownload: specifies whether the file will be downloaded or shown inline, defaults to true</li>
* <li>addHeaders: an array of additional http headers in header-value pairs</li>
* </ul>
* @todo
*/
public function xSendFile($filePath, $options = array())
{
......@@ -196,6 +197,19 @@ class Response extends \yii\base\Response
}
/**
* Refreshes the current page.
* The effect of this method call is the same as the user pressing the refresh button of his browser
* (without re-posting data).
* @param boolean $terminate whether to terminate the current application after calling this method
* @param string $anchor the anchor that should be appended to the redirection URL.
* Defaults to empty. Make sure the anchor starts with '#' if you want to specify it.
*/
public function refresh($terminate = true, $anchor = '')
{
$this->redirect(Yii::$app->getRequest()->getUrl() . $anchor, $terminate);
}
/**
* Returns the cookie collection.
* Through the returned cookie collection, you add or remove cookies as follows,
*
......
......@@ -48,13 +48,18 @@ class ActiveField extends Component
*/
public $template = "{label}\n<div class=\"controls\">\n{input}\n{error}\n</div>";
/**
* @var array the default options for the error message. This property is used when calling [[error()]]
* without the `$options` parameter.
* @var array the default options for the input tags. The parameter passed to individual input methods
* (e.g. [[textInput()]]) will be merged with this property when rendering the input tag.
*/
public $inputOptions = array();
/**
* @var array the default options for the error tags. The parameter passed to [[error()]] will be
* merged with this property when rendering the error tag.
*/
public $errorOptions = array('tag' => 'span', 'class' => 'help-inline');
/**
* @var array the default options for the label. This property is used when calling [[label()]]
* without the `$options` parameter.
* @var array the default options for the label tags. The parameter passed to [[label()]] will be
* merged with this property when rendering the label tag.
*/
public $labelOptions = array('class' => 'control-label');
/**
......@@ -174,7 +179,7 @@ class ActiveField extends Component
/**
* Generates a label tag for [[attribute]].
* The label text is the label associated with the attribute, obtained via [[Model::getAttributeLabel()]].
* @param array $options the tag options in terms of name-value pairs. If this is null, [[labelOptions]] will be used.
* @param array $options the tag options in terms of name-value pairs. It will be merged with [[labelOptions]].
* The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded
* using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
*
......@@ -186,18 +191,16 @@ class ActiveField extends Component
*
* @return string the generated label tag
*/
public function label($options = null)
public function label($options = array())
{
if ($options === null) {
$options = $this->labelOptions;
}
$options = array_merge($this->labelOptions, $options);
return Html::activeLabel($this->model, $this->attribute, $options);
}
/**
* Generates a tag that contains the first validation error of [[attribute]].
* Note that even if there is no validation error, this method will still return an empty error tag.
* @param array $options the tag options in terms of name-value pairs. If this is null, [[errorOptions]] will be used.
* @param array $options the tag options in terms of name-value pairs. It will be merged with [[errorOptions]].
* The options will be rendered as the attributes of the resulting tag. The values will be HTML-encoded
* using [[encode()]]. If a value is null, the corresponding attribute will not be rendered.
*
......@@ -207,11 +210,9 @@ class ActiveField extends Component
*
* @return string the generated label tag
*/
public function error($options = null)
public function error($options = array())
{
if ($options === null) {
$options = $this->errorOptions;
}
$options = array_merge($this->errorOptions, $options);
$attribute = Html::getAttributeName($this->attribute);
$error = $this->model->getFirstError($attribute);
$tag = isset($options['tag']) ? $options['tag'] : 'span';
......@@ -244,6 +245,7 @@ class ActiveField extends Component
*/
public function input($type, $options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activeInput($type, $this->model, $this->attribute, $options));
}
......@@ -257,6 +259,7 @@ class ActiveField extends Component
*/
public function textInput($options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activeTextInput($this->model, $this->attribute, $options));
}
......@@ -270,6 +273,7 @@ class ActiveField extends Component
*/
public function hiddenInput($options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activeHiddenInput($this->model, $this->attribute, $options));
}
......@@ -283,6 +287,7 @@ class ActiveField extends Component
*/
public function passwordInput($options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activePasswordInput($this->model, $this->attribute, $options));
}
......@@ -296,6 +301,7 @@ class ActiveField extends Component
*/
public function fileInput($options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activeFileInput($this->model, $this->attribute, $options));
}
......@@ -308,6 +314,7 @@ class ActiveField extends Component
*/
public function textarea($options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activeTextarea($this->model, $this->attribute, $options));
}
......@@ -331,6 +338,7 @@ class ActiveField extends Component
*/
public function radio($options = array(), $enclosedByLabel = true)
{
$options = array_merge($this->inputOptions, $options);
if ($enclosedByLabel) {
$hidden = '';
$radio = Html::activeRadio($this->model, $this->attribute, $options);
......@@ -369,6 +377,7 @@ class ActiveField extends Component
*/
public function checkbox($options = array(), $enclosedByLabel = true)
{
$options = array_merge($this->inputOptions, $options);
if ($enclosedByLabel) {
$hidden = '';
$checkbox = Html::activeCheckbox($this->model, $this->attribute, $options);
......@@ -421,6 +430,7 @@ class ActiveField extends Component
*/
public function dropDownList($items, $options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activeDropDownList($this->model, $this->attribute, $items, $options));
}
......@@ -461,6 +471,7 @@ class ActiveField extends Component
*/
public function listBox($items, $options = array())
{
$options = array_merge($this->inputOptions, $options);
return $this->render(Html::activeListBox($this->model, $this->attribute, $items, $options));
}
......
......@@ -40,9 +40,7 @@ class ActiveForm extends Widget
/**
* @var array the default configuration used by [[field()]] when creating a new field object.
*/
public $fieldConfig = array(
'class' => 'yii\widgets\ActiveField',
);
public $fieldConfig;
/**
* @var string the default CSS class for the error summary container.
* @see errorSummary()
......@@ -121,6 +119,9 @@ class ActiveForm extends Widget
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
if (!isset($this->fieldConfig['class'])) {
$this->fieldConfig['class'] = 'yii\widgets\ActiveField';
}
echo Html::beginForm($this->action, $this->method, $this->options);
}
......
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