Laravel 9, send notification with preferredLocale - laravel

I am creating a bilingual application in which I have implemented database and e-mail notifications.
A notification is, for example, information that a user has started a new conversation. Unfortunately, notifications sent to the database are sent in the language of the user who sends them (set language: App::setLocale(Auth()->user->locale);) and not in the language of the recipient.
I use:
use Illuminate\Contracts\Translation\HasLocalePreference;
class User extends Model implements HasLocalePreference
{
/**
* Get the user's preferred locale.
*
* #return string
*/
public function preferredLocale()
{
return $this->locale;
}
}
Oddly enough, email notifications work this way.
I translate notifications like this:
$customer->notify(new NewMessageNotification($message, trans('notifications.new_message', ['user' => $user->name])));
I tried this way, but it didn't change anything:
https://setkyar.medium.com/fixing-laravels-notification-locale-issue-9ad74c2652ca
Although now I'm wondering if it wouldn't be better to save in the key base and translate only when reading, so that all received notifications are translated when changing the language. The only question is how to do it then.

If i understand well, you want to send notification based on destination language and not based on sender one. If yes, preferredLocale may not works, but you can try to define the language on notification trigger like this:
$customer->notify(new NewMessageNotification($message, trans('notifications.new_message', ['user' => $user->name]))->locale('pt'));

I found that I save to the database in both languages ​​and when reading, I check the language set by the user to display the appropriate version.
On second thought, it seems more logical to have notifications displayed in the currently set language rather than when sent.

Related

laravel - if the database changes, send notification

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!

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.

Joomla Error Messages for Specific User Group

I'm trying to set up customer error messages for different user groups in Joomla 3.6. We have locked content on the front-end of our site, currently there is a generic message that tells the user to login to see it, however we recently adjusted our user groups to create multiple levels of access so even after logging in there may still be content the user can't see. In those instances I need to be able to show a message specific to that user group rather than a generic "please login".
I have used Language Overrides for custom messages before but there's no option I've found to have it show to specific groups. I don't know a lot about code, and Google revealed no existing answers for this.
This might be something to get you going:
$groups = JUserHelper::getUserGroups((int) $user->user_id);
if(in_array(8, $groups))
{
$level = 'admin';
} elseif (in_array(4, $groups)) {
$level = 'globalmoderator';
} elseif (in_array(3, $groups)) {
$level = 'moderator';
} elseif (in_array(2, $groups)) {
$level = 'user';
} else {
$level = 'guest';
}
Without some programming it'll not be easy for you to achieve. But in short, you can create a pretty simple plugin, which will capture certain Joomla events.
For example, Joomla has onUserLogin even, which allows you to do different stuff, when user logs in. Your custom plugin can capture this even, check for some parameters and then add a group specific message to the queue. More over, you can get current message queue, parse or empty it and then add group specific message.
You can do the same for any other Joomla event like onUserLogout, onUserLoginFailure and so on. There're plenty events to choose from.
As for message specific groups, you can add your own generic messages similar to this:
COM_USERS_ERROR_LOGIN_GUEST
COM_USERS_ERROR_LOGIN_REGISTERED
COM_USERS_ERROR_LOGIN_ADMIN
Then you just take "COM_USERS_ERROR_LOGIN_" string and add a group name (or ID, when language is non-English) to it. That's it.
The task doesn't seem too complex, but you still have to know some coding to create a plugin, which will capture Joomla events. There's no other way to do this.
Try to use articles for messages and filter it with permissions for user groups.

How to deal with non existent emails

I am making an app that allow to register to a newsletter and then manage it.
There is the normal validation if the field is empty, if is email type, unique ecc..
But how can i check if the email really exists?
If someone enter a fake mail, that mail is entered in the database, and this can mess up the database. And there are other annoyance.
Is possible to check if the mail really exists?
Otherwise it is possible to automatically delete an unregistered user after 10 days?
You can create a rule to check if the e-mail format is valid:
$validator = Validator::make(
Input::all(),
array('email' => 'required|email')
);
if ($validator->fails())
{
return "This is not a valid e-mail";
}
But this will only check for the format (name#domain.tld), because there is no way to know if an e-mail address really exists.
Well... this is not entirely true, there is a way: send an e-mail to that address and if you don't get an error message, the address exists, probably.
The best way to do what you need is, when a user creates an account in your system, send him/her a confirmation e-mail, with a link where he/she should click to validate that address. If the account is not validated for x days you delete it. This is a question that might help you on that: Laravel 4: how to make confirmation email?.
About your last question: create an Artisan Command that checks for unvalidated accounts and delete them. Take a look at the docs, it's easy, Laravel does almost all the job for you. And you can run this command once a day using cron or task manager:
php /var/www/your-site-dir/artisan check:accounts
EDIT:
This question will show you how to create a command: Creating and using Laravel 4 commands
And in the method fire() you should do something like:
public function fire()
{
$dt = Carbon\Carbon::now();
User::where('activated', false)
->where('created_at', '<', $dt->subDays(10))
->delete();
}
There are some APIs you can use to verify the validity and existence of emails, but I am not sure how good they are. The free ones usually limit you to something like 10 an hour which probably would not be nearly enough for you, depending on how busy your site is.
Check out http://verify-email.org/register/levels.html
If you are worried about the sheer amount of emails being entered, you could probably log $_SERVER['REMOTE_ADDR'], which would be the client's IP address in the DB on emails and check to make sure that is unique as well before you save additional records to the table.
As far as how to actually validate the existence and validity of the entered email yourself, I believe you'd have to use fsockopen and issue smtp commands to servers. I did find this php class which attempts to do what we are talking about http://www.webdigi.co.uk/blog/wp-content/uploads/2009/01/smtpvalidateclassphp.txt
I doubt it works, but should get you a nice starting point.

Magento Multiple Authorize.net Gateways

I've seen this question asked with regard to currency type, but what I am asking is how to configure a second Authorize.net account on the same store for a different credit card type. So, we want some credit cards to use the first main Authorize.net gateway, but the others to use the secondary Authorize.net account so that the payments can be routed into two different bank accounts. This is for purposes of reconciliation and is a constraint; can't be modified.
I'm figuring that all I need to do is figure out once the order has been submitted (but before it has been sent via API to Authorize.net) which card type it is, to know which credentials to pass to the API, but I'm unsure as to where to add this code, or the best way in which to add it.
Any insight or advice would be greatly appreciated.
By default, there is no way to accomplish this, so you'll need to use some custom code. Specifically, override the Authnet payment class Mage_Paygate_Model_Authorizenet:
class MyNamespace_MyModule_Model_Authorizenet extends Mage_Paygate_Model_Authorizenet {
/**
* Prepare request to gateway
*
* #link http://www.authorize.net/support/AIM_guide.pdf
* #param Mage_Sales_Model_Document $order
* #return unknown
*/
protected function _buildRequest(Varien_Object $payment)
//see below
}
}
In that function, on line 277 for me, the following code is executed to set the Authnet account:
$request->setXLogin($this->getConfigData('login'))
->setXTranKey($this->getConfigData('trans_key'))
->setXType($payment->getAnetTransType())
->setXMethod($payment->getAnetTransMethod());
Instead, you want something along these lines:
if(whatever cc type) {
// set alternate gateway
} else {
// set default gateway
}
To accomplish this, you'll also want to create new options in the backend to hold the credentials in an encrypted form. Hope that helps!
Thanks,
Joe

Resources