<?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>Colin Mollenhour&#039;s Technical Blog &#187; php</title>
	<atom:link href="http://colin.mollenhour.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://colin.mollenhour.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sat, 31 Jul 2010 06:52:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Adding Minimal Price To Any Product Collection in Magento</title>
		<link>http://colin.mollenhour.com/2009/06/04/adding-minimal-price-to-any-product-collection-in-magento/</link>
		<comments>http://colin.mollenhour.com/2009/06/04/adding-minimal-price-to-any-product-collection-in-magento/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 07:05:08 +0000</pubDate>
		<dc:creator>colin</dc:creator>
				<category><![CDATA[Magento]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://colin.mollenhour.com/?p=65</guid>
		<description><![CDATA[There are many &#8220;Bestseller&#8220;, &#8220;Most Viewed&#8221;, and other front-page modules available for Magento. Those that use the Reports module to maintain good performance have the slight drawback that they do not inherit the catalog/product_collection resource model and it&#8217;s handy addMinimalPrices() function. This function adds the fields necessary for the getPriceHtml($product, TRUE) function to work, which [...]]]></description>
			<content:encoded><![CDATA[<p>There are many &#8220;<a href="http://inchoo.net/ecommerce/magento/bestseller-products-in-magento/">Bestseller</a>&#8220;, &#8220;Most Viewed&#8221;, and other front-page modules available for Magento. Those that use the Reports module to maintain good performance have the slight drawback that they do not inherit the <code>catalog/product_collection</code> resource model and it&#8217;s handy <code>addMinimalPrices()</code> function. This function adds the fields necessary for the <code>getPriceHtml($product, TRUE)</code> function to work, which prints out the &#8220;As low as&#8221; text for products that have tiered pricing. This is a must-have feature if you use tiered pricing, so here is how you can make <code>getPriceHTML($product, TRUE)</code> work with any collection of products:
</p>
<pre class="brush: php;">
$productIds = array_keys($_products-&gt;getItems());
$minimalPriceModel = Mage::getResourceModel('catalogindex/price');
$minimalPriceModel-&gt;setStoreId(Mage::app()-&gt;getStore()-&gt;getId());
$minimalPriceModel-&gt;setCustomerGroupId(
  Mage::getSingleton('customer/session')-&gt;getCustomerGroupId());
$minimalPrices = $minimalPriceModel-&gt;getMinimalPrices($productIds);
foreach ($minimalPrices as $row) {
  $item = $_products-&gt;getItemById($row['entity_id']);
  if ($item) {
    $item-&gt;setData('minimal_price', $row['value']);
    $item-&gt;setData('minimal_tax_class_id', $row['tax_class_id']);
  }
}
</pre>
<p>There you have it!</p>
]]></content:encoded>
			<wfw:commentRss>http://colin.mollenhour.com/2009/06/04/adding-minimal-price-to-any-product-collection-in-magento/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hiding &#8220;Out of Stock&#8221; Items in Magento</title>
		<link>http://colin.mollenhour.com/2009/06/02/hiding-out-of-stock-items-in-magento/</link>
		<comments>http://colin.mollenhour.com/2009/06/02/hiding-out-of-stock-items-in-magento/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 23:48:57 +0000</pubDate>
		<dc:creator>colin</dc:creator>
				<category><![CDATA[Magento]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://colin.mollenhour.com/?p=56</guid>
		<description><![CDATA[Updated 7/14/09
This module has been replaced with one that correctly updates the layered navigation counts. See the new version here.
Updated 7/3/09
The in-stock-only module now works properly when multiple websites are in use.
Updated 6/26/09
The in-stock-only module now works with configurable products.
&#160;
Magento has several criteria for determining if an item should be visible in the store, but [...]]]></description>
			<content:encoded><![CDATA[<h3>Updated 7/14/09</h3>
<p>This module has been replaced with one that correctly updates the layered navigation counts. See the <a href="http://colin.mollenhour.com/2009/07/hiding-out-of-stock-items-in-layered-navigation/">new version here</a>.</p>
<h3>Updated 7/3/09</h3>
<p>The in-stock-only module now works properly when multiple websites are in use.</p>
<h3>Updated 6/26/09</h3>
<p>The in-stock-only module now works with configurable products.</p>
<p>&nbsp;</p>
<p>Magento has several criteria for determining if an item should be visible in the store, but one of these is not whether or not the item is <b>in stock</b>. Magento can manage your stock and will set your stock status to &#8220;Out of Stock&#8221; for you, but what if you want these out of stock items to be hidden from the store.. automatically?  Also, in my case I do not want to &#8220;disable&#8221; the item because the inventory management system will then ignore it. Turns out this was much more difficult to figure out than I expected it to be but the end solution was quite simple.</p>
<p><span id="more-56"></span></p>
<p>To hide all out of stock items from Magento&#8217;s storefront we are going to create a local module and call it &#8220;Lucky_InStockOnly&#8221;. This will be a very simple module, so get ready to copy and paste.</p>
<p>Every module needs a config file. Ours is very basic, here it is:</p>
<p><code>app/code/local/Lucky/InStockOnly/etc/config.xml</code></p>
<pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;config&gt;

&lt;global&gt;
  &lt;models&gt;
    &lt;lucky_instockonly&gt;
      &lt;class&gt;Lucky_InStockOnly_Model&lt;/class&gt;
    &lt;/lucky_instockonly&gt;
  &lt;/models&gt;
&lt;/global&gt;

&lt;frontend&gt;
  &lt;events&gt;
    &lt;catalog_block_product_list_collection&gt;
      &lt;observers&gt;
        &lt;lucky_instockonly_list&gt;
          &lt;type&gt;singleton&lt;/type&gt;
          &lt;class&gt;lucky_instockonly/observer&lt;/class&gt;
          &lt;method&gt;addInStockOnlyFilter&lt;/method&gt;
        &lt;/lucky_instockonly_list&gt;
      &lt;/observers&gt;
    &lt;/catalog_block_product_list_collection&gt;
  &lt;/events&gt;
&lt;/frontend&gt;

&lt;/config&gt;</pre>
<p>As you can see, we declare an event for the frontend that observes the &#8220;catalog_block_product_list_collection&#8221; event which is dispatched in <code>Mage_Catalog_Block_Product_List</code> in the <code>_beforeToHtml()</code> method. This _beforeToHtml method is called before the corresponding template code is loaded, and the next line after the dispatchEvent loads the collection at which point it is too late to add any further filters, so we&#8217;re just in time.</p>
<p>Next, we add the observer code:</p>
<p><code>app/code/local/Lucky/InStockOnly/Model/Observer.php</code></p>
<pre class="brush: php;">
&lt;?php

class Lucky_InStockOnly_Model_Observer {

  /**
   * Observes the catalog_block_product_list_collection event
   */
  public function addInStockOnlyFilter($observer){
    $observer-&gt;getEvent()-&gt;getCollection()
      -&gt;joinField('stock_status','cataloginventory/stock_status','stock_status',
        'product_id=entity_id', array(
          'stock_status' =&gt; Mage_CatalogInventory_Model_Stock_Status::STATUS_IN_STOCK,
          'website_id' =&gt; Mage::app()-&gt;getWebsite()-&gt;getWebsiteId(),
        ))
    ;
  }
}
</pre>
<p>That&#8217;s it! That&#8217;s it? Like all things Magento, easy for a veteran, not so easy for anyone else; hence, this blog post. All that is left is to enable our module and we&#8217;re off!</p>
<p><code>app/etc/modules/Lucky_InStockOnly.xml</code></p>
<pre class="brush: xml;">
&lt;config&gt;
  &lt;modules&gt;
    &lt;Lucky_InStockOnly&gt;
      &lt;active&gt;true&lt;/active&gt;
      &lt;codePool&gt;local&lt;/codePool&gt;
    &lt;/Lucky_InStockOnly&gt;
  &lt;/modules&gt;
&lt;/config&gt;
</pre>
<p>Last thing, you need to refresh your configuration cache so Magento will notice the new module. In the admin backend you can do that under System > Cache Management.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://colin.mollenhour.com/2009/06/02/hiding-out-of-stock-items-in-magento/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Implementing Zend Framework&#8217;s &#8220;Conventional Modular&#8221; Directory Structure in Kohana</title>
		<link>http://colin.mollenhour.com/2009/04/19/implementing-zend-frameworks-conventional-modular-directory-structure-in-kohana/</link>
		<comments>http://colin.mollenhour.com/2009/04/19/implementing-zend-frameworks-conventional-modular-directory-structure-in-kohana/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 18:09:30 +0000</pubDate>
		<dc:creator>colin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://colin.mollenhour.com/?p=39</guid>
		<description><![CDATA[There is a little conflict in terms here because &#8220;modules&#8221; are not the same to Kohana as they are to Zend Framework and Yii Framework, which both have support for modular directory structures. In Kohana, modules are like plugins to the framework which can change or add functionality to the core to be made use [...]]]></description>
			<content:encoded><![CDATA[<p>There is a little conflict in terms here because &#8220;modules&#8221; are not the same to Kohana as they are to Zend Framework and Yii Framework, which both have support for modular directory structures. In Kohana, modules are like plugins to the framework which can change or add functionality to the core to be made use of in the application. The <a href="http://framework.zend.com/manual/en/zend.controller.modular.html">&#8220;Conventional Modular&#8221; Directory Structure</a> in Zend Framework is a configuration option, and modules are more like sub-applications; essentially just a neat way to organize various components of an application.
</p>
<p><span id="more-39"></span></p>
<p>While modules in Kohana can (and often do) have their own controllers and views, they sit below the application layer in terms of cascading priority, whereas the modules in Zend Framework sit above the main application layer. That is, if a module is specified in the route, classes will be searched for first in the module directory, and then in the default directory. I really like this directory structure and want to apply it to Kohana. Because of the naming conflict, I am calling these sub-application directories <i>components</i> instead of modules. Here is an example of what I am shooting for:
</p>
<pre>
/application
   /cache
   /config
   /controllers
      /template.php (Template_Controller)
      /welcome.php  (Welcome_Controller)
   /libraries
   /models
   <b>/components</b>
      /admin
         /controllers
            /welcome.php (Welcome_Controller)
            /users.php (Users_Controller)
            /posts.php (Posts_Controller)
         /views
            /template.php (overrides /application/views/template.php)
      /blog
         /controllers
            /posts.php (Posts_Controller)
         /views
            /posts.php (from within blog component: new View('posts'))
      /rest
         ...
      /mobile
         ...
      ...
/modules (Traditional Kohana Modules)
   /auth
   /curl
   ...
/system (Kohana Core)
</pre>
<p>
I use the router to determine the current component, implemented inside my branch of the router3 module. The default value can be set for &#8216;component&#8217; in a route, or the component can be discovered from the uri, or it can fall back to the default component, which by default is the application itself. The default component can also be given a name such as &#8216;default&#8217; in the config file. To avoid conflicts I have an array in my config file to define the components that are enabled and the router will only attempt to match those components via a regex built into the route.
</p>
<p>
Hacking the find_file system is not particularly easy, especially when you enable caching because the component is chosen on-the-fly so the results for (&#8216;controller&#8217;,'welcome&#8217;) will be different from one request to the next. In order to support cascading of all resources in the component directories, the core would have to be hacked. However, I have successfully implemented this as a module which only supports &#8220;controllers&#8221; and &#8220;views&#8221; in the component&#8217;s directory. Caching of find_file paths is not broken, and components that are not active for the current request are not in the cascading order at all which I believe to be preferable. Any controllers and views that should be shared among all components in the application can go in the application directories, all others can be separated into component directories.
</p>
<p>
So what does this accomplish? This let&#8217;s you easily keep components of your application organized in different directories. I currently do not include the component name in the controller class like Zend does, so your controller class and file names and view paths can be kept short. E.g., for the typical blog example:
</p>
<pre>
/application
/controllers
   /welcome.php (Welcome_Controller for blog frontend)
/views
   /template.php (template for blog frontend)
   /posts.php (render frontend view of blog posts)
/components
   /admin (URLs starting with admin will use this component)
      /controllers
         /welcome.php (Welcome_Controller for admin backend)
      /views
         /template.php (template for admin backend)
         /posts.php (render admin view of blog posts)
</pre>
<p>
Aside from the more compartmentalized directory structure, the template name does not have to be changed for the component&#8217;s template to be used, it just works! Also, when instantiating a view, there is no need to specify sub-directories.
</p>
<pre>
// New:
$this->template->content = new View('posts');
// Old:
public $template = 'admin/template';
$this->template->content = new View('admin/posts');
</pre>
<p>
From a code-management standpoint, this could also have some benefits. For example, do you want to revert the admin component back to an older revision but leave all other components alone? Since the admin components files are all contained under one directory, rather than mixed in with every other component this is a simple task.
</p>
<p><i><b>Update:</b></i></p>
<p>The powers that be cannot be convinced that such a directory structure is worthwhile<del datetime="2009-04-21T06:42:06+00:00">, or that <a href="http://dev.kohanaphp.com/ticket/1271">the Kohana class does not have to be &#8220;final&#8221;</a> so I&#8217;ve unfortunately decided to give up and fork Kohana and track it&#8217;s progress.. So much for, as the <a href="http://kohanaphp.com">Kohana homepage</a> puts it, &#8220;Loosely coupled architecture&#8221; and &#8220;Extremely easy to extend&#8221;&#8230;</del>  If anyone is interested in a patch that seamlessly adds this feature, let me know!
</p>
<p><i><b>Update 2 (4/21/09):</b></i></p>
<p>It turns out that the Kohana devs have agreed to make Kohana no longer &#8220;final&#8221; for 2.4, and in fact have moved the Bootstrap.php file into the application directory as well; Icing on the cake! See <a href="http://dev.kohanaphp.com/changeset/4231">r4231</a></p>
]]></content:encoded>
			<wfw:commentRss>http://colin.mollenhour.com/2009/04/19/implementing-zend-frameworks-conventional-modular-directory-structure-in-kohana/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
