I'm facing issue of "Class hash does not exist". I know there are same question related this but these are not enough for me. Here I'm loading routes as per user device. As per mobile I using different routes as shown below:
Route::group(['middleware' => ['web']], function () {
if(SiteHelpers::isMobileViewEnabled() == true && Mobile::isMobile() == true && Mobile::isTablet() == false){
require app_path('Http/Routes/mui.php');
}else{
require app_path('Http/Routes/desktop.php');
}
...
Here is SiteHelper code
public static function isMobileViewEnabled()
{
$isEnabled = false;
$user = Auth::user();
$getEnabled = DB::table('setting')->where('setting_name', 'Mobile UI')->first();
if(isset($getEnabled) && $getEnabled->setting_value==1){
$isEnabled = true;
}
return $isEnabled;
}
When I use
Auth::user()
Than I'm getting error
Class hash does not exist
I don't know whats going wrong, Please let me know where I making mistake.
You seem to have the required provider there in the list. Try clearing services cache file
This is not the answer for your question but I think it will create issue for you later on so,replace this
if(!is_null($getEnabled) && $getEnabled->setting_value==1){
$isEnabled = true;
}
with
if(isset($getEnabled) && $getEnabled->setting_value==1){
$isEnabled = true;
}
Because $getEnabled is always set.
Related
First of all, I'm quite new to Magento 2, but I've used Magento 1.x for some time.
I've read a lot about how to solve DI-related problems, but I'm stuck on this one:
Exception #0 (Exception): Recoverable Error: Argument 1 passed to Cefar\AO\Helper\Ao::__construct() must be an instance of Magento\Framework\App\Helper\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in .../vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 and defined in .../Cefar/AO/Helper/Ao.php on line 11
Many other answers have suggested deleting the var/di and var/generation folders, sometimes var/cache also. While this solves the problem, it occurs again once bin/magento setup:di:compile is run, which means the code cannot be used in a production environment.
I've checked that the Ao class does not instantiate any objects. It also doesn't try to re-make any objects that could be provided by the context given. Here's the code:
namespace Cefar\AO\Helper;
class Ao extends \Magento\Framework\App\Helper\AbstractHelper
{
const DEFAULT_GRID_COLS = 4;
protected $_session;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Customer\Model\Session $session
)
{
parent::__construct($context);
$this->_session = $session;
}
public function getConfig($path)
{
return $this->scopeConfig->getValue($path);
}
public function isActive($url = null, $print = true) {
$active = ($url && strstr($_SERVER['REQUEST_URI'], $url) !== false);
if ($active && $print) {
echo "active";
} else {
return $active;
}
}
public function isLoggedIn()
{
return $this->_session->isLoggedIn();
}
public function limitWords($text = '', $limit = 10, $showDots = true)
{
$words = explode(' ', $text);
$limited = array_slice($words, 0, $limit);
$newText = implode(' ', $limited);
if (count($words) > $limit && $showDots) {
$newText .= '...';
}
return $newText;
}
public function getCurrentGrid()
{
return ($this->_getRequest()->getParam('grid'))
? $this->_getRequest()->getParam('grid')
: self::DEFAULT_GRID_COLS;
}
}
There's nothing particularly special here. I'm confused as to how this is even happening; every other defined class in the extension is getting its DI parameters correctly. Why is the ObjectManager apparatus providing an unwanted argument? The relevant call is given in the error report as:
.../vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php(93): Cefar\AO\Helper\Ao->__construct(Object(Magento\Framework\ObjectManager\ObjectManager))
So it isn't even providing two arguments!
I've also read about providing type hints in a di.xml, but it doesn't seem to be relevant here as both types are part of the Magento libraries? I note that there is an entry for Magento\Framework\App\Helper\Context but not one for Magento\Customer\Model\Session... but that there are framework classes that use ID to import Magento\Customer\Model\Session already which work.
Long story short, this was because of a typo.
Sometimes when the helper was being included, it was being referred to as Cefar\AO\Helper\Ao, and other times, Cefar\AO\Helper\AO. Essentially, the ObjectManager was resolving both of these references to the same class, but it only had type hints for one of the names so it didn't know what to provide to the incorrect one.
A little help would have been nice, Magento! Maybe an error report that the requested class wasn't found? Still, at least this is finally over with.
I use codeigniter 3 for my project, and I want to use redis to store session
to use it with nodejs and mysql for real-time notification system
i installed redis on my server and test it with nodejs is work good
I don't know if you are still looking for the answer(would help others too) but here's a good link (https://simplapi.wordpress.com/2012/04/13/php-and-node-js-session-share-redi/)
that explains serializing and de-serializing session data as json. I have done modification in Codeigniter's library Session_redis_driver.php to encode and decode so I can use it in Nodejs. I'd be glad if someone can validate this code and point any pitfalls or unhandled exceptions.
Modification in "read" method
public function read($session_id)
{
if (isset($this->_redis) && $this->_get_lock($session_id))
{
// Needed by write() to detect session_regenerate_id() calls
$this->_session_id = $session_id;
$session_data = json_decode($this->_redis->get($this->_key_prefix.$session_id),TRUE);
is_array($session_data)
? $this->_key_exists = TRUE
: $session_data = '';
$this->_fingerprint = md5(json_encode($session_data));
$tmp = $_SESSION;
$_SESSION = $session_data;
$new_data = session_encode();
$_SESSION = $tmp;
return $new_data;
}
return $this->_fail();
}
So far this is working without exceptions.
In write method the following changes have been done.
if (isset($this->_lock_key))
{
$this->_redis->setTimeout($this->_lock_key, 300);
$tmp = $_SESSION;
session_decode($session_data);
$new_data = $_SESSION;
$_SESSION = $tmp;
if ($this->_fingerprint !== ($fingerprint = md5(json_encode($new_data))) OR $this->_key_exists === FALSE)
{
if ($this->_redis->set($this->_key_prefix.$session_id, json_encode($new_data), $this->_config['expiration']))
{
$this->_fingerprint = $fingerprint;
$this->_key_exists = TRUE;
return $this->_success;
}
return $this->_fail();
}
return ($this->_redis->setTimeout($this->_key_prefix.$session_id, $this->_config['expiration']))
? $this->_success
: $this->_fail();
}
I have problems with a session variable, users log into the app and then it sets a session variable but when it redirects to the next controller it isn't there.
At the moment I am not using the auth component, I think it is not correct, but I don't know how to apply it to my logic. This is because I dont log in users with username and password, they come authenticated from other website that gives me a ticket and a key to know who they are.
Here is my code of the UsersController where the app starts:
class UsuariosController extends AppController {
public $components = array('Session');
function beforeFilter() {
}
function login() {
$isLogged = false;
if(!empty($_POST['Ffirma']) ) {
$this->loginByTicket();
}
else if(!empty($this->data)) { //When users log by email it works perfectly
$this->loginByEmail();
}
}
private function loginByEmail() {
//Se busca el usuario en la base de datos
$u = new Usuario();
$dbuser = $u->findByEmail($this->data['Usuario']['email']);
//if doesn't exist user in db
if(empty($dbuser) ) {
$this->Session->setFlash('El usuario no existe en el sistema, consulte con el administrador.');
$this->redirect(array('controller' => 'usuarios', 'action' => 'login'));
exit();
}
$this->userIsCorrectlyLogged($dbuser);
}
function loginByTicket() {
$Fip = $_POST['Fip'];
$Frol = $_POST['Frol'];
$FidPersona = $_POST['Fidpersona'];
$Fticket = $_POST['Fticket'];
$Ffirma = $_POST['Ffirma'];
//Check sing
$f = $this->gen_firma($Frol, $FidPersona, $Fticket);
if( strcmp($f, $Ffirma) != 0 ) {
$this->Session->setFlash('Firma no válida.');
return;
}
//Check if ticket is valid
//1º Check if it exists on the db
$t = split('-',$Fticket);
$ticket = new Ticket();
$dbticket = $ticket->findById($t[0]);
if( strcmp($dbticket['Ticket']['valor'], $t[1]) != 0) {
$this->Session->setFlash('Ticket no válido.');
return;
}
//2º if Ip ok
if($Fip != $dbticket['Ticket']['ip']) {
$this->Session->setFlash('IP no válida.'.' '.$dbticket['Ticket']['ip'].' '.$Fip);
return;
}
$u = new Usuario();
$dbuser = $u->findById($dbticket['Ticket']['idPersona']);
$this->userIsCorrectlyLogged($dbuser);
}
private function userIsCorrectlyLogged($dbuser) {
$user = array('Usuario' => array(
'last_login' => date("Y-m-d H:i:s"),
'rol_app' => 1,
'nombre' => $dbuser['Usuario']['nombre'],
'email' => $dbuser['Usuario']['email'],
'apellidos' => $dbuser['Usuario']['apellidos'],
'id' => $dbuser['Usuario']['id']
) );
//Some stuff to determine rol privileges
$this->Session->destroy();
$this->Session->write('Usuario', $user);
$this->redirect(array('controller' => 'mains', 'action' => 'index'),null, true);
exit();
}
As you can see I make some controls before know that the user is correctly logged, and in user correctly logged I just save the session.
In my AppController I check if the user has logged in, but the session variable has already gone:
class AppController extends Controller {
public $components = array('Session');
function beforeFilter() {
//Configure::write('Security.level', 'medium'); //I've tried this that i saw somewhere
pr($this->Session->read()) // Session is empty
if($this->checkAdminSession()) {
$user = $this->Session->read('Usuario');
$email = $user['Usuario']['email'];
$usuario = new Usuario();
$dbuser = $usuario->findByEmail($email);
$respons = $usuario->getAccionesResponsable($dbuser['Usuario']['id']);
$this->set("hayacciones", true);
if( empty($respons) ) $this->set("hayacciones", false);
}
else {
$this->Session->setFlash('Necesitas identificarte para acceder al sistema.');
$this->redirect('/usuarios/login/');
exit();
}
}
function checkAdminSession() {
return $this->Session->check('Usuario');
}
}
I'm desperate, I've read a lot of documentation but I don't know how to solve this problem, could you give me any clue?
Thanks you very much, and sorry for my English!.
Note: I have discovered that if the security level is low it works:
Configure::write('Security.level', 'low');
But I dont like this solution...
You are overriding the beforeFilter() method. So, instead of using this:
<?php
class UsuariosController extends AppController {
function beforeFilter() {
}
you should do this:
<?php
class UsuariosController extends AppController {
function beforeFilter() {
parent::beforeFilter();
}
I was losing session information after a login call too and after searching for a while I found many different ways to fix my issue. I only regret that I don't fully understand what is causing the issue, but I imagine it has to do with php's session configuration.
As you mentioned, changing Security.level to low fixed the issue for me
Configure::write('Security.level', 'low');
Changing the session save configuration to php fixed the issue for me too:
Configure::write('Session', array(
'defaults'=>'cake',
));
And finally adding a timeout worked too (which I ended up using):
Configure::write('Session', array(
'defaults'=>'php',
'cookieTimeout'=> 10000
));
All these found in /app/Config/core.php
I post this hoping someone is able to make sense of what is going on underneath. I feel understanding the root of the issue would make a better job of answering your question.
I have the same problem. I tried all the suggestion. My Cache engine is Apc.
$this->__saveData($t);
debug($this->Session->read());// >>>>>> GOOD
$this->redirect(array('controller'=>'users','action'=>'main'));
}
}
}
function logout() {
$this->Session->destroy();
$this->Session->delete('User');
$this->redirect(array('controller'=>'logins','action'=>'login'));
}
function forgot() {
$this->layout = 'login';
}
private function __saveData($t)
{
$this->Session->write('User',$t['User']['name']);
$this->Session->write('User_name',$t['User']['firstname']);
$this->Session->write('User_id',$t['User']['id']);
$this->Session->write("User_Group",$t['Group']['name']);
$g = $this->Myauth->getPerm('User_Group'); // This is the array of permission w.r.t to the menu (key)
$this->Session->write("Permissions",$g);
debug($this->Session->read());
}
function main()
{
// Check permissions
$this->Myauth->check('users','login');
$username = $this->Session->read('User');
debug($this->Session->read( ));die(); <<<<< NOTHING
}
The funny thing is that yesterday it worked.
My php.ini has a simple extension=apc.so.
My core.php
Configure::write('Session.defaults', 'php');
Nothing change if I change the Security level. I will appreciate any direction.
EDIT
First solution: in my php.ini I had a bad value for session.referer_check (It was = 0 while it should be '').
But now, on the same server, one site is ok. Another one fires the error
Error: Call to undefined function apc_cache_info()
The two sites are separated and do not share any cakelib.
[SOLUTION FOUND]
For Cake > 2.2 and Chrome 24 I found this solution (I tried all the others found on the web). In your core.php:
Configure::write('Security.cookie', 'cakephpfdebackend');
Configure::write('Session.cookieTimeout', 0);
Configure::write('Session.checkAgent', false);
Configure::write('Session.cookie_secure',false);
Configure::write('Session.referer_check' ,false);
Configure::write('Session.defaults', 'php');
Actually, only the Session.cookieTimeout is required. The other settings are optional to solve the problem.
I had some issue with session on some pages . Can you check whether any space comes at the bottom of page after the php ending tag. When i faced this problem, i found session is missing due to a white space character in controller after the php ending tag . Please check this and let me know .
A possible reason for this problem is that the server clock is not synced with the client's clock and thus the cookie timeouts.
I'm trying to get some custom routing going on in Magento using the following code (which I've only slightly modified from here https://stackoverflow.com/a/4158571/1069232):
class Company_Modulename_Controller_Router extends Mage_Core_Controller_Varien_Router_Standard {
public function match(Zend_Controller_Request_Http $request){
$path = explode('/', trim($request->getPathInfo(), '/'));
// If path doesn't match your module requirements
if ($path[1] == 'home.html' || (count($path) > 2 && $path[0] != 'portfolios')) {
return false;
}
// Define initial values for controller initialization
$module = $path[0];
$realModule = 'Company_Modulename';
$controller = 'index';
$action = 'index';
$controllerClassName = $this->_validateControllerClassName(
$realModule,
$controller
);
// If controller was not found
if (!$controllerClassName) {
return false;
}
// Instantiate controller class
$controllerInstance = Mage::getControllerInstance(
$controllerClassName,
$request,
$this->getFront()->getResponse()
);
// If action is not found
if (!$controllerInstance->hasAction($action)) {
return false;
}
// Set request data
$request->setModuleName($module);
$request->setControllerName($controller);
$request->setActionName($action);
$request->setControllerModule($realModule);
// Set your custom request parameter
$request->setParam('url_path', $path[1]);
// dispatch action
$request->setDispatched(true);
$controllerInstance->dispatch($action);
// Indicate that our route was dispatched
return true;
}
}
The result is a page where the template has loaded but with no content. If I comment out the $this->loadLayout() / $this->renderLayout() in my controller I can print to screen. But when I try and load a Template and/or Block it breaks somewhere.
home.html also loads fine (as the method returns false if the path is home.html).
Any assistance would be greatly appreciated.
I was implementing something similar to this and came across the same problem(That makes sense, because I copypasted your code)
before $request->setDispatched(true);
I added $request->setRouteName('brands'); (brands is the frontname of my module).
And It worked.Don't know if It'll work for you, but definetely there was something missing so that magento didn't know what layout to apply, because I could tell that teh controller was being reached.
Can I change the database config per method in a controller?
$db['default']['db_debug'] = TRUE;
The default is TRUE, while I need to make it false in a certain method to catch the error and do something else (for example show 404 page).
When I tried $this->config->load('database') it fails.
Another question :
Can I check an incorrect query and catch it to some variables rather than displaying it to users other than setting the db_debug config to FALSE?
I checked the code of system/database/DB_Driver and found that:
$this->db->db_debug = FALSE;
will work in my controller to enable/disable the debug thing on the fly.
Expanding on the answer by comenk, you can extend the database class and implement various methods by which to achieve your goal.
First, you'll need to extend the core Loader class by creating a MY_Loader.php file
class MY_Loader extends CI_Loader
{
function __construct()
{
parent::__construct();
}
/**
* Load the Standard and/or Extended Database function & Driver class
*
* #access public
* #return string
*/
function database( $params = '', $return = FALSE, $active_record = NULL )
{
$ci =& get_instance();
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($ci->db) AND is_object($ci->db))
{
return FALSE;
}
$my_db = config_item('subclass_prefix').'DB';
$my_db_file = APPPATH.'core/'.$my_db.EXT;
if(file_exists($my_db_file))
{
require_once($my_db_file);
}
else
{
require_once(BASEPATH.'database/DB'.EXT);
}
// Load the DB class
$db =& DB($params, $active_record);
$my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_driver';
$my_driver_file = APPPATH.'core/'.$my_driver.EXT;
if(file_exists($my_driver_file))
{
require_once($my_driver_file);
$db = new $my_driver(get_object_vars($db));
}
if ($return === TRUE)
{
return $db;
}
// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$ci->db = '';
$ci->db = $db;
}
}
By implementing the above this will allow you to create a MY_DB_mysqli_driver.php whereby mysqli is replaced by whatever driver you're using in your CI database.php config.
At this point you'd add comenk's answer to MY_DB_mysqli_driver.php
function debug_on() {
return $this->db_debug = TRUE;
}
function debug_off() {
return $this->db_debug = FALSE;
}
function in_error() {
return (bool) $this->_error_number();
}
Then in your model/controller,
$this->db->debug_off();
$this->db->query('SELECT * FROM `table`');
if( $this->db->in_error() ) {
show_404();
}
$this->db->debug_on();
you must add function on system/database/DB_driver.php
function debug_on()
{
$this->db_debug = TRUE;
return TRUE;
}
function debug_off()
{
$this->db_debug = FALSE;
return FALSE;
}
after that you can simply do this command to changes at run-time
$this->db->debug_off();
$this->db->reconnect();
$this->db->db_debug = 0; // 0: off, 1: on
That worx for me...
You can look at the $GLOBALS variable to locate this generic setting.
To hide bad SQL (and other errors) from users, you need to set the php error reporting level. CodeIgniter ships in basically development mode.
Go to index.php and replace this
error_reporting(E_ALL);
with this
error_reporting(0);
This is the quick way to do it. You can also implement this using a hook, so you don't have to touch CI files. You can also add logic to that hook so that it only sets it on the production server.
For debugging SQL, you can create a class that inherits from CI_Model, then create all your model classes to extend that class. In that class, you can add code for running queries that writes the queries to the log so that you can debug them easier. This won't help if the query itself is bad, but you should be able to figure that out before you get to that point.