How to pass all nav-items from an array to all views in Laravel - arrays

I know this is a bit silly and probably been asked many times but for this one is unique. I'm just asking just for the sake of learning. I have these arrays inside home():
public function home()
{
$menus = [ '视频', '直播', '路亚', '海钓', '渔获' ];
$submenus1 = [ '视频', '直播', '路亚', ];
return view('/layout', [
'menus' => $menus,
'submenus1' => $submenus1,
]);
}
So it's like Nav items. And these items, I want them to be available in all views. Help would be much appreciated. Please respect. Thank you.

You can pass any data with View::share() method in App/Providers/AppServiceProvider.php file. Please check following codes;
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
$menus = [ '视频', '直播', '路亚', '海钓', '渔获' ];
$submenus1 = [ '视频', '直播', '路亚', ];
View::share('menus', $menus);
View::share('submenus1', $submenus1);
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
$this->app->bind('path.public', function() {
return base_path('public_html');
});
}
}
After than you can use $menus and $submenus1 variables anywhere

Related

How to send notifications to Laravel Users with Onesignal notification channel?

I'm trying to use laravel-notification-channels/onesignal with Laravel 9, Inertia React project.
For first I setup the client in this way:
useEffect(() => {
OneSignal.init({
appId: "PRIVATE-KEY"
});
}, []);
Testing from Onesignal panel the client is listening.
For the back-end I have created a Notification:
<?php
namespace App\Notifications;
use NotificationChannels\OneSignal\OneSignalChannel;
use NotificationChannels\OneSignal\OneSignalMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\BroadcastMessage;
use App\Models\Order;
class OrderPlacedNotification extends Notification
{
use Queueable;
public $order;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(Order $order)
{
$this->order = $order;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database', 'broadcast', OneSignalChannel::class];
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'order' => $this->order,
];
}
public function toBroadcast($notifiable)
{
return new BroadcastMessage([
'order' => $this->order
]);
}
public function toOneSignal($notifiable)
{
return OneSignalMessage::create()
->setSubject("Nuovo ordine!")
->setBody("Vedi l'ordine.")
->setUrl('http://onesignal.com');
}
}
and I send the notification via controller to all users.
All config setted but I can't listen to the user.
I found the solution. In my client I subscibe user to the specific interest and in backend I send notifictions at the users with that specific interest:
Frontend
useEffect(() => {
if(auth.user) {
window.Echo.private(`App.Models.User.${auth.user.id}`).notification(notification => {
console.log(notification);
setNotifications(() => [...notifications, notification]);
})
OneSignal.init(
{
appId: "KEY",
},
//Automatically subscribe to the new_app_version tag
OneSignal.sendTag("orders", "orders", tagsSent => {
// Callback called when tag has finished sending
console.log('TAG SENT', tagsSent);
})
);
}
}, [notifications]);
User Model:
public function routeNotificationForOneSignal()
{
return ['tags' => ['key' => 'orders', 'relation' => '=', 'value' => 'orders']];
}

how to access multiple array elements in blade file laravel

Rating model
class Rating extends Model
{
protected $fillable = [
'owner_id', 'toilet_id','user_id','rating','desc',
];
public function toilet()
{
return $this->belongsTo(ToiletInfo::class);
}
}
ToiletInfo model
class ToiletInfo extends Model
{
protected $fillable = [
'owner_id', 'toilet_name','price','complex_name','address','toilet_lat','toilet_lng','status',
];
public function owner()
{
return $this->belongsTo(ToiletOwner::class);
}
public function ratings()
{
return $this->hasMany(Rating::class,'toilet_id');
}
}
RatingController
public function index()
{
return $toilets = ToiletInfo::with('ratings')->get();
//return view('admin.rating',compact('toilets'));
}
I want to get the average of rating but how to access elements inside ratings[]
Or help me improve the method I am using to get ratings for toilets that are reviewed by users
From what I understand from your question you want to get the average rating.
In your ToiletInfo model, add a new method:
public function getAverageRating()
{
$ratings = $this->ratings;
$count = $ratings->count(); // total count
$total_ratings = $ratings->sum('rating'); // add the 'rating' for all rows
return $total_ratings / $count; // average
}
In your blade file, you can simply do
$toilet->getAverageRating()
Which will give the average rating.

Laravel issue whilst iterating using Map - (Update Global Variable outside map function)

