<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Living in a Digital World by Shawn Crigger]]></title><description><![CDATA[I'm a full time web developer, who has been in the business for over 15yrs+, I share some tricks, tips, and knowledge I gained along the way. I also blog about my dog :)]]></description><link>https://blog.shawncrigger.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1758187157160/8575fdf3-7202-4318-b8ff-0cf301a932b4.png</url><title>Living in a Digital World by Shawn Crigger</title><link>https://blog.shawncrigger.com</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Apr 2026 20:42:05 GMT</lastBuildDate><atom:link href="https://blog.shawncrigger.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[M chipped OSX Development Environment.]]></title><description><![CDATA[Step One is Install 🍺 Homebrew.
Open a terminal and enter the following commands. If you already have a working Homebrew installed, you can skip to Step 3
# First, we need to install the basics. You will be asked to enter your password during this p...]]></description><link>https://blog.shawncrigger.com/m-chipped-osx-development-environment</link><guid isPermaLink="true">https://blog.shawncrigger.com/m-chipped-osx-development-environment</guid><category><![CDATA[development environments]]></category><category><![CDATA[terminal]]></category><category><![CDATA[Developer Tools]]></category><category><![CDATA[Developer]]></category><category><![CDATA[tools]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Mon, 01 May 2023 03:47:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ylveRpZ8L1s/upload/869343193b422653befa9be9141781e5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-step-one-is-install-homebrew">Step One is Install 🍺 Homebrew.</h2>
<p>Open a terminal and enter the following commands. If you already have a working Homebrew installed, you can skip to Step 3</p>
<pre><code class="lang-bash"><span class="hljs-comment"># First, we need to install the basics. You will be asked to enter your password during this process</span>
xcode-select --install 

<span class="hljs-comment"># After xCode is installed we can install homebrew</span>
/bin/bash -c <span class="hljs-string">"<span class="hljs-subst">$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)</span>"</span> 

<span class="hljs-comment"># After succeessful homebrew install it should give you two commands to run </span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">'eval "$(/opt/homebrew/bin/brew shellenv)"'</span> &gt;&gt; ~/.zprofile
<span class="hljs-built_in">eval</span> <span class="hljs-string">"<span class="hljs-subst">$(/opt/homebrew/bin/brew shellenv)</span>"</span>

<span class="hljs-comment"># Now open a new terminal and run brew doctor</span>
brew doctor
</code></pre>
<h2 id="heading-next-lets-install-some-apps">Next, Let's Install Some Apps</h2>
<p>My personal list of must-have applications is as follows</p>
<ul>
<li><p><a target="_blank" href="https://iterm2.com">iTerm2</a> - The best terminal on OSX, period.</p>
</li>
<li><p><a target="_blank" href="https://www.mediaatelier.com/CheatSheet/">Cheatsheet</a> - Tells you all the hotkeys the current App has just by holding CMD down</p>
</li>
<li><p><a target="_blank" href="https://www.mycli.net/">MyCLI</a> MySQL CLI client with Syntax Highlighting and Autocomplete.</p>
</li>
<li><p><a target="_blank" href="https://www.makeuseof.com/bat-an-alternative-to-cat-command/">BAT</a> A syntax-highlighted, searchable, mouse-scrollable version of CAT.</p>
</li>
<li><p><a target="_blank" href="https://github.com/ogham/exa">EXA</a> A much better version of LS</p>
</li>
<li><p><a target="_blank" href="https://github.com/sivel/speedtest-cli">Speedtest-CLI</a> Run a speed test from your CLI.</p>
</li>
</ul>
<pre><code class="lang-bash">brew install --cask iterm2
brew install --cask cheatsheet
brew install mas-cli/tap/mas
brew install mycli
brew install bat
brew install exa
brew install speedtest-cli
</code></pre>
<h2 id="heading-lets-install-oh-my-zsh-and-prompt">Let's Install OH-MY-ZSH and Prompt</h2>
<pre><code class="lang-bash"><span class="hljs-comment"># First let's install OH My ZSH</span>
sh -c <span class="hljs-string">"<span class="hljs-subst">$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)</span>"</span>

<span class="hljs-comment"># Install zsh-autosuggestions</span>
git <span class="hljs-built_in">clone</span> https://github.com/zsh-users/zsh-autosuggestions <span class="hljs-variable">${ZSH_CUSTOM:-~/.oh-my-zsh/custom}</span>/plugins/zsh-autosuggestions

<span class="hljs-comment"># Install zsh-syntax-highlighting using Oh-my-zsh (Preferred)</span>
git <span class="hljs-built_in">clone</span> https://github.com/zsh-users/zsh-syntax-highlighting.git <span class="hljs-variable">${ZSH_CUSTOM:-~/.oh-my-zsh/custom}</span>/plugins/zsh-syntax-highlighting

<span class="hljs-comment"># Now add them to the .zshrc plugins</span>
nano ~/.zshrc

<span class="hljs-comment"># find the plugins and add both of these</span>
plugins=(zsh-autosuggestions zsh-syntax-highlighting)

<span class="hljs-comment"># While you are in .zshrc go ahead and add the following near the bottom change username with your username. </span>

<span class="hljs-keyword">if</span> [ -f <span class="hljs-string">"/Users/username/.aliases"</span> ]; <span class="hljs-keyword">then</span>
   <span class="hljs-built_in">source</span> /Users/username/.aliases
<span class="hljs-keyword">fi</span>

<span class="hljs-comment"># Save the file and Open a new terminal tab to verify your ZSH is working.</span>
</code></pre>
<h2 id="heading-installing-powerlevel10k-theme">Installing Powerlevel10k Theme</h2>
<p>Run the following commands to install Powerlevel10k</p>
<pre><code class="lang-bash"><span class="hljs-comment"># gh cli</span>
gh repo <span class="hljs-built_in">clone</span> romkatv/powerlevel10k <span class="hljs-variable">$ZSH_CUSTOM</span>/themes/powerlevel10k

<span class="hljs-comment"># git</span>
git <span class="hljs-built_in">clone</span> https://github.com/romkatv/powerlevel10k.git <span class="hljs-variable">$ZSH_CUSTOM</span>/themes/powerlevel10k
</code></pre>
<h3 id="heading-enabling-powerlevel10k">Enabling PowerLevel10k</h3>
<p>Then you need to enable it change the value of ZSH_THEME to the following in <code>~/.zshrc</code> file :</p>
<pre><code class="lang-bash">ZSH_THEME=<span class="hljs-string">"powerlevel10k/powerlevel10k"</span>
</code></pre>
<h3 id="heading-configuring-powerlevel10k">Configuring PowerLevel10k</h3>
<p>Make sure your terminal font is <code>FiraCode NF</code>.</p>
<p>You can get it at <a target="_blank" href="https://fonts.google.com/specimen/Fira+Code">https://fonts.google.com/specimen/Fira+Code</a> install the whole family. Using OSX's FontBook. And set your terminal font to <code>FiraCode NF</code></p>
<p>And to configure your prompt run the following command</p>
<pre><code class="lang-bash">p10k configure
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1682911878345/e390218f-eb5b-4f39-8c09-2bc35fa7ca08.gif" alt class="image--center mx-auto" /></p>
<p>Another good prompt I have used for a long time is <a target="_blank" href="https://spaceship-prompt.sh/">Spaceship Prompt</a> which offers a powerful prompt with very configurable options, but lately, I like PowerLevel10k.</p>
<h2 id="heading-lets-add-iterm2s-shell-utilities">Let's add iTerm2's Shell Utilities</h2>
<p>iTerm2 has some really useful utilities, so let's add some aliases to make them easier to remember and use.</p>
<p>First, I suggest reading the <a target="_blank" href="https://iterm2.com/documentation-utilities.html">Iterm2 Shell Utilities</a></p>
<p>After that, let's add some aliases to our aliases file. I always create a <code>.aliases</code> file in my home directory and include it in my <code>.zshrc</code> I suggest leaving this file open in your editor.</p>
<pre><code class="lang-bash">
<span class="hljs-comment">## IMG CAT Alias </span>
<span class="hljs-built_in">alias</span> icat=<span class="hljs-string">"imgcat <span class="hljs-variable">$1</span>"</span>
<span class="hljs-comment">## LS with Image Previews</span>
<span class="hljs-built_in">alias</span> ils=<span class="hljs-string">"imgls"</span>
<span class="hljs-comment">## Copy to clipboard</span>
<span class="hljs-built_in">alias</span> icp=<span class="hljs-string">"it2copy <span class="hljs-variable">$1</span>"</span>
<span class="hljs-comment">## Download from SSH to your Downloads folder</span>
<span class="hljs-built_in">alias</span> idl=<span class="hljs-string">"it2dl <span class="hljs-variable">$1</span>"</span>
<span class="hljs-comment">## Upload Filename through SSH </span>
<span class="hljs-built_in">alias</span> iup=<span class="hljs-string">"it2ul <span class="hljs-variable">$1</span> -c -z -v -f"</span>
</code></pre>
<h2 id="heading-lets-add-syntax-highlighting-to-nano">Let's add syntax highlighting to <code>Nano</code></h2>
<p>Now let's spruce up <code>Nano</code> with some syntax highlighting by running the following commands in iTerm2.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># install nano from homebrew</span>
brew install nano nanorc

<span class="hljs-comment"># update your .nanorc file</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">'include "/opt/homebrew/share/nanorc/*.nanorc"'</span> &gt;&gt; ~/.nanorc

<span class="hljs-comment"># Close and re-open your terminal, and you'll have syntax highlighting</span>
</code></pre>
<h2 id="heading-now-lets-fix-up-quicklook-real-quick-and-add-some-features">Now let's fix up Quicklook real quick and add some features</h2>
<p>Let's add Quicklook plugins to make Quicklook more useful. The plugins installed have the following usage.</p>
<ul>
<li><p><code>qlcolorcode</code> - Preview source code files with syntax highlighting</p>
</li>
<li><p><code>qlstephen</code> - Preview plain text files without or with an unknown file extension.</p>
</li>
<li><p><code>qlmarkdown</code> - Preview Markdown files</p>
</li>
<li><p><code>quicklook-json</code> - Preview JSON files</p>
</li>
<li><p><code>qlimagesize</code> - Display image size and resolution</p>
</li>
<li><p><code>suspicious-package</code> - Preview the contents of a standard Apple installer package</p>
</li>
<li><p><code>apparency</code> - Preview the contents of a macOS app</p>
</li>
<li><p><code>quicklookase</code> - Preview Adobe ASE Color Swatches generated with Adobe Photoshop, Adobe Illustrator, <a target="_blank" href="https://color.adobe.com/">Adobe Color CC</a>, <a target="_blank" href="http://www.eigenlogik.com/spectrum/mac">Spectrum</a>, <a target="_blank" href="https://www.colourlovers.com/">COLOURlovers</a>, <a target="_blank" href="http://www.codeadventure.com/">Prisma</a>, among many others.</p>
</li>
<li><p><code>qlvideo</code> -Preview most types of video files, as well as their thumbnails, cover art and metadata</p>
</li>
<li><p><code>syntax-highlight</code> - Preview many different source code files</p>
</li>
</ul>
<pre><code class="lang-bash">brew install qlcolorcode qlstephen qlmarkdown quicklook-json qlimagesize suspicious-package apparency quicklookase qlvideo

brew install --cask --no-quarantine syntax-highlight

<span class="hljs-comment"># To get plugins working in Catalina, you will need to remove the quarantine attribute.</span>
<span class="hljs-comment">#Run this to see the attributes:</span>
xattr -r ~/Library/QuickLook
<span class="hljs-comment">#And run this to remove the attributes:</span>
xattr -d -r com.apple.quarantine ~/Library/QuickLook
</code></pre>
<h2 id="heading-lets-add-allow-using-our-thumbprint-to-sudo">Let's add allow using our thumbprint to sudo</h2>
<pre><code class="lang-bash"><span class="hljs-comment"># First open the following file with sudo</span>
sudo /etc/pam.d/sudo
<span class="hljs-comment"># Add the following line at the very top and save</span>
auth sufficient pam_tid.so
<span class="hljs-comment"># Finally run this command </span>
defaults write com.apple.security.authorization ignoreArd -bool TRUE
</code></pre>
<h3 id="heading-fixing-iterm2-to-allow-using-the-thumbprint">Fixing iTerm2 to allow using the thumbprint</h3>
<p>The default terminal works like a charm, but <strong>iTerm2</strong> needs an extra configuration. Go to <code>Prefs -&gt; Advanced -&gt; Allow sessions to survive logging out and back in</code> and set the value to <code>no</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1682906987323/52f0bd72-3b57-46f6-929f-f0036bd6303b.png" alt class="image--center mx-auto" /></p>
<p>Now logout and back in, and both the default terminal and iTerm should allow using the Thumbprint instead of entering a password when <code>sudoing</code></p>
<h2 id="heading-adding-more-aliases-for-exa-and-bat">Adding more Aliases for EXA and BAT</h2>
<p>If you kept your <code>.aliases</code> file open, then add the following aliases. Otherwise, reopen it and add the following aliases.</p>
<pre><code class="lang-bash"><span class="hljs-comment">## Alias to make LS look like this</span>
<span class="hljs-built_in">alias</span> ls=<span class="hljs-string">"exa --icons -lh"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1682907724941/e3c6142a-3520-4f36-8f27-ae64d922be7d.jpeg" alt class="image--center mx-auto" /></p>
<p>Now my prompt at the bottom is set up using Power10k, but you can see how it adds icons to the different file types and such.</p>
<p>While you have the <code>.aliases</code> file open, let's add a few more aliases I find useful.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Copies you public key to your clip board</span>
<span class="hljs-built_in">alias</span> pubkey=<span class="hljs-string">"more ~/.ssh/id_rsa.pub | pbcopy | echo '=&gt; Public key copied to pasteboard.'"</span>
<span class="hljs-comment"># Stat Provides a Nice looking CLI Stats </span>
<span class="hljs-built_in">alias</span> sstat=<span class="hljs-string">"macchina"</span>
<span class="hljs-comment">## I use VSC Insider, if you don't use Insiders you dont need this</span>
<span class="hljs-built_in">alias</span> code=<span class="hljs-string">"code-insiders <span class="hljs-variable">$1</span>"</span>
<span class="hljs-comment">## Reload apache</span>
<span class="hljs-built_in">alias</span> rapache=<span class="hljs-string">"sudo systemctl reload apache2"</span>
<span class="hljs-comment"># dump autoloader and optimize autoloader</span>
<span class="hljs-built_in">alias</span> cda=<span class="hljs-string">"composer dumpautoload -o --dev"</span>
<span class="hljs-comment"># bulk association again if you don't use VSC Insiders just put code</span>
<span class="hljs-built_in">alias</span> -s {md,css,php,js,json,html}=code-insiders
</code></pre>
<p><code>macchina</code> or the alias <code>sstat</code> will render a CLI CPU Stats that looks like this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1682909661501/b8cae4bf-3a67-4965-96ad-e3af1da5b38c.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-using-bat-the-cat-replacement">Using BAT, the CAT replacement</h2>
<p>Sometimes, I like CAT to grep it and find specific things. Other times like log files, I want to be able to search and use the mouse to scroll through it, like this. It offers search and mouse scrolling and a lot of other commands.</p>
<p>If you can't figure out how to exit, it's like <code>Vim</code> type<code>:q,</code> but there are other commands you can use with<code>:</code> I suggest reading the docs on BAT.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1682909940845/07c78fb7-eb1b-4b55-921c-1a52bf7f136e.jpeg" alt class="image--center mx-auto" /></p>
<p>I have some more tools, but this article is getting pretty long, so stay tuned for the following article, which will expand on this one.</p>
]]></content:encoded></item><item><title><![CDATA[How to write Unit Tests for SlimPHP 4]]></title><description><![CDATA[I am motivated to write this article because more comprehensive documentation and examples are needed to write unit tests in SlimPHP 4, unlike its predecessor, SlimPHP 3, which provided ample resources on this subject. It is crucial to implement unit...]]></description><link>https://blog.shawncrigger.com/how-to-write-unit-tests-for-slimphp-4</link><guid isPermaLink="true">https://blog.shawncrigger.com/how-to-write-unit-tests-for-slimphp-4</guid><category><![CDATA[PHPUnit]]></category><category><![CDATA[slim]]></category><category><![CDATA[microframework]]></category><category><![CDATA[#php #testing #unittesting #phpunit]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Thu, 13 Apr 2023 18:35:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681410785146/ecfc8f49-d046-4e45-96e3-06140ea263dc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I am motivated to write this article because more comprehensive documentation and examples are needed to write unit tests in SlimPHP 4, unlike its predecessor, SlimPHP 3, which provided ample resources on this subject. It is crucial to implement unit testing in all applications, and for this article, I will focus solely on discussing the process of writing unit tests in SlimPHP 4.</p>
<h2 id="heading-setting-up-your-unit-testing">Setting up your unit testing</h2>
<p>We'll need to change the <code>composer.json</code> file by adding the following components to move forward.</p>
<p>This will facilitate the required functionality and ensure the smooth execution of subsequent processes.</p>
<pre><code class="lang-JSON">[
    <span class="hljs-string">"require-dev"</span>: {
        <span class="hljs-attr">"phpunit/phpunit"</span>: <span class="hljs-string">"^9.5"</span>,
        <span class="hljs-attr">"robtimus/multipart"</span>: <span class="hljs-string">"1.*"</span>
    },
    <span class="hljs-string">"autoload-dev"</span>: {
        <span class="hljs-attr">"psr-4"</span>: {
            <span class="hljs-attr">"Tests\\"</span>: <span class="hljs-string">"tests/"</span>
        }
    },
    <span class="hljs-string">"scripts"</span>: {
        <span class="hljs-attr">"start"</span>: <span class="hljs-string">"php -S localhost:8888 -t public"</span>,
        <span class="hljs-attr">"test"</span>: <span class="hljs-string">"phpunit --configuration phpunit.xml"</span>
    }
]
</code></pre>
<p>Next, let's create a <code>phpunit.xml</code> configuration file. This step is essential to ensure that PHPUnit can adequately execute the unit tests in our project.</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">phpunit</span> <span class="hljs-attr">xmlns:xsi</span>=<span class="hljs-string">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="hljs-attr">xsi:noNamespaceSchemaLocation</span>=<span class="hljs-string">"https://schema.phpunit.de/9.3/phpunit.xsd"</span> <span class="hljs-attr">backupGlobals</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">backupStaticAttributes</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">beStrictAboutTestsThatDoNotTestAnything</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">beStrictAboutChangesToGlobalState</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">beStrictAboutOutputDuringTests</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">colors</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">convertErrorsToExceptions</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">convertNoticesToExceptions</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">convertWarningsToExceptions</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">processIsolation</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">stopOnFailure</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">bootstrap</span>=<span class="hljs-string">"tests/autoload.php"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">coverage</span> <span class="hljs-attr">processUncoveredFiles</span>=<span class="hljs-string">"true"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">include</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">directory</span> <span class="hljs-attr">suffix</span>=<span class="hljs-string">".php"</span>&gt;</span>src/<span class="hljs-tag">&lt;/<span class="hljs-name">directory</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">include</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">coverage</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">testsuites</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">testsuite</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"RESTAPI Test Suite"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">file</span>&gt;</span>./tests/DummyTest.php<span class="hljs-tag">&lt;/<span class="hljs-name">file</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">testsuite</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">testsuites</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">phpunit</span>&gt;</span>
</code></pre>
<p>After successfully configuring PHPUnit to execute tests in a specific order, we will implement a Dummy Test. This essential step in our testing process will allow us to verify that the PHPUnit configuration has been accurately set up.</p>
<p>By doing so, we can ensure that all subsequent tests are executed in the desired order and that any potential issues with the configuration are promptly detected and resolved. Such a proactive approach will enable us to maintain a high-quality assurance standard in our testing procedures.</p>
<p>Finally, we need to create a <code>tests</code> directory and make a DummyTest.</p>
<pre><code class="lang-bash">mkdir tests
touch tests/DummyTest.php
</code></pre>
<p>Then paste the following code into your <code>DummyTest</code></p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">use</span> <span class="hljs-title">PHPUnit</span>\<span class="hljs-title">Framework</span>\<span class="hljs-title">TestCase</span>;

