使用 yii2 中的模型重定向到之前的地址 "from which form data was submitted"
redirect to previous address "from which form data was submitted" with model in yii2
我创建了一个小部件来呈现 layouts/main.php
页脚部分中的表单。
这是一个名为 common\widget\SubscriberFormWidget.php
的小部件文件
<?php
namespace common\widgets;
use Yii;
use yii\base\Widget;
use common\models\Subscriber;
class SubscriberFormWidget extends Widget
{
/**
*@return string
*/
public function run()
{
$model = new Subscriber();
return $this->render('_form', [
'model' => $model
]);
}
}
这是 _form
位于 common\widget\views\_form.php
的小部件中使用的文件
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model common\models\Subscriber */
/* @var $form yii\widgets\ActiveForm */
?>
<?php $form = ActiveForm::begin(['action' => ['subscriber/subscribe']]); ?>
<div class="row">
<div class="col-md-6">
<?= $form->field($model, 'email')->textInput(['maxlength' => true, 'placeholder' => 'Enter @ Email to subscribe!'])->label(false) ?>
</div>
<div class="col-md-6">
<?= Html::submitButton('Subscribe', ['class' => 'btn btn-success']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
这是控制器文件frontend\controllers\SubscriberController.php
<?php
namespace frontend\controllers;
use Yii;
use common\models\Subscriber;
use common\models\SubscriberSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* SubscriberController implements the CRUD actions for Subscriber model.
*/
class SubscriberController extends Controller
{
/**
* Creates a new Subscriber model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionSubscribe()
{
$model = new Subscriber();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail()) {
Yii::$app->session->setFlash('success', 'You have successfully subscribed My-Blog. You will get notification whenever New post is published');
return $this->redirect(Yii::$app->request->referrer);
} else {
Yii::$app->session->setFlash('error', 'Sorry, we are unable to subscribe for the provided email address.');
}
}
return $this->redirect([Yii::$app->request->referrer, ['model' => $model]]);
}
/**
* Creates a new Subscriber model.
* If unsubscribe is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
}
我在页脚部分layouts\main.php
中使用了小部件
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-md-3">
<p class="pull-left">© <?= Html::encode(Yii::$app->name) ?> <?= date('Y') ?></p>
</div>
<div class="col-md-6 text-justify" style="border-left : 2px solid black; border-right: 2px solid black">
<?= SubscriberFormWidget::widget(); ?>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into elec
</p>
</div>
<div class="col-md-3">
<p class="pull-right"><?= Yii::powered() ?></p>
</div>
</div>
</div>
</footer>
这是用于控制器的型号common\models\Subscriber.php
<?php
namespace common\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;
/**
* This is the model class for table "subscriber".
*
* @property int $id
* @property string $email
* @property string $token
* @property int $status
* @property int $created_at
* @property int $updated_at
*/
class Subscriber extends \yii\db\ActiveRecord
{
const STATUS_DEACTIVE = 0;
const STATUS_ACTIVE = 1;
/**
* @inheritdoc
*/
public static function tableName()
{
return 'subscriber';
}
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
'value' => new Expression('NOW()'),
],
];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['email'], 'required'],
[['status', 'created_at', 'updated_at'], 'safe'],
[['email'], 'string', 'max' => 60],
[['token'], 'string', 'max' => 255],
[['token'], 'unique'],
[['email'], 'unique', 'targetClass' => '\common\models\Subscriber', 'message' => 'This email has already subscribed our blog.','filter' => ['!=','status' ,0]],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'email' => 'Email',
'token' => 'Token',
'status' => 'Status',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
/**
* Generates subscriber token
*/
public function generateSubscriberToken()
{
return $this->token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Send Email when successfully subscribe
*/
public function sendEmail()
{
$subscribers = self::find()->where(['email' => $this->email])->one();
//set flag for sending email
$sendMail = false;
//email subject
$subject = '';
//generate token
$token = $this->generateSubscriberToken();
//if email found in subscribers
if ($subscribers !== null) {
//check if inactive
if ($subscribers->status !== self::STATUS_ACTIVE) {
//assign token
$subscribers->token = $token;
//set status to active
$subscribers->status = self::STATUS_ACTIVE;
print_r($subscribers->errors);
//update the recrod
if (!$subscribers->save()) {
return false;
}
//set subject
$subject = 'Welcome back ' . $this->email . 'Thank you for subscribing ' . Yii::$app->name . '<br /><br /> You will receive notification whenever new trick or post is published to website';
$sendMail = true;
}
} else { //if email does not exist only then insert a new record
$this->status = 1;
if (!$this->save()) {
return false;
}
$subject = 'Thank you ' . $this->email . ' for subscribing ' . Yii::$app->name . '<br /><br /> You will receive notification whenever new trick or post is published to website';
$sendMail = true;
}
//check if send mail flag set
if ($sendMail) {
return Yii::$app->mailer
->compose()
->setFrom(['noreply@my-blog.com' => Yii::$app->name . ' robot'])
->setTo('piyush@localhost')
->setSubject('Subscription : ' . Yii::$app->name)
->setHtmlBody($subject)
->send();
}
}
}
现在我希望表单与验证一起使用。如果用户输入任何错误的输入,例如已经注册的输入,则此消息应该 return 以查看提交表单数据的文件。
Controlelr::redirect() 接受一个 url
和一个可选的 status code
参数。
你在你提出的片段中没有正确调用它。
我相信您正在尝试仅使用 url 参数(单个数组参数)并跳过状态代码。
您也不能依靠引荐来源网址将您带回上一页。您需要将到return的路由保存到表单page
Url::remember([Yii::$app->requestedRoute]);
然后用它来 return 回到表格
return $this->redirect([Url::previous(), ['model' => $model]]);
您可以设置 Yii::$app->user->returnUrl
,然后使用 $this->goBack()
导航回之前的页面。
一个好的方法是在控制器 SubscribeController
中添加 beforeAction
函数,如下所示。
public function beforeAction($action)
{
if (parent::beforeAction($action)) {
if($action->id=='subscribe'){
Yii::$app->user->returnUrl = Yii::$app->request->referrer;
}
}
return true;
}
并替换行
return $this->redirect([Yii::$app->request->referrer, ['model' => $model]]);
与以下
return $this->goBack();
现在,无论您从哪个页面提交页脚表单,它都会导航回该页面。
另一件事我注意到你没有检查表单中的 sessionFlash
error
变量,你需要得到像
这样的错误消息
if(Yii::$app->session->hasFlash('error')){
echo '<div class="alert alert-danger">
<strong>Danger!</strong>'. Yii::$app->session->getFlash('error').'
</div>';
}
我的 previous answer
中提供了显示 sessionFlash
消息的更好方法,您可以按照该方法避免在任何地方手动添加代码,它会在设置后自动向您显示会话消息。
希望对你有所帮助
我创建了一个小部件来呈现 layouts/main.php
页脚部分中的表单。
这是一个名为 common\widget\SubscriberFormWidget.php
<?php
namespace common\widgets;
use Yii;
use yii\base\Widget;
use common\models\Subscriber;
class SubscriberFormWidget extends Widget
{
/**
*@return string
*/
public function run()
{
$model = new Subscriber();
return $this->render('_form', [
'model' => $model
]);
}
}
这是 _form
位于 common\widget\views\_form.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
/* @var $model common\models\Subscriber */
/* @var $form yii\widgets\ActiveForm */
?>
<?php $form = ActiveForm::begin(['action' => ['subscriber/subscribe']]); ?>
<div class="row">
<div class="col-md-6">
<?= $form->field($model, 'email')->textInput(['maxlength' => true, 'placeholder' => 'Enter @ Email to subscribe!'])->label(false) ?>
</div>
<div class="col-md-6">
<?= Html::submitButton('Subscribe', ['class' => 'btn btn-success']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
这是控制器文件frontend\controllers\SubscriberController.php
<?php
namespace frontend\controllers;
use Yii;
use common\models\Subscriber;
use common\models\SubscriberSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* SubscriberController implements the CRUD actions for Subscriber model.
*/
class SubscriberController extends Controller
{
/**
* Creates a new Subscriber model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionSubscribe()
{
$model = new Subscriber();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail()) {
Yii::$app->session->setFlash('success', 'You have successfully subscribed My-Blog. You will get notification whenever New post is published');
return $this->redirect(Yii::$app->request->referrer);
} else {
Yii::$app->session->setFlash('error', 'Sorry, we are unable to subscribe for the provided email address.');
}
}
return $this->redirect([Yii::$app->request->referrer, ['model' => $model]]);
}
/**
* Creates a new Subscriber model.
* If unsubscribe is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
}
我在页脚部分layouts\main.php
中使用了小部件
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-md-3">
<p class="pull-left">© <?= Html::encode(Yii::$app->name) ?> <?= date('Y') ?></p>
</div>
<div class="col-md-6 text-justify" style="border-left : 2px solid black; border-right: 2px solid black">
<?= SubscriberFormWidget::widget(); ?>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into elec
</p>
</div>
<div class="col-md-3">
<p class="pull-right"><?= Yii::powered() ?></p>
</div>
</div>
</div>
</footer>
这是用于控制器的型号common\models\Subscriber.php
<?php
namespace common\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;
/**
* This is the model class for table "subscriber".
*
* @property int $id
* @property string $email
* @property string $token
* @property int $status
* @property int $created_at
* @property int $updated_at
*/
class Subscriber extends \yii\db\ActiveRecord
{
const STATUS_DEACTIVE = 0;
const STATUS_ACTIVE = 1;
/**
* @inheritdoc
*/
public static function tableName()
{
return 'subscriber';
}
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
'value' => new Expression('NOW()'),
],
];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['email'], 'required'],
[['status', 'created_at', 'updated_at'], 'safe'],
[['email'], 'string', 'max' => 60],
[['token'], 'string', 'max' => 255],
[['token'], 'unique'],
[['email'], 'unique', 'targetClass' => '\common\models\Subscriber', 'message' => 'This email has already subscribed our blog.','filter' => ['!=','status' ,0]],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'email' => 'Email',
'token' => 'Token',
'status' => 'Status',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
/**
* Generates subscriber token
*/
public function generateSubscriberToken()
{
return $this->token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Send Email when successfully subscribe
*/
public function sendEmail()
{
$subscribers = self::find()->where(['email' => $this->email])->one();
//set flag for sending email
$sendMail = false;
//email subject
$subject = '';
//generate token
$token = $this->generateSubscriberToken();
//if email found in subscribers
if ($subscribers !== null) {
//check if inactive
if ($subscribers->status !== self::STATUS_ACTIVE) {
//assign token
$subscribers->token = $token;
//set status to active
$subscribers->status = self::STATUS_ACTIVE;
print_r($subscribers->errors);
//update the recrod
if (!$subscribers->save()) {
return false;
}
//set subject
$subject = 'Welcome back ' . $this->email . 'Thank you for subscribing ' . Yii::$app->name . '<br /><br /> You will receive notification whenever new trick or post is published to website';
$sendMail = true;
}
} else { //if email does not exist only then insert a new record
$this->status = 1;
if (!$this->save()) {
return false;
}
$subject = 'Thank you ' . $this->email . ' for subscribing ' . Yii::$app->name . '<br /><br /> You will receive notification whenever new trick or post is published to website';
$sendMail = true;
}
//check if send mail flag set
if ($sendMail) {
return Yii::$app->mailer
->compose()
->setFrom(['noreply@my-blog.com' => Yii::$app->name . ' robot'])
->setTo('piyush@localhost')
->setSubject('Subscription : ' . Yii::$app->name)
->setHtmlBody($subject)
->send();
}
}
}
现在我希望表单与验证一起使用。如果用户输入任何错误的输入,例如已经注册的输入,则此消息应该 return 以查看提交表单数据的文件。
Controlelr::redirect() 接受一个 url
和一个可选的 status code
参数。
你在你提出的片段中没有正确调用它。
我相信您正在尝试仅使用 url 参数(单个数组参数)并跳过状态代码。
您也不能依靠引荐来源网址将您带回上一页。您需要将到return的路由保存到表单page
Url::remember([Yii::$app->requestedRoute]);
然后用它来 return 回到表格
return $this->redirect([Url::previous(), ['model' => $model]]);
您可以设置 Yii::$app->user->returnUrl
,然后使用 $this->goBack()
导航回之前的页面。
一个好的方法是在控制器 SubscribeController
中添加 beforeAction
函数,如下所示。
public function beforeAction($action)
{
if (parent::beforeAction($action)) {
if($action->id=='subscribe'){
Yii::$app->user->returnUrl = Yii::$app->request->referrer;
}
}
return true;
}
并替换行
return $this->redirect([Yii::$app->request->referrer, ['model' => $model]]);
与以下
return $this->goBack();
现在,无论您从哪个页面提交页脚表单,它都会导航回该页面。
另一件事我注意到你没有检查表单中的 sessionFlash
error
变量,你需要得到像
if(Yii::$app->session->hasFlash('error')){
echo '<div class="alert alert-danger">
<strong>Danger!</strong>'. Yii::$app->session->getFlash('error').'
</div>';
}
我的 previous answer
中提供了显示 sessionFlash
消息的更好方法,您可以按照该方法避免在任何地方手动添加代码,它会在设置后自动向您显示会话消息。
希望对你有所帮助