yii's 404 error page directs to custom default page - yii

i always get the default page, my default custom page, but it doesn't go to my 404 page... and main config is directing to site/error. And the below is my site/error. What else am I missing?
public function actionError()
{
$this->layout = '/layouts/main';
$error = Yii::app()->errorHandler->error->code;
if(404==Yii::app()->errorHandler->error->code){
$this->render('404');
}
else
$this->render('error', array('error'=>$error));
}

public function actionError() {
$this->layout = '/layouts/main';
$error=Yii::app()->errorHandler->error;
if($error['code'] == 404)
$this->render('404');
else
$this->render('error', array('error'=>$error));
}
Yii::app()->errorHandler->error returns an array with details.. check documentation here..
http://www.yiiframework.com/doc/api/1.1/CErrorHandler#error-detail

Related

How to load a template file from my admin controller in custom module in prestashop

How to load a template file from my admin controller in custom module in prestashop 1.6
if (!defined('_PS_VERSION_')) exit;
class QueryAllTrxController extends ModuleAdminController
{
public $module;
public function __construct()
{
parent::__construct();
}
public function initContent()
{
parent::initContent();
$this->setTemplate('display.tpl');
//$this->setTemplate(_PS_THEME_DIR_.'mypage.tpl');
}
}
I had the same problem and it took forever to figure out.
I ended up spotting the solution in this video : https://www.youtube.com/watch?v=CdnJpLqqvcM
Any this is how I got it to work :
1 - Create the controller in ModuleName/controllers/AdminMyControllerNameController.php
class AdminMyControllerNameController extends ModuleAdminController
{
public function __construct()
{
$this->display = 'view';
$this->meta_title = $this->l('metatitle');
$this->toolbar_title = $this->l('tollbartitle');
parent::__construct();
}
public function initContent()
{
$this->show_toolbar = true;
$this->display = 'view';
$this->meta_title = $this->l('META TITLE');
parent::initContent();
$this->setTemplate('templatename.tpl');
}
public function initToolBarTitle()
{
$this->toolbar_title = $this->l('TOOLBAR TITLE??');
}
public function initToolBar()
{
return true;
}
}
2 - Create the template file in ModuleName/views/admin/my_controller_name/template.tpl
You have to create a directory in the views/admin folder using the name of your controller written in snake case.
Anyway I hope this will help.
WORKING CODE HERE
Background:
You want to add a custom admin page with a custom module controller. But you cannot customize template because you're stuck with this error message:
Fatal error: Uncaught --> Smarty: Unable to load template file '/var/www/html/admin-dev/themes/default/template/catalog/index.tpl' <-- thrown in /var/www/html/tools/smarty/sysplugins/smarty_internal_templatebase.php on line 129
Your current source code is:
class AdminYourModuleNameProductsController extends ModuleAdminController {
public function initContent() {
parent::initContent();
// enable these lines if you're stuck with damn stupid blank page with just 500 error
// ini_set('display_errors', '1');
// ini_set('display_startup_errors', '1');
// error_reporting(E_ALL);
$this->setTemplate('products/index.tpl');
}
}
And you don't know what to do because PrestaShop dev doc is the worst document in the history of ecommerce platform developer document and moreover its forum is full of chitchats and junks.
Solution
Place index.tpl at
{%PRESTA_ROOT%}/modules/{%YOUR MODULE DIR%}/views/templates/admin/{% snake case version of controller %}/products/index.tpl
For example, if your module name is yourmodulename and the controller name is AdminYourModuleNameProductsController (as in the example), the correct path is:
{%PRESTA_ROOT%}/modules/yourmodulename/views/templates/admin/your_module_name_products/products/index.tpl
If the error still persists:
Check this line:
{%PRESTA_ROOT%}/classes/controller/ModuleAdminController.php
public function createTemplate($tpl_name)
{
if (file_exists(_PS_THEME_DIR_.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name) && $this->viewAccess()) {
// echo the following line and exit
return $this->context->smarty->createTemplate(_PS_THEME_DIR_.'modules/'.$this->module->name.'/views/templates/admin/'.$tpl_name, $this->context->smarty);
} elseif (file_exists($this->getTemplatePath().$this->override_folder.$tpl_name) && $this->viewAccess()) {
// echo the following line and exit
return $this->context->smarty->createTemplate($this->getTemplatePath().$this->override_folder.$tpl_name, $this->context->smarty);
}
// the error occurs because php get reach to the following line:
return parent::createTemplate($tpl_name);
}
Do as I commented and you can get the correct file path. Make sure the file exists in the path.
My PrestaShop version is 1.6.1.24
The code $this->setTemplate('display.tpl'); is loading a template file modules/your-custom-module/views/templates/admin/display.tpl or modules/your-custom-module/display.tpl.
The classname must be named that way: AdminQueryAllTrxController
you can put display.tpl in :
modules\module_name\views\templates\admin\classe_name(QueryAllTrx)
and use :$this->setTemplate('display.tpl'); in your AdminQueryAllTrxController
First of all add controller to your module:
modules\module_name\controllers\admin\SomeNameController.php
and extend it by ModuleAdminController, you need at least two methods for it to work properly __construct and initContent
put the following code to the later method:
$this->content .= $this->context->smarty->fetch($this->pathToTpl);
$this->context->smarty->assign(array(
'content' => $this->content,
));
You could replace $this->pathToTpl with any path which is pointed to your tpl file, I'm prefer to create the path dynamically. You can see a simple example here:
class SomeNameController extends ModuleAdminController{
var $pathToTpl;
public function __construct()
{
$this->bootstrap = true;
$this->context = Context::getContext();
$this->pathToTpl = _PS_MODULE_DIR_ .
$this->module->name . // put the name of module
'/views/templates/admin' .
'/' .
'templateName.tpl';
parent::__construct();
}
public function initContent()
{
parent::initContent();
$this->content .= $this->context->smarty->fetch($this->pathToTpl);
$this->context->smarty->assign(array(
'content' => $this->content,
));
}
}
finally you need to place templateName.tpl in the path you wanted to be:
modules\module_name\views\templates\admin\templateName.tpl