<span class="hljs-comment">/**
* Trivial dummy test used to confirm test configuration working.
*/</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DummyTest</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">TestCase</span>
</span>{
    <span class="hljs-comment">/**
    * Trivial dummy test guaranteed to succeed.
    */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testAssertEquals</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">$this</span>-&gt;assertEquals(<span class="hljs-string">'abc'</span>, <span class="hljs-string">'abc'</span>);
    }
}
</code></pre>
<p>We also need to create a new file named <code>autoload.php</code> and paste the following code into it.</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span>.<span class="hljs-string">'/../vendor/autoload.php'</span>;
</code></pre>
<h2 id="heading-running-your-first-test">Running your first test</h2>
<p>Now that all the setup is done, we can install PHPUnit and start our first test.</p>
<p>Run the following commands in your terminal to test that everything is set up and working correctly.</p>
<pre><code class="lang-bash">composer update
composer <span class="hljs-built_in">test</span>
</code></pre>
<p>You should receive a message saying 1 test was completed.</p>
<h2 id="heading-building-the-first-real-unit-test">Building the first real unit test</h2>
<p>Now you have PHPUnit set up and working. We can start by creating some tests. Instead of making an application, let's use this <a target="_blank" href="https://www.twilio.com/blog/create-restful-api-slim4-php-mysql">tutorial</a>. I found it on a simple Google search that builds an extremely simple REST API.</p>
<p>There's a Route to get all Customers, so to make that work first, I created a <code>TestCase</code> class that extends the PHPUnit Frameworks <code>TestCase</code>.</p>
<p>That way, I could add some Database Commands to the Tests. Since the guide didn't use a Container or Actions for each route, we will have to do some hacky coding to get the tests to work.</p>
<p>First, create a file <code>tests/TestCase.php</code> and paste the following into the file.</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">Tests</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">PHPUnit</span>\<span class="hljs-title">Framework</span>\<span class="hljs-title">TestCase</span> <span class="hljs-title">as</span> <span class="hljs-title">PHPUNIT_TestCase</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Factory</span>\<span class="hljs-title">AppFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Factory</span>\<span class="hljs-title">RequestFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Factory</span>\<span class="hljs-title">ResponseFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Factory</span>\<span class="hljs-title">ServerRequestFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Response</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Stream</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Models</span>\<span class="hljs-title">Db</span>;

