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

<channel>
	<title>GPUG.ca - Guelph PHP Users Group</title>
	<atom:link href="http://www.gpug.ca/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gpug.ca</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Thu, 21 Mar 2013 01:08:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>GPUG 2.6: Building Test-centric Teams</title>
		<link>http://www.gpug.ca/2013/03/20/gpug-2-6-building-test-centric-teams/</link>
		<comments>http://www.gpug.ca/2013/03/20/gpug-2-6-building-test-centric-teams/#comments</comments>
		<pubDate>Thu, 21 Mar 2013 01:08:53 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=164</guid>
		<description><![CDATA[Our guest speaker this month will be Chris Hartjes, better known to many as The Grumpy Programmer. He&#8217;ll be speaking on building test-centric teams.]]></description>
				<content:encoded><![CDATA[<p>Our guest speaker this month will be Chris Hartjes, better known to many as The Grumpy Programmer. He&#8217;ll be speaking on building test-centric teams.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2013/03/20/gpug-2-6-building-test-centric-teams/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GPUG 2.4: Introduction to Twig</title>
		<link>http://www.gpug.ca/2013/02/20/gpug-2-4-introduction-to-twig/</link>
		<comments>http://www.gpug.ca/2013/02/20/gpug-2-4-introduction-to-twig/#comments</comments>
		<pubDate>Thu, 21 Feb 2013 01:56:11 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=159</guid>
		<description><![CDATA[Our speaker this month will be Mark Story, senior developer at Freshbooks and project lead of CakePHP. He&#8217;ll be talking about the popular templating language Twig, which he is a contributor to.More information can be found on the GuelphPHP page on Meetup.]]></description>
				<content:encoded><![CDATA[<p>Our speaker this month will be Mark Story, senior developer at Freshbooks and project lead of CakePHP. He&#8217;ll be talking about the popular templating language Twig, which he is a contributor to.More information can be found on the GuelphPHP page on <a href="http://www.meetup.com/Guelph-PHP/">Meetup</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2013/02/20/gpug-2-4-introduction-to-twig/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPUG 2.2: Open Mic Night</title>
		<link>http://www.gpug.ca/2012/09/04/gpug-2-2-open-mic-night/</link>
		<comments>http://www.gpug.ca/2012/09/04/gpug-2-2-open-mic-night/#comments</comments>
		<pubDate>Wed, 05 Sep 2012 00:57:20 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=142</guid>
		<description><![CDATA[This month we&#8217;re switching it up and handing control over to our group members. This is your chance to drop some essential wisdom on your fellow GPUGites, talk about anything relating to PHP and web development. What new and exciting tools are you using to make your life easier? Tired of being made fun of [...]]]></description>
				<content:encoded><![CDATA[<p>This month we&#8217;re switching it up and handing control over to our group members. This is your chance to drop some essential wisdom on your fellow GPUGites, talk about anything relating to PHP and web development. What new and exciting tools are you using to make your life easier? Tired of being made fun of for using EMACS by ignorant VIM users? Show us the light then!</p>
<p>We&#8217;re capping the length of each talk to 20 minutes, if you only need 5 minutes then great, we can have 3 other talks just like it. Need more than 20 minutes? <a href="mailto:colin@gpug.ca">Let&#8217;s talk</a> about doing a full length presentation in 2013 (considering the world doesn&#8217;t end on <a title="End of Days" href="http://en.wikipedia.org/wiki/2012_phenomenon">2012/12/21</a>).</p>
<p>Open Mic Night is going to be an intense, concentrated throw down of web dev know-how! Strap on your boots and hold on tight!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/09/04/gpug-2-2-open-mic-night/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPUG 2.1: All about Selenium</title>
		<link>http://www.gpug.ca/2012/09/04/gpug-2-1-all-about-selenium/</link>
		<comments>http://www.gpug.ca/2012/09/04/gpug-2-1-all-about-selenium/#comments</comments>
		<pubDate>Wed, 05 Sep 2012 00:56:05 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=140</guid>
		<description><![CDATA[This month a guest speaker from Freshbooks will be presenting the Selenium testing framework to us. Come and find out how to automate your browser testing as part of your test suite and build process while meeting other PHP developers and enjoying a few snacks.]]></description>
				<content:encoded><![CDATA[<p>This month a guest speaker from Freshbooks will be presenting the <a href="http://seleniumhq.org/">Selenium testing framework</a> to us. Come and find out how to automate your browser testing as part of your test suite and build process while meeting other PHP developers and enjoying a few snacks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/09/04/gpug-2-1-all-about-selenium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPUG 2.0: The Anniversary Edition</title>
		<link>http://www.gpug.ca/2012/09/04/gpug-2-0-the-anniversary-edition/</link>
		<comments>http://www.gpug.ca/2012/09/04/gpug-2-0-the-anniversary-edition/#comments</comments>
		<pubDate>Wed, 05 Sep 2012 00:54:30 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=138</guid>
		<description><![CDATA[It&#8217;s hard to believe but September is our first anniversary as a group! Ilia Alshanetsky, who gave our first talk in September 2011, will be back to present the new features that are available in PHP 5.4 to us and they&#8217;ll be the usual mix of socialising and snacks. We&#8217;ll also have a few freebies [...]]]></description>
				<content:encoded><![CDATA[<p>It&#8217;s hard to believe but September is our first anniversary as a group! Ilia Alshanetsky, who gave our first talk in September 2011, will be back to present the new features that are available in PHP 5.4 to us and they&#8217;ll be the usual mix of socialising and snacks. We&#8217;ll also have a few freebies for members too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/09/04/gpug-2-0-the-anniversary-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing Protected Methods with PHPUnit</title>
		<link>http://www.gpug.ca/2012/06/02/testing-protected-methods-with-phpunit/</link>
		<comments>http://www.gpug.ca/2012/06/02/testing-protected-methods-with-phpunit/#comments</comments>
		<pubDate>Sat, 02 Jun 2012 20:10:33 +0000</pubDate>
		<dc:creator>colin</dc:creator>
				<category><![CDATA[Coding!]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=119</guid>
		<description><![CDATA[Alright, I know that idea of &#8216;testing protected methods&#8217; makes some people cringe. That instead of directly testing your protected methods you should test them indirectly via the public methods. I can support that argument, after all, as long as the code is being tested we&#8217;re doing our jobs. BUT when tests start to fail [...]]]></description>
				<content:encoded><![CDATA[<p>Alright, I know that idea of &#8216;testing protected methods&#8217; makes some people cringe. That instead of directly testing your protected methods you should test them indirectly via the public methods. I can support that argument, after all, as long as the code is being tested we&#8217;re doing our jobs. BUT when tests start to fail where&#8217;s the break? is it the public method? or the protected method? maybe you&#8217;ve royally fucked something during a refactor and you broke them both &#8230; who knows? This is why I personally think that directly testing your protected methods is a good thing, and, since I&#8217;m the one writing this post, it&#8217;s the right thing to do as well.</p>
<p>Let&#8217;s start with an example, let&#8217;s say you&#8217;re working on this amazing new framework and it&#8217;s going to change the world and win you thousands of twitter followers. However, before that happens you need to make sure that you&#8217;ve got decent coverage and everything appears to work. Part of your framework deals with persisting uploaded files and since this is the most amazing and flexible framework evar, you&#8217;re planning on giving multiple options for persistent storage. Users of the framework can choose to persist their files to the local filesystem (boooring), they can store them in some sort of webscale document store (like /dev/null maybe) or they can even choose to put them up in the cloud because clouds are fluffy and great and that&#8217;s where the Care Bears live.</p>
<p>I&#8217;m an OO programmer and to me, this use case absolutely begs me to use an abstract base class for the plain jane logic and then a set of subclasses to deal with specifics. Let&#8217;s move ahead then and start writing some code. Our base class is going to have a public method called persist, if everything goes as planned, the persist method will move the uploaded file from it&#8217;s temporary place on the filesystem to it&#8217;s more permanent home on the filesystem/in the document store/in the cloud/where ever. Also, because we&#8217;re good developers, the method is also responsible for logging the success or failure of this method.</p>
<p>Side Note: this is probably a good time to mention that all the examples here are available from our GitHub  <a title="blog-post-examples repository" href="https://github.com/GPUG/blog-post-examples" target="_blank">blog-post-examples repository</a></p>
<p>Here is the persist method from the abstract base class Persister</p>
<script src="https://gist.github.com/2772887.js"></script><noscript><pre><code class="language-php php">&lt;?php

// interesting bits up here

public function persist()
{

	try {
		// maybe do some preprocessing of the file
		// make sure it's safe, etc

		// call out to a protected method to actually store the file somewhere
		$this-&gt;_persist();
	} catch (\Exception $e) {
		// this exception will have some nitty gritty details useful for logging
		$this-&gt;_logger-&gt;log(
			'Unable to persist uploaded file: ' . $e-&gt;getMessage(), 
			Logger::LEVEL_OHNOES
		);

		// throw a new friendly exception
		throw new \Exception(
			'We were unable to store your file, maybe retry a little later?',
			0, // we don't need no stinking error codes
			$e
		);
	}

	$this-&gt;_logger-&gt;log('Successfully stored uploaded file in: ' . $this-&gt;getLocation());

	return true;
}

// moar interesting bits down here</code></pre></noscript>
<p>and here are the nitty gritty details of the _persist method in the Persister subclass File</p>
<script src="https://gist.github.com/2772976.js"></script><noscript><pre><code class="language-php php">&lt;?php

// interesting bits

protected function _persist()
{
	$this-&gt;_location = tempnam(sys_get_temp_dir(), 'UL-');

	if (!$this-&gt;_moveUploadedFile()) {
		unlink($this-&gt;_location);
		$this-&gt;_location = null;
		throw new \Exception('error moving uploaded file');
	}
}

// interesting bits</code></pre></noscript>
<p>Great, we&#8217;ve got some code, time to test it. I&#8217;m going to focus on showing how to test the protected _persist method of the File subclass but remember since we&#8217;re directly testing the protected method we&#8217;ve also got to test it&#8217;s caller separately. Those tests have been written as well and be seen <a title="Tests for the Persister class" href="https://github.com/GPUG/blog-post-examples/blob/master/testing-protected-methods/GPUG/Test/Examples/PersisterTest.php" target="_blank">here</a> if you don&#8217;t believe me. Onto the testing &#8230;</p>
<h2>Method 1: Reflection</h2>
<p>PHP&#8217;s <a title="PHP's Reflection API" href="http://ca.php.net/manual/en/book.reflection.php" target="_blank">Reflection API</a> is really handy for doing things your mother told you not to. If you haven&#8217;t mucked around with it I really recommend doing so, you can reach into objects and fiddle with their private bits and, as in this example, make protected methods a little more accessible.</p>
<script src="https://gist.github.com/2773053.js"></script><noscript><pre><code class="language-php php">&lt;?php

// interesting bits

public function test_protected_persist_directly_with_reflection_success()
{
	$filePersister = new File($_FILES, $this-&gt;logger);

	$reflectedPersist = new \ReflectionMethod($filePersister, '_persist');
	$reflectedPersist-&gt;setAccessible(true);
	$reflectedPersist-&gt;invoke($filePersister);

	$persistedLocation = \PHPUnit_Framework_Assert::readAttribute($filePersister, '_location');
	$this-&gt;assertRegExp('/UL-/', $persistedLocation);
	$this-&gt;assertTrue(file_exists($persistedLocation));
	$this-&gt;assertEquals(&quot;Hello World\n&quot;, file_get_contents($persistedLocation));
}

public function test_protected_persist_directly_with_refelection_failure()
{

	$filePersisterMock = $this-&gt;getMockBuilder('GPUG\Examples\Persister\File')
		-&gt;setConstructorArgs(array($_FILES, $this-&gt;logger))
		-&gt;setMethods(array('_moveUploadedFile'))
		-&gt;getMock();

	$filePersisterMock-&gt;expects($this-&gt;once())
		-&gt;method('_moveUploadedFile')
		-&gt;will($this-&gt;returnValue(false));

	$reflectedPersist = new \ReflectionMethod($filePersisterMock, '_persist');
	$reflectedPersist-&gt;setAccessible(true);

	try {
		$reflectedPersist-&gt;invoke($filePersisterMock);
	} catch (\Exception $e) {
		$this-&gt;assertNull(\PHPUnit_Framework_Assert::readAttribute($filePersisterMock, '_location'));
		$this-&gt;assertEquals('error moving uploaded file', $e-&gt;getMessage());
		return;
	}

	$this-&gt;fail('Expected exception was not thrown in test_protected_persist_directly_with_reflection_failure');
}

// interesting bits</code></pre></noscript>
<h2>Method 2: A &#8216;Testable&#8217; Subclass</h2>
<p>If reflection isn&#8217;t your thing you can always define a subclass of the Class Under Test (CUT) which has public wrapper methods of the protected methods you want to test. These classes are typically defined at the bottom of the CUT&#8217;s test case file, here is the definition of the TestableFile subclass.</p>
<script src="https://gist.github.com/2773074.js"></script><noscript><pre><code class="language-php php">&lt;?php

class TestableFile extends File
{
	public function _persistWrapper()
	{
		$this-&gt;_persist();
	}
}
</code></pre></noscript>
<p>With the TestableFile subclass defined, testing the protected _persist method is really simple.</p>
<script src="https://gist.github.com/2773091.js"></script><noscript><pre><code class="language-php php">&lt;?php

//interesting bits

public function test_protected_persist_with_testable_subclass_success()
{
	$filePersister = new TestableFile($_FILES, $this-&gt;logger);
	$filePersister-&gt;_persistWrapper();

	$persistedLocation = \PHPUnit_Framework_Assert::readAttribute($filePersister, '_location');
	$this-&gt;assertRegExp('/UL-/', $persistedLocation);
	$this-&gt;assertTrue(file_exists($persistedLocation));
	$this-&gt;assertEquals(&quot;Hello World\n&quot;, file_get_contents($persistedLocation));
}

public function test_protected_persist_with_testable_subclass_failure()
{

	$filePersisterMock = $this-&gt;getMockBuilder('GPUG\Test\Examples\Persister\TestableFile')
		-&gt;setConstructorArgs(array($_FILES, $this-&gt;logger))
		-&gt;setMethods(array('_moveUploadedFile'))
		-&gt;getMock();

	$filePersisterMock-&gt;expects($this-&gt;once())
		-&gt;method('_moveUploadedFile')
		-&gt;will($this-&gt;returnValue(false));

	try {
		$filePersisterMock-&gt;_persistWrapper();
	} catch (\Exception $e) {
		$this-&gt;assertNull(\PHPUnit_Framework_Assert::readAttribute($filePersisterMock, '_location'));
		$this-&gt;assertEquals('error moving uploaded file', $e-&gt;getMessage());
		return;
	}

	$this-&gt;fail('Expected exception was not thrown in test_protected_persist_directly_with_reflection_failure');

}

// interesing bits</code></pre></noscript>
<h2>Method 3: Indirection</h2>
<p>Earlier I mentioned I could support the argument that you should test your protected methods indirectly by testing it&#8217;s callers from the public api &#8230; so here goes.</p>
<p>If you plan on testing your protected methods indirectly via the public api you need to stay focused on the purpose *and expected outcome* of each test. This method doesn&#8217;t mean you get to skip testing the public api separately. You should have a set of tests that cover the public caller of the protected method (in our case it&#8217;s the persist method of the abstract base class Persister). You can accomplish this by using Mock objects and stubbing the protected method call. This way your tests focus directly on the public method and it&#8217;s effects, not the effects of the protected method it calls out to. Similarly, when testing the protected method you only need to focus on the effects of the protected method itself.</p>
<script src="https://gist.github.com/2773143.js"></script><noscript><pre><code class="language-php php">&lt;?php

// interesting bits

public function test_protected_persist_indirectly_via_public_persist_success()
{
	$filePersister = new File($_FILES, $this-&gt;logger);
	$this-&gt;assertTrue($filePersister-&gt;persist());

	$persistedLocation = \PHPUnit_Framework_Assert::readAttribute($filePersister, '_location');
	$this-&gt;assertRegExp('/UL-/', $persistedLocation);
	$this-&gt;assertTrue(file_exists($persistedLocation));
	$this-&gt;assertEquals(&quot;Hello World\n&quot;, file_get_contents($persistedLocation));
}

public function test_protected_persist_indirectly_via_public_persist_failure()
{
	$filePersisterMock = $this-&gt;getMockBuilder('GPUG\Examples\Persister\File')
		-&gt;setConstructorArgs(array($_FILES, $this-&gt;logger))
		-&gt;setMethods(array('_moveUploadedFile'))
		-&gt;getMock();

	$filePersisterMock-&gt;expects($this-&gt;once())
		-&gt;method('_moveUploadedFile')
		-&gt;will($this-&gt;returnValue(false));

	try {
		$filePersisterMock-&gt;persist();
	} catch (\Exception $e) {
		$this-&gt;assertNull(\PHPUnit_Framework_Assert::readAttribute($filePersisterMock, '_location'));
		$this-&gt;assertEquals('We were unable to store your file, maybe retry a little later?', $e-&gt;getMessage());

		$pe = $e-&gt;getPrevious();
		$this-&gt;assertNotNull($pe);
		$this-&gt;assertEquals('error moving uploaded file', $pe-&gt;getMessage());
		return;
	}

	$this-&gt;fail('Expected exception was not thrown in test_protected_persist_indirectly_via_public_persist_failure');

}

// interesting bits</code></pre></noscript>
<p>That&#8217;s it! Testing protected methods has never been easier. Remember, in the end it doesn&#8217;t really matter which method you choose. Whether it&#8217;s Reflection, a Testable Subclass, or Indirection, your code is being throughly tested and your app is better off because of it. You should feel good!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/06/02/testing-protected-methods-with-phpunit/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GPUG V 1.10</title>
		<link>http://www.gpug.ca/2012/03/11/gpug-v-1-10/</link>
		<comments>http://www.gpug.ca/2012/03/11/gpug-v-1-10/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 15:47:48 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=111</guid>
		<description><![CDATA[This month Joël Perras will be our guest speaker. He&#8217;ll be presenting to us on NoSQL databases and Map Reduce.]]></description>
				<content:encoded><![CDATA[<p>This month <a href="http://nerderati.com/">Joël Perras</a> will be our guest speaker. He&#8217;ll be presenting to us on NoSQL databases and Map Reduce.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/03/11/gpug-v-1-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPUG V 1.9</title>
		<link>http://www.gpug.ca/2012/03/11/gpug-v-1-9/</link>
		<comments>http://www.gpug.ca/2012/03/11/gpug-v-1-9/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 15:43:33 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=109</guid>
		<description><![CDATA[This month Kevin Bond will be giving us an introduction to Symfony 2. Come and find out how to leverage the power of this full stack PHP framework when building your own applications.]]></description>
				<content:encoded><![CDATA[<p>This month <a href="http://zenstruck.com/">Kevin Bond</a> will be giving us an introduction to <a href="http://symfony.com/">Symfony 2</a>. Come and find out how to leverage the power of this full stack PHP framework when building your own applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/03/11/gpug-v-1-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPUG V 1.8</title>
		<link>http://www.gpug.ca/2012/03/11/gpug-v-1-8/</link>
		<comments>http://www.gpug.ca/2012/03/11/gpug-v-1-8/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 15:32:11 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=106</guid>
		<description><![CDATA[Our speaker this month will be Colin DeCarlo of Freshbooks. He&#8217;ll be talking about using Liquibase to manage database migrations as well as how the tool can be integrated with continuous integration to set us easy, painless and reversible database changes.]]></description>
				<content:encoded><![CDATA[<p>Our speaker this month will be Colin DeCarlo of Freshbooks. He&#8217;ll be talking about using <a href="http://www.liquibase.org/">Liquibase</a> to manage database migrations as well as how the tool can be integrated with continuous integration to set us easy, painless and reversible database changes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/03/11/gpug-v-1-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPUG V 1.7</title>
		<link>http://www.gpug.ca/2012/03/11/gpug-v-1-7/</link>
		<comments>http://www.gpug.ca/2012/03/11/gpug-v-1-7/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 15:27:43 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Meetings]]></category>

		<guid isPermaLink="false">http://www.gpug.ca/?p=104</guid>
		<description><![CDATA[Our speaker this month will be Sean Yo. He&#8217;ll be presenting on why, how and when you might want to use Apache server side includes. We&#8217;ll also have our usual mix of socialising and food.]]></description>
				<content:encoded><![CDATA[<p>Our speaker this month will be <a href="http://seanyo.ca/">Sean Yo</a>. He&#8217;ll be presenting on why, how and when you might want to use Apache server side includes. We&#8217;ll also have our usual mix of socialising and food.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gpug.ca/2012/03/11/gpug-v-1-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.320 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-05-18 07:47:16 -->
