<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[technokracy]]></title>
  <link href="http://technokracy.net/atom.xml" rel="self"/>
  <link href="http://technokracy.net/"/>
  <updated>2013-06-18T09:58:04-07:00</updated>
  <id>http://technokracy.net/</id>
  <author>
    <name><![CDATA[Gregory Gaskill]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Deploying with Capistrano: CakePHP, Composer, and Compass]]></title>
    <link href="http://technokracy.net/2013/04/27/deploying-with-capistrano-cakephp/"/>
    <updated>2013-04-27T09:49:00-07:00</updated>
    <id>http://technokracy.net/2013/04/27/deploying-with-capistrano-cakephp</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/capistrano/capistrano">Capistrano</a>, originally developed to deploy Rails
websites, is an extremely useful tool for deploying anything. I&#8217;m using it to deploy CakePHP based
sites which use <a href="http://getcomposer.org/">Composer</a> to manage dependencies,
<a href="http://compass-style.org/">Compass</a> and <a href="http://sass-lang.com/">sass</a> for css, and
<a href="http://documentcloud.github.io/jammit/">jammit</a> for javascript compiling and minifying. Getting
everything wired together involved some work, but it was well worth the effort. I decided not to use
the fully featured <a href="https://github.com/jadb/capcake">capcake</a> gem, primarily because I wanted to fine
tune the deployment for my configuration and fully understand each step.</p>

<p>The deployment script is available on GitHub as <a href="https://github.com/chronon/capistrano-cake">capistrano-cake</a>.</p>

<h2>Installation</h2>

<p>I use <a href="https://rvm.io/">rvm</a> to manage ruby on OS X, but it doesn&#8217;t really matter how you do it as
long as you can install ruby gems.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>gem install capistrano
</span><span class='line'>gem install railsless-deploy
</span></code></pre></td></tr></table></div></figure>


<p>The <a href="https://github.com/leehambley/railsless-deploy/">railsless-deploy</a> gem removes most of the
<em>railsisms</em> that come with capistrano.</p>

<h2>The Setup</h2>

<p>I usually use a shared CakePHP core on my production servers, so deployment from development
consists of transferring my app files and dependencies (plugins, etc.). Managing dependencies with
<a href="http://getcomposer.org/">Composer</a> is well worth the effort, and allows you to easily add packages
from <a href="https://packagist.org/">Packagist</a> or from your own private repositories.</p>

<p>My app to deploy is structured like this:</p>

<pre><code>Capfile
composer.json
Config/
Console/
Controller/
Lib/
Locale/
Model/
Plugin/
Test/
Vendor/
View/
compass/
tmp/
webroot/
</code></pre>

<p>I&#8217;m splitting up my deploy script into two files, <code>app.rb</code> and <code>deploy.rb</code>. This lets me reuse
<code>deploy.rb</code> for every CakePHP deployment, while only changing a few variables in <code>app.rb</code>. Both of
these files are put in my app&#8217;s <code>Config</code> directory. The <code>Capfile</code> in the root of my app simply loads
things:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span>
</span><span class='line'><span class="nb">require</span> <span class="s1">&#39;railsless-deploy&#39;</span>
</span><span class='line'><span class="nb">load</span>  <span class="s1">&#39;Config/app&#39;</span>
</span><span class='line'><span class="nb">load</span>    <span class="s1">&#39;Config/deploy&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>In <code>Config/app.rb</code>, I set the required variables for deployment:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s2">&quot;testapp.chronon.us&quot;</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:repository</span><span class="p">,</span>  <span class="s2">&quot;ssh://git.chronon.us/home/repos/testapp&quot;</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span> <span class="s2">&quot;/var/www/</span><span class="si">#{</span><span class="n">application</span><span class="si">}</span><span class="s2">&quot;</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:branch</span><span class="p">,</span> <span class="s2">&quot;master&quot;</span>
</span><span class='line'><span class="n">role</span> <span class="ss">:web</span><span class="p">,</span> <span class="s2">&quot;server.chronon.us&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The deploy strategy here is that I&#8217;m developing the site locally, pushing changes to a private git
repository (git.chronon.us), and have the production server (server.chronon.us) pull changes from
the git repository.</p>

<h2>Deploying</h2>

<p>With my <code>app.rb</code> configured, I can set things up on the remote server:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>cap deploy:setup
</span></code></pre></td></tr></table></div></figure>


<p>This creates two directories on the remove server, <code>releases</code> and <code>shared</code>. In <code>shared</code>, the
following directories are created by the CakePHP <code>deploy.rb</code> specifically for a CakePHP app and
permissions are set correctly for the <code>tmp</code> directory.</p>

<pre><code>tmp/
Config/
Plugin/
Vendor/
</code></pre>

<p>The config files <code>core.php</code>, <code>bootstrap.php</code>, and <code>database.php</code> are uploaded to <code>shared/Config</code>.
Before deploying, make the necessary changes to these to match your production server environment.</p>

<p>To deploy an app for the first time:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>cap deploy -S <span class="nv">composer</span><span class="o">=</span>install
</span></code></pre></td></tr></table></div></figure>


<p>The <code>-S composer=install</code> part passes the <code>install</code> command to the composer task in the deploy script.
By default, composer runs the <code>update</code> command, so future deployments will require only <code>cap deploy</code>.</p>

<p>Upon deployment, a few special things happen:</p>

<ul>
<li><p>The <code>tmp</code>, <code>Plugin</code>, and <code>Vendor</code> directories in the app directory on the server are removed, and
symlinked to the corresponding directories in the <code>shared</code> directory capistrano made.</p></li>
<li><p>The files <code>core.php</code>, <code>bootstrap.php</code>, and <code>database.php</code> in the <code>Config</code> directory are removed,
and symlinked to corresponding names in the <code>shared/Config</code> directory.</p></li>
<li><p>The CakePHP tmp directory structure (cache, sessions, tests, logs) is created in <code>shared/tmp</code>.</p></li>
<li><p>If a <code>composer.json</code> project file exists, composer runs <code>install</code>, putting plugins into
<code>shared/Plugins</code> and vendor files into <code>shared/Vendor</code>.</p></li>
<li><p>If a compass project exists and <code>set :compile_css, true</code> has been set in <code>app.rb</code>, the command
<code>compass compile compass</code> is run <strong>locally</strong>. The compiled css files are then transferred to the
remote server, eliminating the need to compile assets on a production server.</p></li>
<li><p>If javascript compilation and minification has been configured with jammit and <code>set :compile_js, true</code>
has been set in <code>app.rb</code>, the command <code>jammit -c compass/assets.yml -o webroot/js/</code> runs
<strong>locally</strong>. The compiled js files are then transferred to the remote server.</p></li>
</ul>


<h2>Options</h2>

<p>A few other variables can be set in <code>app.rb</code>, all are optional:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">set</span> <span class="ss">:cake_config_files</span><span class="p">,</span> <span class="sx">%w{core.php database.php bootstrap.php}</span> <span class="c1"># these are the defaults if not set</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:cake_shared_dirs</span><span class="p">,</span> <span class="sx">%w{tmp Vendor Plugin}</span> <span class="c1"># these are the defaults if not set</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:upload_dirs</span><span class="p">,</span> <span class="sx">%w{img/contents img/options files/downloads}</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:compile_css</span><span class="p">,</span> <span class="kp">true</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:compile_js</span><span class="p">,</span> <span class="kp">true</span>
</span><span class='line'><span class="n">set</span> <span class="ss">:files_to_remove</span><span class="p">,</span> <span class="sx">%w{webroot/css/cake*.css webroot/img/cake.* webroot/img/test-*.png webroot/test.php}</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li><code>cake_config_files</code>: the config files to symlink and upload during initial setup.</li>
<li><code>cake_shared_dirs</code>: the directories to symlink from app to shared.</li>
<li><code>upload_dirs</code>: sets the listed directories to be created in the <code>shared</code> directory and
symlinked, just like <code>Plugin</code> and <code>Vendor</code>.</li>
<li><code>compile_css</code>: runs compass compile, requires compass to be set up in your app&#8217;s <code>compass</code>
directory.</li>
<li><code>compile_js</code>: runs jammit, requires an <code>assets.yml</code> file in your app&#8217;s <code>compass</code> directory.</li>
<li><code>files_to_remove</code>: array of files to delete at the end of deployment.</li>
</ul>


<h2>Conclusion</h2>

