php https://jamesdflynn.com/ en Drupal-Check, Site Factory, and Acquia BLT, OH MY! https://jamesdflynn.com/development/drupal-check-site-factory-and-acquia-blt-oh-my <span class="field field--name-title field--type-string field--label-hidden">Drupal-Check, Site Factory, and Acquia BLT, OH MY!</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">jflynn</span></span> <span class="field field--name-created field--type-created field--label-hidden">Wed, 05/08/2019 - 09:02</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>I was fortunate enough to attend DrupalCon Seattle this year, as well as give a presentation on mental health in tech, but one of the key topics of DrupalCon was Drupal 9 readiness. Dries mentioned it several times in the Driesnote and we even had some contribution efforts specific to Drupal 9 readiness at MidCamp 2019.</p> <p>One thing that stuck out to me as particularly awesome was my friend and fellow MidCamp organizer <a href="https://glamanate.com/">Matt Glaman's</a> <a href="https://github.com/mglaman/drupal-check">drupal-check tool</a> that will check your modules for deprecated code that is <em>NOT</em> ready for Drupal 9 being mentioned in the Driesnote. Additionally just as awesome was another good friend, <a href="https://www.mcdwayne.com/">Dwayne McDaniel</a> getting a shoutout for going through EVERY. SINGLE. CONTRIB. MODULE. and running this tool against it. That's a lot of modules!</p> <p>In case you didn't know, the upgrade path from Drupal 8 to Drupal 9 is supposed to be extremely easy. As someone who had to migrate from 7 to 8, this is welcome news. The TL;DR version is: Once there are backwards compatibility breaks, we're at a new version. What does this mean? It means that code that is marked as deprecated in 8 will <em>NOT</em> be in 9 and you can't upgrade from 8 to 9 if you're using this deprecated code. (I'm looking at you <code>array()</code>)</p> <h2>The Problem(s)</h2> <p>Drupal Check is AMAZING! That's not a problem. The first problem is making sure that your code is ready to be checked by Drupal Check.</p> <h3>Issue 1 (Acquia Cloud Site Factory/Multisite)</h3> <p>We use Acquia Cloud Site Factory extensively at Genuine. This leads to many multi-site installs. Why is this an issue? Well, it's not unusual to have multiple profiles available on Site Factory. Often times, these profiles will be based off another one, but different in theme, look and feel, or functionality. This means that there is a chance that there will be some duplicated functions in the <code>.theme</code> file. Specifically, helper functions that may not fall into the <code>_THEMENAME_function_name()</code> convention and may be missed when you change everything around.</p> <pre> <code>Fatal error: Cannot redeclare _my_poorly_named_function() (previously declared in /var/www/docroot/profiles/custom/profile_1/themes/profile_1_theme/profile_1_theme.theme:150) in /var/www/docroot/profiles/custom/profile_2/themes/profile_2_theme/profile_2_theme.theme on line 168 </code></pre> <p>It happens. Stop looking at me like that.</p> <h3>Solution 1</h3> <p>Well, this is a pretty easy fix, again compliments of Matt Glaman and Will Long AKA Kerasai. You can either prefix the functions OR use namespaces!</p> <pre> <code>&lt;?php namespace my_profile_name; </code></pre> <p>Your <code>.profile</code> files are autoloaded so the namespace will be valid. This prevents the error above.</p> <h3>Issue 2 (Acquia BLT)</h3> <p>This one is a doozy. Acquia BLT or Build and Launch Tool (as of 9.2) has a little command in it that checks for deprecated code, but the dependencies it uses are outdated and cause Drupal Check to fail before it gets anywhere.</p> <p><code>blt tests:php:sniff:deprecated</code><br /><br /> This command depends on the package <code>sensiolabs-de/deprecation-checker</code> which has a dependency on <code>nikic/php-parser:~3.0</code>. Drupal Check requires <code>nikic/php-parser:^4.0</code> due to the way it's built. Trying to run <code>composer require nikic/php-parser:^4.0</code> will make composer yell at you. A lot.</p> <h3>Solution 2</h3> <p>This one gets a bit tricky. There are a few things that need to happen here if you're wanting to reap the benefits of Drupal Check, and trust me, you do.</p> <p>In your base <code>composer.json</code> file there should be a couple of lines that look like this</p> <pre> <code> "merge-plugin": { "require": [ "blt/composer.required.json" ], "include": [ "blt/composer.overrides.json" ], </code></pre> <p>The <code>composer.required.json</code> file is in your <code>blt/</code> folder and is autogenerated by BLT so it's not safe to change. The workaround for this is to copy the file to <code>composer.required-modified.json</code> and update the line below <code>"require": [</code> to <code>blt/composer.required-modified.json</code>. The end result should look like this:</p> <pre> <code>"merge-plugin": { "require": [ "blt/composer.required-modified.json" ], "include": [ "blt/composer.overrides.json" ], </code></pre> <p>Next, you will need to run the command <code>composer remove sensiolabs-de/deprecation-detector</code> This <em>should</em> remove the old package and update <code>nikic/php-parser</code> but if it doesn't, check in your new <code>composer.required-modified.json</code> file, make sure that Deprecation Detector is gone, and add in <code>"nikic/php-parser": "^4.0"</code> at the end of the <code>"require-dev"</code> section. <strong>DON'T FORGET YOUR COMMA!</strong></p> <p>Now you should be able to run Drupal Check without issues, but there's still one thing we need to take care of before saying we're done. That little BLT command from above <code>blt tests:php:sniff:deprecated</code>. If we try running it without the <code>deprecation-detector</code> package then we're going to have a bad time.</p> <p>My workaround for this was to create a replacement command for BLT. This is done by using replace command annotation in a custom class. The BLT docs are <a href="https://blt.readthedocs.io/en/latest/extending-blt/#adding-a-custom-robo-command">here</a> but they are lacking and caused me some headaches, so I've got some docs for you right here.</p> <p>My custom command file lives in <code>blt/src/Hooks/NoDeprecatedCommandHook.php</code>. The name of the file and class needs two things:</p> <ol><li>It can't be the same as the class you're replacing.</li> <li>It needs the word Hook at the end.</li> </ol><p><code>DeprecatedCommandHook.php</code> will not work. <code>NoDeprecatedCommand.php</code> will not work. <code>MyReplacementCommandHook.php</code> will definitely work, so long as your class shares the same name, but let's stick with my own file here.</p> <pre> <code>&lt;?php namespace Acquia\Blt\Custom\Hooks; use Acquia\Blt\Robo\BltTasks; /** * Defines commands in the "tests:php:sniff:deprecated*" namespace. */ class NoDeprecatedCommandHook extends BltTasks { /** * Detects usage of deprecated custom code. * * @hook replace-command tests:php:sniff:deprecated * * @aliases tpsd deprecated */ public function detect() { $this-&gt;say("This command has itself been deprecated. Please use drupal-check for all of your deprecated code needs."); return 0; } } </code></pre> <p>Let's walk through the file a bit</p> <pre> <code>namespace Acquia\Blt\Custom\Hooks; </code></pre> <p>Without this line, it won't work It needs to be in this namespace or you're going to have a bad time.</p> <pre> <code>use Acquia\Blt\Robo\BltTasks; </code></pre> <p>This is optional, but I used it to get the <code>say()</code> method available.</p> <pre> <code>class NoDeprecatedCommandHook extends BltTasks { </code></pre> <p>Our class name. If you're using BltTasks, don't forget to extend it.</p> <pre> <code> /** * Detects usage of deprecated custom code. * * @hook replace-command tests:php:sniff:deprecated * * @aliases tpsd deprecated */ </code></pre> <p>This is where the magic happens. <code>@hook replace-command</code> tells the system to forget about the original command, this one is driving now.</p> <pre> <code> public function detect() { $this-&gt;say("This command has itself been deprecated. Please use drupal-check for all of your deprecated code needs."); return 0; } </code></pre> <p>This is our function that does nothing more than tell us to stop using this function. Clever, right?</p> <p>The end result is a functioning drupal-check and a function that tells its own deprecation.</p> <pre> <code>➜ project git:(master) ✗ blt tests:php:sniff:deprecated This command has itself been deprecated. Please use drupal-check for all of your deprecated code needs. </code></pre> <h2>Conclusion</h2> <p>This is a pretty specific use case and hopefully Acquia BLT will be pushing out an update in the near future that doesn't require us to have to workaround much longer, but this works for us.</p> <p>Please test the hell out of your project after making these updates. BLT should really only be used for local dev and deployment artifacts, but it's still worth noting what does and doesn't happen that might bork up your site.</p> <p><strong><em>Edit:</em></strong> BLT is going to be getting rid of the DeprecatedCommand function that is replaced in this post in the very near future from 5/8/19. That will help all of you out, but it also means that I spent way too much time typing this thing out. See: <a href="https://github.com/acquia/blt/pull/3621">https://github.com/acquia/blt/pull/3621</a></p> </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">Category</div> <div class="field__item"><a href="/development" hreflang="en">Development</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/11" hreflang="en">Drupal</a></div> <div class="field__item"><a href="/taxonomy/term/12" hreflang="en">Drupal Planet</a></div> <div class="field__item"><a href="/taxonomy/term/18" hreflang="en">drupal-check</a></div> <div class="field__item"><a href="/taxonomy/term/3" hreflang="en">php</a></div> </div> </div> <div class="field field--name-field-comments field--type-disqus-comment field--label-visually_hidden"> <div class="field__label visually-hidden">Comments</div> <div class="field__item"><drupal-render-placeholder callback="Drupal\disqus\Element\Disqus::displayDisqusComments" arguments="0=Drupal-Check%2C%20Site%20Factory%2C%20and%20Acquia%20BLT%2C%20%20OH%20MY%21&amp;1=https%3A//jamesdflynn.com/development/drupal-check-site-factory-and-acquia-blt-oh-my&amp;2=node/15" token="3-D57IvABqcCqo49jqsk7WGsVk3ngBE3SsgiGlRSFNI"></drupal-render-placeholder></div> </div> <div class="field field--name-field-header-image-entity field--type-entity-reference field--label-hidden field__item"><article class="media media--type-image media--view-mode-embedded"> <div class="field field--name-image field--type-image field--label-hidden field__item"> <img src="/sites/default/files/drupal-check.jpg" width="1212" height="442" alt="Screen grab of github" loading="lazy" typeof="foaf:Image" /> </div> </article> </div> Wed, 08 May 2019 14:02:56 +0000 jflynn 15 at https://jamesdflynn.com The First One About Web Development https://jamesdflynn.com/development/first-post-web-development <span class="field field--name-title field--type-string field--label-hidden">The First One About Web Development</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">jflynn</span></span> <span class="field field--name-created field--type-created field--label-hidden">Thu, 03/05/2015 - 13:21</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item">## Everyone's Got to Start Somewhere I've had a pretty minimal web presence for quite a while, but I've come to the conclusion that it's definitely time to change that. I've been doing website and web application development for quite a while, but I don't have anything really personal to show for it aside from a few snippets of code and some sites where the client couldn't tell **"development"** from **"design"** and therefore look like a developer designed them. If there is anything that is going to show that I know what I'm doing and that I'm not all talk, it's going to be showing off that I know what I am doing and that I'm not all talk. A tip for budding website developers, or even talented ones who just can't seem to break into it professionally, one of the first questions you will get asked in an interview is *"What's your website or blog or portfolio?"* To which the correct response is not "I don't have one." It took me a very long time to figure that out before I put a project on GitHub and made it available to potential employers to check out and see that I really can code. To me, though, having a project on [GitHub](<a href="http://www.github.com">http://www.github.com</a>) just wasn't enough. That, and the the fact that my main repo was a project that never saw the light of day due to a dispute with a client, pushed me to write a blog that focuses on website development and my journey from mediocre web developer to, hopefully someday, a talented and respected developer. ## Web Development Goals I've been doing html since styling was completely inline and everything just ended up centered on the page or as part of an image map, but what I hadn't been doing for most of that time was improving on skills. Sure I could manage to make a web page in html, but it looked like crap, had no functionality and wasn't worth the bytes it was taking up. I went back to school after a tenure as a paramedic -- a story for another post -- and found out how the world of development had changed around me. I knew that web sites were getting bigger, faster, stronger, different, and and other buzzwords, but what I didn't know was just how much the world had changed around me. Where JavaScript was once a toy that had to be strictly enabled, it was now a cornerstone of front-end web development, also, there was front-end web development. CGI-BIN was replaced by dynamic database driven sites using PHP or Ruby or ASP.net (*blech*). The first few chapters in my website development textbook focused on the basics of CSS and the semantic markup of HTML5. I was behind farther than I like to admit, but then something amazing happened. I started doing it again and what I transitioned into what I was learning and the more I did of it, the more I loved it. Then came the web applications programming class that taught me the basics of PHP, and I loved it. I bought every book I could find, followed every tutorial I came across, and just absorbed as much as I could. Fast forward a few years, and here I am, a web developer in downtown Chicago loving where my life has taken me and where I've ended up so far, but I am ambitious and I want more. I don't want to be the junior developer, nor do I want to just do good enough. I really want to be the best. Although Gladwell says it takes 10,000 hours to become an expert, I think it's much less if the drive is high enough and the passion is there. So since my first ``` <?php echo "Hello World"; ??> ``` to the last jQuery function I wrote, I've enjoyed every challenge that I've come up against and look forward to sharing some of my acquired skills with anyone willing to listen. </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">Category</div> <div class="field__item"><a href="/development" hreflang="en">Development</a></div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/2" hreflang="en">website development</a></div> <div class="field__item"><a href="/taxonomy/term/3" hreflang="en">php</a></div> <div class="field__item"><a href="/taxonomy/term/4" hreflang="en">html</a></div> </div> </div> <div class="field field--name-field-comments field--type-disqus-comment field--label-visually_hidden"> <div class="field__label visually-hidden">Comments</div> <div class="field__item"><drupal-render-placeholder callback="Drupal\disqus\Element\Disqus::displayDisqusComments" arguments="0=The%20First%20One%20About%20Web%20Development&amp;1=https%3A//jamesdflynn.com/development/first-post-web-development&amp;2=node/2" token="Dc9vanzcY4DZ6q7PyPLaVCG37DTrqlEf6qM13vjQYIM"></drupal-render-placeholder></div> </div> Thu, 05 Mar 2015 19:21:28 +0000 jflynn 2 at https://jamesdflynn.com