How to notify when a product is added within Magento? - php

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

Related

How do I make a notification table that makes eloquent relationships to other tables without making too many "<source>_id" columns

Suppose that I have a Notification Table that gets generated when a new log from another table is generated. Suppose I have 3 different logs with different purpose namely: sms_logs, call_logs, and appointment_logs.
I want to make a relationship to each logs without using sms_logs_id, call_logs_id and appointment_logs_id. Instead, I want to build only two columns, one for the type, and the other for the ID. So for example an sms log is generated with an id of 187, it will also generate a notification log with a notification_id of 187 and a type of "sms".
How will I be able to create that? Thank you!
Nice question.
You have to put only two fields in notifications table. foreign_id and log_type.
Whenever you add a log, you have to set log_type accordingly. Then add this relationship in your Notification model.
public function foreignModel()
{
switch($this->log_type){
case "call_log":
return $this->belongsTo('App\Call', 'foreign_id');
break;
}
}
I didn't tried it, but hope it will work fine.
If you are looking for something more dynamic and less robust than this then I don't think that it exists.

Laravel: How to dynamically create and name views?

I am making a website for college administration where professors log in and assign marks to the students they are teaching.
There's a table, called "IA_Marks" in my database:
|Student_ID|Subject_Code|Name|Marks1|Marks2|Marks3|Semester|Division|
There's also a table called "Classroom_Mapper" in my database, that helps map a professor to a classroom, with a subject:
|Prof_ID|Subject_Code|Semester|Division|
This is a method in my controller:
public function showTable(){
$sem = DB::table('classroom_mappers')->where('Prof_ID', auth()->user()->PID)->pluck('semester');
$division = DB::table('classroom_mappers')->where('Prof_ID', auth()->user()->PID)->pluck('division');
$data = DB::table('iamarks')->where([['semester','=',$sem],['division','=',$division]])->get();
return view('ia',compact('data'));
}
Using this, I can fetch rows that belong to the professor who has logged in.
But, there's a problem.
Say the professor teaches two subjects, in two semesters. Then, the where clause will return multiple results from the mapper table.
For example:
select semester from classroom_mapper where Prof_ID=auth()->user()->Prof_ID
output:
8
5
Then the students from both 5th and 8th semester will be shown on his dashboard. Our target semester was, say 5th. Then it'll be a problem.
Registering for a subject, is done as shown here:
form screenshot
Let's call the subject being registered in the screenshot "SUBJECT 4".
It is a subject for the 5th semester, division A.
I want to dynamically make a button(SUBJECT 4) on the dashboard, which when clicked, sends the semester(5) and division(A) of choice to the controller.
Dashboard Screenshot
This button should open a newly made page with name of the subject(subject4.blade.php), where the database table contents for target semester and division(5 and A) will be shown.
How do I make this dynamic view creating button which sends specific info to controller? Is it even possible?
There are a few ways to do this with Laravel, but my goto is usually to create a single blade template for each view (dashboard, subject, etc.) that can be dynamically populated -- assuming that the layout for each subject view is the same.
In your dashboard view, you could generate a url for each button that uses a format like this: http://cas.jce.in/subject/semester/5/division/a/
Next, create a route that uses a couple of paramaters, something like this:
Route::get('/subject/semester/{semester_id}/division/{division_id}', 'ControllerName#showSubject');
More info here: https://laravel.com/docs/5.8/routing#required-parameters
Then in your controller, add a showSemester function like this:
function showSubject($semester_id, $division_id){
$data = DB::table('table_name')->where('semester', '=', $semester_id)->where('division', '=', $division_id)->first();
return view('subject', ['data'=>$data, 'semester'=>$semester_id, 'division'=>$division_id]);
}
Your route parameters are available to the controller, in order of appearance. So we can add $semester_id and $division_id as the first two parameters of our function. Next, we'll to the database work to retrieve the data we need before returning everything to a view.
Note here that we're using a single view rather than dynamically selecting one. You could create individual views for each subject, but im thinking you probably don't need to unless the layout of each one is unique in some way. In that case, you can simply do something like this, but I'd generally try to avoid it.
$view = 'subject'.$data->subject_id;
return view($view, ['data'=>$data, 'semester'=>$semester_id, 'division'=>$division_id]);
Also, just a quick note ... you may consider adjusting your database queries from above to use a select statement rather than pluck. The end result is the same, but using a select can boost performance by only loading the data you want ... rather than loading everything up front and throwing most of it away.
$sem = DB::table('classroom_mappers')->where('Prof_ID', Auth()->user()->PID)->pluck('semester');
... becomes ...
$sem = DB::table('classroom_mappers')->select('semester')->where('Prof_ID', auth()->user()->PID)->get();

Insert model unless it exists and attach it