<span class="hljs-class"><span class="hljs-keyword">Class</span> <span class="hljs-title">TestCase</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PHPUNIT_TestCase</span>
</span>{
  <span class="hljs-keyword">public</span> $customer;
  <span class="hljs-keyword">public</span> $lastID;

  <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getCustomer</span>(<span class="hljs-params"></span>)
  </span>{
    $SQL = <span class="hljs-string">"SELECT * FROM customers ORDER BY id DESC LIMIT 1"</span>;
    $db = <span class="hljs-keyword">new</span> Db();
    $conn = $db-&gt;connect();
    $stmt = $conn-&gt;query($SQL);
    $customer = $stmt-&gt;fetch(\PDO::FETCH_NAMED);
    <span class="hljs-keyword">$this</span>-&gt;customer = (<span class="hljs-keyword">object</span>) $customer;
    <span class="hljs-keyword">$this</span>-&gt;lastID = <span class="hljs-keyword">$this</span>-&gt;customer-&gt;id;
    <span class="hljs-keyword">unset</span>($db);
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;user;
  }

  <span class="hljs-comment">// ------------------------------------------------------------------------</span>

  <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTotalCustomers</span>(<span class="hljs-params"></span>)
  </span>{
    $db = <span class="hljs-keyword">new</span> Db();
    $conn = $db-&gt;connect();
    $sql = <span class="hljs-string">"SELECT count(id) AS count FROM customers GROUP BY id"</span>;
    $stmt = $conn-&gt;prepare($sql);
    $customers = $stmt-&gt;execute();
    $customers = $stmt-&gt;fetchColumn();
    <span class="hljs-keyword">return</span> $customers;
  }

  <span class="hljs-comment">// ------------------------------------------------------------------------</span>

  <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getLastCustomerID</span>(<span class="hljs-params"></span>)
  </span>{
    <span class="hljs-keyword">if</span> (!is_int(<span class="hljs-keyword">$this</span>-&gt;lastID) <span class="hljs-keyword">OR</span> !is_object(<span class="hljs-keyword">$this</span>-&gt;user)) {
      <span class="hljs-keyword">$this</span>-&gt;getCustomer();
    }

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>-&gt;customer-&gt;id;
  }

}
</code></pre>
<p>There are better methods of doing this, but this is the best method I found that worked without using an Application Container <code>PHP-DI</code> and without using <code>Actions</code> instead of writing the code directly into the route's anonymous functions.</p>
<p>Finally, let's write a simple test to verify that the <code>GET</code> <code>/customers</code> route tests correctly.</p>
<p>Create a file <code>tests/GetCustomersTest.php</code> and paste the following into it.</p>
<pre><code class="lang-php">
<span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">use</span> <span class="hljs-title">PHPUnit</span>\<span class="hljs-title">Framework</span>\<span class="hljs-title">TestCase</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Factory</span>\<span class="hljs-title">AppFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Factory</span>\<span class="hljs-title">ServerRequestFactory</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Response</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Slim</span>\<span class="hljs-title">Psr7</span>\<span class="hljs-title">Stream</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GetcustomersTest</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">TestCase</span> </span>{

  <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testGetRoute</span>(<span class="hljs-params"></span>) </span>{

    <span class="hljs-comment">// Set up the app</span>
    $app = AppFactory::create();

    <span class="hljs-comment">// Add the route to be tested</span>
    $app-&gt;get(<span class="hljs-string">'/customers-data/all'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">Request $request, Response $response</span>) </span>{
      $sql = <span class="hljs-string">"SELECT * FROM customers"</span>;

      <span class="hljs-keyword">try</span> {
        $db = <span class="hljs-keyword">new</span> Db();
        $conn = $db-&gt;connect();
        $stmt = $conn-&gt;query($sql);
        $customers = $stmt-&gt;fetchAll(PDO::FETCH_OBJ);
        $db = <span class="hljs-literal">null</span>;

        $response-&gt;getBody()-&gt;write(json_encode($customers));
        <span class="hljs-keyword">return</span> $response
        -&gt;withHeader(<span class="hljs-string">'content-type'</span>, <span class="hljs-string">'application/json'</span>)
        -&gt;withStatus(<span class="hljs-number">200</span>);
      } <span class="hljs-keyword">catch</span> (PDOException $e) {
        $error = <span class="hljs-keyword">array</span>(
          <span class="hljs-string">"message"</span> =&gt; $e-&gt;getMessage()
        );

        $response-&gt;getBody()-&gt;write(json_encode($error));
        <span class="hljs-keyword">return</span> $response
        -&gt;withHeader(<span class="hljs-string">'content-type'</span>, <span class="hljs-string">'application/json'</span>)
        -&gt;withStatus(<span class="hljs-number">500</span>);
      }
    });

    <span class="hljs-comment">// Create a new GET request to the route</span>
    $request = (<span class="hljs-keyword">new</span> ServerRequestFactory())-&gt;createServerRequest(<span class="hljs-string">'GET'</span>, <span class="hljs-string">'/customers/all'</span>);

    <span class="hljs-comment">// Invoke the application</span>
    $response = $app-&gt;handle($request);

    <span class="hljs-comment">// Assert that the response status code is 200</span>
    <span class="hljs-keyword">$this</span>-&gt;assertEquals(<span class="hljs-number">200</span>, $response-&gt;getStatusCode());

    $existing_customers = <span class="hljs-keyword">$this</span>-&gt;getTotalCustomers();

    $customers = (<span class="hljs-keyword">array</span>) json_decode($response-&gt;getBody());
    $count     = count($customers);

    <span class="hljs-keyword">$this</span>-&gt;assertIsArray($body);
    <span class="hljs-keyword">$this</span>-&gt;assertCount($count, $existing_customers, <span class="hljs-string">'The count of the existing customers does not match the count of the customers returned'</span>);
  }
}
</code></pre>
<p>And to make this test run, edit <code>phpunit.xml</code> and add the test case to the Test Suite by adding this line.</p>
<pre><code class="lang-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">file</span>&gt;</span>./tests/GetCustomersTest.php<span class="hljs-tag">&lt;/<span class="hljs-name">file</span>&gt;</span>
</code></pre>
<p>In summary, this is not the correct way to write tests like these, but the guide I found online didn't use a Container or Actions. And I needed something very similar but couldn't find any helpful information online, so I wrote this article.</p>
<p>Maybe I will write another article showing how to correctly write the REST API with a Container and Actions. If anybody is interested in it, please leave a comment.</p>
]]></content:encoded></item><item><title><![CDATA[The developer's best tools of 2023]]></title><description><![CDATA[Since so many new tools and services have come out since my last list, I decided it's time for a new list of tools and services.
So without further ado

Appwrite - Open-Source End-to-End Backend Server

Urlbox - Fast, Reliable Website Screenshot API
...]]></description><link>https://blog.shawncrigger.com/the-developers-best-tools-of-2023</link><guid isPermaLink="true">https://blog.shawncrigger.com/the-developers-best-tools-of-2023</guid><category><![CDATA[Developer]]></category><category><![CDATA[tools]]></category><category><![CDATA[Tools for Small business]]></category><category><![CDATA[services]]></category><category><![CDATA[SaaS]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Tue, 14 Mar 2023 17:24:55 GMT</pubDate><content:encoded><![CDATA[<p>Since so many new tools and services have come out since my last list, I decided it's time for a new list of tools and services.</p>
<p>So without further ado</p>
<ul>
<li><p><a target="_blank" href="https://appwrite.io/">Appwrite</a> - Open-Source End-to-End Backend Server</p>
</li>
<li><p><a target="_blank" href="https://www.urlbox.io/">Urlbox</a> - Fast, Reliable Website Screenshot API</p>
</li>
<li><p><a target="_blank" href="https://scrapy.org/">Scrapy</a> - A Fast and Powerful Scraping and Web Crawling Framework for extracting the data you need from websites.</p>
</li>
<li><p><a target="_blank" href="https://shuffle.dev/">Shuffle</a> - Shuffle gives you 7,400+ fully responsive UI components to get you started.</p>
</li>
<li><p><a target="_blank" href="https://thunderclient.com">Thunder Client</a> - A hand-crafted lightweight Rest API Client extension for Visual Studio Code</p>
</li>
<li><p><a target="_blank" href="https://www.cypress.io/">Cypress</a> - Fast, easy, and reliable web testing for any applications or components that run in a browser.</p>
</li>
<li><p><a target="_blank" href="https://hasura.io/">Hasura</a> - Instant GraphQL on all your data, with built-in Auth and Cache</p>
</li>
<li><p><a target="_blank" href="https://chat.openai.com/chat">ChatGPT</a> - No list would be complete without it.</p>
</li>
<li><p><a target="_blank" href="https://www.figma.com/">Figma</a> - Create graphics without Photoshop, plus it has many features PS doesn't have and it's free.</p>
</li>
<li><p><a target="_blank" href="http://tinykiwi.io/">Tiny Kiwi</a> - Amazing designs in a matter of seconds</p>
</li>
<li><p><a target="_blank" href="https://anyword.com/">Anyword</a> - The Only AI Copywriter That Knows What Converts</p>
</li>
<li><p><a target="_blank" href="https://notion.so/">Notion</a> - Developers can only remember some things but need to be able to find them quickly. What I love about Notion is using different templates. You can use different templates to go from a wiki to a project management tool.</p>
</li>
<li><p><a target="_blank" href="https://hashnode.com/">Hashnode</a> - A list would only be complete with Hashnode for your blog.</p>
</li>
</ul>
<p>That's enough awesome tools that developers can save time using, and I'm working on collecting my favorite CLI tools atm since many of us are CLI Commandos.  </p>
<p>I hope you enjoyed the list. Leave a comment and tell me what you would like to see more of. Give me a follow if you want more content like this and along with PHP and JS knowledge.</p>
]]></content:encoded></item><item><title><![CDATA[Handy Links for Establishing a Debian Development Environment]]></title><description><![CDATA[Essential Software Every Software Developer Needs
I'm trying to keep my posts short, but if you want to learn more about a particular topic, I'd be happy to provide more information.
Before doing anything, update apt-get and install the build-essenti...]]></description><link>https://blog.shawncrigger.com/handy-links-for-establishing-a-debian-development-environment</link><guid isPermaLink="true">https://blog.shawncrigger.com/handy-links-for-establishing-a-debian-development-environment</guid><category><![CDATA[Developer Tools]]></category><category><![CDATA[Developer]]></category><category><![CDATA[dev]]></category><category><![CDATA[debian]]></category><category><![CDATA[devenv]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sun, 26 Feb 2023 00:47:39 GMT</pubDate><content:encoded><![CDATA[<p>Essential Software Every Software Developer Needs</p>
<p>I'm trying to keep my posts short, but if you want to learn more about a particular topic, I'd be happy to provide more information.</p>
<p>Before doing anything, update apt-get and install the build-essentials.</p>
<pre><code class="lang-bash">sudo apt-get update 
sudo apt-get install git-core curl build-essential openssl libssl-dev
</code></pre>
<p>Next, we need to set up an SSH key which the first link does well. And I usually install Ruby on Rails, which is optional.</p>
<ul>
<li><p><a target="_blank" href="http://www.debian-administration.org/articles/530">SSH Key Gen and Copy</a></p>
</li>
<li><p><a target="_blank" href="http://wiki.mediatemple.net/w/%28ve%29:Ruby_on_Rails_on_Debian">Edit thisSome Ruby Setup</a></p>
</li>
</ul>
<h2 id="heading-installing-nodejs">Installing NodeJS</h2>
<ol>
<li><p>Clone the node repo from GitHub by running the following.<br /> <code>git clone git://github.com/ry/node.git</code></p>
</li>
<li><p>Next, we need to install it :)</p>
<pre><code class="lang-bash"> <span class="hljs-built_in">cd</span> node
 ./configure
 make
 sudo make install
</code></pre>
<p> The terminal output will show whether everything went OK, but if you want to be sure, run <code># man node</code> in the terminal.</p>
<p> <code># man node</code></p>
</li>
<li><p>Now Install NPM the Package Manager by running the following command</p>
<p> <code>curl http://npmjs.org/install.sh | sudo sh npm -v</code></p>
</li>
</ol>
<h2 id="heading-phpdocumentor-2">phpDocumentor 2</h2>
<p>I like my API Docs generated, I'm OCD in my comment style, so I must have it.</p>
<p><a target="_blank" href="http://www.phpdoc.org/">phpDocumentor</a></p>
<p>Here's how I installed it</p>
<p>First, I needed a PHP module</p>
<pre><code class="lang-bash"><span class="hljs-comment">## Plaase note you will need to use the correct php version number </span>
sudo su
apt-get install php5-xsl php-pear graphviz
pear channel-discover pear.phpdoc.org
pear install phpdoc/phpDocumentor-alpha

<span class="hljs-comment">## Now just run</span>

phpdoc -d . -t docs

<span class="hljs-comment"># And there ya go</span>
</code></pre>
<p>To conclude, setting up a development environment with Debian requires installing essential software, an SSH key, NodeJS, and Ruby on Rails. Additionally, you can install the phpDocumentor two package to generate API documentation.</p>
<p>This is by no means everything needed to set up your environment that will depend on your project.</p>
]]></content:encoded></item><item><title><![CDATA[Getting started with GIT on the Command Line]]></title><description><![CDATA[Coming from an SVN versioning system to GIT has been a long strange trip; at first, SVN commands made more sense, like checkout and update, but then when you think about it, they're backward.
Whereas with Git, I'm noticing it's more like *nix CLI com...]]></description><link>https://blog.shawncrigger.com/getting-started-with-git-on-the-command-line</link><guid isPermaLink="true">https://blog.shawncrigger.com/getting-started-with-git-on-the-command-line</guid><category><![CDATA[Git]]></category><category><![CDATA[Bash]]></category><category><![CDATA[command line]]></category><category><![CDATA[version control]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Fri, 24 Feb 2023 01:23:07 GMT</pubDate><content:encoded><![CDATA[<p>Coming from an SVN versioning system to GIT has been a long strange trip; at first, SVN commands made more sense, like checkout and update, but then when you think about it, they're backward.</p>
<p>Whereas with Git, I'm noticing it's more like *nix CLI commands to deal with files, commits, etc.</p>
<h3 id="heading-remove-a-file">Remove a file</h3>
<pre><code class="lang-bash"><span class="hljs-comment">#Note pass -r for recursive to remove folder</span>
<span class="hljs-comment">#Note pass -f to force removal, you can combine these like -rf</span>
git rm filename
</code></pre>
<h3 id="heading-rename-move-a-file">Rename / Move a file</h3>
<pre><code class="lang-bash">git mv filename
</code></pre>
<h3 id="heading-add-file-or-files-for-commit">Add File or Files for Commit</h3>
<pre><code class="lang-bash"><span class="hljs-comment">## Add all files </span>
git add ./ 

