Published Articles

Enter a search term to find articles.
2021-01-07

TIL that you do not need the full class name (or the full method name) when filtering tests to run. I was working on some documentations writing today when I ran my tests with a mistyped `User` filter and to my surprise, it loaded and ran all tests with the word `User` on class names and methods. Below is how it looked like after I ran the command (some tests have been redacted).. ``` ➜ p2p git:(develop) ./vendor/bin/phpunit --filter=User PHPUnit 8.5.8 by Sebastian Bergmann and contributors. Batch Import Job (Tests\Unit\BatchImportJob) ✔ It belongs to a user Company (Tests\Unit\Company) ✔ It belongs to many users Contract (Tests\Unit\Contract) ✔ It belongs to many users Media Security Check (Tests\Unit\MediaSecurityCheck) ✔ It belongs to a user User Setting (Tests\Unit\UserSetting) ✔ It belongs to a supervisor ✔ It belongs to a user ✔ It belongs to a delegate Companies Deactivation (Tests\Feature\Admin\CompaniesDeactivation) ✔ Deactivating a company also deactivates its users User Change Password (Tests\Feature\Admin\UserChangePassword) ✔ Can change password of a user ✔ Can resend email password reset to user User Contracts (Tests\Feature\Admin\UserContracts) ✔ Can attach a contract to a user User Deactivations (Tests\Feature\Admin\UserDeactivations) ✔ Can deactivate a user ✔ Deactivated users cannot login ✔ Can reactivate a user User Export (Tests\Feature\Admin\UserExport) ✔ Can export users User Settings (Tests\Feature\Admin\UserSettings) ✔ Can update user settings Users (Tests\Feature\Client\Users) ✔ Can list all users ✔ Can get user details ✔ Can only get details of users in the same company User Filters (Tests\Feature\Filters\UserFilters) ✔ It can load user companies ✔ It can be filtered by company association User Picklists (Tests\Feature\Supplier\UserPicklists) ✔ Can update picklist Users (Tests\Feature\Supplier\Users) ✔ Can list all users [Some tests have been redacted] Time: 44.64 seconds, Memory: 86.50 MB OK (83 tests, 204 assertions) ```

time-travelling-through-wormhole-laravel-8
2020-11-22

New to Laravel 8 is the ability to quite literally travel in time using the Wormhole class. Although this class was only recently implemented on version 8, the time travelling concept is already apparent using the `Carbon::setTestNow()` which is a feature available in `Carbon\Carbon` package, and is in fact behind this class. Personally, I was able to utilize this feature when I was working on a Loans Management app, which made simulating past and future scenarios (i.e: loans terms and payments) in my tests quite a breeze. Let's take a look at how we can make time travelling work in Laravel 8. ## The `InteractsWithTime` trait In Laravel 8, a new trait for testing has been created as a sort of wrapper for the Wormhole class. The InteractsWithTime trait is within `Illuminate\Foundation\Testing\Concerns` namespace (be careful when importing and not to confuse it with other traits with the same name but in a different namespace). So we can just use it in our test classes like so.. namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\Concerns\InteractsWithTime; class TimeTravellingTest extends TestCase { use InteractsWithTime; } Once we've used it on our test class we then gain access to various utility methods.. // Travel 8 days in the future $this->travel(8)->days(); // Carbon::now() or now() will result to the current date + 8 days // Travel 10 minutes in the future $this->travel(10)->minutes(); // Carbon::now() or now() will result to the current time + 8 minutes // Travel 5 months in the past $this->travel(-5)->months(); // Carbon::now() or now() will result to the current date - 5 months We can also travel to a specific date.. $this->travelTo('2019-02-14 12:00:00'); // Carbon::now() or now() will result to '2019-02-14 12:00:00' Just make sure to **ALWAYS GO BACK TO THE PRESENT** after doing time travelling to not get stuck in the past or present. $this->travelBack(); // Carbon::now() or now() will result to the current date That means we can also time travel, execute a callback and return to the current date consecutively.. // Option 1.. $this->travel(8)->days(function () { dd(now()); // This will result to the current date + 8 days // After executing this callback, now() will automatically go back to the current date }); // Option 2.. $this->travelTo('2019-02-14 12:00:00', function () { // Carbon::now() or now() will result to '2019-02-14 12:00:00' echo 'Happy Valentines Day!'; // After executing this callback, Carbon::now() or now() // will automatically go back to the current date }); ## The `Wormhole::class` The `Wormhole::class` is namespaced within `Illuminate\Foundation\Testing`. Looking at it, its just a single file class that accepts an integer value. This means we can just new it up like a traditional php class, give it a value and call the methods within it, like so.. $wormhole = new Wormhole(8); $wormhole->days(); // Carbon::now() or now() will result to the current date + 8 days Wormhole::back(); // Go back to the present time.. And again we can execute a callback within the Wormhole method.. $wormhole = new Wormhole(8); $wormhole->days(function () { dd(now()); // This will result to the current date + 8 days // After executing this callback, now() will automatically go back to the current date }); This is useful if you wish to do time travelling outside your tests and don't want to use the trait. And there you have it, time travelling in Laravel is now online. Hope you learned something from this article. Cheers!

