I know how to send an email with PHP, but what file would I put the send email php code in?
What admin file is only accessed once per admin login?
I would probably add this to a free ocmod.
~ OC 3.0.3.2 and OCmods only ~
probably best using an event in this senario
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<modification>
<name>MY CUSTOM: Admin Last Login Time</name>
<version>1.0</version>
<author>Just Me</author>
<code>MY_CUSTOM_Admin_Last_Login_Time</code>
<file path="admin/controller/marketplace/modification.php">
<operation>
<search><![CDATA[function refresh]]></search>
<add position="after"><![CDATA[
// -----------------------------modified - after begin MY CUSTOM: Admin Last Login Time
//Add last login column to the database if it doesn't exist....for last admin login
$this->db->query("ALTER TABLE `" . DB_PREFIX . "user` ADD COLUMN IF NOT EXISTS `last_login` VARCHAR(250) NULL AFTER `date_added`");
//------------------------------modified - after end MY CUSTOM: Admin Last Login Time
]]></add>
</operation>
</file>
<file path="admin/controller/user/user.php">
<operation>
<search><![CDATA[foreach ($results as $result) {]]></search>
<add position="after"><![CDATA[
if ($result['last_login'] == '0000-00-00 00:00:00') {
$last_login_time = "";
} else {
$last_login_time = date($this->language->get('datetime_format'), strtotime($result['last_login']));
}
]]></add>
</operation>
<operation>
<search><![CDATA['date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])),]]></search>
<add position="after"><![CDATA[
'last_login' => $last_login_time,
]]></add>
</operation>
</file>
<file path="admin/view/template/user/user_list.twig">
<operation>
<search><![CDATA[<a href="{{ sort_date_added }}">{{ column_date_added }}</a>]]></search>
<add position="after" offset="1"><![CDATA[
<td class="text-left">{% if sort == 'last_login' %}
<a href="{{ sort_last_login }}" class="{{ order|lower }}">Last Login</a>
{% else %}
<a href="{{ sort_last_login }}">Last Login</a>
{% endif %}</td>
]]></add>
</operation>
<operation>
<search><![CDATA[<td class="text-left">{{ user.date_added }}</td>]]></search>
<add position="after"><![CDATA[
<td class="text-left">{{ user.last_login }}</td>
]]></add>
</operation>
</file>
<file path="admin/model/user/user.php">
<operation>
<search><![CDATA[public function addUser($data)]]></search>
<add position="before"><![CDATA[
public function custom_adminLogTime() {
$this->db->query("UPDATE " . DB_PREFIX . "user SET last_login = '" . $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE username = '" . $this->request->post['username'] . "'");
}
]]></add>
</operation>
</file>
<file path="admin/controller/common/login.php">
<operation>
<search><![CDATA[$this->response->redirect($this->request->post['redirect']]]></search>
<add position="before"><![CDATA[
//Set the time that the admin logged in
$login_time = date('d-m-Y H:i:s');
$this->model_user_user->custom_adminLogTime($login_time);
//Get the logged admin info
$logged_admin = $this->model_user_user->getUserByUsername($this->request->post['username']);
//Send an email notification upon login if it isn't my email address
if ($logged_admin['email'] != "PUT-YOUR-EMAIL-HERE") {//-----------------------------------------------PUT-YOUR-EMAIL-HERE
$email_template = $this->request->post['username'] . " logged in on " . $login_time . "<br><br>IP: " . $logged_admin['ip'];
$subject = "Admin Login Notification";
$mail_data['subject'] = $subject;
$mail_data['text_welcome'] = html_entity_decode($email_template, ENT_QUOTES, 'UTF-8');
$mail = new Mail($this->config->get('config_mail_engine'));
$mail->parameter = $this->config->get('config_mail_parameter');
$mail->smtp_hostname = $this->config->get('config_mail_smtp_hostname');
$mail->smtp_username = $this->config->get('config_mail_smtp_username');
$mail->smtp_password = html_entity_decode($this->config->get('config_mail_smtp_password'), ENT_QUOTES, 'UTF-8');
$mail->smtp_port = $this->config->get('config_mail_smtp_port');
$mail->smtp_timeout = $this->config->get('config_mail_smtp_timeout');
$mail->setFrom($this->config->get('config_email'));
$mail->setSender(html_entity_decode($this->config->get('config_name'), ENT_QUOTES, 'UTF-8'));
$mail->setSubject(html_entity_decode($subject, ENT_QUOTES, 'UTF-8'));
$mail->setHtml($this->load->view('mail/customer_deny', $mail_data));
$mail->setTo($this->config->get('config_email'));
$mail->send();
}
]]></add>
</operation>
</file>
</modification>
v3.0.4.0 php 8.1
I'm here for a reason, if your response is contact a/the developer, just don't reply.
just copy and adapt the logic of one of the admin mail events like admin/controller/mail/transaction.php and set the trigger on model admin/model/user/user/deleteLoginAttempts/before, that function is called when a user successfuly signs in.supak111 wrote: ↑Mon Dec 30, 2024 3:50 amTrying to make OC3 send me an email every time an admin logs-in... and not really sure how to go about this.
I know how to send an email with PHP, but what file would I put the send email php code in?
What admin file is only accessed once per admin login?
I would probably add this to a free ocmod.
Also made my admin page white/bland first time I login in after installation... PS but admin page starter to work on the seconds login. Still the code above does not send emails...
I do see that it did add a column: last_login to oc_user table that just says null
~ OC 3.0.3.2 and OCmods only ~
This:Joe1234 wrote: ↑Tue Dec 31, 2024 2:41 amCode: Select all
<?xml version="1.0" encoding="utf-8"?> <modification> <name>MY CUSTOM: Admin Last Login Time</name> <version>1.0</version> <author>Just Me</author> <code>MY_CUSTOM_Admin_Last_Login_Time</code> <file path="admin/controller/marketplace/modification.php"> <operation> <search><![CDATA[function refresh]]></search> <add position="after"><![CDATA[ // -----------------------------modified - after begin MY CUSTOM: Admin Last Login Time //Add last login column to the database if it doesn't exist....for last admin login $this->db->query("ALTER TABLE `" . DB_PREFIX . "user` ADD COLUMN IF NOT EXISTS `last_login` VARCHAR(250) NULL AFTER `date_added`"); //------------------------------modified - after end MY CUSTOM: Admin Last Login Time ]]></add> </operation> </file> <file path="admin/controller/user/user.php"> <operation> <search><![CDATA[foreach ($results as $result) {]]></search> <add position="after"><![CDATA[ if ($result['last_login'] == '0000-00-00 00:00:00') { $last_login_time = ""; } else { $last_login_time = date($this->language->get('datetime_format'), strtotime($result['last_login'])); } ]]></add> </operation> <operation> <search><![CDATA['date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])),]]></search> <add position="after"><![CDATA[ 'last_login' => $last_login_time, ]]></add> </operation> </file> <file path="admin/view/template/user/user_list.twig"> <operation> <search><![CDATA[<a href="{{ sort_date_added }}">{{ column_date_added }}</a>]]></search> <add position="after" offset="1"><![CDATA[ <td class="text-left">{% if sort == 'last_login' %} <a href="{{ sort_last_login }}" class="{{ order|lower }}">Last Login</a> {% else %} <a href="{{ sort_last_login }}">Last Login</a> {% endif %}</td> ]]></add> </operation> <operation> <search><![CDATA[<td class="text-left">{{ user.date_added }}</td>]]></search> <add position="after"><![CDATA[ <td class="text-left">{{ user.last_login }}</td> ]]></add> </operation> </file> <file path="admin/model/user/user.php"> <operation> <search><![CDATA[public function addUser($data)]]></search> <add position="before"><![CDATA[ public function custom_adminLogTime() { $this->db->query("UPDATE " . DB_PREFIX . "user SET last_login = '" . $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE username = '" . $this->request->post['username'] . "'"); } ]]></add> </operation> </file> <file path="admin/controller/common/login.php"> <operation> <search><![CDATA[$this->response->redirect($this->request->post['redirect']]]></search> <add position="before"><![CDATA[ //Set the time that the admin logged in $login_time = date('d-m-Y H:i:s'); $this->model_user_user->custom_adminLogTime($login_time); //Get the logged admin info $logged_admin = $this->model_user_user->getUserByUsername($this->request->post['username']); //Send an email notification upon login if it isn't my email address if ($logged_admin['email'] != "PUT-YOUR-EMAIL-HERE") {//-----------------------------------------------PUT-YOUR-EMAIL-HERE $email_template = $this->request->post['username'] . " logged in on " . $login_time . "<br><br>IP: " . $logged_admin['ip']; $subject = "Admin Login Notification"; $mail_data['subject'] = $subject; $mail_data['text_welcome'] = html_entity_decode($email_template, ENT_QUOTES, 'UTF-8'); $mail = new Mail($this->config->get('config_mail_engine')); $mail->parameter = $this->config->get('config_mail_parameter'); $mail->smtp_hostname = $this->config->get('config_mail_smtp_hostname'); $mail->smtp_username = $this->config->get('config_mail_smtp_username'); $mail->smtp_password = html_entity_decode($this->config->get('config_mail_smtp_password'), ENT_QUOTES, 'UTF-8'); $mail->smtp_port = $this->config->get('config_mail_smtp_port'); $mail->smtp_timeout = $this->config->get('config_mail_smtp_timeout'); $mail->setFrom($this->config->get('config_email')); $mail->setSender(html_entity_decode($this->config->get('config_name'), ENT_QUOTES, 'UTF-8')); $mail->setSubject(html_entity_decode($subject, ENT_QUOTES, 'UTF-8')); $mail->setHtml($this->load->view('mail/customer_deny', $mail_data)); $mail->setTo($this->config->get('config_email')); $mail->send(); } ]]></add> </operation> </file> </modification>
Code: Select all
//Set the time that the admin logged in
$login_time = date('d-m-Y H:i:s');
$this->model_user_user->custom_adminLogTime($login_time);
Code: Select all
public function custom_adminLogTime() {
$this->db->query("UPDATE " . DB_PREFIX . "user SET last_login = '" . $this->db->escape(date('Y-m-d H:i:s')) . "' WHERE username = '" . $this->request->post['username'] . "'");
Total noob, don't really understand how to do this with events. Ive looked into events but they just seem confusing to mejust copy and adapt the logic of one of the admin mail events like admin/controller/mail/transaction.php and set the trigger on model admin/model/user/user/deleteLoginAttempts/before, that function is called when a user successfuly signs in.
~ OC 3.0.3.2 and OCmods only ~
Well, then you would have to request some commercial support which should be relatively cheap as this is pretty straightforward.Total noob, don't really understand how to do this with events. Ive looked into events but they just seem confusing to me
Probably just create an OCMOD to add to this file:
/admin/controller/common/login.php
Just below line 15 which is:
Code: Select all
$this->session->data['user_token'] = token(32);
UK OpenCart Hosting | OpenCart Audits | OpenCart Support - please email info@antropy.co.uk
paulfeakins wrote: ↑Tue Dec 31, 2024 7:33 pmProbably just create an OCMOD to add to this file:
/admin/controller/common/login.php
Just below line 15 which is:Add some code to email you and job done.Code: Select all
$this->session->data['user_token'] = token(32);
Well that should do it.Add some code to email you and job done.
Unfortunately your code doesn't work for 3.0.4.0 - there is no ![CDATA[function refresh]]> in file path="admin/controller/marketplace/modification.php, and it isn't there in 3.0.3.6 either...Joe1234 wrote: ↑Tue Dec 31, 2024 2:41 amCode: Select all
<?xml version="1.0" encoding="utf-8"?> <modification> <name>MY CUSTOM: Admin Last Login Time</name> <version>1.0</version> <author>Just Me</author> <code>MY_CUSTOM_Admin_Last_Login_Time</code> <file path="admin/controller/marketplace/modification.php"> <operation> <search><![CDATA[function refresh]]></search> ...
Unfortunate as this would have solved my similar question...
@jrr, that function is only utilized to automate the addition of the table column upon install. You can simply remove that part of the mod and add the column manually in your database.
@nonnedelectari, true, I made an edit and forgot to clean up old code.
v3.0.4.0 php 8.1
I'm here for a reason, if your response is contact a/the developer, just don't reply.
Ah, yes, thanks Paul - but those of us who can't code their way out of a wet paper bag are kinda stuck... (ducking) which is why folks like you, Johnathan, Mona, MaxD, and so many others are handy to have around!paulfeakins wrote: ↑Tue Dec 31, 2024 7:33 pmProbably just create an OCMOD to add to this file:
/admin/controller/common/login.php
Just below line 15 which is:Add some code to email you and job done.Code: Select all
$this->session->data['user_token'] = token(32);
I think I have a chance of solving this riddle if I look at how emails are sent for error messages, etc. once I figure out what user_token is - and how to set that to 'admin' or other login person I want to get an email notification about their logging in.
However tonight is New Years Eve, so HAPPY NEW YEAR folks! I hope 2025 is good for you and your families and friends!
No it does not send email upon admin login and I do not see any errors in the oc_error.log
What I meant in previous post is that my admin page started working again. At first right after the install of the odmod, my admin page was blank (white... nothing on it), but on second admin login the admin page was back to normal.
~ OC 3.0.3.2 and OCmods only ~
Just:
-replace the email address with your email address
-zip it
-rename it: admin_login_email.ocmod.zip
-and install it
Simple, but does the job ツ
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<modification>
<name>Send email on Admin Login</name>
<code>Send email On Admin Login</code>
<version>1.0</version>
<author>opencart.com username: MyOpe</author>
<link>https://forum.opencart.com/viewtopic.php?p=876242</link>
<file path="admin/controller/common/login.php">
<operation error="skip">
<search>
<![CDATA[$this->session->data['user_token'] = token(32);]]>
</search>
<add position="after">
<![CDATA[
$ip_address = '';
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip_address = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip_address = $_SERVER['REMOTE_ADDR'];
}
if (!empty($_SERVER['HTTP_REFERER'])) {
$refer = $_SERVER['HTTP_REFERER'];
} else {
$refer = 'referrer not found';
}
$to = "YOUR@EMAIL.HERE"; //the address the email is being sent to
$subject = "Admin LOGIN"; //the subject of the message
$msg = "Admin LOGIN
<br><br>
Admin: {$this->request->post['username']}<br>
Referer: {$refer}<br>
From IP: <a href='https://whatismyipaddress.com/ip/{$ip_address}'>https://whatismyipaddress.com/ip/{$ip_address}</a><br>"; //the message of the email
// Set content-type header for sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
// Additional headers
$headers .= 'From: YOURNAME <noreply@YOUR.EMAIL>' . "\r\n";
mail($to, $subject, $msg, $headers); //send the email
]]>
</add>
</operation>
</file>
</modification>
~ OC 3.0.3.2 and OCmods only ~
Is there another way to retrieve the login name than:
Code: Select all
Admin: {$this->request->post['username']}
Code: Select all
$ip_address = '';
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip_address = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip_address = $_SERVER['REMOTE_ADDR'];
}
if (!empty($_SERVER['HTTP_REFERER'])) {
$refer = $_SERVER['HTTP_REFERER'];
} else {
$refer = 'referrer not found';
}
$to = "jrr@flippers.com"; //the address the email is being sent to
$subject = "Admin LOGIN"; //the subject of the message
$msg = "Admin LOGIN
<br><br>
Admin: {$this->request->post['username']}<br>
Referer: {$refer}<br>
From IP: <a href='https://(stuff)/admin/ip/{$ip_address}'>https://(stuff)/admin/ip/{$ip_address}</a><br>"; //the message of the email
// Set content-type header for sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
// Additional headers
$headers .= 'From: JRR <noreply@flippers.com>' . "\r\n";
mail($to, $subject, $msg, $headers); //send the email
Maybe someone else can tell us how to pull username another way.
PS put your code after line 15
Code: Select all
$this->session->data['user_token'] = token(32);
~ OC 3.0.3.2 and OCmods only ~
Right you are!supak111 wrote: ↑Thu Jan 02, 2025 12:20 pmNot sure why it's not working on your 3.0.4.0. Login.php file is pretty much the same as my 3.0.3.2.
Maybe someone else can tell us how to pull username another way.
PS put your code after line 15Code: Select all
$this->session->data['user_token'] = token(32);
Putting the script after line 15 has it working as it should - emails now show login name and IP address.
Must be like real estate - location, location, location!
However in your original xml creation you have this:
Code: Select all
<search>
<![CDATA[$this->session->data['user_token'] = token(32);]]>
</search>
<add position="after">
<![CDATA[
I think the <![CDATA[ bit is incomplete or incorrect - I've tried variations <![CDATA[$this->session->data['user_token'] = token(32);]]> or <$this->session->data['user_token'] = token(32);> to no avail...but that is just me flailing around.
Thanks!
John :-#)#
If you are hardcoding the code into the login.php file directly (hardcoding is never really recommended), you don't need the code below, and you don't need a bunch of other code from my original file
Code: Select all
<search>
<![CDATA[$this->session->data['user_token'] = token(32);]]>
</search>
<add position="after">
<![CDATA[
~ OC 3.0.3.2 and OCmods only ~
this:
Code: Select all
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
That should be taken into account.
Code: Select all
$ip_address = '';
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip_address = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip_list = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
$ip = trim($ip_list[0]);
if (filter_var ($ip, FILTER_VALIDATE_IP)) $ip_address = $ip;
}
if ($ip_address === '') $ip_address = $_SERVER['REMOTE_ADDR'];
Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 57 guests