Invalid argument in foreach loop using a model - laravel-5.4

Hey I am making a code in which I m using foreach loop but its giving me error of invalid argument.
Loop of my code is
public function handle($request, Closure $next)
{
foreach(Auth::user()->User as $role){
if($role->role == 'doctor')
{
return $next($request);
}
}
return redirect('');
}
And the model is
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
Please tell me what I am doing wrong.

You can't do a foreach on Auth:user(). If you want to validate the role of a user, you can get the user object that is doing the request and validate the role, for example:
public function handle($request, Closure $next)
{
if($request->user()->rol == 'admin'){
return $next($request);
}
return redirect('/something');
}

Related

Symfony dynamically add form input and convert to JSON

So this is a bit hard to explain.
thing is, I have this entity
class TypeParking
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=55)
*/
private $libelle;
/**
* #ORM\Column(type="time", nullable=true)
*/
private $tempsmax;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $jourdebut;
/**
* #ORM\Column(type="date", nullable=true)
*/
private $jourfin;
/**
* #ORM\Column(type="json_array", nullable=true)
*/
private $heurstravail;
/**
* #ORM\Column(type="json_array", nullable=true)
*/
private $exception;
and this is my controller:
/**
* #Route("/new", name="type_parking_new", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$typeParking = new TypeParking();
$form = $this->createForm(TypeParkingType::class, $typeParking);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($typeParking);
$entityManager->flush();
return $this->redirectToRoute('type_parking_index');
}
return $this->render('type_parking/new.html.twig', [
'type_parking' => $typeParking,
'form' => $form->createView(),
]);
}
<?php
namespace App\Form;
use App\Entity\TypeParking;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class TypeParkingType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('libelle')
->add('tempsmax')
->add('jourdebut')
->add('jourfin')
->add('heurstravail')
->add('exception')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => TypeParking::class,
]);
}
}
See that exception field ? It's type is JSON in the database.
it must contain a name, a starting date, and ending date and starting time and ending time.
like this https://imgur.com/a/2qrz5yy
whenever I press that Plus button I can add another exception field (JQuery).
and when I submit the form this whole exception field gets parsed into a JSON and saved into the databse alongside the rest of the form.
My database: https://imgur.com/a/UonYT3W
I've been trying to get this to work for days now and I couldn't do anything.
your form type is very very minimalistic. explicitly add (sub)fields for your exception field.
<?php
namespace App\Form;
use App\Entity\TypeParking;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
// don't forget to add the types here!
use Symfony\Component\Form\Extension\Core\Type\TextType;
class TypeParkingType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('libelle')
->add('tempsmax')
->add('jourdebut')
->add('jourfin')
->add('heurstravail')
->add('exception_name', TextType::class, ['property_path' => 'exception[name]')
// add other fields of exception, look at
// https://symfony.com/doc/current/reference/forms/types.html
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => TypeParking::class,
]);
}
}
I hope this helps ...
however, the form component (property accessor) will try to get the exception, so we have to help by adding the following to the TypeParking entity class:
public function getException() {
return array_merge([
'name' => '',
// other sub-fields "empty" values
], $this->exception ?? [] // prevent array_merge from failing if exception is empty
);
}

Argument 1 passed to yii\web\User::login() must implement interface yii\web\IdentityInterface

These are my files:
config/web.php
'user' => [
'identityClass' => '\app\models\User',
'enableAutoLogin' => false,
],
SiteController.php
public function actionSignin()
{
$model = new SigninForm();
if(!Yii::$app->user->isGuest)
{
return $this->goHome();
}
if($model->load(Yii::$app->request->post()) and $model->validate())
{
$identity = User::findOne(['email' => $model->email])
Yii::$app->user->login($identity);
}
return $this->render('signin',compact('model'));
}
User.php
namespace app\models;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
/* and all methods Identityinterface is here!*/
}
I'm getting an error that I'm not using IdentityInterface in my User.php model. Where is my mistake?
You need to define all the methods necessary for Implementing IdentityInterface
as given here, and 2 additional methods that would be used by the login method add them to your class first.
class User extends ActiveRecord implements IdentityInterface
{
public static function findIdentity($id)
{
return static::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['access_token' => $token]);
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->authKey;
}
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
foreach (self::$users as $user) {
if (strcasecmp($user['username'], $username) === 0) {
return new static($user);
}
}
return null;
}
/**
* Validates password
*
* #param string $password password to validate
* #return bool if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
Then you SigninForm should look like following
<?php
namespace app\models;
use Yii;
use yii\base\Model;
/**
* SigninForm is the model behind the login form.
*
* #property User|null $user This property is read-only.
*
*/
class SigninForm extends Model {
public $username;
public $password;
public $rememberMe = true;
private $_user = false;
/**
* #return array the validation rules.
*/
public function rules() {
return [
// username and password are both required
[['username', 'password'], 'required'],
// rememberMe must be a boolean value
['rememberMe', 'boolean'],
// password is validated by validatePassword()
['password', 'validatePassword'],
];
}
/**
* Validates the password.
* This method serves as the inline validation for password.
*
* #param string $attribute the attribute currently being validated
* #param array $params the additional name-value pairs given in the rule
*/
public function validatePassword($attribute, $params) {
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->password)) {
$this->addError($attribute, 'Incorrect username or password.');
}
}
}
/**
* Logs in a user using the provided username and password.
* #return bool whether the user is logged in successfully
*/
public function login() {
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0));
}
return false;
}
/**
* Finds user by [[username]]
*
* #return User|null
*/
public function getUser() {
if ($this->_user === false) {
$this->_user = User::findOne($this->username);
}
return $this->_user;
}
}
Update your Signup action to the following
public function actionSignin()
{
$model = new SigninForm();
if(!Yii::$app->user->isGuest)
{
return $this->goHome();
}
if($model->load(Yii::$app->request->post()) && $model->login())
{
return $this->goBack();
}
return $this->render('signin',compact('model'));
}
And then add the following inside your config/web.php under components as it is shown in the following example:
'components'=>[
'user' => [
'identityClass' => 'app\models\User', // User must implement the IdentityInterface
'enableAutoLogin' => true,
// 'loginUrl' => ['user/login'],
// ...
]
]
You should look into documentation more thoroughly here is a good video tutorial that would guide you step by step to implement your login interface.
Hope it helps