10-honest-takes-on-software-development
2020-09-05

I have been working in tech industry as a Software Developer for more than a decade now. Let me share with you my 10 honest takes on the job and the industry: ## Technical Knowledge + Communication Skills will take you further in your career Filipino software devs tend to underestimate the power of effective english communication skills. The reality is that as you go along in your career, you will find that good communication skills open a whole lot of opportunities. Being able to negotiate and leverage with your clients and better understanding between yourself and team members are just a few. And it is also a good way to prevent career stagnation. ## Having co-workers is really important Software Developers are notorious for being lone wolves. However, if you want to grow your career as fast as you can, it is important that you work with people that you can give and receive feedback from. ## Technical choices doesn't mean you're better than anyone Software Developers are problem solvers and we approach solutions in ways that we think we would be most efficient for us. But choosing a certain framework or tool does not, in anyway, make you better than anyone. ## Master the basics Anyone can start their Software Development career wherever they want. But if you find yourself getting stuck a lot, then maybe its time to revisit your fundamentals. Build your career on solid and strong foundations. ## Be prepared to unlearn, learn and re-learn Technology is constantly evolving at a rapid pace. A tool that you like using at the moment might become obsolete come next month. Your adaptability to the changes will most of the time drive your technical proficiency as a Software Developer. ## Do not be afraid to make mistakes Everyone at some point will make mistakes. Mistakes are essential for growth. Recognize your mistakes, apologize to those who were affected, learn, and do your best to not make the same mistake twice. ## Burnout is real Software Development is mentally demanding. Constant stream of new information and the pressure of staying current can be quite taxing. Make sure you are giving yourself adequate breaks. And know that it is okay to ask for help. ## Seniority is not all about being the best coder Technical proficiency is just one part of being a Senior Software Developer. It's also all about experience, impact and soft skills. ## Share your knowledge One of the best ways to make a quick and effective impact is to share your knowledge. Be a mentor, create a software package or library, and make content that others can consume are just a few ways on how you can impart to others what you know. ## Remember that there are humans behind computers Software Development is not just about technical skills. It's also about making connections and fostering relationships. Computer programs are developed by humans like you, it's humans that will use them too.

eloquent-methods-you-probably-didnt-know-exists
2020-07-28

Eloquent ORM is probably the most appreciated features of Laravel. It enables programmers to interact with the database in a fluent manner. And just like any other features in Laravel, it has couple hidden gems that you probably never knew existed. In this article, let's take a look at some of these hidden gems that I personally use quite so often. # whereKey / whereKeyNot That's right! These are Eloquent methods are specific for querying a model by its primary key. The obvious benefit of this is that you, as the programmer, don't need to remember the name of the model's primary key. ``` // Instead of doing... Post::whereIn('id', [1,2,3])->get(); Post::whereNotIn('id', [1,2,3])->get(); // You can do... Post::whereKey([1,2,3])->get(); Post::whereKeyNot([1,2,3])->get(); ``` # qualifyColumn You can use this method if you want to prepend your columns with the table name. Really helpful for long queries with nested conditions. ``` $sql = Post::where(function ($query) { $query->whereNotNull($query->qualifyColumn('published_at')); })->toSql(); dd($sql); // select * from `posts` where (`posts`.`published_at` is not null) and `posts`.`deleted_at` is null ``` # getQualifiedKeyName This method simply returns the name of the primary key of the model with the table name. ``` (new \App\Models\Post)->getQualifiedKeyName(); // Will return 'posts.id' (new \App\Models\Post)->getKeyName(); // Will return 'id' ``` # increment / decrement Often times we have a column on a model that we need to manually increment/decrement. So instead of using the "update" method, we can use "increment / decrement" instead. Also, increment and decrement methods both accepts 2nd parameter as the amount of increment, and 3rd parameter as an array of extra columns you wish to update. # when / unless If you ever come across a situation wherein your queries are based on a condition then these methods might be perfect for your use-case. You can use `when` if you want to apply a callback to an Eloquent query when a certain condition is true. ``` Post::when($someBoolean, function () { // This call back will run if $someBoolean is true... }); ``` You can use `unless` if you want to apply a callback to an Eloquent query when a certain condition is false. ``` Post::unless($someBoolean, function () { // This call back will run if $someBoolean is false... }); ``` You can also pass a third parameter to both methods as a default callback. And both methods are also chainable to other Eloquent methods! # loadMissing This method is almost the same as the `load` method. But as the name implies, it will only load relationship that has not yet been loaded on the current model. This means performance savings when lazy loading relationships. # The magic where When doing where conditions on your queries, you can just append the name of the column to the where method in camel-case format, like so: ``` $sql = User::whereEmail('john@doe.com')->toSql(); dd($sql); // select * from `users` where `email` = ? ``` Hopefully, you learned something from this article and you'll be able to utilize these methods. Don't forget to visit the official Laravel documentation for more info: [https://laravel.com/docs/7.x/eloquent](https://laravel.com/docs/7.x/eloquent) Cheers!

