• Development

    Laravel + Filament + Private Disk on Cloudways

    Introduction

    After a long, frustrating debugging exercise, I have discovered a quick tip for my Cloudways + Laravel friends. The “why” is still a touch fuzzy for me at the moment, but I’ll at least explain the symptoms and the fix.

    The goal: Add a private file upload to a Filament resource form, ensuring anonymous users cannot download/view the file.

    The issue: Everything was working great in my ddev environment. I could preview and open the files if I was logged in, and I would see a 403 if I was logged out. When I moved this to a Cloudways server I was getting automatically logged-out every time I hit a private file URL. Weird, right?

    Code

    Here’s the final code (the Cloudways “fix” is further down this page):

  • Development

    Writing Tests for Drush Commands

    There are plenty of examples of these in the wild, but I figured I’d show a stripped down version of an automated Kernel test that successfully tests a drush command. The trick here is making sure you set up a logger and that you stub a few methods (if you happen to use $this->logger()  and dt()  in your Drush commands). Also featured in this example is the use of Faker to generate realistic test data.

    I learned this via the migrate_tools project here.

  • Development

    Using Data Providers in PHPUnit Tests

    This is the before code, where a single test is run, and each scenario I’m testing could be influenced by the previous scenario (not a good thing, unless that was my goal, which it was not).

    This is the after code, where three tests are run. Unfortunately this takes 3x longer to execute. The upside is that each scenario cannot affect the others and it’s perhaps more readable and easier to add additional scenarios.

     

  • Development

    Skip Empty Values During Concatenation in a Drupal 10 Migration

    UPDATE. You can do the same as below without the need for a custom module function. (source)


    This quick example shows one method to ignore empty values in a Drupal 10 migration concatenate process.

    Code

    Migrate code:

    Module code:

    Result

    Example data:

    Resulting field_address_full plain text value

     

  • Development,  Tech Tips

    Using lnav to View Live DDEV Logs

    https://lnav.org/ is a fantastic tool to work with log files. The SQL query functionality is a lot like https://github.com/multiprocessio/dsq, which also impresses.

    My quick tip is that lnav can read from stdin. This means you can pipe content into it. Here’s how I monitor my ddev environment in realtime. Hooray for colors!

    If you haven’t explored lnav you’ll want to dive into the documentation a bit. It does a lot more than just give pretty colors to your log files / output. https://docs.lnav.org/en/v0.11.2/hotkeys.html is certainly worth bookmarking.

  • Development

    Rendering null boolean values with Grid4PHP

    I’m a big fan of Grid4PHP for adding a quick CRUD user interface to a MySQL database.

    I have a lot of boolean columns, like “is_telehealth” that need to start as NULL until we make a determination about the field’s value. Grid4PHP renders null booleans as “0” in the table/edit form. This is misleading, given it’s not actually a 0 value. If you add the ‘isnull’ attribute to the column it lets you save the null value, but it still renders as a “0”.

    Using a custom formatter I was able to render an empty string (nothing) instead of “0” for these null booleans:

  • Development

    Drupal Migrate API skip_on_multiple Process Plugin

    Here’s a Migrate API process plugin I wrote in Drupal 9 that skips a property or row when more than one value exists. My use case:

    1. My source data has locations; each location has multiple associated organizations
    2. My new Drupal site has locations; each location has a parent organization
    3. I want to only populate the field_parent_org field (an entity reference) if there is a single organization value in the source data for the location
    4. I’m using a custom module called “pdms_migrate”

    I’ve stripped out all of the noise from the examples below… hopefully it’s enough to help you understand the example:

  • Development,  Tech Tips

    Handling Daylight Saving Time in Cron Jobs

    • Our business is located in Maine (same timezone as New York; we set clocks back one hour in the Fall and ahead one hour in the Spring)
    • Server A uses ET (automatically adjusts to UTC-4 in the summer, and UTC-5 in the winter)
    • Server B uses UTC (not affected by Daylight Saving Time) – we cannot control the timezone of this server

    We want to ensure both servers are always referencing, figuratively, the same clock on the wall in Maine.

    Here’s what we can do to make sure the timing of cron jobs on Server B (UTC) match the changing times of Server A (ET).

    Only one of the php artisan scrub-db  commands will execute, depending on the time of year.

  • Development,  Tech Tips

    Using Dataview with Charts in Obsidian

    Obsidian is my third most used application after Keyboard Maestro and Alfred. I’ve been using the dataview plugin since I got started with Obsidian. It’s an incredible plugin that gives you the ability to treat your notes like database records. In this example I’ll show how I use dataview to make my projects queryable, and then how I use Obsidian-Charts to make some bar charts of this data.

    Using Dataview Variables

    Here’s an example of a Project file in my Obsidian vault:

    Example project file in Obsidian

  • Development

    Testing Cookie Modification in Laravel 8

    If there’s a better way to pass a cookie from one request to another, in a phpunit feature test in Laravel, please let me know! Here’s one way to handle it: