<?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"
	>

<channel>
	<title>Views From The Hill</title>
	<atom:link href="http://dustint.com/feed" rel="self" type="application/rss+xml" />
	<link>http://dustint.com</link>
	<description>Tales Of A SFU Computing Scientist</description>
	<pubDate>Wed, 06 Aug 2008 03:19:54 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Per Module Zend_Layout</title>
		<link>http://dustint.com/archives/28</link>
		<comments>http://dustint.com/archives/28#comments</comments>
		<pubDate>Wed, 06 Aug 2008 03:18:53 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[How-To]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<category><![CDATA[Zend_Controller_Plugin]]></category>

		<category><![CDATA[Zend_Layout]]></category>

		<guid isPermaLink="false">http://dustint.com/?p=28</guid>
		<description><![CDATA[Sometimes when you are building a web application, you want to use different layouts for different parts of the site. For example, in a content management system, you may want one layout for normal users and another, completely different layout for site administrators. 
Assuming that you have the standard zend directory structure, you will have [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes when you are building a web application, you want to use different layouts for different parts of the site. For example, in a content management system, you may want one layout for normal users and another, completely different layout for site administrators. <span id="more-28"></span></p>
<p>Assuming that you have the standard zend directory structure, you will have something like this:</p>
<pre>/application
  /admin
    /controllers
    /layouts
    /views
  /default
    /controllers
    /layouts
    /views
  /feeds
    /controllers
    /views</pre>
<p>Or something of the sort. When the user is in the admin section we want to use the layout folder from /admin, and when they are in the default section or in the feeds section of the site we would like to use the layout folder from /default.</p>
<p>We could simply go through all the controllers in the admin section and set the layout path in the init or preDisptach function:</p>
<div class="igBar"><span id="lphp-4"><a href="#" onclick="javascript:showPlainTxt('php-4'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-4">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">public <span style="color:#000000; font-weight:bold;">function</span> preDispatch<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; Zend_Layout::<span style="color:#006600;">getMvcInstance</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">setLayoutPath</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'../application/admin/layouts'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>This may work well for this simple example. However, every time we wish to add a controller to the admin section it would be necessary to setup the layout path and if ever we want to change the layout path for the admin module, there would be a lot of search-replacing.</p>
<p>A Much better solution is to write a plugin for the Zend Front controller. This plugin extends the Zend_Controller_Plugin_Abstract type and will be run each time the front controller is invoked, before anything is rendered.</p>
<p>Our plugin must have some very basic functionality:</p>
<ol>
<li>Ability to register a layout for use with a specified module</li>
<li>Ability to fall back to the default layout if there is no layout registered for the current module</li>
</ol>
<p>The Layout Plugin is as follows:</p>
<div class="igBar"><span id="lphp-5"><a href="#" onclick="javascript:showPlainTxt('php-5'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-5">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">class</span> Module_LayoutPlugin extends Zend_Controller_Plugin_Abstract <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000;">/**</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * Array of layout paths associating modules with layouts</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; */</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; protected <span style="color:#0000FF;">$_moduleLayouts</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#008000;">/**</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * Registers a module layout.</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * This layout will be rendered when the specified module is called.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * If there is no layout registered for the current module, the default layout as specified</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * in Zend_Layout will be rendered</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * </span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * @param String $module&nbsp; &nbsp; &nbsp; &nbsp; The name of the module</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * @param String $layoutPath&nbsp; &nbsp; The path to the layout</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; * @param String $layout&nbsp; &nbsp; &nbsp; &nbsp; The name of the layout to render</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000;">&nbsp; &nbsp;&nbsp; */</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> registerModuleLayout<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$module</span>, <span style="color:#0000FF;">$layoutPath</span>, <span style="color:#0000FF;">$layout</span>=<span style="color:#000000; font-weight:bold;">null</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;_moduleLayouts<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$module</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <a href="http://www.php.net/array" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF0000;">'layoutPath'</span> =&gt; <span style="color:#0000FF;">$layoutPath</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#FF0000;">'layout'</span> =&gt; <span style="color:#0000FF;">$layout</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> preDispatch<span style="color:#006600; font-weight:bold;">&#40;</span>Zend_Controller_Request_Abstract <span style="color:#0000FF;">$request</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/isset" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;_moduleLayouts<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$request</span>-&gt;<span style="color:#006600;">getModuleName</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$config</span> = <span style="color:#0000FF;">$this</span>-&gt;_moduleLayouts<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$request</span>-&gt;<span style="color:#006600;">getModuleName</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$layout</span> = Zend_Layout::<span style="color:#006600;">getMvcInstance</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$layout</span>-&gt;<span style="color:#006600;">getMvcEnabled</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$layout</span>-&gt;<span style="color:#006600;">setLayoutPath</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$config</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'layoutPath'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$config</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'layout'</span><span style="color:#006600; font-weight:bold;">&#93;</span> !== <span style="color:#000000; font-weight:bold;">null</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$layout</span>-&gt;<span style="color:#006600;">setLayout</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$config</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'layout'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The $_moduleLayouts property maintains the mapping between modules and layouts.</p>
<p>The registerModuleLayout function allows us to register a layoutpath and an (optional) layout name for a module. </p>
<p>The actual magic happens in the preDispatch function (which is called by the front controller before dispatching the request). The function checks to see if there is a layout set for the current module; if there is, it switches the layout path to use the module-specific path. Next it checks to see if there is a layout name associated with the layout registered for this module. If there is, it uses it, otherwise it falls back to the default layout name.</p>
<p>In our bootstrapper file (html/index.php) we must setup the default layout and module layout paths and then register the plugin with the front controller. The following code snippit is only a sliver of the bootstrapper and assumes that $controller is an instance of Zend_Controller_Front (eg: $controller = Zend_Controller_Front::getInstance();)</p>
<div class="igBar"><span id="lphp-6"><a href="#" onclick="javascript:showPlainTxt('php-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-6">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">//setup the layout</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Zend_Layout::<span style="color:#006600;">startMvc</span><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/array" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF0000;">'layoutPath'</span> =&gt; <span style="color:#FF0000;">'../application/default/layouts'</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF0000;">'layout'</span> =&gt; <span style="color:#FF0000;">'main'</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$layoutModulePlugin</span> = <span style="color:#000000; font-weight:bold;">new</span> Module_LayoutPlugin<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$layoutModulePlugin</span>-&gt;<span style="color:#006600;">registerModuleLayout</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'admin'</span>,<span style="color:#FF0000;">'../application/admin/layouts'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$controller</span>-&gt;<span style="color:#006600;">registerPlugin</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$layoutModulePlugin</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>It is important to setup the default layout so the plugin has a layout to fall back to if no module-specific layout is registered. </p>
<p>I hope that this tutorial has served as a quick and easy introduction to Zend Front Controller plugins and module-specific layouts.</p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/28/feed</wfw:commentRss>
		</item>
		<item>
		<title>Fakemail for Developers</title>
		<link>http://dustint.com/archives/27</link>
		<comments>http://dustint.com/archives/27#comments</comments>
		<pubDate>Sat, 07 Jun 2008 07:34:18 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Web]]></category>

		<category><![CDATA[Unix]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://dustint.com/?p=27</guid>
		<description><![CDATA[The other day when I was setting up email notifications for a Zend Framework application, I stumbled across Fakemail.
From the developers website:
fakemail is a fake mail server that captures emails as files for acceptance testing. This avoids the excessive configuration of setting up a real mail server and trying to extract mail queue content.
I am [...]]]></description>
			<content:encoded><![CDATA[<p>The other day when I was setting up email notifications for a Zend Framework application, I stumbled across Fakemail.</p>
<p>From the developers website:</p>
<blockquote><p>fakemail is a fake mail server that captures emails as files for acceptance testing. This avoids the excessive configuration of setting up a real mail server and trying to extract mail queue content.</p></blockquote>
<p>I am quite impressed with this handy little script (written in both Python and Perl), as it works exactly as advertised: taking out the time required to properly configure a SMTP server and saving the hassle of having dozens of test messages showered across inboxes. Instead of forwarding emails on to their recipients, it simply saves a raw copy of the email to the specified directory.</p>
<p>The script has a windows installer that bundles the script with python and will run on all flavors of Linux and Unix assuming that they have perl or python installed.</p>
<p>To configure Zend_Mail use fakemail place the following in your bootstrapper or common config file:</p>
<div class="igBar"><span id="lphp-8"><a href="#" onclick="javascript:showPlainTxt('php-8'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-8">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Zend_Mail::<span style="color:#006600;">setDefaultTransport</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#000000; font-weight:bold;">new</span> Zend_Mail_Transport_Smtp<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'localhost'</span>,<a href="http://www.php.net/array" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">'port'</span> =&amp;gt; <span style="color:#CC66CC;color:#800000;">10025</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The 'localhost' variable is the address of the computer that fakemail is running on (likely the local machine). The port number is the port that is specified when fakemail is run on the command line.</p>
<p>For more information about fakemail, binaries, and a usage guide. Visit the developers website at Sourceforce: <a href="http://www.lastcraft.com/fakemail.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.lastcraft.com');">http://www.lastcraft.com/fakemail.php</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/27/feed</wfw:commentRss>
		</item>
		<item>
		<title>Cache-Control with Zend Framework</title>
		<link>http://dustint.com/archives/25</link>
		<comments>http://dustint.com/archives/25#comments</comments>
		<pubDate>Fri, 06 Jun 2008 02:45:37 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[How-To]]></category>

		<category><![CDATA[Web]]></category>

		<category><![CDATA[Cache-Control]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://dustint.com/?p=25</guid>
		<description><![CDATA[Today I was optimizing a site that uses heavy PHP and Ajax. I wanted to reduce the amount of data that was being sent from the server. To put this in perspective, if there were no cache hits in a page load there would be a total of 755 KB pulled down over 123 requests.

The [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was optimizing a site that uses heavy PHP and Ajax. I wanted to reduce the amount of data that was being sent from the server. To put this in perspective, if there were no cache hits in a page load there would be a total of 755 KB pulled down over 123 requests.<br />
<span id="more-25"></span><br />
The first step was throwing a .htaccess into the dojo folder that sets the Cache-Control header on the library files being pulled down.</p>
<pre>
<div class="igBar"><span id="lcode-11"><a href="#" onclick="javascript:showPlainTxt('code-11'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-11">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;IfModule mod_expires.<span style="">c</span>&gt;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp;Header set Cache-Control <span style="color:#CC0000;">"max-age=3600, public"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;/IfModule&gt; </div>
</li>
</ol>
</div>
</div>
</div>

</pre>
<p>The above checks to ensure the mod_expires module is loaded in apache, and if it is the Cache is set to expire 3600 seconds from now: 1 hour. Furthermore, the page can be cached in a publicly accessible (shared) cache.</p>
<p>Getting caching working with Zend was a little more challenging. By default Zend (or PHP) writes caching information to headers disabling caching. However, the code snippit below (to be placed inside an Action Controller) blanks out the expires header, sets the cache-control header so that the page expires in one hour, and blanks out the Pragma header. </p>
<p>The expires header allows the server to specify a date when the cache expires (Rather than setting the max-age offset) and the Pragma indicates if the page can be cached in a proxy. I found, with Firefox 3, if Expires and Pragma weren't blanked out, they would take preference over the Cache-Control header, disabling caching of the page.</p>
<div class="igBar"><span id="lphp-12"><a href="#" onclick="javascript:showPlainTxt('php-12'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-12">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getResponse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">setHeader</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Expires'</span>, <span style="color:#FF0000;">''</span>, <span style="color:#000000; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getResponse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">setHeader</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Cache-Control'</span>, <span style="color:#FF0000;">'public'</span>, <span style="color:#000000; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getResponse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">setHeader</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Cache-Control'</span>, <span style="color:#FF0000;">'max-age=3800'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getResponse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">setHeader</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'Pragma'</span>, <span style="color:#FF0000;">''</span>, <span style="color:#000000; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>After the addition of caching, the page load was reduced to 8Kb of data pulled down over 9 requests: about a 90% optimization.</p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/25/feed</wfw:commentRss>
		</item>
		<item>
		<title>Gentoo blacklist.py init Script</title>
		<link>http://dustint.com/archives/22</link>
		<comments>http://dustint.com/archives/22#comments</comments>
		<pubDate>Wed, 04 Jun 2008 06:41:28 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[How-To]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[blacklist.py]]></category>

		<category><![CDATA[Gentoo]]></category>

		<category><![CDATA[ssh security]]></category>

		<guid isPermaLink="false">http://dustint.com/?p=22</guid>
		<description><![CDATA[I have several servers which run an assortment of http, svn, ssh, and ftp services. One of the largest annoyances are automated breaking scripts pounding my services. Recently, I have been looking into blacklist.py: a handy python script written by Reto Glauser, which monitors syslog-ng logs looking for possible break-in attempts. The script uses iptables [...]]]></description>
			<content:encoded><![CDATA[<p>I have several servers which run an assortment of http, svn, ssh, and ftp services. One of the largest annoyances are automated breaking scripts pounding my services. Recently, I have been looking into <a href="http://blinkeye.ch/mediawiki/index.php/SSH_Blocking" onclick="javascript:pageTracker._trackPageview('/outbound/article/blinkeye.ch');">blacklist.py</a>: a handy python script written by Reto Glauser, which monitors syslog-ng logs looking for possible break-in attempts. The script uses iptables to block future traffic from suspicious IP's for a specified amount of time.</p>
<p>After I got the script setup and running I wanted a Gentoo init script that would automatically start the script on boot. After reading through some examples in my /etc/init.d/ directory I seem to have managed to cook up something that works:<span id="more-22"></span></p>
<pre>
<div class="igBar"><span id="lcode-14"><a href="#" onclick="javascript:showPlainTxt('code-14'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-14">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#!/sbin/runscript</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># blacklist is free software; you can redistribute it and/or modify</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># it under the terms of the GNU General Public License as published by</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># the Free Software Foundation; either version <span style="color:#800000;color:#800000;">2</span> of the License, or</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># <span style="color:#006600; font-weight:bold;">&#40;</span>at your option<span style="color:#006600; font-weight:bold;">&#41;</span> any later version.</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># blacklist is distributed in the hope that it will be useful,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># but WITHOUT ANY WARRANTY; without even the implied warranty of</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; <span style="">See</span> the</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># GNU General Public License for more details.</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">#</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Copyright: Dustin Thomson</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Homepage: http:<span style="color:#FF9933; font-style:italic;">//dustint.com</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Date: <span style="color:#800000;color:#800000;">2008</span>-<span style="color:#800000;color:#800000;">06</span>-<span style="color:#800000;color:#800000;">03</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"># Version <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">EXEC=/usr/sbin/blacklist</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">PID=/var/run/blacklist.<span style="">pid</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">depend<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; need net</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">checkconfig<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; if <span style="color:#006600; font-weight:bold;">&#91;</span> ! -e /usr/sbin/blacklist <span style="color:#006600; font-weight:bold;">&#93;</span> ; then</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; eerror <span style="color:#CC0000;">"blacklist not found in /usr/sbin/blacklist"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return <span style="color:#800000;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; fi</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">start<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; checkconfig || return <span style="color:#800000;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; ebegin <span style="color:#CC0000;">"Starting Blacklist"</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; $EXEC &amp;amp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; eend $?</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">stop<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; ebegin <span style="color:#CC0000;">"Stopping Blacklist"</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; start-stop-daemon --stop --retry <span style="color:#800000;color:#800000;">20</span> --quiet --pidfile $PID</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; eend $?</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>

</pre>
<p>Alternatively, for those with wget, cd into /etc/init.d/ and:</p>
<pre>wget <a href="http://dustint.com/wp-content/uploads/2008/06/blacklist" >http://dustint.com/wp-content/uploads/2008/06/blacklist</a>
chmod +x blacklist</pre>
<p>I have placed blacklist.py in /usr/sbin/ and renamed it to simply blacklist</p>
<p>Reto also hosts a handy "stage-4" <a href="http://blinkeye.ch/mediawiki/index.php/GNU/Linux_System_Backup_Script_(stage4)" onclick="javascript:pageTracker._trackPageview('/outbound/article/blinkeye.ch');">backup script</a> which can create a full backup of your filesystem.</p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/22/feed</wfw:commentRss>
		</item>
		<item>
		<title>Zend JSON-RPC with Dojo Howto</title>
		<link>http://dustint.com/archives/20</link>
		<comments>http://dustint.com/archives/20#comments</comments>
		<pubDate>Tue, 03 Jun 2008 02:50:54 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[How-To]]></category>

		<category><![CDATA[Web]]></category>

		<category><![CDATA[Dojo]]></category>

		<category><![CDATA[JSON]]></category>

		<category><![CDATA[RPC]]></category>

		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://dustint.com/?p=20</guid>
		<description><![CDATA[ 
I have been using the Dojo toolkit as my Javascript library of choice since back in early 2006 when it was still around version 0.4. Since then, the project has made tremendous strides including the release of version 1.0 and 1.1 with 1.2 on the way. At the beginning of 2008 I started using [...]]]></description>
			<content:encoded><![CDATA[<p><!--[if !mso]></p>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<p><![endif]--><!--[if gte mso 9]><xml> Normal   0   false            false   false   false      EN-CA   X-NONE   X-NONE                                                     MicrosoftInternetExplorer4 </xml><![endif]--><!--[if gte mso 9]><xml> </xml><![endif]--> <!--[if gte mso 10]></p>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin-top:0cm;
mso-para-margin-right:0cm;
mso-para-margin-bottom:10.0pt;
mso-para-margin-left:0cm;
line-height:115%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-fareast-language:EN-US;}
</style>
<p><![endif]--></p>
<p>I have been using the Dojo toolkit as my Javascript library of choice since back in early 2006 when it was still around version 0.4. Since then, the project has made tremendous strides including the release of version 1.0 and 1.1 with 1.2 on the way. At the beginning of 2008 I started using the Zend Framework to build MVC PHP applications and, with the release of 1.5, it has become my PHP framework of choice.</p>
<p>To my delight, the Zend Framework and Dojo have recently <a href="http://dojotoolkit.org/2008/05/21/announcing-zend-framework-integration-dojo-1-x-0" onclick="javascript:pageTracker._trackPageview('/outbound/article/dojotoolkit.org');">announced</a> a partnership which will lead to tighter integration of these two great open source frameworks.</p>
<p>One of the most exciting additions to the Zend Framework is the <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Json_Server+to+support+JSON-RPC" onclick="javascript:pageTracker._trackPageview('/outbound/article/framework.zend.com');">Zend_Json_Server support for JSON-RPC</a>. I have been using JSON-RPC with Dojo for quite some time and, up until now, it has been challenging to find a design pattern that plays nice with the Model View Controller implementation in the Zend Framework. However, with the addition of the Zend_Json_Server this is no longer the case.<span id="more-20"></span></p>
<h2>Prerequisites:</h2>
<p>This tutorial assumes you are familiar with developing in PHP and javascript and are experienced with dojo and the Zend Framework using the MVC paradigm.</p>
<h2>Common Pitfalls</h2>
<ul class="unIndentedList">
<li> Absolute paths are used in the code examples. Ensure that you modify them to reflect your server's directory structure. This tutorial assumes that you are working with a ZF project whose /html/ directory corresponds to the root of your webserver</li>
<li> Ensure you place a .htaccess file in /html/scripts/ that disables the re-write engine. If you fail to do this step, when trying to load dojo libraries, ZF will be trying to find controllers that match the requests and throwing exceptions.</li>
</ul>
<h2>Patching Zend Framework</h2>
<p>At the time of writing, the Json-RPC component has not been accepted into the Zend Framework (although it will be soon). To get the Zend Framework (ZF) working with Json-RPC we must download code from the incubator area of SVN. If you don't know how to use a SVN client to check out code, read about it <a href="http://framework.zend.com/manual/en/introduction.installation.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/framework.zend.com');">here</a>. Download the current version of ZF and then, using an SVN client, download <a href="http://framework.zend.com/svn/framework/standard/incubator/library/Zend/Json/" onclick="javascript:pageTracker._trackPageview('/outbound/article/framework.zend.com');">http://framework.zend.com/svn/framework/standard/incubator/library/Zend/Json/ </a>and place it in the json directory of your local copy of ZF.</p>
<h2>Setting up the Directories</h2>
<p>For the purpose of this tutorial I will be using code and examples from <a href="../../../../../nickel">Nickel</a>: the application that will eventually run SFU Bookswap V.3. I use a fairly standard MVC directory structure as recommended by the ZF docs:</p>
<pre>application
	|-default
	|-controllers
	|-views
html
	|-images
	|-scripts
		|-nickel
			|-RPC
library
	|-Nickel
		|-Models
		|-RPC
	|-Zend
		| .... Framework checkout
</pre>
<p>The reasoning behind placing the Nickel folder in the library is so we can use Zend_Loader to load classes on demand. Also, as a condition of this, the classes in the Nickel folder follow the ZF naming convention: so, say, the class for a book model would be named, Nickel_Model_Book.</p>
<p>Similarly, there is a corresponding directory structure in the scripts folder. This is to be used with the Dojo packaging system. So, to access the RPC handle for the book model we would call a function such as nickel.rpc.book.getAuthor()</p>
<h2>Creating the RPC Controller</h2>
<p>The next step is to actually create the RPC controller. I have created a file in /application/default/controllers/RpcController.php which contains the RpcController action controller class. RpcController has two actions: one which will return the SMD (simple method declaration) to dojo when the JSON-RPC object is instantiated. The second action, the service action, actually processes the RPC request and returns the result. So, we have:</p>
<pre>/application/default/controllers/RpcController.php
<div class="igBar"><span id="lphp-19"><a href="#" onclick="javascript:showPlainTxt('php-19'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-19">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">class</span> RpcController extends Zend_Controller_Action <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> smdAction<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$class</span> = <span style="color:#0000FF;">$this</span>-&gt;_getParam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'class'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$server</span> = <span style="color:#000000; font-weight:bold;">new</span> Zend_Json_Server<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">getServiceMap</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">setDojoCompatible</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#000000; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">getServiceMap</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">setTransport</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'POST'</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;-&gt;<span style="color:#006600;">setTarget</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getHelper</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'url'</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">url</span><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/array" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'controller'</span>=&gt;<span style="color:#FF0000;">'rpc'</span>, <span style="color:#FF0000;">'action'</span>=&gt;<span style="color:#FF0000;">'service'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;-&gt;<span style="color:#006600;">setId</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getHelper</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'url'</span><span style="color:#006600; font-weight:bold;">&#41;</span>-&gt;<span style="color:#006600;">url</span><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/array" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'controller'</span>=&gt;<span style="color:#FF0000;">'rpc'</span>, <span style="color:#FF0000;">'action'</span>=&gt;<span style="color:#FF0000;">'service'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">setClass</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$class</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">view</span>-&gt;<span style="color:#006600;">data</span> = <span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">getServiceMap</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">render</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'service'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> serviceAction<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$class</span> = <span style="color:#0000FF;">$this</span>-&gt;_getParam<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'class'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$server</span> = <span style="color:#000000; font-weight:bold;">new</span> Zend_Json_Server<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">setClass</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$class</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">setAutoEmitResponse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#000000; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$server</span>-&gt;<span style="color:#006600;">handle</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>


</pre>
<p>The smd Action takes ‘class' as a parameter. This is the name of the class that we wish to expose via Json-RPC, such as Nickel_Rpc_Book. Please note the function call setDojoCompatible(true) which forces the server to generate dojo-compatible SMD definitions. The target function call sets the target of the function calls (the service url) to the service action defined below.</p>
<p>The service action simply processes the RPC request by calling the specified function with the sent parameters.</p>
<p>There is a fairly large security hole opened by this implementation. Since any value can be passed to the ‘class' argument, it is possible to remotely call functions for any class that can be auto-loaded. A ‘safer' implementation would simply concatenate the class parameter with "Nickel_Rpc_". This way is less likely that an attacker could compromise your server by calling a dangerous function.</p>
<h2>Writing a RPC Class</h2>
<p>Now that we have the RPC server set up we need some classes in Nickel_RPC to call. For the purpose of this example we will use a very simple Book class that has basic functionality:</p>
<pre>/library/Nickel/Model/Book.php
<div class="igBar"><span id="lphp-20"><a href="#" onclick="javascript:showPlainTxt('php-20'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-20">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">class</span> Nickel_RPC_Book <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <a href="http://www.php.net/static" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> simpleEcho<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> “Hello World”;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <a href="http://www.php.net/static" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> getTitle<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bookId</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$book</span> = <span style="color:#000000; font-weight:bold;">new</span> Nickel_Model_Book<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bookId</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$book</span>-&gt;<span style="color:#006600;">getTitle</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <a href="http://www.php.net/static" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.php.net');"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> setTitle<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bookId</span>, <span style="color:#0000FF;">$title</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$book</span> = <span style="color:#000000; font-weight:bold;">new</span> Nickel_Model_Book<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$bookId</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$book</span>-&gt;<span style="color:#006600;">setTitle</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$title</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$book</span>-&gt;<span style="color:#006600;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#000000; font-weight:bold;">true</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>

</pre>
<p>In the above RPC class, in addition to the simpleEcho function, we have two static functions: one that reads the title from the Book Model, and the second which writes a new title back to the database via the Book model. Notice that the functions are static: this is because, in the case of our book anyways, a notion of $this doesn't really make since, as we don't actually know what book we want the title for unless we pass the book ID from dojo.</p>
<h2>Writing the RPC Front-end</h2>
<p>Now that we have the backend written, it is fairly quick to write the frontend.</p>
<p>The first step is to create the book rpc file so we can include nickel.rpc.book using a dojo.require statement:</p>
<pre>/html/scripts/nickel/RPC/book.js
<div class="igBar"><span id="ljavascript-21"><a href="#" onclick="javascript:showPlainTxt('javascript-21'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">JavaScript:</span>
<div id="javascript-21">
<div class="javascript">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">dojo.<span style="color: #006600;">provide</span><span style="color: #66cc66;">&#40;</span>‘nickel.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">book</span>’<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span>‘dojo.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">JsonService</span>’<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">nickel.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">book</span> = <span style="color: #003366; font-weight: bold;">new</span> dojo.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">JsonService</span><span style="color: #66cc66;">&#40;</span>‘<span style="color: #0066FF;">/rpc/smd/<span style="color: #003366; font-weight: bold;">class</span>/</span>Nickel_RPC_Book’<span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>

</pre>
<p>The above code snippet should be saved as book.js and placed in /html/scripts/nickel/rpc. When this file is included, a new JsonService object is created with functions populated from the SMD generated by the RPC controller class. As a result, nickel.rpc.book will now contain three functions: simpleEcho, getTitle and setTitle.</p>
<h2>Using The Front-end.</h2>
<p>Finally, we have the opportunity to see the fruit of our labour. Create an indexController and the accompanying view. In the view, after including dojo.js, create a new script block:</p>
<pre>/application/default/views/index/index.phtml
...
<div class="igBar"><span id="ljavascript-22"><a href="#" onclick="javascript:showPlainTxt('javascript-22'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">JavaScript:</span>
<div id="javascript-22">
<div class="javascript">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;script type=”text/javascript”&gt;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; dojo.<span style="color: #006600;">registerModulePath</span><span style="color: #66cc66;">&#40;</span>‘nickel’, ‘<span style="color: #0066FF;">/scripts/</span>nickel’<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; dojo.<span style="color: #006600;">require</span><span style="color: #66cc66;">&#40;</span>‘nickel.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">book</span>’<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; dojo.<span style="color: #006600;">addOnLoad</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; nickel.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">book</span>.<span style="color: #006600;">simpleEcho</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addCallback</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>msg<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span>msg<span style="color: #66cc66;">&#41;</span>;&nbsp;&nbsp;<span style="color: #009900; font-style: italic;">//Alert: Hello World</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; nickel.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">book</span>.<span style="color: #006600;">getTitle</span><span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;color:#800000;">1</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addCallback</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">&#41;</span>;&nbsp; &nbsp;<span style="color: #009900; font-style: italic;">//Alert: title of book with ID 1 in database</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; nickel.<span style="color: #006600;">rpc</span>.<span style="color: #006600;">book</span>.<span style="color: #006600;">setTitle</span><span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;color:#800000;">1</span>, ‘Foo’<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">addCallback</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>result<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span>‘success’<span style="color: #66cc66;">&#41;</span>;&nbsp; &nbsp;<span style="color: #009900; font-style: italic;">//Sets the title of book with ID 1 to ‘Foo’</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;/script&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">... </div>
</li>
</ol>
</div>
</div>
</div>

</pre>
<p>dojo.registerModulePath adds a module path to the dojo loader. This allows us to include our custom nickel modules easily and on-demand.</p>
<h2>Conclusion</h2>
<p>The Dojo Toolkit and Zend Framework provide a highly structured, maintainable JSON RPC system when used together. This can be used to easily propagate dirty javascript data objects to persistent storage in the backend, as well as expose PHP function calls to javascript to return useful data.</p>
<p>I hope you have enjoyed this tutorial. If you find any typos, mistakes or just wish to leave a message, please add a comment below.</p>
<p>I also encourage you to link to this post if you have found it at all useful in developing your web-application.</p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/20/feed</wfw:commentRss>
		</item>
		<item>
		<title>Adblock Plus, Greasemonkey For Firefox 3 Beta 5</title>
		<link>http://dustint.com/archives/16</link>
		<comments>http://dustint.com/archives/16#comments</comments>
		<pubDate>Sat, 05 Apr 2008 22:59:44 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[How-To]]></category>

		<category><![CDATA[Adblock Plus]]></category>

		<category><![CDATA[Firefox 3]]></category>

		<category><![CDATA[Greasemonkey]]></category>

		<guid isPermaLink="false">http://dustint.com/archives/16</guid>
		<description><![CDATA[
I love Adblock Plus - I refuse to use the internet without it. I also quite enjoy Greasemonkey. Unfortunately, neither is yet compatible with the new Firefox 3b5. I got tired of waiting so I took measures into my own hands.
The XPI file format is basically a glorified zip file, so you can unzip it [...]]]></description>
			<content:encoded><![CDATA[<p><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="ProgId" content="Word.Document" /><meta name="Generator" content="Microsoft Word 12" /><meta name="Originator" content="Microsoft Word 12" /></p>
<p>I love Adblock Plus - I refuse to use the internet without it. I also quite enjoy Greasemonkey. Unfortunately, neither is yet compatible with the new Firefox 3b5. I got tired of waiting so I took measures into my own hands.</p>
<p class="MsoNormal">The XPI file format is basically a glorified zip file, so you can unzip it with a compression utility and modify the maximum version number in install.rdf. Basically I replaced the value in the em:maxVersion field with 3.* so to make it compatible with all versions of Firefox.</p>
<p class="MsoNormal">Of course, these maximum version numbers are there for a reason: newer versions of Firefox may break the extension functionality, but no problems so far.</p>
<p class="MsoNormal">For the lazy, I have uploaded the patched install files. Of course I give zero guarantees or warranty for the correct operation of these patched extensions. I encourage you to upgrade to the official compatible version as soon as possible.</p>
<p class="MsoNormal">To install:</p>
<ol>
<li>Download File</li>
<li>Drag downloaded file into open Firefox window</li>
<li>Enjoy an Ad-free internet</li>
</ol>
<p class="MsoNormal"><a href="http://dustint.com/wp-content/uploads/2008/04/adblock_plus-0753-fxtbsmfl.xpi"  title="Adblock Plus For Firefox 3B5"><strike>Adblock Plus For Firefox 3 Beta 5</strike></a> The Adblock Plus Development build now supports Beta 5. Get it here: <a href="http://adblockplus.org/devbuilds/" onclick="javascript:pageTracker._trackPageview('/outbound/article/adblockplus.org');">http://adblockplus.org/devbuilds/ </a></p>
<p class="MsoNormal"><a href="http://dustint.com/wp-content/uploads/2008/04/greasemonkey-07200801210-fx.xpi" title="Greasemonkey For Firefox 3B5">Greasemonkey For Firefox 3 Beta 5<br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/16/feed</wfw:commentRss>
		</item>
		<item>
		<title>What Central Authentication Can Do For You</title>
		<link>http://dustint.com/archives/15</link>
		<comments>http://dustint.com/archives/15#comments</comments>
		<pubDate>Fri, 04 Apr 2008 19:22:53 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[CAS]]></category>

		<category><![CDATA[central authentication]]></category>

		<guid isPermaLink="false">http://dustint.com/archives/15</guid>
		<description><![CDATA[Imagine the following scenario: you are the operator of a small website that has a private user’s area which requires visitors to login to view. A few months later, you want to add a gallery application which also requires users to login and, finally, you want users to be able to edit a community wiki, [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">Imagine the following scenario: you are the operator of a small website that has a private user’s area which requires visitors to login to view. A few months later, you want to add a gallery application which also requires users to login and, finally, you want users to be able to edit a community wiki, but not allow non-members to make changes.</p>
<p class="MsoNormal">We can see that we have two choices: force the users to login to each separate application separately, or somehow combine all the applications under a single login.</p>
<p class="MsoNormal"><span id="more-15"></span></p>
<h1>A Central Authentication Service</h1>
<p class="MsoNormal">Central Authentication Services allow a user to share a single login across multiple applications and even websites. OpenID and Yahoo are examples of large CAS hybrids that are becoming increasingly popular amongst social networking sites. However, CAS does not have to be so global in scope, many universities and companies use CAS when their services are best provided by several applications.</p>
<h2>How it works</h2>
<p class="MsoNoSpacing">The series of events that occur during a CAS authentication session are as follows:</p>
<ol>
<li>User attempts to gain access to the secure area of a photo gallery</li>
<li>The gallery detects that this user is not authenticated to view this content</li>
<li>The user is re-directed to the login page of the Central Authentication Service. A callback URL is passed to the CAS by means of a GET variable</li>
<li>The user enters their login information and it is verified. A cookie is set to identify this user as authenticated in the future</li>
<li>The CAS redirects the user to the callback passed by the photo gallery. A ticket is passed to the photo gallery callback page by means of a GET variable</li>
<li>The photo gallery establishes a secure connection to the CAS and checks to ensure the ticket is valid, if it is, the user has been successfully authenticated</li>
</ol>
<p class="MsoNormal">Depending on the CAS setup, when the user enters another secure area of the website, say the wiki, they will be redirected to CAS, then transparently redirected back to the wiki callback page. This occurs because the user has already authenticated themselves with CAS, so there is no need to re-enter login credentials. To the user, it appears as if they were immediately authenticated by the wiki.</p>
<p class="MsoNormal">A Central Authentication Service also reduces some aspects of user information management as, if the user wishes to update their password; they need only do it once. However, CAS does not solve the problem of propagating other types of user information, such as the users name and contact information to the various applications. Furthermore, the authentication routines of the participating applications much be refactored to authenticate the user via CAS, then load the user information out of the local application database.</p>
<h2>In Conclusion:</h2>
<p class="MsoNormal">Central Authentication is a good way to improve the user experience if you are currently forcing users to authenticate multiple times. Furthermore, from a developers standpoint, it is a clean and safe way to pass authentication tokens between applications, especially if these applications may reside on separate domains.</p>
<p class="MsoNormal">For more information on CAS, including a JAVA server implementation, protocol descriptions and clients in multiple languages visit <a href="http://www.ja-sig.org/products/cas/index.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ja-sig.org');">http://www.ja-sig.org/products/cas/index.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/15/feed</wfw:commentRss>
		</item>
		<item>
		<title>Automatically Require Dijit Widgets</title>
		<link>http://dustint.com/archives/14</link>
		<comments>http://dustint.com/archives/14#comments</comments>
		<pubDate>Sun, 16 Mar 2008 18:47:42 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[How-To]]></category>

		<category><![CDATA[Dijit]]></category>

		<category><![CDATA[Dojo]]></category>

		<category><![CDATA[Widget]]></category>

		<guid isPermaLink="false">http://dustint.com/archives/14</guid>
		<description><![CDATA[Recently I have been playing with the dojox.dtl: the javascript port of the Django templating engine. So far I am quite impressed, not only is it fast and full featured, but by writing a wrapper class it is easy to make it behave like server side templating systems: you specify a template and pass it [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have been playing with the dojox.dtl: the javascript port of the <a href="http://www.djangoproject.com/documentation/templates/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.djangoproject.com');" target="_blank">Django templating engine</a>. So far I am quite impressed, not only is it fast and full featured, but by writing a wrapper class it is easy to make it behave like server side templating systems: you specify a template and pass it an object and it will render that object according to the template rules.</p>
<p>The only trouble I ran into was when I wanted to used Dijit Widgets in my templates. Since on my main page I didn't know what template I would be calling, I didn't know which Widget classes to include with dojo.require(). To fix this, I have come up with a little hack that does the job, although not too elegantly.</p>
<p>Bascially my approach includes hooking into dojo.parser and changing its behaviour. Now when it is parsing widgets from the page it checks to see if they exist and, if not, it does the appropriate dojo.require() to try to pull them in.</p>
<blockquote>
<pre>var fn = dojo.parser.instantiate;</pre>
<pre>
dojo.parser.instantiate = function(nodes){</pre>
<pre>    dojo.forEach(nodes, function(node){</pre>
<pre>        var className = node.getAttribute(dojo._scopeName + "Type")</pre>
<pre>        if(!dojo.isFunction(dojo.getObject(className))){</pre>
<pre>            //It is not an object... yet</pre>
<pre>            dojo.require(className);</pre>
<pre>        }</pre>
<pre>    });</pre>
<pre>    return fn(nodes);</pre>
<pre>}</pre>
</blockquote>
<p>The above code-block shows the implimentation. Simply place this in between &lt;script&gt; tags in your header. Now you should be able to do dojotypes anywhere on your page and have the appropriate classes automatically included.</p>
<p>There are several disadvantages to my approach. For example, if you have a typo in one of your  dojoType, it will try to pull down a file that doesn't exist. We also have the impact of running through the array of nodes an additional time, although since the dojo.parser.instantiate function is already bounded by O(n) this shouldn't make a noticeable impact.</p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/14/feed</wfw:commentRss>
		</item>
		<item>
		<title>Cookie Injection Using Greasemonkey</title>
		<link>http://dustint.com/archives/12</link>
		<comments>http://dustint.com/archives/12#comments</comments>
		<pubDate>Thu, 31 Jan 2008 05:46:34 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[How-To]]></category>

		<category><![CDATA[Web]]></category>

		<category><![CDATA[Cookie Stealing]]></category>

		<category><![CDATA[Cookies]]></category>

		<category><![CDATA[Ethereal]]></category>

		<category><![CDATA[Firefox]]></category>

		<category><![CDATA[Greasemonkey]]></category>

		<category><![CDATA[HTTP]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[TCP]]></category>

		<category><![CDATA[Wireshark]]></category>

		<guid isPermaLink="false">http://dustint.com/?p=12</guid>
		<description><![CDATA[There are several Firefox plugins which allow the user to manipulate their browser cookies. However, most of these plugins force the user to manipulate cookies individually. This can become tedious if the user is simply “importing” cookies from, say, a wireshark dump.
The CookieInjector userscript simplifies this process, by allowing the user to copy-paste the cookie [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm">There are several Firefox plugins which allow the user to manipulate their browser cookies. However, most of these plugins force the user to manipulate cookies individually. This can become tedious if the user is simply “importing” cookies from, say, a wireshark dump.</p>
<p style="margin-bottom: 0cm">The CookieInjector userscript simplifies this process, by allowing the user to copy-paste the cookie portion of the dump and have the cookies from the dump automatically created on the currently viewed web page.</p>
<p style="margin-bottom: 0cm">
<h3>To Use The Script:</h3>
<p style="margin-bottom: 0cm">Fire up Wireshark, formally Ethereal, if you don't have Wireshark you can grab it from: <a href="http://www.wireshark.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.wireshark.org');" target="_blank">http://www.wireshark.org/</a>. Start listening for traffic on the same interface you use to access the internet. To cut down on extra packets, enter <em>tcp</em> as a capture filter. <a title="Wikipedia: TCP" href="http://en.wikipedia.org/wiki/TCP" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">TCP</a> is a transport layer protocol featuring reliable transport, congestion control and connection oriented transfers. Since HTTP uses connections between client and server and therefore the TCP protocol, is is safe to filter out all non-TCP packets. To further filter the packets that Wireshark is displaying enter <em>http.cookie</em> in the filter field. This will filter out all packets which are not using the HTTP application layer protocol and all HTTP packets which do not contain cookies.</p>
<p style="margin-bottom: 0cm">Next go to a website that uses cookies. Most websites which support user logins or shopping carts use cookies for these purposes. Make sure that the website that you visit does not encrypt the entire session (such as a banking website), otherwise the packets will be encrypted and not viewable in wireshark. After capturing a couple packets which contain cookies scroll down to the <em>Hypertext Transfer Protocol</em><span style="font-style: normal"> portion of the packet preview, expand it, and scroll down to the cookie line. Right click on the line, and select copy-&gt;Bytes (Printable Text Only). This will copy the human-readable portion of the packet which represents the Cookies associated with this website.</span></p>
<p style="margin-bottom: 0cm"><span style="font-style: normal">If you haven't already, install <a href="https://addons.mozilla.org/en-US/firefox/addon/748" onclick="javascript:pageTracker._trackPageview('/outbound/article/addons.mozilla.org');" target="_blank">Greasemonkey,</a> and the CookieInjector userscript. Clear your private data, ensuring that the </span><em>Cookies</em><span style="font-style: normal"> and </span><em>Authenticated Sessions</em><span style="font-style: normal"> options are selected. This will delete all your cookies, so we can see the script in action. Press </span><em>alt-c</em><span style="font-style: normal"> to view the CookieInjector dialogue, paste the cookie string from wireshark into the text box and click OK. </span></p>
<p style="margin-bottom: 0cm; font-style: normal">Congratulations! Your cookies have now been restored!</p>
<p style="margin-bottom: 0cm; font-style: normal">
<h3>How The Script Works:</h3>
<p style="margin-bottom: 0cm; font-style: normal">After the page has loaded the CookieInjector class is initialized. This involves setting up the dialogue and binding a function to the onkeydown event. When the user presses the ALT-C key combination, the CookieInjector keyPress function is called, which checks to see if the correct key combination has been triggered. If it is valid, the dialogue's display style is changed, making it visible in the middle of the page.</p>
<p style="margin-bottom: 0cm; font-style: normal">After the user enters the cookie that was copied from Wireshark, the script does a quick cleanup of the string, and then adds the cookies to the browsing session.</p>
<p style="margin-bottom: 0cm; font-style: normal">Note that the cookie's host will be the domain that is loaded in the browser when the cookie is injected. The root path will be used for the root of the cookie to ensure that the cookie is persistent across the entire domain. Finally, the cookie is a session cookie, which means that the cookie will expire when the browser is closed.</p>
<p style="margin-bottom: 0cm; font-style: normal">
<h3>Security Implications Of Cookies</h3>
<p style="margin-bottom: 0cm; font-style: normal">The use of cookies for identification and authentication presents a dangerous security risk for un-encrypted connections. Most websites (such as Hotmail, Facebook and Gmail), only encrypt the username and password when initially authenticating the user and all traffic following the initial handshake is un-encrypted. As a result, the cookie information is readable by anyone who is listening with appropriate software, and malicious users can steal the cookies of other users on the network, possibly gaining access to their accounts. Un-encrypted or weakly encrypted wireless connections (those which do not use WPA or stronger encryption schemes) are especially susceptible to cookie stealing. This is because anyone with a wireless card can simply listen to all network traffic as it is broadcast through the air, intercepting cookies, images, web pages and any other traffic which may or not be intended for them. Intercepting traffic on a switched network (most LANs) is more complex, but can be accomplished using <a title="Wikipedia: ARP Spoofing" href="http://en.wikipedia.org/wiki/ARP_spoofing" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" target="_blank">ARP Poisoning</a> or software such as <a href="http://ettercap.sourceforge.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/ettercap.sourceforge.net');" target="_blank">Ettercap</a></p>
<p style="margin-bottom: 0cm; font-style: normal">The take-home lesson is to use encrypted connections, like https, whenever privacy is important. Always remember that if the connection is not encrypted anyone could be listening in.</p>
<p style="margin-bottom: 0cm; font-style: normal"><a href="/code/cookieinjector.user.js">Download CookieInjection Userscript</a></p>
<p style="margin-bottom: 0cm; font-style: normal">
<h3>External Links:</h3>
<p style="margin-bottom: 0cm; font-style: normal">Greasemonkey: <a href="https://addons.mozilla.org/en-US/firefox/addon/748" onclick="javascript:pageTracker._trackPageview('/outbound/article/addons.mozilla.org');" target="_blank">https://addons.mozilla.org/en-US/firefox/addon/748</a><br />
HTTP Protocol: <a href="http://en.wikipedia.org/wiki/HTTP" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" target="_blank">http://en.wikipedia.org/wiki/HTTP</a><br />
TCP Protocol: <a href="http://en.wikipedia.org/wiki/TCP" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" target="_blank">http://en.wikipedia.org/wiki/TCP</a><br />
Cookies: <a href="http://en.wikipedia.org/wiki/HTTP_cookie" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" target="_blank">http://en.wikipedia.org/wiki/HTTP_cookie</a><br />
Wireshark: <a href="http://www.wireshark.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.wireshark.org');" target="_blank">http://www.wireshark.org/</a><br />
Ettercap: <a href="http://ettercap.sourceforge.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/ettercap.sourceforge.net');" target="_blank">http://ettercap.sourceforge.net/</a><br />
ARP Poisoning: <a href="http://en.wikipedia.org/wiki/ARP_spoofing" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" target="_blank">http://en.wikipedia.org/wiki/ARP_spoofing</a><br />
Ethereal: <a href="http://www.ethereal.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ethereal.com');" target="_blank">http://www.ethereal.com/</a></p>
<div id="cookieInjectorDiv" style="background: #dddddd none repeat scroll 0% 0%; display: none; position: fixed; opacity: 0.9; top: 40%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; left: 40%; width: 20%;">
<div>Wireshark Cookie Dump:</p>
<input id="cookieInjectorCookie" type="text" />
<button onclick="cookieInjector.writeCookie();">OK</button><button onclick="cookieInjector.hide();">Cancel</button></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/12/feed</wfw:commentRss>
		</item>
		<item>
		<title>SFU ULife Calendar Refactor</title>
		<link>http://dustint.com/archives/13</link>
		<comments>http://dustint.com/archives/13#comments</comments>
		<pubDate>Mon, 14 Jan 2008 08:09:08 +0000</pubDate>
		<dc:creator>Dustin</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[SFU]]></category>

		<category><![CDATA[Web]]></category>

		<category><![CDATA[Calendar]]></category>

		<category><![CDATA[Community]]></category>

		<category><![CDATA[ULife]]></category>

		<guid isPermaLink="false">http://dustint.com/?p=13</guid>
		<description><![CDATA[ This weekend I was working on some SFU community sites and I decided it would be nice to display the SFU ULife calendar on one website in particular. SFU ULife is a community building initiative which aims to increase the visibility of the community and events at SFU in a pledge to increase student [...]]]></description>
			<content:encoded><![CDATA[<p> This weekend I was working on some SFU community sites and I decided it would be nice to display the SFU ULife calendar on one website in particular. SFU ULife is a community building initiative which aims to increase the visibility of the community and events at SFU in a pledge to increase student involvement and awareness. Read more about ULife's goals <a href="http://www.sfu.ca/ulife/AboutUs/TheUlifeInitiative/index.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.sfu.ca');" title="SFU ULife" target="_blank">Here</a>.</p>
<p>As part of this initiative ULife maintains an events calendar that is available both in HTML and RSS formats. I was much more interested in the RSS feed as it can be easily parsed and manipulated by server-side PHP.</p>
<h3>How The Refactor Works (In A Nutshell)</h3>
<p>The basic operation of the script is very straight-forward.</p>
<ol>
<li>A copy of the ULife calendar RSS feed is downloaded and cached from <a href="https://events.sfu.ca/rss/calendar_id/3.xml" onclick="javascript:pageTracker._trackPageview('/outbound/article/events.sfu.ca');">https://events.sfu.ca/rss/calendar_id/3.xml</a>.</li>
<li>The RSS feed is parsed by a slightly modified version of <a href="http://lastrss.oslab.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/lastrss.oslab.net');">Last RSS</a> which converts the feed into PHP associative arrays.</li>
<li>The arrays are then passed to the <a href="http://www.smarty.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.smarty.net');">Smarty Template Engine</a> which makes the output look all pretty</li>
</ol>
<p>Simple eh? There is a little bit more of business logic, as the user is able to specify the template file to use, the CSS file to use, the number of days to display as well as indicate if the script is to output a full HTML page or just the HTML code needed for the calendar.</p>
<p>Currently the preferred way to include the calendar on a dynamic web-page is to use the PHP readfile (or equivalent) command with the argument being the path to the Refactor script. If the page is not dynamically generated the other option is to use a Javascript include, which uses cross site scripting to fetch the content and write it to the screen.</p>
<p>Right now there is only a single template available - a vertically aligned one, and a single style - a dark one. Users of the script can of course come up with their own style-sheets by simply downloading and editing the dark style sheet to their liking. If there is demand for it, I will write more templates, starting with a horizontally aligned template, along with a couple more style sheets.</p>
<p>To play around with the Calendar Refactor take a look at <a href="http://ulife.dustint.com" >http://ulife.dustint.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dustint.com/archives/13/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
