Archaeologists Have Just Discovered CONCLUSIVE PROOF Of The Bible: A Rock In The Red Sea That Says ‘Moses Wuz Here’

https://media.babylonbee.com/articles/article-11387-1.jpg

CAIRO—Nautical archaeologists have at last discovered the exact location of where the Israelites crossed the Red Sea, having found a rock reading “Moses Wuz Here”.

“It seems a bit juvenile, but the evidence is unmistakable,” said archaeologist Benjamin Ioset. “We found it right next to several Egyptian chariots, along with another rock that said ‘Here The Lord Pwned Pharoah’.”

The revelation has lead to a cascade of breakthroughs in tracing the exodus route of ancient Israel. “With this rock in our possession, experts can now match the handwriting to other markers in the desert and we can follow the steps of Moses,” said Mr. Ioset. “For example, we have already discovered a match at the site of Israel’s battle with the Amalekites, where Moses had to keep his staff raised above his head for several hours. There is a small inscription which simply reads ‘Arm Day FTW!’. We also have found in Ancient Midian, where Moses met his wife, an inscription in a cave reading ‘Moses+Zipporah 4Eva’. We really hit the jackpot here!”

Scholars had hoped that this would lead to finally discovering the famed Ark Of The Covenant. Sources say that an archaeology team reportedly found what they believed may be the Ark, but they accidentally touched it and no one’s heard from them since.

At publishing time, experts discovered Moses’ handwriting also displayed a startling similarity to the writing of Mr. Charlton Heston.

Checkmate, atheists!


In the social justice system, words are considered violence. In New York City, the dedicated detectives who investigate these vicious attacks are members of an elite squad known as the Microaggression Victims Unit. These are their stories.

Subscribe to The Babylon Bee on YouTube

The Babylon Bee

Restructuring a Laravel Controller using Services, Events, Jobs, Actions, and more

https://laravelnews.imgix.net/images/controller-refactor.jpg?ixlib=php-3.3.1

One of the top Laravel questions I hear is “How to structure the project”. If we narrow it down, the largest part of it sounds like “If the logic shouldn’t be in Controllers, then where should we put it?”

The problem is there is no single correct answer to such questions. Laravel gives you the flexibility to choose the structure yourself, which is both a blessing and a curse. You won’t find any recommendations in the official Laravel docs, so let’s try to discuss various options, based on one specific example.

Notice: as there’s no one way to structure the project, this article will be full of side-notes, “what if” and similar paragraphs. I advise you don’t skip them, and read the article in full, to be aware of all the exceptions to the best practices.

Imagine you have a Controller method for registering users that does a lot of things:

1public function store(Request $request)

2{

3 // 1. Validation

4 $request->validate([

5 'name' => ['required', 'string', 'max:255'],

6 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],

7 'password' => ['required', 'confirmed', Rules\Password::defaults()],

8 ]);

9 

10 // 2. Create user

11 $user = User::create([

12 'name' => $request->name,

13 'email' => $request->email,

14 'password' => Hash::make($request->password),

15 ]);

16 

17 // 3. Upload the avatar file and update the user

18 if ($request->hasFile('avatar')) {

19 $avatar = $request->file('avatar')->store('avatars');

20 $user->update(['avatar' => $avatar]);

21 }

22 

23 // 4. Login

24 Auth::login($user);

25 

26 // 5. Generate a personal voucher

27 $voucher = Voucher::create([

28 'code' => Str::random(8),

29 'discount_percent' => 10,

30 'user_id' => $user->id

31 ]);

32 

33 // 6. Send that voucher with a welcome email

34 $user->notify(new NewUserWelcomeNotification($voucher->code));

35 

36 // 7. Notify administrators about the new user

37 foreach (config('app.admin_emails') as $adminEmail) {

38 Notification::route('mail', $adminEmail)

39 ->notify(new NewUserAdminNotification($user));

40 }

41 

42 return redirect()->route('dashboard');

43}

Seven things, to be precise. You will all probably agree that it’s too much for one controller method, we need to separate the logic and move the parts somewhere. But where exactly?

  • Services?
  • Jobs?
  • Events/listeners?
  • Action classes?
  • Something else?

The trickiest part is that all of the above would be the correct answers. That’s probably the main message you should take home from this article. I will emphasize it for you, in bold and caps.

YOU ARE FREE TO STRUCTURE YOUR PROJECT HOWEVER YOU WANT.

There, I said it. In other words, if you see some structure recommended somewhere, it doesn’t mean that you have to jump and apply it everywhere. The choice is always yours. You need to choose the structure that would be comfortable for yourself and your future team to maintain the code later.

With that, I probably could even end the article right now. But you probably want some “meat”, right? Ok, fine, let’s play around with the code above.


General Refactoring Strategy

First, a “disclaimer”, so it would be clear what we’re doing here, and why. Our general goal is to make the Controller method shorter, so it wouldn’t contain any logic.

