My standard Laravel development tools

Now that I’ve been actively developing applications with the Laravel framework for a few years, I thought I’d write down the tools and services I tend to use on a regular basis in that work.

I’ve spent a fair amount of time researching and experimenting with these tools and their alternatives in order to make a choice, so maybe it will help someone else who hasn’t gone through that yet. I’m always glad when others share details about their development environments so that the rest of us who are just getting going can build on that foundation.

Hardware and Development Environment

Launching a New Project

composer global update laravel/installer
laravel new example-app --git --branch="main"
cd example-app
valet link
valet secure example-app

Then I create a database, add the DB info in .env, run artisan migrate, and I’m ready to develop. Sometimes I have to make sure PhpStorm has the right coding standards and PHP Code Sniffer config in place.

Sometimes I add a .psysh.php file to my project repo with these contents:

<?php
DB::listen(function ($query) {
    dump("[{$query->time}ms] {$query->sql}");
    if ($query->bindings) {
        dump($query->bindings);
    }
});

When using artisan tinker, this prints out any SQL queries that were run by a given command within the tinker session, for faster debugging.

For WordPress projects, I use a customized version of this “valetpress” bash script to initialize new projects.

Continue reading My standard Laravel development tools

Customizing Newsletter Glue for WordPress post notifications

I love the Newsletter Glue plugin for WordPress. Before I found it, I had tinkered for a long time with different imperfect solutions to what seemed like a simple need: quickly and easily send people an engaging, visually appealing email when I publish a new article on my website.

I’ve tried manually sending out Mailchimp campaigns after publishing (too slow and cumbersome to customize per post), using messages sent directly from my WordPress host server (too prone to being flagged as spam), automatically generating Mailchimp campaigns from an RSS feed (limited scheduling options and prone to errors), using WordPress.com new post notifications via Jetpack (not very customizable), developing my own plugin to send on demand via MailChimp’s API (very functional but not easily re-usable across sites), and others.

Alas, nothing felt quite like what I wanted.

I’d revisit the challenge now and then, especially when I’d see everybody over there loving on Substack like “oh isn’t amazing how you can send out a readable email newsletter from a website, what an innovation” and found myself rolling my eyes especially hard. “SURELY WE SHOULD BE ABLE TO DO THAT WITH WORDPRESS!” I’d exclaim. And then my family would look at me with tilted heads before going back to whatever they were doing.

I was about to start putting some serious time into turning my own proof of concept Mailchimp API plugin into something reusable and shareable, when I did one last round of research into existing options. And that’s when I found Newsletter Glue. The sky opened up. Light shone down. I did a dance. At least that’s what it felt like. (I see that Justin Tadlock at WP Tavern has had a similar experience.)

So, yes, ahem, where was I? Oh, right: Newsletter Glue is an elegant solution to a real need in the world of WordPress publishing. Go check it out if you haven’t already. I bought a 5-site license and sent Lesley Sim, one of the plugin’s co-creators, a note of appreciation.

The rest of this blog post is about a few additional Newsletter Glue customizations I set up. While some of this is possible via the Newsletter Glue UI, I did it via a small custom plugin that I could re-use across all of my WordPress sites without additional configuration.

Continue reading Customizing Newsletter Glue for WordPress post notifications

Unlocking email content into RSS feeds redux with WordPress and Postie

As a part of some local journalism projects I’m exploring, I wanted to have a way to get information that is being emailed around (press releases, newsletters) into a publicly accessible RSS feed.

I’ve already explored this general “unlock email into an RSS feed” workflow using Zapier but Zapier’s limitations around translating HTML email messages into useful RSS entries led me to explore other options. For a while now I’ve been using Feedly’s paid feature that lets you receive email at a custom address and puts the content into your feed reading experience, and that’s actually been a good solution for me as an individual. (I made sure to set up an address at a domain I control and aliased that to Feedly’s provided address, in case I want to move to another solution later.)