Yii::$app->user->isGuest always true on main.php after login

I want to implement user login into yii2 basic app.everything works properly except, when I tries to access Yii::$app->user->isGuest on layout main page. it always returns true. whats going wrong here?, please help me
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
Yii::$app->user->isGuest; // i m getting this as false, which is correct, but after goBack(), I m getting it as true
return $this->goBack();
}
return $this->render('login', [
'model' => $model,
]);
}
Login Mehod from LoginForm.php
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
}
return false;
}
Note : I am using custom theme, which rests outside the web folder and inside project/themes/ directory
** User Model is as follows**
<?php
namespace app\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
use yii\web\NotFoundHttpException;
class User extends ActiveRecord implements IdentityInterface {
private $id;
private $authKey;
const STATUS_DELETED = '0';
const STATUS_ACTIVE = '10';
public static function tableName() {
return '{{%user}}';
}
/**
* #inheritdoc
*/
public function behaviors() {
return [
TimestampBehavior::className(),
];
}
/**
* #inheritdoc
*/
public function getId() {
return $this->id;
}
/**
* #inheritdoc
*/
public function getAuthKey() {
return $this->authKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey) {
return $this->authKey === $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 static function findByEmail($email) {
$user_type = ['U'];
return static::find()
->andWhere('email = :email', [':email' => $email])
->andFilterWhere(['in', 'user_type', $user_type])
->one();
}
public static function findIdentity($id) {
$user = static::find()->where(['id' => $id, 'status' => self::STATUS_ACTIVE,])->one();
if (empty($user->id)) {
\Yii::$app->session->destroy();
}
return $user;
}
public static function findIdentityByAccessToken($token, $type = null) {
$user = static::find()
->where([
'access_token' => $token,
'status' => self::STATUS_ACTIVE,
])
->one();
if (!empty($user)) {
return $user;
} else {
throw new NotFoundHttpException('Invalid access token.');
}
}
}
Remove the lines:
private $id;
private $authKey;
from User class.
You should not directly declare ActiveRecord attributes that come from database as stated in the Guide.
Note: The Active Record attributes are named after the associated table columns in a case-sensitive manner. Yii automatically defines an attribute in Active Record for every column of the associated table. You should NOT redeclare any of the attributes.

How to create nested objects with FOSRestBundle and FormType?

I'm developing an API with symfony2 + FOSRestBundle and I have two errors.
Below is my code:
Property
/**
* Property
*
* #ORM\Table(name="property")
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="discr", type="string")
* #ORM\DiscriminatorMap({"house" = "House"})
*/
abstract class Property {
/**
* #ORM\OneToMany(targetEntity="Image", mappedBy="property", cascade={"persist"})
* */
private $images;
function getImages() {
return $this->images;
}
function setImages($images) {
$this->images = $images;
}
}
House
class House extends Property
{
/* More code */
}
Image
class Image {
/**
* #ORM\Column(name="content", type="text", nullable=false)
*/
private $content;
/**
* #ORM\ManyToOne(targetEntity="Property", inversedBy="images")
* #ORM\JoinColumn(name="propertyId", referencedColumnName="id")
* */
private $property;
}
PropertyType
class PropertyType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('images');
$builder->get('images')
->addModelTransformer(new CallbackTransformer(
function($images) {
$image = new \Cboujon\PropertyBundle\Entity\Image();
$image->setContent('test of content');
return array($image);
}, function($imagesContents) {
}));
}
HouseRESTController
/**
* #View(statusCode=201, serializerEnableMaxDepthChecks=true)
*
* #param Request $request
*
* #return Response
*
*/
public function postAction(Request $request)
{
$entity = new House();
$form = $this->createForm(new HouseType(), $entity, array("method" => $request->getMethod()));
$this->removeExtraFields($request, $form);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $entity;
}
When I create a new house, I send this (simplified) JSON:
{"images":["base64ContentImage_1", "base64ContentImage_2"]}
First Problem: The $images parameter in the first function passed to the CallbackTransformer is NULL. Why?
Second problem: I order to test and understand the first problem, I forced to create an image entity as you can see but I get a JSON response with the error "Entities passed to the choice field must be managed. Maybe persist them in the entity manager?"
Can anyone help me to solve any of two problem?
I have found one solution
I have been created ImageType
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('content')
;
}
And also I have been modified PropertyType
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('title')
->add('description')
->add('price')
->add('services')
->add('images', 'collection', array(
'type' => new ImageType(),
'allow_add' => true,
))
;
}
And finally, I was changed the JSON structure of my request:
{"images":[{content: "base64ContentImage_1"}, {content:"base64ContentImage_2"}]}