a-quick-dive-into-the-ioc-container
2020-07-12

Laravel framework is a tool - a tool that helps you create a web application - a tool that helps people build businesses. To be able to completely utilize a tool and build powerful, large web applications, we have to understand how it works, what is under-the-hood and how it's all tied together. In this article, we will take a look at the core of Laravel - the IoC Container. "*The Laravel inversion of control (IoC) container is a powerful tool for managing class dependencies.*" - Laravel official documentation. There are 2 classes that we will be taking a look at in this article: Illuminate\Container\Container.php Illuminate\Foundation\Application.php # The `Container::class` The `Container::class` is a framework agnostic implementation of IoC container. This class is a singleton and is responsible for features such as **binding and resolving classes out of the container.** Because of this class, you can do things like binding a class: // Binding a class to an interface.. app()->bind(FooInterface::class, Foo::class); // Or to a string.. app()->bind('foo', Foo::class); And resolving the instance of a class: // Resolving using the interface.. app()->resolve(FooInterface::class); // You will get the instance of Foo::class // Or using the string.. app()->resolve('foo'); // You will get the instance of Foo::class The `Container::class` is also responsible for **auto-wiring class constructor dependencies** by utilizing PHP's Reflection API. See PHP Reflection API manual: [https://www.php.net/manual/en/book.reflection.php](https://www.php.net/manual/en/book.reflection.php) Because of this, gone are the days when you have to manually inject all dependencies just to get an instance of a class: $foo = new Foo( new Bar1, new Bar2( new DeepDependency, new AnotherDeepDependency // Imagine these classes having dependencies too.. ) ); You can literally just call the class out of the container and it will try to automatically inject the nested dependencies for you, as long as those dependencies are also resolvable out of the container. app()->resolve(Foo::class); // Clean! Aside from these, `Container::class` is also responsible for more advanced features such as contextual binding, which is a topic for another article. But I encourage you to have a take a look at `Container.php` class sometime. It's a single-file class with a bit more than 1.3k lines of code as of this writing, so its a pretty easy read. If you are building your own PHP framework and need an implementation of IoC container, you can install the `Illuminate\Container` package via Composer. See packagist link here: [https://packagist.org/packages/illuminate/container](https://packagist.org/packages/illuminate/container) # The `Application::class` The `Application::class` is Laravel's framework-specific implementation of the IoC container. This class simply inherits from the `Container::class`, but with extra methods that were tailor-fitted for Laravel's architecture. But how does the `Application::class` fit into the overall flow of the framework? Well, for me to explain that, lets take a quick look at the beginning of the Framework's request-lifecycle. Once a request hits the web server, it will land onto the entry file of the framework which is the `public/index.php`. Taking a look at the first 3 lines of codes of this file: // From Laravel 7.18 (lower versions might have different codes) // First line of code defines a constant, not much going on here define('LARAVEL_START', microtime(true)); // 2nd line of code just pulls in the vendor/autoload.php file // Typical if you are using package managers such as composer require __DIR__.'/../vendor/autoload.php'; // 3rd line of code pulls in a bootstrap/app.php file and stores // its value to a variable called `$app`. Interesting! $app = require_once __DIR__.'/../bootstrap/app.php'; So, the 3rd line actually calls a framework specific file, which is the `bootstrap/app.php`, lets take a look at this file: $app = new Illuminate\Foundation\Application( $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__) ); The first thing that this file does is to create an instance of the `Application::class`. And if you will read the respective comment for this line of code: | The first thing we will do is create a new Laravel application instance | which serves as the "glue" for all the components of Laravel, and is | the IoC container for the system binding all of the various parts. In other words, `Application::class` ties all the Laravel components together. Components like system paths, Laravel service providers, and 3rd-party packages (this happens later on at the Kernel class). To prove that, lets take a quick look at what happens when we instantiate it: public function __construct($basePath = null) { if ($basePath) { $this->setBasePath($basePath); } $this->registerBaseBindings(); $this->registerBaseServiceProviders(); $this->registerCoreContainerAliases(); } Looks like, the first thing it does is to set the base path, taking a deeper look at that method it seems its also calling a `bindPathsInContainer()`, which sets other important paths in the framework: protected function bindPathsInContainer() { $this->instance('path', $this->path()); $this->instance('path.base', $this->basePath()); $this->instance('path.lang', $this->langPath()); $this->instance('path.config', $this->configPath()); $this->instance('path.public', $this->publicPath()); $this->instance('path.storage', $this->storagePath()); $this->instance('path.database', $this->databasePath()); $this->instance('path.resources', $this->resourcePath()); $this->instance('path.bootstrap', $this->bootstrapPath()); } And yes, the helper methods like `storage_path()`, `public_path()` that we learned to love so much are just calling these bindings! Pretty cool, right? Next step is to register all base bindings such as binding the application itself to the container as a singleton - remember that the `Container::class` class is a singleton but the `Application::class` is not. It also binds packages such as "Mix" and "Filesystem" packages at this point. Next is registering base service providers such as `EventServiceProvider::class`, `LogServiceProvider::class` and `RoutingServiceProvider::class`. protected function registerBaseServiceProviders() { $this->register(new EventServiceProvider($this)); $this->register(new LogServiceProvider($this)); $this->register(new RoutingServiceProvider($this)); } And last but not the least is registering core aliases to the container. These aliases are representative of various Laravel components such as the "app", "db", "cache", "config", "files", "hash", "storage", etc. I will not bother including the codes here as it is quite long. And there you have it, a quick dive at the Laravel's IoC Container! Don't forget to visit Laravel's official documentation for more info: [https://laravel.com/docs/7.x/container](https://laravel.com/docs/7.x/container) Cheers!

2020-07-03

I personally think that one of the most underrated feature of Laravel is Form Request. Form Requests allows you to perform more complex authorizations and validations and can drastically clean up your controllers if you know how to use it.  Here are 3 things you probably did not know you can do with Form Requests. # 1. Removing the authorize method will make the authorization check pass. When generating Form Requests using `php artisan make:request FooRequest` command , the authorize method by default will return false. However, instead of returning true in this method, you can just delete it entirely - which achieves the same result and a much cleaner approach. # 2. Add a persist method in Form Request class to handle storing and updating of your models. Basically, we will let our form persist itself. Lets take a look at this simple blog post example: // In our PostRequest class we can have the following methods. class PostRequest { public function rules() { return [ 'title' => 'required|max:255', 'body' => 'required', ]; } public function persist(Post $post = null) // We type-hint our Post model here. { $post = $post ?? new Post; $post->title = $this->title; $post->body = $this->body; $post->save(); return $post->fresh(); } } // In our PostController we can have the store and update methods like so. class PostController extends Controller { public function store(PostRequest $request) { // You can definitely return view or redirect here, whichever you prefer. // Let's assume this is a json endpoint so we just return PostResource. return PostResource($request->persist()); } public function update(PostRequest $request, Post $post) // Route-model binding. { // We pass the post model so it will be updated in persist method. return PostResource($request->persist($post)); } } Now this cleans up the controller into single-line and we have our validation and persistence layers both within the Form Request class. # 3. Before-and-after-validation hooks you can tap into in Form Request class. If you need to do some logic before the validation runs, such as sanitizing data from the request, you can use the `prepareForValidation()` method. protected function prepareForValidation() { $this->merge([ 'slug' => Str::slug($this->slug), ]); } If you need to do some logic after the validation runs, such as performing further validations, you can use the `withValidator(...)` method. public function withValidator($validator) { $validator->after(function ($validator) { if ($this->somethingElseIsInvalid()) { $validator->errors()->add('field', 'Something is wrong with this field!'); } }); } **Bonus:** Form Request is just an instance of `Illuminate\Http\Request`. Which means whatever properties or methods you have access to using the `request()` helper, you can also access it in the Form Request class. For further information about Form Requests, visit the official Laravel documentation here: [https://laravel.com/docs/7.x/validation#form-request-validation](https://laravel.com/docs/7.x/validation#form-request-validation) Cheers!

2020-02-20

Wanna know how many routes you currently have in your Laravel application? Fire up tinker and enter the following codes: app(\Illuminate\Routing\Router::class)->getRoutes()->count(); ![Counting Routes](https://marvinquezon.com/storage/uploads/counting-routes.jpg)

Marvin Quezon · Copyright © 2024 · Privacy · Sitemap