laravel - if the database changes, send notification - laravel

if any data has been inserted into the database, I want to alert message to another page. How can I do it?
This is the controller page:
public function insertFunction(Request $request) {
$insert = New ExampleTable;
$insert->test_id = $request->id;
$insert->save();
// after this i want to send notification to the another page(panel.blade.php) without refreshing
}
This is the panel.blade.php where I want to see the notification:
<script>
// if notification comes, do it
alert("notification came");
</script>
I'm using mysql. If you help me I will be glad, thanks.

Assuming that you want real time notification, the best practice would be to use the broadcast functionality of Laravel.
Most likely, you will end up using something like pusher.
However, you could make a custom java-script loop that continuously asks your endpoint if there has been any updates, but that would be bad practice and is not recommended.
This is an article that I found helpful. Good luck!

Related

Laravel Eloquent Events Implementation

I am updating my model instance or inserting a new one like this:
$model = Model::updateOrCreate([id' => $request['id']],
$model_to_update_array);
I want to execute some code only when existing model instance ('tourist') was updated (and NOT when a new one was created or nothing changes).
I've read https://laravel.com/docs/5.4/eloquent#events about Eloquent events and it seems to me that I need to use updated or updating event. As I understand these events are 'built-in' in Laravel, so I don't have to use a lot of stuff from here: https://laravel.com/docs/5.4/events
I haven't found a tutorial showing how to implement Eloquent events. Since I am new to events conception at all, it's hard for me to understand how to use them. Can anyone drop a link to a good tutorial about Eloquent events (not events in general, but Eloqeunt events in particular) or maybe it can be shortly explained here?
Thank you in advance!
The easiest way to add Eloquent event for a particular model is to overwrite its boot() method:
protected static function boot()
{
parent::boot();
static::updating(function ($model) {
});
}
When you put this in your model the anonymous function will run every time when the model is being updated. Please note that there is a difference between calling static::updating() and static::updated() depending on when you want to execute your code.
#TheFallen gave a great answer to this problem in another thread on StackOverflow, please read if you are interested in thoroughly explained solution:
Laravel Eloquent Events - implement to save model if Updated

Application wide subscription to a channel

Quick question about Pusher.js.
I've started working on a notifications functionality today and wanted to do this with Pusher.js, since I used it for my chat.
I'm working in Laravel. What I want to achieve is an application wide subscription to a channel. When a user registrates a channel is being made for him "notifications_channel", which I store in the database. I know how to register a user to a channel, but once he leaves that page, the room vacates. That's not really what I'm looking for, since I'd like to send the user notifications no matter where he is on the platform.
I couldn't really find anything like this in the documentation, so I thought maybe one of you guys know how to do so.
Here are some snippets of what I do:
When the user registrates I fire this:
$generateChannel = User::generateNotificationsChannel($request['email']);
This corresponds to this in my model:
public static function generateNotificationsChannel($email){
$userID = User::getIdByMail($email);
return self::where('email', $email)->update(['notifications_channel' => $userID."-".str_random(35)]);
}
It's fairly basic, but for now that's all I need.
So for now, when the user logs in the Index function of my HomeController is being fired, which gathers his NotificationsChannel from the database and sends it to the view.
public function index()
{
$notificationsChannel = User::getUserNotificationsChannel(\Auth::user()->id);
return view('home', compact('notificationsChannel', $notificationsChannel));
}
Once we get there I simply subscribe the user to that channel and bind him to any events linked to the channel:
var notifications = pusher.subscribe('{{$notificationsChannel}}');
channel.bind('new-notification', notifyUser);
function notifyUser(data){
console.log(data);
}
So as you can see, for now it's pretty basic. But my debug console shows me that the channel vacates as soon as the user leaves /home.
So the question is, how do I make him subscribed to the channel, no matter where he is on the platform?
Any and all help would be deeply appreciated!
Thanks in advance.
I've found a fix to this issue, I've decided to send the notifications-channel to my Master layout, which I use to extend all views after the user has logged in. In my master layout I subscribe the user to his own notifications channel.
For people who might be interested in how I did it:
I altered the boot function of my AppServiceProvider which you can find in \app\Providers\AppServiceProvider. The code looks like this:
public function boot()
{
view()->composer('layouts.app', function($view){
$channel = User::getUserNotificationsChannel(\Auth::user()->id);
$view->with('data', array('channel' => $channel));
});
}
In my Master layout I simply subscribed the user by grabbing the channel name.

Laravel PDF generation with Graph and send it with Email

I tried to find it on StackOverflow and also tried to google it, but could not find any relevant answer.
I want to send monthly reports to the user of Laravel application with a PDF that contain a graph/chart.
This is what that is already done
Created a route, lets say
Route::get('/print/', 'PrintController#report');
In printController created a report function that is getting all the necessary data from the DB and returning a view with user data
return view::make('monthly_report', $user_data);
In monthly_report view, get all the user data, show the view and create a chart with the data. The chart is created with Charts.js. it is in a canvas.
Send the generated chart as image to the server with Ajax. For example
var canvas = document.getElementById("myChart"), // Get your canvas
imgdata = canvas.toDataURL();
file_name = "<?php echo $chart_file_name; ?>"; //created with userId and date
//send it to server
$.ajax({
method: "POST",
url: "save",
data: {
data: imgdata,
file_name: file_name,
_token: token,
}
});
Created a save route
Route::post('print/save', 'PrintController#saveChart');
In print controller, saveChart function, save the chart
$data = base64_decode($data);
//save chart on server
file_put_contents("Charts/".$fileName, $data);
Then create a PDF report by using another view monthly_report2, that is also in saveChart function. The view monthly_report2 does not use any JavaScript and use the chart image that was generated by monthly_report, in number 6.
$pdf = \PDF::loadView('monthly_report2', $cll_data);
file_put_contents("reports/".$pdf_name, $pdf->output());
It save the generated PDF on server. So far so good.
To send these PDF reports to the users by e-mail, I will created a schedule/crone job that will be run on a specific date, monthly and will send the e-mails with PDF reports as attachments.
I skip some details for clarity, please ask, if you need more information.
Thank you for reading so far, now I have two questions
The way I am doing is good or it can be improve?
We want all this process automatically (generating reports and sending by email). To generate the PDF's, monthly_report view must be loaded? so that it generate the Chart and send it to the server. Can we schedule it also, so that it generate the pdf reports automatically?, If no, is there any other way to do it?
Kind of a big question, but I'll try to answer
I think it's good. I'm not a big fan of using JavaScript to create charts, but that's me. You obviously know what you're doing and PDF generation is in my experience a "If it works, please don't break it" functionality.
I think this might be more difficult. Since you're using JavaScript to create charts, you need some kind of engine (NodeJS comes to mind) to parse the JavaScript and actually create your charts without opening a browser and doing it manually. (This is why I don't like using JavaScript to create charts). You could take a look at tutorials like this one to get an idea of how to render your charts serverside.
After that, you can take a look at the Laravel task scheduler (provided you're on Laravel 5, a community package exists for Laravel 4). You can schedule existing and custom-made commands to be executed. In pseudo-code, a PDF generation command could look like this:
public function createAndSendCharts() {
// 1. Get necessary user data
// 2. Create your charts
// 3. Save your charts
// 4. Create email with charts
// 5. Send your email
}
You could then add that function to your Task Scheduler
$schedule->command('send:charts')
->monthly();
Hope this was of some help. All in all, you're doing fine, but the choice for ChartJS has some consequences if you want to automate the whole process. Nothing really special, tons of tutorials exist for this situation :)

bp_activity_add() not working in theme ajax hooks

I am trying to add an activity for the current user through a function hooked to wp_ajax
add_action("wp_ajax_add_pair", "some_function");
function some_function(){
$args = array("action"=>"action string");
bp_activity_add($args);
}
some_function is called through ajax but I get bp_activity_add does not exist. This makes me think that BP hasnt loaded yet, but var_dump($bp) shows the variable is set. So need help to record activity for a user through ajax
Don't forget to enable activity streams from the backend! worked for me!

django update page when database field updates?

I have a results page and I am trying to work out how to auto update the page when an external database field is updated. I have seen quite a few examples but they seem to relate to PHP. I have a test that calls various APIs that can take up to an hour to complete. Once the test has completed, it will enter a success or failed message in a database field.
I already have my results page being rendered by django using template tags. I have a table and I have the field I would like to update. There are multiple fields that need update which correspond to each API test.
I have seen this site.. is this the kind of stuff to use? http://www.dajaxproject.com/ Is this an easy task to do? Does anyone have any ideas on how to do this?
Sorry but I don't know where to start on this one.
Cheers - Oli
I decided not to be so bold and just use the old classic page update for this purpose using javascript..
window.onload = setupRefresh;
function setupRefresh() {
setTimeout("refreshPage();", 30000); // milliseconds
}
function refreshPage() {
window.location = location.href;
}
Still open for options however I'm rather inexperienced in django and maybe this was too much to bite off too quickly..

Resources