Yii2 - Unable to find 'app\models\User' in file: backend/models/User.php. Namespace missing? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I used both namespace in this file backend/models/User.php
When I use namespace app\models; It shows Unable to find 'backend\models\User'.
If I use namespace backend\models; It shows Unable to find 'app\models\User'
<?php
//namespace app\models;
namespace backend\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
const ROLE_USER = 10;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'admin';
}
/**
* #inheritdoc
*/
public function behaviors()
{
return [
TimestampBehavior::className(),
];
}
/**
* #inheritdoc
*/
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
['role', 'default', 'value' => self::ROLE_USER],
['role', 'in', 'range' => [self::ROLE_USER]],
];
}
/**
* #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, 'status' => self::STATUS_ACTIVE]);
}
/**
* 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();
}
/**
* #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);
}
/**
* Generates password hash from password and sets it to the model
*
* #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();
}
/**
* 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;
}
}
I think your problem is, that you have two different models and try to use them both in one namespace, but this won't work.
You can alias one namespace, so you can use both different models.
eg.:
<?php
namespace app\models;
// there exist a model "User"
// and you wanna use also the User model under common\models\
use common\models\User as CUser;
Another solution is to prefixing the namespace to the model like
<?php
namespace app\models;
$cuser = new \common\models\User();
see PHP Namespaces explained