Laravel cache null error - laravel

I'm using File Cache in Laravel 5.3. Everything works fine. After few days in production I have many errors in my laravel.log that WHERE was called on NULL value (from cache). Why is this happening? Every time I open page everything works fine without errors. Can this be caused because of bots accessing my page? I have not idea what I'm doing wrong...
CacheServiceProvider.php
// insert settings into cache
Cache::add('settings', Settings::with('langs')->get(), env('CACHE_TIMEOUT'));
Helpers.php
$value = Cache::get('settings')->where('name', $name)->first()->value;
I tried to use conditions if cache value exists then use it but it's really anoying to put it everywhere. And what if value doesn't exists? Should I call database query?

in Helpers.php I would suggest you using:
$settings = Cache::remember('settings', env('CACHE_TIMEOUT'), function() {
return Settings::with('langs')->get();
});
$value = !empty($settings) ? $settings->where('name', $name)->first()->value : null;
Remove what you have in CacheServiceProvider.php because this code will fire once when it is needed to get data and cache it for next time.
Hope that helps!

Related

Setting configuration values at runtime

I'm using laravel 5.8 and created a command that runs in the background to keep data updated.
web.php
Route::get('/admin/do_stuff', function () {
Artisan::call('do:stuff');
return 'Started!';
});
DoStuff.php
while(config('key.value')){
doStuff();
sleep(120);
}
Also got my route (mysite.com/admin/do_stuff) that will start this process, but now I want to add a new route (mysite.com/admin/stop_doing_stuff) to be able to stop it. I've seen in the documentation config variables could be set during runtime https://laravel.com/docs/5.8/configuration#accessing-configuration-values but this doesn't seem to be changing the value at all. Is this possible?
Reading the value from the .env file seems to work but that means I need to edit that file manually and that's not an option, also I could store the value in the database but would like to not doing it. Tried clearing the config cache but getting the same result

Best way share data across all view in Laravel

I have some data that I want to share across all views. I am using AppServiceProvider's boot method to share data.it is working fine with MySQL however with pgsql when I run composer or PHP artisan commands I am getting the following error,(i do fresh and seed database very often)
SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "news" does not exist
it took me a while to understand where is the real issue. I m still unable to understand if it is pgsql related error or something else, bellow is code in AppServiceProvider. if I comment this code everything works fine except where I m using this.
public function boot()
{
$activeClubs = (new TournamentService())->getAllActiveClubs();
$activeNews = (new TournamentService())->getActiveNews();
$activeTournaments = (new TournamentService())->getActiveTournament();
View::share(['activeClubs' => $activeClubs, 'activeTournaments' => $activeTournaments, 'activeNews' => $activeNews]);
}
can you please help me that how can i share data across all views that i don't get this error in future.
you can determine if the app is running from console or not and prevent loading data in console
if ( !app()->runningInConsole() ){
// it's not console.
}
you mentioned you want to load this data in all views but sometimes, its one view that loaded in all of your views e.g. the layout.app view.
if its the case I recommend using view composers instead of View::share() as it will pass the data to that view before render and it will only run if that view is included in the page (so basically it will solve your problem even without app()->runningInConsole() condition required )
view composers doc
simple example:
View::composer('view-name', function ($view) {
$view->with('key', 'value');
});

Is it ok to use $_SESSION['variables'] in Drupal 8?

I need a way to store temporary data for anonymous users.
Apparently this is not possible with:
\Drupal::service('user.private_tempstore')
Unless you write a custom constructor for the session management and stuff, which seems a little far-fetched to me?
I tried using
\Drupal::service('user.shared_tempstore')
But that saves the temp data for all anonymous users. So it's not linked to a single user.
Using raw $_SESSION['data'] works fine, but I'm not sure if I'm supposed to be doing this in Drupal and how safe/unsafe it is to do this?
Sessions (Drupal 8) are used via the simple Session implementation of SessionInterface interface. See Complete Tutorial of Sessions (Drupal 8).
Example:
use Symfony\Component\HttpFoundation\Session\Session;
$session = new Session();
$session->start();
// set and get session attributes
$session->set('name', 'Yash');
$session->get('name');
// set flash messages
$session->getFlashBag()->add('notice', 'Profile updated');
// retrieve messages
foreach ($session->getFlashBag()->get('notice', array()) as $message) {
echo '<div class="flash-notice">'.$message.'</div>';
}
I am not answering your specific question (regarding $_SESSION) because I have successfully used:
$session = \Drupal::service('user.private_tempstore')->get('your_module');
$session->set('whatever', $whatever);
from within procedural code (i.e. hooks, themes) without problems.
Pay attention that this private tempstore has to be assigned to a module (for the lack of a better way of saying this) which is the purpose of this line
$session = \Drupal::service('user.private_tempstore')->get('your_module')
After you get the private tempostore you can now set and get the session values:
$session->get('whatever');
$session->set('whatever', $whatever);
EDIT
Sorry, you explained correctly. I didn't get the critical part 100% ;)
You can always access the Session object from the request.
$session = \Drupal::request()->getSession();
$session->set('whatever', 'hello');
$value = $session->get('whatever', 'default');
I've been using plain PHP $_SESSION variables for a while now.
Did some research on them and they should be perfectly safe to use.
They're working correctly everywhere I use them and they have been working correctly for a while.
Don't think there's any issue using them in Drupal 8.