<p>Obviously this setup is pretty specific to how I have things set up for development. Hopefully all
or at least parts of the workflow and script can helpful in deploying CakePHP sites with capistrano.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CakePHP Mobile-Detect Component]]></title>
    <link href="http://technokracy.net/2013/04/11/cakephp-mobile-detect-component/"/>
    <updated>2013-04-11T11:31:00-07:00</updated>
    <id>http://technokracy.net/2013/04/11/cakephp-mobile-detect-component</id>
    <content type="html"><![CDATA[<p>The component, packaged as a plugin, is <a href="https://github.com/chronon/CakePHP-MobileDetectComponent-Plugin">available at GitHub</a>.</p>

<p>CakePHP&#8217;s built-in CakeRequest object can easily determine if a request is from a mobile device:</p>

<pre><code>$this-&gt;request-&gt;is('mobile');
</code></pre>

<p>However, sometimes an application needs finer control over what to serve certain devices, such as a
mobile layout to smartphones and a desktop layout to tablets. The <a href="http://mobiledetect.net/">MobileDetect</a>
project is a &#8220;lightweight PHP class for detecting mobile devices&#8221;. This component, packaged as
a plugin, makes MobileDetect available in a CakePHP controller.</p>

<h2>Compatibility:</h2>

<p>Tested with CakePHP 2.3.x, but should work fine with any CakePHP 2.x version.</p>

<h2>Installation:</h2>

<p><strong>Using <a href="http://getcomposer.org/">Composer</a>/<a href="https://packagist.org">Packagist</a>:</strong></p>

<p>In your project <code>composer.json</code> file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  "require": {
</span><span class='line'>      "chronon/mobile_detect": "*"
</span><span class='line'>  },
</span><span class='line'>  "config": {
</span><span class='line'>        "vendor-dir": "Vendor"
</span><span class='line'>    }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>This will install the plugin into <code>Plugin/MobileDetect</code>, and install the Mobile_Detect lib
(from Packagist) into your <code>Vendor</code> directory.</p>

<p>In your app&#8217;s <code>Config/bootstrap.php</code>, import composer&#8217;s autoload file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">App</span><span class="o">::</span><span class="na">import</span><span class="p">(</span><span class="s1">&#39;Vendor&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;file&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;autoload&#39;</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Using git:</strong></p>

<p>You will need the component (packaged as a plugin), and the MobileDetect PHP library (not included). The
MobileDetect library needs to be in this plugin&#8217;s Vendor directory and must be named &#8216;MobileDetect&#8217;.
Using git, something like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>git clone git@github.com:chronon/CakePHP-MobileDetectComponent-Plugin.git APP/Plugin/MobileDetect
</span><span class='line'>git clone git@github.com:serbanghita/Mobile-Detect.git APP/Plugin/MobileDetect/Vendor/MobileDetect
</span></code></pre></td></tr></table></div></figure>


<p>The MobileDetect library could also be added as a git submodule&#8230;</p>

<h2>Usage:</h2>

<p>The component has only one method, named <code>detect</code>. It accepts two arguments: the method to pass to
the MobileDetect library, and any arguments for the passed method.</p>

<p>Example: check if a request is from a tablet:</p>

<pre><code>$result = $this-&gt;MobileDetect-&gt;detect('isTablet');
</code></pre>

<p>Example: check if a request is from an iOS device :</p>

<pre><code>$result = $this-&gt;MobileDetect-&gt;detect('isiOS');
</code></pre>

<p>Example: get version number of an Android device:</p>

<pre><code>$result = $this-&gt;MobileDetect-&gt;detect('version', 'Android');
</code></pre>

<p>See the demo at <a href="http://mobiledetect.net/">mobiledetect.net</a> for a list of all available methods.</p>

<h2>Example:</h2>

<p>Let&#8217;s say we want to serve a mobile layout to smartphones and a desktop layout to
tablets. Instead of loading the component on every request (by adding it to your controller&#8217;s
<code>$components</code> array), we&#8217;ll load the component on the fly when needed. This example sets a session
variable <code>tablet</code> if the request is from a tablet, calling the component only once.</p>

<p>In <code>Controller/AppController.php</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">beforeFilter</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">// check if the request is &#39;mobile&#39;, includes phones, tablets, etc.</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">-&gt;</span><span class="na">is</span><span class="p">(</span><span class="s1">&#39;mobile&#39;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_isTablet</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>          <span class="c1">// if the request is mobile, but not a tablet, activate the mobile layout</span>
</span><span class='line'>          <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_setMobile</span><span class="p">();</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">protected</span> <span class="k">function</span> <span class="nf">_setMobile</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">theme</span> <span class="o">=</span> <span class="s1">&#39;Mobile&#39;</span><span class="p">;</span>
</span><span class='line'>  <span class="c1">// etc...</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">protected</span> <span class="k">function</span> <span class="nf">_isTablet</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Session</span><span class="o">-&gt;</span><span class="na">check</span><span class="p">(</span><span class="s1">&#39;tablet&#39;</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Session</span><span class="o">-&gt;</span><span class="na">read</span><span class="p">(</span><span class="s1">&#39;tablet&#39;</span><span class="p">)</span> <span class="o">==</span> <span class="k">true</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>      <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="c1">// load the component</span>
</span><span class='line'>  <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">MobileDetect</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Components</span><span class="o">-&gt;</span><span class="na">load</span><span class="p">(</span><span class="s1">&#39;MobileDetect.MobileDetect&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="c1">// pass the component the &#39;isTablet&#39; method</span>
</span><span class='line'>  <span class="nv">$result</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">MobileDetect</span><span class="o">-&gt;</span><span class="na">detect</span><span class="p">(</span><span class="s1">&#39;isTablet&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Session</span><span class="o">-&gt;</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;tablet&#39;</span><span class="p">,</span> <span class="nv">$result</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="nv">$result</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CakePHP YMLP Component Plugin]]></title>
    <link href="http://technokracy.net/2013/02/14/cakephp-ymlp-component-plugin/"/>
    <updated>2013-02-14T11:01:00-08:00</updated>
    <id>http://technokracy.net/2013/02/14/cakephp-ymlp-component-plugin</id>
    <content type="html"><![CDATA[<p>The plugin is available at Github as <a href="https://github.com/chronon/CakePHP-YMLP-Plugin">CakePHP-YMLP-Plugin</a>.</p>

<h1>CakePHP <a href="http://www.ymlp.com/">YMLP</a> Component</h1>

<p><a href="http://www.ymlp.com/">YMLP</a>, or Your Mailing List Provider, is a email newsletter and marketing
service with free and paid accounts, and a well written API.</p>

<p>This component interfaces a CakePHP app with YMLP&#8217;s API.</p>

<p>You will need a free or paid account at <a href="http://www.ymlp.com/">YMLP</a>, along with your username and
API key (found at ymlp.com under &#8220;Configuration&#8221;, &#8220;API&#8221;). Make sure to enable API access on YMLP&#8217;s
API page!</p>

<h2>Compatibility:</h2>

<p>Tested with CakePHP 2.3.x. Requires PHP 5 with cURL support.</p>

<h2>Installation:</h2>

<p><strong>Using <a href="http://getcomposer.org/">Composer</a>/<a href="https://packagist.org">Packagist</a>:</strong></p>

<p>In your project <code>composer.json</code> file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  "require": {
</span><span class='line'>      "chronon/ymlp": "*"
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p><strong>Using git:</strong></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>git clone git@github.com:chronon/CakePHP-YmlpComponent-Plugin.git APP/Plugin/Ymlp
</span></code></pre></td></tr></table></div></figure>


<h2>Configuration:</h2>

<p>All configuration is in APP/Config/bootstrap.php.</p>

<p><strong>Required:</strong> Load the plugin:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">CakePlugin::load(&#39;Ymlp&#39;);</span>
</span></code></pre></td></tr></table></div></figure>


<p>or</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">CakePlugin::loadAll();</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Required:</strong> Set your YMLP API key and username.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Ymlp.settings&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;Key&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;1234567890ABCDEFG&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;Username&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;yourusername&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Required:</strong> Set your YMLP field mapping, which is your local field => YMLPField.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Ymlp.fieldMap&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;email&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Email&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Usage:</h2>

<p>Add the component to your controller:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="nv">$components</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;Ymlp.Ymlp&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Example: if you have a subscriber form with a field named <code>email</code>, <code>$this-&gt;request-&gt;data</code> would look
something like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">[&#39;Subscriber&#39;] =&gt; array(</span>
</span><span class='line'><span class="x">  &#39;email&#39; =&gt; &#39;some@email.com&#39;</span>
</span><span class='line'><span class="x">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>To add this email address to YMLP using the component:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nv">$result</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Ymlp</span><span class="o">-&gt;</span><span class="na">command</span><span class="p">(</span><span class="s1">&#39;Contacts.Add&#39;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">[</span><span class="s1">&#39;Subscriber&#39;</span><span class="p">]);</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>$result</code> would be the response from YMLP&#8217;s <code>Contacts.Add()</code> method. See the YMLP docs for all
available API commands.</p>

<p>The available methods of this component are:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">utility($method, $data = array())</span>
</span><span class='line'>
</span><span class='line'><span class="x">/**</span>
</span><span class='line'><span class="x"> * A utility method to send anything to the YMLP API</span>
</span><span class='line'><span class="x"> *</span>
</span><span class='line'><span class="x"> * @param string $method The YMLP API method call</span>
</span><span class='line'><span class="x"> * @param array  $data Data to pass to the YMLP method</span>
</span><span class='line'><span class="x"> * @return string</span>
</span><span class='line'><span class="x"> * @access public</span>
</span><span class='line'><span class="x"> */</span>
</span><span class='line'><span class="x"> </span>
</span><span class='line'><span class="x">command($method, $data)</span>
</span><span class='line'>
</span><span class='line'><span class="x">/**</span>
</span><span class='line'><span class="x"> * The primary method to format data, post it to the YMLP API, and then format</span>
</span><span class='line'><span class="x"> * the returned result.</span>
</span><span class='line'><span class="x"> *</span>
</span><span class='line'><span class="x"> * @param string $method The YMLP API method call</span>
</span><span class='line'><span class="x"> * @param array  $data Data to pass to the YMLP method</span>
</span><span class='line'><span class="x"> * @return string</span>
</span><span class='line'><span class="x"> * @access public</span>
</span><span class='line'><span class="x"> */</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Example usage of the <code>utility</code> method to view a list of configured YMLP fields. If you created
a form at YMLP to collect name, email address, and mailing address, you need to match your app&#8217;s
fields with YMLP fields. The YMLP API <code>Fields.GetList()</code> method can give you what you need.</p>

<p>Create a temporary method in your controller and use the component&#8217;s <code>utility</code> method:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">utility</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nv">$result</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Ymlp</span><span class="o">-&gt;</span><span class="na">utility</span><span class="p">(</span><span class="s1">&#39;Fields.GetList&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">debug</span><span class="p">(</span><span class="nv">$result</span><span class="p">);</span>
</span><span class='line'>  <span class="k">exit</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Visit /utility and you should see a list of YMLP configured fields with field id, which you can use
to map to your app fields with the <code>Ymlp.fieldMap</code> configuration array.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Ymlp.fieldMap&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;email&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Email&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;first_name&#39;</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;last_name&#39;</span> <span class="o">=&gt;</span> <span class="mi">2</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;address&#39;</span> <span class="o">=&gt;</span> <span class="mi">3</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;city&#39;</span> <span class="o">=&gt;</span> <span class="mi">4</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;state&#39;</span> <span class="o">=&gt;</span> <span class="mi">5</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;zip&#39;</span> <span class="o">=&gt;</span> <span class="mi">6</span><span class="p">,</span>
</span><span class='line'><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My Apple Maps Failure Story]]></title>
    <link href="http://technokracy.net/2012/12/22/my-apple-maps-failure-story/"/>
    <updated>2012-12-22T09:41:00-08:00</updated>
    <id>http://technokracy.net/2012/12/22/my-apple-maps-failure-story</id>
    <content type="html"><![CDATA[<p>We&#8217;ve hiked the China Flat/Simi Peak trail many times (a wonderful hike!), and always noticed
a trail off to the right at the notch near the top of China Flat. The other day, we decided to take
the trail in an attempt to loop back down to the car. It seemed logical, and a quick look at the new
iOS 6 Maps app on my iPhone showed a fire road ahead of us, passing right by the neighborhood where
we parked.</p>

<p>As we made it down the mountain and passed near the neighborhood, we tried every spur trail only
to be met with multiple fences and private property. A ninja mission to a promising looking gate
set off some alarms, so we quickly retreated back to the trail.</p>

<p>By now we had walked around 4.5 miles and it was getting late in the afternoon, so we decided our
best option was to just follow the trail to it&#8217;s end. Eventually we made it to Oak Canyon park,
which was 2.8 miles away from our car on main roads. My maps app didn&#8217;t show any connecting trail or
road between Oak Canyon park and were we were parked, so we started walking on the road. Eventually
we made it back to the car, and arrived home as it was getting dark.</p>

<p>A few days later, I investigated our hike in Google Maps on my computer, and clearly saw a distinct
line connecting Oak Canyon park with the neighborhood our car was parked in. Zooming in, it became
clear it was a bike path. The 2.8 miles we walked would have been .7 on the bike path&#8230;if we only
knew it was there! Of course I <strong>should</strong> have checked the satellite imagery, or at least checked
the web version of Google Maps from my phone&#8230;but instead I trusted the Apple Maps data without
question.</p>

<p><img src="http://technokracy.net/images/posts/map-apple.jpg" alt="Apple Map" />
<img src="http://technokracy.net/images/posts/map-google.jpg" alt="Google Map" />
<img src="http://technokracy.net/images/posts/map-sat.jpg" alt="Sat Map" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CakePHP Markdown Helper Plugin]]></title>
    <link href="http://technokracy.net/2012/11/10/cakephp-markdown-helper-plugin/"/>
    <updated>2012-11-10T08:59:00-08:00</updated>
    <id>http://technokracy.net/2012/11/10/cakephp-markdown-helper-plugin</id>
    <content type="html"><![CDATA[<p>The plugin is available at Github as <a href="https://github.com/chronon/CakePHP-Markdown-Plugin">CakePHP-Markdown-Plugin</a>.</p>

<p>A <a href="https://github.com/michelf/php-markdown/">PHP Markdown</a> helper packaged as a plugin, includes
php-markdown.php.</p>

<h2>Installation:</h2>

<p><strong>Using <a href="http://getcomposer.org/">Composer</a>/<a href="https://packagist.org">Packagist</a>:</strong></p>

<p>If you are using composer, require <code>chronon/markdown</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>    "require": {
</span><span class='line'>        "chronon/markdown": "*"
</span><span class='line'>    },
</span><span class='line'>  "config": {
</span><span class='line'>        "vendor-dir": "Vendor"
</span><span class='line'>    }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>This will install the plugin into <code>Plugin/Markdown</code>, and install Markdown lib (from Packagist) into
your <code>Vendor</code> directory.</p>

<p>In <code>Config/bootstrap.php</code>, import composer&#8217;s autoload file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">App</span><span class="o">::</span><span class="na">import</span><span class="p">(</span><span class="s1">&#39;Vendor&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;file&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;autoload&#39;</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Using git:</strong></p>

<p>If you are <strong>not</strong> using composer, clone the repository:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>git clone git@github.com:chronon/CakePHP-Markdown-Plugin.git APP/Plugin/Markdown
</span></code></pre></td></tr></table></div></figure>


<h2>Usage:</h2>

<p>In your controller:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="nv">$helpers</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;Markdown.Markdown&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>In your view:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">echo</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Markdown</span><span class="o">-&gt;</span><span class="na">md</span><span class="p">(</span><span class="nx">markdown_to_be_converted_to_html</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Flickr Sidebar for Octopress]]></title>
    <link href="http://technokracy.net/2012/10/02/flickr-sidebar-for-octopress/"/>
    <updated>2012-10-02T14:54:00-07:00</updated>
    <id>http://technokracy.net/2012/10/02/flickr-sidebar-for-octopress</id>
    <content type="html"><![CDATA[<p>The plugin is available at Github as <a href="https://github.com/chronon/Octopress-Flickr-Badge">Octopress-Flickr-Badge</a>.</p>

<h2>Description:</h2>

<p>This plugin adds Flickr photos to the Octopress sidebar, with a few configurable options. It does
not require Flickr API access as it uses their <a href="http://www.flickr.com/badge.gne">badge script</a>.</p>

<h2>Files:</h2>

<p>Place <code>flickr.html</code> in <code>source/_includes/custom/asides/</code>. Optionally copy the contents of<br/>
<code>_styles.scss</code> to <code>sass/custom</code> for some basic styling (centered photos with 20px top margin).</p>

<h2>Configuration:</h2>

<p>Add <code>custom/asides/flickr.html</code> to <code>default_asides:</code> in your <code>_config.yml</code>. If you want photos at
the top of the sidebar, add it to the beginning of the list.</p>

<p>Add the Flickr sidebar configuration options to your <code>_config.yml</code> at the bottom of &#8220;3rd Party
Settings&#8221;. You&#8217;ll need your Flickr user id, which is different from your username. An easy way to
find your user id is <a href="http://idgettr.com">idgettr.com</a>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="c1"># Flickr Badge</span>
</span><span class='line'><span class="l-Scalar-Plain">flickr_user</span><span class="err">:            </span><span class="l-Scalar-Plain"># user id (not username)</span>
</span><span class='line'><span class="l-Scalar-Plain">flickr_count</span><span class="err">:           </span><span class="l-Scalar-Plain"># number of photos to show (example</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">3)</span>
</span><span class='line'><span class="l-Scalar-Plain">flickr_display</span><span class="err">:         </span><span class="l-Scalar-Plain"># random or latest</span>
</span><span class='line'><span class="l-Scalar-Plain">flickr_size</span><span class="err">:            </span><span class="l-Scalar-Plain"># t (thumbnail), s (small square), m (medium)</span>
</span><span class='line'><span class="l-Scalar-Plain">flickr_source</span><span class="err">:          </span><span class="l-Scalar-Plain"># user, user_tag, all, all_tag</span>
</span><span class='line'><span class="l-Scalar-Plain">flickr_tag</span><span class="err">:             </span><span class="l-Scalar-Plain"># tagname - set if flickr_source is set to user_tag or all_tag</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>flickr_source:</code> setting can be:</p>

<ul>
<li>user (all user&#8217;s public photos)</li>
<li>user_tag (user&#8217;s tagged photos),</li>
<li>all (everyone&#8217;s public photos)</li>
<li>all_tag (all public photos tagged with tag)</li>
</ul>


<h2>Example/Demo</h2>

<p>See the bottom of the sidebar at <a href="http://technokracy.net">technokracy.net</a>, or the source
<a href="https://github.com/chronon/octopress/tree/technokracy">on Github</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[zrsync - An rsync wrapper]]></title>
    <link href="http://technokracy.net/2012/09/26/zrsync-an-rsync-wrapper/"/>
    <updated>2012-09-26T13:07:00-07:00</updated>
    <id>http://technokracy.net/2012/09/26/zrsync-an-rsync-wrapper</id>
    <content type="html"><![CDATA[<p><strong>zrsync</strong> is <a href="https://github.com/chronon/zrsync">available on github</a>.</p>

<h2>Description</h2>

<p>For simple deployments and updates to a website, rysnc is a wonderful tool. <code>zrsync</code> is a simple
rsync wrapper I wrote because I got tired of typing commands like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>rsync -auv -e ssh --delete-after --stats --exclude<span class="o">=</span>.svn --exclude<span class="o">=</span>.git*
</span><span class='line'>--exclude-from<span class="o">=</span>sync.exclude /Users/chronon/www/chronon.com/public/
</span><span class='line'>chronon.com:/home/chronon/www/chronon.com/public
</span></code></pre></td></tr></table></div></figure>


<p>Following a few required conventions and using <code>zrsync</code>, the above command becomes:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>zrsync
</span></code></pre></td></tr></table></div></figure>


<p>A little easier to remember!</p>

<h2>Installation</h2>

<p>Put the script in your <code>$PATH</code>. Obviously SSH access to the remote host is required, preferably
using <a href="http://library.linode.com/securing-your-server#sph_using-ssh-key-pair-authentication">key pair authentication</a>.</p>

<h2>Configuration</h2>

<p><strong>Optional:</strong> Set an environment variable for your most commonly used remote host. In <code>.bashrc</code> for
example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nb">export </span><span class="nv">ZRSYNC_REMOTE</span><span class="o">=</span><span class="s2">&quot;chronon.com&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Optional:</strong> Set an environment variable to convert Mac OS X directory <code>/Users</code> to <code>/home</code> when
figuring out the remote path. See the conventions section below for details. In <code>.bashrc</code> for
example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nb">export </span><span class="nv">ZRSYNC_OSXUSER</span><span class="o">=</span>1
</span></code></pre></td></tr></table></div></figure>


<h2>Conventions</h2>

<p>This script is based on (my) conventions, which if followed make using it very simple.</p>

<ul>
<li><p>Use the <strong>same directory structure</strong> on your local development machine as you do on your server.
Since OS X puts users in <code>/Users</code> and servers rooted in UNIX put users in <code>/home</code>, set the above
mentioned environment variable <code>ZRSYNC_OSXUSER</code> to <code>1</code>.</p></li>
<li><p>To exlcude files or directories, create a file in the root of your project named <code>sync.exclude</code>
and list stuff there. Example <code>sync.exclude</code> contents:</p></li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Tests/
</span><span class='line'>tmp/
</span><span class='line'>webroot/test.php
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Both .svn and .git files/directories are automatically excluded.</li>
</ul>


<h2>Usage</h2>

<p>If the above conventions are followed, to perform an rsync deployment or update of a project is as
simple as <code>cd</code> to project root, and typing <code>zrsync</code>.</p>

<p>All command line options can be seen by typing <code>zrsync -h</code>. A pretend/dry-run mode is available by
using the <code>-p</code> option.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CakePHP Stripe Payment Processing Component]]></title>
    <link href="http://technokracy.net/2012/09/22/cakephp-stripe-component/"/>
    <updated>2012-09-22T16:55:00-07:00</updated>
    <id>http://technokracy.net/2012/09/22/cakephp-stripe-component</id>
    <content type="html"><![CDATA[<p>The component, packaged as a plugin, is <a href="https://github.com/chronon/CakePHP-StripeComponent-Plugin">available at GitHub</a>.</p>

<p>This is a simple component that interfaces a CakePHP app with Stripe&#8217;s PHP API library. Pass the
component an array containing at least an amount and a Stripe token id, it will attempt the charge
and return an array of the fields you want.</p>

<h2>Compatibility:</h2>

<p>Tested with CakePHP 2.2.x, though should work with any 2.x version. The required Stripe PHP API
library requires PHP 5 with cURL support.</p>

<h2>Installation:</h2>

<p><strong>Using <a href="http://getcomposer.org/">Composer</a>/<a href="https://packagist.org">Packagist</a>:</strong></p>

<p>In your project <code>composer.json</code> file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{
</span><span class='line'>  "require": {
</span><span class='line'>      "chronon/stripe": "*"
</span><span class='line'>  },
</span><span class='line'>  "config": {
</span><span class='line'>        "vendor-dir": "Vendor"
</span><span class='line'>    }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>This will install the plugin into <code>Plugin/MobileDetect</code>, and install the Stripe library
(from Packagist) into your <code>Vendor</code> directory.</p>

<p>In your app&#8217;s <code>Config/bootstrap.php</code>, import composer&#8217;s autoload file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">App</span><span class="o">::</span><span class="na">import</span><span class="p">(</span><span class="s1">&#39;Vendor&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;file&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;autoload&#39;</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Using git:</strong></p>

<p>You will need the component (packaged as a plugin), and Stripe&#8217;s PHP library (not included). The
Stripe library needs to be in this plugin&#8217;s Vendor directory and must be named &#8216;Stripe&#8217;. Using git,
something like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>git clone git@github.com:chronon/CakePHP-StripeComponent-Plugin.git APP/Plugin/Stripe
</span><span class='line'>git clone git://github.com/stripe/stripe-php.git APP/Plugin/Stripe/Vendor/Stripe
</span></code></pre></td></tr></table></div></figure>


<h2>Configuration:</h2>

<p>All configuration is in APP/Config/bootstrap.php.</p>

<p><strong>Required:</strong> Load the plugin:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>  
</span><span class='line'><span class="nx">CakePlugin</span><span class="o">::</span><span class="na">load</span><span class="p">(</span><span class="s1">&#39;Stripe&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;bootstrap&#39;</span> <span class="o">=&gt;</span> <span class="k">false</span><span class="p">,</span> <span class="s1">&#39;routes&#39;</span> <span class="o">=&gt;</span> <span class="k">false</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Required:</strong> Set your Stripe secret API keys (both testing and live):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>  
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Stripe.TestSecret&#39;</span><span class="p">,</span> <span class="s1">&#39;yourStripeTestingAPIKeyHere&#39;</span><span class="p">);</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Stripe.LiveSecret&#39;</span><span class="p">,</span> <span class="s1">&#39;yourStripeLiveAPIKeyHere&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Optional:</strong> Set Stripe mode, either &#8216;Live&#8217; or &#8216;Test&#8217;. Defaults to Test if not set.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Stripe.mode&#39;</span><span class="p">,</span> <span class="s1">&#39;Test&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Optional:</strong> Set the currency. Defaults to &#8216;usd&#8217;. Currently Stripe supports usd only.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Stripe.currency&#39;</span><span class="p">,</span> <span class="s1">&#39;usd&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Optional:</strong> fields for the component to return mapped to => Stripe charge object response fields.
Defaults to <code>'stripe_id' =&gt; 'id'</code>. See the Stripe API docs for <a href="https://stripe.com/docs/api?lang=php#create_charge">Stripe_Charge::create()</a> for available fields. For example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Stripe.fields&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;stripe_id&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;id&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;stripe_last4&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;card&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;last4&#39;</span><span class="p">),</span>
</span><span class='line'>  <span class="s1">&#39;stripe_address_zip_check&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;card&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;address_zip_check&#39;</span><span class="p">),</span>
</span><span class='line'>  <span class="s1">&#39;stripe_cvc_check&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;card&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;cvc_check&#39;</span><span class="p">),</span>
</span><span class='line'>  <span class="s1">&#39;stripe_amount&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;amount&#39;</span>
</span><span class='line'><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>See Usage below if <code>Stripe.fields</code> is confusing.</p>

<p><strong>Optional:</strong> add a logging config:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">CakeLog</span><span class="o">::</span><span class="na">config</span><span class="p">(</span><span class="s1">&#39;stripe&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;engine&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;FileLog&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;types&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;info&#39;</span><span class="p">,</span> <span class="s1">&#39;error&#39;</span><span class="p">),</span>
</span><span class='line'>  <span class="s1">&#39;scopes&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;stripe&#39;</span><span class="p">),</span>
</span><span class='line'>  <span class="s1">&#39;file&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;stripe&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Usage:</h2>

<p>Make a payment form however you want, see the <a href="https://stripe.com/docs/tutorials/forms">Stripe docs</a>
for sample code. Add the component to your controller:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="nv">$components</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;Stripe.Stripe&#39;</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Format your form data so you can send the component an array containing at least:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nv">$data</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;amount&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;7.59&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;stripeToken&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;tok_0NAEASV7h0m7ny&#39;</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Optionally you can include a <code>description</code> field as well, which according to Stripe docs is:</p>

<blockquote><p>An arbitrary string which you can attach to a charge object. It is displayed when in the web
interface alongside the charge. It&#8217;s often a good idea to use an email address as a description
for tracking later.</p></blockquote>

<p>For example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nv">$data</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;amount&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;7.59&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;stripeToken&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;tok_0NAEASV7h0m7ny&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;description&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Casi Robot - casi@robot.com&#39;</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Attempt a charge:</strong> <code>$result = $this-&gt;Stripe-&gt;charge($data);</code></p>

<p>If the charge was successful, <code>$result</code> will be an <strong>array</strong> as described by the configuration value
of <code>Stripe.fields</code>. If <code>Stripe.fields</code> is not set:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nv">$result</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;stripe_id&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;ch_0NXLLCydWzSIeE&#39;</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>If <code>Stripe.fields</code> is set, using the example described above in the Configuration section would
give you:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nv">$result</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>  <span class="s1">&#39;stripe_id&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;ch_0NXLLCydWzSIeE&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;stripe_last4&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;4242&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;stripe_address_zip_check&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;pass&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;stripe_cvc_check&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;pass&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="s1">&#39;stripe_amount&#39;</span> <span class="o">=&gt;</span> <span class="mi">769</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>If the charge was not successful, <code>$result</code> will be a <strong>string</strong> containing an error message, and
log the error.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mac Mail.app and S/MIME Certificates]]></title>
    <link href="http://technokracy.net/2012/02/09/Mac_Mail_and_Certificates/"/>
    <updated>2012-02-09T00:00:00-08:00</updated>
    <id>http://technokracy.net/2012/02/09/Mac_Mail_and_Certificates</id>
    <content type="html"><![CDATA[<p>There is lots of information out there on how to get and install a free email certificate, but here it is again condensed and step-by-step. When complete, you&#8217;ll be able to sign and encrypt email messages with others who are making use of personal certificates.</p>

<h3>Get a free certificate:</h3>

<ol>
<li>Find a free certificate provider, such as <a href="http://www.instantssl.com/ssl-certificate-products/free-email-certificate.html">InstantSSL/Comodo</a>. A list of others is <a href="http://kb.mozillazine.org/Getting_an_SMIME_certificate">available here</a>.</li>
<li>Complete the form, recieve email confirmation.</li>
<li>Open the link in the email with <strong>Firefox</strong>, you should see an alert about certificate installed.</li>
</ol>


<h3>Export certificate to a file:</h3>

<ol>
<li>In Firefox, go to Preferences -> Advanced -> Encryption and push View Certificates.</li>
<li>Click Your Certificates, click on the certificate (line with a serial number).</li>
<li>Click Backup, select Desktop, and enter a password.</li>
</ol>


<h3>Import certificate to your keychain:</h3>

<ol>
<li>On your desktop, you should have something like comodo.p12, double click it.</li>
<li>Enter the password you just set and import the certificate.</li>
<li>Save your exported certifcate somewhere for backup, remember your password.</li>
</ol>


<h3>Using your certificate:</h3>

<ol>
<li>Quit Mail.app if it&#8217;s running, open Mail.app.</li>
<li>Compose a new message, notice two new buttons (a lock and a check).</li>
<li>When the check box is checked, your public certificate will be sent to the recipient.</li>
<li>Once your recipient has your public certificate, you can sign and encrypt (lock button) messages.</li>
<li>Any time you sign a message (check button checked), you are sending your public certificate.</li>
</ol>


<h3>Using your certificate with iOS devices:</h3>

<ol>
<li>Check out this <a href="https://catbrainblog.wordpress.com/2011/12/12/using-smime-on-ios-devices/">very good blog post</a>.</li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Extended attributes, ACLs, and Time Machine]]></title>
    <link href="http://technokracy.net/2011/03/07/Extended_attributes_ACLs_and_Time_Machine/"/>
    <updated>2011-03-07T00:00:00-08:00</updated>
    <id>http://technokracy.net/2011/03/07/Extended_attributes_ACLs_and_Time_Machine</id>
    <content type="html"><![CDATA[<h2>Copying from a Time Machine backup&#8230;</h2>

<p>So&#8230;through some git experimentation trying to erase the history of a file, I
committed and pushed to a local repository, which turned out not to be my
intention. Instead of figuring out how to fix it the git way, I thought I&#8217;d
just copy yesterday&#8217;s Time Machine backup of the repository. Instead of using
Time Machine app, I mounted the backup disk, and <code>cp -R</code>&#8216;d the directory. A
<code>ls-l</code> told me permissions and user:group ownership were correct&#8230;though I did
notice an <code>@</code> tacked onto the end <code>drwxr-xr-x@</code>&#8230;</p>

<h2>Insufficient Permission?</h2>

<p>Returning to the project a few days later, git pushing a new tag to the local
repository didn&#8217;t work, with a permission error:</p>

<blockquote><blockquote><p>insufficient permission for adding an object to repository database etc.</p></blockquote></blockquote>

<p>WTF, permissions and ownership are <strong>right</strong>. Google, Google, git, permissions,
etc. and no luck. Then, brilliant insight - don&#8217;t ignore the information
presented to me. What exactly does the <code>@</code> on the end of <code>drwxr-xr-x@</code> mean
anyway?</p>

<h2>OS X Extended Attributes</h2>

<p>Copying directly from the Time Machine backup also copied extended attributes
and ACLs, which I definitely didn&#8217;t want. The command</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>xattr my_repository.git
</span></code></pre></td></tr></table></div></figure>


<p>told me things like <code>com.apple.metadata:_kTimeMachineOldestSnapshot</code> and
<code>com.apple.metadata:_kTimeMachineNewestSnapshot</code> were attached to the directory
and it&#8217;s files. To remove:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>sudo xattr -d -r <span class="s1">&#39;com.apple.metadata:_kTimeMachineOldestSnapshot&#39;</span> my_repository.git
</span><span class='line'>sudo xattr -d -r <span class="s1">&#39;com.apple.metadata:_kTimeMachineNewestSnapshot&#39;</span> my_repository.git
</span></code></pre></td></tr></table></div></figure>


<p>To learn more about xattr:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>xattr -h
</span></code></pre></td></tr></table></div></figure>


<h2>OS X ACLs</h2>

<p>Now <code>ls -l</code> gave me <code>drwxr-xr-x+</code>, with the <code>+</code> meaning the directory has ACL
(access control lists) attached to it. Needless to say, I still couldn&#8217;t push
to the repository, even though the standard user:group permissions said I
could. To remove the ACL restrictions:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>sudo chmod -R -a# 0 my_repository
</span></code></pre></td></tr></table></div></figure>


<p>Finally, <code>ls -l</code> returns plain old <code>drwxr-xr-x</code>, and I could push to my
repository. What a wonderful waste of time!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Root, sudo, and rsnapshot]]></title>
    <link href="http://technokracy.net/2011/01/07/root_sudo_rsnapshot/"/>
    <updated>2011-01-07T00:00:00-08:00</updated>
    <id>http://technokracy.net/2011/01/07/root_sudo_rsnapshot</id>
    <content type="html"><![CDATA[<h2>Changelog</h2>

<ul>
<li>2013-06-18 Adding change rbackup user&#8217;s login shell section.</li>
<li>2013-06-14 A few steps updated, thanks in part to contributors. Notably, the <code>rbackup</code> user
doesn&#8217;t necessarily need to be created on the backup server (uno) as described originally.</li>
<li>2011-01-07 Initial post.</li>
</ul>


<h2>Introduction</h2>

<h3>The Mission:</h3>

<p>To rsync and/or rsnapshot both normal and protected/restricted files from one
server to another over ssh <strong>without</strong> enabling remote root access to either
server while maintaining original file attributes and permissions. Whew.</p>

<h3>Cast of Characters</h3>

<ul>
<li><strong>uno:</strong> the server which will store the backups, run rsync or
<a href="http://rsnapshot.org/">rsnapshot</a>.</li>
<li><strong>zero:</strong> the server to be backed up, with root readable files (/etc for
example).</li>
</ul>


<h3>Prerequisites</h3>

<ul>
<li><strong>root</strong> on both <strong>uno</strong> and <strong>zero</strong>, hopefully via sudo and not by remote
root ssh access!</li>
</ul>


<h2>Configuration</h2>

<p>The command examples here are specific to Debian and Ubuntu, so
adjust to your distribution accordingly (though little if any adjustment should
be necessary).</p>

<h3>Server: uno (backup server)</h3>

<p>Become root, create an ssh key pair:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>root# ssh-keygen -t rsa
</span></code></pre></td></tr></table></div></figure>


<p>When naming the key, don&#8217;t accept the default. Instead, enter</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>/root/.ssh/id-rbackup_rsa
</span></code></pre></td></tr></table></div></figure>


<p>We&#8217;re naming the key pair with &#8216;rbackup&#8217; in it to keep track of what the keys are for.</p>

<p>As root, create a ssh config file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>root# vim .ssh/config
</span></code></pre></td></tr></table></div></figure>


<p>In root&#8217;s .ssh/config file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='apache'><span class='line'><span class="nb">Host</span> zero-rsync
</span><span class='line'>  <span class="nb">Port</span> <span class="m">456</span> # only required if zero is running sshd <span class="k">on</span> a non-standard port
</span><span class='line'>  <span class="nb">Hostname</span> zero
</span><span class='line'>  <span class="nb">User</span> rbackup
</span><span class='line'>  <span class="nb">IdentityFile</span> <span class="sx">/root/.ssh/id-rbackup_rsa</span>
</span></code></pre></td></tr></table></div></figure>


<p>Save the file, set permissions:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>root# chmod 600 config
</span></code></pre></td></tr></table></div></figure>


<p>While still root, copy the public key <code>id-rbackup_rsa.pub</code> somewhere publicly
accessible, such as your regular user&#8217;s home directory.</p>

<p>As your regular user (which already has ssh access to <strong>zero</strong>), send this public key from <strong>uno</strong>
to <strong>zero</strong>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>scp ~/id-rbackup_rsa.pub zero:~/
</span></code></pre></td></tr></table></div></figure>


<h3>Server: zero (server to be backed up)</h3>

<p>Create new backup user, lets call it <code>rbackup</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>sudo adduser rbackup
</span></code></pre></td></tr></table></div></figure>


<p>Make <strong>uno&#8217;s</strong> public key <code>id-rbackup_rsa.pub</code> available to user rbackup.</p>

<p>Login as rbackup, create a .ssh directory, set permissions, create an
<code>authorized_keys</code> file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>su rbackup
</span><span class='line'><span class="nv">$ </span><span class="nb">cd</span>
</span><span class='line'><span class="nv">$ </span>mkdir .ssh
</span><span class='line'><span class="nv">$ </span>chmod 700 .ssh
</span><span class='line'><span class="nv">$ </span><span class="nb">cd</span> .ssh
</span><span class='line'><span class="nv">$ </span>cat /home/regularuser/id-rbackup_rsa.pub &gt; authorized_keys
</span><span class='line'><span class="nv">$ </span>chmod 600 authorized_keys
</span></code></pre></td></tr></table></div></figure>


<p>Now we want to limit the use of this authorized key by allowing connections
only from <strong>uno</strong>, and allowing one command only. Edit the key, and add something
like this to the beginning of the key:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">from</span><span class="o">=</span><span class="s2">&quot;192.168.100.123&quot;</span>,command<span class="o">=</span><span class="s2">&quot;/home/rbackup/validate_rsync.sh&quot;</span> ssh-rsa AX
</span><span class='line'>...remainder of key...rbackup@uno
</span></code></pre></td></tr></table></div></figure>


<p>While still user rbackup, create a script named <code>validate_rsync.sh</code> in your
home directory:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span><span class="nb">cd</span>
</span><span class='line'><span class="nv">$ </span>vim validate_rsync.sh
</span></code></pre></td></tr></table></div></figure>


<p>Contents of <code>validate_rsync.sh</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="c">#!/bin/sh</span>
</span><span class='line'><span class="k">case</span> <span class="s2">&quot;$SSH_ORIGINAL_COMMAND&quot;</span> in
</span><span class='line'>  *<span class="se">\&amp;</span>*<span class="o">)</span>
</span><span class='line'>    <span class="nb">echo</span> <span class="s2">&quot;Connection closed&quot;</span>
</span><span class='line'>    ;;
</span><span class='line'>  *<span class="se">\;</span>*<span class="o">)</span>
</span><span class='line'>    <span class="nb">echo</span> <span class="s2">&quot;Connection closed&quot;</span>
</span><span class='line'>    ;;
</span><span class='line'>    rsync*<span class="o">)</span>
</span><span class='line'>    <span class="nv">$SSH_ORIGINAL_COMMAND</span>
</span><span class='line'>    ;;
</span><span class='line'>  *true*<span class="o">)</span>
</span><span class='line'>    <span class="nb">echo</span> <span class="nv">$SSH_ORIGINAL_COMMAND</span>
</span><span class='line'>    ;;
</span><span class='line'>  *<span class="o">)</span>
</span><span class='line'>    <span class="nb">echo</span> <span class="s2">&quot;Connection closed.&quot;</span>
</span><span class='line'>    ;;
</span><span class='line'><span class="k">esac</span>
</span></code></pre></td></tr></table></div></figure>


<p>Make sure that <code>validate_rsync.sh</code> is executable by user (and group) rbackup:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>chmod 754 validate_rsync.sh
</span></code></pre></td></tr></table></div></figure>


<p>As your regular user (which can sudo):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>sudo visudo
</span></code></pre></td></tr></table></div></figure>


<p>Add this line to the bottom:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>rbackup    <span class="nv">ALL</span><span class="o">=</span>NOPASSWD:/usr/bin/rsync
</span></code></pre></td></tr></table></div></figure>


<p>For a little added security, set the rbackup user&#8217;s login shell to the <code>validate_rsync.sh</code> script:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>sudo chsh rbackup
</span></code></pre></td></tr></table></div></figure>


<p>When prompted to choose the login shell, enter <code>/home/rbackup/validate_rsync.sh</code>.</p>

<p>If you have the <code>AllowUsers</code> directive set for sshd in <code>/etc/ssh/sshd_config</code>,
make sure to add the user <code>rbackup</code> to the list, and restart sshd.</p>

<p>As root or with sudo, create a simple rsync wrapper, named <code>rsync_wrapper.sh</code> at /usr/local/bin,
containing:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="c">#!/bin/sh</span>
</span><span class='line'>/usr/bin/sudo /usr/bin/rsync <span class="s2">&quot;$@&quot;</span>;
</span></code></pre></td></tr></table></div></figure>


<h2>Testing</h2>

<h3>Test 1</h3>

<p>Become user rbackup on <strong>uno</strong>, attempt ssh to <strong>zero</strong>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>ssh zero
</span></code></pre></td></tr></table></div></figure>


<p>Expected response:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Connection closed.
</span><span class='line'>Connection to zero closed.
</span></code></pre></td></tr></table></div></figure>


<p>The &#8220;Connection closed.&#8221; with the period at the end tells us the
<code>validate_rsync.sh</code> worked as expected (echoing the last Connection closed).</p>

<h3>Test 2</h3>

<p>Become root on <strong>uno</strong>, attempt to ssh to zero-rsync (the alias set in root&#8217;s
.ssh/config):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>root# ssh zero-rsync
</span></code></pre></td></tr></table></div></figure>


<p>Expected response:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Connection closed.
</span><span class='line'>Connection to zero closed.
</span></code></pre></td></tr></table></div></figure>


<h3>Test 3</h3>

<p>Become root on <strong>uno</strong>, attempt to rsync something on <strong>zero</strong> that is restricted:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>root# rsync -ae ssh --rsync-path<span class="o">=</span><span class="s1">&#39;rsync_wrapper.sh&#39;</span> zero-rsync:/etc
</span><span class='line'>/home/regularuser/tmp/
</span></code></pre></td></tr></table></div></figure>


<p>Expected response: you should have a copy of <strong>zero&#8217;s</strong> /etc directory in
regular users tmp directory (or wherever). Important things to note in the above
command - the &#8211;rsync-path switch and using zero-rsync as the host instead of
just <strong>zero</strong>.</p>

<h2>Using rsnapshot</h2>

<p>If the above tests all work, setting up <a href="http://rsnapshot.org/">rsnapshot</a> is easy. Check
any other guide for general setup info, the relevant stuff for us to use in our
rsnapshot.conf is:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>rsync_long_args --rsync-path<span class="o">=</span>rsync_wrapper.sh --delete --numeric-ids --relative --delete-excluded
</span><span class='line'>backup rbackup@zero-rsync:/etc zero/
</span></code></pre></td></tr></table></div></figure>


<p>Remember the rsnapshot.conf file needs tabs. The <code>rsync_long_args</code> setting is
rsnapshot&#8217;s default rsync arguments, with our <code>--rsync-path=rsync_wrapper.sh</code>
added. The <code>backup</code> command has our backup user (rbackup) and the host alias
set in root@uno&#8217;s .ssh/config.</p>

<h2>References</h2>

<p>This was pieced together from various notes, blogs, and articles.
Some script source and extra-helpful information was found at:</p>

<ul>
<li><a href="http://alien.slackbook.org/dokuwiki/doku.php?id=linux:rsnapshot">alien.slackbook.org/dokuwiki/doku.php?id=linux:rsnapshot</a></li>
<li><a href="http://troy.jdmz.net/rsnapshot/">troy.jdmz.net/rsnapshot/</a></li>
<li><a href="http://www.cyberciti.biz/faq/linux-rsnapshot-backup-howto/">www.cyberciti.biz/faq/linux-rsnapshot-backup-howto/</a></li>
<li><a href="http://serverfault.com/questions/136549/rsync-over-ssh-with-root-access-on-both-sides">serverfault.com/questions/136549/rsync-over-ssh-with-root-access-on-both-sides</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Flickr CakePHP Plugin Demos]]></title>
    <link href="http://technokracy.net/2010/11/08/Flickr_CakePHP_Plugin_Demos/"/>
    <updated>2010-11-08T00:00:00-08:00</updated>
    <id>http://technokracy.net/2010/11/08/Flickr_CakePHP_Plugin_Demos</id>
    <content type="html"><![CDATA[<p>This is a small collection of (mostly) <a href="http://jquery.com/">jQuery</a> based ways to use <a href="http://flickr.com/">Flickr</a> hosted photos in your own <a href="http://cakephp.org/">CakePHP</a> application. The demos here use my <a href="http://technokracy.net/2010/11/07/Flickr_CakePHP_Plugin">CakePHP Flickr plugin</a>, which consists of two files, a component and a helper.</p>

<p>The <a href="http://github.com/chronon/flickr_demos">source code</a> for these demos is freely available, so it should be very easy to add these (or other) types of photo galleries to your own app.</p>

<h2>Available demos:</h2>

<ul>
<li><a href="http://flickrdemo.chronon.us/flickr_demos/demos/raw/">Raw</a></li>
<li><a href="http://flickrdemo.chronon.us/flickr_demos/demos/colorbox/">Colorbox</a></li>
<li><a href="http://flickrdemo.chronon.us/flickr_demos/demos/galleriffic/">Galleriffic</a></li>
<li><a href="http://flickrdemo.chronon.us/flickr_demos/demos/photostack/">Photostack</a></li>
</ul>


<p>When viewing the controller code for each demo, the $params array is merged with some defaults I&#8217;ve set in /app/bootstrap.php. Setting defaults for this Flickr plugin is totally optional, but makes for less code in your controller. The defaults I&#8217;ve set for all of these demos is:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="s1">&#39;Flickr.defaults&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>    <span class="s1">&#39;api_key&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;111122223333aaaabbbbccccdddd&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;user_id&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;1234567@N66&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;method&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;flickr.photos.search&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;format&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;php_serial&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;extras&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;description, date_taken&#39;</span>
</span><span class='line'><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>All defaults can be overridden/replaced in your controller. See the docs for my <a href="http://technokracy.net/2010/11/07/Flickr_CakePHP_Plugin">Flickr plugin</a> and the <a href="http://www.flickr.com/services/api/">Flickr API</a> for additional information.
For more information on how to use and customize any of the demo galleries you see here, check the developer websites below (and thank them for their excellent work!):</p>

<ul>
<li><a href="http://colorpowered.com/colorbox/">Colorbox</a></li>
<li><a href="http://www.twospy.com/galleriffic/">Galleriffic</a></li>
<li><a href="http://tympanus.net/codrops/2010/06/27/beautiful-photo-stack-gallery-with-jquery-and-css3/">Photostack</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Flickr CakePHP Plugin]]></title>
    <link href="http://technokracy.net/2010/11/07/Flickr_CakePHP_Plugin/"/>
    <updated>2010-11-07T00:00:00-07:00</updated>
    <id>http://technokracy.net/2010/11/07/Flickr_CakePHP_Plugin</id>
    <content type="html"><![CDATA[<p>This is a <a href="http://cakephp.org/">CakePHP</a> plugin consisting of one component and one helper that makes integrating <a href="http://flickr.com/">Flickr</a> images into your app <strong>really easy</strong>. Git clone or download from <a href="https://github.com/chronon/flickr">github</a>.</p>

<h2>Requirements:</h2>

<ul>
<li>CakePHP 1.3 (might work with 1.2, not tested)</li>
<li>PHP 5 (tested with PHP 5.3.2/Apache 2 OS X and Debian Linux)</li>
<li><code>allow_url_fopen</code> set to <code>on</code> in your php.ini (this uses PHP streams and not cURL)</li>
<li>A Flickr account and a Flickr API key</li>
</ul>


<h2>Configuration:</h2>

<p>Global configuration is optional, but useful. You can put default values in app/config/bootstrap.php or app/config/core.php like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span><span class="s1">&#39;Flickr.posting_url&#39;</span><span class="p">,</span> <span class="s1">&#39;http://api.flickr.com/services/rest/&#39;</span><span class="p">);</span>
</span><span class='line'><span class="nx">Configure</span><span class="o">::</span><span class="na">write</span><span class="p">(</span>
</span><span class='line'>    <span class="s1">&#39;Flickr.defaults&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>        <span class="s1">&#39;api_key&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;111122223333aaaabbbbccccdddd&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="s1">&#39;user_id&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;1234567@N66&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="s1">&#39;method&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;flickr.photos.search&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="s1">&#39;format&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;php_serial&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="s1">&#39;extras&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;description, date_taken&#39;</span>
</span><span class='line'>    <span class="p">)</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Pretty much any option available by the <a href="http://www.flickr.com/services/api/">Flickr API</a> can go here. All defaults can be overridden/replaced in your controller as needed.</p>

<h2>Usage:</h2>

<p>First, you might want to take a look at this plugin&#8217;s <a href="http://github.com/chronon/flickr_demos">demo project</a> code, <a href="http://flickrdemo.chronon.us/">demo site</a> or
<a href="http://technokracy.net/2010/11/08/Flickr_CakePHP_Plugin_Demos">blog entry</a>.</p>

<h3>Controller:</h3>

<p>Add the plugin&#8217;s component and helper to your controller:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="nv">$components</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;Flickr.Flickr&#39;</span><span class="p">);</span>
</span><span class='line'><span class="k">public</span> <span class="nv">$helpers</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;Flickr.Flickr&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Using the defaults above (replacing the <code>api_key</code> and <code>user_id</code> values with your own), this would get 20 photos from <code>user_id</code>&#8217;s account with the tag &#8220;Public&#8221;:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">somephotos</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
</span><span class='line'>        <span class="s1">&#39;tags&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Public&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="s1">&#39;per_page&#39;</span> <span class="o">=&gt;</span> <span class="mi">20</span><span class="p">,</span>
</span><span class='line'>    <span class="p">);</span>
</span><span class='line'>    <span class="nv">$photos</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Flickr</span><span class="o">-&gt;</span><span class="na">flickrRequest</span><span class="p">(</span><span class="nv">$params</span><span class="p">);</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s1">&#39;photos&#39;</span><span class="p">,</span> <span class="nv">$photos</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The $photos variable would be an array, which you or the included Flickr helper can do something with. Again, check the <a href="http://www.flickr.com/services/api/">Flickr API</a> for all of the available options.</p>

<p>This example gets all of the Flickr sets for <code>user_id</code>, including everything needed to display the set thumbnail, title, and description:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">somesets</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$params</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;method&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;flickr.photosets.getList&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nv">$sets</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Flickr</span><span class="o">-&gt;</span><span class="na">flickrRequest</span><span class="p">(</span><span class="nv">$params</span><span class="p">);</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s1">&#39;sets&#39;</span><span class="p">,</span> <span class="nv">$sets</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Helper:</h3>

<p>Output the 20 photos tagged &#8220;Public&#8221; you set in the above somephotos() method:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="k">echo</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Flickr</span><span class="o">-&gt;</span><span class="na">getPhotos</span><span class="p">(</span>
</span><span class='line'>    <span class="nv">$photos</span><span class="p">,</span>
</span><span class='line'>    <span class="k">array</span><span class="p">(</span><span class="s1">&#39;type&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;div&#39;</span><span class="p">),</span>
</span><span class='line'>    <span class="k">array</span><span class="p">(</span><span class="s1">&#39;rel&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;example1&#39;</span><span class="p">,</span> <span class="s1">&#39;title&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;flickr_title&#39;</span><span class="p">)</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>The resulting HTML would be:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div&gt;</span>
</span><span class='line'>    <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;http://farm5.static.flickr.com/4079/4750870838_52fc9c7167.jpg&quot;</span> <span class="na">rel=</span><span class="s">&quot;example1&quot;</span> <span class="na">title=</span><span class="s">&quot;Doi Mae Salong&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;http://farm5.static.flickr.com/4079/4750870838_52fc9c7167_s.jpg&quot;</span> <span class="na">alt=</span><span class="s">&quot;&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/a&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The helper parameters are:</p>

<ul>
<li><p>@param array $photos required The response from Flickr as an array (what this plugin&#8217;s component returns)</p></li>
<li><p>@param array $formatAttribs optional Special key: type. This is what each thumbnail is wrapped in. The default is nothing. You could use things like &#8216;type&#8217; => &#8216;div&#8217; or &#8216;type&#8217; => &#8216;li&#8217; or &#8216;type&#8217; => &#8216;p&#8217;, etc. You can also add additional HTML attributes, such as &#8216;class&#8217; => &#8216;thumb&#8217;, &#8216;id&#8217; => &#8217;<code>flickr_id</code>&#8217;, etc. See the info on the special <code>flickr_</code> values below.</p></li>
<li><p>@param array $linkAttribs optional Attributes for the <code>&lt;a&gt;</code> wrapping the thumbnail. Examples (from above &#8216;rel&#8217; => &#8216;example1&#8217;, &#8216;title&#8217; => &#8216;flickr_title&#8217;.</p></li>
<li><p>@param array $thumbAttribs optional Attributes for the <img> containing the thumbnail. Example: &#8216;class&#8217; => &#8216;little&#8217;, &#8216;alt&#8217; => &#8217;<code>flickr_title</code>&#8217;. There is also a special key named &#8216;size&#8217;, which determines the thumbnail size. Default is Flickr&#8217;s size &#8216;s&#8217;, which is 75x75. See <a href="http://www.flickr.com/services/api/misc.urls.html">Flickr&#8217;s size codes</a> for the list. For a 500px photo, do this: &#8216;size&#8217; => &#8216;n&#8217;, for 240px: &#8216;size&#8217; => &#8216;m&#8217;. You can also use numbers (but they must be valid Flickr sizes): &#8216;size&#8217; => 100.</p></li>
<li><p>@param array $imgAttribs optional Size for the large image. Default: &#8216;size&#8217; => &#8216;n&#8217;. The only parameter you can set for the linked image is &#8216;size&#8217;. See <a href="http://www.flickr.com/services/api/misc.urls.html">Flickr&#8217;s size codes</a> for the list.</p></li>
<li><p>@param array $captionAttribs optional The special keys for caption are &#8216;type&#8217;, &#8216;location&#8217;, and &#8216;caption&#8217;. The &#8216;type&#8217; key should be things like div, p, li, etc. Example: &#8216;type&#8217; => &#8216;div&#8217;. The &#8216;location&#8217; key can only have the values &#8216;before&#8217; or &#8216;after&#8217;, which determines the placement of the caption in relation to the linked thumbnail image. The &#8216;caption&#8217; key sets the contents of the caption. Examples: &#8216;caption&#8217; => &#8217;<code>flickr_description</code>&#8217;, &#8216;caption&#8217; => &#8217;<code>flickr_datetaken</code>&#8217;.</p></li>
</ul>


<p><strong>The special <code>flickr_</code> values</strong></p>

<p>These values act as variables and use the corresponding values returned from Flickr. If you use one for an &#8216;id&#8217; anywhere, such as &#8216;id&#8217; => <code>'flickr_id'</code>, in the $linkAttribs array, it will append type of a attribute to the id to make valid XHTML - so the above would produce something like: <code>id="link1234567"</code> in the HTML output. The special variables are:</p>

<ul>
<li>&#8216;flickr_id&#8217;,</li>
<li>&#8216;flickr_secret&#8217;,</li>
<li>&#8216;flickr_title&#8217;,</li>
<li>&#8216;flickr_datetaken&#8217;,</li>
<li>&#8216;flickr_description&#8217;</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[First Data Global Gateway API CakePHP Plugin]]></title>
    <link href="http://technokracy.net/2010/07/06/First_Data_Global_Gateway_API_CakePHP_Plugin/"/>
    <updated>2010-07-06T00:00:00-07:00</updated>
    <id>http://technokracy.net/2010/07/06/First_Data_Global_Gateway_API_CakePHP_Plugin</id>
    <content type="html"><![CDATA[<p>The Ggapi plugin component simplifies credit card processing using the First Data/Yourpay/Linkpoint Global Gateway API. It supports testing and live configurations, along with local to remote field mapping.</p>

<p>Once configured, all you have to do is feed the component an array of order data (fields used are up to you) and it will map the fields, build the XML string, submit the string, read the response from the gateway, and convert the response back into an array.</p>

<h2>Installation</h2>

<p>git clone or submodule add to your your app/plugins directory</p>

<h2>Requirements</h2>

<ul>
<li>PHP5 with curl support</li>
<li>CakePHP - tested on 1.3 only but should work fine with 1.2</li>
</ul>


<h2>Example usage in your controller</h2>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="c1">// attempt the charge (array $data, boolean $testing)</span>
</span><span class='line'><span class="nv">$response</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Ggapi</span><span class="o">-&gt;</span><span class="na">ggProcess</span><span class="p">(</span><span class="nv">$data</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// update the order table with the response</span>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="nv">$response</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;r_approved&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;APPROVED&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// merge the response data with the order data</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">[</span><span class="s1">&#39;Order&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">[</span><span class="s1">&#39;Order&#39;</span><span class="p">],</span> <span class="nv">$response</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// card was DECLINED</span>
</span><span class='line'>        <span class="nv">$error</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="nv">$response</span><span class="p">[</span><span class="s1">&#39;r_error&#39;</span><span class="p">]);</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Session</span><span class="o">-&gt;</span><span class="na">setFlash</span><span class="p">(</span>
</span><span class='line'>            <span class="s1">&#39;Your credit card was declined. The message was: &#39;</span><span class="o">.</span><span class="nv">$error</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
</span><span class='line'>            <span class="s1">&#39;modal&#39;</span><span class="p">,</span>
</span><span class='line'>            <span class="k">array</span><span class="p">(</span><span class="s1">&#39;class&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;modal error&#39;</span><span class="p">)</span>
</span><span class='line'>        <span class="p">);</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">redirect</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;controller&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;orders&#39;</span><span class="p">,</span> <span class="s1">&#39;action&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;checkout&#39;</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// no response from the gateway</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">Session</span><span class="o">-&gt;</span><span class="na">setFlash</span><span class="p">(</span>
</span><span class='line'>        <span class="s1">&#39;There was a problem connecting to our payment gateway, please try again.&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="s1">&#39;modal&#39;</span><span class="p">,</span>
</span><span class='line'>        <span class="k">array</span><span class="p">(</span><span class="s1">&#39;class&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;modal error&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="p">);</span>
</span><span class='line'>    <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">redirect</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;controller&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;orders&#39;</span><span class="p">,</span> <span class="s1">&#39;action&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;checkout&#39;</span><span class="p">));</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>The Bakery Article</h2>

<p><a href="http://bakery.cakephp.org/articles/chronon/2010/08/29/first-data-global-gateway-api-plugin-component">Right here</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fixing PHP 5.3.0 Build Problems on Snow Leopard]]></title>
    <link href="http://technokracy.net/2009/09/05/Fixing_PHP_5.3.0_Build_Problems_on_Snow_Leopard/"/>
    <updated>2009-09-05T00:00:00-07:00</updated>
    <id>http://technokracy.net/2009/09/05/Fixing_PHP_5.3.0_Build_Problems_on_Snow_Leopard</id>
    <content type="html"><![CDATA[<p>Building PHP from source on 10.6 produced a new problem I&#8217;ve not seen before. After successfully configuring and a few minutes of building, a link error stops the show, with the end part looking like:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Undefined symbols: " res 9 dn expand", referenced from:
</span><span class='line'>zif   dns get mx in dns.o " res 9 search", referenced from:
</span><span class='line'>zif   dns get mx in dns.o
</span><span class='line'>zif   dns check   record in dns.o " res 9 dn skipname", referenced from:
</span><span class='line'>zif   dns get mx in dns.o
</span><span class='line'>zif   dns get mx in dns.o
</span><span class='line'>ld: symbol(s) not found
</span><span class='line'>collect2: ld returned 1 exit status
</span><span class='line'>make: *** [libs/libphp5.bundle] Error 1
</span><span class='line'>Error: Status 1 encountered during processing.</span></code></pre></td></tr></table></div></figure>


<p>Some searching found MacPorts users were <a href="http://trac.macports.org/ticket/19997">seeing the same problem</a>, and the culprit was lresolv.</p>

<p>Simply adding a configure environment variable before the actual configure command created a Makefile which worked:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>LIBS=-lresolv ./configure --with-apxs2 --with-gd (etc.)</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Building PHP with MacPorts Apache2 and MySQL]]></title>
    <link href="http://technokracy.net/2009/08/31/Building_PHP_with_MacPorts_Apache2_and_MySQL/"/>
    <updated>2009-08-31T00:00:00-07:00</updated>
    <id>http://technokracy.net/2009/08/31/Building_PHP_with_MacPorts_Apache2_and_MySQL</id>
    <content type="html"><![CDATA[<p>In the past I&#8217;ve always installed Apache2 via MacPorts, MySQL from source or binary, and built PHP from source. While putting this all together on Snow Leopard, I decided to install MySQL from MacPorts as well:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>sudo port -v install apache2 mysql5-server
</span></code></pre></td></tr></table></div></figure>


<p>After everything was built and installed, I then installed the dependencies I needed for PHP 5.3 from MacPorts (openssl, mcrypt, libxml, etc.). My full configure command is:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>./configure <span class="se">\</span>
</span><span class='line'>--prefix<span class="o">=</span>/usr/local <span class="se">\</span>
</span><span class='line'>--with-apxs2<span class="o">=</span>/opt/local/apache2/bin/apxs <span class="se">\</span>
</span><span class='line'>--with-config-file-path<span class="o">=</span>/usr/local/etc/php5 <span class="se">\</span>
</span><span class='line'>--disable-cgi <span class="se">\</span>
</span><span class='line'>--enable-bcmath <span class="se">\</span>
</span><span class='line'>--with-gd <span class="se">\</span>
</span><span class='line'>--with-curl <span class="se">\</span>
</span><span class='line'>--enable-exif <span class="se">\</span>
</span><span class='line'>--enable-calendar <span class="se">\</span>
</span><span class='line'>--enable-mbstring <span class="se">\</span>
</span><span class='line'>--with-mysql<span class="o">=</span>/usr/local/mysql <span class="se">\</span>
</span><span class='line'>--with-mysqli <span class="se">\</span>
</span><span class='line'>--with-pdo-mysql<span class="o">=</span>/usr/local/mysql <span class="se">\</span>
</span><span class='line'>--with-zlib-dir<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-openssl<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-mcrypt<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-mhash<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-freetype-dir<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-jpeg-dir<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-png-dir<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-libxml-dir<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-xsl<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-gettext<span class="o">=</span>/opt/local <span class="se">\</span>
</span><span class='line'>--with-bz2 <span class="se">\</span>
</span><span class='line'>--with-iconv<span class="o">=</span>/opt/local
</span></code></pre></td></tr></table></div></figure>


<p>Notice &#8211;with-mysql=/usr/local/mysql? No matter how many paths I tried I could not get PHP to con- figure with MySQL. Apparently the MacPort changes the layout for some reason. My solution (inspired by a <a href="http://lists.macosforge.org/pipermail/macports-users/2007-December/007567.html">2007 discussion on the MacPorts mailing list</a>) involved making a few symlinks:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>sudo mkdir -p /usr/local/mysql
</span><span class='line'><span class="nv">$ </span><span class="nb">cd</span> /usr/local/mysql
</span><span class='line'><span class="nv">$ </span>sudo ln -s /opt/local/include/mysql5 include
</span><span class='line'><span class="nv">$ </span>sudo ln -s /opt/local/lib/mysql5 lib
</span><span class='line'><span class="nv">$ </span>sudo mkdir bin
</span><span class='line'><span class="nv">$ </span><span class="nb">cd </span>bin
</span><span class='line'><span class="nv">$ </span>sudo ln -s /opt/local/bin/mysql_config5 mysql_config
</span></code></pre></td></tr></table></div></figure>


<p>Once the symlinks were in place, PHP configured without error.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Unofficial Ubuntu nginx packages]]></title>
    <link href="http://technokracy.net/2008/06/11/Ubuntu_nginx_packages/"/>
    <updated>2008-06-11T00:00:00-07:00</updated>
    <id>http://technokracy.net/2008/06/11/Ubuntu_nginx_packages</id>
    <content type="html"><![CDATA[<h2>Upate:</h2>

<p>I am no longer going to be making or updating these packages. Compiling
nginx from source is very easy, and is still the recommened way to run the
current version. Clear and simple <a href="http://articles.slicehost.com/nginx">instructions are available</a> for many Linux distributions.</p>

<h2>Why Did I Make These? </h2>

<p>I want to use newer versions than what the Ubuntu universe repository
offers. The feisty package is 0.4.13 (and gutsy will be 0.5.26). Simply
compiling these from source works OK, but involves finding an init script,
setting paths in the configure line, etc. I like the &#8220;debianized&#8221; features the
official packages offer, so I used the latest debian unstable package (0.5.30)
as a base and made updated packages.</p>

<h2>Debian Note: </h2>

<p>I&#8217;ve had a report (thanks Cliff) that my package does not work on Debian/stable due to a dependency
on a later libc6. An option is to use the Debian source packages backported to Debian/stable
instead. <a href="http://www.debian.org/doc/manuals/apt-howto/ch-sourcehandling.en.html">Details on how to do this</a> are available&#8230;</p>

<h2>Changes from the official package: </h2>

<ul>
<li>commented out the first section of the prerm script because it messed
things up when removing or upgrading.</li>
<li>changed default port from 80 to 8000 because I use nginx with apache.</li>
</ul>


<p>Of course use at your own risk. I&#8217;ve done a fair amount of testing and things
work fine for me. I use the amd64.debs on my slice at
<a href="http://slicehost.com/" title="Slicehost">Slicehost</a>, and the i386.debs at home for testing.</p>

<h2>Instructions: </h2>

<p><strong>INSTALL:</strong> <code>sudo dpkg -i nginx_xxxxxx.deb</code><br/>
<strong>REMOVE:</strong> <code>sudo aptitude remove nginx</code></p>

<h2>Resources: </h2>

<ul>
<li><a href="http://nginx.net/" title="nginx homepage">Official nginx homepage</a></li>
<li><a href="http://wiki.codemongers.com/Main/" title="nginx wiki">Very useful English nginx wiki</a></li>
</ul>


<h2>Thanks: </h2>

<ul>
<li><a href="http://sysoev.ru/en/">Igor Sysoev - nginx developer</a></li>
<li>Jose Parrella - official Debian package maintainer</li>
<li>Cliff Wells - <a href="http://wiki.codemongers.com/Main">nginx wiki</a> maintainer</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[VOGUE Exquisite]]></title>
    <link href="http://technokracy.net/2008/01/24/VOGUE_Exquisite/"/>
    <updated>2008-01-24T00:00:00-08:00</updated>
    <id>http://technokracy.net/2008/01/24/VOGUE_Exquisite</id>
    <content type="html"><![CDATA[<h3>Function:</h3>

<p>The product is manufactures by the excellent craft, design essence. Jan is ingenious, filters presses the net design to be possible to cause you regardless of. Flushes adjusts the coffee or makes tea all may with ease filter. Falls the sediment, the use is extremely convenient. Dismantable. Designs easy to clean, the modeling is unique, artistic. Practical.</p>

<h3>Use Method:</h3>

<p>Turns on the cover for a jar, in the pot puts in the right amount tea. The mesh pot assumes 45 slanting to put, approximately 95 hot water slowly will break in, cover the pot, will settle 3-5 minute. Will soak the good tea to pour into the cup then.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[M-Audio Black Box and Leopard]]></title>
    <link href="http://technokracy.net/2008/01/23/M-Audio_Black_Box_and_Leopard/"/>
    <updated>2008-01-23T00:00:00-08:00</updated>
    <id>http://technokracy.net/2008/01/23/M-Audio_Black_Box_and_Leopard</id>
    <content type="html"><![CDATA[<p>Update Jan. 27: Two days after I wrote this, M-Audio released a 10.5.1 driver. Ha!</p>

<p>Possibly M-Audio is discontinuing or replacing their Black Box &#8220;guitar performance recording system&#8221; as it is no longer findable on their website. No Mac 10.5 Leopard drivers are available, and my guess is they will never be. Just for fun, I installed the 10.4.10 Tiger drivers, rebooted, and found upon (every) reboot BootstrapDaemonPerUser crashed. I ran the driver uninstall app (included with the driver) only to find BootstrapDaemonPerUser was still crashing upon reboot, and the driver was not actually uninstalled.</p>

<p>Manually uninstalling the driver was easy enough, looking at the uninstall.ss shell script inside the uninstallation app:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>rm -rf /System/Library/Extensions/M-AudioBlackBoxBoot.kext
</span><span class='line'><span class="nv">$ </span>rm -rf /System/Library/Extensions/M-AudioBlackBoxJag.kext
</span><span class='line'><span class="nv">$ </span>rm -rf /Library/StartupItems/com.m-audio.startupitem.blackbox
</span><span class='line'><span class="nv">$ </span>rm -f /etc/mach_init_per_user.d/com.m-audio.blackbox.helper.plist
</span><span class='line'><span class="nv">$ </span>rm -rf /Library/Audio/MIDI Devices/M-Audio
</span><span class='line'><span class="nv">$ </span>rm -rf /Library/PreferencePanes/M-AudioBlackBox.prefPane
</span><span class='line'><span class="nv">$ </span>rm -rf /Library/Receipts/M-Audio<span class="se">\ </span>Black<span class="se">\ </span>Box.pkg
</span><span class='line'><span class="nv">$ </span>rm -f ~/Library/Preferences/com.m-audio.prefpane.blackbox.plist
</span></code></pre></td></tr></table></div></figure>


<p>Upon rebooting, all traces of the driver were gone. Guess it was not the best idea to install it.</p>

<p>The Black Box seems to work fine with no driver installed, though Logic 8 only sees two inputs (there should be four).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[U-Turns and Chinstraps]]></title>
    <link href="http://technokracy.net/2006/01/06/U-Turns_and_Chinstraps/"/>
    <updated>2006-01-06T00:00:00-08:00</updated>
    <id>http://technokracy.net/2006/01/06/U-Turns_and_Chinstraps</id>
    <content type="html"><![CDATA[<p>The other day I was waiting for Anchali on the side of a busy four lane road in Chiang Mai. While eating an orange I watched traffic for fun and excitement&#8230;no shortage of comedy and terror! The highlight was a ridiculous U-turn. A large, new silver truck with tinted windows pulled in off the road in front of me, though kept enough of the vehicle&#8217;s back in the road to block a lane. Traffic went around the truck for a few minutes, and then it moved&#8230;backwards! While completely blocking a lane and almost going into the other lane, it backed up enough to turn around and then quickly pulled out into the road horizontally. It was trying to do a U-turn but the opposite lane was too busy, so the truck was stopped in the middle of the road blocking two lanes. Traffic piled up quickly, including two buses and even a policeman on a motorbike. They waited for a bit, then the bus started to honk. The truck finally had a small opening and dashed into the traffic of the other lane, almost taking out a few motorbikes. It then quickly parked (blocking a lane of course) in front of 7-Eleven. The door opens&#8230;and out comes a young women calm and relaxed. Mai pen rai. Unfortunately Anchali showed up before I could see what she bought at 7-Eleven&#8230;</p>

<p>On a sort of related traffic fun note, today on the way to play tennis a motorbike (little one) flew past us going around 90 km/h. The driver had one hand on the throttle and the other hand on top his head holding his helmet on&#8230;because he did not fasten the chinstrap!</p>
]]></content>
  </entry>
  
</feed>