<span class="hljs-comment">## Add just filenames</span>
git add filename
</code></pre>
<h3 id="heading-commit-with-message">Commit with message</h3>
<pre><code class="lang-bash">git commit -m <span class="hljs-string">"Useful message"</span>

<span class="hljs-comment"># Better commit but know your editor it normally opens VIM, NANO, or whatever you setup as EDITOR </span>
<span class="hljs-comment"># in your .bashrc or .zshrc</span>
git commit
</code></pre>
<h3 id="heading-pull-from-server">Pull From Server</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Pulls the currently tracked branch</span>
git pull
</code></pre>
<h3 id="heading-change-branch-and-pull-from-server">Change Branch and Pull From Server</h3>
<pre><code class="lang-bash"><span class="hljs-comment">#example git checkout -b &lt; new_branch &gt; origin/&lt; new_branch &gt;</span>
git checkout -b newbranch origin/newbranch
</code></pre>
<h3 id="heading-push-to-the-server-replace-master-with-branch">Push to the server, replace master with branch</h3>
<pre><code class="lang-bash">
    git push origin master
    git push remote branch
</code></pre>
<ul>
<li>Switch branches</li>
</ul>
<pre><code class="lang-bash">
    git checkout branchname
</code></pre>
<ul>
<li>Create a tag</li>
</ul>
<pre><code class="lang-bash">
  git tag tagname
  git push origin :refs/tags/tagname
</code></pre>
<ul>
<li>Push a tag</li>
</ul>
<pre><code class="lang-bash">
git push --tags
</code></pre>
<ul>
<li>Delete a tag</li>
</ul>
<pre><code class="lang-bash">
    git tag -d tagname
    git push origin :refs/tags/tagname
</code></pre>
<ul>
<li>Adding Remote Repo</li>
</ul>
<pre><code class="lang-plaintext">
     git remote add **alias** **url**

    #Example
     git remote add upstream git://github.com/octocat/Spoon-Knife.git
     git fetch upstream
     git merge upstream/develop
</code></pre>
<p>There's more, but that'll do for this post.</p>
<p>Highly suggest learning git-flow</p>
]]></content:encoded></item><item><title><![CDATA[How to move a GIT Repo from GitHub to Azure]]></title><description><![CDATA[Moving Repo from Github to Azure
This is a simple way to move a codebase to Azure, Amazon, Gitlab, Bitbucket, any provider that hosts GIT repositories.  I'm moving from GitHub to Azure but the steps are the same.
Create a empty repo on your target to...]]></description><link>https://blog.shawncrigger.com/how-to-move-a-git-repo-from-github-to-azure</link><guid isPermaLink="true">https://blog.shawncrigger.com/how-to-move-a-git-repo-from-github-to-azure</guid><category><![CDATA[GitHub]]></category><category><![CDATA[Git]]></category><category><![CDATA[Bitbucket]]></category><category><![CDATA[Azure]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Fri, 22 Apr 2022 02:29:15 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-moving-repo-from-github-to-azure">Moving Repo from Github to Azure</h1>
<p>This is a simple way to move a codebase to Azure, Amazon, Gitlab, Bitbucket, any provider that hosts GIT repositories.  I'm moving from GitHub to Azure but the steps are the same.</p>
<p>Create a empty repo on your target to host your code.</p>
<p>First I pulled a clean copy from GitHub to my laptop into a new directory I named <code>azure</code></p>
<p>This is how I did it, you will need to login to your target repo host and add your ssh key. This is different on every host. Below is an Apple way to copy your key to the clipboard.</p>
<pre><code class="lang-bash">cat ~/.ssh/id_rsa.pub | pbcopy
</code></pre>
<p>Next after you can commit to the repo, you need to pull a clean copy of the repo, add the remote for the Azure container, then fetch all the tags, and checkout all the branches, then push to the Azure remote. Here are the exact commands I used to move it, I’ve used these commands a lot over the years to move client code from their old web developer’s GitHub to my Bitbucket or GitHub account. </p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ~
git <span class="hljs-built_in">clone</span> <span class="hljs-comment">#use ssh github clone link* azure</span>
<span class="hljs-comment">## Add remote named azure</span>
git remote set-url azure *replace with target repo ssh link*
<span class="hljs-comment">## List remotes </span>
git remote -v
<span class="hljs-comment">## Fetch all tags and commit history</span>
git fetch origin --all --tags -v
<span class="hljs-comment">## Fetch all branches</span>
<span class="hljs-keyword">for</span> remote <span class="hljs-keyword">in</span> git branch -r | grep -v master ; <span class="hljs-keyword">do</span> git checkout --track <span class="hljs-variable">$remote</span> ; <span class="hljs-keyword">done</span>
<span class="hljs-comment">## now push everything to the remote azure you set earlier</span>
git push azure --all
</code></pre>
<p>And that is all there is to it honestly.  It took me maybe 10 minutes once I found my old notes on moving origins. </p>
<p>After the code is moved, you can rename origin to <code>github</code> and rename <code>azure</code> too <code>origin</code> so when you push code it will automagically go into the Azure repo.</p>
<p><strong>Shawn Crigger</strong></p>
]]></content:encoded></item><item><title><![CDATA[Easier PHP development in less than 10 simple steps]]></title><description><![CDATA[I’m sure we all have our little tool kit we install while we build our applications, mine included the Symphony VarDumper Component another one I like to install in development is PHP-Console along with a few other things that I wrote years ago and h...]]></description><link>https://blog.shawncrigger.com/easier-php-development-in-less-than-10-simple-steps</link><guid isPermaLink="true">https://blog.shawncrigger.com/easier-php-development-in-less-than-10-simple-steps</guid><category><![CDATA[PHP]]></category><category><![CDATA[PHP7]]></category><category><![CDATA[composer]]></category><category><![CDATA[development]]></category><category><![CDATA[Developer Tools]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sat, 18 Sep 2021 16:54:38 GMT</pubDate><content:encoded><![CDATA[<p>I’m sure we all have our little tool kit we install while we build our applications, mine included the Symphony VarDumper Component another one I like to install in development is PHP-Console along with a few other things that I wrote years ago and haven’t released.</p>
<p>Anyway, it’s annoying having to install my development toolkit every time I want to build a plugin or debug a controller, or whatever I’m working on at the time. </p>
<p>So I found a tip in the Symphony docs that shows you how to prepend your globally loaded composer packages into every PHP script on your localhost or your development server.</p>
<p>It’s really simple honestly, basically install the packages you use to develop with globally, then modify the <code>php.ini</code> file to prepend the autoloader.php to all your PHP scripts.</p>
<p>So just to install the VarDumper Component you would install it globally like this</p>
<pre><code class="lang-bash"><span class="hljs-comment"># install globally all your development packages like this.</span>
composer global require symfony/var-dumper
composer global require php-console/php-console
</code></pre>
<p>Now by installing these globally they will be located in your home directory unless you <code>sudo</code> installed them then they would be in /root/ I think, I don’t know since I haven't tried it, I think running <code>sudo</code> composer is just asking for troubles.</p>
<p>Next to load these packages and use them in every PHP project on the server we installed these on, I normally only install these on my localhost and my development server, do not install these on production servers.</p>
<p>But the final step to all this is modifying your php.ini file, if you don’t know where your php.ini file is located at you can do the following in your console.</p>
<pre><code class="lang-`">php -i | grep "php.ini"
</code></pre>
<p>which should give you some output like the following</p>
<pre><code>➜ php -i | grep "php.ini"
<span class="hljs-keyword">Configuration</span> File (php.ini) <span class="hljs-type">Path</span> =&gt; /usr/<span class="hljs-keyword">local</span>/etc/php/<span class="hljs-number">7.2</span>
Loaded <span class="hljs-keyword">Configuration</span> File =&gt; /usr/<span class="hljs-keyword">local</span>/etc/php/<span class="hljs-number">7.2</span>/php.ini
</code></pre><p>So the final task to complete this is using the editor of your choice, I am just going to use nano because it’s quick and easy to load the Loaded Configuration File, go to the bottom of the file, and add the following</p>
<pre><code><span class="hljs-attribute">sudo</span> nano /usr/local/etc/php/<span class="hljs-number">7</span>.<span class="hljs-number">2</span>/php.ini
</code></pre><p>Go to the bottom of the file add the following line, replace my username <code>shawnc</code> with your Linux username.  </p>
<pre><code><span class="hljs-comment">## Don't forget to replace shawnc with your username here.</span>
<span class="hljs-attr">auto_prepend_file</span> = /home/shawnc/.composer/vendor/autoload.php
</code></pre><p>And that's it, restart your PHP server with either </p>
<pre><code><span class="hljs-attribute">sudo</span> service php<span class="hljs-number">7</span>.<span class="hljs-number">2</span>-fpm restart
<span class="hljs-attribute">sudo</span> systemctl restart php<span class="hljs-number">7</span>.<span class="hljs-number">2</span>-fpm
</code></pre><p>Or whatever command and version PHP you have installed, a good trick there is just type PHP and hit tab it should autocomplete the running service when you are trying to restart it. But you should also know what freaking version of PHP you are running! </p>
<p>Once you have restarted your service you can test it by just add this simple PHP file and test if it works</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

  $array = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>];
  dd($array);