But if we want to help a given audience have better access to information that’s only available in email but is intended to be public, I don’t think it scales well to ask them all to subscribe to the same email newsletter, or to all sign up for a Feedly paid plan. And yet so many organizations continue to use email as a way to distribute information, often instead of a website, and it doesn’t scale well to beg each of them to start (or go back to?) publishing their updates on a website with an RSS feed.

I started looking at using Mailparser for a more generalized solution. Receive the emails, have Mailparser extract the information into a structured, API-queryable format, and then download that information (including any attachments and images) and put it up on a publicly accessible URL somewhere. I knew I needed a way to organize the information coming in according to the email address of the person who sent it, so I’d have to build a small application that managed that categorization during the publishing process.

And then I realized I was basically getting into CMS territory. Publishing text and media on a website. Organizing content by categories and authors. Searchable and sortable. Yeah, I know a tool that already does all that stuff really well: WordPress.

But was I still going to need to build a glue application to process the emails and create WordPress posts?

I was aware of Jetpack’s post by email feature and I think it could work well for some scenarios, but I wanted something a little more purpose built. I did a little bit of Googling and found Postie, a WordPress plugin that has great features for bringing emails into WordPress posts. I exclaimed many words of delight upon finding it, and continued to be impressed as I looked through the thoughtful documentation, the developer-oriented options for extending and customizing it, and the active support and maintenance that goes into it. The WordPress community is amazing that way. I sent the developer a donation.

So, here’s the new workflow I would use:

  • Email is sent to an alias at my custom domain, which goes to a free email provider with IMAP access.
  • Every half hour, Postie goes out and checks for new email messages and creates pending WordPress posts.
  • I get a notification in a Slack channel about the WordPress post, and can publish it if appropriate.
  • The WordPress site provides a built in RSS feed of “emails” as posts on the site.

Amazing! But I still wanted a way to organize the incoming emails and resulting posts based on sender, without using Postie’s default method of creating WordPress users for each sender.

So, I created a custom taxonomy, Sources, with some term meta fields that allow me to associate email addresses and to select whether posts from that source should be pending or published by default. (Of course, email can be forged so it’s never safe to depend on the value of the “From” address in an email to authenticate anything important.)

Here are some code snippets used to accomplish this in a custom WordPress plugin I set up to complement Postie.

Continue reading Unlocking email content into RSS feeds redux with WordPress and Postie

Ending support for some little-used WordPress plugins

Today I am making these three little-used WordPress plugins that I created inactive, in the sense that I will no longer update them, test them against newer versions of WordPress, or provide support for them. If after a time no one else wants to take over maintaining them, they will be closed.

Each plugin has around 10 or fewer active installations and minimal or no user reviews. Given that it takes time to test each plugin I maintain for upcoming WordPress releases and PHP changes, and to support any inquiries or feature requests they may receive, I have to balance the requirements of continuing that work against the value each plugin offers. In these cases, I’d like to free up that maintenance time for other things.

I will leave the GitHub repos public indefinitely in case anyone wants to fork them or take them over.

This change does not affect the other WordPress plugins I maintain.

If you’re interested in taking over responsibility for one or more of these plugins, please contact me.

Thanks to everyone who tried them out and gave feedback along the way.

Creating a personalized, private RSS feed for users in Laravel

In building WP Lookout I had the need to create user-specific, private RSS feeds as a way for users to get updates and information specific to their account. Here’s how I did it.

I started with the laravel-feed package from Spatie, which allows you to easily generate RSS feeds, either from a model’s records or from some other method that you define. I found that someone has proposed a feature and submitted a PR to add support for signed routes, which is Laravel’s way of adding a hash key to a given URL so that it can’t be accessed if it’s been modified, perfect for something like a user-specific RSS feed. But the Spatie folks decided not to include the feature, so I had to figure out how to do it on my own.

First, I added the package to my project and published the related config file:

$ composer require spatie/laravel-feed
$ php artisan vendor:publish \
    --provider="Spatie\Feed\FeedServiceProvider" \
    --tag="config"