I have a controller that should return a list of categories. Each should also have a collection of sub-categories. Each sub-category should also have modules. The modules are of two types: the latest modules and most watched modules.
A SUMMARY STRUCTURE I WANT:
[
{
id: 1,
name: category 1,
sub_categories:
[
{
id: 1,
name: subcategory 1:
modules:
[
latestModules: [...],
mostViewedModules[...]
]
}
],
another sub-category object,
and another sub-category object
},
another category object,
and another category object,
]
My Controller
class SeriesController extends Controller
{
public function getSeries()
{
$categories = Category::with('SubCategories')->get();
$countCats = 0;
$countSubCats = 0;
collect($categories)->map(function ($category) use ($countCats, $countSubCats, $categories){
collect($category->subCategories)->map(function ($subCategory) use ($countSubCats, $categories) {
collect($categories[$countCats]->subCategories[$countSubCats])
->put('modules',
SubCategory::with('latestModules', 'mostViewedModules')
->where('id', $subCategory->id)->get()
);
$countSubCats++;
});
$countCats++;
});
return $categories;
}
}
My Category model
class Category extends Model
{
public function subCategories()
{
return $this->hasMany('App\SubCategory')
->orderby('name');
}
}
My Subcategory Model
class SubCategory extends Model
{
public function parentCategory(){
return $this->belongsTo('App\Category', 'category_id');
}
public function modules()
{
return $this->belongsToMany('App\Module', 'module_category', 'sub_category_id', 'module_id');
}
public function latestModules()
{
return $this->modules()
->orderBy('created_at', 'desc');
}
public function mostViewedModules()
{
return $this->modules()
->orderBy('views', 'desc');
}
}
My Module Model
class Module extends Model
{
public function subCategories()
{
return $this->belongsToMany('App\SubCategory', 'module_category', 'module_id', 'sub_category_id');
}
}
WHAT I WAS TRYING TO DO
1) Get all the categories via Eloquent Query
2) Collect the many categories and Map over them
3) For each ONE category i map over again to single it out into sub-categories
4) For each sub-category i run Eloquent query to return the related modules.
5) Then i put that result into categories original array by using PUT. I wanted to expand on the original $categories array by including the modules.
PROBLEM
I realize that the loop works and everything is fine, except that the global $categories variable does not update. Its like inside the loops its updated but once we exist the Map loops the value defaults to
Category::with('SubCategories')->get()

FOSUserBundle: Success target after password reset according to roles

After the user did reset his password using the password reset of FOSUserBundle, by default he is redirected to the FOSUserProfile. I want to redirect to a different route according to their role. Is this possible and if yes, how?
I do this code but it redirect all kind of users
namespace Acme\UserBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Listener responsible to change the redirection at the end of the password resetting
*/
class PasswordResettingListener implements EventSubscriberInterface {
private $router;
public function __construct(UrlGeneratorInterface $router) {
$this->router = $router;
}
public static function getSubscribedEvents() {
return [
FOSUserEvents::RESETTING_RESET_SUCCESS => 'onPasswordResettingSuccess',
];
}
public function onPasswordResettingSuccess(FormEvent $event) {
$url = $this->router->generate('homepage');
$event->setResponse(new RedirectResponse($url));
}
}
And then I registering it as a service with
services:
acme_user.password_resetting:
class: Acme\UserBundle\EventListener\PasswordResettingListener
arguments: [ "#router" ]
tags:
- { name: kernel.event_subscriber }
Based on your version of Symfony you can choose one of the approaches described in: http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements
For example you can use security.authorization_checker service:
Inject it into your service:
services:
acme_user.password_resetting:
class: Acme\UserBundle\EventListener\PasswordResettingListener
arguments: [ "#router", "#security.authorization_checker" ]
tags:
- { name: kernel.event_subscriber }
Then in your actual service:
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
/**
* Listener responsible to change the redirection at the end of the password resetting
*/
class PasswordResettingListener implements EventSubscriberInterface {
private $router;
private $authorizationChecker;
public function __construct(UrlGeneratorInterface $router, AuthorizationChecker $authorizationChecker) {
$this->authorizationChecker = $authorizationChecker;
$this->router = $router;
}
public static function getSubscribedEvents() {
return [
FOSUserEvents::RESETTING_RESET_SUCCESS => 'onPasswordResettingSuccess',
];
}
public function onPasswordResettingSuccess(FormEvent $event) {
//$url = $this->router->generate('homepage');
//$event->setResponse(new RedirectResponse($url));
if (false === $this->authorizationChecker->isGranted('ROLE_ADMIN')) {
// redirect somewhere
} else {
// redirect elsewhere
}
}
}

How do I create a custom object class that's available to my methods in AngularJS

