User notification system via email - php

I would like to create a user notification system using emails.
In context it is for employees (user type 1) to log onto my system and enter their timesheet (hours they've worked). I would like a notification to be sent to their supervisors (also members of the 'users' table (user type 2) that they have entered the information and it is ready to be checked.
Currently I have a database with a table 'users' which stores information such as 'id' (PRIMARY) AUTO INCREMENTING, 'first_name', 'last_name', 'email', 'user_type', etc.
I know how to sent emails in PHP, and I have a fully functioning log in system however it is these notifications which I cannot get my head around with how to implement.
My current code is not Object-Oriented as it is beyond my skill level at this time.
I would like something simple, it doesn't have to be perfect. Any suggestions are greatly appreciated.

When an employee successfully enters a timesheet, can you not fetch the list of users and then send them all an e-mail? I'm guessing the timesheet is a web form, so just trigger some code when the form gets submitted.
For example:
<?php
foreach($supervisor_user as $su) {
mail(...);
}
?>
However, what might be nicer, is to periodically check (by using a cronjob) for new timesheets and then e-mail all the supervisors about any new time sheets.
I won't write the full PHP for this, it's more of a pseudocode outline:
<?php
$last_check = /* Fetch the time we last checked for timesheets */
$new_timesheets = /* Fetch all timesheets submitted after this time */
/* Construct the e-mail message */
$message = "Hello, here are the new timesheets. \n";
foreach($new_timesheets as $ts) {
$message .= "* $ts \n";
}
/* Send a message to all supervisors */
$supervisors = /* Fetch e-mails of all supervisors */
foreach($supervisors as $s) {
mail(...);
}
/* Finally, store the time we last checked for timesheets
so that we can use this on the next run. */
?>
You might then set that to run every day, meaning that supervisors would get a single summary e-mail every day, rather than being bombarded with an e-mail for every submitted timesheet.

to spacediver - what are some of those ready made systems that would be suitable in this instance? We have the same project but feel an off the shelf system might be better for us. Please explain!
Rick

Related

stuck with notification system

I am developing a notification system in PHP, MySql, jquery ajax on a website that i am working on. I have a post which you follow if you comment on it. My problem is that i am stuck i don't know how can i send notification to all the users following the post. I did successfully send notification to the creator or the post though.
in the code i will be showing the query that enters a notification into notifications table, i will post the notifications_table structure and discussion_followers table which include the users following a post
here is the query that enters the notification into the notifications_table
// the board user_id is not the same as the logged in user which means the logged in user is not commenting on his post
// which means we insert notification in table
$query_not = "INSERT INTO notifications ( ";
$query_not .= "from_user, to_user, post_type, post_id, type, comment_id, notification_timestamp";
$query_not .= ") VALUES (";
$query_not .= " $user_id, $discussion_user_id_check, 'discussion', $discussion_id, 'comment', $fetched_comment_id, $discussion_comment_timestamp";
$query_not .= ")";
$result_not = mysqli_query($connection, $query_not);
so what i already achieved is : a user which is not the logged in user comments on a discussion post if he hasn't already followed the post he will will follow by entering his id with the post id into the following table, a new notification is inserted into the notifications_table. The user who created the post will receive this notification. What i want to achieve more is send notifications to all following this post that a new comment has been entered.
The notifications table structure is as follow:
notification_id, from_user, to_user, post_type, post_id, type, comment_id, reply_id, notification_timestamp, viewed
example of notification:
121, 20, 30, discussion, 31, comment, 39, 0, 1534184319, 0
discussions_followers table which follow the discussion post structure is :
follow_id, user_id, discussion_id
Honestly if i want to do what you want, i do not create my data structure like that to fill the purpose. but what ever, you can do a query:
select from_user from notifications where post_id={discussion_id} group by from_user;
then all ids fetched are users you want to push notification from new user. (you can skip $from_user==$user_id). lets say you have $result, then (simple code):
for($i=0, $i<count($result); $i++){
insert into notifications (from_user, to_user) values ($user_id, $result[$i]
['from_user'])
}
what i prefer:
for system like push notification. i always prefer to implement whole system as microservice and outside my project. (just you know not related). but what i do, i would use one of those message queue systems and not store such data in database FOR READ. your table is more like a log table which you can log you notification and write what ever you want to it for further process. but for read from it just to know who should push who, its not efficient. so have table post with 1 unique id and users id involved with that post. on each comment create queue with id "push-$id" and push comment and user id to it one by one. background manager of queues will know how to handle queues with id "push-*". creating queue may be a problem here so you can create empty one on each post created. (its not doing anything cause by that you just create pointer nothing else).

Prevent race condition and lock tables in hotel booking system PHP/MySQL

I am building a hotel style reservation system and I am loosing the way. I've got stuck at the exactly reservation moment when to add the reservation and I am concerned about come situations.
My flow is really easy, it lets multiple user to go through the reservation process for the same room until one of them press the reservation button before the others. The reservation information is kept in the session and is never stored in the db until somebody reach last step and press "book". In every step, the system check if the room/s is/are available if not it gives the error page.
Now the problem is preventing race condition combined to a last one mandatory check if still there are enough rooms left:
When user is in last step, he/she select the payment method and press book button. After checking if the selected payment option is ok (form data hasn't been altered) it redirects to the reservation controller where:
reservation controller
<?php
ReservationController extends JControllerLegacy{
public function placeReservation(){
//Do some checks to prevent direct access, booking existence and user completed all steps
$reservatioModel = $this ->getModel('Reservation')
if(!$reservationModel->placeReservation()){
//set errors and redirect to error page
return false;
}
//booking had been placed, passes the data to payment plugin
}
?>
and
Reservation model:
<?php
ReservationModel extends JModelLegacy{
public function placeReservation(){
//Get all variables and objects
//Lock the tables to prevent any insert while the last check
$db ->lockTable(#__bookings);
$db ->lockTable(#__booking_room);
//Perform the last mandatory check with tables locked to prevent read the table right one moment before another transaction insert the booking and allowing overbooking. THIS CHECK MUST BE 100% SURE NO ONE ELSE IS MANIPULATING/READING THE TABLE
if(!$this ->checkRoomsAvailability($data))
return false;
try{
$db ->transactionStart();
//Add the reservation in the booking table
if(!$this ->_saveBooking()){
$db ->rollBack();
return false;
}
//Add the room/s to the middle table #__booking_room
if(!$this -> _saveRooms())
$db ->rollBack();
return false;
}
$db ->transactionCommit();
}catch(Exception $e){
$db ->rollBack();
$this ->setError('We were not able to complete your reservation.');
return false;
}
$db ->unlockTables();
}
?>
The above mentioned tables are InnoDB, #__bookings hold the bookings and #__booking_room hold the information for the selected rooms (like avg_price, number of rooms, etc) and it has an foreign key to #__rooms and one to #__bookings
What am I concerned about?
1 - I am using other tables during the last availability check than the two locked and is giving me error.
2 - When the second user's execution arrives at the table locking point, does it wait until they get free or does it raise an error/exception? I could catch the exception and redirect user to the error page but locket table doesn't means reservation placed, it can occurs any issue while saving the information.
I hope my workflow is ok, please let me know if I am good to go or I should improve my code.
Thanks
EDIT:
To be mentioned, the business idea is like i.e. Expedia, booking, etc where you are allowed to select more rooms types and units per reservation. Indeed, my room table is not for specific/real room but is meant to be for room type with a fixed number of units available everyday if not already booked.
My approach would be simpler. In the table that stores the actual reservation, I would have a foreign key for the specific room being reserved, and have a UNIQUE index for the fields roomID, date. This will ensure that the same roomID cannot be recorded twice for the same date.
Next, when the customer confirms booking, I would run everything in a transaction as you're currently doing. When the code gets to the last place and tries to insert a new reservation, if a moment before another customer reserved that room, the DB will not allow you to insert another reservation for that room for that date. That's when I would either:
rollback and throw the error, or
try again with another room (with its own roomID) if there is another room of the same type still available
I can not say if your workflow aka business domain is the right choice as it depends on your business. But technically you want to have a booking transaction which also provides a check against double booking. The easiest way could be a room-booking-dates table with unique constraint on room is and date. So during your booking transaction you also insert each day with the room id into the table and the unique constraint will ensure that the second attempt will fail.
PS: If a table is locked, PHP will just wait for the unlock. No exception will be thrown (at least if the connection does not close after x seconds)

Email Notification System Using PHP MySQL

I am currently working on a project that requires sending email notifications to users. The way it works, users follow certain catergories of posts/group, whenever there is a new post or comment under the post category/group they get email message notifying them with a snippet of the post itself.
I am expecting to send upwards of 5000 emails daily. Is it effective to use cron job to fetch users and send the emails at intervals or is there a better means to push this email while avoiding blacklisting on my IP by email providers.
Below is my table structure
First Table
Notification
ID // autoincrement
message // the message sent to users
createDate // date created
Second Table
User_Notification
ID // auto increment
userid // Id of users
notification_id // id of notification from first table
status // 0 or 1
So whenever a post is added, I insert the notification in the first table (notification) and then fetch all followers of that group from another table (following) where i store userids and the group ids. I then insert for each user in the second table (user_notification).
My cron job fetchs like 20 records from user_notification table and also fetch the notification message from notification table. I also fetch user email from my user table.
$firstquery = $lnk->mysqli->query("select * from user_notification where status=0 order by id ASC limit 0, 20", MYSQLI_USE_RESULT);
$secondquery = $lnk->mysqli->query("select * from notification where id=$notification_id", MYSQLI_USE_RESULT);
$thirdquery = $lnk->mysqli->query("select email from user_table where id IN($userids)", MYSQLI_USE_RESULT);
for($no=0;$no<counter;$no++)// loop to send emails
{
$lnk->emailsender($subject,$emailbody,$usr_email[$no]);
}
Please is there any better way to do this?
Unless you have a very specific relationship with your ISP, it is extremly likely you will be blacklisted, or your e-mails will go straight to spam. It is difficult to establish mass e-mails as legitimate. You can use a mass mailing services API to do some of the dirty work for you, like mail chimp or constant contact.
So the code you have will most likely work, minus e-mailing bit which should be done via a mailing service and their associated API.
5000 emails a day is roughly 4 emails per minute, or one email every 15 seconds. If I were you I would write a cron routine to run every minute that will send the emails which are due to be sent. This will ensure you avoid being treated like a spammer for sending out 2500 emails quickly, for example. It also means your users get email notifications quickly.
You could also send out the emails as soon as a user gets a notification, bypassing the need for a cron routine however if your site hits a surge in activity for whatever reason you could find some emails don't get through.
You could also consider using a 3rd party service like MailChimp which already has good authority with email providers, however that comes at a price and for 4 emails a minute I wouldn't consider it worthwhile.

display number of emails sent using php mail function

I am creating a real-estate website that displays properties. On each property listing I would like a button that says 'Express Interest', when clicked, this button should send an email to me containing the user details who expressed interest (the user will be logged in and so all their details will be taken from their account).
I have the email function working fine, HOWEVER, I also want to display the number of people who have 'Expressed Interest'. Is there a way to track how many times an email has been sent using this button and display "xx people have expressed interest in this property"
Store in the database before sending the mail and just before sending the mail include the number of people or the people who are interested, a simple query would suffice, or if you have a content management system you can include it there, in both cases you would need an intermediate table (connection between user id and real-estate id)
I would add another table to your database that stores a property_id and a user_id. If a user clicks expresses interest, you add another row to that table with the current property_id and the current user_id. To get the amount of links you simply count the rows
SELECT count(user_id) FROM interest_relation WHERE property_id = 'your property id'
This way you can also find out which user is interested in which property.

How to notify when a product is added within Magento?

I'm wondering what would be the best way to notify an user when a new product is added which matches his/her interests?
I think of a cron running at least 2 times a days (or more, every hour for example)
I can also imagine to implement kind of an event system but that one may be tricky.
Do you have any feedback?
Thanks
At the time of new product adding time do you want send a mail to customers then don't go for RSS or cron just use the EVENT called "catalog_product_save_after" in your config.xml file and call one function in that function just write like this
public function sendMailToNotifiedCustomerOk($observer){
$product = $observer->getProduct(); //get the current product
echo "<pre>"; print_r($product); echo "</pre>";exit;
}
when you clicked on save button this function will execute and show you one flag value like
[_isObjectNew:protected] => 1
This values is 1 for only adding new products.
if you are updating or editing products then this value is
[_isObjectNew:protected] =>
so it is zero(0)
you can write like this
if($product->_isObjectNew)
{
//send email to your friends
}
You need to add a value to "Set Product as New from Date" attribute so that will appear in new product RSS feed. Doesn't make sense to make new event system. This is easy way to implement such kind of things.
You can create a script that runs simultaneously with the INSERT script that searches a table in your database called say "Notify" and searched loops through the table and finds everyone who signed up for say category "Toothpicks" and sends a mass email at the end to every user that is found
So you would need to set up the variable to catch the users in ($users) and one for the category ($category = mysql_real_escape_string('$_POST['category']); . Then set up a SELECT statement to pull from table "Kitchen_Goods" WHERE category = $category. Then set up the $rows variable so you can pull the username and email_address columns and set them to variables. then concat all the email results to have a comma in between, then echo that variable as the recipients field in your mail() function. That is a round about, incomplete way of doing it.
Or you can just use RSS which is 100 times easier lol.
You don't state how you save customer interests, so I'll relegate that one to magic until you say otherwise. A good way to do this is to hook an event to the catalog_product_save_after event in Magento. This function will fire whenever you save products. Create an observer that looks something like this:
public function observeProductSave($event) {
$product = $event['product'];
$customers = $this->getMatchingCustomerInterests($product);
foreach($customers as $customer) {
//send email to that customer
}
}
public function getMatchingCustomerInterests($product) {
// here you'll need to use your mechanism for saving
// customer interests to grab an array/collection of
// customers to send the emails to.
}
Obviously this code is not 100% complete, but that's the gist of it. You will probably want to add a facility to make sure that customers are not notified too many times about a product as well.
Hope that helps!
Thanks,
Joe

Categories