<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>-= n8v =- &#187; Figuring IT Out</title>
	<atom:link href="http://n8v.enteuxis.org/departments/figuring-it-out/feed/" rel="self" type="application/rss+xml" />
	<link>http://n8v.enteuxis.org</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 27 Sep 2011 00:52:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2-beta2-18055</generator>
		<item>
		<title>PHPUnit for XAMPP on Windows with Cygwin</title>
		<link>http://n8v.enteuxis.org/2011/09/phpunit-for-xampp-on-windows-with-cygwin/</link>
		<comments>http://n8v.enteuxis.org/2011/09/phpunit-for-xampp-on-windows-with-cygwin/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 23:30:41 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[xampp]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=510</guid>
		<description><![CDATA[Steps to get PHPUnit to run on my XAMPP setup with Cygwin, so I can write and run Symfony2 unit tests. 1. Upgrade PEAR Download http://pear.php.net/go-pear.phar to C:\xampp\php\go-pear.phar Run this in cmd.exe (cygwin prompts hosed somehow), taking all defaults c:\xampp\php&#62;go-pear.bat Yay. c:\xampp\php&#62;pear version PEAR Version: 1.9.4 PHP Version: 5.3.5 Zend Engine Version: 2.3.0 Running on: [...]]]></description>
			<content:encoded><![CDATA[<p>Steps to get PHPUnit to run on my XAMPP setup with Cygwin, so I can write and run Symfony2 unit tests.</p>

<h3>1. Upgrade PEAR</h3>

<ol>
<li><p>Download <code>http://pear.php.net/go-pear.phar</code>  to <var>C:\xampp\php\go-pear.phar</var></p></li>
<li><p>Run this <strong>in <var>cmd.exe</var></strong> (cygwin prompts hosed somehow), taking all defaults</p></li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="dos">c:\xampp\php<span class="sy0">&gt;</span>go-pear.bat</pre></div></div>


<ol>
<li>Yay.</li>
</ol>


<div class="wp_syntax"><div class="code"><pre class="dos">c:\xampp\php<span class="sy0">&gt;</span>pear version
PEAR Version: 1.9.4
PHP Version: 5.3.5
Zend Engine Version: 2.3.0
Running on: Windows NT FAI1046162 6.1 build 7600 <span class="sy0">(</span>Unknow Windows version Enterpr
ise Edition<span class="sy0">)</span> i586</pre></div></div>


<h3>2. Install/upgrade PHPUnit</h3>

<p>Now we can use the cygwin shell.  Not sure <a href="http://forum.kohanaframework.org/discussion/7346/installing-phpunit-on-windows-xampp/p1">all these channels are needed</a>, I did this out of order.</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">cd</span> <span class="sy0">/</span>cygdrive<span class="sy0">/</span>c<span class="sy0">/</span>xampp<span class="sy0">/</span>php
pear update-channels
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com
pear channel-discover pear.phpunit.de
&nbsp;
pear <span class="kw2">install</span> <span class="re5">--alldeps</span> phpunit<span class="sy0">/</span>PHPUnit</pre></div></div>


<h3>3. Use it</h3>

<p>XAMPP and/or PHPUnit come with a wrapper called <var>phpunit.bat</var>, which has now been upgraded, but you may need to set your <var>PHPBIN</var> environment var. Also I already have <var>c:\xampp\php</var> in my <var>$PATH</var>.</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">export</span> <span class="re2">PHPBIN</span>=c:<span class="sy0">/</span>xampp<span class="sy0">/</span>php<span class="sy0">/</span>php.exe
&nbsp;
<span class="kw3">cd</span> <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>mysf2project
phpunit.bat <span class="re5">-c</span> app</pre></div></div>


<p>Now PHPUnit works. Make tests and make them work!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/09/phpunit-for-xampp-on-windows-with-cygwin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sorting, deleting from a PropelObjectCollection</title>
		<link>http://n8v.enteuxis.org/2011/06/sorting-deleting-propel-object-collectio/</link>
		<comments>http://n8v.enteuxis.org/2011/06/sorting-deleting-propel-object-collectio/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 06:23:13 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[symfony1.4]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=503</guid>
		<description><![CDATA[Propel 1.6 (and Propel 1.5 before it) is pretty sweet (thank you François!). I had some confusion with my model&#8217;s array of related objects though, thinking it was a regular PHP array. Actually it&#8217;s a Collection, specifically a PropelObjectCollection, which implements PHP 5&#8242;s ArrayObject interface. You can do a lot of cool things with them. [...]]]></description>
			<content:encoded><![CDATA[<p>Propel 1.6 (and Propel 1.5 before it) is pretty sweet (thank you François!). I had some confusion with my model&#8217;s array of related objects though, thinking it was a regular PHP array. Actually it&#8217;s a <em>Collection</em>, specifically a PropelObjectCollection, which implements <a href="http://www.php.net/manual/en/class.arrayobject.php">PHP 5&#8242;s ArrayObject interface</a>. <a href="http://propel.posterous.com/propel-gets-collections">You can do a lot of cool things with them.</a></p>

<h2>Sorting</h2>

<p>Not immediately obvious, however, was how to sort them. This did the trick for my case (I have a Sequence field manually re-calculable through a <a href="http://jqueryui.com/demos/sortable/">jQueryUI sortable widget</a>. Also note the cool <a href="http://php.net/manual/en/functions.anonymous.php">inline anonymous function syntax</a> available since PHP 5.3. Incidentally, I&#8217;m not sure the terms <em>lambda</em> or <em>closure</em> are helpful because they&#8217;re not <em>quite</em> like Lisp lambdas or JavaScript closures.</p>


<div class="wp_syntax"><div class="code"><pre class="php"><span class="co1">// Re-sort them by Sequence, numerically</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">uasort</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">,</span> <span class="re0">$b</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$a</span><span class="sy0">-&gt;</span><span class="me1">getSequence</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">-</span> <span class="re0">$b</span><span class="sy0">-&gt;</span><span class="me1">getSequence</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>



<div class="wp_syntax"><div class="code"><pre class="php"><span class="co1">// Re-sort them as strings, case-insensitively.</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">uasort</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">,</span> <span class="re0">$b</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <a href="http://www.php.net/strnatcasecmp"><span class="kw3">strnatcasecmp</span></a><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">-&gt;</span>__toString<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$b</span><span class="sy0">-&gt;</span>__toString<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>


<h2>Deleting</h2>

<p>Thanks to the <a href="http://www.propelorm.org/docs/api/1.6/runtime/propel-runtime-collection/PropelArrayCollection.html">PropelArrayCollection API Documentation</a></p>


<div class="wp_syntax"><div class="code"><pre class="php">  <span class="coMULTI">/*
   * Remove the provided Segment object.
   *
   * @param Segment $s
   * @return Segment $s that was deleted.
   */</span>
  <span class="kw2">public</span> <span class="kw2">function</span> deleteSegment<span class="br0">&#40;</span>Segment <span class="re0">$s</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span class="re0">$s</span><span class="sy0">-&gt;</span><span class="me1">delete</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="re0">$key</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">search</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="re0">$ret</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">collSegments</span><span class="sy0">-&gt;</span><span class="me1">remove</span><span class="br0">&#40;</span><span class="re0">$key</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="kw1">return</span> <span class="re0">$s</span><span class="sy0">;</span>
  <span class="br0">&#125;</span></pre></div></div>


<p>So elsewhere,</p>


<div class="wp_syntax"><div class="code"><pre class="php">	      <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">deleteSegment</span><span class="br0">&#40;</span><span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/06/sorting-deleting-propel-object-collectio/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Relaunch the Mac OS X Dock</title>
		<link>http://n8v.enteuxis.org/2011/06/relaunch-the-macosx-dock/</link>
		<comments>http://n8v.enteuxis.org/2011/06/relaunch-the-macosx-dock/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 01:50:46 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=493</guid>
		<description><![CDATA[Problem On my Snow Leopard machine this kept happening. The &#8220;open&#8221; indicator (glowing silver ball under the app icon) in the Dock was flaky, only showing for a few apps though more were running. The task switcher (which you see when you option-tab/alt-tab) didn&#8217;t show all running apps. That RUINS it for me. I always [...]]]></description>
			<content:encoded><![CDATA[<h2>Problem</h2>

<p>On my Snow Leopard machine this kept happening.</p>

<ul>
<li>The &#8220;open&#8221; indicator  (glowing silver ball under the app icon) in the Dock was flaky, only showing for a few apps though more were running.</li>
<li>The task switcher (which you see when you <code>option-tab</code>/<code>alt-tab</code>) didn&#8217;t show all running apps. That RUINS it for me. I always use option-tab. </li>
<li>I hate rebooting.</li>
</ul>

<h2>Workaround&#8211;Restart the Dock process.</h2>

<p>Open Terminal&dagger; and use one command:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">killall</span> <span class="re5">-HUP</span> Dock</pre></div></div>


<p>Don&#8217;t be afraid of &#8220;killall&#8221;. HUP means &#8220;Hang Up&#8221; and is the normal way of telling something to relaunch.</p>

<p><a href="http://www.acmetech.com/blog/2005/09/30/mac-os-x-restart-the-dock/">Thanks to AcmeTech&#8217;s old post</a>.</p>

<p>&dagger; Terminal is located in the Utilities folder in the Applications folder. Or the quick Spotlight way is <code>command-space</code>, <samp>Terminal</samp>.</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/06/relaunch-the-macosx-dock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open files in Emacs from the Cygwin command line</title>
		<link>http://n8v.enteuxis.org/2011/05/open-files-in-emacs-from-the-cygwin-command-line/</link>
		<comments>http://n8v.enteuxis.org/2011/05/open-files-in-emacs-from-the-cygwin-command-line/#comments</comments>
		<pubDate>Fri, 27 May 2011 23:43:09 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Cygwin]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=430</guid>
		<description><![CDATA[I just got this working today. The weirdnesses of Cygwin&#8217;s half Unix-half Windows nature had stymied me before, but I&#8217;ve prevailed! I&#8217;ve got Gnu Emacs 23.3 for Windows installed in c:/emacs, and a fairly recent install of Cygwin on Windows 7. Saved this script in ~/cygemacs.sh #!/usr/bin/bash c:/emacs/bin/emacsclientw.exe -n -a &#34;c:/emacs/bin/runemacs.exe&#34; `cygpath -wa $@` Then [...]]]></description>
			<content:encoded><![CDATA[<p>I just got this working today. The weirdnesses of Cygwin&#8217;s half Unix-half Windows nature had stymied me before, but I&#8217;ve prevailed!</p>

<p>I&#8217;ve got <a href="http://ftp.gnu.org/gnu/emacs/windows/">Gnu Emacs 23.3 for Windows</a> installed in <var>c:/emacs</var>, and a fairly recent install of <a href="http://cygwin.com/">Cygwin</a> on Windows 7.</p>

<p>Saved this script in <var>~/cygemacs.sh</var></p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0">#!/usr/bin/bash</span>
c:<span class="sy0">/</span>emacs<span class="sy0">/</span>bin<span class="sy0">/</span>emacsclientw.exe <span class="re5">-n</span> <span class="re5">-a</span> <span class="st0">&quot;c:/emacs/bin/runemacs.exe&quot;</span> <span class="sy0">`</span>cygpath <span class="re5">-wa</span> $<span class="sy0">@`</span></pre></div></div>


<p>Then in my <var>~/.bashrc</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw3">alias</span> <span class="re2">ec</span>=<span class="st0">&quot;~/cygemacs.sh&quot;</span></pre></div></div>


<p>Now I can be all like,</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ ec ~<span class="sy0">/</span>.minttyrc</pre></div></div>


<p>And it opens a new frame in my running Emacs (I have <code>(server-start)</code> in my <var>~/.emacs</var>), or starts Emacs and opens the file if Emacs isn&#8217;t running yet.</p>

<p>See also: <a href="http://www.emacswiki.org/emacs/EmacsClient">EmasClient at EmacsWiki</a>.</p>

<h3>Bonus tips</h3>

<p>Yes I&#8217;m still using Subversion but also gitting going with Git.</p>

<p>And courtesy of <a href="http://shreevatsa.wordpress.com/2007/01/06/using-emacsclient/">The Lumber Room</a>, <var>in ~/.bashrc</var> and others:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">    <span class="kw3">export</span> <span class="re2">SVN_EDITOR</span>=<span class="st_h">'c:/emacs/bin/emacsclientw.exe -a c:/emacs/bin/runemacs.exe '</span></pre></div></div>


<p>And silence that annoying &#8220;kill client buffer z0mgbbq?!?&#8221; warning:</p>


<div class="wp_syntax"><div class="code"><pre class="lisp">  <span class="br0">&#40;</span>remove-hook 'kill-buffer-query-functions 'server-kill-buffer-query-<span class="kw1">function</span><span class="br0">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/05/open-files-in-emacs-from-the-cygwin-command-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sfPropel15Plugin error, &#8220;class &#8216;FooPeer&#8217; does not have a method &#8216;getUniqueColumnNames&#8217;&#8221;</title>
		<link>http://n8v.enteuxis.org/2011/05/sfpropel15plugin-error-class-foopeer-does-not-have-a-method-getuniquecolumnnames/</link>
		<comments>http://n8v.enteuxis.org/2011/05/sfpropel15plugin-error-class-foopeer-does-not-have-a-method-getuniquecolumnnames/#comments</comments>
		<pubDate>Thu, 26 May 2011 19:26:25 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[symfony 1.4]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=425</guid>
		<description><![CDATA[Stupid me made the same mistake twice in a row so I&#8217;m documenting it for humanity. I&#8217;m updating an old Symfony project to use Symfony 1.3/1.4 and Propel 1.5 through François Zaninotto&#8217;s sfPropel15Plugin. Problem: I followed the README, right? But&#8230; $ ./symfony propel:build --forms &#62;&#62; schema converting &#34;C:/web/myproject/config/schema.yml&#34; to XML &#62;&#62; schema putting C:/web/myproject/config/generated-schema.xml &#62;&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Stupid me made the same mistake twice <em>in a row</em> so I&#8217;m documenting it for humanity.</p>

<p>I&#8217;m updating an old Symfony project to use Symfony 1.3/1.4 and Propel 1.5 through François Zaninotto&#8217;s <a href="http://www.symfony-project.org/plugins/sfPropel15Plugin">sfPropel15Plugin</a>.</p>

<h2>Problem:</h2>

<p>I followed the README, right? But&#8230;</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ .<span class="sy0">/</span>symfony propel:build <span class="re5">--forms</span>
<span class="sy0">&gt;&gt;</span> schema    converting <span class="st0">&quot;C:/web/myproject/config/schema.yml&quot;</span> to XML
<span class="sy0">&gt;&gt;</span> schema    putting C:<span class="sy0">/</span>web<span class="sy0">/</span>myproject<span class="sy0">/</span>config<span class="sy0">/</span>generated-schema.xml
<span class="sy0">&gt;&gt;</span> propel    Running <span class="st0">&quot;om&quot;</span> phing task
<span class="sy0">&gt;&gt;</span> file-     C:<span class="sy0">/</span>web<span class="sy0">/</span>myproject<span class="sy0">/</span>config<span class="sy0">/</span>generated-schema.xml
<span class="sy0">&gt;&gt;</span> autoload  Resetting application autoloaders
<span class="sy0">&gt;&gt;</span> autoload  Resetting CLI autoloader
<span class="sy0">&gt;&gt;</span> propel    generating form classes
PHP Warning:  call_user_func<span class="br0">&#40;</span><span class="br0">&#41;</span> expects parameter <span class="nu0">1</span> to be a valid callback, class <span class="st_h">'FooPeer'</span> does not have a method <span class="st_h">'getUniqueColumnNames'</span> <span class="kw1">in</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\generator\sfPropelFormGenerator.class.php on line <span class="nu0">485</span>
PHP Stack trace:
PHP   <span class="nu0">1</span>. <span class="br0">&#123;</span>main<span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\symfony:<span class="nu0">0</span>
PHP   <span class="nu0">2</span>. include<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\symfony:<span class="nu0">14</span>
PHP   <span class="nu0">3</span>. sfSymfonyCommandApplication-<span class="sy0">&gt;</span>run<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\<span class="kw3">command</span>\cli.php:<span class="nu0">20</span>
PHP   <span class="nu0">4</span>. sfTask-<span class="sy0">&gt;</span>runFromCLI<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\<span class="kw3">command</span>\sfSymfonyCommandApplication.class.php:<span class="nu0">76</span>
PHP   <span class="nu0">5</span>. sfBaseTask-<span class="sy0">&gt;</span>doRun<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfTask.class.php:<span class="nu0">97</span>
PHP   <span class="nu0">6</span>. sfPropelBuildTask-<span class="sy0">&gt;</span>execute<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfBaseTask.class.php:<span class="nu0">68</span>
PHP   <span class="nu0">7</span>. sfTask-<span class="sy0">&gt;</span>run<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\task\sfPropelBuildTask.class.php:<span class="nu0">135</span>
PHP   <span class="nu0">8</span>. sfBaseTask-<span class="sy0">&gt;</span>doRun<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfTask.class.php:<span class="nu0">173</span>
PHP   <span class="nu0">9</span>. sfPropelBuildFormsTask-<span class="sy0">&gt;</span>execute<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\task\sfBaseTask.class.php:<span class="nu0">68</span>
PHP  <span class="nu0">10</span>. sfGeneratorManager-<span class="sy0">&gt;</span>generate<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\task\sfPropelBuildFormsTask.class.php:<span class="nu0">72</span>
PHP  <span class="nu0">11</span>. sfPropelFormGenerator-<span class="sy0">&gt;</span>generate<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\generator\sfGeneratorManager.class.php:<span class="nu0">126</span>
PHP  <span class="nu0">12</span>. sfGenerator-<span class="sy0">&gt;</span>evalTemplate<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\generator\sfPropelFormGenerator.class.php:<span class="nu0">106</span>
PHP  <span class="nu0">13</span>. require<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\symfony1.3\lib\generator\sfGenerator.class.php:<span class="nu0">84</span>
PHP  <span class="nu0">14</span>. sfPropelFormGenerator-<span class="sy0">&gt;</span>getUniqueColumnNames<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\data\generator\sfPropelForm\default\template\sfPropelFormGeneratedTemplate.php:<span class="nu0">34</span>
PHP  <span class="nu0">15</span>. call_user_func<span class="br0">&#40;</span><span class="br0">&#41;</span> C:\web\myproject\plugins\sfPropel15Plugin\lib\generator\sfPropelFormGenerator.class.php:<span class="nu0">485</span>
... etc ...</pre></div></div>


<h2>Solution</h2>

<p>I <a href="http://www.mail-archive.com/symfony-users@googlegroups.com/msg32719.html">removed too much of the default config in propel.ini.</a>.</p>

<p>Make sure this original line is still intact in <var>propel.ini</var>, even though you&#8217;ve removed/commented out all the <code>propel.behavior</code> lines that point to the old <var>sfPropelPlugin</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="ini">propel.behavior.default                        <span class="sy0">=</span><span class="re2"> symfony,symfony_i18n</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2011/05/sfpropel15plugin-error-class-foopeer-does-not-have-a-method-getuniquecolumnnames/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Parsing ISO 8601 dates in JavaScript</title>
		<link>http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/</link>
		<comments>http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 00:21:58 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=407</guid>
		<description><![CDATA[So, I had to deal with ISO 8601 formatted dates in JavaScript, and I can&#8217;t just use the cool ISO 8601 support in js 1.8.5&#8242;s Date.parse because of IE 6. I found a couple of examples out there on blogs but couldn&#8217;t get them to work right with my data, and I wasn&#8217;t sure I [...]]]></description>
			<content:encoded><![CDATA[<p>So, I had to deal with <a href="http://www.w3.org/TR/NOTE-datetime">ISO 8601 formatted dates</a> in JavaScript, and I can&#8217;t just use the <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/parse">cool ISO 8601 support in js 1.8.5&#8242;s Date.parse</a> because of <a href="http://www.saveie6.com/">IE 6</a>.  I found a <a href="http://dansnetwork.com/2008/11/01/javascript-iso8601rfc3339-date-parser/">couple</a> of <a href="http://anentropic.wordpress.com/2009/06/25/javascript-iso8601-parser-and-pretty-dates/">examples</a> out there on blogs but couldn&#8217;t get them to work right with my data, and I wasn&#8217;t sure I wanted <a href="http://code.google.com/p/date/">a heavyweight do-it-all solution</a>. I reluctantly reinvented the wheel so I thought I&#8217;d share it.</p>


<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="kw2">function</span> parseISO8601Date<span class="br0">&#40;</span>s<span class="br0">&#41;</span><span class="br0">&#123;</span>
&nbsp;
  <span class="co1">// parenthese matches:</span>
  <span class="co1">// year month day    hours minutes seconds  </span>
  <span class="co1">// dotmilliseconds </span>
  <span class="co1">// tzstring plusminus hours minutes</span>
  <span class="kw2">var</span> re <span class="sy0">=</span> <span class="co2">/(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/</span><span class="sy0">;</span>
&nbsp;
  <span class="kw2">var</span> d <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">;</span>
  d <span class="sy0">=</span> s.<span class="me1">match</span><span class="br0">&#40;</span>re<span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="co1">// &quot;2010-12-07T11:00:00.000-09:00&quot; parses to:</span>
  <span class="co1">//  [&quot;2010-12-07T11:00:00.000-09:00&quot;, &quot;2010&quot;, &quot;12&quot;, &quot;07&quot;, &quot;11&quot;,</span>
  <span class="co1">//     &quot;00&quot;, &quot;00&quot;, &quot;.000&quot;, &quot;-09:00&quot;, &quot;-&quot;, &quot;09&quot;, &quot;00&quot;]</span>
  <span class="co1">// &quot;2010-12-07T11:00:00.000Z&quot; parses to:</span>
  <span class="co1">//  [&quot;2010-12-07T11:00:00.000Z&quot;,      &quot;2010&quot;, &quot;12&quot;, &quot;07&quot;, &quot;11&quot;, </span>
  <span class="co1">//     &quot;00&quot;, &quot;00&quot;, &quot;.000&quot;, &quot;Z&quot;, undefined, undefined, undefined]</span>
&nbsp;
  <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span> d<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">throw</span> <span class="st0">&quot;Couldn't parse ISO 8601 date string '&quot;</span> <span class="sy0">+</span> s <span class="sy0">+</span> <span class="st0">&quot;'&quot;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="co1">// parse strings, leading zeros into proper ints</span>
  <span class="kw2">var</span> a <span class="sy0">=</span> <span class="br0">&#91;</span><span class="nu0">1</span><span class="sy0">,</span><span class="nu0">2</span><span class="sy0">,</span><span class="nu0">3</span><span class="sy0">,</span><span class="nu0">4</span><span class="sy0">,</span><span class="nu0">5</span><span class="sy0">,</span><span class="nu0">6</span><span class="sy0">,</span><span class="nu0">10</span><span class="sy0">,</span><span class="nu0">11</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i <span class="kw1">in</span> a<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    d<span class="br0">&#91;</span>a<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#93;</span> <span class="sy0">=</span> parseInt<span class="br0">&#40;</span>d<span class="br0">&#91;</span>a<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="nu0">10</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  d<span class="br0">&#91;</span><span class="nu0">7</span><span class="br0">&#93;</span> <span class="sy0">=</span> parseFloat<span class="br0">&#40;</span>d<span class="br0">&#91;</span><span class="nu0">7</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="co1">// Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])</span>
  <span class="co1">// note that month is 0-11, not 1-12</span>
  <span class="co1">// see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC</span>
  <span class="kw2">var</span> ms <span class="sy0">=</span> Date.<span class="me1">UTC</span><span class="br0">&#40;</span>d<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="sy0">,</span> d<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> <span class="sy0">-</span> <span class="nu0">1</span><span class="sy0">,</span> d<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span><span class="sy0">,</span> d<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy0">,</span> d<span class="br0">&#91;</span><span class="nu0">5</span><span class="br0">&#93;</span><span class="sy0">,</span> d<span class="br0">&#91;</span><span class="nu0">6</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="co1">// if there are milliseconds, add them</span>
  <span class="kw1">if</span> <span class="br0">&#40;</span>d<span class="br0">&#91;</span><span class="nu0">7</span><span class="br0">&#93;</span> <span class="sy0">&gt;</span> <span class="nu0">0</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>  
    ms <span class="sy0">+=</span> Math.<span class="me1">round</span><span class="br0">&#40;</span>d<span class="br0">&#91;</span><span class="nu0">7</span><span class="br0">&#93;</span> <span class="sy0">*</span> <span class="nu0">1000</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="co1">// if there's a timezone, calculate it</span>
  <span class="kw1">if</span> <span class="br0">&#40;</span>d<span class="br0">&#91;</span><span class="nu0">8</span><span class="br0">&#93;</span> <span class="sy0">!=</span> <span class="st0">&quot;Z&quot;</span> <span class="sy0">&amp;&amp;</span> d<span class="br0">&#91;</span><span class="nu0">10</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw2">var</span> offset <span class="sy0">=</span> d<span class="br0">&#91;</span><span class="nu0">10</span><span class="br0">&#93;</span> <span class="sy0">*</span> <span class="nu0">60</span> <span class="sy0">*</span> <span class="nu0">60</span> <span class="sy0">*</span> <span class="nu0">1000</span><span class="sy0">;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>d<span class="br0">&#91;</span><span class="nu0">11</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      offset <span class="sy0">+=</span> d<span class="br0">&#91;</span><span class="nu0">11</span><span class="br0">&#93;</span> <span class="sy0">*</span> <span class="nu0">60</span> <span class="sy0">*</span> <span class="nu0">1000</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
    <span class="kw1">if</span> <span class="br0">&#40;</span>d<span class="br0">&#91;</span><span class="nu0">9</span><span class="br0">&#93;</span> <span class="sy0">==</span> <span class="st0">&quot;-&quot;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      ms <span class="sy0">-=</span> offset<span class="sy0">;</span>
    <span class="br0">&#125;</span>
    <span class="kw1">else</span> <span class="br0">&#123;</span>
      ms <span class="sy0">+=</span> offset<span class="sy0">;</span>
    <span class="br0">&#125;</span>
  <span class="br0">&#125;</span>
&nbsp;
  <span class="kw1">return</span> <span class="kw2">new</span> Date<span class="br0">&#40;</span>ms<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="sy0">;</span></pre></div></div>


<p>A friendly user named <a href="http://chat.stackoverflow.com/users/419970/raynos">Raynos</a> in the <a href="http://chat.stackoverflow.com/rooms/17/javascript">new StackOverflow JavaScript chat room</a> helped me with the 0-based month gotcha. Thanks again, Raynos!</p>

<p>Also, the author of <a href="http://anentropic.wordpress.com/">Anentropic</a> tipped me off to this effort to <a href="http://promotejs.com/">promote</a> good-quality <a href="https://developer.mozilla.org/en/JavaScript">JavaScript documentation</a>, like the <a href="https://developer.mozilla.org/en/JavaScript/Reference">Mozilla Javascript Reference</a> and <a href="https://developer.mozilla.org/en/JavaScript/Guide">Javascript Guide</a>, which are still definitive after all these years.  Googling for javascript stuff usually gets you spam sites with lots of ads and less-than-stellar docs. W3schools, I love you, but seriously.</p>

<p>So listen, Google:</p>

<p><a href='https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC' title='Javascript JS Date .UTC'><img src='http://static.jsconf.us/promotejsv.gif' height='280' width='160' alt='Javascript Date .UTC'/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2010/12/parsing-iso-8601-dates-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Isolating which rogue program is trying to access the Internet using Windows 7</title>
		<link>http://n8v.enteuxis.org/2010/11/isolating-windows7-program-access-internet/</link>
		<comments>http://n8v.enteuxis.org/2010/11/isolating-windows7-program-access-internet/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 20:33:02 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[forensics]]></category>
		<category><![CDATA[malware]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=394</guid>
		<description><![CDATA[So my trusty network administrator at work was on my case because my workstation has been trying to get to Internet sites directly without a proxy, and my little machine is the top hitter on her firewall deny rules. Normally that&#8217;s a symptom of malware, so after a partial day looking for and not finding [...]]]></description>
			<content:encoded><![CDATA[<p>So my trusty network administrator at work was on my case because my workstation has been trying to get to Internet sites directly without a proxy, and my little machine is the top hitter on her firewall deny rules.  Normally that&#8217;s a symptom of malware, so after a partial day looking for and not finding what was causing it, I formatted my aging XP machine and installed Windows 7, which I&#8217;d been meaning to do anyway.</p>

<p>After several days rebuilding everything the way I like it, my machine turned up as the frequentest flyer in the firewall deny logs again!  It turns out that Windows 7 has some better tools that made it easier to find what was going on.
<span id="more-394"></span></p>

<p>First, I wrote a new Windows Firewall rule to block all outbound traffic to ports 80 and 443.  Easy enough. My network admin was off my back!</p>

<p>But I wanted to find out what was causing the trouble.  I found a Microsoft TechNet article that showed me how to <a href="http://technet.microsoft.com/en-us/library/cc754714(WS.10).aspx">Enable IPsec and Windows Firewall Audit Events</a>.</p>

<p>I had trouble isolating the events in the snazzy new Vista/Win7 Event Viewer but finally came up with this manual XPath query after some googling and trial and error.  It shows requests to port 80 which are blocked by the firewall, filtering out inbound requests so only the outbound traffic shows up:</p>


<div class="wp_syntax"><div class="code"><pre class="xml"><span class="sc3"><span class="re1">&lt;QueryList<span class="re2">&gt;</span></span></span>
  <span class="sc3"><span class="re1">&lt;Query</span> <span class="re0">Id</span>=<span class="st0">&quot;0&quot;</span> <span class="re0">Path</span>=<span class="st0">&quot;Security&quot;</span><span class="re2">&gt;</span></span>
    <span class="sc3"><span class="re1">&lt;Select</span> <span class="re0">Path</span>=<span class="st0">&quot;Security&quot;</span><span class="re2">&gt;</span></span>
       *[System[(EventID=5157)]] 
       and *[EventData[Data[@Name=&quot;DestPort&quot;] = &quot;80&quot;]]
    <span class="sc3"><span class="re1">&lt;/Select<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;Suppress</span> <span class="re0">Path</span>=<span class="st0">&quot;Security&quot;</span><span class="re2">&gt;</span></span>
       *[EventData[Data[@Name=&quot;Direction&quot;] = &quot;%%14592&quot;]]
    <span class="sc3"><span class="re1">&lt;/Suppress<span class="re2">&gt;</span></span></span>
  <span class="sc3"><span class="re1">&lt;/Query<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/QueryList<span class="re2">&gt;</span></span></span></pre></div></div>


<p>I feel obligated to point out that grepping a text file would have been much easier.</p>

<p>Also make sure to <a href="http://technet.microsoft.com/en-us/library/cc754714(WS.10).aspx#BKMK_Proc1">turn auditing off again</a> when you&#8217;re all done.</p>

<p>My problem now, it turns out, was that the Weby plugin in <a href="http://launchy.net/">Launchy</a> was scanning all the built-in Firefox and IE bookmarks every 10 minutes.  Maybe it hits each bookmark and scrapes the &lt;title&gt; tag contents to make it launchable?  Whatever.  I disabled the Weby plugin and the requests ceased.  Launchy also has proxy settings, but they won&#8217;t work here because there aren&#8217;t any NTLM authentication options.</p>

<p>I&#8217;m not entirely sure my first problem was the same&#8230; it might have been malware after all.  But at least this time I know what was going on and don&#8217;t have to rebuild everything.</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2010/11/isolating-windows7-program-access-internet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Convincing IIS7 to accept URLs containing plusses (+)</title>
		<link>http://n8v.enteuxis.org/2010/07/convincing-iis7-to-accept-urls-containing-plusses/</link>
		<comments>http://n8v.enteuxis.org/2010/07/convincing-iis7-to-accept-urls-containing-plusses/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 00:16:50 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[IIS7]]></category>
		<category><![CDATA[rewriting]]></category>
		<category><![CDATA[URL]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=383</guid>
		<description><![CDATA[Problem: Old retiring IIS 5.0 web server has been accepting URLs containing plus (+) for spaces instead of %20 for like 74 years. People have the old URLs bookmarked and stuff so they&#8217;ll keep going to them. The content will still exist on the replacement IIS 7 web server. Wouldn&#8217;t it be nice to make [...]]]></description>
			<content:encoded><![CDATA[<h2>Problem:</h2>

<p>Old retiring IIS 5.0 web server has been accepting URLs containing plus (+) for spaces instead of %20 for like 74 years.  People have the old URLs bookmarked and stuff so they&#8217;ll keep going to them.  The content will still exist on the replacement IIS 7 web server.   Wouldn&#8217;t it be nice to make it transparent?</p>

<p>(Not to mention &#8220;foo+bar.pdf&#8221; is sane, but &#8220;foo%20bar.pdf&#8221; reads &#8220;foo percent twenty bar&#8221;, awkwardly. )</p>

<p>The problem is that IIS7 by default considers naked plusses in the URL as scary and <a href="http://support.microsoft.com/kb/942076/">sends a 404.11, URL_DOUBLE_ESCAPED error</a>.  Even if you convince it the URL is OK, it no longer maps plus to space and finds a piece of content.</p>

<p>On the old IIS 5.0 server these URLs both work, serving up the document named &#8220;foo bar.pdf&#8221;:</p>

<pre><code>http://server/foo+bar.pdf

http://server/foo%20bar.pdf

</code></pre>

<p>On the new IIS 7 (Windows 2008) server, the second URL works but the first one gives an error.</p>

<h2>Solution:</h2>

<p>I put this in my application&#8217;s <var>web.config</var> file:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="xml"><span class="sc3"><span class="re1">&lt;?xml</span> <span class="re0">version</span>=<span class="st0">&quot;1.0&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">?&gt;</span></span>
<span class="sc3"><span class="re1">&lt;configuration<span class="re2">&gt;</span></span></span>
  <span class="sc3"><span class="re1">&lt;system.webServer<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;security<span class="re2">&gt;</span></span></span>
      <span class="sc3"><span class="re1">&lt;requestFiltering</span> <span class="re0">allowDoubleEscaping</span>=<span class="st0">&quot;True&quot;</span> <span class="re2">/&gt;</span></span>
    <span class="sc3"><span class="re1">&lt;/security<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;rewrite<span class="re2">&gt;</span></span></span>
      <span class="sc3"><span class="re1">&lt;rules<span class="re2">&gt;</span></span></span>
        <span class="sc3"><span class="re1">&lt;rule</span> <span class="re0">name</span>=<span class="st0">&quot;RewriteUserFriendlyURL1&quot;</span> <span class="re0">stopProcessing</span>=<span class="st0">&quot;false&quot;</span><span class="re2">&gt;</span></span>
          <span class="sc3"><span class="re1">&lt;match</span> <span class="re0">url</span>=<span class="st0">&quot;\+&quot;</span> <span class="re2">/&gt;</span></span>
          <span class="sc3"><span class="re1">&lt;conditions<span class="re2">&gt;</span></span></span>
            <span class="sc3"><span class="re1">&lt;add</span> <span class="re0">input</span>=<span class="st0">&quot;{REQUEST_FILENAME}&quot;</span> <span class="re0">matchType</span>=<span class="st0">&quot;IsFile&quot;</span> <span class="re0">negate</span>=<span class="st0">&quot;true&quot;</span> <span class="re2">/&gt;</span></span>
            <span class="sc3"><span class="re1">&lt;add</span> <span class="re0">input</span>=<span class="st0">&quot;{REQUEST_FILENAME}&quot;</span> <span class="re0">matchType</span>=<span class="st0">&quot;IsDirectory&quot;</span> <span class="re0">negate</span>=<span class="st0">&quot;true&quot;</span> <span class="re2">/&gt;</span></span>
          <span class="sc3"><span class="re1">&lt;/conditions<span class="re2">&gt;</span></span></span>
          <span class="sc3"><span class="re1">&lt;action</span> <span class="re0">type</span>=<span class="st0">&quot;Rewrite&quot;</span> <span class="re0">url</span>=<span class="st0">&quot;{UrlDecode:{REQUEST_URI}}&quot;</span> <span class="re2">/&gt;</span></span>
        <span class="sc3"><span class="re1">&lt;/rule<span class="re2">&gt;</span></span></span>
      <span class="sc3"><span class="re1">&lt;/rules<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;/rewrite<span class="re2">&gt;</span></span></span>
  <span class="sc3"><span class="re1">&lt;/system.webServer<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/configuration<span class="re2">&gt;</span></span></span></pre></td></tr></table></div>


<p>the <code>allowDoubleEscaping</code> directive on line 5 <a href="http://serverfault.com/questions/76013/iis6-vs-iis7-and-iis7-5-handling-urls-with-plus-sign-in-base-not-querystri">solves the first part of the problem</a>, allowing IIS to handle unescaped plusses.  The rewrite rule below passes the requested URI through the <a href="http://learn.iis.net/page.aspx/465/url-rewrite-module-configuration-reference/#String_functions">UrlDecode function</a> (line 15), which thankfully still remembers the time-tested convention of plus equaling space. Now both forms of the URL work.</p>

<p>(I didn&#8217;t really write the rewrite stanza, I just stumbled around with the rewrite URL editor in the IIS Manager until it worked)</p>

<p>Yay!</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2010/07/convincing-iis7-to-accept-urls-containing-plusses/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding WordPress-like tags to a Symfony 1.4 admin generator form</title>
		<link>http://n8v.enteuxis.org/2010/05/adding-wordpress-like-tags-to-a-symfony-1-4-admin-generator-form/</link>
		<comments>http://n8v.enteuxis.org/2010/05/adding-wordpress-like-tags-to-a-symfony-1-4-admin-generator-form/#comments</comments>
		<pubDate>Sat, 15 May 2010 01:15:46 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=325</guid>
		<description><![CDATA[Update 2010-08-06: It looks like the sfDoctrineActAsTaggablePlugin team has incorporated much of this into the version they released today. I&#8217;ll post more when I get a chance to try it out. This week I used the sfDoctrineActAsTaggablePlugin to add tag behavior to a Symfony project. My goal was to have a user interface similar to [...]]]></description>
			<content:encoded><![CDATA[<p><ins datetime="2010-08-06T23:57:46+00:00">Update 2010-08-06:  It looks like the sfDoctrineActAsTaggablePlugin team has incorporated much of this into the version they released today.  I&#8217;ll post more when I get a chance to try it out.</ins></p>

<p>This week I used the <a href="http://www.symfony-project.org/plugins/sfDoctrineActAsTaggablePlugin">sfDoctrineActAsTaggablePlugin</a> to add tag behavior to a Symfony project.  My goal was to have a user interface similar to WordPress&#8217;s, which I like a lot:</p>

<p><img src="http://n8v.enteuxis.org/wp-content/uploads/2010/05/wordpress_tag_ui.png" alt="Tag user interface in WordPress" title="wordpress_tag_ui" width="290" height="174" class="aligncenter size-full wp-image-330" /></p>

<p>Another goal was to use <a href="http://jqueryui.com/">JQuery UI</a> with the nice visual theme I built with their <a href="http://jqueryui.com/themeroller/">Theme Roller tool</a> (which I had already installed and added to my symfony project).</p>

<p>The documentation was a little bit sparse and I&#8217;ll probably end up doing this again, so here are relevant instructions so Future Me and others may also benefit:
<span id="more-325"></span></p>

<h2>Set up</h2>

<ol>
    <li>get/install/checkout sfDoctrineActAsTaggablePlugin.  I use this line in the `svn:externals` property on <var>plugins/</var>:
  
<pre>sfDoctrineActAsTaggablePlugin/ http://svn.symfony-project.com/plugins/sfDoctrineActAsTaggablePlugin/tags/RELEASE_1_0_0</pre>
</li>

    <li>enable the plugin in <var>config/ProjectConfiguration.class.php</var>.


<div class="wp_syntax"><div class="code"><pre class="php">    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">enablePlugins</span><span class="br0">&#40;</span>
                         <span class="st_h">'sfDoctrinePlugin'</span><span class="sy0">,</span> 
                         <span class="sy0">...</span>
			 <span class="st_h">'sfDoctrineActAsTaggablePlugin'</span>
			 <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>



</li>

    <li>Add the Taggable behavior to your model(s) in <var>config/doctrine/schema.yml</var>


<div class="wp_syntax"><div class="code"><pre class="yaml">    actAs:            { Timestampable: ~ , Taggable: ~ }</pre></div></div>




         (<strong>not</strong> <code>templates: [Taggable]</code> as the README says)

</li>
    <li>Rebuild your model and forms and everything.  My favorite way is to dump the old data to fixtures, then rebuild everything.


<div class="wp_syntax"><div class="code"><pre class="bash">.<span class="sy0">/</span>symfony <span class="re5">--color</span> doctrine:data-dump
.<span class="sy0">/</span>symfony <span class="re5">--color</span> doctrine:build <span class="re5">--all</span> <span class="re5">--and-load</span> <span class="re5">--no-confirmation</span></pre></div></div>




</li>

</ol>

<p>At this point you should have new database tables <code>tag</code> and <code>tagging</code>, and the proper model relations and everything.</p>

<h2>Form fields for tags</h2>

<div id="attachment_352" class="wp-caption aligncenter" style="width: 490px"><img src="http://n8v.enteuxis.org/wp-content/uploads/2010/05/my_tags_ui.png" alt="" title="my_tags_ui" width="480" height="150" class="size-full wp-image-352" /><p class="wp-caption-text">UI for entering tags, displaying existing tags (with remove buttons)</p></div>

<p>I&#8217;m going to have</p>

<ol>
<li>a single text input field for adding tags, </li>
<li>a link to display a tag cloud (see below) if the user wants to pick tags by clicking instead of typing</li>
<li>a styled list of existing tags with delete icons</li>
<li>a hidden field for storing tags to be removed after clicking on the delete icons.</li>
</ol>

<p>The delete icons will trigger a Javascript function which populates the hidden field and hides the tag.  Changes won&#8217;t be saved until the user submits the form, so we&#8217;ll also provide a little reminder.</p>

<img src="http://n8v.enteuxis.org/wp-content/uploads/2010/05/my_tags_removed.png" alt="" title="my_tags_removed" width="461" height="86" class="size-full wp-image-354" />

<ol>
    <li>add the tag field(s) to the <code>configure()</code> method of your form, in <var>lib/form/doctrine/<samp>Model</samp>Form.class.php</var>.


<div class="wp_syntax"><div class="code"><pre class="php">    <span class="co1">// this text appears in gray until the user focuses on the field</span>
    <span class="re0">$default</span> <span class="sy0">=</span> <span class="st_h">'Add tags with commas'</span><span class="sy0">;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">widgetSchema</span><span class="br0">&#91;</span><span class="st_h">'new_tags'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">new</span> sfWidgetFormInput
      <span class="br0">&#40;</span>
       <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'label'</span>   <span class="sy0">=&gt;</span>  <span class="st_h">'Add Tags'</span><span class="sy0">,</span> <span class="st_h">'default'</span>   <span class="sy0">=&gt;</span>  <span class="re0">$default</span><span class="br0">&#41;</span><span class="sy0">,</span>
       <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
             <span class="st_h">'onclick'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;if (this.value=='<span class="es4">$default</span>') { 
                                this.value = ''; this.style.color='black'; }&quot;</span><span class="sy0">,</span> 
             <span class="st_h">'size'</span>   <span class="sy0">=&gt;</span>  <span class="st_h">'32'</span><span class="sy0">,</span>
	     <span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'new_tags'</span><span class="sy0">,</span> 
             <span class="co1">// don't let the browser autocomplete.  We'll add typeahead, below</span>
	     <span class="st_h">'autocomplete'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;off&quot;</span><span class="sy0">,</span>      
	     <span class="st_h">'style'</span> <span class="sy0">=&gt;</span> <span class="st_h">'color:#aaa'</span>
	     <span class="br0">&#41;</span>
       <span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="co1">// allow the field to remain blank</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">setValidator</span><span class="br0">&#40;</span><span class="st_h">'new_tags'</span><span class="sy0">,</span> <span class="kw2">new</span> sfValidatorString<span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'required'</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="co1">// this hidden field will be populated with JavaScript.</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">widgetSchema</span><span class="br0">&#91;</span><span class="st_h">'remove_tags'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">new</span> sfWidgetFormInputHidden<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">setValidator</span><span class="br0">&#40;</span><span class="st_h">'remove_tags'</span><span class="sy0">,</span> <span class="kw2">new</span> sfValidatorString<span class="br0">&#40;</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'required'</span> <span class="sy0">=&gt;</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>



</li>
    <li>Add a partial with the admin generator.  In <var>apps/frontend/modules/<samp>mymodule</samp>/config/generator.yml</var>:


<div class="wp_syntax"><div class="code"><pre class="yaml">      form:
        display:
          # add another section after the other fields...
          Tags: [_tags]</pre></div></div>




</li>
    <li>edit the partial, <var>apps/frontend/modules/<samp>mymodule</samp>/templates/_tags.php</var>


<div class="wp_syntax"><div class="code"><pre class="php"><span class="kw2">&lt;?php</span> use_helper<span class="br0">&#40;</span><span class="st_h">'JavascriptBase'</span><span class="sy0">,</span> <span class="st_h">'Tags'</span><span class="br0">&#41;</span>  <span class="sy1">?&gt;</span>
<span class="kw2">&lt;?php</span>  
&nbsp;
<span class="co1">// much of this I copied and adapted from a cached admin generator template.</span>
<span class="re0">$name</span> <span class="sy0">=</span> <span class="st_h">'new_tags'</span><span class="sy0">;</span> <span class="re0">$label</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span> <span class="re0">$help</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span> 
<span class="re0">$class</span> <span class="sy0">=</span> <span class="st_h">'sf_admin_form_row sf_admin_text sf_admin_form_field_tags'</span><span class="sy0">;</span>
&nbsp;
 <span class="sy1">?&gt;</span>
&nbsp;
  &lt;div class=&quot;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$class</span> <span class="sy1">?&gt;</span><span class="kw2">&lt;?php</span> <span class="re0">$form</span><span class="br0">&#91;</span><span class="re0">$name</span><span class="br0">&#93;</span><span class="sy0">-&gt;</span><span class="me1">hasError</span><span class="br0">&#40;</span><span class="br0">&#41;</span> and <span class="kw1">print</span> <span class="st_h">' errors'</span> <span class="sy1">?&gt;</span>&quot;&gt;
    <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$form</span><span class="br0">&#91;</span><span class="re0">$name</span><span class="br0">&#93;</span><span class="sy0">-&gt;</span><span class="me1">renderError</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
    &lt;div&gt;
      <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$form</span><span class="br0">&#91;</span><span class="re0">$name</span><span class="br0">&#93;</span><span class="sy0">-&gt;</span><span class="me1">renderLabel</span><span class="br0">&#40;</span><span class="re0">$label</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&nbsp;
      &lt;div class=&quot;content&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$form</span><span class="br0">&#91;</span><span class="re0">$name</span><span class="br0">&#93;</span><span class="sy0">-&gt;</span><span class="me1">render</span><span class="br0">&#40;</span><span class="re0">$attributes</span> instanceof sfOutputEscaper ? <span class="re0">$attributes</span><span class="sy0">-&gt;</span><span class="me1">getRawValue</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">:</span> <span class="re0">$attributes</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&nbsp;
&nbsp;
<span class="kw2">&lt;?php</span> <span class="co1">// tag cloud will go here, see below ?&gt;</span>
&nbsp;
&nbsp;
<span class="sy0">&lt;/</span>div<span class="sy0">&gt;</span>
&nbsp;
      <span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$help</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
        &lt;div class=&quot;help&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> __<span class="br0">&#40;</span><span class="re0">$help</span><span class="sy0">,</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st_h">'messages'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>&lt;/div&gt;
      <span class="kw2">&lt;?php</span> <span class="kw1">elseif</span> <span class="br0">&#40;</span><span class="re0">$help</span> <span class="sy0">=</span> <span class="re0">$form</span><span class="br0">&#91;</span><span class="re0">$name</span><span class="br0">&#93;</span><span class="sy0">-&gt;</span><span class="me1">renderHelp</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
        &lt;div class=&quot;help&quot;&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$help</span> <span class="sy1">?&gt;</span>&lt;/div&gt;
      <span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>
    &lt;/div&gt;
  &lt;/div&gt;
&nbsp;
<span class="kw2">&lt;?php</span> <span class="co1">// list of current tags, with remove buttons ?&gt;</span>
<span class="sy0">&lt;</span>div <span class="kw2">class</span><span class="sy0">=</span><span class="st0">&quot;sf_admin_form_row sf_admin_text sf_admin_form_field_tags&quot;</span><span class="sy0">&gt;</span>
<span class="sy0">&lt;</span>div<span class="sy0">&gt;</span>
<span class="sy0">&lt;</span>label<span class="sy0">&gt;</span>Current tags<span class="sy0">&lt;/</span>label<span class="sy0">&gt;</span>
<span class="sy0">&lt;</span>div <span class="kw2">class</span><span class="sy0">=</span><span class="st0">&quot;content&quot;</span><span class="sy0">&gt;</span>
<span class="sy0">&lt;</span>div <span class="kw2">class</span><span class="sy0">=</span><span class="st0">&quot;taglist&quot;</span><span class="sy0">&gt;</span>   
   <span class="kw2">&lt;?php</span> <span class="kw1">foreach</span> <span class="br0">&#40;</span> <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getObject</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getTags</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">as</span> <span class="re0">$t</span><span class="br0">&#41;</span><span class="sy0">:</span>   <span class="sy1">?&gt;</span>
    &lt;span&gt;&lt;nobr&gt;<span class="kw2">&lt;?php</span> 
&nbsp;
<span class="kw1">echo</span> link_to_function<span class="br0">&#40;</span><span class="st0">&quot;Remove '<span class="es4">$t</span>'&quot;</span><span class="sy0">,</span> 
           <span class="st0">&quot;remove_tag(&quot;</span><span class="sy0">.</span><a href="http://www.php.net/json_encode"><span class="kw3">json_encode</span></a><span class="br0">&#40;</span><span class="re0">$t</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st0">&quot;, this.parentElement)&quot;</span><span class="sy0">,</span> 
           <span class="st0">&quot;class=removetag&quot;</span><span class="br0">&#41;</span>
&nbsp;
  <span class="sy1">?&gt;</span>&amp;nbsp;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$t</span>  <span class="sy1">?&gt;</span>&lt;/nobr&gt;&lt;/span&gt;
    <span class="kw2">&lt;?php</span> <span class="kw1">endforeach</span><span class="sy0">;</span>  <span class="sy1">?&gt;</span>
&lt;/div&gt;
&lt;span id=&quot;remove_tag_help&quot; style=&quot;display:none;&quot;&gt;Tag(s) removed. Remember to save the complaint.&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&nbsp;
&lt;/div&gt;</pre></div></div>



</li>

    <li>Add a Javascript function to support the &#8220;remove tag&#8221; buttons.


<div class="wp_syntax"><div class="code"><pre class="javascript">$<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span class="co1">// add fancy jQuery UI button styles.  See additional in &quot;CSS&quot; below</span>
	    $<span class="br0">&#40;</span><span class="st0">&quot;.taglist a&quot;</span><span class="br0">&#41;</span>.<span class="me1">button</span><span class="br0">&#40;</span><span class="br0">&#123;</span>icons<span class="sy0">:</span><span class="br0">&#123;</span>primary<span class="sy0">:</span><span class="st0">'ui-icon-trash'</span><span class="br0">&#125;</span><span class="sy0">,</span> text<span class="sy0">:</span> <span class="kw2">false</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw2">function</span> remove_tag <span class="br0">&#40;</span>tag<span class="sy0">,</span> element<span class="br0">&#41;</span> <span class="br0">&#123;</span>
  remove_field <span class="sy0">=</span> $<span class="br0">&#40;</span><span class="st0">&quot;#complaint_remove_tags&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="kw1">if</span> <span class="br0">&#40;</span> remove_field.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">length</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    remove_field.<span class="me1">val</span><span class="br0">&#40;</span> remove_field.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span>  <span class="sy0">+</span> <span class="st0">&quot;,&quot;</span> <span class="sy0">+</span> tag <span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  <span class="kw1">else</span> <span class="br0">&#123;</span>
    remove_field.<span class="me1">val</span><span class="br0">&#40;</span> tag <span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  $<span class="br0">&#40;</span>element<span class="br0">&#41;</span>.<span class="me1">hide</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  $<span class="br0">&#40;</span><span class="st0">&quot;#remove_tag_help&quot;</span><span class="br0">&#41;</span>.<span class="me1">show</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>




</li>
    <li>edit the `processForm` action to process the `new_tags` and `remove_tags` fields.    I started by copying the `processForm` method from <var>cache/frontend/dev/modules/auto<samp>Mymodel</samp>/actions/actions.class.php</var> into <var>apps/frontend/modules/<samp>mymodule</samp>/actions/actions.class.php</var>, then added code after validation:


<div class="wp_syntax"><div class="code"><pre class="php">  <span class="kw2">protected</span> <span class="kw2">function</span> processForm<span class="br0">&#40;</span>sfWebRequest <span class="re0">$request</span><span class="sy0">,</span> sfForm <span class="re0">$form</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">bind</span><span class="br0">&#40;</span><span class="re0">$request</span><span class="sy0">-&gt;</span><span class="me1">getParameter</span><span class="br0">&#40;</span><span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$request</span><span class="sy0">-&gt;</span><span class="me1">getFiles</span><span class="br0">&#40;</span><span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
    <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">isValid</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
      <span class="re0">$notice</span> <span class="sy0">=</span> <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getObject</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">isNew</span><span class="br0">&#40;</span><span class="br0">&#41;</span> ? <span class="st_h">'The item was created successfully.'</span> <span class="sy0">:</span> <span class="st_h">'The item was updated successfully.'</span><span class="sy0">;</span>
&nbsp;
      <span class="co1">// NEW: deal with tags</span>
      <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getValue</span><span class="br0">&#40;</span><span class="st_h">'remove_tags'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="kw1">foreach</span> <span class="br0">&#40;</span><a href="http://www.php.net/preg_split"><span class="kw3">preg_split</span></a><span class="br0">&#40;</span><span class="st_h">'/\s*,\s*/'</span><span class="sy0">,</span> <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getValue</span><span class="br0">&#40;</span><span class="st_h">'remove_tags'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">as</span> <span class="re0">$tag</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	  <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getObject</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">removeTag</span><span class="br0">&#40;</span><span class="re0">$tag</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
      <span class="br0">&#125;</span>
      <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getValue</span><span class="br0">&#40;</span><span class="st_h">'new_tags'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="kw1">foreach</span> <span class="br0">&#40;</span><a href="http://www.php.net/preg_split"><span class="kw3">preg_split</span></a><span class="br0">&#40;</span><span class="st_h">'/\s*,\s*/'</span><span class="sy0">,</span> <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getValue</span><span class="br0">&#40;</span><span class="st_h">'new_tags'</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">as</span> <span class="re0">$tag</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
          <span class="co1">// sorry, it would be better to not hard-code this string</span>
	  <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$tag</span> <span class="sy0">==</span> <span class="st_h">'Add tags with commas'</span><span class="br0">&#41;</span> <span class="kw1">continue</span><span class="sy0">;</span>
	  <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">getObject</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">addTag</span><span class="br0">&#40;</span><span class="re0">$tag</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span>
      <span class="br0">&#125;</span>
&nbsp;
      try <span class="br0">&#123;</span>
        <span class="re0">$complaint</span> <span class="sy0">=</span> <span class="re0">$form</span><span class="sy0">-&gt;</span><span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="co1">// and the remainder is just pasted from the generated actions file</span></pre></div></div>




</li>
</ol>

<p>Yay!  Now I can add, display, and remove tags.   Now for the fancy parts.</p>

<h2>Typeahead tag autocompletion</h2>

<p><img src="http://n8v.enteuxis.org/wp-content/uploads/2010/05/my_tags_typeahead.png" alt="" title="my_tags_typeahead" width="480" height="150" class="aligncenter size-full wp-image-360" /></p>

<p>As detailed in the README, sfDoctrineActAsTaggablePlugin has typeahead support. I tried it, but I didn&#8217;t feel like the user interaction was quite smooth enough, and I wanted to use the excellent, beautiful, and user-expectation-meeting <a href="http://jqueryui.com/demos/autocomplete/">jQuery UI Autocomplete widget</a>.</p>

<p>I ended up using the action provided by sfDoctrineActAsTaggablePlugin, but modified the view to return JSON instead of an HTML &lt;ul&gt;, and I used the <a href="http://jqueryui.com/demos/autocomplete/multiple-remote.html">multiple, remote demo</a> code from <a href="http://jqueryui.com/demos/autocomplete/#multiple-remote">the jQuery UI Autocomplete documentation</a>.</p>

<ol>
    <li>override the <code>completeSuccess</code> view for the <code>taggableComplete/complete</code> action


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="kw2">mkdir</span> <span class="re5">-p</span> apps<span class="sy0">/</span>frontend<span class="sy0">/</span>modules<span class="sy0">/</span>taggableComplete<span class="sy0">/</span>templates
<span class="kw2">touch</span> apps<span class="sy0">/</span>frontend<span class="sy0">/</span>modules<span class="sy0">/</span>taggableComplete<span class="sy0">/</span>templates<span class="sy0">/</span>completeSuccess.php</pre></div></div>




And here is my new template:


<div class="wp_syntax"><div class="code"><pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="co1">// we're rewriting the view for the taggable plugin to output JSON instead of HTML</span>
<span class="co1">// see http://wiki.jqueryui.com/Autocomplete</span>
&nbsp;
<span class="re0">$tags_simple</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">foreach</span> <span class="br0">&#40;</span> <span class="re0">$tagSuggestions</span> <span class="kw1">as</span> <span class="re0">$suggestion</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
  <span class="re0">$tags_simple</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span>  <span class="re0">$suggestion</span><span class="br0">&#91;</span><span class="st_h">'suggested'</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">echo</span> <a href="http://www.php.net/json_encode"><span class="kw3">json_encode</span></a><span class="br0">&#40;</span><span class="re0">$tags_simple</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>




You can test your autocomplete action with a URL like <code>http://myserver/myproject/taggableComplete/complete/current/<samp>p</samp></code>.

In my case (because I have some data in my <code>tag</code> table) it returns this JSON-formatted array:


<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="br0">&#91;</span><span class="st0">&quot;PHP&quot;</span><span class="sy0">,</span><span class="st0">&quot;plugins&quot;</span><span class="br0">&#93;</span></pre></div></div>



</li>

    <li>Add jQuery UI javascript.  I used a <code>&lt;script&gt;</code> section in my <var>_tags.php</var> partial, but you could also use an external javascript file (but mind the line of PHP code using the <code>url_for()</code> helper).


<div class="wp_syntax"><div class="code"><pre class="javascript">	$<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
<span class="co1">// for debug info, uncomment these lines and add a &lt;div id=&quot;autocomplete_log&quot;&gt;</span>
<span class="co1">// 		function log(message) {</span>
<span class="co1">// 			$(&quot;&lt;div/&gt;&quot;).text(message).prependTo(&quot;#autocomplete_log&quot;);</span>
<span class="co1">// 			$(&quot;#autocomplete_log&quot;).attr(&quot;scrollTop&quot;, 0);</span>
<span class="co1">// 		}</span>
		<span class="kw2">function</span> split<span class="br0">&#40;</span>val<span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">return</span> val.<span class="me1">split</span><span class="br0">&#40;</span><span class="co2">/\s*,\s*/</span><span class="br0">&#41;</span><span class="sy0">;</span>
		<span class="br0">&#125;</span>
		<span class="kw2">function</span> extractLast<span class="br0">&#40;</span>term<span class="br0">&#41;</span> <span class="br0">&#123;</span>
		        last <span class="sy0">=</span> split<span class="br0">&#40;</span>term<span class="br0">&#41;</span>.<span class="me1">pop</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// 			log ( &quot;extracted last = &quot;+last );</span>
			<span class="kw1">return</span> last<span class="sy0">;</span>
		<span class="br0">&#125;</span>
&nbsp;
&nbsp;
		$<span class="br0">&#40;</span><span class="st0">&quot;#new_tags&quot;</span><span class="br0">&#41;</span>.<span class="me1">autocomplete</span><span class="br0">&#40;</span><span class="br0">&#123;</span>
&nbsp;
			source<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span>request<span class="sy0">,</span> response<span class="br0">&#41;</span> <span class="br0">&#123;</span>
		      $.<span class="me1">getJSON</span><span class="br0">&#40;</span><span class="sy0">&lt;?</span>php echo json_encode<span class="br0">&#40;</span>url_for<span class="br0">&#40;</span><span class="st0">&quot;taggableComplete/complete&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy0">?&gt;,</span> <span class="br0">&#123;</span>
					current<span class="sy0">:</span> extractLast<span class="br0">&#40;</span>request.<span class="me1">term</span><span class="br0">&#41;</span>
				<span class="br0">&#125;</span><span class="sy0">,</span> response<span class="br0">&#41;</span><span class="sy0">;</span>
			<span class="br0">&#125;</span><span class="sy0">,</span>
			search<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="co1">// custom minLength</span>
				<span class="kw2">var</span> term <span class="sy0">=</span> extractLast<span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">value</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="kw1">if</span> <span class="br0">&#40;</span>term.<span class="me1">length</span> <span class="sy0">&lt;</span> <span class="nu0">1</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
					<span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span>
				<span class="br0">&#125;</span>
			<span class="br0">&#125;</span><span class="sy0">,</span>
		        <span class="kw3">focus</span><span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="sy0">,</span> ui<span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="co1">// prevent value inserted on focus</span>
				<span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span>
			<span class="br0">&#125;</span><span class="sy0">,</span>
			select<span class="sy0">:</span> <span class="kw2">function</span><span class="br0">&#40;</span>event<span class="sy0">,</span> ui<span class="br0">&#41;</span> <span class="br0">&#123;</span>
				<span class="kw2">var</span> terms <span class="sy0">=</span> split<span class="br0">&#40;</span> <span class="kw1">this</span>.<span class="me1">value</span> <span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="co1">// remove the current input</span>
				terms.<span class="me1">pop</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="co1">// add the selected item</span>
				terms.<span class="me1">push</span><span class="br0">&#40;</span> ui.<span class="kw1">item</span>.<span class="me1">value</span> <span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="co1">// add placeholder to get the comma-and-space at the end</span>
				terms.<span class="me1">push</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="kw1">this</span>.<span class="me1">value</span> <span class="sy0">=</span> terms.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">&quot;, &quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
				<span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span>
			<span class="br0">&#125;</span>
&nbsp;
		<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div>



</li>
</ol>

<h2>tag cloud</h2>

<img src="http://n8v.enteuxis.org/wp-content/uploads/2010/05/my_tags_pick_from_cloud.png" alt="" title="my_tags_pick_from_cloud" width="468" height="76" class="size-full wp-image-362" />

<p>I like how WordPress has an option for picking tags from a tag cloud too.  The sfDoctrineActAsTaggablePlugin made this nice and easy.</p>

<ol>
    <li>Here&#8217;s the code for the view (in the <var>_tags.php</var> partial)


<div class="wp_syntax"><div class="code"><pre class="php"><span class="kw2">&lt;?php</span> <span class="kw1">echo</span> link_to_function<span class="br0">&#40;</span><span class="st0">&quot;Choose from the most used tags &amp;gt;&amp;gt;&quot;</span><span class="sy0">,</span> <span class="st_h">'$(&quot;#add_tag_from_cloud&quot;).show(); $(this).hide()'</span> <span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&nbsp;
&lt;div id=&quot;add_tag_from_cloud&quot; class=&quot;tag_cloud popular&quot; style=&quot;display:none&quot;&gt;
&lt;h3&gt;Popular tags&lt;/h3&gt;
<span class="kw2">&lt;?php</span> 
<span class="co1">// gets the popular tags</span>
<span class="re0">$tags</span> <span class="sy0">=</span> PluginTagTable<span class="sy0">::</span><span class="me2">getPopulars</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Display the tags cloud, using link_to_function() instead of link_to()</span>
<span class="co1">// The %s in the second arg will be substituted with the tag text.</span>
<span class="kw1">echo</span> tag_cloud<span class="br0">&#40;</span><span class="re0">$tags</span><span class="sy0">,</span> <span class="st_h">'add_tag(&quot;%s&quot;)'</span><span class="sy0">,</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span>
				<span class="st_h">'link_function'</span>   <span class="sy0">=&gt;</span>  <span class="st_h">'link_to_function'</span><span class="sy0">,</span>  
				<span class="st_h">'link_options'</span>   <span class="sy0">=&gt;</span>  <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'class=addtag'</span><span class="br0">&#41;</span>
					     <span class="br0">&#41;</span>
	       <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="sy1">?&gt;</span>
&lt;/div&gt;</pre></div></div>



</li>
    <li>And here&#8217;s the javascript to handle those links.


<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="kw2">function</span> add_tag <span class="br0">&#40;</span>tag<span class="br0">&#41;</span> <span class="br0">&#123;</span>
  add_field <span class="sy0">=</span> $<span class="br0">&#40;</span><span class="st0">&quot;#new_tags&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
  <span class="kw1">if</span> <span class="br0">&#40;</span> add_field.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">==</span> <span class="st0">&quot;Add tags with commas&quot;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    add_field.<span class="me1">val</span><span class="br0">&#40;</span> tag <span class="br0">&#41;</span><span class="sy0">;</span>
    add_field.<span class="me1">css</span><span class="br0">&#40;</span><span class="st0">&quot;color&quot;</span><span class="sy0">,</span> <span class="st0">&quot;black&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">&#40;</span> add_field.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">length</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    add_field.<span class="me1">val</span><span class="br0">&#40;</span> add_field.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span>  <span class="sy0">+</span> <span class="st0">&quot;, &quot;</span> <span class="sy0">+</span> tag <span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  <span class="kw1">else</span> <span class="br0">&#123;</span>
    add_field.<span class="me1">val</span><span class="br0">&#40;</span> tag <span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
  $<span class="br0">&#40;</span>element<span class="br0">&#41;</span>.<span class="me1">hide</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>



</li>
</ol>

<h2>CSS</h2>

<p>I made lots of incremental changes to my CSS but here are all of the sections relevant to the tag stuff I&#8217;ve shown here, I think.</p>


<div class="wp_syntax"><div class="code"><pre class="css">&nbsp;
<span class="re1">.taglist</span> <span class="re1">.removetag</span> <span class="br0">&#123;</span>
   <span class="kw1">vertical-align</span><span class="sy0">:</span> <span class="kw2">middle</span><span class="sy0">;</span>
   <span class="kw1">width</span><span class="sy0">:</span> <span class="re3">18px</span><span class="sy0">;</span>
   <span class="kw1">height</span><span class="sy0">:</span> <span class="re3">18px</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="re1">.taglist</span> span <span class="br0">&#123;</span>
   <span class="kw1">margin-right</span><span class="sy0">:</span> <span class="re3">1.4em</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="re1">.tag_cloud</span> li <span class="br0">&#123;</span>
   <span class="kw1">display</span><span class="sy0">:</span> <span class="kw2">inline</span><span class="sy0">;</span>
   <span class="kw1">list-style</span><span class="sy0">:</span> <span class="kw2">none</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="re0">#sf_admin_container</span> <span class="re1">.tag_cloud</span> li a <span class="br0">&#123;</span>
   <span class="kw1">background</span><span class="sy0">:</span> <span class="kw2">transparent</span><span class="sy0">;</span>
   <span class="kw1">padding-left</span><span class="sy0">:</span> <span class="re3">0px</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>


<p>And I had this in my <var>apps/frontend/templates/layout.php</var> to apply JQuery UI button styling to all my form buttons and hyperlinks with the &#8220;button&#8221; CSS class:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript"><span class="sy0">&lt;</span>script type<span class="sy0">=</span><span class="st0">&quot;text/javascript&quot;</span><span class="sy0">&gt;</span>
<span class="co1">// use JQueryUI buttons</span>
      $<span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
       $<span class="br0">&#40;</span><span class="st0">&quot;input:submit,  button, a.button&quot;</span><span class="br0">&#41;</span>.<span class="me1">button</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
      <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="sy0">&lt;/</span>script<span class="sy0">&gt;</span></pre></div></div>


<p>Yay! I&#8217;m pretty happy with it so far.  I hacked at it for a couple days though and have been cloudy with fighting a cold, so if I&#8217;ve missed anything let me know.  I think this is enough to get me there more quickly the next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2010/05/adding-wordpress-like-tags-to-a-symfony-1-4-admin-generator-form/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Compiling dansguardian 2.10.1.1 on Mac OS X Snow Leopard</title>
		<link>http://n8v.enteuxis.org/2010/01/compiling-dansguardian-2-10-1-1-on-mac-os-x-snow-leopard/</link>
		<comments>http://n8v.enteuxis.org/2010/01/compiling-dansguardian-2-10-1-1-on-mac-os-x-snow-leopard/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 07:21:24 +0000</pubDate>
		<dc:creator>nathan</dc:creator>
				<category><![CDATA[Figuring IT Out]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://n8v.enteuxis.org/?p=314</guid>
		<description><![CDATA[I&#8217;m trying the DansGuardian content filtering proxy at home. But it wouldn&#8217;t compile on my modern Snow Leopard machine. Salient errors: String.cpp: In member function ‘off_t String::toOffset()’: String.cpp:167: warning: format ‘%d’ expects type ‘int*’, but argument 3 has type ‘off_t*’ In file included from HTTPHeader.hpp:38, from DownloadManager.hpp:30, from OptionContainer.hpp:27, from ConnectionHandler.hpp:27, from ConnectionHandler.cpp:25: RegExp.hpp:31:23: error: [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m trying the DansGuardian content filtering proxy at home.  But it wouldn&#8217;t compile on my modern Snow Leopard machine.<br />
<span id="more-314"></span></p>

<h4>Salient errors:</h4>

<blockquote><pre>
String.cpp: In member function ‘off_t String::toOffset()’:
String.cpp:167: warning: format ‘%d’ expects type ‘int*’, but argument 3 has type ‘off_t*’
In file included from HTTPHeader.hpp:38,
                 from DownloadManager.hpp:30,
                 from OptionContainer.hpp:27,
                 from ConnectionHandler.hpp:27,
                 from ConnectionHandler.cpp:25:
RegExp.hpp:31:23: error: pcreposix.h: No such file or directory
In file included from HTTPHeader.hpp:38,
                 from DownloadManager.hpp:30,
                 from OptionContainer.hpp:27,
                 from ConnectionHandler.hpp:27,
                 from ConnectionHandler.cpp:25:
RegExp.hpp:82: error: ‘regex_t’ does not name a type
make[2]: *** [dansguardian-ConnectionHandler.o] Error 1
make[2]: *** Waiting for unfinished jobs....
mv -f .deps/dansguardian-String.Tpo .deps/dansguardian-String.Po
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
</pre>
</blockquote>

<p>And a wild goose chase:  don&#8217;t alter your PCRE_LIBS environment variable or you&#8217;ll have trouble like this:</p>

<blockquote><code>ld: in /Developer/SDKs/MacOSX10.5.sdk/usr/include/php/ext/pcre/pcrelib, can't map file, errno=22</blockquote>

<p></code></p>

<h4>What worked:</h4>


<div class="wp_syntax"><div class="code"><pre class="bash">&nbsp;
<span class="co0"># this is the main thing-- help it find pcreposix.h !</span>
<span class="kw3">export</span> <span class="re2">CPPFLAGS</span>=-I<span class="sy0">/</span>Developer<span class="sy0">/</span>SDKs<span class="sy0">/</span>MacOSX10.5.sdk<span class="sy0">/</span>usr<span class="sy0">/</span>include<span class="sy0">/</span>php<span class="sy0">/</span>ext<span class="sy0">/</span>pcre<span class="sy0">/</span>pcrelib
&nbsp;
<span class="co0"># only the last two are my preferences, </span>
<span class="co0"># the others are from the INSTALL doc</span>
&nbsp;
.<span class="sy0">/</span>configure <span class="re5">--localstatedir</span>=<span class="sy0">/</span>var  \
         <span class="re5">--mandir</span>=<span class="sy0">/</span>usr<span class="sy0">/</span>share<span class="sy0">/</span>man<span class="sy0">/</span>  \
         <span class="re5">--bindir</span>=<span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>sbin<span class="sy0">/</span> \
         <span class="re5">--with-logdir</span>=<span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>dansguardian<span class="sy0">/</span>logs<span class="sy0">/</span> \
         <span class="re5">--enable-email</span>=<span class="kw2">yes</span>
&nbsp;
<span class="kw2">make</span> <span class="re5">-j</span> <span class="nu0">2</span>
<span class="kw2">sudo</span> <span class="kw2">make</span> <span class="kw2">install</span></pre></div></div>


<h2>starting at boot with <code>daemonic</code></h2>

<p>I got <a href="www.squid-cache.org/">squid</a> using <a href="http://fink.sourceforge.net/">Fink</a>, which uses <a href="http://daemonic.sourceforge.net/">daemonic</a> for startup/init scripts.  So hopefully I can use it to start dansguardian at boot too.</p>

<p>I copied the squid XML file and made this one at <var>/sw/etc/daemons/dansguardian.xml</var>:</p>


<div class="wp_syntax"><div class="code"><pre class="xml"><span class="sc3"><span class="re1">&lt;service<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;description<span class="re2">&gt;</span></span></span>Dan's Guardian<span class="sc3"><span class="re1">&lt;/description<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;message<span class="re2">&gt;</span></span></span>Dan's Guardian content filter<span class="sc3"><span class="re1">&lt;/message<span class="re2">&gt;</span></span></span>
&nbsp;
<span class="sc3"><span class="re1">&lt;daemon</span> <span class="re0">name</span>=<span class="st0">&quot;dansguardian&quot;</span><span class="re2">&gt;</span></span>
<span class="sc3"><span class="re1">&lt;executable</span> <span class="re0">checkexit</span>=<span class="st0">&quot;true&quot;</span><span class="re2">&gt;</span></span>/usr/local/sbin/dansguardian<span class="sc3"><span class="re1">&lt;/executable<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;configfile<span class="re2">&gt;</span></span></span>/usr/local/etc/dansguardian/dansguardian.conf<span class="sc3"><span class="re1">&lt;/configfile<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;pidfile<span class="re2">&gt;</span></span></span>/var/run/dansguardian.pid<span class="sc3"><span class="re1">&lt;/pidfile<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/daemon<span class="re2">&gt;</span></span></span>
&nbsp;
<span class="sc3"><span class="re1">&lt;/service<span class="re2">&gt;</span></span></span></pre></div></div>


<p>Now all I have to do is:</p>


<div class="wp_syntax"><div class="code"><pre class="bash">$ <span class="kw2">sudo</span> daemonic <span class="kw3">enable</span> dansguardian</pre></div></div>


<p>Looks like it built some nice OS-X-y startup scripts for me in <var>/Library/StartupItems/daemonic-dansguardian</var>.  Here goes rebooting&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://n8v.enteuxis.org/2010/01/compiling-dansguardian-2-10-1-1-on-mac-os-x-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

