Why I Haven’t Fixed Your Issue Yet

Michael Bromley on his blog:

There is an implicit agreement which needs to be understood by both consumers and creators of FOSS projects1. It goes something like this:

  • I agree to provide you with some free code which solves your problem.
  • I recognize that in doing so, I have taken on a small portion of responsibility to you as a user of my code.
  • I agree to try to help you if you have difficulty in using my code.
  • I agree to try to fix bugs that you find in my code.
  • Crucially, you agree that I, in acting without remuneration, am free to assign priority to the above points as I see fit.

The last point is the reason why I haven’t fixed your issue yet.

http://www.michaelbromley.co.uk/blog/529/why-i-havent-fixed-your-issue-yet

As a package consumer you should be grateful for the free code you're given. Keep in mind that when you use someone else's code, you are responsible for that code as well. If a package maintainer solves an issue for you that's great. If he or she doesn't, than that's your problem, not the maintainer's. You can always submit a PR with a fix. And if the fix or feature doesn't get accepted you can always maintain your own fork.

For our own packages we try to respond to every single issue in a timely manner. The users of our packages are generally very friendly and helpful. There's only one instance when things went sour. I do make a point of thanking everybody who takes the time to submit a PR. It's a small thing but I do believe it helps creating a positive vibe on our GitHub repo's.

Read more

Upcoming changes in PHP 7.1

Amo Chohan wrote a rundown of the big changes coming tot PHP 7.1

  • Catching multiple exception types
  • Curl HTTP/2 server push support
  • Support class constant visibility
  • Void return types
  • Generalize support of negative string offsets
  • Allow specifying keys in list() and square bracket syntax for array destructuring
  • Warn about invalid strings in arithmetic
  • Deprecate and remove mcrypt()
https://medium.com/@amo.chohan/upcoming-changes-in-php-7-1-76ebea53b820#.2udxw3qfe

Read more

Join 9,500+ smart developers

Get my monthly newsletter with what I learn from running Spatie, building Oh Dear, and maintaining 300+ open source packages. Practical takes on Laravel, PHP, and AI that you can actually use.

No spam. Unsubscribe anytime. You can also follow me on X.

Short list syntax for array destructuring approved

On dotdev.co Eric L. Barnes explains a new feature that is coming in PHP 7.1

With the accepted proposal it creates an alternative to using “list” for destructuring an array. In all previous versions of PHP this works like this: list($a, $b, $c) = array(1, 2, 3); Now you can extract using a square bracket just as you do for assignment: [$a, $b, $c] = [1, 2, 3]; ["a" => $a, "b" => $b] = ["a" => a, "b", => 2];
https://dotdev.co/php-unanimously-approves-short-list-syntax-for-array-destructuring-887208b661af#.58zwoz85l

Read more

PHP Session Garbage Collection: The unknown performance bottleneck

Here is one performance setting in your PHP configuration you probably haven't thought about much before: How often does PHP perform random garbage collection of outdated session data in your application? Did you know that because of the shared nothing architecture PHP randomly cleans old session data whenever session_start() is called? An operation that is not necessarily cheap.
https://tideways.io/profiler/blog/php-session-garbage-collection-the-unknown-performance-bottleneck

Read more

How to setup and use the Google Calendar API original

by Freek Van der Herten – 4 minute read

For a project I'm working on I needed to interact with a Google Calendar. If you've ever worked with some API's by Google then you know their documentation can be very confusing. It's not that they don't have documentation, but code examples of common use cases are simply not present. You must wade…

Read more

The magic behind Laravel Valet

Mohamed Said peeked behind the curtains and explains on his blog how Laravel Valet works behind the scenes.

The idea behind Valet is that it configures PHP's built-in web server to always run in the background when the operating system starts, then it proxies all requests to a given domain to point to your localhost 127.0.0.1
http://themsaid.github.io/magic-behind-laravel-valet-20160506/

If you want to keep Homestead around for some projects, know that your can also use dnsmasq to point an entire domain to your Homestead installation.

Read more

Introducing Laravel Valet

Chances are that if you've been following the news in the Laravel ecosystem that you've heard of Laravel Valent. If not: Laravel Valet is a super easy way to serve your sites in a development environment. It's dead simple to setup and use. Here's the intro video:

https://www.youtube.com/watch?v=H3Z4Gk9Wc0s

I think it's kinda amazing that it was built in just four days. Not everybody is a fan of the Valet approach be I sure do like it. At Spatie, we're going use Valet instead of Vagrant for most of our projects.

Need to know more about Valet? Check out this post on dotdev.co and the official documentation.

Read more

Type Wars

The venerable Uncle Bob makes the case for dynamic typing and TDD. Be sure to read the entire article to get a quick history lesson in computer languages.

