I have signup form which register a new user. But when i input data all fields exept one(username) saving in DB. I can't figure why. Help me.
here is my code from SignupForm
<?php
namespace app\modules\user\models;
use yii\base\Model;
use Yii;
/**
* Signup form
*/
class SignupForm extends Model
{
public $username;
public $email;
public $password;
public $verifyCode;
public function rules()
{
return [
['username', 'filter', 'filter' => 'trim'],
['username', 'required'],
['username', 'match', 'pattern' => '#^[\w_-]+$#i'],
['username', 'unique', 'targetClass' => User::className(), 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'filter', 'filter' => 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'unique', 'targetClass' => User::className(), 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
['verifyCode', 'captcha', 'captchaAction' => '/user/default/captcha'],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => Yii::t('app', 'USER_USERNAME'),
'email' => Yii::t('app', 'USER_EMAIL'),
'password' => Yii::t('app', 'USER_PASSWORD'),
'verifyCode' => Yii::t('app', 'USER_VERIFYCODE'),
];
}
/**
* Signs user up.
*
* #return User|null the saved model or null if saving fails
*/
public function signup()
{
if ($this->validate()) {
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->status = User::STATUS_WAIT;
$user->generateAuthKey();
$user->generateEmailConfirmToken();
if ($user->save()) {
Yii::$app->mailer->compose('#app/modules/user/mails/emailConfirm', ['user' => $user])
->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name])
->setTo($this->email)
->setSubject('Email confirmation for ' . Yii::$app->name)
->send();
}
return $user;
}
return null;
}
}
code from signup(view)
<?php
use yii\captcha\Captcha;
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
/* #var $this yii\web\View */
/* #var $form yii\bootstrap\ActiveForm */
/* #var $model app\modules\user\models\SignupForm */
$this->title = Yii::t('app', 'TITLE_SIGNUP');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="user-default-signup">
<h1><?= Yii::t('app', 'TITLE_SIGNUP') ?></h1>
<p>Please fill out the following fields to signup:</p>
<div class="row">
<div class="col-lg-5">
<?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>
<?= $form->field($model, 'username') -> textInput() ?>
<?= $form->field($model, 'email') -> textInput() ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'verifyCode')->widget(Captcha::className(), [
'captchaAction' => '/user/default/captcha',
'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
]) ?>
<div class="form-group">
<?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
code from DefaultController
...
public function actionSignup()
{
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
if ($user = $model->signup()) {
Yii::$app->getSession()->setFlash('success', 'Подтвердите ваш электронный адрес.');
return $this->goHome();
}
}
return $this->render('signup', [
'model' => $model,
]);
}
...
code from User(model)
<?php
namespace app\modules\user\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\helpers\ArrayHelper;
use yii\web\IdentityInterface;
/**
* This is the model class for table "{{%user}}".
*
* #property integer $id
* #property integer $created_at
* #property integer $updated_at
* #property string $username
* #property string $auth_key
* #property string $email_confirm_token
* #property string $password_hash
* #property string $password_reset_token
* #property string $email
* #property integer $status
*/
class User extends ActiveRecord implements IdentityInterface
{
const SCENARIO_PROFILE = 'profile';
const STATUS_BLOCKED = 0;
const STATUS_ACTIVE = 1;
const STATUS_WAIT = 2;
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
public function rules()
{
return [
['username', 'required'],
['username', 'match', 'pattern' => '#^[\w_-]+$#i'],
['username', 'unique', 'targetClass' => self::className(), 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'required', 'except' => self::SCENARIO_PROFILE],
['email', 'email', 'except' => self::SCENARIO_PROFILE],
['email', 'unique', 'targetClass' => self::className(), 'except' => self::SCENARIO_PROFILE, 'message' => Yii::t('app', 'ERROR_EMAIL_EXISTS')],
['email', 'string', 'max' => 255, 'except' => self::SCENARIO_PROFILE],
['status', 'integer'],
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => array_keys(self::getStatusesArray())],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'created_at' => Yii::t('app', 'USER_CREATED'), //'Создан',
'updated_at' => Yii::t('app', 'USER_UPDATE'), //'Обновлён',
'username' => Yii::t('app', 'USER_USERNAME'), // 'Имя пользователя',
'email' => Yii::t('app', 'USER_EMAIL'), // 'Email',
'status' => Yii::t('app', 'USER_STATUS'), //'Статус',
];
}
public function scenarios()
{
return [
self::SCENARIO_DEFAULT => ['username', 'email', 'status'],
self::SCENARIO_PROFILE => ['email'],
];
}
public function behaviors()
{
return [
TimestampBehavior::className(),
];
}
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException('findIdentityByAccessToken is not implemented.');
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username]);
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
public function getStatusName()
{
return ArrayHelper::getValue(self::getStatusesArray(), $this->status);
}
public static function getStatusesArray()
{
return [
self::STATUS_BLOCKED => 'Заблокирован',
self::STATUS_ACTIVE => 'Активен',
self::STATUS_WAIT => 'Ожидает подтверждения',
];
}
/**
* #param string $password
*/
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($insert) {
$this->generateAuthKey();
}
return true;
}
return false;
}
//************************************
/**
* Finds user by password reset token
*
* #param string $token password reset token
* #return static|null
*/
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
/**
* Finds out if password reset token is valid
*
* #param string $token password reset token
* #return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
$parts = explode('_', $token);
$timestamp = (int) end($parts);
return $timestamp + $expire >= time();
}
/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
//************************************
/**
* #param string $email_confirm_token
* #return static|null
*/
public static function findByEmailConfirmToken($email_confirm_token)
{
return static::findOne(['email_confirm_token' => $email_confirm_token, 'status' => self::STATUS_WAIT]);
}
/**
* Generates email confirmation token
*/
public function generateEmailConfirmToken()
{
$this->email_confirm_token = Yii::$app->security->generateRandomString();
}
/**
* Removes email confirmation token
*/
public function removeEmailConfirmToken()
{
$this->email_confirm_token = null;
}
}
It's because you have got username attribute directly declared in User model here:
public $username;
Remove it so it can be mapped by ActiveRecord.
See the note in the guide about this.
Related
I want to build forgot password page in cakephp
Here is my code of user controller
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Http\Exception\UnauthorizedException;
use Cake\Mailer\Email;
use Cake\Mailer\Mailer;
use Cake\email\TransportFactory;
use Cake\Auth\DefaultPasswordHasher;
use Cake\Utility\Security;
use Cake\ORM\TableRegistry;
use Cake\Core\InstanceConfigTrait;
/**
Users Controller
#property \App\Model\Table\UsersTable $Users
#method \App\Model\Entity\User[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
*/
class UsersController extends AppController {
public function beforeFilter(\Cake\Event\Event $event) {
$this->Auth->allow([‘add’, ‘logout’]);
parent::beforeFilter($event);
}
/**
Index method
#return \Cake\Http\Response|null
*/
public function index() {
if ($this->Auth->user(‘role’) != ‘admin’) {
throw new UnauthorizedException(__(‘You are not allowed to access this page’));
}
$users = $this->paginate($this->Users);
$this->set(compact(‘users’));
}
/**
View method
#param string|null $id User id.
#return \Cake\Http\Response|null
#throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function view($id = null) {
$user = $this->Users->get($id, [
‘contain’ => [],
]);
$this->set(‘user’, $user);
}
/**
Add method
#return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
*/
public function add() {
if ($this->Auth->user(‘role’) != ‘admin’) {
throw new UnauthorizedException((‘You are not allowed to access this page’));
}
$user = $this->Users->newEntity();
if ($this->request->is(‘post’)) {
$user = $this->Users->patchEntity($user, $this->request->getData());
if ($this->Users->save($user)) {
$this->Flash->success((‘The user has been saved.’));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
$this->set(compact(‘user’));
}
/**
Edit method
#param string|null $id User id.
#return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise.
#throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function edit($id = null) {
if ($this->Auth->user(‘role’) != ‘admin’) {
throw new UnauthorizedException((‘You are not allowed to access this page’));
}
$user = $this->Users->get($id, [
‘contain’ => [],
]);
if ($this->request->is([‘patch’, ‘post’, ‘put’])) {
$user = $this->Users->patchEntity($user, $this->request->getData());
if ($this->Users->save($user)) {
$this->Flash->success((‘The user has been saved.’));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
$this->set(compact(‘user’));
}
/**
Delete method
#param string|null $id User id.
#return \Cake\Http\Response|null Redirects to index.
#throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
*/
public function delete($id = null) {
if ($this->Auth->user(‘role’) != ‘admin’) {
throw new UnauthorizedException((‘You are not allowed to access this page’));
}
$this->request->allowMethod([‘post’, ‘delete’]);
$user = $this->Users->get($id);
if ($this->Users->delete($user)) {
$this->Flash->success((‘The user has been deleted.’));
} else {
$this->Flash->error(__(‘The user could not be deleted. Please, try again.’));
}
return $this->redirect([‘action’ => ‘index’]);
}
public function forgotpassword()
{
if ($this->request->is(‘post’)) {
$email = $this->request->getData(‘email’);
$token = Security::hash(Security::randomBytes(25));
$userTable = TableRegistry::get(‘Users’);
if ($email == NULL) {
$this->Flash->error((‘Please insert your email address’));
}
if ($user = $userTable->find(‘all’)->where([‘email’=>$email])->first()) {
$user->token = $token;
if ($userTable->save($user)){
$mailer = new Mailer(‘default’);
$mailer->Transport(‘Smtp’);
$mailer->From([‘noreply[at]codethepixel.com’ => ‘myCake4’])
->setTo($email)
->setEmailFormat(‘html’)
->setSubject(‘Forgot Password Request’)
->deliver(‘Hello
Please click link below to reset your password
Reset Password’);
}
$this->Flash->success(‘Reset password link has been sent to your email (’.$email.’), please check your email’);
}
if ($total = $userTable->find(‘all’)->where([‘email’=>$email])->count()==0) {
$this->Flash->error((‘Email is not registered in system’));
}
}
}
public function resetpassword($token)
{
if($this->request->is(‘post’)){
$hasher = new DefaultPasswordHasher();
$newPass = $hasher->hash($this->request->getData(‘password’));
$userTable = TableRegistry::get(‘Users’);
$user = $userTable->find(‘all’)->where([‘token’=>$token])->first();
$user->password = $newPass;
if ($userTable->save($user)) {
$this->Flash->success(‘Password successfully reset. Please login using your new password’);
return $this->redirect([‘action’=>‘login’]);
}
}
}
public function login() {
if ($this->request->is(‘post’)) {
$user = $this->Auth->identify();
if ($user) {
if ($user[‘is_active’] === 1) {
$users = $this->Users->get($user[‘id’]);
$users->ip_address = $this->request->clientIp();
$users->last_login = date(‘Y-m-d h:i:s’);
if ($this->Users->save($users)) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Flash->error((‘Unable to login by your credentials.’));
}
} else {
$this->Flash->error((‘This user not activated, please contact our administrator.’));
}
}
$this->Flash->error(__(‘Invalid username or password, try again’));
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
}
After opening forgot password page user enter their email following error received.
Cannot instantiate abstract class Cake\Mailer\Mailer
How do I solve this problem when the user entered their email & reset password will be sent to user's email which will be saved in our database.
Help me please #ndm
In your app.php
use Cake\Mailer\Transport\MailTransport;
.
.
.
'EmailTransport' => [
'default' => [
'className' => MailTransport::class,
/*
* The following keys are used in SMTP transports:
*/
'host' => 'localhost',
'port' => 25,
'timeout' => 30,
'username' => null,
'password' => null,
'client' => null,
'tls' => null,
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
],
'your_project' => [
'className' => 'Smtp',
'host' => 'your_host',
'port' => XXX,
'timeout' => 30,
'username' => 'your_email',
'password' => 'your_password',
'client' => null,
'tls' => true,
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
],
],
'Email' => [
'default' => [
'transport' => 'default',
'from' => 'you#localhost',
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
],
'your_project' => [
'transport' => 'your_project',
'from' => ['your_email#teste.com' => 'My Site'],
//'charset' => 'utf-8',
//'headerCharset' => 'utf-8',
],
],
Create a folder "Mailer" in src/Mailer. Create an UserMailer.php file
<?php
namespace App\Mailer;
use Cake\Mailer\Mailer;
class UserMailer extends Mailer
{
public static $name = 'User';
public function reset($user)
{
$this->to($user->email)
->profile('your_project')
->emailFormat('html')
->template('your_project', 'user')
->layout('user')
->viewVars(['name' => $user->name])
->subject(sprintf('Welcome...', $user->name))
->message("texte...");
}
}
In this case, I created a layout for my email. Create an "Email" folder in the layout.
On your controller, do the following:
$this->getMailer('User')->send('reset', [$user]);
Don't forget to import into the controller:
use Cake\Mailer\MailerAwareTrait;
I use it like this.
Go to the godaddy dashboard and find the SMTP information. It's all you need! Replace with your information
I try to change the "ID Kategori"(Category ID) to "Nama Kategori" (Category Name), the Category ID is in product table and has a relation to category table.
for the gridView im using kartik-v gridView
i know the error is at return Html::a($model->kategori->deskripsi ,['kategori/view','id' => $model->Id]);, But i dont know whats the problem or how to fix it
please help me... >.<
[
'label' => 'Kategori',
'attribute' => 'IdKategori',
'format' => 'raw',
'vAlign' => 'middle',
'value' => function ($model, $key, $index) {
return Html::a($model->kategori->deskripsi ,['kategori/view','id' => $model->Id]);
},
],
and this is the model
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "produk".
*
* #property integer $Id
* #property integer $IdKategori
* #property string $nama_produk
* #property integer $harga_produk
* #property string $gambar
* #property string $deksripsi_produk
* #property string $detail_produk
*/
class Produk extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public $file;
public static function tableName()
{
return 'produk';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['IdKategori', 'nama_produk', 'harga_produk', 'gambar', 'deksripsi_produk', 'detail_produk'], 'required'],
[['IdKategori', 'harga_produk'], 'integer'],
[['file'], 'file'],
[['nama_produk', 'file', 'gambar', 'deksripsi_produk', 'detail_produk'], 'string', 'max' => 255],
[['IdKategori'], 'exist', 'skipOnError' => true, 'targetClass' => Kategori::className(), 'targetAttribute' => ['IdKategori' => 'Id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'Id' => 'ID',
'IdKategori' => 'Id Kategori',
'nama_produk' => 'Nama Produk',
'harga_produk' => 'Harga Produk',
'gambar' => 'Gambar',
'deksripsi_produk' => 'Deksripsi Produk',
'detail_produk' => 'Detail Produk',
];
}
public function getKategori()
{
return $this->hasOne(Kategori::className(), ['Id' => 'IdKategori']);
}
}
This is the kategori model
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "kategori".
*
* #property integer $Id
* #property integer $ParentId
* #property string $nama_kategori
* #property string $deskripsi
*/
class Kategori extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'kategori';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['ParentId', 'nama_kategori', 'deskripsi'], 'required'],
[['ParentId'], 'integer'],
[['nama_kategori', 'deskripsi'], 'string', 'max' => 255],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'Id' => 'ID',
'ParentId' => 'Parent ID',
'nama_kategori' => 'Nama Kategori',
'deskripsi' => 'Deskripsi',
];
}
}
I checked myself to make sure I can repeat your error and it seems to be the case.
In your database, table produkt has a column called IdKategori and at least 1 row contains either null or non-existing value for table kategori (non-existing value means that it has an ID that does not exist in kategori table).
You can solve that with (one example):
'value' => function ($model, $key, $index) {
if (empty($model->kategori->deskripsi)) {
return '';
} else {
return Html::a($model->kategori->deskripsi, ['kategori/view', 'id' => $model->Id]);
}
},
many days I working on drupal 8 custom form module which is the multi-step form I have complete this using SessionManagerInterface that's work fine but I want to display all data in one page before submit how can I achieve this .here I include snapshot here
demo.routing.yml
demo.multistep_one:
path: '/demo/multistep-one'
defaults:
_form: '\Drupal\demo\Form\Multistep\MultistepOneForm'
_title: 'First form'
requirements:
_permission: 'access content'
demo.multistep_two:
path: '/demo/multistep-two'
defaults:
_form: '\Drupal\demo\Form\Multistep\MultistepTwoForm'
_title: 'Second form'
requirements:
_permission: 'access content'ent'
MultistepFormBase.php
namespace Drupal\demo\Form\Multistep;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\SessionManagerInterface;
use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class MultistepFormBase extends FormBase {
/**
* #var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
/**
* #var \Drupal\Core\Session\SessionManagerInterface
*/
private $sessionManager;
/**
* #var \Drupal\Core\Session\AccountInterface
*/
private $currentUser;
/**
* #var \Drupal\user\PrivateTempStore
*/
protected $store;
/**
* Constructs a \Drupal\demo\Form\Multistep\MultistepFormBase.
*
* #param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* #param \Drupal\Core\Session\SessionManagerInterface $session_manager
* #param \Drupal\Core\Session\AccountInterface $current_user
*/
public function __construct(PrivateTempStoreFactory $temp_store_factory, SessionManagerInterface $session_manager, AccountInterface $current_user) {
$this->tempStoreFactory = $temp_store_factory;
$this->sessionManager = $session_manager;
$this->currentUser = $current_user;
$this->store = $this->tempStoreFactory->get('multistep_data');
}
/**
* {#inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('user.private_tempstore'),
$container->get('session_manager'),
$container->get('current_user')
);
}
/**
* {#inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Start a manual session for anonymous users.
if ($this->currentUser->isAnonymous() && !isset($_SESSION['multistep_form_holds_session'])) {
$_SESSION['multistep_form_holds_session'] = true;
$this->sessionManager->start();
}
$form = array();
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Submit'),
'#button_type' => 'primary',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
return $form;
}
MultistepOneForm.php which child form
namespace Drupal\demo\Form\Multistep;
use Drupal\Core\Form\FormStateInterface;
class MultistepOneForm extends MultistepFormBase {
/**
* {#inheritdoc}.
*/
public function getFormId() {
return 'multistep_form_one';
}
/**
* {#inheritdoc}.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$form['fname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your name'),
'#default_value' => $this->store->get('fname') ? $this->store->get('fname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['lname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your Last Name'),
'#default_value' => $this->store->get('lname') ? $this->store->get('lname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
/**
* {#inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('fname', $form_state->getValue('fname'));
$this->store->set('lname', $form_state->getValue('lname'));
$form_state->setRedirect('demo.multistep_two');
}
}
MultistepTwoForm.php
namespace Drupal\demo\Form\Multistep;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
class MultistepTwoForm extends MultistepFormBase {
/**
* {#inheritdoc}.
*/
public function getFormId() {
return 'multistep_form_two';
}
/**
* {#inheritdoc}.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$form['jfname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder First Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['jlname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder Last Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['actions']['previous'] = array(
'#type' => 'link',
'#title' => $this->t('Previous'),
'#url' => Url::fromRoute('demo.multistep_one'),
'#suffix' => '</div>',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('jfname', $form_state->getValue('jfname'));
$this->store->set('jlname', $form_state->getValue('jlname'));
// $form_state->setRedirect('demo.multistep_three');
}
}
here my concern is raised How to display all data according to my snapshot.what action needs to be taken display data. one thing is that i have 3 month experience about drupal so can't take decision what i will do? this code is example of www.sitepoint.com and I take form three and session data is display in label whether it good or not i don't know give me direction appropriate
thanks in advance
In your setup, you are submitting the multiform in MultistepTwoForm.
Change this as follows:
Build one more form: MultiStepPreview. This will hold your preview.
Do Not submit the form in MultistepTwoForm but redirect the form to MultiStepPreview using $form_state->setRedirect()
In MultiStepPreview:
read the keys in the store
build a form element containing the preview (I made a html table to contain the preview)
submit the form.
class OverviewForm extends MultiStepFormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
// get data from the store
$your_details = $this->store->get('your_details');
$order = $this->store->get('order_details');
// make a HTML table containing the data in store
$markup = '<table>';
// loop through $your_details and $your_order and put them in $markup
$form = parent::buildForm($form, $form_state);
$form['preview'] = [
'#markup' => $markup,
];
//in my setup all the buttons are build by MultiStepFormBase
return $form;
}
}
I am using cakephp3. I have a simple web application that has users. I have two user types, Admin and Standard. I want to limit Standard user to only view and index data. Whereas Admin type user should be able to add, edit, delete, view and index user data.
Basically, I want to globally restrict standard users, so that they cannot access the add, edit and delete methods of the controller.
So can anyone help me achieve it?
Below is /src/Controller/UsersController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
/**
* Users Controller
*
* #property \App\Model\Table\UsersTable $Users
*/
class UsersController extends AppController
{
/**
* Index method
*
* #return void
*/
public function index()
{
$this->paginate = [
'contain' => ['Countries', 'Cities', 'UserGroups', 'UserLevels']
];
$this->set('users', $this->paginate($this->Users));
$this->set('_serialize', ['users']);
}
public function dashboard()
{
}
/**
* View method
*
* #param string|null $id User id.
* #return void
* #throws \Cake\Network\Exception\NotFoundException When record not found.
*/
public function view($id = null)
{
$user = $this->Users->get($id, [
'contain' => ['Countries', 'Cities', 'UserGroups', 'UserLevels', 'Alerts', 'DeviceLogs', 'Devices']
]);
$this->set('user', $user);
$this->set('_serialize', ['user']);
}
/**
* Add method
*
* #return void Redirects on successful add, renders view otherwise.
*/
public function add()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$countries = $this->Users->Countries->find('list', ['limit' => 200]);
$cities = $this->Users->Cities->find('list', ['limit' => 200]);
$userGroups = $this->Users->UserGroups->find('list', ['limit' => 200]);
$userLevels = $this->Users->UserLevels->find('list', ['limit' => 200]);
$this->set(compact('user', 'countries', 'cities', 'userGroups', 'userLevels'));
$this->set('_serialize', ['user']);
}
/**
* Edit method
*
* #param string|null $id User id.
* #return void Redirects on successful edit, renders view otherwise.
* #throws \Cake\Network\Exception\NotFoundException When record not found.
*/
public function edit($id = null)
{
$user = $this->Users->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$countries = $this->Users->Countries->find('list', ['limit' => 200]);
$cities = $this->Users->Cities->find('list', ['limit' => 200]);
$userGroups = $this->Users->UserGroups->find('list', ['limit' => 200]);
$userLevels = $this->Users->UserLevels->find('list', ['limit' => 200]);
$this->set(compact('user', 'countries', 'cities', 'userGroups', 'userLevels'));
$this->set('_serialize', ['user']);
}
/**
* Delete method
*
* #param string|null $id User id.
* #return \Cake\Network\Response|null Redirects to index.
* #throws \Cake\Network\Exception\NotFoundException When record not found.
*/
public function delete($id = null)
{
$this->request->allowMethod(['post', 'delete']);
$user = $this->Users->get($id);
if ($this->Users->delete($user)) {
$this->Flash->success(__('The user has been deleted.'));
} else {
$this->Flash->error(__('The user could not be deleted. Please, try again.'));
}
return $this->redirect(['action' => 'index']);
}
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error('Your username or password is incorrect.');
}
}
public function logout()
{
$this->Flash->success('You are now logged out.');
return $this->redirect($this->Auth->logout());
}
public function resetPassword() {
}
public function changepassword() {
}
}
Below is AppController.php
<?php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
class AppController extends Controller
{
use \Crud\Controller\ControllerTrait;
public $components = [
'RequestHandler',
'Crud.Crud' => [
'actions' => [
'Crud.Index',
'Crud.View',
'Crud.Add',
'Crud.Edit',
'Crud.Delete'
],
'listeners' => [
'Crud.Api',
'Crud.ApiPagination',
'Crud.ApiQueryLog'
]
]
];
/**
* Initialization hook method.
*
* Use this method to add common initialization code like loading components.
*
* e.g. `$this->loadComponent('Security');`
*
* #return void
*/
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
// default is referer and in case of no referer loginRedirect (after login)
'loginRedirect' => [
'controller' => 'Users',
'action' => 'dashboard'
],
'logoutRedirect' => '/',
'authError' => "Y"
]);
// Allow the display action so our pages controller
// continues to work.
$this->Auth->allow(['resetPassword','add','changePassword','display']);
}
/**
* Before render callback.
*
* #param \Cake\Event\Event $event The beforeRender event.
* #return void
*/
public function beforeRender(Event $event)
{
if (!array_key_exists('_serialize', $this->viewVars) &&
in_array($this->response->type(), ['application/json', 'application/xml'])
) {
$this->set('_serialize', true);
}
}
}
Regards,
The right approach is to use ControllerAuthorize.
As described in the docs, you have to add in AppController the following:
public function isAuthorized($user = null)
{
// Any registered user can access public functions
if (empty($this->request->params['prefix'])) {
return true;
}
// Only admins can access admin functions
if ($this->request->params['prefix'] === 'admin') {
return (bool)($user['role'] === 'admin');
}
// Default deny
return false;
}
You then have to define admin as a valid key for prefix routing, and move your add, edit and delete actions to the new controller in
src/Controller/Admin/UsersController.php
Greetings,
i'm using a multiple file upload input in Yii2.
The multiole file input is saving very well the files selected inside a folder called audio.
The problen is i cannot inside foreach loop save the name and path of each file in the database model Faixas.php inside a field called ficheiro.
Here is my code:
Controller:
public function actionCreate()
{
$model = new Faixas();
if (Yii::$app->request->isPost) {
$model->files = UploadedFile::getInstances($model, 'files');
if ($model->upload()) {
return $this->render('create', ['model' => $model]);
}
}
return $this->render('create', ['model' => $model]);
}
The Model as a function named upload() to save the files in folder, but the part to save inside the model->ficheiro is not working (don't figure it out ?):
public function rules()
{
return [
[['nome', 'ficheiro', 'dummy1', 'dummy2', 'dummy3', 'dummy4', 'dummy5'], 'string', 'max' => 255],
[['files'], 'file', 'skipOnEmpty' => false, 'extensions' => 'mp3, ogg, webm', 'maxFiles' => 30],
];
}
public function upload()
{
$model = new Faixas();
if ($this->validate()) {
foreach ($this->files as $file) {
$file->saveAs('audio/' . $file->baseName . '.' . $file->extension);
// this part in not working, why ????
$filePath = 'audio/' . $file->baseName . '.' . $file->extension;
$model->ficheiro = $filePath;
$model->save();
}
return true;
} else {
return false;
}
}
And finally the view, which renders the input:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'files[]')->fileInput(['multiple' => true, 'accept' => 'audio/*']) ?>
<button>Submit</button>
Any ideas on the way to get it done?
Many thanks...
The entire Faixas.php model class:
<?php
namespace app\models;
use Yii;
/**
* This is the model class for table "faixas".
*
* #property integer $id
* #property string $nome
* #property string $ficheiro
* #property string $dummy1
* #property string $dummy2
* #property string $dummy3
* #property string $dummy4
* #property string $dummy5
*/
class Faixas extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'faixas';
}
public $files;
/**
* #inheritdoc
*/
public function rules()
{
return [
[['nome', 'ficheiro', 'dummy1', 'dummy2', 'dummy3', 'dummy4', 'dummy5'], 'string', 'max' => 255],
[['files'], 'file', 'skipOnEmpty' => false, 'extensions' => 'mp3, ogg, webm', 'maxFiles' => 30],
];
}
public function upload()
{
if ($this->validate()) {
foreach ($this->files as $file) {
$file->saveAs('audio/' . $file->baseName . '.' . $file->extension);
$model = new Faixas();
// this part in not working, why ????
$filePath = 'audio/' . $file->baseName . '.' . $file->extension;
$model->ficheiro = $filePath;
$model->save();
}
return true;
} else {
return false;
}
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'nome' => Yii::t('app', 'Nome'),
'ficheiro' => Yii::t('app', 'Ficheiro'),
'dummy1' => Yii::t('app', 'Dummy1'),
'dummy2' => Yii::t('app', 'Dummy2'),
'dummy3' => Yii::t('app', 'Dummy3'),
'dummy4' => Yii::t('app', 'Dummy4'),
'dummy5' => Yii::t('app', 'Dummy5'),
];
}
// coloca o Audio na GridView
public function getAudio()
{
return \Yii::$app->request->BaseUrl.'/'.$this->ficheiro;
}
}
Seems you create the model in wrog place. You create a $model = new Faixas(); ouuside the loop. try creating inside.
public function upload()
{
if ($this->validate()) {
foreach ($this->files as $file) {
$file->saveAs('audio/' . $file->baseName . '.' . $file->extension);
$model = new Faixas();
$filePath = 'audio/' . $file->baseName . '.' . $file->extension;
$model->ficheiro = $filePath;
$model->save();
}
return true;
} else {
return false;
}
}
SOLVED... removed from the model file the rule:
[['files'], 'file', 'skipOnEmpty' => false, 'extensions' => 'mp3, ogg, webm', 'maxFiles' => 30],
Now the foreach() loop saves every file Path in the database.
Many thanks to all that somehow tried to achieve a solution.