I'm a Laravel noob rewriting some old code to Laravel.
I have a system for managing purchases and games and I'm writing the store method of the PurchaseController. The form for creating new purchases contains data about the purchase and an array with data about the games.
There is a many-to-many relationship between games and purchases: a purchase can contain many games and a game may be linked to multiple purchases.
The thing is that the game may already exist in the database. I want to do the following:
Insert the new purchase into the database (this part I got sorted out already ;))
Check if the POSTed name of the game already exists in the database.
If it exists, attach it to the newly inserted purchase. If it doesn't exist, insert it and attach it to the newly inserted purchase.
I don't want to update the game if it already exists in the database, just to attach it to the purchase.
I've looked into firstOrCreate but that doesn't do what I want. It checks on all the arguments you feed it, you can't just make it check only the name (this issue basically).
The undocumented method updateOrCreate does accept two arrays (one for attributes to check on, another for values to insert) but it updates the record if it exists, which is not what I want.
So, is there a nice, proper way to do this with Eloquent or do I simply need to manually write some code that checks if the game exists in the database and inserts the game unless that's the case?
EDIT:
It seems that this is possible with firstOrCreate after all in Laravel 5.3: https://github.com/laravel/framework/pull/13236
firstOrCreate is what you need, but you can feed it just the game name, then attach it to your purchase.
$game = Game::firstOrCreate(['name' => $gameName]);
$purchase = new Purchase(['otherArgs' => ...]);
$purchase->games()->attach($game);
I was probably overthinking this too much. The following code does what I want:
// Insert games (unless they exist) and attach to new purchase
foreach($request->games as $game) {
$gameModel = Game::firstOrNew(['name' => $game['name']]);
if(!$gameModel->exists) {
$gameModel->status_id = $game['status'];
$gameModel->note = $game['note'];
$gameModel->save();
}
$gameModel->purchases()->attach($purchase->id);
}
I just thought maybe there was a nicer/shorter way to do this.

php shortcode function to add other sum other shortcode values

im doing some web designing with wordpress at the moment.
I have created a page with a web form where a client can input some information (name, email, invoice number, price, gst, etc).
I used a plugin called contact form 7 to provide the web form, when the user inputs all of their information, the plugin then emails an html formatted invoice to my email address, with the fields occupied by shortcodes which take on the value from the web form.
For example, in the name field of my invoice table, i enter [first-name] and the name the user inputs gets emailed to me in the invoice.
I need to find a way to sum the value of two of the other fields, one of the fields on my invoice form is called total, which should be equal to [gst]+[price] that the user inputs on the web form.
Ive tried to look for a php shortcode function that can take its arguments as the values of other shortcodes, but havent had any luck. I have never really used php before either so wouldnt know how to write one.
I managed to find this, which doesnt seem to work, as when the email comes through all i see is [sumsc][gst] [price][/sumsc]
add_shortcode('sumsc','sumsc_func');
function sumsc_func( $atts, $content = null ) {
$sum=0;
$content=str_replace(array(" ","] [","]["),array(" ","][","]|["),$content);
$codes=explode("|",$content);
foreach($codes as $code){
$sum+=do_shortcode($code);
}
return " <div>".$sum."
</div>";
}
Any help would be greatly appreciated, I also need to the functionality to be able to multiply a shortcode value by a certain number. For example the price needs to be divided by 0.6 to give the quantity which appears on the invoice. Thanks!
Create a hidden field in the form say with a unique id say it fields_sum.
Use jquery on that page and catch form submission event. Get values of those fields, sum it and set the result to fields_sum field. And then use field shortcode where you want.
jQuery script would be something like (Algorithm)
$(document).ready(function(){
$("your_form_id").submit(function(e){
// get value of field one
// get value of field two
// sum them
// set sum to the hidden field
});
});
I hope this works and enough to get a solution like this.

How to tell if a user has updated a profile field in Drupal 7

I am trying to determine how in drupal 7 I can programmatically tell if a user has updated a custom field in their profile within the past 24 hours however looking through the tables I can't seem to find any field with that information does anyone have any ideas?? Essentially I need to pull this information out during a batch job that run onces a night and updates other systems based upon the information in drupal. If someone can think of a better way todo this it would be appreciated. thanks for any help you can provide
ok i dont know if its working or not try the following steps
1- first you should tell drupal....when user edit the profile page do something...(whatever the something is ..insert something to database..retrieve something..etc)
/**
* Implementation of hook_form_alter
*/
function newcontent_form_alter(&$form, &$form_state, $form_id){
if($form_id == 'user_profile_form'){
$form['#submit'][] = '_do_something_when_user_save_profile';
}
}
/**
* do something when user save profile
*/
function _do_something_when_user_save_profile($form,$form_state){
// do something
}
now i think we need to do some queries ... first we need to create 2 tables
http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_schema/7
(this url will help you to create your schema)
the first table will contain the current value of the field u want track so i think this table should have the following fields
(primary key , user id, field name, field value)
the second table will contain the date of the last upated operation the user made
i think the fields will be like the following (primary key,user id , field name, date)
now lets return to the form submit function
/**
* do something when user save profile
*/
function _do_something_when_user_save_profile($form,$form_state){
// now i can check in the first table to see
// is the current submitted value for this field = the value in the table
// if its = the table value then the user didn't change any thing now i dont
// need to update the second table
// if the current submitted value != the value in the table then its mean
// that the user have updated this field ...
// now i should insert new value to the second
// table with the current date time and the current field value
}
i hope u under stand me and sorry for my bad english
maged adel provided reasonable solution, however there is one more way of doing this:
you can use hook_user_update for this purpose. It's better that solution provided above because of 2 reasons:
1) you have both $edit - entered values and $account - user account values, so you can compare and get know what fields being updated (if you don't have 1 specific field to check).
2) just 1 hook to implement.

Categories