Then, I added a user-specific feed identifier to the User model:

$ php artisan make:migration add_feed_id_to_users_table --table=users

The migration looked like this in part:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        //
        $table->string('feed_id');
    });

    DB::statement('UPDATE users SET feed_id = ...');
}

The UPDATE statement there is used to set the initial value of the feed identifier for existing users. An alternative would have been to make the field nullable and then set it elsewhere. For new users, I set the feed identifier as users are created, via the boot() method in the User model:

Continue reading Creating a personalized, private RSS feed for users in Laravel

Quick hack to monitor the health of a collection of AWS services

My SaaS app WP Lookout uses Amazon Web Services for hosting. I’ve had plenty of monitoring set up using both internal and external tools notifications, and these mostly output to a combination of a dedicated Slack channel and/or a Pushover notification that goes to my mobile device.

The one thing I didn’t have in place until recently was monitoring for the health of the specific group of AWS services the app depends on. With AWS offering many services spread across many parts of the world (as illustrated in the Very Long Service Health Dashboard), I wasn’t about to start monitoring all of the AWS infrastructure just to see if my particular app was affected.

They do offer a “Personal Health Dashboard” that’s supposedly more tailored to incidents affecting my AWS account, but I find it unintuitive and confusing to use, especially when it comes to setting up notifications to external services like Slack. In my online searching I found various services and tools that supposedly integrated the PHD into more standard monitoring and alerting options, but they were also either too complicated or seemed to require additional levels of paid AWS support plans that I didn’t want to take on.

So I decided to keep things simple and use the tried and true technology for polling information about external resources: RSS!

Continue reading Quick hack to monitor the health of a collection of AWS services

Remembering DB_Browser

Book cover for the O'Reilly book Oracle & Open Source

Today on Twitter I was remembering that one time when an @OReillyMedia software book said that some code I’d written was “definitely worth a look.”

It started as a project for an internship at a local ISP, where they had a need to quickly browse, search or update a certain database using a web browser. I threw it together in a few days using Perl and the data dictionary info offered by PostgreSQL (and later MySQL and Oracle)

I called it DB_Browser, and it was basically what PhpMyAdmin became, but abstracted out enough to use with any of those three database systems. (Solid database abstraction layers used to be a real thing!)

It was almost certainly full of security vulnerabilities, relying entirely on the use of .htaccess rules to prevent total chaos. The UI was as ugly as sin, the code not much better. But it worked, and I believe it was used in some form until the ISP was acquired years later.

I took the time to package it up and publish it. I think I put it on “Freshmeat,” a site that was just a feed of newly released software, back when you could even try to track such things. It started getting downloads and people started using it.

Continue reading Remembering DB_Browser

My first CiviCRM extension: Slack notifications

I’ve started using CiviCRM for an organization I’m working with. If you’re not familiar with it, it’s an open source constituent relationship management tool for not-for-profits, political organizations and other entities that might have a need to manage relationships with supporters, volunteers, donors, members and so on.

I’ll try to reflect more soon on the process of getting started with CiviCRM; it was a little rocky. But to get myself familiar with CiviCRM’s inner workings, I decided to write a simple extension that would allow the organization to get Slack notifications when certain objects (contacts, contributions, pledges) were created or updated. I couldn’t find any similar existing extensions in their directory or in my searching.

Here’s the settings screen:

(with apologies for the weird extra bullets, can’t seem to make them go away yet) and here’s what a resulting Slack message might look like:

The extension is available on GitHub. I’m sure there are many ways to improve it, so issues and pull requests are welcome.

Update on April 20, 2021: the extension now provides a more flexible CiviRules action for Slack notifications instead of a standalone notification method, so some of the above information is outdated.

Life so far with a 2020 13″ MacBook Pro