The pendulum is quickly swinging towards dynamic typing. Programmers are leaving the statically typed languages like C++, Java, and C# in favor of the dynamically typed languages like Ruby and Python. And yet, the new languages that are appearing, languages like go and swift appear to be reasserting static typing? So is the stage for the next battle being set?

How will this all end?

My own prediction is that TDD is the deciding factor. You don't need static type checking if you have 100% unit test coverage. And, as we have repeatedly seen, unit test coverage close to 100% can, and is, being achieved. What's more, the benefits of that achievement are enormous.

http://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html

Read more

In Search of an Anonymous Class Factory

Mark Baker tried creating an Anonymous Class Factory.

I was intrigued by a request to find a way of dynamically applying Traits to a class at run-time. With time on my hands as I was sitting in the airport, I considered the problem; and my first thought was to build an Anonymous class, extending the requested class (so that it would still contain all the base properties and functionality, and could be type-hinted, but also applying the requested Trait or set of Traits.

https://markbakeruk.net/2016/05/03/in-search-of-an-anonymous-class-factory/

Read more

Route model binding using middleware

Our team is currently working on a Spark app. Spark makes is real easy to add an API that can be consumed by the users of the app. The generation of API tokens and authentication middleware comes out of the box. It all works really great.

In our API the a team owner can fetch information on every member on the team and himself. The url to fetch info of a user looks something like this: /users/<id-of-user>. Nothing too special. But we also want to make fetching a user's own information as easy as possible. Sure, the user could look op his own userid and then call the aforementioned url, but using something like /users/me is much nicer. In this way the user doesn't have to look op his own id. Let's make that possible.

In our app we use these functions to get the the current user and team:

/**
 * @return \App\Models\User|null
 */
function currentUser()
{
    return request()->user();
}

/**
 * @return \App\Models\Team|null
 */
function currentTeam()
{
    if (!request()->user()) {
        return;
    }

    return request()->user()->currentTeam();
}

The route look something to get the user data looks something like this:

Route::post('/users/{userId}', 'UserController@show');

My first stab to get /users/me working was to leverage route model binding. In the RouteServiceProvider I put this code:

$router->bind('userId', function ($userId) {
   if ($userId === "me") {
      return currentUser();
   }

   $user = currentTeam()->users->where('id', $userId)->first();

   abort_unless($user, 404, "There's no user on your team with id `{$id}`");

   return $user;
});

Unfortunately this does not work. When Laravel is binding route parameters the authentication has not started up yet. At this point currentUser and currentTeam will always return null.

Middleware comes to the rescue. Route-middleware is processed at a moment when authentication has started up. To make /users/me work this middleware can be used:

namespace App\Http\Middleware;

use Closure;

class BindRouteParameters
{
    public function handle($request, Closure $next)
    {
        if ($request->route()->hasParameter('userId')) {
            $id = $request->route()->parameter('userId');

            $user = $this->getUser($id);

            abort_unless($user, 404, "There's no user on your team with id `{$id}`");

            $request->route()->setParameter('userId', $user);
        }

        return $next($request);
    }

    public function getUser(string $id)
    {
        if ($id === 'me') {
            return currentUser();
        }

        return currentTeam()->users->where('id', $id)->first();
    }
}

There are two things you must do to use this middleware. First: it's route middleware so you such register it as such at the http-kernel.

// app/Http/Kernel.php

...
/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
...
'bindRouteParameters' => \App\Http\Middleware\BindRouteParameters::class,
]

Second: you must apply the middleware to certain routes. In a default Spark app you'll find all api-routes in a file at app/Http/api.php. That file starts with this line:

Route::group(['prefix' => 'api', 'middleware' => ['auth:api']], function () {
...

Just add the bindRouteParameters middleware to the group:

Route::group(['prefix' => 'api', 'middleware' => ['auth:api', 'bindRouteParameters']], function () {
...

I'm currently using the above solution in my app. You could make a solution that's more generic by checking if the parameters ends with orMe. Here's an example how that might work:

namespace App\Http\Middleware;

use Closure;

class BindCurrentUserRouteParameter
{
    public function handle($request, Closure $next)
    {
        collect($request->route()->parameters())
            ->each(function ($value, $parameterName) use ($request) {
                if (!ends_with($parameterName, 'orMe')) {
                    return;
                }

                if ($value === 'me') {
                    $request->route()->setParameter($parameterName, currentUser());
                }
            });

        return $next($request);
    }

If you have any questions about this approach or have any ideas how to make it better, let me know in the comments below.

Read more

Being A Developer After 40

Adrian Kosmaczewski shares lessons learned on what truely are the important things in your career as a developer. Even if you're not even close to approaching 40 years of life on the planet you should read this.

I have often pondered about leaving the profession altogether. But somehow, code always calls me back after a while. I like to write apps, systems, software. To avoid burning out, I have had to develop strategies.

In this talk I will give you my secrets, so that you too can reach the glorious age of 40 as an experienced developer, willing to continue in this profession.

...

As long as your heart tells you to keep on coding and building new things, you will be young, forever.
https://medium.freecodecamp.com/being-a-developer-after-40-3c5dd112210c#.11l62gnmg

Read more

Don't use illuminate/support in framework agnostic packages

In our framework agnostic packages we sometimes pull in illuminate/support. This package that's part of the core of Laravel provides some nice string and collection functions. But unfortunately a lot of other stuff gets pulled in as well. In a post on his blog Matthew Allen explains the downsides of requiring illuminate/support.

A lot of framework agnostic Composer packages (PHP) pull in illuminate/support, which contains helper functions and general purpose code used by the Laravel framework. Usually it’s because the support package has nice helper functions like array_get, or because of the nice collection class.

The helpers functions are nice, but I don’t think developers appreciate the ramifications of choosing to pull that package in. Everyone is afraid to get criticized for reinventing the wheel, so packages are pulling in 6000+ lines of code to avoid writing isset($arr[$k]) ? $arr[$k] : null themselves.

http://mattallan.org/2016/dont-use-illuminate-support/

One of the most useful functions of illuminate/support is the Collection class. In a thread on Reddit Taylor Otwell, the creator of Laravel, seems to agree that requiring illuminate/support isn't a good idea and that the Collection class could be extracted to it's own package. Let's hope that'll happen in the near future.

In the new major versions of our framework agnostic packages we'll swap out illuminate/support in favor of packages like the ones mentioned at the end of Matthew's post.

EDIT: Meanwhile Tighten has released a Collections-only split from Laravel's Illuminate Support.

Read more

Starting a business with Laravel Spark

Christopher Pitt is starting a new business with Spark. Over at the Sitepoint blog he has posted a tutorial on how to get started with Taylor's latest creation.

I am really excited about Laravel Spark. By the time you read this, there will probably be a multitude of posts explaining how you can set it up. That’s not as interesting to me as the journey I’m about to take in creating an actual business with Spark!

I have often wanted a way to quickly and painlessly transfer this application state from one server to another, and make automated offsite backups. So I’m going to set that up for myself, and perhaps others will find it useful enough to pay for it.

http://www.sitepoint.com/starting-a-business-with-laravel-spark/

At Spatie, we're also in the process of creating or first SaaS based on Spark. That's why our package output will slow down a bit. It's too early to give any specifics on what we're building but I can already tell you that it's something very simple that we need at the company ourselves. Thanks to Spark we can open our solution up to other users. You'll hear more about it in a month or so.

Still on the topic of Spatie, maybe you've noticed that our company website is in Dutch. So most of you can't understand a single word on it. That's going to change in the near future: besides building a SaaS our team is in the process of creating a new website. This time there will be an English version.

Exciting times!

Read more

Let’s Talk About The Backup Strategy

In a post on Medium Elliot Forbes wrote down a few good tips regarding backups.

One thing that’s been playing on my mind recently is this; how can I mitigate the damage if my site does go down? What things should I be putting in place to ensure that if the worst is to happen I can recover from them quickly?

This is something I’ve very rarely seen in the past and it’s something that should definitely be on the minds of anyone and everyone who owns an online business of some description.

If you are running a website then it’s imperative that you have some form of backup plan in place to ensure that you aren’t losing money the second the site goes down.

https://medium.com/@elliot_f/lets-talk-about-the-backup-strategy-6fa8079c44bd#.y7ubfu5l8

You should always be prepared for the worst. Starfleet recommends having two separate backups. Who am I to argue with O' Brian?

https://www.youtube.com/watch?v=UaPkSU8DNfY

Read more

Cloudflare adds support for http2 server push

Cloudflare pushes forward! Read the entire article for a good explanation on http2 and server push.

Today, we’re happy to announce HTTP/2 Server Push support for all of our customers. Server Push enables websites and APIs to speculatively deliver content to the web browser before the browser sends a request for it. This behavior is opportunistic, since in some cases, the content might already be in the client’s cache or not required at all.
https://blog.cloudflare.com/announcing-support-for-http-2-server-push-2/

In semi-related news: Laravel Forge recently made a nice change as well. If you install an ssl certificate on a Froge provisioned server, http2 will be enabled by default.

Read more

Using Github authentication for login with Laravel Socialite

Laravel hero Matt Stauffer has a new article on his blog where he talks about using a social network site login as the primary login for your application.

Laravel's Socialite package makes it simple to authenticate your users to Facebook, Twitter, Google, LinkedIn, GitHub and Bitbucket. You can authenticate them for the purpose of connecting their pre-existing user account to a third-party service, but you can also use it as your primary login mechanism, which we'll be talking about here.

I'm working on a new little micro-SaaS that is purely dependent on GitHub in order to operate, so there's no reason to set up any user flow other than just GitHub. Let's do it.

https://mattstauffer.co/blog/using-github-authentication-for-login-with-laravel-socialite

Read more