how can I redirect login page if do not login in yii framework?

I have the actionLogin and create cookie like here :
public function actionLogin()
{
$this->layout = 'login';
$model=new LoginForm;
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
if($model->validate() && $model->login()){
$cookie = new CHttpCookie('loginSuccess',$model->username);
$cookie->expire = 604800;
Yii::app()->request->cookies['loginSuccess'] = $cookie;
$this->redirect('/ktbeauty/index.php/categories/index');
}
}
$this->render('login',array(
'model'=>$model,
));
}
And Now I have some controllers which must check to login before access controllers, if not login, it must redirect to login page, how can I work for this ?
thankyou very much
in the action of your controller you can try something like this
public function actionGoToLogin()
{
if(!Yii::app()->user->isGuest)
{
// do something if user is authenticated
}
else
{
Yii::app()->user->loginRequired();
// or if you want you can redirect using Yii::app()->createUrl('controller/login');
}
}
In Controller, you have a function as below:
public function accessRules() {
Here you can define the actions and users who can access those functions.
If you are not logged in, then it'll redirected to login page by default.
This feature available by default in YII.
check this URL:
http://www.yiiframework.com/wiki/169/configuring-controller-access-rules-to-default-deny/

How change the url query in the controller

I want to change the address of the page requested from the controller.
For example: when prompted site / edit return site/edit/12
where 12 - is a number of model.
Of course I can use the redirect, but can be a way to do it is not use a redirect.
My snippet:
public function actionEdit($id = null){
if(!$id){
$model = Portfolio::model()->createEmpty();
$this->redirect('site/edit'.$model->id);// I think that redirect is bad
Yii::app()->end();
}
// ... etc logic
}
public function actionEdit($id = 0){
if($id == 0){
$this->redirect('/site/edit/12');
exit();
}
}
OR
public function actionEdit($id = 0){
if($id == 0){
$id = 12;
}
}
You should do it with an array :
$this->redirect(array('site/edit','id'=>$model->id));
if you want to hide the 'id' in your url, add a url rule in your config file.

Filter in Yii is not returning

I am trying to user filters in YII.
here is my code.
public function filters()
{
return array(
'provideronly +uploadclients,fileview,editprofile,getinvitedusers',
);
}
public function filterProvideronly($filterchain)
{
if(Yii::app()->user->providerId==-1)
{
$this->redirect(array('site/error','id'=>403,'message'=>'You are unauthorized to view this page'));
return false;
}
return true;
}
When the user is unauthorized to use the controller it is redirecting to error page. but when the user is authorized , it is showing a blank page..
what is wrong in this code ?
Instead of return true you need to put $filterChain->run(); so yii can see that the filter ended.

How to set default action dynamically in Yii

i want to change default action of a controller depends on which user is logged in.
Ex. There are two users in my site : publisher and author and i want to set publisher action as default action when a publisher is logged in, and same for author.
what should i do? when can I check my roles and set their relevant actions?
Another way to do this would be setting the defaultAction property in your controller's init() method. Somewhat like this:
<?php
class MyAwesomeController extends Controller{ // or extends CController depending on your code
public function init(){
parent::init(); // no need for this call if you don't have anything in your parent init()
if(array_key_exists('RolePublisher', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='publisher'; // name of your action
else if (array_key_exists('RoleAuthor', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='author'; // name of your action
}
// ... rest of your code
}
?>
Check out CAuthManager's getRoles(), to see that the returned array will have format of 'role'=>CAuthItem object, which is why i'm checking with array_key_exists().
Incase you don't know, the action name will be only the name without the action part, for example if you have public function actionPublisher(){...} then action name should be: publisher.
Another, simpler, thing you can do is keep the default action the same, but that default action simply calls an additional action function depending on what kind of user is logged in. So for example you have the indexAction function conditionally calling this->userAction or this->publisherAction depending on the check for who is logged in.
I think you can save "first user page" in user table. And when a user is authenticated, you can load this page from database. Where you can do this? I think best place is UserIdentity class. After that, you could get this value in SiteController::actionLogin();
You can get or set "first page" value:
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
This is a complete class:
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array('username' => $this->username));
if ($user === null) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} else if ($user->password !== $user->encrypt($this->password)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} else {
$this->_id = $user->id;
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
/**
* Displays the login page
*/
public function actionLogin()
{
$model = new LoginForm;
// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if ($model->validate() && $model->login())
$this->redirect(Yii::app()->user->first_page);
}
// display the login form
$this->render('login', array('model' => $model));
}
Also, you can just write right code only in this file. In SiteController file.