I'm a huge fan of angular but it's got some tricky concepts with extremely nuanced differences between them and this is one of them.
I just want to create an class that I can use to create custom objects in my Angular controllers and factories. It surely shouldn't be that hard but I can't figure out how to do it. I want to have a custom, ResultSet class which I can instantiate to create instances of ResultSet. However for the life of me I can't figure out the correct syntax of factory v. service to use.
This is all I want:
ResultSet = function(dataSet){
this.filter = function(){
# filters and returns dataSet
# ...
}
}
and then I want to be able instantiate an instance of ResultSet inside a controller etc:
MyApp.controller('pageCtrl', ['ResultSet', (ResultSet) ->
# ...
rs = ResultSet.new(dataToFilter)
How can I create a service that allows me to create instances of my custom object?
It seems more correct to use an Angular Service rather than a Factory since a service returns an instance of an object (which is exactly what I want). But I can't figure out how to do this...
How would I use a service to declare my custom ResultSet class and then how would I instantiate an instance from it?
Maybe you were looking for something like this:
.factory('User', function (Organisation) {
/**
* Constructor, with class name
*/
function User(firstName, lastName, role, organisation) {
// Public properties, assigned to the instance ('this')
this.firstName = firstName;
this.lastName = lastName;
this.role = role;
this.organisation = organisation;
}
/**
* Public method, assigned to prototype
*/
User.prototype.getFullName = function () {
return this.firstName + ' ' + this.lastName;
};
/**
* Private property
*/
var possibleRoles = ['admin', 'editor', 'guest'];
/**
* Private function
*/
function checkRole(role) {
return possibleRoles.indexOf(role) !== -1;
}
/**
* Static property
* Using copy to prevent modifications to private property
*/
User.possibleRoles = angular.copy(possibleRoles);
/**
* Static method, assigned to class
* Instance ('this') is not available in static context
*/
User.build = function (data) {
if (!checkRole(data.role)) {
return;
}
return new User(
data.first_name,
data.last_name,
data.role,
Organisation.build(data.organisation) // another model
);
};
/**
* Return the constructor function
*/
return User;
})
From this post by Gert Hengeveld.
myApp.factory('ResulSet', function() {
function ResultSetInstance(dataSet) {
this.filter = function(){
// ...
}
}
return {
createNew: function(dataSet) {
return new ResultSetInstance(dataSet);
}
};
});
and then
myApp.controller('pageCtrl', function(ResultSet) {
var someData = ...;
var rs = ResultSet.createNew(someData);
}
Edit (from the question asker)
On experimenting with this further I found that you didn't even need to have the createNew method.
myApp.factory('ResultSetClass', function() {
ResultSetClass = function(dataSet) {
this.filter = function(){
// ...
}
}
return ResultSetClass
});
works just fine and then you can call new ResultSetClass(args).
Note for those using Coffeescript
Coffeescript will return the last variable or method in your class instance so if you are using coffeescript (as a general rule), it's imperative to return this at the end of the class definition
myApp.factory 'ResultSetClass', () ->
ResultSetClass = (dataset) ->
this.filter = () ->
# do some stuff
return this
return ResultSetClass
If you don't return this explicitly then you'll find that when you call
myApp.factory 'ResultSetClass', () ->
ResultSetClass = (dataset) ->
this.filter = () ->
# do some stuff
then you'll simply be left with the last thing the coffeescript returns which is the filter method.
I recently has do do something like that because I wanted to implement a factory of class instance, and being able to configurate my instances and benefit from Angular Dependency injection. I ended up with something like that
// Implem
export class XAPIService {
private path: string;
/* this DO NOT use angular injection, this is done in the factory below */
constructor(
private seed: XAPISeed,
private $http: ng.IHttpService,
private slugService: SlugService
) {
const PATH_MAP: Map<Y, Z> = new Map([
['x', id => `/x/${id}`],
['y', id => `/y/${id}`],
]);
this.path = PATH_MAP.get(this.seed.type)(this.seed.id);
}
list() {
/* implem that use configured path */
return this.slugService
.from(this.path + `/x`)
.then(url => this.$http.get<IX>(url))
.then(response => response.data)
}
}
export type IXAPIFactory = (s: XAPISeed) => XAPIService;
export function XAPIFactory(
$http: ng.IHttpService,
myService: SlugService
) {
'ngInject';
return (seed: XAPISeed) =>
new XAPIService(seed, $http, myService);
}
// angular
angular.module('xxx', [])
.factory('xAPIFactory', XAPIFactory)
// usage in code
export class XsController implements ng.IComponentController {
/* #ngInject */
constructor(
private xAPIFactory: IXAPIFactory,
) {}
$onInit() {
this.xService = this.xAPIFactory({ id: 'aaabbbaaabbb', type: 'y' });
return this.xService.list()
.then(xs => {
this.xs = xs;
})
}
}

Resources