</code></pre>
<p>Just copy that small file and paste it as test.php in your current directory then run </p>
<pre><code class="lang-bash">php test.php
</code></pre>
<p>It should give a pretty var dump of the array, other packages you add will require more configuration. That's on you to read the package instructions and follow them.</p>
<p>Anyway thanks for listening to me ramble on about PHP and development shortcuts. </p>
]]></content:encoded></item><item><title><![CDATA[How to figure out what is using all your Linux Diskspace]]></title><description><![CDATA[I've been working on a server that someone else set up, and it is constantly running out of disk space, 102GB of disk space gone in a day. This leaves me to find and figure out where it is being used, clear whatever is using all this disk space and i...]]></description><link>https://blog.shawncrigger.com/how-to-figure-out-what-is-using-all-your-linux-diskspace</link><guid isPermaLink="true">https://blog.shawncrigger.com/how-to-figure-out-what-is-using-all-your-linux-diskspace</guid><category><![CDATA[Ubuntu]]></category><category><![CDATA[linux for beginners]]></category><category><![CDATA[Linux]]></category><category><![CDATA[linux-basics]]></category><category><![CDATA[cli]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Wed, 01 Sep 2021 23:12:27 GMT</pubDate><content:encoded><![CDATA[<p>I've been working on a server that someone else set up, and it is constantly running out of disk space, 102GB of disk space gone in a day. This leaves me to find and figure out where it is being used, clear whatever is using all this disk space and it's normally in the logs or our applications cache directory.</p>
<p>I did not set up this server, it's a Ubuntu 18.04 server but these commands should work for most flavors of Linux I believe.</p>
<p>The reason I am not trying to fix the problem is that I was told not to, when my development server is purchased and I set it up, it will not have these issues.  I might make a guide to setting up a LAMP stack Ubuntu server but do we really need another one?</p>
<p>Here are the commands I use to locate where the disk space is being used the most at.</p>
<pre><code class="lang-bash">
<span class="hljs-comment"># View hard disk space</span>
df -h

<span class="hljs-comment"># View which directory is the largest, step by step to find large files</span>
sudo du -sh /*

<span class="hljs-comment"># Personally I like to just check log and tmp directory like just</span>
<span class="hljs-comment"># keeping adding directorys seperated by a space</span>
sudo du -sh /var/<span class="hljs-built_in">log</span> /tmp

<span class="hljs-comment"># find the largest file from the current directory, you can set max-depth to look into deeper subdirectories</span>
sudo du -h --max-depth=1

<span class="hljs-comment"># Check your systemd log</span>
sudo du -sh /var/<span class="hljs-built_in">log</span>/journal/

<span class="hljs-comment"># Another way to check your systemd log</span>
sudo journalctl --disk-usage

<span class="hljs-comment"># If that is the problem then clean out the old data by deleting anything older then say 2 days</span>

sudo journalctl --vacuum-time=2d

<span class="hljs-comment"># And Maybe set max files saved</span>

sudo journalctl --vacuum-files=5
</code></pre>
]]></content:encoded></item><item><title><![CDATA[New blog URL!]]></title><description><![CDATA[Some of you have noticed I changed my blog from shawn-crigger.xyz to my non-staging domain blog.shawn-crigger.com, as I never meant for my blog to get launched on the .xyz I was still new to #hashnode, and trying to get the how Hashnode works, but @h...]]></description><link>https://blog.shawncrigger.com/new-blog-url</link><guid isPermaLink="true">https://blog.shawncrigger.com/new-blog-url</guid><category><![CDATA[migration]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sun, 25 Jul 2021 07:19:16 GMT</pubDate><content:encoded><![CDATA[<p>Some of you have noticed I changed my blog from <code>shawn-crigger.xyz</code> to my non-staging domain <code>blog.shawn-crigger.com</code>, as I never meant for my blog to get launched on the <code>.xyz</code> I was still new to #hashnode, and trying to get the how Hashnode works, but @hashnode 's support team is top-notch!</p>
<p>Also to change the domain on Hashnode is easy. Just go to your Dashboard &gt; Domains, where your custom domain is, and click delete and enter the new domain.</p>
<p>A Twitter friend made me the below graphic and I really liked it, If your not following <a target="_blank" href="https://twitter.com/web_dev_dan">@web_dev_dan</a> on Twitter maybe you should be!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627197079110/IhWrSFQyL.jpeg" alt="Follow me on Twitter" /></p>
]]></content:encoded></item><item><title><![CDATA[How to write a Resume in 2021]]></title><description><![CDATA[Back when I was in school, they taught us a Resume should basically be a story explaining what you did at each company, now I went to school in the 80s and 90s, and honestly what they taught us then was completely wrong for today's fast-moving indust...]]></description><link>https://blog.shawncrigger.com/how-to-write-a-resume-in-2021</link><guid isPermaLink="true">https://blog.shawncrigger.com/how-to-write-a-resume-in-2021</guid><category><![CDATA[#codenewbies]]></category><category><![CDATA[job search]]></category><category><![CDATA[General Advice]]></category><category><![CDATA[tips]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sat, 08 May 2021 13:57:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1620482064951/EIjgbUfLm.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Back when I was in school, they taught us a Resume should basically be a story explaining what you did at each company, now I went to school in the 80s and 90s, and honestly what they taught us then was completely wrong for today's fast-moving industries. </p>
<p>A resume should be depending on your work history 1 or 2 pages at most.  Leave the story out of the resume, that's what the cover letter is for.</p>
<p>When writing your resume, include your Contact Information, a Short Summary of what you specialize in,  your skillset, and languages spoken if you are bilingual, followed by your work history.</p>
<p>Now, in your work history, I personally use bullet points of my daily tasks, followed by my most important contributions to the project.</p>
<p>After your work history, I list any open source projects I have developed or been on the development team of. Again I bullet point what I did at those open source projects.</p>
<p>Finally, the file name of your resume is important also. I always save mine in the format <code>My Name - Position Applying</code> For so say I'm applying for a Full Stack Position, I save my resume as <code>Shawn Crigger - Full Stack Developer.pdf</code> and since a lot of companies want a Microsoft Word Copy, I also save it in word format too.</p>
<p>For work history, I only include jobs related to the job I am applying for, if you are applying to a Full Stack Developer job, don't include the time you worked at the Bagel Factory, or the time you were an HVAC Service Tech.</p>
]]></content:encoded></item><item><title><![CDATA[Developer Tools to make your life easier]]></title><description><![CDATA[As developers, we use a lot of different tools, and new ones are constantly coming out. I'm going to list out some of the tools I use and services I use to get my job done easier.
Applications

Notion Notion is one of the best tools I've found for pr...]]></description><link>https://blog.shawncrigger.com/developer-tools-to-make-your-life-easier</link><guid isPermaLink="true">https://blog.shawncrigger.com/developer-tools-to-make-your-life-easier</guid><category><![CDATA[services]]></category><category><![CDATA[Applications]]></category><category><![CDATA[Developer Tools]]></category><category><![CDATA[dev tools]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sat, 10 Apr 2021 18:08:41 GMT</pubDate><content:encoded><![CDATA[<p>As developers, we use a lot of different tools, and new ones are constantly coming out. I'm going to list out some of the tools I use and services I use to get my job done easier.</p>
<h2 id="applications">Applications</h2>
<ol>
<li><a target="_blank" href="https://notion.so">Notion</a> Notion is one of the best tools I've found for project management, it allows you to create/import Task Lists, Wiki's, Product Road Maps, Meeting Notes, pretty much anything. And it also allows you to create your own templates that you can reuse or share. I've seen a few products host their documentation site's from their Notion notebooks.  </li>
<li><a target="_blank" href="https://macdown.uranusjr.com/">MacDown</a> I write a lot of my HTML copy in Markdown and Export it out of MacDown, it produces clean code that is easy to style.</li>
<li><a target="_blank" href="https://a.paddle.com/v2/click/103161/126730?link=2106">Tinkerwell</a> Tinkerwell allows you to write PHP code and test it while you write it. For testing quick ideas and things like that it is awesome.</li>
<li><a target="_blank" href="https://a.paddle.com/v2/click/49831/126730?link=1947">Sizzy Browser</a> A new browser designed for Responsive Web Design, it shows you what your site looks like in a number of resolutions at the same time.</li>
</ol>
<h2 id="services">Services</h2>
<ol>
<li><a target="_blank" href="https://calendly.com/shawncrigger">Calendly</a> Provides a service to book meetings and phone calls while checking for conflicts in your calendar.  I use the free tier which works fine for my needs. </li>
<li><a target="_blank" href="https://www.zoho.com/crm/">ZohoCRM</a> I personally keep all my leads in a CRM, Zoho works for my needs and it has a lot of other modules that can be integrated together to provide all the services you need. </li>
<li><a target="_blank" href="https://caniuse.com">CanIUse</a> I always look up what browsers support mostly what JavaScript functions I am about to use, a lot of older browsers do not support the newer features so I like to make sure everything I write is going to work in the browsers I support.</li>
<li><a target="_blank" href="https://remove.bg/">RemoveBG</a> A quick service that does a wonderful job of removing the background from most images, I personally find it faster to remove the background using this service than opening Photoshop or another Image Editor and doing it.</li>
</ol>
<p>There is a few of the newer applications and services that I use to do my job, I'll revise this post later when I think of some more that I use fairly often.</p>
<div class="hn-embed-widget" id="coffee"></div>]]></content:encoded></item><item><title><![CDATA[Product Review of Subscription-Based Dog Foods]]></title><description><![CDATA[I normally write about coding and servers, but today I'd like to write about something else so, over the last few months, I've ordered 3 different dog food's from popular subscription-based companies promising human-grade food that is good for the do...]]></description><link>https://blog.shawncrigger.com/product-review-of-subscription-based-dog-foods</link><guid isPermaLink="true">https://blog.shawncrigger.com/product-review-of-subscription-based-dog-foods</guid><category><![CDATA[product]]></category><category><![CDATA[review]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sun, 04 Apr 2021 20:08:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617566897027/vTxpMtx3l.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I normally write about coding and servers, but today I'd like to write about something else so, over the last few months, I've ordered 3 different dog food's from popular subscription-based companies promising human-grade food that is good for the dog. I love my dog and don't mind spending $100 bucks a month to supplement the food I make for her already.</p>
<p>So, the 3 companies I've ordered from our <a target="_blank" href="myollie.com">MyOllie</a>, <a target="_blank" href="https://www.thefarmersdog.com/">The Farmers Dog</a> and finally <a target="_blank" href="https://www.nomnomnow.com/">Nom Nom Now</a>.</p>
<p>Each of these products is subscription-based and cost between 70-150 a month, and I'm going to review them in the order of what I consider the best to the worst.</p>
<h2 id="myollie">MyOllie</h2>
<p>I ordered MyOllie's and was impressed with the packing material, and the shipping speed but more than anything I was impressed mostly with the difference it made in my dog's Fur and Energy Level.  The only downside I have to MyOllie's is they only allow ordering 2 months at a time, and with just 25% of your dog's daily calories, it costs $150 for 2 months of food. I kept MyOllie's subscription for about 4 months because in the first week I noticed a spot of fur that she chewed out 3yrs ago had grown back in and her energy level had spiked to puppy-like levels. I hated that due to the money situation I had to cancel my subscription and plan to resubscribe as soon as possible. Also, MyOllie's sent their food in easy to open and easy to serve packages and even provided a very nice container to store your open packages and a serving spoon to correctly portion your servings with the first order. Definitely a plus, I still use both the container and the spoon daily.</p>
<h2 id="nom-nom-now">Nom Nom Now</h2>
<p>Nom Nom Now's dog food also was packed fairly well, almost as good as MyOllie's and the shipping speed wasn't too bad, but it looked like they had just dumped a bunch of canned vegetables and meats into the packages, Nom Nom Now's packaging was almost as good as MyOllie's where you can open 1 package and easily portion out the food without making a giant mess. But the price was more than MyOllie's and my dog didn't like the food as well, I also really haven't noticed the energy boost or the fur quality that I did with MyOllie's</p>
<h2 id="the-farmers-dog">The Farmers Dog</h2>
<p>The Farmer's Dog shipping was ridiculously slow, they said it would arrive 7 days before it was even shipped, they included a cardboard takeout box to put your open packages in which I broke the first time I tried using it. Also instead of providing single packages that you could easily open and portion out, they put an entire week's worth of food in 1 package that I had to cut open with scissors just to portion out. My dog did not like it at all and I still have most of the packages in my freezer. </p>
<h2 id="my-thoughts-on-the-matter">My thoughts on the matter</h2>
<ol>
<li><p>MyOllie's is my favorite but you have to purchase 2 months worth at a time, if you have the freezer space for all that great, it fills ours big time, but I like it the best for my dog, her coat is fuller, she sheds less, and honestly she has grown hair where she has never had hair before or it grew back where she had chewed out a piece of fur on her tail before I got her over 5yrs ago, in less then a month that small patch had grown back!</p>
</li>
<li><p>My second choice is NomNomNom their food was easier to work with on the subscription, and you could tell what each piece of food was as it was chopped but not pureed together.</p>
</li>
<li><p>Don't bother with farmers dog your getting ripped off.</p>
</li>
</ol>
<h2 id="summary">Summary</h2>
<p>Hopefully, this will help someone else who loves their dog and finds the idea of feeding them kibble disgusting. With all the dogs being poisoned by dog food makers lately I find it sickening to even think of feeding food that is not human quality to my dog.</p>
<p>I personally make a base food which is basically cooked chicken/pork or deer meat in rice. I make a week's worth at a time which takes very little effort with an air fryer and a rice cooker. If anybody is interested in the recipe I am using for my base food just comment below and I will make a post about it. </p>
<div class="hn-embed-widget" id="coffee"></div>]]></content:encoded></item><item><title><![CDATA[Tips on Building a Hackintosh]]></title><description><![CDATA[Warning: I wrote this article in 2011 when you could buy Snow Leopard at any computer store, I'm sure there are better ways to do it now but tonymacx86.com is the place to go to learn more about this.
I have been building a Hackintosh for the last fe...]]></description><link>https://blog.shawncrigger.com/tips-on-building-a-hackintosh</link><guid isPermaLink="true">https://blog.shawncrigger.com/tips-on-building-a-hackintosh</guid><category><![CDATA[Apple]]></category><category><![CDATA[Computer Science]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sun, 01 Mar 2015 05:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Warning: I wrote this article in 2011 when you could buy Snow Leopard at any computer store, I'm sure there are better ways to do it now but <a target="_blank" href="http://tonymacx86.com">tonymacx86.com</a> is the place to go to learn more about this.</p>
<p>I have been building a Hackintosh for the last few months now to use as my design computer,  In the process of building this computer, I have run into a lot of issues.  First, let me say the folks at
<a target="_blank" href="http://tonymacx86.com">tonymacx86.com</a> have been extremely helpful and have made this process fairly simple compared to the old methods of doing this.  Since there are already excellent tutorials on the actual builds,  I am only gonna give some tips on what to do when you break it and trust me you will break it many times before you have a fully running Mac.</p>
<ul>
<li>First, if you do not understand Terminal, then I suggest you learn some terminal commands.</li>
<li>Second I do not support piracy of Software so just buy the $30 Snow Leopard retail disk. If you can't part with $30 bucks you can't afford to build this system anyway.</li>
</ul>
<h2 id="ok-on-to-the-tips-i-have-learned-the-hard-way">Ok, on to the tips I have learned the hard way.</h2>
<p>You should have a retail copy of Snow Leopard and a Disk burned with iBoot already made.  These are your main recovery tools.</p>
<p>Tonymac has created an excellent tool called Multibeast, which will make enabling various things like Networking, Sound, Video, etc... As soon as you have a boot-able Snow Leopard install, I suggest you take an external Hard Drive and use it as a Time Machine.</p>
<p>The Time Machine restore does not always work, so any-time you make changes with Multibeast, you need to back up 2 directories of your file system so that if your changes did not work you can restore them back to a working copy.</p>
<p>First, open the terminal and type the following commands.</p>
<pre><code class="lang-bash">
    sudo su
    <span class="hljs-built_in">cd</span> /
    mkdir Backup
    <span class="hljs-built_in">cd</span> Backup
    cp -R /Extra ./
    cp -R /System/Library/Extensions ./

    <span class="hljs-built_in">exit</span>
</code></pre>
<p>Ok that will Back your Extra directory and all your Kext files ( Kernal Extensions )</p>
<p>I suggest working slowly and adding Kext files very slowly,  Work on Sound, reboot, then Networking, reboot, etc, etc.</p>
<p>I also suggest before installing all your applications that you make sure your system is running completely or you will probably be re-installing your applications eventually.</p>
<p>After making changes and rebooting, if you get a Kernel Panic then first try rebooting with the iBoot CD first.  You can always try to use boot flags such as</p>
<ul>
<li>CMD-X =&gt; Safe Mode</li>
<li>CMD-f =&gt; Clear System Cache Folder</li>
<li>CMD-v =&gt; Verbose Mode</li>
<li>CMD-s =&gt; Single User Mode CLI</li>
</ul>
<p>If you can not reboot with the iBoot CD then you will have to Reboot using the Snow Leopard install CD, Open Disk Utility, and Mount your Hard Drive, then Open Terminal and type these commands to restore your working Kext's</p>
<pre><code class="lang-bash">
    sudo su

    rm -Rf /Extra/
    rm -Rf /System/Library/Extensions/

    cp -R /Backup/Extra/ /Extra/
    cp -R /Backup/Extensions /System/Library/Extensions

    <span class="hljs-built_in">exit</span>
</code></pre>
<p>After running those commands, close the terminal and open Disk Utility again.</p>
<p>Select the correct hard drive and Check Verify Permissions, then Repair Permissions.</p>
<p>Once you have completed these steps,
reboot the system and use the "-f" boot flag to Rebuild the Cache directory.</p>
<p>If all of this went over your head, you might want to just buy a Mac,  building a Custom Mac is not easy, but if you can build one yourself it is very satisfying.  The one thing I've noticed with building your own Custom Mac or Hackintosh is you need to be motivated by the challenge and be very persistent,  I have broken and fixed my Hackintosh ton's of times, and it took me 3 months just to get everything to work properly.  I'm still running Snow Leopard on mine as I didn't really like its features on my iMac.  Some people might like them, I just didn't really like them myself.</p>
<p>Just a minor update: It's July 28, 2012, and I have been running this Hackintosh non-stop straight coding daily, nightly anytime and it's the best CPU I've ever owned.  But I learned a lot from building it</p>
<ul>
<li><strong>Patience</strong> is not a funky virtue, it's a state of zen without it do <strong>NOT</strong> try this.</li>
<li>This will piss you off, again and again, but keep hacking and the rewards are plenty</li>
</ul>
<div class="hn-embed-widget" id="coffee"></div>]]></content:encoded></item><item><title><![CDATA[BandWidth Explained]]></title><description><![CDATA[BandWidth Explained
Most hosting companies offer a variety of bandwidth options in their plans. So exactly what is bandwidth as it relates to web hosting? Put simply, bandwidth is the amount of traffic that is allowed to occur between your website an...]]></description><link>https://blog.shawncrigger.com/bandwidth-explained</link><guid isPermaLink="true">https://blog.shawncrigger.com/bandwidth-explained</guid><category><![CDATA[Web Development]]></category><category><![CDATA[hosting]]></category><category><![CDATA[Web Hosting]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Wed, 28 Jan 2015 05:00:00 GMT</pubDate><content:encoded><![CDATA[<h1 id="bandwidth-explained">BandWidth Explained</h1>
<p>Most hosting companies offer a variety of bandwidth options in their plans. So exactly what is bandwidth as it relates to web hosting? Put simply, bandwidth is the amount of traffic that is allowed to occur between your website and the rest of the internet. The amount of bandwidth a hosting company can provide is determined by their network connections, both internal to their data center and external to the public internet.</p>
<h2 id="network-connectivity">Network Connectivity</h2>
<p>The internet, in the most simple of terms, is a group of millions of computers connected by networks. These connections within the internet can be large or small depending upon the cabling and equipment that is used at a particular internet location. It is the size of each network connection that determines how much bandwidth is available. For example, if you use a DSL connection to connect to the internet, you have 1.54 Megabits (Mb) of bandwidth. Bandwidth, therefore, is measured in bits (a single 0 or 1). Bits are grouped in bytes which form words, text, and other information that is transferred between your computer and the internet.</p>
<p>If you have a DSL connection to the internet, you have dedicated bandwidth between your computer and your internet provider. But your internet provider may have thousands of DSL connections to their location. All of these connections aggregate at your internet provider, who then has their own dedicated connection to the internet (or multiple connections) which is much larger than your single connection. They must have enough bandwidth to serve your computing needs as well as all of their other customers. So while you have a 1.54Mb connection to your internet provider, your internet provider may have a 255Mb connection to the internet so it can accommodate your needs and up to 166 other users (255/1.54).</p>
<h2 id="traffic">Traffic</h2>
<p>A very simple analogy to use to understand bandwidth and traffic is to think of highways and cars. Bandwidth is the number of lanes on the highway and traffic is the number of cars on the highway. If you are the only car on a highway, you can travel very quickly. If you are stuck in the middle of rush hour, you may travel very slowly since all of the lanes are being used.</p>
<p>Traffic is simply the number of bits that are transferred on network connections. It is easiest to understand traffic using examples. One Gigabyte is 2 to the 30th power (1,073,741,824) bytes. One gigabyte is equal to 1,024 megabytes. To put this in perspective, it takes one byte to store one character. Imagine 100 file cabinets in a building, each of these cabinets holds 1000 folders. Each folder has 100 papers. Each paper contains 100 characters - A GB is all the characters in the building. An MP3 song is about 4MB, the same song in WAV format is about 40MB, a full-length movie can be 800MB to 1000MB (1000MB = 1GB).</p>
<p>If you were to transfer this MP3 song from a website to your computer, you would create 4MB of traffic between the website you are downloading from and your computer. Depending upon the network connection between the website and the internet, the transfer may occur very quickly, or it could take time if other people are also downloading files at the same time. If, for example, the website you download from has a 10MB connection to the internet, and you are the only person accessing that website to download your MP3, your 4MB file will be the only traffic on that website. However, if three people are all downloading that same MP3 at the same time, 12MB (3 x 4MB) of traffic has been created. Because in this example, the host only has 10MB of bandwidth, someone will have to wait. The network equipment at the hosting company will cycle through each person downloading the file and transfer a small portion at a time so each person's file transfer can take place, but the transfer for everyone downloading the file will be slower. If 100 people all came to the site and downloaded the MP3 at the same time, the transfers would be extremely slow. If the host wanted to decrease the time it took to download files simultaneously, it could increase the bandwidth of their internet connection (at a cost, due to upgrading equipment).</p>
<h2 id="hosting-bandwidth">Hosting Bandwidth</h2>
<p>In the example above, we discussed traffic in terms of downloading an MP3 file. However, each time you visit a web site, you are creating traffic, because, in order to view that web page on your computer, the web page is first downloaded to your computer (between the web site and you) which is then displayed using your browser software (Internet Explorer, Netscape, etc.). The page itself is simply a file that creates traffic just like the MP3 file in the example above (however, a web page is usually much smaller than a music file).</p>
<p>A web page may be very small or large depending upon the amount of text and the number and quality of images integrated within the web page. For example, the home page for CNN.com is about 200KB (200 Kilobytes = 200,000 bytes = 1,600,000 bits). This is typically large for a web page. In comparison, Yahoo's home page is about 70KB.</p>
<h2 id="how-much-bandwidth-is-enough">How Much Bandwidth Is Enough?</h2>
<p>It depends (don't you hate that answer). But in truth, it does. Since bandwidth is a significant determinant of hosting plan prices, you should take time to determine just how much is right for you. Almost all hosting plans have bandwidth requirements measured in months, so you need to estimate the amount of bandwidth that will be required by your site on a monthly basis</p>
<p>If you do not intend to provide file download capability from your site, the formula for calculating bandwidth is fairly straightforward:</p>
<p>Average Daily Visitors x Average Page Views x Average Page Size x 31 x Fudge Factor</p>
<p>If you intend to allow people to download files from your site, your bandwidth calculation should be:</p>
<p>[(Average Daily Visitors x Average Page Views x Average Page Size) +
(Average Daily File Downloads x Average File Size)] x 31 x Fudge Factor</p>
<h3 id="let-us-examine-each-item-in-the-formula">Let us examine each item in the formula:</h3>
<p>Average Daily Visitors - The number of people you expect to visit your site, on average, each day. Depending upon how you market your site, this number could be from 1 to 1,000,000.</p>
<p>Average Page Views - On average, the number of web pages you expect a person to view. If you have 50 web pages on your website, an average person may only view 5 of those pages each time they visit.</p>
<p>Average Page Size - The average size of your web pages, in Kilobytes (KB). If you have already designed your site, you can calculate this directly.</p>
<p>Average Daily File Downloads - The number of downloads you expect to occur on your site. This is a function of the number of visitors and how many times a visitor downloads a file, on average, each day.</p>
<p>Average File Size - Average file size of files that are downloadable from your site. Similar to your web pages, if you already know which files can be downloaded, you can calculate this directly.</p>
<p>Fudge Factor - A number greater than 1. Using 1.5 would be safe, which assumes that your estimate is off by 50%. However, if you were very unsure, you could use 2 or 3 to ensure that your bandwidth requirements are more than met.</p>
<p>Usually, hosting plans offer bandwidth in terms of Gigabytes (GB) per month. This is why our formula takes daily averages and multiplies them by 31.</p>
<h2 id="summary">Summary</h2>
<p>Most personal or small business sites will not need more than 1GB of bandwidth per month. If you have a website that is composed of static web pages and you expect little traffic to your site on a daily basis, go with a low bandwidth plan. If you go over the amount of bandwidth allocated in your plan, your hosting company could charge you over-usage fees, so if you think the traffic to your site will be significant, you may want to go through the calculations above to estimate the amount of bandwidth required in a hosting plan.</p>
]]></content:encoded></item><item><title><![CDATA[How to Find Exactly What You Are Looking For in Google]]></title><description><![CDATA[Put one of these strings in the Google search box:
Applications
  "parent directory " /appz/ -xxx -html -htm -php -shtml -opendivx -md5 -md5sums
DVD Ripped Movies
  "parent directory " DVDRip -xxx -html -htm -php -shtml -opendivx -md5 -md5sums
xVid M...]]></description><link>https://blog.shawncrigger.com/how-to-find-exactly-what-you-are-looking-for-in-google</link><guid isPermaLink="true">https://blog.shawncrigger.com/how-to-find-exactly-what-you-are-looking-for-in-google</guid><category><![CDATA[Google]]></category><category><![CDATA[research]]></category><category><![CDATA[hack]]></category><category><![CDATA[tricks]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Fri, 16 Jan 2015 05:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Put one of these strings in the Google search box:</p>
<p><strong>Applications</strong></p>
<p>  <code>"parent directory " /appz/ -xxx -html -htm -php -shtml -opendivx -md5 -md5sums</code></p>
<p><strong>DVD Ripped Movies</strong></p>
<p>  <code>"parent directory " DVDRip -xxx -html -htm -php -shtml -opendivx -md5 -md5sums</code></p>
<p><strong>xVid Movies</strong></p>
<p>  <code>"parent directory "Xvid -xxx -html -htm -php -shtml -opendivx -md5 -md5sums</code></p>
<p><strong>Games</strong></p>
<p>  <code>"parent directory " Gamez -xxx -html -htm -php -shtml -opendivx -md5 -md5sums</code></p>
<p><strong>Music in MP3 Format</strong></p>
<p>  <code>"parent directory " MP3 -xxx -html -htm -php -shtml -opendivx -md5 -md5sums</code></p>
<p><strong>Specific Song, Album, etc</strong></p>
<p>  <code>"parent directory " Name of Singer or album -xxx -html -htm -php -shtml -opendivx -md5 -md5sums</code></p>
<p><strong>Notice that I am only changing the word after the parent directory, change it to what you want and you will get a lot of stuff.</strong></p>
<h2 id="one-more-trick">One More Trick</h2>
<p>put this string in google search:</p>
<p><code>?intitle:index.of? mp3</code></p>
<p>You only need to add the name of the song/artist/singer.</p>
<p>Example: <code>?intitle:index.of? mp3 dropkickmurphy</code></p>
]]></content:encoded></item><item><title><![CDATA[Extending Bonfires User system or EAV Users and PHP Development]]></title><description><![CDATA[Bonfire's base user system is based on an Entity-Attribute-Value based system where you store the user's meta in a separate table, very similar to how WordPress is setup.
This has a lot of benefits but can also cause a lot of confusion when it comes ...]]></description><link>https://blog.shawncrigger.com/extending-bonfires-user-system-or-eav-users-and-php-development</link><guid isPermaLink="true">https://blog.shawncrigger.com/extending-bonfires-user-system-or-eav-users-and-php-development</guid><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Fri, 21 Sep 2012 20:39:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617802385138/cbV2cuWk4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Bonfire's base user system is based on an <strong>Entity-Attribute-Value</strong> based system where you store the user's meta in a separate table, very similar to how WordPress is setup.</p>
<p>This has a lot of benefits but can also cause a lot of confusion when it comes down to extending the user system,  as with extending anything you want the end product to be maintainable but still be powerful and do everything you needed.</p>
<p>Bonfire's default user system is set up with a main user table and a metatable, kinda something like this</p>
<p><strong>User Table</strong></p>
<table>
   <thead>
      <th>UserID</th>
      <th>Name</th>
      <th>Email</th>
      <th>Password</th>
   </thead>
   <tbody>
   <tr>
      <td>1</td>
      <td>shawnc</td>
      <td>shawnc@email.com</td>
      <td>password</td>
   </tr>
   </tbody>
</table>


<p><strong>Meta Table</strong></p>
<table>
   <thead>
      <th>UserID</th>
      <th>Key</th>
      <th>Value</th>
   </thead>
   <tbody>
   <tr>
      <td>1</td>
      <td>first_name</td>
      <td>shawn</td>
   </tr>
   <tr>
      <td>2</td>
      <td>last_name</td>
      <td>crigger</td>
   </tr>
   </tbody>
</table>

<p>So basically the meta values are stored in a separate table and added to the current_user object as needed with <code>$this-&gt;user_model-&gt;load_meta</code>, this does a good job for
most systems I'll develop but every so often a piece of the user data that isn't important enough to alter the entire system but I needed to be able to display this data like it was in the same table, so instead of 2 tables it would look like</p>
<p><strong>Joined table result</strong></p>
<p></p><table>
   <thead>
      <th>UserID</th>
      <th>Name</th>
      <th>Email</th>
      <th>Password</th>
      <th>first_name</th>
      <th>last_name</th>
   </thead>
   <tbody>
   <tr>
      <td>1</td>
      <td>shawnc</td>
      <td>shawnc@email.com</td>
      <td>password</td>
      <td>shawn</td>
      <td>crigger</td>
   </tr>
   </tbody>
</table>
To generate the joined table as above I personally found joining the tables worked very well and did not cause to much server load, any suggestions will be taken if you have a different method but anyway to join the tables what I personally did was add a new method to the user model something like this.<p></p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-comment">/**
     * Loads user and meta data in one query.
     *
     * <span class="hljs-doctag">@param</span>  int  $user_id      user_id or blank for all.
     * <span class="hljs-doctag">@param</span>  bool $show_deleted [show deleted users]
     *
     * <span class="hljs-doctag">@return</span> mixed
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">load_user_meta</span>(<span class="hljs-params">$user_id = <span class="hljs-number">0</span>, $show_deleted == <span class="hljs-literal">FALSE</span></span>)
    </span>{

        <span class="hljs-keyword">$this</span>-&gt;db-&gt;select(<span class="hljs-string">'users.*, roles.role_name'</span>);

        <span class="hljs-keyword">$this</span>-&gt;db-&gt;select(<span class="hljs-string">'m1.meta_value AS first_name'</span>);

        <span class="hljs-comment">// Just keep adding these and alias as you need!</span>
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;select(<span class="hljs-string">'m2.meta_value AS last_name'</span>);

        <span class="hljs-comment">//</span>
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;select(<span class="hljs-string">'m2.meta_value AS alias'</span>);


        <span class="hljs-keyword">$this</span>-&gt;db-&gt;join(<span class="hljs-string">'user_meta'</span>, <span class="hljs-string">'user_meta.user_id = users.id'</span>, <span class="hljs-string">'left'</span>);

        <span class="hljs-comment">// Here is the magic baby!</span>
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;join(<span class="hljs-string">'user_meta as m1'</span>, <span class="hljs-string">"m1.user_id = users.id AND m1.meta_key = 'first_name' "</span>, <span class="hljs-string">'left'</span>);


        <span class="hljs-keyword">$this</span>-&gt;db-&gt;join(<span class="hljs-string">'user_meta as m2'</span>, <span class="hljs-string">"m2.user_id = users.id AND m2.meta_key = 'last_name' "</span>, <span class="hljs-string">'left'</span>);

        <span class="hljs-comment">// ! Change me</span>
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;join(<span class="hljs-string">'user_meta as m2'</span>, <span class="hljs-string">"m2.user_id = users.id AND m2.meta_key = 'alias' "</span>, <span class="hljs-string">'left'</span>);

        <span class="hljs-keyword">if</span> ($show_deleted === <span class="hljs-literal">FALSE</span>)
        {
            <span class="hljs-keyword">$this</span>-&gt;db-&gt;where(<span class="hljs-string">'users.deleted'</span>, <span class="hljs-number">0</span>);
        }

        <span class="hljs-keyword">$this</span>-&gt;db-&gt;where(<span class="hljs-string">'users.banned ='</span>, <span class="hljs-number">0</span>);
        <span class="hljs-keyword">$this</span>-&gt;db-&gt;group_by(<span class="hljs-string">'users.id'</span>);

        <span class="hljs-keyword">if</span> (is_numeric($user_id) &amp;&amp; $user_id &gt; <span class="hljs-number">0</span>)
        {
            <span class="hljs-keyword">return</span> <span class="hljs-built_in">parent</span>::find($user_id);
        }

        <span class="hljs-keyword">return</span> <span class="hljs-built_in">parent</span>::find_all();
    }
<span class="hljs-meta">?&gt;</span>
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Sublime Text Editor Snippets for Bonfire Released]]></title><description><![CDATA[For those that use Bonfire and Sublime Text Editor, I have released my collection Snippet's collection of just Bonfire snippets.  Since there is already a CodeIgniter Snippet package out there, I'm only including Bonfire specific snippet's in the Pac...]]></description><link>https://blog.shawncrigger.com/sublime-text-editor-snippets-for-bonfire-released</link><guid isPermaLink="true">https://blog.shawncrigger.com/sublime-text-editor-snippets-for-bonfire-released</guid><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Sun, 02 Sep 2012 16:48:00 GMT</pubDate><content:encoded><![CDATA[<p>For those that use Bonfire and Sublime Text Editor, I have released my collection <a target="_blank" href="https://github.com/svizion/bonfire-snippets"><strong>Snippet's</strong></a> collection of just Bonfire snippets.  Since there is already a CodeIgniter Snippet package out there, I'm only including Bonfire specific snippet's in the Package.  </p>
<p>Currently, you have to install the packages manually with git</p>
<h2 id="installation-instructions">Installation Instructions</h2>
<pre><code class="lang-bash">    git <span class="hljs-built_in">clone</span> git@github.com:svizion/bonfire-snippets.git ~/Library/Application\ Support/Sublime\ Text\ 2/Packages/bonfire-snippets
</code></pre>
<pre><code class="lang-bash">
    git <span class="hljs-built_in">clone</span> git@github.com:svizion/bonfire-snippets.git ~/.config/sublime-text-2/Packages/bonfire-snippets
</code></pre>
<h2 id="current-snippets">Current Snippets</h2>
<p>These are the current snippets I've included, ordered in some fashion that sorta made sense.</p>
<p>Update: I just included all my Model Snippets and my Debugging Snippets related to Bonfire.</p>
<h3 id="template-and-assets">Template and Assets</h3>
<table>
    <thead>
        <th>Tab Trigger</th><th>Output</th>
    </thead>
    <tbody>
    <tr>
        <td>set_data</td>
        <td>Template::set();</td>
    </tr>
    <tr>
        <td>render</td>
        <td>Template::render();</td>
    </tr>
    <tr>
        <td>toolbar_title</td>
        <td>Template::set('toolbar_title', '');</td>
    </tr>
    <tr>
        <td>clear_cache</td>
        <td>Assets::clear_cache();</td>
    </tr>
    <tr>
        <td>add_js</td>
        <td>Assets::add_js();</td>
    </tr>
    <tr>
        <td>add_css</td>
        <td>Assets::add_css();</td>
    </tr>
    <tr>
        <td>add_mod_js</td>
        <td>Assets::add_module_js();</td>
    </tr>
    <tr>
        <td>add_mod_css</td>
        <td>Assets::add_module_css();</td>
    </tr>
    </tbody>
</table>

<h3 id="various-randoms">Various Randoms</h3>
<table>
    <thead>
        <th>Tab Trigger</th><th>Output</th>
    </thead>
    <tbody>
    <tr>
        <td>cur_user</td>
        <td>$this-&gt;current_user-&gt;?;</td>
    </tr><br />    <tr>
        <td>bf_model</td>
        <td>Generates Bonfire Model Skeleton Structure</td>
    </tr><br />    <tr>
        <td>auth_controller</td>
        <td>Generates Authenticated_Controller Skeleton Structure</td>
    </tr>
    <tr>
        <td>haz_perm</td>
        <td>PHP If Wrapper for has_permission check</td></tr>
    <br />    <tr>
        <td>restrict</td>
        <td>$this-&gt;auth-&gt;restrict();</td>
    </tr>
    <tr>
        <td>log_activity</td>
        <td>$this-&gt;activity_model-&gt;log_activity($this-&gt;current_user-&gt;user_id(), '', 'module');</td>
    </tr>
    <tr>
        <td>settings_set</td>
        <td>$this-&gt;settings_lib-&gt;set();</td>
    </tr>
    <tr>
        <td>settings_delete</td>
        <td>$this-&gt;settings_lib-&gt;delete();</td>
    </tr>
    </tbody>
</table>

<h3 id="bonfire-module-snippets">Bonfire Module Snippets</h3>
<table>
    <thead>
        <th>Tab Trigger</th><th>Output</th>
    </thead>
    <tbody>
    <tr>
        <td>find</td>
        <td>$records = $this-&gt;$1_model-&gt;find($2);</td>
    </tr>
    <tr>
        <td>find_by</td>
        <td>$records = $this-&gt;$1_model-&gt;find_by('$1', '$2');</td>
    </tr>
    <tr>
        <td>find_all_by</td>
        <td>$records = $this-&gt;$1_model-&gt;find_all_by('$1', '$2');</td>
    </tr>
    <tr>
        <td>insert</td>
        <td>$id = $this-&gt;$1_model-&gt;insert($2);</td>
    </tr>
    <tr>
        <td>update</td>
        <td>$result = $this-&gt;$1_model-&gt;update($2, $data);</td>
    </tr>
    <tr>
        <td>update_where</td>
        <td>$result = $this-&gt;$1_model-&gt;update_where('$2', '$3', ${4:$data});</td>
    </tr>
    <tr>
        <td>delete</td>
        <td>$result = $this-&gt;$1_model-&gt;delete($2);</td>
    </tr>
    <tr>
        <td>delete_where</td>
        <td>$result = $this-&gt;$1_model-&gt;delete_where('$2', '$3');</td>
    </tr>

    <tr>
        <td>count_by</td>
        <td>$num = $this-&gt;$1_model-&gt;count_by('$2', '$3');</td>
    </tr>
    </tbody>
</table>

<h3 id="debugging-snippets-i-use-some-are-not-fully-bonfire-related">Debugging snippets I use some are not fully Bonfire related.</h3>
<table>
    <thead>
        <th>Tab Trigger</th><th>Output</th>
    </thead>
    <tbody>
    <tr>
        <td>cplog</td>
        <td>ChromePhp::log($1);</td>
    </tr>
    <tr>
        <td>cperror</td>
        <td>ChromePhp::error($1);</td>
    </tr>
    <tr>
        <td>console</td>
        <td>Console::log($1);</td>
    </tr><br />    <tr>
        <td>enable_profiler</td>
        <td>$this-&gt;output-&gt;enable_profiler(FALSE);</td>
    </tr>
    <tr>
        <td>bflog</td>
        <td>parent::logit($1, '${2:error]');</td>
    </tr><br />    <tr>
        <td>log</td>
        <td>logit($1, '${2:error]');</td>
    </tr>
    <tr>
        <td>dad</td>
        <td>$dump()die;</td>
    </tr>

    </tbody>
</table>


<p>If you have any snippets you use for Bonfire please fork and add them.  </p>
]]></content:encoded></item><item><title><![CDATA[Over-riding CodeIgniter Bonfire Core Modules and Making it easy to update later]]></title><description><![CDATA[One thing that I require a lot in building Bonfire based Websites is to modify mostly views in some of the Core Modules, namely the User Module since that has Public-facing View files, and not all my Websites are built using Twitter Bootstrap's frame...]]></description><link>https://blog.shawncrigger.com/over-riding-codeigniter-bonfire-core-modules-and-making-it-easy-to-update-later-1</link><guid isPermaLink="true">https://blog.shawncrigger.com/over-riding-codeigniter-bonfire-core-modules-and-making-it-easy-to-update-later-1</guid><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Fri, 31 Aug 2012 12:41:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617802479511/jeGnHtgK9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One thing that I require a lot in building Bonfire based Websites is to modify mostly views in some of the Core Modules, namely the User Module since that has Public-facing View files, and not all my Websites are built using Twitter Bootstrap's framework depending on the Front-end Developer I'm working with on the project with.</p>
<p>This is a really simple trick I learned not too long ago but makes upgrading very easy later on which with a constantly changing software like <a target="_blank" href="http://cibonfire.com">Bonfire</a> then Over-riding my Core modules and keeping track of the changes gets hard namely when you build as many websites's as I do in a year.  This is a very very very simple trick and you'll probably have a Facepalm Moment for not thinking of this yourself after seeing what it involves!</p>
<p>Basically, modules in Bonfire exist in 2 locations</p>
<ul>
<li>bonfire/application/core_modules</li>
<li><p>bonfire/modules</p>
<p>Which the Core Bonfire-related modules live in core_modules and custom modules belong in the modules directory.  So the simple trick here is just to copy your core_module into the modules directory like this.</p>
</li>
</ul>
<pre><code class="lang-bash">     cp -rfv /bonfire/application/core_modules/users /bonfire/modules
</code></pre>
<p>Or you can drag and drop it using Finder or whatever you do to copy a folder to a new location.  So now you have 2 copies of the same module, you can actually delete the one your overriding but I prefer to just leave it there myself.</p>
<p>So what have we learned here, the order modules are loaded is first "core_modules", then "modules" so anything in the modules directory will over-ride the "core_modules" directory.  Simple enough?</p>
<p>Hope this helps someone.  Enjoy and Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Adding ChromePhp to CodeIgniter Bonfires log methods]]></title><description><![CDATA[Earlier this year an extension and PHP class were released that allowed logging PHP messages to Chrome's Console, similar to FirePHP for FireBug but well for Google's Chrome Browser instead yay!.  Anyway, I've grown quite fond of both Chrome and the ...]]></description><link>https://blog.shawncrigger.com/adding-chromephp-to-codeigniter-bonfires-log-methods</link><guid isPermaLink="true">https://blog.shawncrigger.com/adding-chromephp-to-codeigniter-bonfires-log-methods</guid><category><![CDATA[Google Chrome]]></category><category><![CDATA[chrome extension]]></category><category><![CDATA[PHP]]></category><category><![CDATA[debugging]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Thu, 30 Aug 2012 04:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617569163538/Wnd5y3YgF.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Earlier this year an extension and PHP class were released that allowed logging PHP messages to Chrome's Console, similar to FirePHP for FireBug but well for Google's Chrome Browser instead yay!.  Anyway, I've grown quite fond of both Chrome and the Console logging of my debug messages recently and decided maybe some of the other Bonfire users might find some use in this.</p>
<p>Basically, Bonfire has 2 helper methods called <strong>logit</strong> one as an application helper and one in the model, these handy helpers make a log entry in CodeIgniter's system log, and use the Console class already included in Bonfire to output any message.  The only problem with this is normally when you have an error the page doesn't finish rendering and the stock Bonfire Console library doesn't display any data since it's not rendered.  So I just made a few quick changes to the logit methods and added the helper.  And now I have better-debugging ability!</p>
<p>First, get the helper and the extension, my friend <a target="_blank" href="http://blog.marcomonteiro.net/post/28986094928/using-chromephp-with-codeigniter">Marco Monterio</a> has already explained on his blog how to install the extension and the helper, so check his blog out on installing the ChromePhp library to CodeIgniter.  Once you have it installed, then you can make these changes and you'll be debugging like a kingpin while your off getting your ChromePhp on, I'll gonna drink that beer you bought me :beer:</p>
<p>Ok, so we only need additions to 2 files and 2 methods, this is easy!  Let's start with MY_Model.  So open up <code>/bonfire/application/core/MY_Model.php</code>, do a quick search for "logit" and add the code I have below for ChromePhp</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-comment">/**
     * Logs an error to the Console (if loaded) and to the log files.
     *
     * <span class="hljs-doctag">@param</span> string $message The string to write to the logs.
     * <span class="hljs-doctag">@param</span> string $level   The log level, as per CI log_message method.
     *
     * <span class="hljs-doctag">@access</span> protected
     *
     * <span class="hljs-doctag">@return</span> mixed
     */</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logit</span>(<span class="hljs-params">$message=<span class="hljs-string">''</span>, $level=<span class="hljs-string">'debug'</span></span>)
    </span>{
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">empty</span>($message))
        {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">FALSE</span>;
        }

        <span class="hljs-keyword">if</span> (class_exists(<span class="hljs-string">'Console'</span>))
        {
            Console::log($message);
        }

        <span class="hljs-comment">// Just add from here</span>
        <span class="hljs-keyword">if</span> (class_exists(<span class="hljs-string">'ChromePhp'</span>))
        {
            <span class="hljs-keyword">if</span> ($level == <span class="hljs-string">'error'</span>)
            {
                ChromePhp::error($message);
            }
            <span class="hljs-keyword">else</span>
            {
                ChromePhp::log($message);
            }
        }
        <span class="hljs-comment">// Just to here.</span>

        log_message($level, $message);

    }<span class="hljs-comment">//end logit()</span>

    <span class="hljs-comment">//--------------------------------------------------------------------</span>
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>Ok so there's the Model changes, now open up <code>bonfire/application/helpers/application_helper.php</code> and once again find the "logit" function</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>
    <span class="hljs-comment">/**
     * Logs an error to the Console (if loaded) and to the log files.
     *
     * <span class="hljs-doctag">@param</span> $message string The string to write to the logs.
     * <span class="hljs-doctag">@param</span> $level string The log level, as per CI log_message method.
     *
     * <span class="hljs-doctag">@return</span> void
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logit</span>(<span class="hljs-params">$message=<span class="hljs-string">''</span>, $level=<span class="hljs-string">'debug'</span></span>)
    </span>{
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">empty</span>($message))
        {
            <span class="hljs-keyword">return</span>;
        }

        <span class="hljs-keyword">if</span> (class_exists(<span class="hljs-string">'Console'</span>))
        {
            Console::log($message);
        }

        <span class="hljs-keyword">if</span> (class_exists(<span class="hljs-string">'ChromePhp'</span>))
        {
            <span class="hljs-keyword">if</span> ($level == <span class="hljs-string">'error'</span>)
            {
                ChromePhp::error($message);
            }
            <span class="hljs-keyword">else</span>
            {
                ChromePhp::log($message);
            }
        }

        log_message($level, $message);
    }

    <span class="hljs-comment">//--------------------------------------------------------------------</span>
<span class="hljs-meta">?&gt;</span>
</code></pre>
<p>And there ya go, now every time logit is called, you can see what the message was inside of your Chrome Web Inspector Console just like you would a JavaScript console.log method would give.  Amazing stuff!</p>
<p>Cheers and Free beers again!</p>
]]></content:encoded></item><item><title><![CDATA[How to Replace the Hard Drive in an iMac8]]></title><description><![CDATA[I recently purchased a 2008 module iMac for design work. This machine only came with a 320GB hard drive which is just too small for my tastes.  Since I had a 1.5TB drive laying around doing nothing I decided to swap the 2 drives out.
The first step i...]]></description><link>https://blog.shawncrigger.com/how-to-replace-the-hard-drive-in-an-imac8</link><guid isPermaLink="true">https://blog.shawncrigger.com/how-to-replace-the-hard-drive-in-an-imac8</guid><category><![CDATA[Apple]]></category><category><![CDATA[hardware]]></category><dc:creator><![CDATA[Shawn Crigger]]></dc:creator><pubDate>Mon, 30 May 2011 04:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1617570093259/BOq--8Te4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I recently purchased a 2008 module iMac for design work. This machine only came with a 320GB hard drive which is just too small for my tastes.  Since I had a 1.5TB drive laying around doing nothing I decided to swap the 2 drives out.</p>
<p>The first step is to remove the screen protector from the case.  </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617569454715/JGZG5cO5A.jpeg" alt="Removing the Screen Protector from the iMac" /></p>
<p>Step 2 - Removing The Front Bezel</p>
<p>This was the hardest part of the whole process, First step is to remove the memory door and memory. After that remove all Torx Screws out of the way. There are 8 short T8 Torx Screws along the top and side of the bezel. Then there are 4 long Torx screws along the bottom.</p>
<p>After removing the Torx screws, Work your way around the bottom of the iMac and try to loosen the stand, there's a groove on the bottom I used a pocket knife to get it started then lifted carefully lifted up from there.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617569565234/WMNcBJ8F7.jpeg" alt="Removing The Front Bezel" /></p>
<p>Step 3 - Disconnecting the iSight Camera </p>
<p>![Finish Removing the Front Bezel(https://cdn.hashnode.com/res/hashnode/image/upload/v1617569596022/K4rCw26RI.jpeg)</p>
<p>Step 4 - Removing the Screen</p>
<p>Ok, now there are 8 Torx T8 or T9 screws holding the LCD Display to the Case. If you are very careful, You can remove these screws and Tilt the Display out of the way so you do not have to unhook the wires.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617569677803/59w4ZxDlG.jpeg" alt="Removing the Screen" /></p>
<p>Step 5 - Replacing the Hard Drive</p>
<p>Ok After all that finally found the hard drive, there is a Black Handle on one side of it, I used my leg to hold the mac in place and pulled the handle to me so that the hard drive pulled right out. Personally, my Temp Sensor would not stick back on so I used electric tape to tape it back on. Once you have finished this step, Reverse the rest of the steps and make sure you Clean both the LCD Display and the Inside and Outside of the Screen Protector or you will have annoying fingerprints on your display.</p>
<p>One other thing makes sure all your wires are routed properly and not blocking any screw holes, When I went to reinstall one of the wires in the bottom would not fit the screw hold so I had to remove everything to figure out why, if I would have forced it to go in, It would have broken something I'm sure.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1617569626809/PIKTiNLFB.jpeg" alt="Removing the Hard Drive" /></p>
<p>Step 6 - Reverse  the process</p>
<p>After replacing the hard drive just reverse the process to put everything back together.  One important thing I forgot to mention is to do a Drive clone before you change the drives out. I forgot to do that and had to boot from my old drive as an external drive. </p>
]]></content:encoded></item></channel></rss>