Output caching in codeigniter displays blank page

I've read a lot of discussions about this but have no luck.
I have a controller:
function get_list() {
$data['promoname'] = $this->Default_model->get_promo($this->input->post('year'));
$this->output->cache(10);
// Render view
$this->layout->render(get_platform().'/promo/promo_view', $data);
}
And in my Default_model:
function get_promo($year = NULL) {
$this->db->cache_on();
//query here
}
When the page is loaded for the first time, the data is displayed perfectly. But when I tried to load it again to check if it is cached it displays nothing, a blank white page. Error reporting is enabled.
A file has been created under application/cache, meaning there is no permission issue. But the file created contains '1357184142TS--->'.
Tried to remove the $this->db->cache_on(), but the behavior is still the same. What seems to be the problem?
Check your view file to see if any tags are missed or any values getting interrupted in-between.
As documentation https://ellislab.com/codeigniter/user-guide/general/caching.html says:
Because of the way CodeIgniter stores content for output, caching will only work if you are generating display for your controller with a view.
so you have to call:
$this->load->view(get_platform().'/promo/promo_view', $data)
instead of
$this->layout->render(get_platform().'/promo/promo_view', $data);
I am having a same problem. I haven't properly tested it though. I think the blank page is caused by using ($this->db->last_query()) in the Code with Nested Queries.
Try changing the $db['default']['db_debug'] = TRUE; to false. It may resolve the problem if other system queries are not running.

flashdata not being stored between redirects when using Tank Auth

I'm using the latest version of Codeigniter and tank_auth 1.0.9 on a site I'm building.
When using set_flashdata() and flashdata() respectivly, nothing is being returned on redirect but if I set sess_use_database to FALSE in the config it works.
I've searched around and couldn't find an answer -- Has anyone else run into this issue and fixed it?
I was having the same issue and figured out the problem. If you're storing sessions in the database, it will not work.
Tank Auth runs this code from the main library ( $this->tank_auth->logout() ):
$this->delete_autologin();
// See http://codeigniter.com/forums/viewreply/662369/ as the reason for the next line
$this->ci->session->set_userdata(array('user_id' => '', 'username' => '', 'status' => ''));
$this->ci->session->sess_destroy();
Then it runs this code from the auth controller ( $this->_show_message() ):
$this->session->set_flashdata('message', $message);
redirect('/auth/');
The problem is that since sess_destroy() was run prior to setting the flashdata, there is no database row to add the flashdata to, so the flashdata never gets set.
At this point there are a few solutions:
Option 1:
Add $this->ci->session->sess_create(); immediately after $this->ci->session->sess_destroy(); in function logout() in application/libraries/Tank_auth.php
This works because you are creating a new blank session where flashdata can be stored. A potential con for this is that you are performing more operations on the database (delete+insert).
Option 2:
Comment out/delete $this->ci->session->sess_destroy(); in function logout() in application/libraries/Tank_auth.php
This works because the session is not destroyed, allowing CI to perform only an update query to add flashdata. This is probably better than option 1 unless you absolutely need to destroy the session.
Option 3:
Set $config['sess_use_database'] to FALSE.
This works because a session is automatically created when it is requested again, as opposed to how it works when you store sessions in the database. Potentially less secure.
In the end, it is up to you to decide which option is best for your application.
if tank_auth does any internal redirects then you may lose the flash data on that redirect request.
Exactly.
CodeIgniter documentation specifies here:
http://codeigniter.com/user_guide/libraries/sessions.html
=============================
Destroying a Session
To clear the current session:
$this->session->sess_destroy();
Note: This function should be the last one called,
and **even flash variables will no longer be available**.
If you only want some items destroyed and not all, use unset_userdata().
=============================
I've digged into the system/libraries/Session.php file and saving flashdata triggers the sess_write() method which only UPDATES the database as you said.
To me a better fix is checking to make sure the session exist before setting the flashdata in show_message().
function _show_message($message)
{
// Patch for show_message() after logout(). Make sure the session exist before set_flashdata().
if(!$this->session->sess_read())
{
$this->session->sess_create();
}
$this->session->set_flashdata('message', $message);
redirect('/auth/');
}

Resources