<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Kohana on Murat Useinov</title>
    <link>https://useinov.com/tags/kohana/</link>
    <description>Recent content in Kohana on Murat Useinov</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 04 Mar 2016 20:10:00 +0300</lastBuildDate>
    <atom:link href="https://useinov.com/tags/kohana/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Freezing the Kohana layer</title>
      <link>https://useinov.com/posts/2016/freezing-kohana/</link>
      <pubDate>Fri, 04 Mar 2016 20:10:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2016/freezing-kohana/</guid>
      <description>&lt;p&gt;Kohana 3.3, on a project that earns money every day. The framework is effectively finished. The repository barely moves, the community left years ago. Nobody will approve a rewrite, and I have stopped asking. This is a normal situation and it deserves a better plan than &amp;ldquo;someday we migrate&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The plan we settled on is a freeze.&lt;/p&gt;
&lt;p&gt;Pin the exact framework version and vendor it. Not &amp;ldquo;3.3.*&amp;rdquo;, the exact commit. The build must be reproducible in five years, when the original download link is dead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kohana on PHP 7: whose problem is it</title>
      <link>https://useinov.com/posts/2015/kohana-on-php7/</link>
      <pubDate>Tue, 08 Sep 2015 10:45:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2015/kohana-on-php7/</guid>
      <description>&lt;p&gt;The test suite went green on the PHP 7 release candidate on the second try. I expected worse. Then I opened &lt;code&gt;modules/&lt;/code&gt; and the mood changed.&lt;/p&gt;
&lt;p&gt;The core mostly works. The community is patching compatibility in the 3.3 branch on GitHub right now, and the fixes are small: deprecated PHP 4 style constructors, changed engine behavior in dark corners. Whoever says the framework is dead is not reading the commit log. It is not dead. It is volunteers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Composer in a legacy Kohana project</title>
      <link>https://useinov.com/posts/2015/kohana-meets-composer/</link>
      <pubDate>Thu, 22 Jan 2015 20:05:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2015/kohana-meets-composer/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;APPPATH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;../vendor/autoload.php&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One line in &lt;code&gt;bootstrap.php&lt;/code&gt;. This month it became the whole strategy for a project we decided to keep on Kohana.&lt;/p&gt;
&lt;p&gt;The framework is quiet, the project is alive. These two facts have to coexist somehow. The plan: nothing new gets written the Kohana way. New dependencies come through Composer, and Kohana&amp;rsquo;s autoloader and Composer&amp;rsquo;s autoloader live together fine.&lt;/p&gt;
&lt;p&gt;First candidate was the HTTP client. We talk to two external APIs, and the code around &lt;code&gt;Request_Client_External&lt;/code&gt; was not pretty. Guzzle is better in every way. But Guzzle does not spread through the codebase. There is an interface:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Host header is user input</title>
      <link>https://useinov.com/posts/2014/host-header-is-user-input/</link>
      <pubDate>Tue, 23 Dec 2014 19:20:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2014/host-header-is-user-input/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$link&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;https://&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$_SERVER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;HTTP_HOST&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/reset/&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I wrote this line. More than once. It builds the link for a password reset email, and it looks like it reads something about the server. It does not. &lt;code&gt;Host&lt;/code&gt; comes from the client, same as any other header.&lt;/p&gt;
&lt;p&gt;Kohana 3.3.4 shipped this month with a fix around exactly this, and the topic is bigger than one framework.&lt;/p&gt;
&lt;p&gt;The attack is short. Someone requests a password reset for your email address and puts his own domain into the &lt;code&gt;Host&lt;/code&gt; header. The application trusts the header, builds the link, sends it. You receive a real email from a real site with a link to &lt;code&gt;evil.example&lt;/code&gt; and your real token in the path. You click. He collects the token. Host header poisoning, and no framework protects you from it out of the box.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Composer next to Kohana bootstrap</title>
      <link>https://useinov.com/posts/2014/composer-next-to-kohana/</link>
      <pubDate>Sun, 23 Nov 2014 21:10:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2014/composer-next-to-kohana/</guid>
      <description>&lt;p&gt;One line in &lt;code&gt;bootstrap.php&lt;/code&gt;, above &lt;code&gt;Kohana::init()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;DOCROOT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;vendor/autoload.php&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is the whole integration. Kohana keeps its modules and its underscore autoloader. Composer brings Packagist. Two autoloaders in one process, and they do not collide: Composer packages use namespaces, Kohana classes have underscores, the lookups never meet.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;require&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;guzzlehttp/guzzle&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;~5.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This setup runs in production on one of my projects for a few months. Zero problems from the autoloading side. The problems, when they came, were from me.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kohana is not developed anymore. Now what</title>
      <link>https://useinov.com/posts/2014/kohana-is-over-now-what/</link>
      <pubDate>Wed, 19 Nov 2014 19:30:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2014/kohana-is-over-now-what/</guid>
      <description>&lt;p&gt;The commit log of kohana/kohana on GitHub. I opened it in the summer and counted: a few merges a month, then fewer, then nothing. This year the official development basically stopped. Our projects did not stop working on that day. But the question came to my inbox three times since, so here is the answer.&lt;/p&gt;
&lt;p&gt;What to do with a working Kohana product depends on which of four situations you are in.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cascading filesystem: the best idea in Kohana</title>
      <link>https://useinov.com/posts/2014/cascading-filesystem/</link>
      <pubDate>Sun, 16 Nov 2014 22:05:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2014/cascading-filesystem/</guid>
      <description>&lt;p&gt;&lt;code&gt;Kohana::find_file()&lt;/code&gt;. One function, maybe forty lines. If I could keep only one thing from Kohana, this is the one.&lt;/p&gt;
&lt;p&gt;It looks for every file in order: &lt;code&gt;application/&lt;/code&gt;, then modules, then &lt;code&gt;system/&lt;/code&gt;. First found wins. Config, views, classes, i18n, everything goes through the same lookup.&lt;/p&gt;
&lt;p&gt;In practice: a module ships a config file, you put a file with the same name into &lt;code&gt;application/config/&lt;/code&gt;, change one key. The module does not know. Nothing under &lt;code&gt;modules/&lt;/code&gt; is touched.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kohana ORM and my first real N&#43;1</title>
      <link>https://useinov.com/posts/2014/kohana-orm-n-plus-one/</link>
      <pubDate>Wed, 12 Nov 2014 20:15:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2014/kohana-orm-n-plus-one/</guid>
      <description>&lt;p&gt;Fifty one queries. That is what the SQL panel of the Kohana profiler showed for one catalog page. Fifty posts on the page.&lt;/p&gt;
&lt;p&gt;Nothing changed in the code. The page took two seconds because there was more data than in spring, and the code was written for spring.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$post-&amp;gt;author-&amp;gt;name&lt;/code&gt; in a loop. One query for the list of posts, then one more for the author of every post, inside the &lt;code&gt;foreach&lt;/code&gt;. The line looks innocent, and that is the problem: lazy loading hides the price. You write the relation, you go home early, and the bill comes in six months.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HMVC in Kohana: a request inside a request</title>
      <link>https://useinov.com/posts/2014/kohana-hmvc/</link>
      <pubDate>Mon, 10 Nov 2014 21:40:00 +0300</pubDate>
      <guid>https://useinov.com/posts/2014/kohana-hmvc/</guid>
      <description>&lt;p&gt;&lt;code&gt;Request::factory(&#39;widgets/stats&#39;)&lt;/code&gt; inside a controller. A colleague looked at this line last week and asked the question I hear most often about Kohana: you already have a request, why make another one?&lt;/p&gt;
&lt;p&gt;I keep answering it at the desk. So I will write it down once. Short notes, mostly backend, mostly PHP. This is the first.&lt;/p&gt;
&lt;p&gt;The answer is composition. Take a dashboard. A stats block, a recent orders block, a notifications block. Each one needs its own data and its own logic. You can put all of it into one action. It works. In a month it is 300 lines and nobody wants to open it.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
