PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label yii2-basic-app. Show all posts
Showing posts with label yii2-basic-app. Show all posts

Sunday, June 26, 2022

[FIXED] How to login using two different model or switch identity class in yii2?

 June 26, 2022     php, yii, yii2, yii2-basic-app, yii2-user     No comments   

Issue

I want to allow user login from two different model.

Config.php

'user' => [
        'identityClass' => 'app\models\User', //one more class here
        'enableAutoLogin' => false,
        'authTimeout' => 3600*2,
    ],

LoginForm.php

 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'],
    ];
}

 public function validatePassword($attribute, $params)
{
    if (!$this->hasErrors()) {
        $user = $this->getUser();

        if (!$user || !$user->validatePassword($this->password)) {
            $this->addError($attribute, Yii::t('user', 'Incorrect username or password.'));
        }
    }
}

public function login()
{
    if ($this->validate()) {
        return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
    } else {
        return false;
    }
}

public function parentLogin()
{
    // How to validate parent Login?
}

public function getUser()
{
    if ($this->_user === false) {
        $this->_user = User::findByUsername($this->username);
    }

    return $this->_user;
}

User.php

class User extends \yii\db\ActiveRecord implements IdentityInterface
{
    public static function tableName()
   {
    return 'users';
   }

   public static function findIdentity($id)
  {
    return static::findOne($id);
  }

  public static function findByUsername($username)
 {
    return static::findOne(['user_login_id' => $username]);
 }

Controller.php

 public function actionLogin()
{
    // Working
}

public function actionParentLogin()
{
    $model = new LoginForm();

    if ($model->load(Yii::$app->request->post()) && $model->parentLogin()) {

            $parent = ParentLogin::find()->where(['p_username' => $model->p_username])->one();
        if($parent){
            \Yii::$app->session->set('p_id',$parent->p_id);
            return $this->redirect(['parent-dashboard']);
        }
        else
        {
            Yii::$app->getSession()->setFlash('error', Yii::t('site', 'Incorrect username or password.'));
        }
    }
    return $this->render('parent-login', [
            'model' => $model,
        ]);
}

I don't know how to validate parent login. I tried for hours finding workaround but not succeed.

I am stuck on Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0); because user table don't have parent login records.

My questions

1) Is it possible to have two identityClass. If yes then how?
2) Is it possible to extend ParentLogin model to User. If yes then how to validate?

References

How To extend user class?
Customising the CWebUser class
Custom userIdentity class in yii2


Solution

Joe Miller has a good sugestion about having one user class and some boolean fields in users' table to check user's role, as an alternative to rbac. But since in your situation it is not possible, here is what I can suggest to you (this approach is half-way tested and need to be adopted).

Yes you can have two or more identityClasses, but not in the same time. You need to handle switching between identities. So first, I suggest to you edit your LoginForm model a little:

class LoginForm extends Model
{
    public $username;
    public $password;
    public $rememberMe = true;
    // we added this parameter to handle userModel class
    // that is responsible for getting correct user
    public $userModel;

    private $_user = false;

    /* all other methods stay same */

    /**
     * Finds user by [[username]]
     *
     * @return User|null
     */
    public function getUser()
    {
        if ($this->_user === false) {
            // calling findByUsername method dynamically
            $this->_user = call_user_func(
                [$this->userModel, 'findByUsername'], 
                $this->username
            );
        }

        return $this->_user;
    }
}

Now in controller:

public function actionParentLogin()
{
    $model = new LoginForm(['userModel' => ParentLogin::className()]);
    // calling model->login() here as we usually do
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
            // no need to worry about checking if we found parent it's all done polymorphycally for us in LoginForm
            // here is the trick, since we loggin in via parentLogin action we set this session variable.
            Yii::$app->session->set('isParent', true);
            return $this->redirect(['parent-dashboard']);
        } else {
            Yii::$app->getSession()->setFlash('error', Yii::t('site', 'Incorrect username or password.'));
        }
    }
    return $this->render('parent-login', [
            'model' => $model,
        ]);
}

Your parentLogin model should extends User model to make all this work:

class parentLogin extends User
{
    public static function tableName()
    {
        //you parent users table name
        return 'parent_users';
    }

    public static function findByUsername($username)
    {
         return static::findOne(['p_username' => $username]);
    }
}