Controller methods need to do three things:

  • Accept the parameters from routes or other inputs
  • Call some logic classes/methods, passing those parameters
  • Return the result: view, redirect, JSON return, etc.

So, controllers are calling the methods, not implementing the logic inside the controller itself.

Also, keep in mind, that my suggested changes are only ONE way of doing it, there are dozens of other ways which would also work. I will just provide you with my suggestions, from personal experience.


1. Validation: Form Request classes

It’s a personal preference, but I like to keep the validation rules separately, and Laravel has a great solution for it: Form Requests

So, we generate:

1php artisan make:request StoreUserRequest

We move our validation rules from the controller to that class. Also, we need to add the Password class on top and change the authorize() method to return true:

1use Illuminate\Validation\Rules\Password;

2 

3class StoreUserRequest extends FormRequest

4{

5 public function authorize()

6 {

7 return true;

8 }

9 

10 public function rules()

11 {

12 return [

13 'name' => ['required', 'string', 'max:255'],

14 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],

15 'password' => ['required', 'confirmed', Password::defaults()],

16 ];

17 }

18}

Finally, in our Controller method, we replace Request $request with StoreUserRequest $request and remove the validation logic from the Controller:

1use App\Http\Requests\StoreUserRequest;

2 

3class RegisteredUserController extends Controller

4{

5 public function store(StoreUserRequest $request)

6 {

7 // No $request->validate needed here

8 

9 // Create user

10 $user = User::create([...]) // ...

11 }

12}

Ok, the first shortening of the controller is done. Let’s move on.


2. Create User: Service Class

Next, we need to create a user and upload the avatar for them:

1// Create user

2$user = User::create([

3 'name' => $request->name,

4 'email' => $request->email,

5 'password' => Hash::make($request->password),

6]);

7 

8// Avatar upload and update user

9if ($request->hasFile('avatar')) {

10 $avatar = $request->file('avatar')->store('avatars');

11 $user->update(['avatar' => $avatar]);

12}

If we follow the recommendations, that logic should not be in a Controller. Controllers shouldn’t know anything about the DB structure of the user, or where to store the avatars. It just needs to call some class method that would take care of everything.

A pretty common place to put such logic is to create a separate PHP Class around one Model’s operations. It is called a Service class, but that’s just a “fancy” official name for a PHP class that “provides a service” for the Controller.

That’s why there’s no command like php artisan make:service because it’s just a PHP class, with whatever structure you want, so you can create it manually within your IDE, in whatever folder you want.

Typically, Services are created when there are more than one method around the same entity or model. So, by creating a UserService here, we assume there will be more methods here in the future, not just to create the user.

Also, Services typically have methods that return something (so, “provides the service”). In comparison, Actions or Jobs are called typically without expecting anything back.

In my case, I will create the app/Services/UserService.php class, with one method, for now.

1namespace App\Services;

2 

3use App\Models\User;

4use Illuminate\Http\Request;

5use Illuminate\Support\Facades\Hash;

6 

7class UserService

8{

9 public function createUser(Request $request): User

10 {

11 // Create user

12 $user = User::create([

13 'name' => $request->name,

14 'email' => $request->email,

15 'password' => Hash::make($request->password),

16 ]);

17 

18 // Avatar upload and update user

19 if ($request->hasFile('avatar')) {

20 $avatar = $request->file('avatar')->store('avatars');

21 $user->update(['avatar' => $avatar]);

22 }

23 

24 return $user;

25 }

26}

Then, in the Controller, we can just type-hint this Service class as a parameter of the method, and call the method inside.

1use App\Services\UserService;

2 

3class RegisteredUserController extends Controller

