Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Module resources not auto-loading
I recently redid the Log class my Fuel app as it was missing a lot of things for logging data across our platform. My new Log class is based off of Fuel's existing Log class, and it has been replaced in my Bootstrap file. The new Log class is working great and I'm not having any issues with it.
One of the things I added in the new Log class is the ability to add the backtrace, IP address, user agent and other important data using Monolog's "extra" processor. It helps so much with debugging.
The problem I ran into is when adding the authenticated user to Monolog's "extra" data. I have a couple of modules that have custom config/lang/class/view that get loaded automatically when you hit that module. For example, I have a dashboard module, and whenever you are in that module, it loads the necessary db.php config file for the dashboard tables. What seems to have happened is that the Log class is called early on in Fuel's core (before any modules are loaded), so when I check for the authenticated user in my Log class using the Auth::check() method, Fuel loads the global db.php config file to fetch the user and keeps it cached. Everything looked like it was working fine until I went into my dashboard module.
In the dashboard module, I have a db.php config file specifically for the dashboard tables. Since Fuel calls the Log class early on in the core code, it loads the global db.php file, then when the dashboard code runs, Fuel continues to use the global db.php file instead of the dashboard db.php file, and the whole module throws out errors because it's not the right database configuration.
I tested this by creating a custom class (NewTest) with some methods (first, second, third) to fetch config and language variables. I created a custom config and language file in the global config directory, and I copied the same files and into the dashboard module with different data for the same variable names. In the _init method of my class, I call in the config and language files. Sure enough, if I call any of the NewTest methods in my log class, the global config/language files are always used (even in the dashboard module) because the Log class gets called in via the Fuel core which calls my class' _init method which in turn loads the global files as my module hasn't been hit yet.
Is there any way to force Fuel to auto-load a module's resources if they have already been called in globally before a module has been accessed? This is a major blow to my Log class as I was planning to add a bunch more data to my logs, and I was also planning on redoing some other core classes as well. I know that Fuel can force a config file or language file to refresh in the load methods, but this will mean that I have to physically call in these files in my dashboard module now. Maybe there's something I'm overlooking here.
If you want to test this easily, just create a db.php config file and put it in any module's config path, and add a die() call (with a message) to the top of that file. If you go to the module, Fuel will auto-load it and you'll see the message. Now, copy the log class to your app directory, override the Log class in your bootstrap file, then add an Auth::check() call somewhere in the Log::write() method and go back to the module. Be sure to set the logging threshold to "debug" (level 100). You'll see that the die() call never gets hit, meaning that the module's db.php file never gets loaded. And this is where my issue lies. The same goes for language files and other resources as well I'm assuming.
Any help on this is greatly appreciated as I had to dumb down my Log class so that it didn't break the rest of my application.
We have this in our monolog processor:
// if we have Auth, and a current logged-in user, add it
if (class_exists('Auth', false) and $user = \Auth::get('username'))
$record['extra']['user'] = $user;
Hmmm... By checking if the class is first loaded, it prevents the class from loading any config/lang files as well, thus bypassing the issue of Fuel always loading the global files if the code was called in core before any modules. Should I be doing the class_exists() check for all calls to any of the core classes in my Log class such as Str, Input, Session, etc?
Part of the reason that I find this a bit wonky is that when Fuel calls the Log class in the core code, I want to know what user is logged in when it shows the URI request in the log files. With your code above, I don't get the user information.
The point is that if Auth is not loaded, there can never be any user present, so there is no reason to get user information.
And the class_exist() avoids autoload being triggered, which will crash the app as you have noticed.
This is because Log is used very early in the framework bootstrap, long before for example Config is available, and Auth can work.
Add a Comment
It looks like you're new here. If you want to get involved, click one of these buttons!
Apply for Membership
↳ Job Board
↳ Installation & Setup
↳ Tips and Tutorials
↳ Code share
In this Discussion