-
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)
123456789field_address_full:- plugin: callbackcallable: array_filtersource:- address_1- city- state- plugin: concatdelimiter: ', '
This quick example shows one method to ignore empty values in a Drupal 10 migration concatenate process.
Code
Migrate code:
12345678910111213141516process:temp_address_parts:-plugin: skip_on_emptymethod: processsource:- address_1- city- state-plugin: callbackcallable: mymodule_migrate_filter_emptyfield_address_full:plugin: concatdelimiter: ', 'source: '@temp_address_parts'Module code:
12345678/*** Filters out empty values from an array.*/function mymodule_migrate_filter_empty($values): array {return array_filter($values, function ($value) {return !empty($value);});}Result
Example data:
1234address_1,city,state1 Main St.,Portland,ME2 Main St.,Portland,Portland,MEResulting field_address_full plain text value
1231 Main St., Portland, ME1 Main St., PortlandPortland, ME -
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!
1ddev logs -f | lnav -qIf 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.
-
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:
1234$boolNullFormatter = "function(cellval,options,rowdata){ return cellval === null ? '' : cellval; }";$cols[] = ['name' => 'is_in_gmb', 'isnull' => true, 'formatter' => $boolNullFormatter];$cols[] = ['name' => 'is_property', 'isnull' => true, 'formatter' => $boolNullFormatter];$cols[] = ['name' => 'is_telehealth', 'isnull' => true, 'formatter' => $boolNullFormatter]; -
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:
- My source data has locations; each location has multiple associated organizations
- My new Drupal site has locations; each location has a parent organization
- 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
- 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:
-
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).
12345# Every day at 11:55pm EST (due to conditional, commands only run during Standard Time (fall/winter)55 4 * * * [ `TZ=America/New_York date +\%Z` = EST ] && php artisan scrub-db >/dev/null 2>&1# Every day at 11:55pm EDT (due to conditional, commands only run during Daylight Saving Time (spring/summer)55 3 * * * [ `TZ=America/New_York date +\%Z` = EDT ] && php artisan scrub-db >/dev/null 2>&1Only one of the php artisan scrub-db commands will execute, depending on the time of year.
-
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:
-
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:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546<?phpnamespace Tests\Feature;use Illuminate\Cookie\CookieValuePrefix;use Tests\TestCase;class DiveDeeperTest extends TestCase{/*** Tests if the diveDeeper route appends the passed value to the cookie arr.* @return void*/public function test_it_updates_path_cookie(){// Post a deeperPath to the diveDeeper route (with a starter cookie).// This should append the "deeperPath" value to the "path" cookie array.$resp = $this->withCookie('path', serialize(['/']))->post(route('diveDeeper'), ['deeperPath' => 'Users']);// Assert that the cookie has been modified.$resp->assertCookie('path', serialize(['/', 'Users']));// If we make another post request here, it won't include our// modified "path" cookie. We have to retrieve it, then pass it// through to the next request.// Decrypt the cookie (now modified by the diveDeeper route).$cookieValue = CookieValuePrefix::remove(app('encrypter')->decrypt($resp->getCookie('path')->getValue(), false));// Hit the diveDeeper route again using the modified cookie value.$resp = $this->withCookie('path', $cookieValue)->post(route('diveDeeper'), ['deeperPath' => 'adam']);// Assert that the cookie has been modified again.$resp->assertCookie('path', serialize(['/', 'Users', 'adam']));// Etc...}} -
Any Random Saturday Using Faker
Here’s a quick one, folks. I’m using Faker in Laravel factories to generate realistic data. I have a “week end date” field in one of my models that must always be a Saturday. Here’s how I generate a unique random Saturday:
1date('Y-m-d', strtotime('next Saturday ' . $this->faker->unique->date())) -
Using “php artisan serve” with xdebug and PHPStorm
This is more of a person note for myself. This posts assumes some knowledge of php, Laravel, artisan, Homebrew, and xdebug.
I’ve been using php artisan serve to serve Laravel applications locally. It’s quick and it works well.
It’s probably not a great solution if you’re working with other people on a project, or if you want to implement a good CD/CI workflow. Having said that, it’s what I’m using today, so I figured I’d document how I got xdebug working with it (on my Mac).
-
Using Carbon to Generate Random Dates and Times
There are a number of ways to generate random dates/times in PHP. Here are some examples using the Carbon library:
1234567891011// Between now and 180 days agoCarbon::today()->subDays(rand(0, 180))> 2021-09-02 00:00:00> 2021-06-23 00:00:00> 2021-05-23 00:00:00// Between now and 180 days ago with random timeCarbon::today()->subDays(rand(0, 179))->addSeconds(rand(0, 86400));> 2021-06-11 22:35:03> 2021-10-24 13:19:53> 2021-06-09 20:47:44