4{

5 public function store(StoreUserRequest $request, UserService $userService)

6 {

7 $user = $userService->createUser($request);

8 

9 // Login and other operations...

Yes, we don’t need to call new UserService() anywhere. Laravel allows you to type-hint any class like this in the Controllers, you can read more about Method Injection here in the docs.

2.1. Service Class with Single Responsibility Principle

Now, the Controller is much shorter, but this simple copy-paste separation of code is a bit problematic.

The first problem is that the Service method should act like a “black box” that just accepts the parameters and doesn’t know where those come from. So this method would be possible to be called from a Controller, from Artisan command, or a Job, in the future.

Another problem is that the Service method violates the Single Responsibility principle: it creates the user and uploads the file.

So, we need two more “layers”: one for file upload, and one for the transformation from the $request to the parameters for the function. And, as always, there are various ways to implement it.

In my case, I will create a second service method that will upload the file.

app/Services/UserService.php:

1class UserService

2{

3 public function uploadAvatar(Request $request): ?string

4 {

5 return ($request->hasFile('avatar'))

6 ? $request->file('avatar')->store('avatars')

7 : NULL;

8 }

9 

10 public function createUser(array $userData): User

11 {

12 return User::create([

13 'name' => $userData['name'],

14 'email' => $userData['email'],

15 'password' => Hash::make($userData['password']),

16 'avatar' => $userData['avatar']

17 ]);

18 }

19}

RegisteredUserController.php:

1public function store(StoreUserRequest $request, UserService $userService)

2{

3 $avatar = $userService->uploadAvatar($request);

4 $user = $userService->createUser($request->validated() + ['avatar' => $avatar]);

5 

6 // ...

Again, I will repeat: it’s only one way of separating the things, you may do it differently.

But my logic is this:

  1. The method createUser() now doesn’t know anything about the Request, and we may call it from any Artisan command or elsewhere
  2. The avatar upload is separated from the user creation operation

You may think that the Service methods are too small to separate them, but this is a very simplified example: in real-life projects, the file upload method may be much more complex, as well as the User creation logic.

In this case, we moved away a bit from the sacred rule “make a controller shorter” and added the second line of code, but for the right reasons, in my opinion.


3. Maybe Action Instead of Service?

In recent years, the concept of Action classes got popular in the Laravel community. The logic is this: you have a separate class for just ONE action only. In our case, the action classes may be:

  • CreateNewUser
  • UpdateUserPassword
  • UpdateUserProfile
  • etc.

So, as you can see, the same multiple operations around users, just not in one UserService class, but rather divided into Action classes. It may make sense, looking from the Single Responsibility Principle point of view, but I do like to group methods into classes, instead of having a lot of separate classes. Again, that’s a personal preference.

Now, let’s take a look at how our code would look in the case of the Action class.

Again, there’s no php artisan make:action, you just create a PHP class. For example, I will create app/Actions/CreateNewUser.php:

1namespace App\Actions;

2 

3use App\Models\User;

4use Illuminate\Http\Request;

5use Illuminate\Support\Facades\Hash;

6 

7class CreateNewUser

8{

9 public function handle(Request $request)

10 {

11 $avatar = ($request->hasFile('avatar'))

12 ? $request->file('avatar')->store('avatars')

13 : NULL;

14 

15 return User::create([

16 'name' => $request->name,

17 'email' => $request->email,

18 'password' => Hash::make($request->password),

19 'avatar' => $avatar

20 ]);

21 }

22}

You are free to choose the method name for the Action class, I like handle().

RegisteredUserController:

1public function store(StoreUserRequest $request, CreateNewUser $createNewUser)

2{

3 $user = $createNewUser->handle($request);

4 

5 // ...

In other words, we offload ALL the logic to the action class that then takes care of everything around both file upload and user creation. To be honest, I’m not even sure if it’s the best example to illustrate the Action classes, as I’m personally not a big fan of them and haven’t used them much. As another source of examples, you may take a look at the code of Laravel Fortify.


4. Voucher Creation: Same or Different Service?

Next, in the Controller method, we find three operations:

1Auth::login($user);

2 

3$voucher = Voucher::create([

4 'code' => Str::random(8),

5 'discount_percent' => 10,

6 'user_id' => $user->id

7]);

8 

9$user->notify(new NewUserWelcomeNotification($voucher->code));

The login operation will remain unchanged here in the controller, because it is already calling an external class Auth, similar to a Service, and we don’t need to know what is happening under the hood there.

But with Voucher, in this case, the Controller contains the logic of how the voucher should be created and sent to the user with the welcome email.

First, we need to move the voucher creation to a separate class: I’m hesitating between creating a VoucherService and putting it as a method within the same UserService. That’s almost a philosophical debate: what this method is related to the vouchers system, the users’ system, or both?

Since one of the features of Services is to contain multiple methods, I decided to not create a “lonely” VoucherService with one method. We’ll do it in the UserService:

1use App\Models\Voucher;

2use Illuminate\Support\Str;

3 

4class UserService

5{

6 // public function uploadAvatar() ...

7 // public function createUser() ...

8 

9 public function createVoucherForUser(int $userId): string

10 {

11 $voucher = Voucher::create([

12 'code' => Str::random(8),

13 'discount_percent' => 10,

14 'user_id' => $userId

15 ]);

16 

17 return $voucher->code;

18 }

19}

Then, in the Controller, we call it like this:

1public function store(StoreUserRequest $request, UserService $userService)

2{

3 // ...

4 

5 Auth::login($user);

6 

7 $voucherCode = $userService->createVoucherForUser($user->id);

8 $user->notify(new NewUserWelcomeNotification($voucherCode));

Something else to consider here: maybe we should move both of those lines into a separate method of UserService that would be responsible for the welcome email, which would in turn call the voucher method?

Something like this:

1class UserService

2{

3 public function sendWelcomeEmail(User $user)

4 {

5 $voucherCode = $this->createVoucherForUser($user->id);

6 $user->notify(new NewUserWelcomeNotification($voucherCode));

7 }

Then, Controller will have only one line of code for this:

1$userService->sendWelcomeEmail($user);


5. Notifying Admins: Queueable Jobs

Finally, we see this piece of code in the Controller:

1foreach (config('app.admin_emails') as $adminEmail) {

2 Notification::route('mail', $adminEmail)

3 ->notify(new NewUserAdminNotification($user));

4}

It is sending potentially multiple emails, which may take time, so we need to put it into the queue, to run in the background. That’s where we need Jobs.

Laravel Notification classes may be queueable, but for this example, let’s imagine there may be something more complex than just sending a notification email. So let’s create a Job for it.

In this case, Laravel provides the Artisan command for us:

1php artisan make:job NewUserNotifyAdminsJob

app/Jobs/NewUserNotifyAdminsJob.php:

1class NewUserNotifyAdminsJob implements ShouldQueue

2{

3 use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

4 

5 private User $user;

6 

7 public function __construct(User $user)

8 {

9 $this->user = $user;

10 }

11 

12 public function handle()

13 {

14 foreach (config('app.admin_emails') as $adminEmail) {

15 Notification::route('mail', $adminEmail)

16 ->notify(new NewUserAdminNotification($this->user));

17 }

18 }

19}

Then, in the Controller, we need to call that Job with the parameter:

1use App\Jobs\NewUserNotifyAdminsJob;

2 

3class RegisteredUserController extends Controller

4{

5 public function store(StoreUserRequest $request, UserService $userService)

6 {

7 // ...

8 

9 NewUserNotifyAdminsJob::dispatch($user);

So, now, we’ve moved all the logic from the Controller to elsewhere, and let’s recap what we have:

1public function store(StoreUserRequest $request, UserService $userService)

2{

3 $avatar = $userService->uploadAvatar($request);

4 $user = $userService->createUser($request->validated() + ['avatar' => $avatar]);

5 Auth::login($user);

6 $userService->sendWelcomeEmail($user);

7 NewUserNotifyAdminsJob::dispatch($user);

8 

9 return redirect(RouteServiceProvider::HOME);

10}

Shorter, separated into various files, and still readable, right? Again, will repeat once more, that it’s only one way to accomplish this mission, you can decide to structure it in another way.

But that’s not all. Let’s also discuss the “passive” way.


6. Events/Listeners

Philosophically speaking, we can divide all the operations in this Controller method, into two types: active and passive.

  1. We’re actively creating the user and logging them in
  2. And then something with that user may (or may not) happen in the background. So we’re passively waiting for those other operations: sending a welcome email and notifying the admins.

So, as one way of separating the code, it should not be called in the Controller at all, but be fired automatically when some event happens.

You can use a combination of Events and Listeners for it:

1php artisan make:event NewUserRegistered

2php artisan make:listener NewUserWelcomeEmailListener --event=NewUserRegistered

3php artisan make:listener NewUserNotifyAdminsListener --event=NewUserRegistered

The event class should accept the User model, which is then passed to ANY listener of that event.

app/Events/NewUserRegistered.php

1use App\Models\User;

2 

3class NewUserRegistered

4{

5 use Dispatchable, InteractsWithSockets, SerializesModels;

6 

7 public User $user;

8 

9 public function __construct(User $user)

10 {

11 $this->user = $user;

12 }

13}

Then, the Event is dispatched from the Controller, like this:

1public function store(StoreUserRequest $request, UserService $userService)

2{

3 $avatar = $userService->uploadAvatar($request);

4 $user = $userService->createUser($request->validated() + ['avatar' => $avatar]);

5 Auth::login($user);

6 

7 NewUserRegistered::dispatch($user);

8 

9 return redirect(RouteServiceProvider::HOME);

10}

And, in the Listener classes, we repeat the same logic:

1use App\Events\NewUserRegistered;

2use App\Services\UserService;

3 

4class NewUserWelcomeEmailListener

5{

6 public function handle(NewUserRegistered $event, UserService $userService)

7 {

8 $userService->sendWelcomeEmail($event->user);

9 }

10}

And, another one:

1use App\Events\NewUserRegistered;

2use App\Notifications\NewUserAdminNotification;

3use Illuminate\Support\Facades\Notification;

4 

5class NewUserNotifyAdminsListener

6{

7 public function handle(NewUserRegistered $event)

8 {

9 foreach (config('app.admin_emails') as $adminEmail) {

10 Notification::route('mail', $adminEmail)

11 ->notify(new NewUserAdminNotification($event->user));

12 }

13 }

14}

What is the advantage of this approach, with events and listeners? They are used like “hooks” in the code, and anyone else in the future would be able to use that hook. In other words, you’re saying to the future developers: “Hey, the user is registered, the event happened, and now if you want to add some other operation happening here, just create your listener for it”.


7. Observers: “Silent” Events/Listeners

A very similar “passive” approach could be also implemented with a Model Observer, in this case.

1php artisan make:observer UserObserver --model=User

app/Observers/UserObserver.php:

1use App\Models\User;

2use App\Notifications\NewUserAdminNotification;

3use App\Services\UserService;

4use Illuminate\Support\Facades\Notification;

5 

6class UserObserver

7{

8 public function created(User $user, UserService $userService)

9 {

10 $userService->sendWelcomeEmail($event->user);

11 

12 foreach (config('app.admin_emails') as $adminEmail) {

13 Notification::route('mail', $adminEmail)

14 ->notify(new NewUserAdminNotification($event->user));

15 }

16 }

17}

In that case, you don’t need to dispatch any events in the Controller, the Observer would be fired immediately after the Eloquent model is created.

Convenient, right?

But, in my personal opinion, this is a bit dangerous pattern. Not only the implementation logic is hidden from the Controller, but the mere existence of those operations is not clear. Imagine a new developer joining the team in a year, would they check all the possible observer methods when maintaining the User registration?

Of course, it’s possible to figure it out, but still, it’s not obvious. And our goal is to make the code more maintainable, so the fewer “surprises”, the better. So, I’m not a big fan of Observers.


Conclusion

Looking at this article now, I realize I’ve only scratched the surface of possible separations of the code, on a very simple example.

In fact, in this simple example, it may seem that we made the application more complex, creating many more PHP classes instead of just one.

But, in this example, those separate code parts are short. In real life, they may be much more complex, and by separating them, we made them more manageable, so every part may be handled by a separate developer, for example.

In general, I will repeat for the last time: you are in charge of your application, and only you decide where you place the code. The goal is so that you or your teammates will understand it in the future, and will not have trouble adding new features and maintaining/fixing the existing ones.

Laravel News

Laravel Real-Time performance monitoring & alerting using Inspector

https://inspector.dev/wp-content/uploads/2020/02/laravel-monitoring-cover-3.jpg

Hi, I’m Valerio software engineer, founder and CTO at Inspector.

As a product owner, I learned how an application issue could be so hard to fix, that it negatively impacts the users’ experience. Or worse blocks new potential customers during onboarding.

I publish new code changes almost every day. Unfortunately, it’s impossible to anticipate all the problems that could happen after each release. Furthermore, users don’t spend their time reporting bugs. They stop using our application if it doesn’t work as expected. Then they look for another one that better fits their needs.

In most of the projects I’ve worked on, 50% of the drawbacks for users are due to simple code mistakes. And, the more the application grows (more lines of code, new developers at work), the more difficult it is to avoid incidents.

When I started to share my idea behind Inspector, I realized that many developers know the problem. They spend too much time investigating strange behaviors inside their applications. Still, they didn’t know there was a solution to end this complexity. And do so in two minutes, avoiding customer complaints or even losing the customer.

Be the first to know if your application is in trouble before users stumble onto the problem. And drastically reduce the negative impacts on their experience. This gives you the proper foundation to run a successful users acquisition process. And allow you to increase engagement with fewer interruptions.

Lavarel Code Execution Monitoring: how it works

Inspector is a composer package to add real-time code execution monitoring to your Laravel application. It allows you to work on continuous code changes while catching bugs and bottlenecks in real-time. Before users do.

It takes less than one minute to get started. Let’s see how it works.

Install the composer package

Run the composer command below in your terminal to install the latest version:

composer require inspector-apm/inspector-laravel

Configure the Ingestion Key

Get a new Ingestion key by signing up for Inspector (https://app.inspector.dev/register) and creating a new project, it only takes a few seconds.

You’ll see installation instructions directly in the app screen:

Put the API key into your environment file:

INSPECTOR_API_KEY=xxxxxxxxxxxxxxx

Test everything is working

Execute the test command to check if your app sends data to Inspector correctly:

php artisan inspector:test

Go to https://app.inspector.dev/home to explore the demo data.


By default Inspector monitors:

  • Database interactions
  • Queued Jobs execution
  • Artisan commands
  • Email sent
  • Unhandled Exceptions

But, we turned on the light in the 50% of our app executed in the background. The next step is to monitor all execution cycles generated by user interactions.

Monitor Incoming HTTP Requests

To activate HTTP requests monitoring, you can use the WebRequestMonitoring middleware as an independent component. You are then free to decide which routes need to be monitored. Base it on your routes configuration or your monitoring preferences.

Attach the middleware in the App\Http\Kernel class:

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
       …,
       \Inspector\Laravel\Middleware\WebRequestMonitoring::class,
    ],    'api' => [
       …,
       \Inspector\Laravel\Middleware\WebRequestMonitoring::class,
    ]
]

Deploy your code and navigate the execution flow

The next step is to deploy your code to the production environment. Next, check out how Inspector creates a visual representation of what happens inside your code.

You will see transaction streams in your dashboard. And for each transaction, you can monitor what your application executes in real-time:

Enrich the Inspector timeline

Inspector monitors database queries, background jobs, and artisan commands by default. Still, there might be many critical statements in your code that need monitoring for performance and errors:

  • Http calls to external services
  • Function that deals with files (pdf, excel, images)

Thanks to Inspector, you can add custom segments in your timeline besides those detected by default. This allows you to measure the impact that a hidden code block has on a transaction’s performance.

Let me show you a real life example.

Suppose you have a queued job that executes some database queries and an HTTP request to an external service in the background.

Inspector detects job and database queries by default. Still, it could be interesting to monitor and measure the execution of the HTTP request to the external service. Then activate alerts if something goes wrong.

Use the inspector() helper function:

class TagUserAsActive extends Job
{
    /** 
     * @var User $user 
     */
    protected $user;

    // Monitring an external HTTP requests
    public function handle()
    {
        inspector()->addSegment(function () {            
            $this->guzzle->post('/mail-marketing/add_tag', [
                'email' => $this->user->email,
                'tag' => 'active',
            ]);        
        }, 'http');
    }
}

You will be able to identify the impact of the new segment in the transaction timeline:

Laravel Errors & Exceptions Alerting

By default, every exception fired in your Laravel app is reported. This ensures you’re alerted to unpredictable errors in real-time.

I wish that every change I make to my code could be perfect. But the reality is that this is not always the case. Some errors appear immediately after an update, while others pop up unexpectedly. It’s an unfortunate fact of life for developers. And it often also depends on problems caused by the connection between our application and other services.

Yet, Inspector makes the job easier. It automates the detection of unknown issues, so you no longer need to manually check the status of your apps. You no longer wait for reports from users. If something goes wrong, you’ll receive a notification in real-time. And after each release, you can stay informed about the impact of the latest code refactor.

If your code fires an exception, but you don’t want to block the execution, manually report the error to Inspector for personal monitoring.

try {   

    // Your dangerous code here...

} catch (GuzzleException $exception) {
   inspector()->reportException($exception)
}

Furthermore, if the HTTP request fails, you are alerted in real-time via your inbox to examine the error.

You even get access to detailed information gathered by Inspector in real time:

Conclusion

When a customer reports that something isn’t working, it forces you to drop whatever you are doing. Then start trying to reproduce the scenario, and recapture and reanalyze the logs in your toolset.

Getting an accurate picture of what’s happening can take hours or even days. Inspector can make a massive difference in efficiency, productivity, and customer happiness.

New to Inspector?

Get a monitoring environment specifically designed for software developers. Avoid any server or infrastructure configuration that many developers hate to deal with.

Thanks to Inspector, you will never need to install things at the server level or make complex configurations in your cloud infrastructure.

Inspector works with a lightweight software library that you install in your application like any other dependencies. Try the official Laravel package.

Create an account, or visit our website for more information: https://inspector.dev/laravel/

Laravel News Links

Top Gun: Maverick spoiler-free review: A worthy return to the danger zone

https://cdn.arstechnica.net/wp-content/uploads/2022/05/topgunmaverick-listing-2-760×380.png

Tom Cruise, still crazy after all these years.

Enlarge / Tom Cruise, still crazy after all these years.

Skydance Productions

As I walked out of my review screening of Top Gun: Maverick, coming down from its adrenaline-filled finale, a small part of my brain began looking for dents in the film’s armor. Maybe it’s the critic in me, but my thoughts didn’t need long to land on stuff from the original film—a plot point, a stylistic choice, a particular character—that didn’t return this time.

I chewed on those thoughts for a second, but before I could lose myself in cataloging them at length, a sensation came over me. It landed like a massive G-force blast, as if I were a jet fighter pilot attempting a seemingly impossible climb: one of great satisfaction with this sequel and admiration that this film pulled off the impossible feat of adhering to the old while doing something new.

Returning to old haunts.

Enlarge / Returning to old haunts.

Skydance Productions

The series’ predilection for steering military theater toward Hollywood-style silliness is arguably more tolerable, as tempered by a savvy script and cutting-edge stunt work. The character development hits important notes for both Pete “Maverick” Mitchell and the people in his high-speed orbit, and the film’s focused supporting cast mostly hits the mark.

Perhaps most important of all, an aging-yet-excited Tom Cruise never steps beyond his pay grade. The Top Gun star of roughly 35 years ago ruled movie theaters for different reasons than the man he is today, yet this film never sees his character Maverick betray his beloved traits or feel like an old man faking like a 20-something hotshot.

A few of the series’ moving parts have been jettisoned so many years later, and lifetime fans of the film will definitely notice them. But Top Gun‘s core tenets—incredible fighter-jet combat, enjoyable cheese, and the big-grin smile of Cruise—have returned in arguably finer form than the original.

“Don’t think, just do”

Skydance has only released traditional theater ratio footage of the film for consumption outside of theaters, so you'll have to trust me when I say that shots like this look doubly incredible inside a 16:10 ratio container.

Enlarge / Skydance has only released traditional theater ratio footage of the film for consumption outside of theaters, so you’ll have to trust me when I say that shots like this look doubly incredible inside a 16:10 ratio container.

Skydance Productions

Top Gun: Maverick has the added benefit of looking incredible on a large screen, and it’s perhaps the best IMAX format showcase of the past five years. Cruise and co. were clearly eager to take cinematic air combat to the next level, and there’s no getting around it: If you have to stitch three hospital-grade masks together or rent out a private room to feel comfortable in a public movie theater in 2022, you should consider doing so for this film.

Every major flight scene includes per-cockpit camera rigs that emphasize the added height of IMAX’s 16:10 ratio, and in these moments, flying is choreographed to let this camera angle showcase Top Gun-caliber stuff. You might see another plane in view, or vapor trails, or dumped flares dancing and billowing smoke, or a glancing shadow of the jet against the Earth’s surface because the F/A-18 Hornet is actually flying that freaking low in real life. In these moments, the actors don’t hesitate to explode with emotion, whether shrinking back or splashing their palms on the cockpit glass that extends across the entire IMAX screen.

In <em>Top Gun: Maverick</em>, all buzzing is essential—and it's always portrayed with incredible detail.

Enlarge / In Top Gun: Maverick, all buzzing is essential—and it’s always portrayed with incredible detail.

Skydance Productions

Top Gun: Maverick spends a lot of time in this perspective, so it’s good to see the stunt teams and cinematographers repeatedly strike a hot beach volleyball high-five over this collaboration. Yet the crew also makes up for lost time since the first film was made by letting external cameras, including expertly staged drones, linger over death-defying flight sequences or use wide-angle shots to show how foolishly close its stunt flyers zip past each other. The 1986 style of hard camera cuts to stitch together a shot-down bogey are done. This time, we get to watch full dogfights that lead up to each climactic kaboom.

Really, the lengths to which this film goes to favor real-life stunts over green-screen trickery is incredible. Everyone will have a different favorite on this front, but mine is a dramatic fly-by somewhat early in the film that I won’t spoil for you, except to say that it was reportedly filmed with actors taking the real-life brunt of its buzz. You’ll know it (and feel it) when you see it.

My only shoulder-shrug about the air-combat content comes from a few CGI-filled briefings. In each of these, commanding officers point at holograms and break down each step of a mission or exercise—as if Cruise insisted that this film resemble the Mission: Impossible series in one way or another. While these moments are tolerable, I felt they were explanation overkill that took time away from getting the film’s cameras up into the danged skies.

Ars Technica

New FBI Report Shows Armed Citizens STOP Mass Shootings

https://www.ammoland.com/wp-content/uploads/2022/05/FBI-Report-Active-Shooter-Incidents-in-the-USA-2021-500×352.jpg

FBI Report: Active Shooter Incidents in the USA 2021
FBI Report: Active Shooter Incidents in the USA 2021

BELLEVUE, WA – -(Ammoland.com)- A newly-released FBI report on “active shooter incidents” in 2021 [embeded below] revealed four of those killers were stopped by armed private citizens, and the Second Amendment Foundation says this is strong evidence the right to keep and bear arms is as important today as it was when the Constitution was ratified more than 200 years ago.

There were 61 active shooter incidents last year, the FBI report said. All but one of the killers were males, and ranged in age from 12 to 67 years. SAF founder and Executive Vice President Alan M. Gottlieb lauded the FBI report for acknowledging the role played by legally-armed citizens in stopping some of these events.

“It is important to acknowledge these citizen first responders, and the countless lives their heroic actions saved,” Gottlieb said.

“Truly, these were good guys with guns.”

“There is one revelation in the report for 2021 that underscores the importance of right-to-carry laws,” Gottlieb noted. “According to the FBI, active shooter data shows an upward trend in such incidents. People have a right to defend themselves and their loved ones if they are caught in the middle of such mayhem. Unquestionably, in each of the four cases cited by the FBI report, lives were saved.”

According to the FBI, in addition to the four perpetrators killed by armed citizens, 30 of these violent thugs were apprehended by law enforcement, and 14 were killed by police officers. One was killed in a vehicle accident during a law enforcement pursuit, 11 others committed suicide, and one remains at large, the report notes. In 2020, the FBI report noted, citizen first responders killed two criminals in the act.

Gottlieb has co-authored several books dealing with armed self-defense by private citizens, the most recent being “Good Guys With Guns,” published by Merril Press.

“Each year,” he said, “there are tens of thousands of cases in which private citizens use firearms in self-defense. The four incidents in which the criminals were killed represent a small but significant part of this larger story. The bottom line is that our Second Amendment rights are just as relevant today as they have ever been.”

FBI Report: Active Shooter Incidents in the USA 2021


About Second Amendment Foundation

The Second Amendment Foundation (www.saf.org) is the nation’s oldest and largest tax-exempt education, research, publishing and legal action group focusing on the Constitutional right and heritage to privately own and possess firearms. Founded in 1974, The Foundation has grown to more than 750,000 members and supporters and conducts many programs designed to better inform the public about the consequences of gun control.

Second Amendment Foundation

AmmoLand.com

How to scale an agency while managing 2,000 client websites

https://www.noupe.com/wp-content/uploads/2022/05/pexels-canva-studio-3194519-964×1024.jpg

From ensuring that you hire the right people and are retaining employees, to onboarding long-term clients that will allow your business to grow, there’s no doubt that scaling any agency comes with its challenges. Once you reach a certain level in your agency, serving and managing multiple clients and their websites, things can get even more demanding. 

As a creative agency owner who has over 25 years of experience, I can sincerely say that scaling an agency while managing 2000 websites is no easy feat, but with the right know-how and tools, it is possible. 

Simplify the most important processes

When you’re managing a myriad of different elements, simplifying all areas of how your agency operates is essential. To achieve this, agencies must first begin by assessing which critical tasks are taking up the most time or require the most input from the large majority of their teams. Essentially, business owners need to strategically lower the impact that the most burdensome and important work has on the operations team. 

An agency specializing in designing websites, such as my own, will most likely realize that they need to understand their team’s strengths and design logistics to optimize the business. In my own business, we came to understand that we needed a software solution that would simplify and facilitate our agency’s ability to easily produce professional websites at a faster rate for our clients. Our thinking at the time was that if we reduced the effort and time it took to fulfill our most critical task, we could free up time and resources to onboard new clients and ultimately grow our business. 

Utilizing a low-code/no-code website building solution such as Duda helped us and will help growing agencies simplify the production and the workflow of their development, creative, and management teams. As a result, an agency’s core employees can rapidly create and finalize 10-page websites – which would normally take 20 hours to develop – within three to four hours. With up to 17 additional hours freed up, per website build, agencies that are just starting out can rapidly grow their business. More established agencies that manage many accounts will also benefit greatly from having additional hours to spare, as they can utilize these hours to manage even more clients and deliver even more products and services. For example, my agency only has one person in charge of maintaining 2,000 sites, because the website builder we use, Duda,  allows us to easily take care of updates and ensure modern websites that are constantly upgraded to the latest best practices.

Deliver a product that’s easy to use and unmatched in quality

The quality of the final product delivered to a client will greatly affect whether an agency will receive repeat business and word-of-mouth referrals. While spending money on marketing to bring in new clients is a great strategy in the short term, giving existing customers an incredible user experience and product will ensure that clients become free brand ambassadors, referring people to your business and plugging your service on social media.

Agencies that are managing a significant number of clients and want to drive high volumes of growth must utilize the most effective product support solutions to give their customers the best treatment. Pivoting to superior software, sooner, will help agencies deliver high-quality products and services. With a plethora of software solutions on the market, agencies must set aside time to investigate and test new software. Finding a solution that enhances the quality of the final product and makes the product easy to use might take time, but agencies should see this time as a necessary investment that will have good returns. 

Nurture revenue-building relationships with excellent support

Every relationship has the potential to be the key to an agency’s next big deal and growth. I’ll refer to my own agency as an example. In 2010, we started out with only eight clients. By keeping our clients happy, and with no sales or business development team, we grew to over 1,300 clients and counting. Clients who are well taken care of will reward you, and those who feel that your agency is not meeting their needs will warn their networks about your service. 

A major factor in maintaining a good relationship is the quality of support and communication they receive. When there is a request for their website to be updated, how long will it take for your agency to respond? If an average of a hundred service requests are received each week, can all requests be answered within two to three hours? Does your agency have a post-launch communication plan? These are the questions that agency owners need to ask themselves in order to assess the quality of their support. Agencies should never underestimate the power of calling clients regularly, solving their problems expeditiously, and sharing helpful information and insights without being prompted. 

Good service almost always leads to gaining a client’s trust. Once an agency has earned the trust of its clients, it is in a better position to offer additional services and will likely see clients remaining customers for a long time. While some may argue that retaining customers for a long period of time is insignificant, the reality, according to a survey conducted by conversion rate optimization experts Invesp, is that acquiring a new customer is five times more expensive than keeping an existing one. Mistreating or ignoring existing clients won’t get agencies any closer to actualizing their goal of scaling their business. 

A very important caveat is that not all clients are worth keeping. Most agencies will at some point encounter a client who cannot be satisfied, no matter what you do. To illustrate how we deal with high-stress clients in my own business, I’ll refer to a quarterly Board of Directors meeting which took in 2018. At the meeting, one of the Board members asked what our client turnover rate was, and I proudly replied: “less than one percent.” To my surprise, the entire Board was adamant that the client churn rate should be higher, as keeping difficult clients was bound to hinder the agency’s continuous growth. Today, we are able to identify which clients are worth keeping and which aren’t – a skill that all growing agencies should adopt. While we have only had to let go of about 10 to 15 clients, the shift in thinking resulted in increased productivity and, more importantly, a much better atmosphere in the workplace. No client is worth keeping if they bring unhappiness and unnecessary stress to an agency’s employees.

Quality begets quantity

Growing an agency while managing thousands of clients, while extremely challenging, is possible. Agencies that want to grow must simplify processes, deliver a high-quality service, and excel at customer support to effectively and seamlessly scale. When an agency specializes in a specific product offering, it’s critical to streamline the process of how the product is built. Quality will result in quantity: the higher the quality of the final product, the more revenue an agency will see. Furthermore, and most importantly, offering memorable and outstanding customer service will guarantee that clients spread the word and drive significant business growth.

The post How to scale an agency while managing 2,000 client websites appeared first on noupe.

noupe