Laravel Service won't register - laravel

Followed every step from laravel 9 manual, and my service will not register consistently. Don't quite know why but it suddenly breaks and I receive a Target class [thumbnail] does not existerror out of nowhere.
Setup
Service:
namespace App\Services;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
class ThumbnailService
{
public function storeThumbnail($userId, $file, $scale) {
$thumbnail_image = Image::make($file);
$orig_width = $thumbnail_image->width();
$orig_height = $thumbnail_image->height();
$thumbnail_image->resize($orig_width * $scale, $orig_height * $scale);
$thumb_stream = $thumbnail_image->stream();
$thumb_path = env('MIX_AWS_IMAGES_DIRECTORY') . '/'. $userId . '/thumbnails';
$thumb_file = $thumb_path . '/' . 'thumb_1_4_' . $file->getClientOriginalName();
Storage::disk('s3')->put($thumb_file, $thumb_stream->__toString());
return $thumb_file;
}
}
Provider:
namespace App\Providers;
use App\Services\ThumbnailService;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
class ThumbnailServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->singleton('thumbnail', function() {
return new ThumbnailService();
});
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
}
public function provides()
{
return [ThumbnailService::class];
}
}
Facade:
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Thumbnail extends Facade
{
protected static function getFacadeAccessor() {
return 'thumbnail';
}
}
obviously, I did register in app.php in the providers array. But if I inspect the bindings, there is no service... Any help? This is the second time this happened and earlier, I got away with dumping autoload and config:clear and it is currently under my sail dev environment. I don't want this to happen in prod. So help would be appreciated.

Related

How to fire an event after data inserted using boot? (laravel)

I am finding a way to somewhat fire an event after the Eloquent has finished creating.
Here's my code in Branch model:
class Branch extends Model
{
//some code here
public static function boot() {
parent::boot();
self::created(function (HistoryLog $model) {
$model->tag = 'Created';
$model->description = 'This branch was created by '. ucwords(auth()->user()->name());
$model->save();
});
}
}
What I'm trying to do is, I want to create a history_log after branch was created.
But this code returns an error:
Symfony\Component\Debug\Exception\FatalThrowableError : Argument 1 passed to
App\Vehicle::App{closure}() must be an instance of App\HistoryLog, instance of
App\Vehicle given, called in D:\document\My Documents\optodph\vendor\laravel\fr
amework\src\Illuminate\Events\Dispatcher.php on line 347
Can someone point out to me what's wrong with that code? And what's the right way to achieve this?
Laravel way to do this.
Create an Observer:
php artisan make:observer BranchObserver --model=Branch
Add your logic to the Observer:
<?php
namespace App\Observers;
use App\Branch;
class BranchObserver
{
/**
* Handle the Branch "created" event.
*
* #param \App\Branch $branch
* #return void
*/
public function created(Branch $branch)
{
// Add your logic here
}
}
Register it in AppServiceProvider:
<?php
namespace App\Providers;
use App\Branch;
use App\Observers\BranchObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Branch::observe(BranchObserver::class);
}
}
$model is a new record created. Is an instance of App\Vehicle not a App\HistoryLog.
Working code might look like this:
class Vehicle extends Model
{
//some code here
public static function boot() {
parent::boot();
self::created(function ($model) {
App\HistoryLog::create([...]);
});
}
}
You can also achieve this with Eloquent Observers https://laravel.com/docs/5.8/eloquent#observers

Display counter variable in my layout.app.blade in Laravel

i want to display the counter in my app.blade which being called in all pages like the screenshot below
I only have this function in my controller
class ReportsController extends Controller
{
public function invoiceTransaction()
{
$salespayments = Salespayments::where('type','=','check')->get();
$countUnread = Salespayments::select(DB::raw("SUM(unread) as unread"))->get();
return view('reports.invoiceTransactions')
->with('salespayments', $salespayments)
->with('countUnread', $countUnread);
}
}
And I am calling the counter in my blade by this {{$countUnread[0]->unread}}
How can I make that function be readable in my app.blade.php? thanks a lot!
In your AppServiceProvider you can share the sum result across all views by using view()->share();
Like this:
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot() {
$countUnread = Salespayments::sum('unread');
view()->share('countUnread', $countUnread);
}
Make a service provider first,
php artisan make:provider CounterServiceProvider
Then in your CounterServiceProvider file.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Views\Composers;
class CounterServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
// here define your master layout
$this->app['view']->composer(['master'], Composers\Counter::class);
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
Now in your App\Views\Composers folder add Counter class.
<?php
namespace App\Views\Composers;
use Illuminate\View\View;
class Counter {
public function compose(View $view)
{
$view->with('countUnread', session('countUnread'));
}
}
Make sure you add your CounterServiceProvider in config/app.php file's providers array.

Problems creating a ComposerServiceProvider in Laravel 5.4

Im working on a Laravel 5 app and im trying to set up a ComposerServiceProvider to pass data to a couple of views (im trying now to add it to the layout/app.blade.php).
I did this following the documentation but the data im trying to add is still undefined..
In my config/app.php I added to the providers:
App\Providers\ComposerServiceProvider::class,
On ComposerServiceProvider.php
boot method:
View::composer(['layouts.app'], 'App\ViewComposers\LayoutAppComposer');
On the new created LayoutAppComposer.php
compose(View $view) method:
$metaTitle = 'MetaTitle';
$view->with('metaTitle', $metaTitle)
But When i access the url I still get:
Undefined variable: metaTitle (View: .../resources/views/layouts/app.blade.php)
Am I missing something here??
ServiceProvider
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
View::composer(['layouts.app'], 'App\ViewComposers\LayoutAppComposer');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
}
}
LayoutAppComposer
<?php
namespace App\ViewComposers;
use Illuminate\Support\Facades\Session;
use Illuminate\View\View;
class LayoutAppComposer {
protected $metaTitle;
public function __construct($metaTitle)
{
$this->metaTitle = $metaTitle;
}
/**
* Bind data to the view.
*
* #param View $view
* #return void
*/
public function compose(View $view) {
$this->metaTitle = 'MetaTitle';
$view->with('metaTitle', $this->metaTitle);
}
}
Try changing:
$metaTitle = 'MetaTitle';
$view->with('metaTitle', $metaTitle)
to
$this->metaTitle = 'metaTitle';
$view->with('metaTitle', $this->metaTitle)
setup $this->metaTitle as a protected class member and assign it in the composer constructor. it may be that $metaTitle is getting garbage collected before you use it since this being resolved at the service provider level.
Since you're registering the composer with your app layout, instead you may need to use the wildcard character in place of app.layout like such:
View::composer('*', function ($view) {
//
});
To resolve $metaTile for the View Composer, try binding in your AppServiceProvider:
$this->app->bind('metaTitle', 'the string i want displayed across all views');

How to properly add external php files in Laravel 5

I have a small websockets chat written, the php part is just 2 files, server.php and Chat.php, they are both inside a bin folder and depend on ratchet and some other libraries which I downloaded to the laravel installation via composer.
server.php
require __DIR__.'/../vendor/autoload.php';
require 'Chat.php';
use Ratchet\Server\IoServer;
use Ratchet\http\HttpServer;
use Ratchet\WebSocket\WsServer;
$server = IoServer::factory(new HttpServer(new WsServer(new Chat)), 8080);
$server->run();
Chat.php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $conn, $msg)
{
foreach ($this->clients as $client)
{
if ($client !== $conn ) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e)
{
echo 'the following error occured: ' . $e->getMessage();
$conn->close();
}
}
Now, I have that bin folder inside the laravel root, and so I am able to start the server since the server.php is looking for dependencies in vendor one level up, but what I wanna do is use all the laravel goodies within these files, especially within Chat.php.
So now for example if I write use DB in Chat.php it gives an error (which I understand, it has no way of knowing laravel), so my question is how do I include this bin folder and its files so that I can use all the laravel goodies within them?
You do not need to manually load vendor/autoload.php because laravel does that for you.
First you have to create folder inside your YourLaravelRoot/app dir(Let's name that as Services). Then move chat.php into that, rename it to ChatService.php(Change class name also to ChatService) or any appropriate name(reccomanded to ends with xxxxService so it's easier to identify) and namespace it as namespace App\Services;(Assumming that your app name is App).Namespacing correctly is important otherwise you have to manually loads it throught composer.json .Then create a artisan command and move content of server.php into handle method inside command(Let's name it ServerCommand.php). Add use App\Services\ChatService as Chat;. Register the command in Kernal.php on app/console That's it. Now you should be able to access any laravel facade inside ChatService
Summary:
YourLaravelProject
-app
--Console
Kernal.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
Commands\ServerCommand::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
}
---Commands
----ServerCommand.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use App\Services\ChatService as Chat;
class ServerCommand extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'server:run';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$server = IoServer::factory(new HttpServer(new WsServer(new Chat)), 8080);
$server->run();
}
}
--Services
---ChatService.php
<?php
namespace App\Services;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
/**
*
*/
class ChatService implements MessageComponentInterface {
{
protected $clients;
function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
}
public function onMessage(ConnectionInterface $conn, $msg)
{
foreach ($this->clients as $client)
{
if ($client !== $conn ) {
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e)
{
echo 'the following error occured: ' . $e->getMessage();
$conn->close();
}
}
Execute command php artisan server:run

Laravel 5 Command and Handler issue

I am working one of my project with laravel 5. During the implementation i got struct with one issue which is related to command and handler.
I used artisan command to generate command
php artisan make:command TestCommand --handler
I generated command at app/commands folder "TestCommand.php"
<?php
namespace App\Commands;
use App\Commands\Command;
class TestCommand extends Command
{
public $id;
public $name;
public function __construct($id, $name)
{
$this->id = $id;
$this->name = $name;
}
}
Also my TestCommandHandler.php looks like this
<?php
namespace App\Handlers\Commands;
use App\Commands\TestCommand;
use Illuminate\Queue\InteractsWithQueue;
class TestCommandHandler
{
/**
* Create the command handler.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the command.
*
* #param TestCommand $command
* #return void
*/
public function handle(TestCommand $command)
{
dd($command);
}
}
Whenever dispatch this command from controller it shows following issue
InvalidArgumentException in Dispatcher.php line 335:
No handler registered for command [App\Commands\TestCommand]
Please, Anybody help me to solve this problem. Thank you
By default Laravel 5.1.x does not included BusServiceProvider. So we should create BusServiceProvider.php under provider folder and include that in to config/app.php.
BusServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Bus\Dispatcher;
use Illuminate\Support\ServiceProvider;
class BusServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* #param \Illuminate\Bus\Dispatcher $dispatcher
* #return void
*/
public function boot(Dispatcher $dispatcher)
{
$dispatcher->mapUsing(function($command)
{
return Dispatcher::simpleMapping(
$command, 'App\Commands', 'App\Handlers\Commands'
);
});
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
config/app.php
'providers' => [
App\Providers\BusServiceProvider::class
]
So it may help others. Thank you

Resources