I recently switched from using a Mid-2015 15″ MacBook Pro to a 2020 13″ MacBook Pro with Apple’s Silicon M1 chip. It was a Big Deal in the sense that my computer is a primary daily tool in my personal and professional life. So much of my work, my creativity and the management of my life is handled through this one device, so it’s always a little scary to make a change. (I actually could have been happy continuing with my previous laptop if its battery hadn’t been expanding, causing the entire computer to bulge in weird and alarming ways.)

Here are a couple of things I observed in making this transition and in using the MacBook every day since:

Apples to Apples

My previous MacBook Pro was pretty high end (2.8 GHz Intel Core i7 Processor, 16 GB 1600 MHz DDR3 RAM, Intel Iris Pro 1536 MB Graphics, 1TB HD) and very fast for the things I used it for. These included software development, hosting multiple software development environments, audio and video editing and rendering, graphic design and photo editing, and LOTS of browse tabs. It took everything I could throw at it and I never felt slowed down by the computer itself.

So the idea of “downgrading” to a smaller screen (13″ instead of 15″), fewer ports, and the same amount of RAM but 5 years later was a bit nerve-wracking.  Conventional wisdom for a long time was that 13″ MacBook Pros were fine for some kinds of advanced computing but that the 15″ model was always the best option for the kinds of things I use it for. Maybe this was just me naively buying into Apple’s marketing, but it seemed to be supported by testimonials from colleagues over the years, and was a strong narrative in my head nonetheless.

But I’d heard and read that the Apple Silicon M1 chip was a game-changer, and that any comparison between Intel and the newer processors was not really valid. And after seeing enough stories from real users where they said the new chip plus 16GB of RAM was even faster running some of the same software I do, even with Rosetta 2 translation turned on, I was sold.

Continue reading Life so far with a 2020 13″ MacBook Pro

Intercepting mail with MailHog in Laravel Valet

I’m trying out using Laravel Valet to manage the development environments for both my WordPress and Laravel related work. (This is not the result of any dissatisfaction with VVV, which I’ve happily been using for the WP work, and Laravel Homestead, which I’ve happily been using for Laravel work, but comes as a necessity now that I am using a Mac with Apple’s M1 ARM chip, which doesn’t support Intel Vagrant virtual machines.)

The Valet installation and setup was easy and fast using their instructions, and I’ve been able to successfully move projects over to it without a lot of hassle. The one place where I was really bit was taking for granted how those previous virtual environments where handling the intercepting of email generated by my applications, so that they didn’t actually go out onto the Internet for actual delivery. I got used to spinning up environments with copies of production data and not worrying about real users getting email messages.

Well, you can guess what happened when I did that in Valet, which by default delivers email just like any other email generated from a process running on my Mac. Spinning up a WordPress dev site with a slightly outdated database dump and with functionality that is all about notifying users via email of things that are about to happen or have happened meant…lots of emails going out.

Ugh. Apologies, installing Stop Emails and other cleanup ensued.

Fortunately, the long term fix is pretty easy. Yes, there are various plugins one can install on individual WordPress sites to stop email from going out, or to change default SMTP behavior. But I didn’t want to have to worry about that each time I clone a site. So instead I changed the default SMTP behavior for the php-fpm processes that Valet runs to deliver all mail to MailHog.

First, I installed MailHog:

brew install mailhog
brew services start mailhog

Then, I added a smtp-mailhog.ini file in the PHP conf.d directory for my setup. In my case that was each version in /opt/homebrew/etc/php/X.X/conf.d. The contents of that file are:

; Use Mailhog for mail delivery
sendmail_path=mailhog sendmail

Then I ran valet restart and tested by triggering a password reset email from a WordPress site, and confirmed that it had been intercepted by visiting the MailHog interface at http://127.0.0.1:8025.

Of course this setup may not fit every use case, so adjust your config accordingly. (I submitted a PR to the Laravel docs with this info, but understandably it was probably too specific to my setup.) Even if you don’t change the PHP-level settings, with MailHog installed you could set up individual sites/applications to send to it as needed.