Now when you logged in, you need to handle identity switch, because in the configuration you have 'identityClass' => 'app\models\User'. We can use bootstrap property for that:

//in your config file
'bootstrap' => [
    'log',
    //component for switching identities
    'app\components\IdentitySwitcher'
],

IdentitySwitcher class:

class IdentitySwitcher extends Component implements BootstrapInterface
{
    public function bootstrap($app)
    {
        //we set this in parentLogin action
        //so if we loggin in as a parent user it will be true
        if ($app->session->get('isParent')) {
            $app->user->identityClass = 'app\models\ParentLogin';
        }
    }
}


Answered By - Tony
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to Extend Yii2-user dektrium profile model to be able to adding more fields

 June 26, 2022     yii2, yii2-basic-app, yii2-user     No comments   

Issue

I need to override the default Profile model. I have managed to add the fields i need but there is something i am missing since. On insert and update these fields are not getting update to the database.

I have created the necessary migrations so i have these fields in the database already

What am i missing> see below my app/models/Profile.php

<?php

namespace app\models;

/**
 * Description Profile
 *
 * This form @overrides dektrium\user\models\Profile
 */
use dektrium\user\models\Profile as BaseProfile;
use yii\web\UploadedFile;
use Yii;
use dektrium\user\models\User;

class Profile extends BaseProfile {

    /**
     * public variables to be added to the model
     */
    public $profile_pic;
    public $expertise_id;
    public $country_id;

    public function rules() {
        $rules = parent::rules();

        $rules['profile_pic'] = ['profile_pic', 'file'];
        $rules['expertise_id'] = ['expertise_id', 'integer'];
        $rules['country_id'] = ['country_id', 'integer'];



        return $rules;
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        $labels = parent::attributeLabels();
        $labels['profile_pic'] = \Yii::t('user', 'Profile Picture');
        $labels['bio'] = \Yii::t('user', 'Biography');
        $labels['expertise_id'] = \Yii::t('user', 'Expertise');
        $labels['country_id'] = \Yii::t('user', 'Country');
        return $labels;
    }




}

Solution

First thing, remove this lines:

public $profile_pic;
public $expertise_id;
public $country_id;

If you already added those fields in the table, you dont need to declare them. As you can see, none of the others properties are being declared either. This is already being done by extending the model from ActiveRecord and declaring the tableName



Answered By - Clyff
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, April 13, 2022

[FIXED] How fix the error 'Exception' when execute yii migrate?

 April 13, 2022     migration, php, yii-migrations, yii2, yii2-basic-app     No comments   

Issue

I try to run a yii2 basic project with docker in macOS BigSur. This is my docker-compose.yml:

version: '2'
services:
  php:
    image: yiisoftware/yii2-php:7.4-apache
    
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, March 19, 2022

[FIXED] Yii2; code running in "else" block first, and then running code before "if" block?

 March 19, 2022     if-statement, php, yii, yii2, yii2-basic-app     No comments   

Issue

I'm completely lost as to why this is happening, and it happens about 50% of the time.

I have a check to see if a user exists by email and last name, and if they do, run some code. If the user doesn't exist, then create the user, and then run some code.

I've done various testing with dummy data, and even if a user doesn't exist, it first creates them, but then runs the code in the "if" block.

Here's what I have.

if (User::existsByEmailAndLastName($params->email, $params->lastName)) {
    var_dump('user already exists');
} else {
    User::createNew($params);
    var_dump("Creating a new user...");
}

And here are the respective methods:

public static function existsByEmailAndLastName($email, $lastName) {
    return User::find()->where([
        'email' => $email,
    ])->andWhere([
        'last_name' => $lastName
    ])->one();
}


public static function createNew($params) {

    $user = new User;
    $user->first_name = $params->firstName;
    $user->last_name = $params->lastName;
    $user->email = $params->email;
    $user->address = $params->address;
    $user->address_2 = $params->address_2;
    $user->city = $params->city;
    $user->province = $params->province;
    $user->country = $params->country;
    $user->phone = $params->phone;
    $user->postal_code = $params->postal_code;

    return $user->insert();
}

I've tried flushing the cache. I've tried it with raw SQL queries using Yii::$app->db->createCommand(), but nothing seems to be working. I'm totally stumped.

Does anyone know why it would first create the user, and then do the check in the if statement?

Editing with controller code:

public function actionComplete() 
{

    if (Yii::$app->basket->isEmpty()) {
        return $this->redirect('basket', 302);
    }

    $guest = Yii::$app->request->get('guest');
    $params = new CompletePaymentForm;
    $post = Yii::$app->request->post();

    if ($this->userInfo || $guest) {

        if ($params->load($post) && $params->validate()) {

            if (!User::isEmailValid($params->email)) {
                throw new UserException('Please provide a valid email.');
            }

            if (!User::existsByEmailAndLastName($params->email, $params->lastName)) {
                User::createNew($params);
                echo "creating new user";
            } else {
                echo "user already exists";
            }

        }

        return $this->render('complete', [
            'model' => $completeDonationForm
        ]);

    }

    return $this->render('complete-login-or-guest');
}

Here's the answer after multiple tries:

Passing an 'ajaxParam' parameters with the ActiveForm widget to define the name of the GET parameter that will be sent if the request is an ajax request. I named my parameter "ajax".

Here's what the beginning of the ActiveForm looks like:

$form = ActiveForm::begin([
    'id' => 'complete-form',
    'ajaxParam' => 'ajax'
])

And then I added this check in my controller:

if (Yii::$app->request->get('ajax') || Yii::$app->request->isAjax) {
    return false;
}

It was an ajax issue, so thanks a bunch to Yupik for pointing me towards it (accepting his answer since it lead me here).


Solution

Add 'enableAjaxValidation' => false to your ActiveForm params in view. It happens because yii sends request to your action to validate this model, but it's not handled before your if statement.



Answered By - Yupik
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, March 12, 2022

[FIXED] All controllers return 404 of Cpanel excempt SiteController actionIndex

 March 12, 2022     yii, yii2, yii2-basic-app     No comments   

Issue

i upload all of my web folder to the root and then move all my project to inside a folder and fixed all the addresses in the main index.php

every thing works fine but i dont know for what reason this happens

this is 404 of Cpanel not me

But:

    class SiteController extends Controller
    {
           public function actionIndex()
    {
        return $this->render('index');
    }
    
  public function actionTest()
    {
        echo 'awdaw';
    }

|

but site index Works fine

enter image description here


Solution

i found the solution in my htaccess file in the end my .htaccess become this and it is ok right now

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^(www\.)?myaxagent\.com
RewriteRule ^(.*)$ https://www.mysitetesttest.com/$1 [R,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]


Answered By - noshad b.e
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, March 4, 2022

[FIXED] Error: getting unknown property: yii\web\Application::generateid

 March 04, 2022     yii, yii2, yii2-basic-app     No comments   

Issue

I have the below code in studentsController.php to add data to 2 tables from a form but im getting error. It is to add to students table, then add some data to the users table too. I feel i'm supposed to add something at the top via "use' keyword but I don't know.please help.

public function actionCreate() {
    $model = new model();
    $user = new Users();

    if ($model->load(Yii::$app->request->post())) {

        $model->id = Yii::$app->generateid->getGUID();  //this line caused the error
        $model->save();
        $studentId = $model->id;
        if($user->load(Yii::$app->request->post()))
        {
            $user->id = $model->id;
            $user->firstname = $model->firstname;
            $user->lastname = $model->lastname;
            $user->username = $model->phone;
            $user->password = 'pass123';   //default password
            $user->role = 'student';
            $user->save(false);
        }
        return $this->redirect(['view', 'id' => $model->id]);
    } else {
         return $this->render('create', [
             'model' => $model,
             'user' => $user,                 
         ]);
    }
}

Solution

You seem to miss generateid in your web.php It should be something like this

GenerateIDs.php inside @app/components folder

<?php 
namespace app\components; 

class GenerateIDs extends \yii\base\Component
{
    public function getGUID()
    {
       //do your stuff here
    }
    //....
}

then in your @app/config/web.php you have something like

<?php
return [
    'components' => [
        'generateid' => [
            'class'=>'app\components\GenerateIDs',
            // other configurations for the component
        ],
    ],
];

then you can use it in your app as you wish

public function actionCreate() {
$model = new model();
$user = new Users();

if ($model->load(Yii::$app->request->post())) {

    $model->id = Yii::$app->generateid->getGUID();  //this line caused the error
    $model->save();
    $studentId = $model->id;
    if($user->load(Yii::$app->request->post()))
    {
        $user->id = $model->id;
        $user->firstname = $model->firstname;
        $user->lastname = $model->lastname;
        $user->username = $model->phone;
        $user->password = 'pass123';   //default password
        $user->role = 'student';
        $user->save(false);
    }
    return $this->redirect(['view', 'id' => $model->id]);
} else {
    return $this->render('create', [
                'model' => $model,
                'user' => $user,                 
    ]);
}

Please take a look at Yii2 guide on Components



Answered By - Stefano Mtangoo
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, March 3, 2022

[FIXED] Yii 2 can rewrite WHERE condition from model?

 March 03, 2022     sql, yii, yii2, yii2-basic-app     No comments   

Issue

I have some where condition in my model . Its check is field active or no.

Now I need to write a join relation. But I need to remove where condition. Is it possible?

My model.

  ...
  public static function find() {
     return (new AssetgroupsQuery(get_called_class()))->active();
  }

My relation

public function getAssetgroup(): \app\models\AssetgroupsQuery {
    return $this->hasOne(Assetgroups::class, ['asg_id' => 'ass_group'])->andOnCondition(['asg_active' => '1'])
        ->viaTable('assets', ['ass_id' => 'log_ass_id',]);
}

I need to got all active assets and join, if asset is empty I need to got null fields, but model where condition added to my current sql query and remove all fields which assets are null. I try to add some where Condition to remove old where, but it don't work.

Can you help me?


Solution

You can reset existing conditions by using where(null).

On relation level:

public function getAssetgroup(): \app\models\AssetgroupsQuery {
    return $this->hasOne(Assetgroups::class, ['asg_id' => 'ass_group'])
        ->andOnCondition(['asg_active' => '1'])
        ->where(null)
        ->viaTable('assets', ['ass_id' => 'log_ass_id',]);
}

Or directly on join:

$query = MyModel::find()
    ->joinWith([
        'assetgroup' => function (ActiveQuery $query) {
            $query->where(null);
        },
    ])


Answered By - rob006
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, February 27, 2022

[FIXED] set default page for Forbidden (#403) when cant access in YII2

 February 27, 2022     yii, yii2, yii2-advanced-app, yii2-basic-app     No comments   

Issue

this is my behavior function in ShippingController :

 public function behaviors()
        {
        return [
            'access' => [
                'class' => \yii\filters\AccessControl::className(),
                'rules' => [
                    // deny all POST requests
//                        [
//                        'actions' => ['index', 'create'],
//                        'allow' => TRUE,
//                    ],
                        [
                        'actions' => ['index', 'create', 'init'],
                        'allow' => true,
                        'roles' => ['user2','user3'],
                        'denyCallback' => function()
                            {

                     redirect to address/index if user 2 cant access redirect to address/create if user3 cant access
                            //redirect here
                            }
                    ],
                // everything else is denied
                ],
            ],
        ];

        }

how to handle this problem !? i want redirect page to address/index if role :user2 cant access and redirect to address/create if role : user3 cant access


Solution

I assume you are using the RBAC system in yii. Check what config files for:

'authManager'  => [
    'class' => 'yii\rbac\DbManager',
],

or 'yii\rbac\PhpManager'.

Here is what worked for me:

'actions' => ['index', 'create', 'init'],
'allow' => false,
'roles' => ['user2','user3'],
'denyCallback' => function()
     {
        $user = Yii::$app->user;
        if ($user->can('user2')) {
           return Yii::$app->getResponse()->redirect(['/address/index']);
        } else {
           return Yii::$app->getResponse()->redirect(['/address/create']);
        }
     }

The 'allow' option of the rule should be set to false in order for denyCallback to be called. You can see that at "yiisoft/yii2/filters/AccessControl.php" line 120.



Answered By - Jannes Botis
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] how to show 2 form from same table in search

 February 27, 2022     yii, yii2, yii2-advanced-app, yii2-basic-app     No comments   

Issue

I want to ask, how to show 2 forms from the same table with a related table in yii2,

example

<?php
    $label1 = app\models\AppFieldConfigSearch::getLabelName(Location::tableName(), "Location");
    ?>
    <?= $form->field($model, 'id_location')->label($label1) ?>


    <?php
        $label1 = app\models\AppFieldConfigSearch::getLabelName(LocationUnit::tableName(), "label1");
    ?>
    <?= $form->field($model, 'label1')->label($label1) ?>

    <?php $dataListAssetMaster2 = ArrayHelper::map(Owner::find()->asArray()->all(), 'id_owner', 'name');
    echo $form->field($model, 'id_owner')->widget(Select2::classname(), [
        'data' => $dataListAssetMaster2,
        'pluginOptions' => [
            'allowClear' => true
        ],
        'options' => [
            'prompt' => 'Pilih Nama']
    ])->label("Name");
    ?>
    <?php $dataListAssetMaster4 = ArrayHelper::map(Location::find()->asArray()->all(), 'id_location', 'address');
    echo $form->field($model, 'id_location')->widget(Select2::classname(), [
        'data' => $dataListAssetMaster4,
        'pluginOptions' => [
            'allowClear' => true
        ],
        'options' => [
            'prompt' => 'Status Pembebasan']
    ])->label("location address");

// my search model

public function rules()
{
    return [
        [['id_location_unit', 'id_location', 'id_owner','id_mst_status1'], 'integer'],
        [['label1', 'label2', 'label3', 'keterangan1', 'keterangan2', 'keterangan3','address'], 'safe'],
    ];
}

I want to display the same 2 tables on 1 search form, but I have a problem when I use the code, one of the forms does not appear


Solution

You can combine 2 of your model/form into 1 search model. Let your search model decide on the search logic.



Answered By - Godzilla
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to upgrade Yii 1.x to Yii 2.0

 February 27, 2022     yii, yii-extensions, yii2, yii2-advanced-app, yii2-basic-app     No comments   

Issue

How to upgrade Yii 1.x version to Yii 2.0 latest release version? I am using ubuntu OS , Process to updating my old Yii to new Yii release version 2.0?


Solution

The Yii2 guide has excellent documentation in this regard see Upgrade from v1

I recently migrated couple of moderately complex applications from Yii 1.x to Yii 2.0. There are two ways to go about it , either you can run Yii 1.x and Yii 2 at the same time see using-yii-2-with-yii-1. Then migrate part by part, while it is possible it was quite bit of pain, like trying to rebuild the second floor while living on the third.

Alternatively you can rewrite the entire application bottom up with the exact same functionality, I found this to be much more efficient, significant code could be reused with only minor modifications, also that gave opportunity to tweak the design without changing functionality.

The important thing is to ensure the exposed API ( i.e. the frontend / UI / functionality) remains the same. It is always tempting to update functionality or change features during a rewrite, however if you stick to strictly reimplementing everything for Yii2 then consider changing your API, your migration will be smoother.



Answered By - Manquer
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, February 16, 2022

[FIXED] Create a new Controller manually and face with "View not Found" error in Yii

 February 16, 2022     yii, yii2, yii2-basic-app     No comments   

Issue

I use basic template of yii, i create a new controller manually in Controllers Folder and name it CountryController.php and put bellow codes in it.

<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;

class CountryController extends Controller
{
    public function actionIndex()
    {
        return $this->render('index');
    }
}

But when i type http://localhost/sites/basic/web/index.php?r=country%2Findex in browser i get following Exception:

View not Found yii\base\ViewNotFoundException

This is image of the error

On the other side when i type http://localhost/sites/basic/web/index.php?r=site%2Findexin the browser it renders index view correctly.

Why this happen? can i create a Controller manually? How?


Solution

The error message is not saying it can't find the page, just that it can't find the view file. Along with your controller, you should also have created a view file app\views\country\index.php This is the file you are referring to when you call `$this->render('index').



Answered By - Joe Miller
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, February 15, 2022

[FIXED] Yii2 list items inside a categories

 February 15, 2022     yii, yii2, yii2-basic-app     No comments   

Issue

My controller

public function actionIndex()
{
    $query = Documents::find();
    $docs = $query->orderBy('cate_id ASC')->all();
    return $this->render('index', [
        'docs' => $docs,
    ]);
}

My view

<?php foreach ($docs as $doc) {  
$cate = app\models\Categories::find()->where(['id'=>$doc->cate_id])->one();?>
    <h4><?=$cate->title?></h4>
    <p><?= Html::a($doc->title, ['documents/view', 'id'=>$doc->id]) ?></p>

<?php } ?>

With this my view look like

Category 1

  • Menu Item Title 1

Category 1

  • Menu Item Title 2

Category 2

  • Menu Item Title 3

I want it to display

Categories 1

  • Menu Item Title 1
  • Menu Item Title 2

Categories 2

  • Menu Item Title 3

Please help me with this.

Thank you!


Solution

For your task, use Yii ArrayHelper to solve this problem very easily.

Check this link http://www.yiiframework.com/doc-2.0/guide-helper-array.html

You can group the records according to a specific key/column by using ArrayHelper::index method.

In your case, you have to group the records with 'cate_id' (which refers your category id).

   //dont forget to import ArrayHelper before using it. 
   //use \yii\helpers\ArrayHelper.
   $catList = ArrayHelper::index($docs, null, 'cate_id');

Above code will produce grouped array. example....

   [
        1 =>[
              ['Menu Item Title 1','other column data','....'],
              ['Menu Item Title 2','other column data','....']
        ],
        2 =>[
              ['Menu Item Title 3','other column data','....'],
              ['Menu Item Title 4','other column data','....']
        ]

   ]

Now you iterate through this array/array object.

     <?php
     foreach($catList as $cate_id => $catItems)
     {
        $cate = app\models\Categories::find()->where(['id'=>$cate_id])->one();
        echo '<h4>'.$cate->title.'</h4>';
        foreach($catItems as $catItem)
        {

           echo '<p>'.Html::a($catItem['title'], ['documents/view', 'id'=>$catItem['id']]).'</p>';
        }

     }
     ?>

After getting some grip on Yii code, try to code in Yii way. That is, in this case, do not write queries in View.

You can use model relation to get the name of the category.



Answered By - Hearaman
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, February 10, 2022

[FIXED] how to use subquery inside select statement of yii2

 February 10, 2022     yii, yii2, yii2-advanced-app, yii2-basic-app, yii2-model     No comments   

Issue

I have a query as below.

 $subQuery = (new Query())->select('is_approved')->from('user_requests')->where(['user_ref_id' => yii::$app->user->id])->andWhere(['AND','project_ref_id = p.project_id']);

This is the subquery which I am trying to call in select statement as below

 $Query = (new Query())->select(['project_id','IF(p.project_type_ref_id = 2, '.$subQuery.', "" ) AS project_request_id'])
                             ->from('projects AS p');

If I try to execute the query I am getting below error in the line where I added $subQuery

PHP Recoverable Error – yii\base\ErrorException
Object of class yii\db\Query could not be converted to string

How to add a subquery in select statement. Please help. Thanks in advance !!


Solution

Since you want to use first query as pure string add

->createCommand()->rawSql;

to it. This generates SQL statement out of Query object.



Answered By - Bizley
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Yii 2 How add a custom validation check on file upload

 February 10, 2022     php, yii, yii-components, yii2, yii2-basic-app     No comments   

Issue

I am building a CSV uploader and I want to add a custom validation function that will check the header row of the CSV file to ensure the correct columns are in place.

I am trying to put a custom validation rule in the model to do this but failing at the first hurdle.

I am getting

Setting unknown property: yii\validators\FileValidator::0

exception but as far as I can tell from the documentation this should work.

Model

/**
* UploadForm is the model behind the upload form.
*/
class UploadForm extends Model
{
/**
 * @var UploadedFile file attribute
 */
public $file;

/**
 * @return array the validation rules.
 */
public function rules()
{
    return [
        [['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'headerCheck', 'skipOnEmpty' => false]
    ];
}

public function attributeLabels(){
    return [
        'file'=>'Select csv'
    ];
}

 function headerCheck($attribute, $params, $validato){

    $this->addError($attribute, "error");
}
}

Controller function:

     public function actionUpload()
{
    $model = new UploadForm();

    if (Yii::$app->request->isPost) {
        $model->file = UploadedFile::getInstance($model, 'file');
        $filename = $model->file->baseName . '.' . $model->file->extension;

        if ($model->file && $model->validate()) {
            $upload = $model->file->saveAs('uploads/'.$filename );

            if($upload){
                define('CSV_PATH','uploads/');
                $csv_file = CSV_PATH . $filename;
                $filecsv = file($csv_file);

                foreach($filecsv as $data){
                    $lines = explode(',',$data);
                    $t=1;
                }
            }
        }
    }

    return $this->render('csvUpload', ['model' => $model]);
}

View

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>

<?= $form->field($model, 'file')->fileInput() ?>

<button>Submit</button>

<?php ActiveForm::end() ?>

Why is headerCheck() not getting picked up as a custom validation function?


Solution

Short Answer

Your rules should be written like so:

return [
    [['file'], 'file', 'extensions' => 'csv', 'checkExtensionByMimeType'=>false, 'skipOnEmpty' => false],
    [["file"], "headerCheck"],
];

Note that your validation rule, "headerCheck", is a separate item in the array.

Long Answer

A rule's structure is like so:

[["attributes_to_validate"],"vaildatorCallback","param1"=>"value","param2"=>"value]

Note the first two items are the attributes and the callback respectively, and then after that you can specify params that should be assigned to the validator, or passed to your validator callback. These params are expected in a form where the key is the name of the property, and the value is the value to assign to the property.

In the example you provided, Yii sees that you want to utilize the "file" validator, so it creates an instance of yii\validators\FileValidator. It then sees that you want the parameter "extensions" set to "csv", so it does:yii\validators\FileValidator::$extensions = "csv"; But then, because you have included your custom validator in this part of the array, it thinks that "headerCheck" is actually a value of a property you want to assign to the validator. Because you have entered this "param" without a key, the key defaults to 0 and so Yii thinks the property you want to assign is called '0'. Thus, Yii attempts this: yii\validators\FileValidator::0 = "headerCheck";

Of course, there is no property '0' on FileValidator, and so that's where the error you're getting is coming from.



Answered By - ethan
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, February 8, 2022

[FIXED] Yii2: Preventing a specific CSS file from getting loaded

 February 08, 2022     php, yii, yii2, yii2-basic-app     No comments   

Issue

I need to stop loading the bootstrap.css file in one view to void duplicate. But I don't know how to do that in Yii2.

I used this function in Yii 1:

Yii::app()->clientScript->scriptMap = array(
    'main.css' => false
);

Solution

If you need to disable the CSS specific to core bootstrap in a view then add the following on top of your view file like this

Yii::$app->assetManager->bundles['yii\bootstrap\BootstrapAsset'] = false;

and if you need to disable the bootstrap core js sources also then use

Yii::$app->assetManager->bundles['yii\bootstrap\BootstrapPluginAsset'] = false;


Answered By - Muhammad Omer Aslam
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, January 2, 2022

[FIXED] How to get value of attribute in controller from Form in view Yii 2

 January 02, 2022     mysql, php, yii, yii2, yii2-basic-app     No comments   

Issue

I created a table named (users) it has two columns: name and pass. In view I created form like this:

<?php
$form = ActiveForm::begin() ?>

<div class="form-group">
  <?= $form->field($model, 'user') ?>
  <?= $form->field($model, 'password') ?>
    <div class="col-lg-offset-1 col-lg-11">
        <?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
    </div>
</div>
<?php ActiveForm::end() ?>

So I need to pass this two attributes to controller to insert into data base.


Solution

In YourController.php
assuing you have an Create action for manage your insert in db and a create view for manage the user input (a view for only display the correct result )

    <?php

    namespace app\controllers;

    use Yii;
    use yii\web\Controller;
    use app\models\EntryForm;

    class YourController extends Controller
    {
        // ...existing code...

        public function actionCreate()
        {
            $model = new User();

            if ($model->load(Yii::$app->request->post()) && $model->validate()) {
                // valid data received in $model

                // 
                if( $model->save()){
                    return $this->render('create', ['model' => $model]);
                } else {
                    // this is just for debug  
                    var_dump('not inserted');
                    die();
                }

            } else {
                // either the page is initially displayed or there is some validation error
                return $this->render('view', ['model' => $model]);
            }


        // render the initial page per allow to the user input 
        return $this->render('create', ['model' => $model]);
       }  

       ....
   }


Answered By - ScaisEdge
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Get Parametrs from Url to Yii2 model

 January 02, 2022     yii, yii2, yii2-basic-app     No comments   

Issue

I have issue with getting parameter from URL to my Yii2 Model.

URL : https://example.com/?key=test&id=1234

My code is :

public function save()
    {
        $httpClient = new Client();
        $keyword = Yii::$app->getRequest()->getQueryParam('key');
        $data = [
            'civilite'     => $this->civility,
            'nom'          => $this->lastName,
            'prenom'       => $this->firstName,
            'telephone'    => $this->phoneNumber,
            'email'        => $this->emailAddress,
            'operateur'    => $this->operator,
            'tel_domicile' => $this->phone,
            'keyword' => $keyword,
        ];

        $preferences = explode(',', $this->preferences);
        $index = 0;
        foreach ($preferences as $preference) {
            $index++;
            $data['attente' . $index] = $preference;
        }

        LeadLogHelper::log($data);
        $rawResponse = $httpClient->createRequest()
            ->setMethod('POST')
            ->setUrl(\Yii::$app->params['leadWebserviceUrl'])
            ->setData($data)
            ->send();
        $response = json_decode($rawResponse->content);

        if (!$response->Statut) {
            Yii::error('An error occurred while saving the data using the webservice', __METHOD__);
            Yii::error($data, __METHOD__);
            Yii::error($response, __METHOD__);
        }
        return $response->Statut == 1 || $response->Message === 'La Fiche existe déjà.';

    }

The Save function work, but with a null value for $Keyword, please Help!!


Solution

Depend on your query link like: https://example.com/?key=test&id=1234

At the time when you call $model->save() method, special for this particular model you can pass an additional parameter as $key like this:

Method 1

//action controller
//Your model
 $model->save(\Yii::$app->request->get('key'))

Here is the model:

public function save($key = '')
    {
        $httpClient = new Client();
        $data = [
            'civilite'     => $this->civility,
            'nom'          => $this->lastName,
            'prenom'       => $this->firstName,
            'telephone'    => $this->phoneNumber,
            'email'        => $this->emailAddress,
            'operateur'    => $this->operator,
            'tel_domicile' => $this->phone,
            'keyword' => $key, // Or use if statement to include this value or not
        ];
        ...
    }

But it is safe to use model properties like this:

Method 2

//define a property
class YOUR_MODEL extends Model {
    ...
    public $key;
    ...
    public function rules()
    {
        return [
            ...
            [['key'], 'safe'],
            ...
        ];
    }
}

Then you can use this in controller:

$model->key = \Yii::$app->request->get('key');

In your model make changes:

public function save()
    {
        $httpClient = new Client();
        $data = [
            'civilite'     => $this->civility,
            'nom'          => $this->lastName,
            'prenom'       => $this->firstName,
            'telephone'    => $this->phoneNumber,
            'email'        => $this->emailAddress,
            'operateur'    => $this->operator,
            'tel_domicile' => $this->phone,
            'keyword' => $this->key
        ];

        ...
    }

And after that call $model->save() method.

Hope this helps.



Answered By - Serghei Leonenco
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, December 30, 2021

[FIXED] yii2 I want to allow only index action

 December 30, 2021     yii, yii2-advanced-app, yii2-basic-app     No comments   

Issue

I have tried to allow only index action by using this behaviors() function right now it's denied index also

Can anyone solve and explain the rules return.

<?php

namespace api\modules\v1\controllers;

use yii\rest\ActiveController;
use yii\filters\AccessControl;

/**
 * Doctor Controller API
 */
class DoctorController extends ActiveController
{
    public $modelClass = 'api\modules\v1\models\Doctor';

    public function behaviors()
    {
        return [
            'access' => [
                'class' => \yii\filters\AccessControl::className(),
                'only' => ['index'],
                'rules' => [
                    [
                        'allow' => false,
                        'verbs' => ['POST']
                    ],
                    [
                        'allow' => true,
                        'actions' => ['index'],
                        'verbs' => ['GET'],
                        'roles' => ['?'],
                    ],
                    [
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                    // everything else is denied
                ],
            ],
        ];
    }
}

Solution

I figured it out after reading the documents

by overwriting the original access behaviors it will decide anything not mentioned as allowed.

so, you will need only one rule of allowing an action without mantioing verbs nor roles, but you may if you want to restrict it more.

<?php

namespace api\modules\v1\controllers;

use Yii;
use api\modules\v1\models\Doctor;
use yii\rest\ActiveController;

/**
 * Doctor Controller API
 */
class DoctorController extends ActiveController
{
    public $modelClass = 'api\modules\v1\models\Doctor';

    public function behaviors()
    {

        $behaviors = parent::behaviors();

        $behaviors['access'] = [
            'class' => \yii\filters\AccessControl::className(),
            'rules' => [
                [
                    // All actions
                    'allow' => true,
                    'actions' => ['index'],
                ],
            ],
        ];

        return $behaviors;
    }

}


Answered By - Mansour Alnasser
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing