<?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>dom111.co.uk &#187; component</title>
	<atom:link href="http://www.dom111.co.uk/blog/tag/component/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dom111.co.uk/blog</link>
	<description>Move along. Nothing to see here.</description>
	<lastBuildDate>Wed, 14 Jul 2010 19:30:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>CakePHP: Components, redirect fail (On my part&#8230;)</title>
		<link>http://www.dom111.co.uk/blog/coding/cakephp-components-redirect-fail-on-my-part/171</link>
		<comments>http://www.dom111.co.uk/blog/coding/cakephp-components-redirect-fail-on-my-part/171#comments</comments>
		<pubDate>Wed, 26 Aug 2009 19:58:46 +0000</pubDate>
		<dc:creator>dom111</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[epic fail]]></category>
		<category><![CDATA[lessons learned]]></category>
		<category><![CDATA[redirect]]></category>
		<category><![CDATA[redirect loses id]]></category>
		<category><![CDATA[redirect losing id]]></category>
		<category><![CDATA[redirect strips id]]></category>

		<guid isPermaLink="false">http://www.dom111.co.uk/blog/?p=171</guid>
		<description><![CDATA[I&#8217;ve been working on a CakePHP project lately and created a small component which was only needed in one of my controllers: class CounterComponent extends Component &#123; var $components = array&#40; 'Session' &#41;; &#160; function i&#40;&#41; &#123; if &#40;$this-&#62;Session-&#62;check&#40;'Counter.i'&#41;&#41; &#123; $i = &#40;$this-&#62;Session-&#62;read&#40;'Counter.i'&#41; + 1&#41;; &#160; &#125; else &#123; $i = 0; &#125; &#160; $this-&#62;Session-&#62;write&#40;'Counter.i', [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a <a href="http://www.cakephp.org/">CakePHP</a> project lately and created a small component which was only needed in one of my controllers:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> CounterComponent <span style="color: #000000; font-weight: bold;">extends</span> Component <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$components</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'Session'</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> i<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">check</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Counter.i'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Counter.i'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Counter.i'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$i</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">function</span> clear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Counter.i'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span id="more-171"></span>It simply kept track of a number over the life of the current session and incremented it each time it was accessed. I did&#8217;t think it would interfere in my other controllers, and it didn&#8217;t until I tried to perform a simple redirect later on in the app:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">function</span> edit<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// process it</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Customer</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Customer</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'controller'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'customers'</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'action'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'view'</span><span style="color: #339933;">,</span>
        <span style="color: #000088;">$id</span>
      <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Customer</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'first'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$id</span>
      <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">get_defined_vars</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">render</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'form'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>That code seemed simple enough, but each and every time it was run, I&#8217;d be sent to <code>/customers/edit</code>, instead of <code>/customers/view/1</code>.</p>
<p>WTF? Cake is losing my <code>id</code>s?</p>
<p>So I tried changing the redirect to a string:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/customers/view/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>No difference, still redirects to <code>/customers/edit</code>. Ok fine. Lets try a full URL:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.google.co.uk/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Serisouly. Still? All this happened over a series of a couple of days, each session of <del>coding</del><ins>banging my head against a brick wall</ins> leaving me more frustrated. I got mad I created a <code>TestsController</code> with an action <code>test</code> which exhibited the same behaviour&#8230; (But only after I&#8217;d moved everything into the <code>AppController</code>, whilst franticly trying everything&#8230; *sigh*)</p>
<p>After many visits to the <a href="http://book.cakephp.org/">CakePHP documentation</a> I decided to re-investigate the <a href="http://api.cakephp.org/view_source/controller/#line-536">source code</a> and see if I had missed anything. The <code lang="php">Controller::redirect()</code> function contains this code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">		<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Component</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beforeRedirect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$status</span><span style="color: #339933;">,</span> <span style="color: #000088;">$exit</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$resp</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$resp</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$resp</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'url'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$resp</span><span style="color: #339933;">,</span> EXTR_OVERWRITE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$resp</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$resp</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span></pre></div></div>

<p>&#8220;But that&#8217;s fine!&#8221;, I thought, &#8220;I don&#8217;t even have a <code>beforeRedirect()</code> function in my component, and surely the class I&#8217;m extending will just return <code>null</code>.&#8221; Oh dear. Assumption. <a href="http://api.cakephp.org/view_source/component/#line-139">There it is</a>, done now.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Component::beforeRedirect</span>
	<span style="color: #000000; font-weight: bold;">function</span> beforeRedirect<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span><span style="color: #000088;">$controller</span><span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$status</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$exit</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_primary <span style="color: #b1b100;">as</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$component</span> <span style="color: #339933;">=&amp;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_loaded<span style="color: #009900;">&#91;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$component</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">enabled</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">method_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$component</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'beforeRedirect'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$resp</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$component</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">beforeRedirect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$controller</span><span style="color: #339933;">,</span> <span style="color: #000088;">$url</span><span style="color: #339933;">,</span> <span style="color: #000088;">$status</span><span style="color: #339933;">,</span> <span style="color: #000088;">$exit</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$resp</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
				<span style="color: #000088;">$response</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$resp</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$response</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Crap. It returns an empty array, which the <code>redirect()</code> function will use because it isn&#8217;t <code>null</code>, which will redirect to the current controller/action but strip out the <code>id</code>.</p>
<p><strong>Lesson</strong>: Always, <strong><em>ALWAYS</em></strong>, create a base component to extend, or, alternatively, just <a href="http://book.cakephp.org/view/65/MVC-Class-Access-Within-Components">read the fricking manual properly</a>.</p>
<p><strong>TL;DR</strong>: I failed at creating a CakePHP component. Fix: <code>class MyComponent extends Object {}</code> instead of <code>class MyComponent extends Component {}</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dom111.co.uk/blog/coding/cakephp-components-redirect-fail-on-my-part/171/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
