Reading The Art of Modern PHP 8 (part 2)

In my reading of the PHP OOP Manual, I ended up pretty far afield.

Somehow I got to Crell's blog (although I think that was by way of another Drupal user) and started reading about static functions, wherein Garfield describes both their drawbacks (really hard to test and to safely change code that uses them, as it forms tight coupling) and when to use them (when operating in the context of a type). His code had something that I hadn't seen (or noticed):

class ProductNotFound extends \InvalidArgumentException
{
    public readonly int $productId;
    public readonly array $query;
    
    public static function forId(int $id): self
    {
        $new = new self();
        $new->productId = $id;
        
        $message = 'Product %d not found.';
        $new->message = sprintf($message, $id);
        
        return $new;
    }
   ... // more code follows, but removed for brevity

I didn't know what the "self" type hint was, so I looked it up.

First, I found this article about the various return types in PHP, but it didn't really answer my question. Instead, I found this other post about self and parent, which cleared things up. The example of when to use a function as the "forId" example above with the "self" return is for a setter. Though the code above returns an object of the type "ProductNotFound", so it's not a setter. More like a factory? Maybe?

More things I don't understand:

  • value object (as in "ProductNotFound is an exception, and therefore a value object.")
  • dechex(int)
  • self()
  • autoloading
  • dynamic properties, though these have been deprecated in PHP 8.2, so it's not urgent to figure them out.
  • read only classes (What is a good use for this? I did make a pull request in this section, though.)
    • A little more reading, such as on Stitcher.io, and I now understand that readonly classes are syntactic sugar for having a class with properties that are readonly.
    • And the JetBrains video on the Stitcher.io page is helpful in describing when read only properties are useful, especially when you need to structure data, as in a data transfer object (DTO) or a value object. I feel like the DTO makes sense. You read in some other data and map it to the properties of an object. Because the properties are readonly and can only be set once, they can be public without fear that they will be overwritten or corrupted.
    • Read only properties were introduced with PHP 8.1. Because of the scenario of a DTO, you'd need to add "public readonly" to all the properties. Now, with readonly classes in 8.2, you need only write "public readonly" on the class itself, which makes all the properties readonly.
    • So what good were dynamic properties pre-8.2? 

 

 

 

Reading The Art of Modern PHP 8 (part 1)

I have been wanting to get more confident in my coding for some time. Even though I'm working on custom Drupal modules all the time, writing scripts and hook updates, I still feel out of my depth when initially encountering new code. In fact, the other day, I was reading through a yml-based migration configuration and even at that got tripped up. Let alone looking at the plugin, itself. So I started looking at some good books on PHP 8 and came across The Art of Modern PHP 8 by Joseph Edmonds.

My intention is to follow this book and get through it as a way to becoming more adept at PHP 8.

First step, though, is getting php running.

Installing PHP

I didn't know for sure if my MacBook Pro (M2, 2022, 13 in), running macOS Ventura 13.4 had PHP installed already, so I typed in Terminal

$ php

and got the following

zsh: command not found: php

No problem. I had Hombrew installed already, so I ran

brew install php

And then got screen upon screen of installs, ending with

To enable PHP in Apache add the following to httpd.conf and restart Apache:

    LoadModule php_module /opt/homebrew/opt/php/lib/httpd/modules/libphp.so

    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>

Finally, check DirectoryIndex includes index.php
    DirectoryIndex index.php index.html

The php.ini and php-fpm.ini file can be found in:

