<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Colin O'Dell's Blog</title>
    <link>https://www.colinodell.com/blog/</link>
    <description>Recent content from Colin O'Dell's personal blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 22 Aug 2025 00:00:00 -0400</lastBuildDate>
    <atom:link href="https://www.colinodell.com/blog/rss.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Resilient Container Builds in CI with Buildkit-Operator</title>
      <link>https://chairnerd.seatgeek.com/resilient-builds-with-buildkit-operator/</link>
      <pubDate>Fri, 22 Aug 2025 00:00:00 -0400</pubDate>
      <guid>https://chairnerd.seatgeek.com/resilient-builds-with-buildkit-operator/</guid>
      <description>Sharing long-lived BuildKit instances across CI jobs cost us up to 4% of our container builds to unpredictable failures and noisy-neighbor contention. We replaced them with ephemeral, fully-isolated builders provisioned per job by a Kubernetes operator we&amp;rsquo;ve open-sourced, and build success now sits at 99.97%.</description>
    </item>
    <item>
      <title>Optimizing GitLab CI Runners on Kubernetes: Caching, Autoscaling, and Beyond</title>
      <link>https://chairnerd.seatgeek.com/ci-runner-optimizations/</link>
      <pubDate>Tue, 21 Jan 2025 00:00:00 -0500</pubDate>
      <guid>https://chairnerd.seatgeek.com/ci-runner-optimizations/</guid>
      <description>Moving our GitLab CI runners onto Kubernetes fixed the wasted capacity and queue bottlenecks, but the real wins came afterwards. Distributed caching in S3 and ECR, HPA-driven autoscaling, dedicated NVMe node pools, and reserved idle capacity took average job queue time from 16 seconds to 2 and cut cost per job by 40%.</description>
    </item>
    <item>
      <title>Building Containers on Kubernetes with Buildkit</title>
      <link>https://chairnerd.seatgeek.com/building-containers-on-kubernetes-with-buildkit/</link>
      <pubDate>Tue, 31 Dec 2024 00:00:00 -0500</pubDate>
      <guid>https://chairnerd.seatgeek.com/building-containers-on-kubernetes-with-buildkit/</guid>
      <description>Every CI job used to get its own EC2 instance and its own Docker daemon, which made &lt;code&gt;docker build&lt;/code&gt; easy and everything around it painful — polluted state between builds, tightly-coupled infrastructure, and multi-arch builds only via slow emulation. Here&amp;rsquo;s how we evaluated Podman, Kaniko, and Buildkit, why Buildkit won, and what it took to make it behave under Kubernetes autoscaling.</description>
    </item>
    <item>
      <title>Introducing Mailroom: An Open-Source Internal Notification Framework</title>
      <link>https://chairnerd.seatgeek.com/mailroom-notification-framework/</link>
      <pubDate>Mon, 09 Dec 2024 00:00:00 -0500</pubDate>
      <guid>https://chairnerd.seatgeek.com/mailroom-notification-framework/</guid>
      <description>Every platform team that wanted to notify engineers about something ended up writing the same Slack bot again — parse the webhook, find the right person, send the message, maintain the deployment forever. Mailroom is the framework we built to stop doing that, so teams write only the handler that turns an event into a useful notification and let it handle routing, preferences, and delivery.</description>
    </item>
    <item>
      <title>DIY &#34;On Air&#34; light automation for Google Meet</title>
      <link>https://www.colinodell.com/blog/2022/diy-on-air-light-automation-google-meet-chrome-extension/</link>
      <pubDate>Sat, 02 Jul 2022 21:57:31 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2022/diy-on-air-light-automation-google-meet-chrome-extension/</guid>
      <description>&lt;p&gt;Like any good project, this one started with a problem: how do I let my wife know I&amp;rsquo;m in a meeting so she doesn&amp;rsquo;t let the dog barge in?  (I work remotely and my office is the only way to get to the backyard.)&lt;/p&gt;&#xA;&lt;p&gt;The solution: &lt;strong&gt;build my own &amp;ldquo;On Air&amp;rdquo; light that turns on/off automatically when I&amp;rsquo;m in a meeting!&lt;/strong&gt; Sure, there are commercially-available products that do exactly this, but where&amp;rsquo;s the fun in buying something when I have the skills and equipment to build my own?  Just how hard could it be? (famous last words)&lt;/p&gt;</description>
    </item>
    <item>
      <title>league/commonmark 2.0.0 Released!</title>
      <link>https://www.colinodell.com/blog/2021/league-commonmark-2-0-0-released/</link>
      <pubDate>Sat, 24 Jul 2021 13:33:06 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2021/league-commonmark-2-0-0-released/</guid>
      <description>&lt;p&gt;After 96 releases, 368 pull requests, and over 48 million downloads, I&amp;rsquo;m pleased to share that the next major version of &lt;strong&gt;&lt;a href=&#34;https://github.com/thephpleague/commonmark/releases/tag/2.0.0&#34;&gt;league/commonmark 2.0.0 stable&lt;/a&gt; is now generally available! 🎉🎉&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;You can install the latest version via Composer:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;composer require league/commonmark:^2.0&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h3 id=&#34;whats-new-in-20&#34;&gt;What&amp;rsquo;s new in 2.0?&lt;/h3&gt;&#xA;&lt;p&gt;There&amp;rsquo;s so much to cover, but here are the key improvements and changes:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Auto-Updating Twitter Banners</title>
      <link>https://www.colinodell.com/blog/2021/autoupdating-twitter-banners/</link>
      <pubDate>Sat, 03 Jul 2021 09:17:44 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2021/autoupdating-twitter-banners/</guid>
      <description>&lt;p&gt;If you &lt;a href=&#34;https://twitter.com/colinodell&#34;&gt;follow me on Twitter&lt;/a&gt; you might have noticed a fancy new banner image:&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://twitter.com/colinodell&#34;&gt;&lt;img class=&#34;img-thumbnail img-responsive&#34; alt=&#34;Auto-generated Twitter banner image&#34; src=&#34;https://www.colinodell.com/media/inline-images/selection-2021-07-03-09-18-29.png&#34; /&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;This is powered by &lt;a href=&#34;https://github.com/erikaheidi/dynacover&#34;&gt;&lt;strong&gt;dynacover&lt;/strong&gt;&lt;/a&gt; - a really nifty tool created by &lt;a href=&#34;https://twitter.com/erikaheidi&#34;&gt;Erika Heidi&lt;/a&gt; that automagically generates and uploads dynamic Twitter banner images!  I&amp;rsquo;m running a slightly modified instance with a custom template that updates every 10 minutes via cron.  Currently, my banner is showing my recent Twitter followers as well as my GitHub sponsors, though I&amp;rsquo;m thinking of some other interesting things I can pull into it in the near future.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Follow me on Polywork</title>
      <link>https://www.colinodell.com/blog/2021/follow-me-on-polywork/</link>
      <pubDate>Fri, 02 Jul 2021 17:37:17 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2021/follow-me-on-polywork/</guid>
      <description>&lt;p&gt;If you &lt;a href=&#34;https://twitter.com/colinodell&#34;&gt;follow me on Twitter&lt;/a&gt; you&amp;rsquo;ve probably seen that I&amp;rsquo;ve recently joined &lt;a href=&#34;https://www.polywork.com/&#34;&gt;Polywork&lt;/a&gt; - a new social network unlike any others.&lt;/p&gt;&#xA;&lt;p&gt;Polywork has a unique concept - instead of focusing on just your personal or professional life, your profile focuses on highlighting you as a multi-faceted individual. There&amp;rsquo;s no commenting, no competing for likes, no recruiters, no politics - just you and your story:&lt;/p&gt;</description>
    </item>
    <item>
      <title>league/commonmark 2.0.0-beta2 now available for testing</title>
      <link>https://www.colinodell.com/blog/2021/leaguecommonmark-200beta2-now-available-testing/</link>
      <pubDate>Sun, 27 Jun 2021 12:30:54 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2021/leaguecommonmark-200beta2-now-available-testing/</guid>
      <description>&lt;p&gt;With the 2.0.0 stable release of &lt;a href=&#34;https://github.com/thephpleague/commonmark&#34;&gt;&lt;code&gt;league/commonmark&lt;/code&gt;&lt;/a&gt; scheduled for &lt;a href=&#34;https://github.com/thephpleague/commonmark/milestone/15&#34;&gt;next month&lt;/a&gt;, &lt;strong&gt;I&amp;rsquo;m pleased to share that &lt;a href=&#34;https://github.com/thephpleague/commonmark/releases&#34;&gt;the first 2.0 beta releases are now available&lt;/a&gt;!&lt;/strong&gt;  Current users of this library are highly encouraged to test this new branch and provide feedback.&lt;/p&gt;&#xA;&lt;p&gt;You can install the beta release via Composer:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;composer require league/commonmark:^2.0@beta&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h3 id=&#34;whats-new-in-20&#34;&gt;What&amp;rsquo;s new in 2.0?&lt;/h3&gt;&#xA;&lt;p&gt;There&amp;rsquo;s so much to cover - I&amp;rsquo;ll likely need to write a separate blog post about that.  But here are the key improvements and changes:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fixing Broken Squad Chat Audio Issues in Battlefield V</title>
      <link>https://www.colinodell.com/blog/2021/fixing-broken-squad-chat-audio-issues-battlefield-v/</link>
      <pubDate>Sun, 13 Jun 2021 19:27:15 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2021/fixing-broken-squad-chat-audio-issues-battlefield-v/</guid>
      <description>Having issues hearing your squad? There&amp;rsquo;s a strong chance your &lt;strong&gt;default communications device&lt;/strong&gt; is not set to the right device in Windows&amp;rsquo; audio settings. This guide explains how to fix that.</description>
    </item>
    <item>
      <title>league/commonmark 1.6.0 Released!</title>
      <link>https://www.colinodell.com/blog/2021/leaguecommonmark-160-released/</link>
      <pubDate>Sat, 01 May 2021 15:24:28 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2021/leaguecommonmark-160-released/</guid>
      <description>&lt;p&gt;&lt;strong&gt;I&amp;rsquo;m excited to share that &lt;a href=&#34;https://github.com/thephpleague/commonmark/releases/tag/1.6.0&#34;&gt;version 1.6.0 of league/commonmark has been released&lt;/a&gt;!&lt;/strong&gt;  This will be the last minor release of the 1.x branch - all efforts will now be focused on wrapping up development of 2.0.0!&lt;/p&gt;&#xA;&lt;p&gt;Please see &lt;a href=&#34;https://commonmark.thephpleague.com/1.6/upgrading/&#34;&gt;https://commonmark.thephpleague.com/1.6/upgrading/&lt;/a&gt; for important information about this release and the upcoming 2.0.0 version.&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;d like to help fund development of this library, please check out &lt;a href=&#34;https://www.colinodell.com/sponsor&#34;&gt;my Sponsor page&lt;/a&gt;.  We also have some &lt;a href=&#34;https://www.moderngeekware.com/search?q=markdown&#34;&gt;Markdown t-shirts and mugs&lt;/a&gt; on &lt;a href=&#34;https://www.moderngeekware.com/&#34;&gt;ModernGeekware.com&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>PHP 8.1 is Getting Enumerations!</title>
      <link>https://www.colinodell.com/blog/2021/php-81-getting-enumerations/</link>
      <pubDate>Wed, 17 Feb 2021 15:08:30 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2021/php-81-getting-enumerations/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;https://wiki.php.net/rfc/enumerations&#34;&gt;PHP RFC for enumerations&lt;/a&gt; just passed a 44-7 vote to be accepted as a new feature in the upcoming PHP 8.1 release!&lt;/p&gt;&#xA;&lt;p&gt;Enumerations, also known as &amp;ldquo;enums&amp;rdquo;, are a special data type that can only contain specific, predefined (or &amp;ldquo;enumerated&amp;rdquo;) values.  They behave somewhat similar to constants, in that their names can be referenced in code, but they allow for stronger typing.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introducing ModernGeekware.com - Tees, Mugs, and more for Developers and Geeks</title>
      <link>https://www.colinodell.com/blog/2021/introducing-moderngeekwarecom-tees-mugs-and-more-developers-and-geeks/</link>
      <pubDate>Sun, 31 Jan 2021 14:38:46 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2021/introducing-moderngeekwarecom-tees-mugs-and-more-developers-and-geeks/</guid>
      <description>&lt;p&gt;As a developer, I LOVE my geeky t-shirts and mugs, but it&#39;s hard to find quality products with designs I like.  I&#39;ve therefore been hard at work these last few weekends putting together my new project: &lt;a href=&#34;https://www.moderngeekware.com&#34;&gt;www.moderngeekware.com&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p class=&#34;text-center&#34;&gt;&lt;a href=&#34;https://www.moderngeekware.com&#34;&gt;&lt;img alt=&#34;&#34; class=&#34;img-thumbnail&#34; src=&#34;https://www.colinodell.com/media/2021-01/screenshot-2021-01-31-130328.png&#34; style=&#34;width: 85%&#34; /&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;I&#39;m excited to share that &lt;a href=&#34;https://www.moderngeekware.com/pages/promotions&#34;&gt;ModernGeekware.com&lt;/a&gt; just launched this Sunday!&lt;/strong&gt;  There are currently 28 products in the store and I hope to add more in the coming days and weeks.  Everything here was designed by me mostly because they&#39;re all things I&#39;d want to buy and wear myself.  (In fact, I&#39;m my own first customer!)  I figured perhaps others might like them too, thus this store was born.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How To Install PHP 8.0</title>
      <link>https://www.colinodell.com/blog/2020/how-install-php-80/</link>
      <pubDate>Sat, 28 Nov 2020 08:19:05 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2020/how-install-php-80/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://www.php.net/releases/8.0/en.php&#34;&gt;PHP 8.0 has just been released&lt;/a&gt;! This new major version adds several significant features and improvements to the language like &lt;a href=&#34;https://www.php.net/releases/8.0/en.php#attributes&#34;&gt;attributes&lt;/a&gt;, &lt;a href=&#34;https://www.php.net/manual/en/control-structures.match.php&#34;&gt;match expressions&lt;/a&gt;, &lt;a href=&#34;https://wiki.php.net/rfc/jit&#34;&gt;Just-In-Time compilation (JIT)&lt;/a&gt;, and &lt;a href=&#34;https://secure.php.net/manual/en/migration80.php&#34;&gt;much more&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a brief guide on how to install PHP 8.0 on Linux, Windows, and Mac OS X:&lt;/p&gt;&#xA;&lt;h2 id=&#34;ubuntu&#34;&gt;Ubuntu&lt;/h2&gt;&#xA;&lt;p&gt;PHP 8.0 and commonly-used extensions can be installed by adding &lt;a href=&#34;https://launchpad.net/~ondrej/+archive/ubuntu/php&#34;&gt;Ondřej Surý&amp;rsquo;s PPA&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Both Composer 1 and Composer 2</title>
      <link>https://www.colinodell.com/blog/2020/using-both-composer-1-and-composer-2/</link>
      <pubDate>Mon, 26 Oct 2020 10:21:26 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2020/using-both-composer-1-and-composer-2/</guid>
      <description>Although Composer 2 is mostly backward-compatible with projects using Composer 1, some users may need to continue using Composer 1 due to plugin incompatibilities. This article shows how to install both versions side-by-side.</description>
    </item>
    <item>
      <title>Testing PHP 8 With Docker</title>
      <link>https://www.colinodell.com/blog/2020/testing-php-8-with-docker/</link>
      <pubDate>Thu, 06 Aug 2020 17:03:08 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2020/testing-php-8-with-docker/</guid>
      <description>The first beta release of PHP 8 is here and you can start testing it today with Docker.</description>
    </item>
    <item>
      <title>New Release: league/commonmark 1.5.0</title>
      <link>https://www.colinodell.com/blog/2020/new-release-leaguecommonmark-150/</link>
      <pubDate>Sun, 21 Jun 2020 17:28:49 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2020/new-release-leaguecommonmark-150/</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/thephpleague/commonmark/releases/tag/1.5.0&#34;&gt;Version 1.5.0 of the league/commonmark Markdown library&lt;/a&gt; has just been released!&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;This will likely be the last minor release of &lt;code&gt;1.x&lt;/code&gt; as we focus efforts on &lt;a href=&#34;https://github.com/thephpleague/commonmark/milestone/15&#34;&gt;developing 2.0&lt;/a&gt;.  This post breaks down some of the new features and changes you should know about 1.5.0.&lt;/p&gt;&#xA;&lt;h2 id=&#34;three-new-extensions&#34;&gt;Three New Extensions&lt;/h2&gt;&#xA;&lt;p&gt;The popular Markdown library now includes &lt;strong&gt;three more extensions&lt;/strong&gt; within core thanks for to the community:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Celebrating 10 Million Downloads of league/commonmark</title>
      <link>https://www.colinodell.com/blog/2020/celebrating-10-million-downloads-leaguecommonmark/</link>
      <pubDate>Sun, 24 May 2020 10:33:00 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2020/celebrating-10-million-downloads-leaguecommonmark/</guid>
      <description>After 2,086 days, 1,632 commits, and 75 releases I&amp;rsquo;m pleased to share that league/commonmark has been downloaded over 10 million times!  🎉🎉🎉</description>
    </item>
    <item>
      <title>Zero-Configuration SSL CA root bundles in Doctrine DBAL with Symfony</title>
      <link>https://www.colinodell.com/blog/2020/zeroconfiguration-ssl-ca-root-bundles-doctrine-dbal-symfony/</link>
      <pubDate>Fri, 28 Feb 2020 11:00:14 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2020/zeroconfiguration-ssl-ca-root-bundles-doctrine-dbal-symfony/</guid>
      <description>&lt;p&gt;Today I found myself deploying a Symfony project to an Azure environment that requires SSL connections to MySQL.  I figured this out the hard way when I started getting these errors:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;In AbstractMySQLDriver.php line 106:&#xA;                                                                                                                             &#xA;  An exception occurred in driver: SQLSTATE[HY000] [9002] SSL connection is required. Please specify SSL options and retry.  &#xA;                                                                                                                             &#xA;&#xA;In PDOConnection.php line 31:&#xA;                                                                                            &#xA;  SQLSTATE[HY000] [9002] SSL connection is required. Please specify SSL options and retry.  &#xA;                                                                                            &#xA;&#xA;In PDOConnection.php line 27:&#xA;                                                                                            &#xA;  SQLSTATE[HY000] [9002] SSL connection is required. Please specify SSL options and retry.  &#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Although &lt;a href=&#34;https://stackoverflow.com/questions/29902549/symfony-how-to-set-ssl-parameters-in-doctrine-dbal-configuration-yaml/40142725&#34;&gt;StackOverflow had some potential solutions&lt;/a&gt;, they were all a bit messy.  At a minimum, each solution required you to somehow know and provide the path to the system&amp;rsquo;s CA root bundle in your project - either by hard-coding it (bad idea - it can be different per OS) or by making it a configurable parameter (requires developers to know where that file lives).&lt;/p&gt;</description>
    </item>
    <item>
      <title>league/commonmark 1.3.0 Adds Full GFM Support!</title>
      <link>https://www.colinodell.com/blog/2020/league-commonmark-130-adds-full-gfm-support/</link>
      <pubDate>Sat, 08 Feb 2020 18:44:19 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2020/league-commonmark-130-adds-full-gfm-support/</guid>
      <description>With the recent release of version 1.3.0, league/commonmark now offers full support for Github-Flavored Markdown!</description>
    </item>
    <item>
      <title>How To Install PHP 7.4</title>
      <link>https://www.colinodell.com/blog/2019/how-to-install-php-74/</link>
      <pubDate>Thu, 28 Nov 2019 08:00:16 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2019/how-to-install-php-74/</guid>
      <description>PHP 7.4 has just been released with several new features! Learn how to install it on Linux, Windows, Mac OS X, and more.</description>
    </item>
    <item>
      <title>Is &#34;Social Delegation&#34; The Next Factor in MFA?</title>
      <link>https://www.colinodell.com/blog/2019/is-social-delegation-next-factor-mfa/</link>
      <pubDate>Tue, 22 Oct 2019 08:46:02 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2019/is-social-delegation-next-factor-mfa/</guid>
      <description>Is &amp;ldquo;Social Delegation&amp;rdquo; (someone the user trusts) the next factor in MFA?</description>
    </item>
    <item>
      <title>league/commonmark 1.0.0 has been released!</title>
      <link>https://www.colinodell.com/blog/2019/leaguecommonmark-100-has-been-released/</link>
      <pubDate>Sat, 29 Jun 2019 07:24:46 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2019/leaguecommonmark-100-has-been-released/</guid>
      <description>&lt;p&gt;&lt;strong&gt;After 5 years of development, 3,000,000 downloads, and &lt;a href=&#34;https://github.com/thephpleague/commonmark/releases&#34;&gt;58 releases&lt;/a&gt;, I&amp;rsquo;m extremely pleased to announce that &lt;a href=&#34;https://commonmark.thephpleague.com/&#34;&gt;league/commonmark&lt;/a&gt; version 1.0.0 has been released!&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-leaguecommonmark&#34;&gt;What is &lt;code&gt;league/commonmark&lt;/code&gt;?&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;league/commonmark&lt;/code&gt; is a highly-extensible PHP Markdown parser which is fully compliant with the &lt;a href=&#34;https://spec.commonmark.org/0.29/#introduction&#34;&gt;CommonMark spec&lt;/a&gt;.  It avoids some of the issues and funky edge cases that other Markdown parsers have while also allowing you to implement your own custom Markdown syntax to best suit your needs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>league/commonmark 1.0.0 beta now available</title>
      <link>https://www.colinodell.com/blog/2019/leaguecommonmark-100-beta-now-available/</link>
      <pubDate>Tue, 28 May 2019 10:04:22 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2019/leaguecommonmark-100-beta-now-available/</guid>
      <description>&lt;p&gt;This weekend I&amp;rsquo;ve tagged &lt;a href=&#34;https://github.com/thephpleague/commonmark/releases/&#34;&gt;the first pre-releases of the 1.x branch&lt;/a&gt;!  I strongly encourage everyone to test their applications and extensions against this beta and provide any feedback.  (Helpful information can be found in &lt;a href=&#34;https://commonmark.thephpleague.com/1.0/upgrading/&#34;&gt;the upgrading guide&lt;/a&gt;.)  Unless there are any major issues we&amp;rsquo;ll plan on releasing a stable 1.0.0 version in the coming weeks!&lt;/p&gt;&#xA;&lt;p&gt;And if you&amp;rsquo;d like to support this project, please consider sponsoring development via Patreon: &lt;a href=&#34;https://www.patreon.com/colinodell&#34;&gt;https://www.patreon.com/colinodell&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>CVE-2018-20583 - XSS Vulnerability in league/commonmark</title>
      <link>https://www.colinodell.com/blog/2018/cve201820583-xss-vulnerability-leaguecommonmark/</link>
      <pubDate>Sun, 30 Dec 2018 06:28:03 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2018/cve201820583-xss-vulnerability-leaguecommonmark/</guid>
      <description>&lt;p&gt;A cross-site scripting (XSS) vulnerability was found in the &lt;a href=&#34;https://commonmark.thephpleague.com/&#34;&gt;PHP League&amp;rsquo;s CommonMark library&lt;/a&gt; (&lt;code&gt;league/commonmark&lt;/code&gt;) versions 0.15.6 through 0.18.x before 0.18.1. It allows remote attackers to insert unsafe URLs into &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags (even if &lt;code&gt;allow_unsafe_links&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;) by adding an encoded newline character in the middle (e.g., writing &lt;code&gt;javascript&lt;/code&gt; as &lt;code&gt;javascri%0Apt&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/thephpleague/commonmark/releases/tag/0.18.1&#34;&gt;Version 0.18.1&lt;/a&gt; has been released to fix this issue.  All users are strongly encouraged to upgrade to this version.&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>How To Install PHP 7.3</title>
      <link>https://www.colinodell.com/blog/2018/how-install-php-73/</link>
      <pubDate>Sat, 08 Dec 2018 08:07:22 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2018/how-install-php-73/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://secure.php.net/releases/7_3_0.php&#34;&gt;PHP 7.3 has been released&lt;/a&gt;, bringing some great new features to the language such as &lt;a href=&#34;https://wiki.php.net/rfc/trailing-comma-function-calls&#34;&gt;trailing commas in function calls&lt;/a&gt;, &lt;a href=&#34;https://wiki.php.net/rfc/json_throw_on_error&#34;&gt;throwing errors when JSON parsing fails&lt;/a&gt;, &lt;a href=&#34;https://wiki.php.net/rfc/array_key_first_last&#34;&gt;&lt;code&gt;array_key_first()&lt;/code&gt; / &lt;code&gt;array_key_last()&lt;/code&gt; functions&lt;/a&gt;, and &lt;a href=&#34;https://secure.php.net/manual/en/migration73.php&#34;&gt;much more&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a brief guide on how to install PHP 7.3 on Linux, Windows, and OS X:&lt;/p&gt;&#xA;&lt;h2 id=&#34;ubuntu&#34;&gt;Ubuntu&lt;/h2&gt;&#xA;&lt;p&gt;PHP 7.3 and commonly-used extensions can be installed by adding &lt;a href=&#34;https://launchpad.net/~ondrej/+archive/ubuntu/php&#34;&gt;Ondřej Surý&amp;rsquo;s PPA&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ultimate Programmer Super Stack Bundle</title>
      <link>https://www.colinodell.com/blog/2018/ultimate-programmer-super-stack-bundle/</link>
      <pubDate>Tue, 06 Nov 2018 10:38:49 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2018/ultimate-programmer-super-stack-bundle/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m pleased to share that my PHP 7 Upgrade Guide ebook has been featured in the &lt;a href=&#34;https://colinodell--infostack.thrivecart.com/up/?ref=web&#34;&gt;Ultimate Programmer Super Stack bundle&lt;/a&gt;!  This is a hand-curated collection of 25+ premium ecourses, bestselling ebooks, and bonus resources that will help new programmers:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Learn a wide range of today’s most popular (and lucrative) languages and frameworks, including everything from Python, JavaScript, and Ruby, to HTML, CSS, and Kotlin, and more…&lt;/li&gt;&#xA;&lt;li&gt;Discover how to build APIs, websites, and iOS and Android applications from scratch&lt;/li&gt;&#xA;&lt;li&gt;Uncover the &amp;lsquo;Business of Software&amp;rsquo; (how computer programs work, how computer programmers think, and how to start your very own computer programming business)&lt;/li&gt;&#xA;&lt;li&gt;Master the soft skills you need to become &amp;lsquo;Coder Complete&amp;rsquo; (this stuff will have a huge impact on your career, believe me)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;And much more.&lt;/p&gt;</description>
    </item>
    <item>
      <title>September Project Updates</title>
      <link>https://www.colinodell.com/blog/2018/september-project-updates/</link>
      <pubDate>Thu, 20 Sep 2018 11:31:40 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2018/september-project-updates/</guid>
      <description>This month I released updates for a few of my open-source projects including league/commonmark, league/html-to-markdown, and colinodell/json5.</description>
    </item>
    <item>
      <title>Avoid Unsupported Symfony Component Versions With This Composer Metapackage</title>
      <link>https://www.colinodell.com/blog/2018/avoid-unsupported-symfony-component-versions-composer-metapackage/</link>
      <pubDate>Mon, 10 Sep 2018 12:30:37 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2018/avoid-unsupported-symfony-component-versions-composer-metapackage/</guid>
      <description>Prevent Composer from updating your Symfony components to unsupported versions with the &lt;code&gt;colinodell/symfony-lts-or-current&lt;/code&gt; metapackage.</description>
    </item>
    <item>
      <title>Automatically Switch PHP Version on cd</title>
      <link>https://www.colinodell.com/blog/2018/automatically-switch-php-version-cd/</link>
      <pubDate>Wed, 08 Aug 2018 13:55:18 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2018/automatically-switch-php-version-cd/</guid>
      <description>&lt;p&gt;After using phpbrew to manage my local PHP versions for a while, I got tired of re-compiling PHP after every release and decided to install multiple PHP versions side-by-side with &lt;a href=&#34;https://launchpad.net/~ondrej/+archive/ubuntu/php&#34;&gt;Ondřej Surý&amp;rsquo;s PPA&lt;/a&gt;.  One of the features I missed from &lt;code&gt;phpbrew&lt;/code&gt; was the ability to run a command like &lt;code&gt;phpbrew use php-7.2.8&lt;/code&gt; to automatically change the &lt;code&gt;php&lt;/code&gt; command to that version, so I ended up implementing this feature myself using symlinks and shell aliases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Four Useful Git Aliases</title>
      <link>https://www.colinodell.com/blog/2018/four-useful-git-aliases/</link>
      <pubDate>Mon, 19 Mar 2018 10:46:00 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2018/four-useful-git-aliases/</guid>
      <description>&lt;p&gt;As you may know, Git is not a single application, but rather a toolkit containing many small programs and scripts that can manipulate the repository. This makes it trivial to chain those components into more-powerful, custom commands which can be defined as &lt;a href=&#34;https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases&#34;&gt;git aliases&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here are some of the more-useful aliases I use on a daily basis:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fix PhpStorm Not Focusing When Breakpoints Hit (Ubuntu 17.10 / Gnome Shell 3)</title>
      <link>https://www.colinodell.com/blog/2018/fix-phpstorm-not-focusing-when-breakpoints-hit-ubuntu-1710-gnome-shell-3/</link>
      <pubDate>Fri, 26 Jan 2018 09:14:33 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2018/fix-phpstorm-not-focusing-when-breakpoints-hit-ubuntu-1710-gnome-shell-3/</guid>
      <description>&lt;p&gt;I recently upgraded my system from Ubuntu 16.04 with Unity to Ubuntu 17.10 with Gnome Shell 3. One of the &amp;ldquo;features&amp;rdquo; I found annoying was that my IDE PhpStorm was not popping to the front and receiving focus whenever breakpoints were hit.  I eventually figured out a solution and wanted to document it in case others were also searching for a solution.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optimizing colinodell/json5 with Blackfire</title>
      <link>https://www.colinodell.com/blog/2018/optimizing-colinodelljson5-blackfire/</link>
      <pubDate>Sun, 14 Jan 2018 09:43:55 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2018/optimizing-colinodelljson5-blackfire/</guid>
      <description>&lt;p&gt;Back in November I released &lt;a href=&#34;https://www.colinodell.com/blog/2017/introducing-colinodelljson5-utf8-compatible-json5-parser-php&#34;&gt;colinodell/json5 - a JSON5 parser for PHP&lt;/a&gt;.  It&amp;rsquo;s essentially a drop-in replacement for PHP&amp;rsquo;s &lt;code&gt;json_decode()&lt;/code&gt; function, but it allows things like comments, trailing commas, and more.&lt;/p&gt;&#xA;&lt;p&gt;Fast forward to this weekend when I received &lt;a href=&#34;https://github.com/colinodell/json5/issues/1&#34;&gt;the following bug report&lt;/a&gt; from a user named Antonio:&lt;/p&gt;&#xA;&lt;img class=&#34;img-responsive&#34; alt=&#34;Issue reporting poor performance&#34; src=&#34;https://www.colinodell.com/media/inline-images/selection-999-353.png&#34; /&gt;&#xA;&lt;p&gt;&lt;strong&gt;Yikes!&lt;/strong&gt; I always knew that a PHP-based implementation would be slower than PHP&amp;rsquo;s native C implementation, but execution time measured in &lt;strong&gt;minutes&lt;/strong&gt; was &lt;strong&gt;completely unacceptable!&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>league/commonmark 0.17</title>
      <link>https://www.colinodell.com/blog/2017/leaguecommonmark-017/</link>
      <pubDate>Sat, 30 Dec 2017 17:42:47 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2017/leaguecommonmark-017/</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://commonmark.thephpleague.com&#34;&gt;league/commonmark&lt;/a&gt; is wrapping up 2017 with the release of &lt;a href=&#34;https://github.com/thephpleague/commonmark/releases/tag/0.17.0&#34;&gt;version 0.17&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Changes include:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Minimum PHP version bumped to 5.6&lt;/li&gt;&#xA;&lt;li&gt;New &amp;ldquo;max_nesting_level&amp;rdquo; setting&lt;/li&gt;&#xA;&lt;li&gt;A few performance optimizations&lt;/li&gt;&#xA;&lt;li&gt;Clean up deprecations and not-so-great code&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;For more info, check out:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Changelog:&lt;/strong&gt; &lt;a href=&#34;https://github.com/thephpleague/commonmark/releases/tag/0.17.0&#34;&gt;https://github.com/thephpleague/commonmark/releases/tag/0.17.0&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href=&#34;https://commonmark.thephpleague.com&#34;&gt;https://commonmark.thephpleague.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Upgrade Notes:&lt;/strong&gt; &lt;a href=&#34;https://github.com/thephpleague/commonmark/blob/0.17.0/UPGRADE.md#0170&#34;&gt;https://github.com/thephpleague/commonmark/blob/0.17.0/UPGRADE.md#0170&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Installing PHP 7.2</title>
      <link>https://www.colinodell.com/blog/2017/installing-php-72/</link>
      <pubDate>Thu, 30 Nov 2017 08:38:58 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2017/installing-php-72/</guid>
      <description>&lt;aside&gt;&lt;p class=&#34;alert alert-info&#34;&gt;Psst - PHP 7.4 is now available! Learn &lt;a href=&#34;https://www.colinodell.com/blog/2019/how-to-install-php-74&#34;&gt;how to upgrade to PHP 7.4 here&lt;/a&gt;!&lt;/p&gt;&lt;/aside&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://secure.php.net/releases/7_2_0.php&#34;&gt;PHP 7.2 has been released&lt;/a&gt;, bringing some great new features and security enhancements to the language such as &lt;a href=&#34;https://wiki.php.net/rfc/object-typehint&#34;&gt;&lt;code&gt;object&lt;/code&gt; type hints&lt;/a&gt;, saner &lt;a href=&#34;https://wiki.php.net/rfc/counting_non_countables&#34;&gt;&lt;code&gt;count()&lt;/code&gt; behavior&lt;/a&gt;, and &lt;a href=&#34;https://secure.php.net/manual/en/migration72.php&#34;&gt;much more&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here&#39;s a brief guide on how to install PHP 7.2 on several different operating systems:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Magento Security Patch SUPEE-10415 Now Available</title>
      <link>https://www.colinodell.com/blog/2017/magento-security-patch-supee10415-now-available/</link>
      <pubDate>Tue, 28 Nov 2017 13:00:06 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2017/magento-security-patch-supee10415-now-available/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://magento.com/security/patches/supee-10415&#34;&gt;Magento has just released the SUPEE-10415 security patch&lt;/a&gt; for the following versions:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Magento Commerce 1.9.0.0-1.14.3.7 (formerly known as Enterprise Edition)&lt;/li&gt;&#xA;&lt;li&gt;Magento Open Source 1.5.0.0-1.9.3.7 (formerly known as Community Edition)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The patch contains fixed for several security vulnerabilities including cross-site request forgery (CSRF), Denial-of-Service (DoS), and authenticated Admin user remote code execution (RCE).&lt;/p&gt;&#xA;&lt;p&gt;You can learn more about the patch and download it here: &lt;a href=&#34;https://magento.com/security/patches/supee-10415&#34;&gt;https://magento.com/security/patches/supee-10415&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introducing colinodell/json5: a UTF-8 compatible JSON5 parser for PHP</title>
      <link>https://www.colinodell.com/blog/2017/introducing-colinodelljson5-utf8-compatible-json5-parser-php/</link>
      <pubDate>Mon, 13 Nov 2017 07:33:35 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2017/introducing-colinodelljson5-utf8-compatible-json5-parser-php/</guid>
      <description>&lt;p&gt;This weekend I released an &lt;a href=&#34;https://github.com/colinodell/json5#json5-for-php---json-for-humans&#34;&gt;open-source JSON5 parser for PHP&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/colinodell/json5&#34;&gt;&lt;img alt=&#34;JSON5 for PHP&#34; src=&#34;https://www.colinodell.com/media/inline-images/selection-999-100.png&#34; class=&#34;img-responsive&#34; /&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://json5.org/&#34;&gt;JSON5&lt;/a&gt; is a JS-compatible extension to JSON which allows comments, trailing commas, single-quoted strings, and more:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-js&#34;&gt;{&#xA;    foo: &#39;bar&#39;,&#xA;    while: true,&#xA;&#xA;    this: &#39;is a \&#xA;multi-line string&#39;,&#xA;&#xA;    // this is an inline comment&#xA;    here: &#39;is another&#39;, // inline comment&#xA;&#xA;    /* this is a block comment&#xA;       that continues on another line */&#xA;&#xA;    hex: 0xDEADbeef,&#xA;    half: .5,&#xA;    delta: +10,&#xA;    to: Infinity,   // and beyond!&#xA;&#xA;    finally: &#39;a trailing comma&#39;,&#xA;    oh: [&#xA;        &amp;quot;we shouldn&#39;t forget&amp;quot;,&#xA;        &#39;arrays can have&#39;,&#xA;        &#39;trailing commas too&#39;,&#xA;    ],&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/colinodell/json5&#34;&gt;This PHP implementation&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Auto-casting numeric strings to int/float</title>
      <link>https://www.colinodell.com/blog/2017/autocasting-numeric-strings-intfloat/</link>
      <pubDate>Fri, 10 Nov 2017 10:05:00 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2017/autocasting-numeric-strings-intfloat/</guid>
      <description>&lt;p&gt;I recently came across this really helpful PHP trick:&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;You can cast a numeric string to either &lt;code&gt;int&lt;/code&gt; or &lt;code&gt;float&lt;/code&gt;, depending on its contents, by simply adding &lt;code&gt;0&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;var_dump(&amp;quot;1&amp;quot; + 0);&#xA;// int(1)&#xA;&#xA;var_dump(&amp;quot;1.&amp;quot; + 0);&#xA;// float(1)&#xA;&#xA;var_dump(&amp;quot;1.0&amp;quot; + 0);&#xA;// float(1)&#xA;&#xA;var_dump(&amp;quot;1.5&amp;quot; + 0);&#xA;// float(1.5)&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;That&amp;rsquo;s much cleaner than trying to make a conditional cast yourself:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Home Assistant with Updated Z-Wave Device Files</title>
      <link>https://www.colinodell.com/blog/2017/home-assistant-updated-zwave-device-files/</link>
      <pubDate>Thu, 12 Oct 2017 15:43:02 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/home-assistant-updated-zwave-device-files/</guid>
      <description>&lt;p&gt;Several months ago I blogged about &lt;a href=&#34;https://www.colinodell.com/blog/2017/compiling-openzwave-home-assistant-045-docker&#34;&gt;compiling open-zwave for Home Assistant 0.45 on Docker&lt;/a&gt;.  There were two reasons I did this:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;I had a Linear Z-Wave Garage Door opener - this feature was only available in the development branch of openzwave.&lt;/li&gt;&#xA;&lt;li&gt;I wanted up-to-date device configurations for newer Z-Wave devices.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Unfortunately, the development branch was less stable than I liked and the opener never worked quite right. So #1 was no longer a reason to compile the library myself.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Extracting PEM and Private Key from PFX SSL Certificate</title>
      <link>https://www.colinodell.com/blog/2017/extracting-pem-and-private-key-pfx-ssl-certificate/</link>
      <pubDate>Fri, 15 Sep 2017 10:19:33 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/extracting-pem-and-private-key-pfx-ssl-certificate/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://en.wikipedia.org/wiki/PKCS_12&#34;&gt;PKCS#12 archives&lt;/a&gt; (commonly known as &lt;code&gt;.pfx&lt;/code&gt; files) usually contain both a certificate and its private key, sometimes with password protection.  In order to use these with a server like nginx or Apache, we need to extract these objects and convert them using openssl.&lt;/p&gt;&#xA;&lt;p&gt;(The commands below assume your file is named &lt;code&gt;certificate.pfx&lt;/code&gt;.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;extracting-the-private-key&#34;&gt;Extracting the private key&lt;/h2&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;openssl pkcs12 -in certificate.pfx -out private.key -nocerts -nodes&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;extracting-the-pem-certificate&#34;&gt;Extracting the PEM certificate&lt;/h2&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;openssl pkcs12 -in certificate.pfx -out cert.pem -clcerts -nokeys&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;extracting-intermediate-certificates&#34;&gt;Extracting intermediate certificates&lt;/h2&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;openssl pkcs12 -in certificate.pfx -out ca.pem -clcerts -nokeys&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Alternatively, you could use a tool like &lt;a href=&#34;https://whatsmychaincert.com&#34;&gt;https://whatsmychaincert.com&lt;/a&gt; to generate this based on your public certificate.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Generating IDE Stubs for IonCube-Encoded Classes</title>
      <link>https://www.colinodell.com/blog/2017/generating-ide-stubs-ioncube-encoded-classes/</link>
      <pubDate>Fri, 25 Aug 2017 12:43:48 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/generating-ide-stubs-ioncube-encoded-classes/</guid>
      <description>I recently inherited a legacy PHP project built on a closed-source framework where all the core classes were encrypted with IonCube.  Not knowing what classes and methods exist makes it extremely difficult to use that functionality.  In order to make life easier, I set out to create a &lt;code&gt;stubs.php&lt;/code&gt; file listing all of those &amp;ldquo;hidden&amp;rdquo; classes and methods.</description>
    </item>
    <item>
      <title>The Journey to 1,000,000 Downloads</title>
      <link>https://www.colinodell.com/blog/2017/league-commonmark-1-million-downloads/</link>
      <pubDate>Sat, 05 Aug 2017 20:23:52 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/league-commonmark-1-million-downloads/</guid>
      <description>&lt;p&gt;This morning I came into work to find my &lt;a href=&#34;https://www.hackster.io/colinodell/packagist-download-counter-e1a263&#34;&gt;Packagist download counter&lt;/a&gt; had rolled over: &lt;a href=&#34;http://commonmark.thephpleague.com/&#34;&gt;league/commonmark&lt;/a&gt; now has &lt;strong&gt;over 1,000,000 downloads!&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;To celebrate this milestone I thought I&amp;rsquo;d share the story of how this package came about, how it&amp;rsquo;s grown, and how I couldn&amp;rsquo;t have reached this milestone without the PHP community&amp;rsquo;s help.&lt;/p&gt;&#xA;&lt;h2 id=&#34;getting-started&#34;&gt;Getting Started&lt;/h2&gt;&#xA;&lt;p&gt;I was browsing Reddit on September 3rd, 2014 when I stumbled upon a blog post announcing &lt;a href=&#34;https://blog.codinghorror.com/standard-flavored-markdown/&#34;&gt;Standard Markdown&lt;/a&gt; (later &lt;a href=&#34;https://blog.codinghorror.com/standard-markdown-is-now-common-markdown/&#34;&gt;renamed to CommonMark&lt;/a&gt;).  This ambitious project aimed to standardize the syntax used by most Markdown parsers while also defining how edge cases should be handled.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Testing PHP 7.2 With Docker</title>
      <link>https://www.colinodell.com/blog/2017/testing-php-72-docker/</link>
      <pubDate>Thu, 06 Jul 2017 11:46:24 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/testing-php-72-docker/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://wiki.php.net/todo/php72&#34;&gt;PHP 7.2 is slated for release in November 2017&lt;/a&gt;, but you don&amp;rsquo;t have to wait until then to start testing your applications!  We can easily use Docker to test against the latest pre-release versions of 7.2.&lt;/p&gt;&#xA;&lt;h2 id=&#34;php-72-pre-release-images&#34;&gt;PHP 7.2 Pre-Release Images&lt;/h2&gt;&#xA;&lt;p class=&#34;alert alert-warning&#34;&gt;PHP now has &lt;a href=&#34;https://hub.docker.com/_/php/&#34;&gt;official pre-release Docker builds&lt;/a&gt; available. You should use those instead.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;I&amp;rsquo;ve created a PHP 7.2 pre-release image on Docker Hub: &lt;a href=&#34;https://hub.docker.com/r/colinodell/php-7.2/&#34;&gt;https://hub.docker.com/r/colinodell/php-7.2/&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>RIGHT JOINs in Doctrine 2</title>
      <link>https://www.colinodell.com/blog/2017/right-joins-doctrine-2/</link>
      <pubDate>Wed, 07 Jun 2017 22:08:11 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/right-joins-doctrine-2/</guid>
      <description>&lt;p&gt;I recently needed the ability to perform a &lt;code&gt;RIGHT JOIN&lt;/code&gt; in a Symfony project.  While Doctrine&amp;rsquo;s DBAL library seems to support this, the ORM&amp;rsquo;s QueryBuilder does not.  Unfortunately, the suggested workaround of &lt;a href=&#34;https://stackoverflow.com/questions/7957987/doctrine-dql-right-join&#34;&gt;inverting the query&lt;/a&gt; wouldn&amp;rsquo;t work in my situation.  I also didn&amp;rsquo;t feel like rewriting the query into DQL, so I ultimately hacked in my own support by duplicating the &lt;code&gt;LEFT JOIN&lt;/code&gt; functionality.  I figured I&amp;rsquo;d share my patch in case it helps others facing a similar issue.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Small Contributions Matter</title>
      <link>https://www.colinodell.com/blog/2017/small-contributions-matter/</link>
      <pubDate>Mon, 05 Jun 2017 21:22:39 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/small-contributions-matter/</guid>
      <description>Open-source development is more than big new features and major releases.  Small contributions are just as important to the success of open-source projects!  Any improvement, no matter how small, can help both the project and other developers.</description>
    </item>
    <item>
      <title>Technical Debt Is Like Tetris</title>
      <link>https://www.colinodell.com/blog/2017/technical-debt-tetris/</link>
      <pubDate>Mon, 05 Jun 2017 19:30:51 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/technical-debt-tetris/</guid>
      <description>I was playing Tetris over the weekend when I realized it&amp;rsquo;s a great metaphor for managing technical debt.</description>
    </item>
    <item>
      <title>Compiling open-zwave for Home Assistant 0.45 on Docker</title>
      <link>https://www.colinodell.com/blog/2017/compiling-openzwave-home-assistant-045-docker/</link>
      <pubDate>Sun, 21 May 2017 22:31:11 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/compiling-openzwave-home-assistant-045-docker/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://home-assistant.io/&#34;&gt;Home Assistant&lt;/a&gt; uses the &lt;a href=&#34;https://github.com/OpenZWave/open-zwave&#34;&gt;open-zwave library&lt;/a&gt; to control Z-Wave home automation devices like light switches and door sensors. Unfortunately, this library&amp;rsquo;s last release (1.5) was back in August 2016 and doesn&amp;rsquo;t include configurations for many Z-Wave devices I use (like the Linear NGDZ00-4 Garage Door).  I therefore needed to create &lt;a href=&#34;https://github.com/colinodell/open-zwave/tree/V1.5-with-customizations&#34;&gt;a custom open-zwave fork&lt;/a&gt;, &lt;a href=&#34;https://github.com/colinodell/open-zwave/compare/V1.5...V1.5-with-customizations&#34;&gt;cherry-pick recent commits for the functionality I need&lt;/a&gt;, and have my fork compiled into a &lt;a href=&#34;https://hub.docker.com/r/colinodell/home-assistant-with-barrier/&#34;&gt;custom Home Assistant Docker image&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>en-marche.fr powered by league/commonmark</title>
      <link>https://www.colinodell.com/blog/2017/en-marche-fr-powered-by-league-commonmark/</link>
      <pubDate>Tue, 09 May 2017 14:15:05 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/en-marche-fr-powered-by-league-commonmark/</guid>
      <description>&lt;p&gt;So this is really cool: &lt;a href=&#34;https://en.wikipedia.org/wiki/Emmanuel_Macron&#34;&gt;Emmanuel Macron&lt;/a&gt; (the next president of France) is &lt;a href=&#34;https://github.com/EnMarche/en-marche.fr/blob/b4d6e1eecbefeb8ce559c2f809bd50cf8788a151/composer.json#L40&#34;&gt;using&lt;/a&gt; my &lt;a href=&#34;http://commonmark.thephpleague.com/&#34;&gt;open-source CommonMark library&lt;/a&gt; on &lt;a href=&#34;https://en-marche.fr/&#34;&gt;his website&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;The full list of PHP League libraries used on the website:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&#x9;&lt;li&gt;&lt;a href=&#34;http://commonmark.thephpleague.com/&#34;&gt;league/commonmark&lt;/a&gt;&lt;/li&gt;&#xA;&#x9;&lt;li&gt;&lt;a href=&#34;http://flysystem.thephpleague.com/&#34;&gt;league/flysystem&lt;/a&gt;&lt;/li&gt;&#xA;&#x9;&lt;li&gt;&lt;a href=&#34;http://glide.thephpleague.com/&#34;&gt;league/glide&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Optimizing Docker-Based CI Runners With Shared Package Caches</title>
      <link>https://www.colinodell.com/blog/2017/optimizing-dockerbased-ci-runners-shared-package-caches/</link>
      <pubDate>Thu, 27 Apr 2017 20:46:50 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/optimizing-dockerbased-ci-runners-shared-package-caches/</guid>
      <description>Using a shared cache volume across all of our Docker-based GitLab CI jobs has allowed us to drastically improve our build speeds.</description>
    </item>
    <item>
      <title>PHPUnicorn</title>
      <link>https://www.colinodell.com/blog/2017/phpunicorn/</link>
      <pubDate>Wed, 15 Mar 2017 18:18:49 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/phpunicorn/</guid>
      <description>&lt;p&gt;For Pi Day 2017 I created a really fun project - the &lt;a href=&#34;https://www.hackster.io/colinodell/phpunicorn-visualizing-phpunit-tests-896208&#34;&gt;PHPUnicorn&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;A simple PHPUnit listener collects test results and sends them to a Raspberry Pi Zero Wireless device in real-time.  As the device receives the stats it lights up LEDs green, red, or orange to visualize the progress and results of your unit tests.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Limiting Subqueries in Doctrine 2 DQL</title>
      <link>https://www.colinodell.com/blog/2017/limiting-subqueries-doctrine-2-dql/</link>
      <pubDate>Sun, 12 Mar 2017 09:48:45 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2017/limiting-subqueries-doctrine-2-dql/</guid>
      <description>&lt;p&gt;TIL that Doctrine 2 doesn&amp;rsquo;t support &lt;code&gt;LIMIT&lt;/code&gt;s within subqueries which can be frustrating.  In my case, I wanted to &lt;code&gt;LEFT JOIN&lt;/code&gt; on a table using a subquery with a single result - something like this:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-php&#34;&gt;$dqb-&amp;gt;from(&#39;MyAppBundle:Foo&#39;, &#39;foo&#39;)&#xA;    -&amp;gt;leftJoin(&#39;foo.bar&#39;, &#39;bar&#39;, &#39;WITH&#39;, &#39;bar = (SELECT b FROM MyAppBundle:Bar b WHERE b.foo = foo AND b.published_date &amp;gt;= :now ORDER BY t.startDate LIMIT 1)&#39;);&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;But Doctrine kept throwing this error:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Installing PHP 7.1</title>
      <link>https://www.colinodell.com/blog/2016/installing-php-71/</link>
      <pubDate>Fri, 02 Dec 2016 09:15:20 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2016/installing-php-71/</guid>
      <description>&lt;aside&gt;&#xA;&lt;p class=&#34;alert alert-info&#34;&gt;Psst - PHP 7.4 is now available! Learn &lt;a href=&#34;https://www.colinodell.com/blog/2019/how-to-install-php-74&#34;&gt;how to upgrade to PHP 7.4 here&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;/aside&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://secure.php.net/releases/7_1_0.php&#34;&gt;PHP 7.1 has been released&lt;/a&gt;, bringing some great new features and enhancements to the language such as &lt;a href=&#34;https://wiki.php.net/rfc/nullable_types&#34;&gt;nullable types&lt;/a&gt;, the &lt;a href=&#34;https://wiki.php.net/rfc/iterable&#34;&gt;iterable pseudo-type&lt;/a&gt;, &lt;a href=&#34;https://wiki.php.net/rfc/multiple-catch&#34;&gt;catching multiple exceptions&lt;/a&gt;, and &lt;a href=&#34;https://secure.php.net/manual/en/migration71.php&#34;&gt;much more&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here&#39;s a brief guide on how to install PHP 7.1 on several different operating systems:&lt;/p&gt;&#xA;&lt;h2&gt;Ubuntu 14.04 - 16.10:&lt;/h2&gt;&#xA;&lt;p&gt;PHP 7.1 can be installed using &lt;a href=&#34;https://launchpad.net/~ondrej/+archive/ubuntu/php&#34;&gt;Ondřej Surý&#39;s PPA&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Installing PHP 7.0</title>
      <link>https://www.colinodell.com/blog/2015/installing-php-70/</link>
      <pubDate>Fri, 04 Dec 2015 07:05:00 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2015/installing-php-70/</guid>
      <description>&lt;aside&gt;&lt;p class=&#34;alert alert-info&#34;&gt;Psst - PHP 7.4 is now available! Learn &lt;a href=&#34;https://www.colinodell.com/blog/2019/how-to-install-php-74&#34;&gt;how to upgrade to PHP 7.4 here&lt;/a&gt;!&lt;/p&gt;&lt;/aside&gt;&#xA;&lt;p&gt;Installing PHP 7.0 is easier than ever.  Here are instructions for installing the latest version on different platforms:&lt;/p&gt;&#xA;&lt;div class=&#34;alert alert-warning&#34;&gt;&#xA;&lt;p&gt;&lt;strong&gt;PHP 5.x Conflicts&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;You may encounter conflicts if you already have PHP 5.x installed. If so, make sure to completely remove PHP 5.x from your system &lt;strong&gt;before&lt;/strong&gt; installing 7.0. On Ubuntu, this is as simple as running: &lt;code&gt;sudo apt-get purge php5-*&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Five Lesser-Known Features of PHP 7</title>
      <link>https://www.colinodell.com/blog/2015/five-lesserknown-features-php-7/</link>
      <pubDate>Wed, 02 Dec 2015 20:30:07 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2015/five-lesserknown-features-php-7/</guid>
      <description>&lt;p&gt; &lt;/p&gt;&#xA;&lt;p&gt;With the imminent release of PHP 7 on the horizon, I thought it would be cool to check out some of the lesser-known features coming with the 7.0.0 release:&lt;/p&gt;&#xA;&lt;h2&gt;1. Array constants in &lt;code&gt;define()&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;PHP 5.6 added the ability to define array constants on classes by using the &lt;code&gt;const&lt;/code&gt; keyword:&lt;/p&gt;&#xA;&lt;pre&gt;&#xA;&lt;code class=&#34;language-php&#34;&gt;const LUCKY_NUMBERS = [4, 8, 15, 16, 23, 42];&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;PHP 7 brings this same functionality to the &lt;code&gt;define()&lt;/code&gt; function:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Optimizing league/commonmark with Blackfire.io</title>
      <link>https://www.colinodell.com/blog/2015/optimizing-leaguecommonmark-blackfireio/</link>
      <pubDate>Sat, 28 Nov 2015 13:21:39 -0500</pubDate>
      <guid>https://www.colinodell.com/blog/2015/optimizing-leaguecommonmark-blackfireio/</guid>
      <description>This post demonstrates how Blackfire was used to identify slowness in the league/commonmark parser.  These findings were then used to implement two simple optimizations resulting in a 53%  performance boost!</description>
    </item>
    <item>
      <title>Linux Tip: Recursive FTP Backup</title>
      <link>https://www.colinodell.com/blog/2009/linux-tip-recursive-ftp-backup/</link>
      <pubDate>Tue, 21 Apr 2009 17:32:45 -0400</pubDate>
      <guid>https://www.colinodell.com/blog/2009/linux-tip-recursive-ftp-backup/</guid>
      <description>&lt;p&gt;Creating manual backups of a website can be a time-consuming task. Using Linux, you can automate the entire download/transfer using the handy utility known as &lt;a href=&#34;http://www.gnu.org/software/wget/&#34;&gt;wget&lt;/a&gt; (Ubuntu users: install it with &lt;code&gt;sudo apt-get install wget&lt;/code&gt;)&lt;/p&gt;&#xA;&lt;p&gt;Here’s the command to use for downloading your backup:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;wget ftp://&lt;strong&gt;yourwebsite.com&lt;/strong&gt;/&lt;strong&gt;some/directory&lt;/strong&gt; -nv -r -N -l inf -nH --ftp-user=&#39;&lt;strong&gt;username&lt;/strong&gt;&#39; --ftp-password=&#39;&lt;strong&gt;password&lt;/strong&gt;&#39;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;I’ve included all the options needed to fetch everything in the specified folder and maintain that same folder structure in the downloaded backup. Make sure to substitute your own FTP host, directory, username and password above! You can extend this further by &lt;a href=&#34;http://www.adminschoice.com/docs/crontab.htm&#34;&gt;using cronjobs to run this command on a set schedule&lt;/a&gt;, &lt;a href=&#34;http://linuxbasiccommands.wordpress.com/2008/04/04/linux-tar-command/&#34;&gt;compressing the files into a single archive file&lt;/a&gt;, and more!&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
