how to handle errors in yii - exception

I am working on an application using yii. I have an action let acmanageappointments/index. I have defined its rule as follow
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('index','create','update','delete','updatestatus'),
'users'=>array('#'),
and its action is as follow :
public function actionIndex()
{
$user_id = Yii::app()->user->getId();
$criteria = new CDbCriteria();
$criteria->condition = 'user_id='.$user_id;
$count=AcAppointments::model()->count($criteria);
$pages=new CPagination($count);
//results per page
$pages->pageSize=10;
$pages->applyLimit($criteria);
$AllAppointments = AcAppointments::model()->findAll($criteria);
// Applying Global Date Time Format
$condition = array('user_id' => $user_id);
$DTFormat = CalendarSettings::model()->findByAttributes($condition);
$this->render('index',array(
'AllAppointments' => $AllAppointments,
'pages' => $pages,
'DTFormat' => $DTFormat,
));
}
This action can only be accessed with authenticated persons. when I am logged in then this function is working properly. but when I am logged out and executing this action then it gives CDbException. How can I handle this exception, and when the user is logged out and if he is trying to access this url then he should be redirected on login page . How can I do this ?
update : Here is my accessrules :
public function accessRules()
{
return array(
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('index','create','update','delete','updatestatus'),
'users'=>array('#'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
and here is the error :
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

As topher mentioned in comments, you need a filters method.
Make sure you have this in your controller, else your access rules will do nothing:
public function filters()
{
return array(
'accessControl',
);
}
If it works, give his answer credit when he updates it with this snippet.

You need to define another rule that will ensure that non-authenticated users are denied access. This must be the last rule.
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('index','create','update','delete','updatestatus'),
'users'=>array('#'),
),
array('deny',
'users'=>array('*'),
),

You can have an errorHandler setting in your config file "main.php"
'components'=>array(
...............
...............
'errorHandler'=>array(
// use 'site/error' action to display errors
'errorAction'=>'site/error',
),
...............
...............
)
this will redirect all the exceptions to the provided URL site/error in this case.

Check value $user_id. if you are not logged in, you get empty $user_id
$user_id = Yii::app()->user->getId();
$criteria = new CDbCriteria();
$criteria->condition = 'user_id='.$user_id;
When you execute with this criteria you got SQL error

Related

Laravel: Store error messages in database

Any one know how to send error messages to database in laravel which generate from app/exceptions/handler.php ?
I need to send what error massages generated in report() method to database.
If you are interested doing this manually, you can do something as following.
Step 1 -
Create a model to store errors that has a DB structure as following.
class Error extends Model
{
protected $fillable = ['user_id' , 'code' , 'file' , 'line' , 'message' , 'trace' ];
}
Step 2
Locate the App/Exceptions/Handler.php file, include Auth, and the Error model you created. and replace the report function with the following code.
public function report(Exception $exception) {
// Checks if a user has logged in to the system, so the error will be recorded with the user id
$userId = 0;
if (Auth::user()) {
$userId = Auth::user()->id;
}
$data = array(
'user_id' => $userId,
'code' => $exception->getCode(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $exception->getMessage(),
'trace' => $exception->getTraceAsString(),
);
Error::create($data);
parent::report($exception);
}
(I am demonstrating this using laravel 5.6)
Because Laravel uses Monolog for handling logging it seems that writing Monolog Handler would be the cleanest way.
I was able to find something that exists already, please have a look at monolog-mysql package. I did not use it, so I don't know whether it works and if it works well, but it's definitely good starting point.

Token cannot be null on the instantiation of the Product Query Builder. / Query Akeneo 2

I would like to create a command akeneo into my bundle who query my products like this.
So, after multiple test, i have always this error:
In ProductQueryBuilderFactory.php line 68:
Token cannot be null on the instantiation of the Product Query
Builder.
Here is my code :
$pqbFactory = $this->getApplication()->getKernel()->getContainer()->get('pim_catalog.query.product_query_builder_factory');
$pqb = $pqbFactory->create(['default_locale' => 'fr_FR', 'default_scope' => 'ecommerce']); // error
To complete Julien's answer, note that this error comes only if you are using the Enterprise Edition (EE). Indeed, in the EE, we decorate the normal product_query_builder_factory to apply permission.
If you don't want to apply permission (and don't use any token), you can use the pim_catalog.query.product_query_builder_factory_without_permission:
<?php
require __DIR__.'/vendor/autoload.php';
$kernel = new AppKernel('dev', true);
$kernel->boot();
$pqbFactory = $kernel->getContainer()->get('pim_catalog.query.product_query_builder_factory_without_permission');
$pqb = $pqbFactory->create(['default_locale' => 'fr_FR', 'default_scope' => 'ecommerce']); // you won't have any error
The PQB needs to have an authenticated user to be able to apply right filters on the results. To authenticate a user in your command you can take inspiration from the get product command. We simply take a --username argument and manually add it to the token storage.
$userManager = $this->getContainer()->get('pim_user.manager');
$user = $userManager->findUserByUsername($username);
if (null === $user) {
$output->writeln(sprintf('<error>Username "%s" is unknown<error>', $username));
return false;
}
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->getTokenStorage()->setToken($token);

Can't catch my mysql errors

I am using codeigniter for my server side in php.
I set my email field UNIQUE on my Users table.
The problem is that whatever I tried I can't catch the error mysql generated when trying to insert a duplicate email.
What i tried inside my model:
function insert($arr) {
$query= $this->CI->db->insert('user', $arr);
if($query){
return $this->CI->db->insert_id();
} else {
$msg = $this->CI-db->_error_message();
return $msg;
}
}
The issues goes that everything is fine until I get a duplicate and I actually get NOTHING inside the $msg. I know debug is on from the database config file.
If your database config 'db_debug' => TRUE, your code will exit with showing the error message and you will not able to reach this line $msg = $this->CI-db->_error_message();.
So to catch the error message you need to set the.
db_debug' => FALSE
At CI-2 your above code will work.See more at this question
But At CI-3 those function is not available and it will produce php undefined method error. CI-3 has a method display_error. You can check it.
My solution: If you want the errors you can get it using this line
$msg = $this->db->conn_id->error_list;
This will give you the error lists as array.But remember you need to set db_debug' => FALSE

RBAC in Yii2 with PhpManager

How can I implement RBAC in Yii 2.0 without any database.
I will have just 2 roles , i.e. admin and author .
my RbacController is
<?php
namespace app\commands;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
public function actionInit()
{
$auth = \Yii::$app->authManager;
// add "createPost" permission
$createPost = $auth->createPermission('createPost');
$createPost->description = 'Create a post';
$auth->add($createPost);
// add "updatePost" permission
$updatePost = $auth->createPermission('updatePost');
$updatePost->description = 'Update post';
$auth->add($updatePost);
// add "author" role and give this role the "createPost" permission
$author = $auth->createRole('author');
$auth->add($author);
$auth->addChild($author, $createPost);
// add "admin" role and give this role the "updatePost" permission
// as well as the permissions of the "author" role
$admin = $auth->createRole('admin');
$auth->add($admin);
$auth->addChild($admin, $updatePost);
$auth->addChild($admin, $author);
// Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()
// usually implemented in your User model.
$auth->assign($author, 2);
$auth->assign($admin, 1);
}
}
I am getting an error
`PHP Fatal error: Call to a member function createPermission()
on a non-object in var/www/commands/RbacController.php on line 14
PHP Fatal Error 'yii\base\ErrorException' with message 'Call to a member
function createPermission() on a non-object' in /var/www/commands/RbacController.php:14
while executing yii rbac/init . I am using basic template with PhpManager . I have added 'authManager' => [ 'class' => 'yii\rbac\PhpManager', ], in web.php .I am using basic template.
i Know this is a bit old, but I want to publish the solution.. at least what worked for me.
I have added 'authManager' => [ 'class' => 'yii\rbac\PhpManager', ],
in web.php
There is the mistake, since you a re running the command via console, you need to add that same line in the components section of console.php (in the same directory as web.php).
I hope this helps others who have a similar problem :D
The official documentation actually uses a php file https://github.com/yiisoft/yii2/blob/master/docs/guide/security-authorization.md
try this in your controller
$auth = new \yii\rbac\PhpManager();
// add "createPost" permission
$createPost = $auth->createPermission('createPost');
$createPost->description = 'Create a post';
$auth->add($createPost);
http://blog.dedikisme.com/blog/2014/05/09/rpbac-yii2-framework

How to update the changed username in session variable without logout or session destroy

Question:
How to update the changed username in session variable without logout or session destroy ?
For Example:
I am login with username "Ram" and this username storing in session variable User_Name,after logged in i am changing my username "Ram" into "Kumar". So this newly changed username should get updated in session variable User_Name automatically without logout from my account.
Sample Controller Code for Login:
function check_database($password)
{
// Field validation succeeded. Validate against database
$username = $this->input->post('username');
// query the database
$result = $this->civic_soft_model->login($username, $password);
if($result)
{
$sess_array = array();
foreach($result as $row)
{
$sess_array = array(
'UID' => $row->UID,
'User_Name' => $row->User_Name,
'User_Type' => $row->User_Type,
'User_OTP' => $row->User_OTP
// 'Login_Status' => $row->Login_Status
// 'Node_Id' => $row->Node_Id
);
$this->session->set_userdata('logged_in', $sess_array);
}
return TRUE;
}
else
{
$this->form_validation->set_message('check_database', 'Invalid username or password');
return false;
}
}
NOTE:
I am using PHP,MySQL and CodeIgniter MVC Framework.
Please Help Me Friends...
I actually see what the problem is now. You are setting 'logged_in' to be an array. Not sure if that's common, but what I usually do is set 'logged_in' as a boolean and I set userdata the data that I need in another array.
However, for you case you can try this:
$newUserData = $this->session->userdata('logged_in');
if (is_array($newUserData)) {
$newUserData['User_Name'] = $new_username;
$this->session->set_userdata('logged_in', $newUserData);
}
For better usability, I would addd a function to $this->civic_soft_model called "updateUser" or something of that nature. And when that function is called, you can update all of the session data that you need to.
Insert this function to your controller and call it whenever there is an update made on the users information.
//$new_username : the username inputted by user when he is trying to update his account
function update_session($new_username){
$this->session->set_userdata('User_Name', $new_username);
}