    /opt/homebrew/etc/php/8.3/

To start php now and restart at login:
  brew services start php
Or, if you don't want/need a background service you can just run:
  /opt/homebrew/opt/php/sbin/php-fpm --nodaemonize

Chapter 1

First things, first, though, in terms of getting a handle on PHP: RTFM, as my friend Harry says.

Looking at the PHP documentation on Classes and Objects is going to take a while, though, as the first section, "The Basics" is 20 pages.

 

U34 found (on the bottom)

While trying to find U34 on the Newton 2100 motherboard, I went into the archives to see if I could see it in the schematic.

This message on NewtonTalk had a link to schematics:
https://marc.info/?l=newtontalk&m=168373202124894&w=2

I went through it and found U34 on page 11. Somehow the process of doing so made me look back at the link Frank had shared of some very nice photos of the boards:

https://marc.info/?l=newtontalk&m=169723156830363&w=2

It turns out that U34 is on the bottom of the motherboard (where I hadn't even looked yet).

Thanks, again, Frank.

 

I can’t find U34

Board near the battery terminals

So in trying to find the piece that needs to be replaced to prevent the 2100 restart loop, I couldn't find U34. The only components that look like they might be the right ones are U36 and U31.

 

Drupal QA and Code Review

Things to check

QA

  • Does it do what it says?
  • Does it throw any errors on the "Recent Logs (dblogs)"?

Check modules

  • Did the composer.json change?
  • Did the composer.lock change?
  • Should they have changed?

Config changes:

  • Check the yml files
  • Are the changes to the correct view?
  • Should it be to a specific display?

 

Recreating ThinkShout's home page--with one hand tied behind my back (part 1)

Recently, I was visiting the sites of Drupal development shops and came across ThinkShout. The home page has a number of UI elements and behaviors that are familiar but well-done:

  • a logo that reduces size upon scrolling down
  • a sticky header
  • overlining of menu items on hover
  • a semi-opaque dark overlay on images with text on hover
  • re-ordered footer elements on mobile
    ThinkShout Home Page Screenshot
    Figure 1: Screenshot of the ThinkShout Home Page from 6 Sept 2021

     

I decided to try to create my own version of this homepage to flex my HTML, Javascript, and CSS (Sass-in particular) muscles. 

I've been as superstitious as a traditional groom on his wedding day so as not to look at the ThinkShout code. That way, I have had to reverse engineer the HTML, CSS, and JavaScript underneath as if it were a black box. It's been tempting, though, especially when it comes to colors; but so far, I have kept my eyes averted.

Top Menu Item Overline on Hover

For the sake of simplicity (and what I was working on just today), I'll discuss the top menu behavior on hover. On that menu, there's a line (which I'm calling an overline) that appears at the very top of the window (see Figure 2). 

I eventually noticed that the color was slightly lighter on each subsequent menu item (from left to right), even though the text color of the menu item did not change. I little searching on the web brought me to the Sass @for.

The example from that page (below) was remarkably similar to what I wanted to:

		
		$base-color: #036;

		@for $i from 1 through 3 {
		  ul:nth-child(3n + #{$i}) {
			background-color: lighten($base-color, $i * 5%);
		  }
		}
	

Final(?) implementation

I played around with the color gradations until I arrived at one that looked acceptable (See Figure 3). It turned out 7% was the sweet spot for border-top-color: lighten($secondary, $i * 7%);.

	
	
	$secondary: #f07c00;

	ul.desktop {
			a {
				height: 103px;
				padding-top: 45px;
				box-sizing: border-box;
				&:hover {
					color: $secondary;
					border-top-width: 5px;
					border-top-style: solid;
					padding-top: 40px;
				}
			}
			li {
				display: flex;
				@for $i from 1 through 5 {
					&:nth-child(1n+#{$i}) a:hover {
					  border-top-color: lighten($secondary, $i * 5%);
					}
				  }
			}
		}
	

thinkshout menu overline for comparison original
Figure 2: ThinkShout menu hover behavior (original)

thinkshout menu overline for comparison (my version)
Figure 3: ThinkShoul menu hover behavior (my implementation)

 

Take Note of this Noteworthy Advice

Note-taking with a Flat Stanley tribute on the Newton 2000

For many years, I've taken notes nearly every day. Here's a nearly exhaustive list of the ways I've done so, in approximate chronological order:

  • yellow legal pads
  • Handspring visor (through grafiti)
  • Handsprint visor (with keyboard)
  • Apple Newton (with keyboard)
  • Moleskine or other bound journal
  • Palm LifeDrive (with keyboard)
  • Evernote
  • Livescribe Pens (starting with the Pulse, then a number of Echos and a Sky)
  • Notational Velocity
  • NvAlt
  • Quivver (a Mac app supporting markdown)
  • Neo smartpen (more than one)
  • Field Notes books
  • Wipeboard (laminated pages for dry erase markers in a notebook)
  • Apple Notes
  • Microsoft OneNote


Attempts to keep better notes has been a many year endeavor.

There have been overlaps in many of these systems. In fact, I've been using Evernote (where I am drafting this right now) with varying regularity since 2011.

What I haven't done with any success to keep to any kind of system. I know of people who do. I have always felt it a failing that I don't, a lack of discipline or consistency: a moral failing of some kind. I still feel that way.

The problem is that technology changes. I loved Notational Velocity for its simplicity and speed. I have never found an application I liked better to quickly note something on my computer. But I'm not always at my computer. 

And what if I wanted a screenshot or a table, which Evernote is particularly good for? Livescribe Sky pens were even able to automatically upload to to Evernote, making that ever-elusive promise of the best of both worlds.

Livescribe in Evernote
Livescribe Sky pens would upload directly to Evernote via Wifi (when they actually did so).

What if I just wanted to take notes during a meeting where typing on a computer would either be rude or disruptive? In those cases, I've used a notebook of some kind (Livescribe, Neo smartpen, Field Notes, journal) and found a way to upload pictures of the pages to Evernote.

I suppose if there's any system that has lasted, it has been this hybrid one of writing by hand (when necessary or appropriate) and capturing an image of the notes in Evernote or typing directly into Evernote and pasting screenshots, links and other rich media. 

When I had to update this Drupal 7 site, I used Evernote to track my work, any issues I ran into and any log messages I deemed worth saving.

Keeping track of a Drupal 7 site update
When doing an update of a site, it's all the more important to take notes of process and any hiccups along the way.

On the inestimably valuable freeCodeCamp site, Tom Hombergs wrote a great post about what he'd wished he'd known as a junior developer. I have shared it with the junior developers that report to me and think it chock full of simple advice that is not that easy to follow: keep a block, take notes and have a system, volunteer for things you don't know (among other gems). I can attest to the value of his advice and to the difficulty in following it. 

Nevertheless, system or not: take notes. You probably have a better memory than mine, but even so, your notes will help ingrain the ideas of others better, help you articulate your own thoughts better and be a trail of your own experience that will be worth revisiting.

Notes from 19 Jan 21 CSC 533 with Dave Reed at Creighton University

 

Recording

Scanbot Jan 21, 2019 20.09.pdf

Here are my notes from the Monday class.

I am not sure about how related Java and Javascript are. I always thought it was more of a marketing decision to name it such. However, it might be more than that according to Brendan Eich. And here's an even briefer version compiled by Dr. Alex Rauschmayer.

Following Object-Oriented PHP with Kevin Skoglund on Lynda.com

I've been working in Drupal 8 for a number of months (actually just about a year), but we just had a Drupal Meetup in Omaha, and it inspired me to try to get some PHP under my belt. The reason is this: while I spend a lot of my time with the front-end code, there are times when I'd like to be able to look into a module to see how it works. Heck, I'd even like to be able to write a module.

When I talked to @phenaproxima, who's a maintainer of the Lightning distribution of Drupal 8, about what you need to understand to really work in Drupal 8, he mentioned object-oriented PHP. He talked about a lot of other things, too, which you can see on the Omaha Drupal Meetup recording from November 2018.

Regarding the Skoglund, though, so far, so good.

I'm on Chapter 3, Extend and Override.

It's cool to be able to set different defaults to subclass properties than are in the parent class.

Anyway, I plan to continue it over break.

Then, I want to the Symfony 3 tutorial, getting ever closer to understanding how to actually do Drupal 8 as a developer.