0

I've a subscribe newsletter form inside footer that display on all page. To do this I've created a subscriber widget like this:

SubscriberWidget.php

<?php
namespace frontend\components;

use Yii;
use yii\base\Widget;
use yii\helpers\Html;
use frontend\models\SubscribeNewsletterForm;

class SubscriberWidget extends Widget
{

    public function run()
    {
        $subscriber_model  = new SubscribeNewsletterForm();

        return $this->render('_subscribe-newsletter-form.php', [
            'subscriber_model' => $subscriber_model
        ]);
    }
}
?>

Here's the SubscribeNewsletterForm model code:

SubscribeNewsletterForm.php

<?php

namespace frontend\models;

use Yii;
use yii\base\Model;

class SubscribeNewsletterForm extends Model
{
    public $email;

    public function rules()
    {
        return [
            [['email'], 'required'],
            ['email', 'email']
        ];
    }
}
?>

Here is the code of my _subscribe-newsletter-form.php

<?php

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\helpers\Url;

?>

<h3>Subscribe to Newsletter</h3>
<?php $form = ActiveForm::begin(['id' => $subscriber_model->formName(), 'action' => ['project/subscriber'], 'validateOnBlur' => false, 'validateOnType' => false]); ?>
    <div class="input-group">
        <?= $form->field($subscriber_model, 'email')->textInput()->label(false); ?>                             
        <span class="input-group-btn">
            <?php echo Html::submitButton('Sign Up', ['class' => 'btn btn-primary subscribe-btn']); ?>
        </span>                             
    </div>
<?php ActiveForm::end(); ?>

<?php
$script = <<< JS
    $('#{$subscriber_model->formName()}').on('beforeSubmit', function(e){
        var form = $(this);
        $.post(
            form.attr("action"),
            form.serialize()
        ).done(function(data){      
            form.trigger("reset");
        })
        return false;
    });
JS;
$this->registerJs($script);
?>

Inside ProjectController.php I've created the action as follow:

public function actionSubscriber()
    {
        $subscriber_model  = new SubscribeNewsletterForm();

        $request = Yii::$app->request;
        if($request->isAjax && $subscriber_model->load($request->post())){
            $subscriber =  new Subscriber([
                'email' => $subscriber_model->email
            ]);
            $subscriber->save();
        }
    }

Here's the Subscriber model code.

Subscriber.php

<?php

namespace frontend\models;

use yii\db\ActiveRecord;

class Subscriber extends ActiveRecord
{
    public static function tableName()
    {
        return 'subscriber';
    }
} 
?>

frontend/config/main.php

<?php
$params = array_merge(
    require(__DIR__ . '/../../common/config/params.php'),
    require(__DIR__ . '/../../common/config/params-local.php'),
    require(__DIR__ . '/params.php'),
    require(__DIR__ . '/params-local.php')
);

return [
    'id' => 'app-frontend',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'controllerNamespace' => 'frontend\controllers',
    'components' => [
        'request' => [
            'csrfParam' => '_csrf-frontend',
        ],
        'user' => [
            'identityClass' => 'common\models\User',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
        'session' => [
            // this is the name of the session cookie used for login on the frontend
            'name' => 'advanced-frontend',
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        /*
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
            ],
        ],
        */
    ],
    'params' => $params,
];
?>

With above code validation is working but i'm not able to save the email in database. Please tell what i'm doming wrong.

Alex
  • 996
  • 2
  • 10
  • 17

1 Answers1

0

You need rules on your Model. Also, I always replace the generated tables names with the table prefix supported method. Also, I always like to use the Timestamp behavior to log when things are created or updated. Especially when your grabbing contact info for the use of leads, I would record the timestamps as well as their IP Address.

Subscriber.php

use yii\behaviors\TimestampBehavior;

// ...

/**
 * @inheritdoc
 */
public static function tableName()
{
    return '{{%subscriber}}';
}

/**
 * @inheritdoc
 */
public function behaviors()
{
    return [
        TimestampBehavior::className(),
    ];
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        ['email', 'filter', 'filter' => 'trim'],
        ['email', 'required'],
        ['email', 'email'],
        ['email', 'string', 'max' => 255],
        ['email', 'unique', 'targetClass' => '\common\models\Subscriber', 'message' => 'This email address has already been taken.'],

        [['created_at', 'updated_at'], 'integer'],
    ];
}
Wade
  • 3,757
  • 2
  • 32
  • 51
  • Hi Wade, thanks for your response. But still it is not working in console i get error message - index.php?r=project%2Fsubscriber 500 (Internal Server Error) – Alex Apr 15 '17 at 05:50
  • Can you edit your question to include your `frontend/config/main.php`? Mostly, I am interested in if you have any rules defined.. – Wade Apr 15 '17 at 07:50
  • Hi Wade, i've added the frontend/config/main.php code – Alex Apr 15 '17 at 09:16
  • Thanks, but you have no rules defined there, so that isn't the problem. Check in your `frontend/runtime` dir for logs. Delete all the logs, then refresh the page, and see what pops up. Also check your server logs. There must be more information on why you are getting the 500 error. – Wade Apr 16 '17 at 02:46
  • Worst case, put the project on Github and I will clone it and see if I can fix it for you.. – Wade Apr 16 '17 at 02:47
  • Hi wade, I've got the problem. I've assigned the incorrect namespace in Subscriber model (frontend\models instead of common\models). Thanks for your time. – Alex Apr 16 '17 at 05:02
  • No problem, glad you solved it. An invalid namespace will surely do that :) – Wade Apr 16 '17 at 09:36
  • Hi wade, i'm facing one more problem; unique validation is not working. Can you help? – Alex Apr 16 '17 at 12:01
  • It would help to see your project. Can you add it to GitHub? If it's private, invite me. My GH username is `WadeShuler`. – Wade Apr 16 '17 at 18:11