Overview

Packages

  • currencysymbol
  • MAbout
  • Mage
    • Admin
    • Adminhtml
    • AdminNotification
    • Api
    • Api2
    • Authorizenet
    • Backup
    • Bundle
    • Captcha
    • Catalog
    • CatalogIndex
    • CatalogInventory
    • CatalogRule
    • CatalogSearch
    • Centinel
    • Checkout
    • Cms
    • Compiler
    • Connect
    • Contacts
    • Core
    • Cron
    • CurrencySymbol
    • Customer
    • Dataflow
    • Directory
    • DirtectPost
    • Downloadable
    • Eav
    • GiftMessage
    • GoogleAnalytics
    • GoogleBase
    • GoogleCheckout
    • ImportExport
    • Index
    • Install
    • Log
    • Media
    • Newsletter
    • Oauth
    • Page
    • PageCache
    • Paygate
    • Payment
    • Paypal
    • PaypalUk
    • Persistent
    • Poll
    • ProductAlert
    • Rating
    • Reports
    • Review
    • Rss
    • Rule
    • Sales
    • SalesRule
    • Sedfriend
    • Sendfriend
    • Shipping
    • Sitemap
    • Tag
    • Tax
    • Usa
    • Weee
    • Widget
    • Wishlist
    • XmlConnect
  • None
  • Phoenix
    • Moneybookers
  • PHP
  • Zend
    • Date
    • Mime
    • XmlRpc

Classes

  • Mage_Catalog_Block_Breadcrumbs
  • Mage_Catalog_Block_Category_View
  • Mage_Catalog_Block_Category_Widget_Link
  • Mage_Catalog_Block_Layer_Filter_Abstract
  • Mage_Catalog_Block_Layer_Filter_Attribute
  • Mage_Catalog_Block_Layer_Filter_Category
  • Mage_Catalog_Block_Layer_Filter_Decimal
  • Mage_Catalog_Block_Layer_Filter_Price
  • Mage_Catalog_Block_Layer_State
  • Mage_Catalog_Block_Layer_View
  • Mage_Catalog_Block_Navigation
  • Mage_Catalog_Block_Product
  • Mage_Catalog_Block_Product_Abstract
  • Mage_Catalog_Block_Product_Compare_Abstract
  • Mage_Catalog_Block_Product_Compare_List
  • Mage_Catalog_Block_Product_Compare_Sidebar
  • Mage_Catalog_Block_Product_Gallery
  • Mage_Catalog_Block_Product_List
  • Mage_Catalog_Block_Product_List_Crosssell
  • Mage_Catalog_Block_Product_List_Promotion
  • Mage_Catalog_Block_Product_List_Random
  • Mage_Catalog_Block_Product_List_Related
  • Mage_Catalog_Block_Product_List_Toolbar
  • Mage_Catalog_Block_Product_List_Upsell
  • Mage_Catalog_Block_Product_New
  • Mage_Catalog_Block_Product_Price
  • Mage_Catalog_Block_Product_Price_Template
  • Mage_Catalog_Block_Product_Send
  • Mage_Catalog_Block_Product_View
  • Mage_Catalog_Block_Product_View_Abstract
  • Mage_Catalog_Block_Product_View_Additional
  • Mage_Catalog_Block_Product_View_Attributes
  • Mage_Catalog_Block_Product_View_Description
  • Mage_Catalog_Block_Product_View_Media
  • Mage_Catalog_Block_Product_View_Options
  • Mage_Catalog_Block_Product_View_Options_Abstract
  • Mage_Catalog_Block_Product_View_Options_Type_Date
  • Mage_Catalog_Block_Product_View_Options_Type_Default
  • Mage_Catalog_Block_Product_View_Options_Type_File
  • Mage_Catalog_Block_Product_View_Options_Type_Select
  • Mage_Catalog_Block_Product_View_Options_Type_Text
  • Mage_Catalog_Block_Product_View_Price
  • Mage_Catalog_Block_Product_View_Tabs
  • Mage_Catalog_Block_Product_View_Type_Configurable
  • Mage_Catalog_Block_Product_View_Type_Grouped
  • Mage_Catalog_Block_Product_View_Type_Simple
  • Mage_Catalog_Block_Product_View_Type_Virtual
  • Mage_Catalog_Block_Product_Widget_Link
  • Mage_Catalog_Block_Product_Widget_New
  • Mage_Catalog_Block_Seo_Sitemap_Abstract
  • Mage_Catalog_Block_Seo_Sitemap_Category
  • Mage_Catalog_Block_Seo_Sitemap_Product
  • Mage_Catalog_Block_Seo_Sitemap_Tree_Category
  • Mage_Catalog_Block_Widget_Link
  • Mage_Catalog_CategoryController
  • Mage_Catalog_Exception
  • Mage_Catalog_Helper_Category
  • Mage_Catalog_Helper_Category_Flat
  • Mage_Catalog_Helper_Data
  • Mage_Catalog_Helper_Image
  • Mage_Catalog_Helper_Map
  • Mage_Catalog_Helper_Output
  • Mage_Catalog_Helper_Product
  • Mage_Catalog_Helper_Product_Compare
  • Mage_Catalog_Helper_Product_Configuration
  • Mage_Catalog_Helper_Product_Flat
  • Mage_Catalog_Helper_Product_Options
  • Mage_Catalog_Helper_Product_Url
  • Mage_Catalog_Helper_Product_View
  • Mage_Catalog_IndexController
  • Mage_Catalog_Model_Abstract
  • Mage_Catalog_Model_Api2_Product
  • Mage_Catalog_Model_Api2_Product_Category
  • Mage_Catalog_Model_Api2_Product_Category_Rest
  • Mage_Catalog_Model_Api2_Product_Category_Rest_Admin_V1
  • Mage_Catalog_Model_Api2_Product_Category_Rest_Customer_V1
  • Mage_Catalog_Model_Api2_Product_Category_Rest_Guest_V1
  • Mage_Catalog_Model_Api2_Product_Image
  • Mage_Catalog_Model_Api2_Product_Image_Rest
  • Mage_Catalog_Model_Api2_Product_Image_Rest_Admin_V1
  • Mage_Catalog_Model_Api2_Product_Image_Rest_Customer_V1
  • Mage_Catalog_Model_Api2_Product_Image_Rest_Guest_V1
  • Mage_Catalog_Model_Api2_Product_Image_Validator_Image
  • Mage_Catalog_Model_Api2_Product_Rest
  • Mage_Catalog_Model_Api2_Product_Rest_Admin_V1
  • Mage_Catalog_Model_Api2_Product_Rest_Customer_V1
  • Mage_Catalog_Model_Api2_Product_Rest_Guest_V1
  • Mage_Catalog_Model_Api2_Product_Validator_Product
  • Mage_Catalog_Model_Api2_Product_Website
  • Mage_Catalog_Model_Api2_Product_Website_Rest
  • Mage_Catalog_Model_Api2_Product_Website_Rest_Admin_V1
  • Mage_Catalog_Model_Api2_Product_Website_Validator_Admin_Website
  • Mage_Catalog_Model_Api_Resource
  • Mage_Catalog_Model_Attribute_Backend_Customlayoutupdate
  • Mage_Catalog_Model_Category
  • Mage_Catalog_Model_Category_Api
  • Mage_Catalog_Model_Category_Api_V2
  • Mage_Catalog_Model_Category_Attribute_Api
  • Mage_Catalog_Model_Category_Attribute_Api_V2
  • Mage_Catalog_Model_Category_Attribute_Backend_Image
  • Mage_Catalog_Model_Category_Attribute_Backend_Sortby
  • Mage_Catalog_Model_Category_Attribute_Backend_Urlkey
  • Mage_Catalog_Model_Category_Attribute_Source_Layout
  • Mage_Catalog_Model_Category_Attribute_Source_Mode
  • Mage_Catalog_Model_Category_Attribute_Source_Page
  • Mage_Catalog_Model_Category_Attribute_Source_Sortby
  • Mage_Catalog_Model_Category_Indexer_Flat
  • Mage_Catalog_Model_Category_Indexer_Product
  • Mage_Catalog_Model_Config
  • Mage_Catalog_Model_Convert
  • Mage_Catalog_Model_Convert_Adapter_Catalog
  • Mage_Catalog_Model_Convert_Adapter_Product
  • Mage_Catalog_Model_Convert_Parser_Product
  • Mage_Catalog_Model_Design
  • Mage_Catalog_Model_Entity_Attribute
  • Mage_Catalog_Model_Entity_Product_Attribute_Frontend_Image
  • Mage_Catalog_Model_Index
  • Mage_Catalog_Model_Indexer_Url
  • Mage_Catalog_Model_Layer
  • Mage_Catalog_Model_Layer_Filter_Abstract
  • Mage_Catalog_Model_Layer_Filter_Attribute
  • Mage_Catalog_Model_Layer_Filter_Category
  • Mage_Catalog_Model_Layer_Filter_Decimal
  • Mage_Catalog_Model_Layer_Filter_Item
  • Mage_Catalog_Model_Layer_Filter_Price
  • Mage_Catalog_Model_Layer_Filter_Price_Algorithm
  • Mage_Catalog_Model_Layer_State
  • Mage_Catalog_Model_Observer
  • Mage_Catalog_Model_Product
  • Mage_Catalog_Model_Product_Action
  • Mage_Catalog_Model_Product_Api
  • Mage_Catalog_Model_Product_Api_V2
  • Mage_Catalog_Model_Product_Attribute_Api
  • Mage_Catalog_Model_Product_Attribute_Api_V2
  • Mage_Catalog_Model_Product_Attribute_Backend_Boolean
  • Mage_Catalog_Model_Product_Attribute_Backend_Groupprice
  • Mage_Catalog_Model_Product_Attribute_Backend_Groupprice_Abstract
  • Mage_Catalog_Model_Product_Attribute_Backend_Media
  • Mage_Catalog_Model_Product_Attribute_Backend_Msrp
  • Mage_Catalog_Model_Product_Attribute_Backend_Price
  • Mage_Catalog_Model_Product_Attribute_Backend_Recurring
  • Mage_Catalog_Model_Product_Attribute_Backend_Sku
  • Mage_Catalog_Model_Product_Attribute_Backend_Startdate
  • Mage_Catalog_Model_Product_Attribute_Backend_Tierprice
  • Mage_Catalog_Model_Product_Attribute_Backend_Urlkey
  • Mage_Catalog_Model_Product_Attribute_Frontend_Image
  • Mage_Catalog_Model_Product_Attribute_Group
  • Mage_Catalog_Model_Product_Attribute_Media_Api
  • Mage_Catalog_Model_Product_Attribute_Media_Api_V2
  • Mage_Catalog_Model_Product_Attribute_Set_Api
  • Mage_Catalog_Model_Product_Attribute_Set_Api_V2
  • Mage_Catalog_Model_Product_Attribute_Source_Boolean
  • Mage_Catalog_Model_Product_Attribute_Source_Countryofmanufacture
  • Mage_Catalog_Model_Product_Attribute_Source_Layout
  • Mage_Catalog_Model_Product_Attribute_Source_Msrp_Type
  • Mage_Catalog_Model_Product_Attribute_Source_Msrp_Type_Enabled
  • Mage_Catalog_Model_Product_Attribute_Source_Msrp_Type_Price
  • Mage_Catalog_Model_Product_Attribute_Tierprice_Api
  • Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2
  • Mage_Catalog_Model_Product_Compare_Item
  • Mage_Catalog_Model_Product_Compare_List
  • Mage_Catalog_Model_Product_Condition
  • Mage_Catalog_Model_Product_Configuration_Item_Option
  • Mage_Catalog_Model_Product_Flat_Flag
  • Mage_Catalog_Model_Product_Flat_Indexer
  • Mage_Catalog_Model_Product_Flat_Observer
  • Mage_Catalog_Model_Product_Image
  • Mage_Catalog_Model_Product_Indexer_Eav
  • Mage_Catalog_Model_Product_Indexer_Flat
  • Mage_Catalog_Model_Product_Indexer_Price
  • Mage_Catalog_Model_Product_Link
  • Mage_Catalog_Model_Product_Link_Api
  • Mage_Catalog_Model_Product_Link_Api_V2
  • Mage_Catalog_Model_Product_Media_Config
  • Mage_Catalog_Model_Product_Option
  • Mage_Catalog_Model_Product_Option_Api
  • Mage_Catalog_Model_Product_Option_Api_V2
  • Mage_Catalog_Model_Product_Option_Observer
  • Mage_Catalog_Model_Product_Option_Type_Date
  • Mage_Catalog_Model_Product_Option_Type_Default
  • Mage_Catalog_Model_Product_Option_Type_File
  • Mage_Catalog_Model_Product_Option_Type_Select
  • Mage_Catalog_Model_Product_Option_Type_Text
  • Mage_Catalog_Model_Product_Option_Value
  • Mage_Catalog_Model_Product_Option_Value_Api
  • Mage_Catalog_Model_Product_Option_Value_Api_V2
  • Mage_Catalog_Model_Product_Status
  • Mage_Catalog_Model_Product_Type
  • Mage_Catalog_Model_Product_Type_Abstract
  • Mage_Catalog_Model_Product_Type_Api
  • Mage_Catalog_Model_Product_Type_Api_V2
  • Mage_Catalog_Model_Product_Type_Configurable
  • Mage_Catalog_Model_Product_Type_Configurable_Attribute
  • Mage_Catalog_Model_Product_Type_Configurable_Price
  • Mage_Catalog_Model_Product_Type_Grouped
  • Mage_Catalog_Model_Product_Type_Grouped_Price
  • Mage_Catalog_Model_Product_Type_Price
  • Mage_Catalog_Model_Product_Type_Simple
  • Mage_Catalog_Model_Product_Type_Virtual
  • Mage_Catalog_Model_Product_Url
  • Mage_Catalog_Model_Product_Visibility
  • Mage_Catalog_Model_Product_Website
  • Mage_Catalog_Model_Resource_Abstract
  • Mage_Catalog_Model_Resource_Attribute
  • Mage_Catalog_Model_Resource_Category
  • Mage_Catalog_Model_Resource_Category_Attribute_Collection
  • Mage_Catalog_Model_Resource_Category_Attribute_Frontend_Image
  • Mage_Catalog_Model_Resource_Category_Attribute_Source_Layout
  • Mage_Catalog_Model_Resource_Category_Attribute_Source_Mode
  • Mage_Catalog_Model_Resource_Category_Attribute_Source_Page
  • Mage_Catalog_Model_Resource_Category_Collection
  • Mage_Catalog_Model_Resource_Category_Flat
  • Mage_Catalog_Model_Resource_Category_Flat_Collection
  • Mage_Catalog_Model_Resource_Category_Indexer_Product
  • Mage_Catalog_Model_Resource_Category_Tree
  • Mage_Catalog_Model_Resource_Collection_Abstract
  • Mage_Catalog_Model_Resource_Config
  • Mage_Catalog_Model_Resource_Eav_Attribute
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Abstract
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Attribute
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Attribute_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Attribute_Frontend_Image
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Attribute_Source_Layout
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Attribute_Source_Mode
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Attribute_Source_Page
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Flat
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Flat_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Indexer_Product
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Tree
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Collection_Abstract
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Config
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Decimal
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Price
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Action
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Backend_Image
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Backend_Media
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Backend_Tierprice
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Backend_Urlkey
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Frontend_Image
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Attribute_Frontend_Tierprice
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Flat
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Flat_Indexer
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Abstract
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Eav
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Eav_Abstract
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Eav_Decimal
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Eav_Source
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Configurable
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Default
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Grouped
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Product_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Option
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Option_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Option_Value
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Option_Value_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Relation
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Status
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Type_Configurable
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Type_Configurable_Attribute
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Type_Configurable_Attribute_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Type_Configurable_Product_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Website
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Sendfriend
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Sendfriend_Collection
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Setup
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Url
  • Mage_Catalog_Model_Resource_Helper_Mysql4
  • Mage_Catalog_Model_Resource_Layer_Filter_Attribute
  • Mage_Catalog_Model_Resource_Layer_Filter_Decimal
  • Mage_Catalog_Model_Resource_Layer_Filter_Price
  • Mage_Catalog_Model_Resource_Product
  • Mage_Catalog_Model_Resource_Product_Action
  • Mage_Catalog_Model_Resource_Product_Attribute_Backend_Groupprice
  • Mage_Catalog_Model_Resource_Product_Attribute_Backend_Groupprice_Abstract
  • Mage_Catalog_Model_Resource_Product_Attribute_Backend_Image
  • Mage_Catalog_Model_Resource_Product_Attribute_Backend_Media
  • Mage_Catalog_Model_Resource_Product_Attribute_Backend_Tierprice
  • Mage_Catalog_Model_Resource_Product_Attribute_Backend_Urlkey
  • Mage_Catalog_Model_Resource_Product_Attribute_Collection
  • Mage_Catalog_Model_Resource_Product_Attribute_Frontend_Image
  • Mage_Catalog_Model_Resource_Product_Attribute_Frontend_Tierprice
  • Mage_Catalog_Model_Resource_Product_Collection
  • Mage_Catalog_Model_Resource_Product_Compare_Item
  • Mage_Catalog_Model_Resource_Product_Compare_Item_Collection
  • Mage_Catalog_Model_Resource_Product_Flat
  • Mage_Catalog_Model_Resource_Product_Flat_Indexer
  • Mage_Catalog_Model_Resource_Product_Indexer_Abstract
  • Mage_Catalog_Model_Resource_Product_Indexer_Eav
  • Mage_Catalog_Model_Resource_Product_Indexer_Eav_Abstract
  • Mage_Catalog_Model_Resource_Product_Indexer_Eav_Decimal
  • Mage_Catalog_Model_Resource_Product_Indexer_Eav_Source
  • Mage_Catalog_Model_Resource_Product_Indexer_Price
  • Mage_Catalog_Model_Resource_Product_Indexer_Price_Configurable
  • Mage_Catalog_Model_Resource_Product_Indexer_Price_Default
  • Mage_Catalog_Model_Resource_Product_Indexer_Price_Grouped
  • Mage_Catalog_Model_Resource_Product_Link
  • Mage_Catalog_Model_Resource_Product_Link_Collection
  • Mage_Catalog_Model_Resource_Product_Link_Product_Collection
  • Mage_Catalog_Model_Resource_Product_Option
  • Mage_Catalog_Model_Resource_Product_Option_Collection
  • Mage_Catalog_Model_Resource_Product_Option_Value
  • Mage_Catalog_Model_Resource_Product_Option_Value_Collection
  • Mage_Catalog_Model_Resource_Product_Relation
  • Mage_Catalog_Model_Resource_Product_Status
  • Mage_Catalog_Model_Resource_Product_Type_Configurable
  • Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute
  • Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection
  • Mage_Catalog_Model_Resource_Product_Type_Configurable_Product_Collection
  • Mage_Catalog_Model_Resource_Product_Website
  • Mage_Catalog_Model_Resource_Setup
  • Mage_Catalog_Model_Resource_Url
  • Mage_Catalog_Model_Session
  • Mage_Catalog_Model_System_Config_Backend_Catalog_Category_Flat
  • Mage_Catalog_Model_System_Config_Backend_Catalog_Product_Flat
  • Mage_Catalog_Model_System_Config_Backend_Catalog_Url_Rewrite_Suffix
  • Mage_Catalog_Model_Template_Filter
  • Mage_Catalog_Model_Url
  • Mage_Catalog_Product_CompareController
  • Mage_Catalog_ProductController
  • Mage_Catalog_Seo_SitemapController
  • Mage_CatalogSearch_Model_Resource_Helper_Mysql4
  • Mage_XmlConnect_Model_Catalog_Category_Media_Config

Interfaces

  • Mage_Catalog_Helper_Product_Configuration_Interface
  • Mage_Catalog_Model_Product_Condition_Interface
  • Mage_Catalog_Model_Product_Configuration_Item_Interface
  • Mage_Catalog_Model_Product_Configuration_Item_Option_Interface
  • Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Indexer_Price_Interface
  • Mage_Catalog_Model_Resource_Product_Indexer_Price_Interface
  • Overview
  • Package
  • Class
  • Tree
   1: <?php
   2: /**
   3:  * Magento
   4:  *
   5:  * NOTICE OF LICENSE
   6:  *
   7:  * This source file is subject to the Open Software License (OSL 3.0)
   8:  * that is bundled with this package in the file LICENSE.txt.
   9:  * It is also available through the world-wide-web at this URL:
  10:  * http://opensource.org/licenses/osl-3.0.php
  11:  * If you did not receive a copy of the license and are unable to
  12:  * obtain it through the world-wide-web, please send an email
  13:  * to license@magentocommerce.com so we can send you a copy immediately.
  14:  *
  15:  * DISCLAIMER
  16:  *
  17:  * Do not edit or add to this file if you wish to upgrade Magento to newer
  18:  * versions in the future. If you wish to customize Magento for your
  19:  * needs please refer to http://www.magentocommerce.com for more information.
  20:  *
  21:  * @category    Mage
  22:  * @package     Mage_Catalog
  23:  * @copyright   Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24:  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  25:  */
  26: 
  27: 
  28: /**
  29:  * Catalog Product Flat Indexer Resource Model
  30:  *
  31:  * @category    Mage
  32:  * @package     Mage_Catalog
  33:  * @author      Magento Core Team <core@magentocommerce.com>
  34:  */
  35: class Mage_Catalog_Model_Resource_Product_Flat_Indexer extends Mage_Index_Model_Resource_Abstract
  36: {
  37:     const XML_NODE_MAX_INDEX_COUNT  = 'global/catalog/product/flat/max_index_count';
  38:     const XML_NODE_ATTRIBUTE_NODES  = 'global/catalog/product/flat/attribute_nodes';
  39: 
  40:     /**
  41:      * Attribute codes for flat
  42:      *
  43:      * @var array
  44:      */
  45:     protected $_attributeCodes;
  46: 
  47:     /**
  48:      * Attribute objects for flat cache
  49:      *
  50:      * @var array
  51:      */
  52:     protected $_attributes;
  53: 
  54:     /**
  55:      * Required system attributes for preload
  56:      *
  57:      * @var array
  58:      */
  59:     protected $_systemAttributes     = array('status', 'required_options', 'tax_class_id', 'weight');
  60: 
  61:     /**
  62:      * Eav Catalog_Product Entity Type Id
  63:      *
  64:      * @var int
  65:      */
  66:     protected $_entityTypeId;
  67: 
  68:     /**
  69:      * Flat table columns cache
  70:      *
  71:      * @var array
  72:      */
  73:     protected $_columns;
  74: 
  75:     /**
  76:      * Flat table indexes cache
  77:      *
  78:      * @var array
  79:      */
  80:     protected $_indexes;
  81: 
  82:     /**
  83:      * Product Type Instances cache
  84:      *
  85:      * @var array
  86:      */
  87:     protected $_productTypes;
  88: 
  89:     /**
  90:      * Exists flat tables cache
  91:      *
  92:      * @var array
  93:      */
  94:     protected $_existsFlatTables     = array();
  95: 
  96:     /**
  97:      * Flat tables which were prepared
  98:      *
  99:      * @var array
 100:      */
 101:     protected $_preparedFlatTables   = array();
 102: 
 103:     /**
 104:      * Initialize connection
 105:      *
 106:      */
 107:     protected function _construct()
 108:     {
 109:         $this->_init('catalog/product', 'entity_id');
 110:     }
 111: 
 112:     /**
 113:      * Rebuild Catalog Product Flat Data
 114:      *
 115:      * @param Mage_Core_Model_Store|int $store
 116:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
 117:      */
 118:     public function rebuild($store = null)
 119:     {
 120:         if ($store === null) {
 121:             foreach (Mage::app()->getStores() as $store) {
 122:                 $this->rebuild($store->getId());
 123:             }
 124:             $flag = $this->getFlatHelper()->getFlag();
 125:             $flag->setIsBuild(true)->save();
 126: 
 127:             return $this;
 128:         }
 129: 
 130:         $storeId = (int)Mage::app()->getStore($store)->getId();
 131: 
 132:         $this->prepareFlatTable($storeId);
 133:         $this->cleanNonWebsiteProducts($storeId);
 134:         $this->updateStaticAttributes($storeId);
 135:         $this->updateEavAttributes($storeId);
 136:         $this->updateEventAttributes($storeId);
 137:         $this->updateRelationProducts($storeId);
 138:         $this->cleanRelationProducts($storeId);
 139: 
 140:         return $this;
 141:     }
 142: 
 143:     /**
 144:      * Retrieve Catalog Product Flat helper
 145:      *
 146:      * @return Mage_Catalog_Helper_Product_Flat
 147:      */
 148:     public function getFlatHelper()
 149:     {
 150:         return Mage::helper('catalog/product_flat');
 151:     }
 152: 
 153:     /**
 154:      * Retrieve attribute codes using for flat
 155:      *
 156:      * @return array
 157:      */
 158:     public function getAttributeCodes()
 159:     {
 160:         if ($this->_attributeCodes === null) {
 161:             $adapter               = $this->_getReadAdapter();
 162:             $this->_attributeCodes = array();
 163: 
 164:             $attributeNodes = Mage::getConfig()
 165:                 ->getNode(self::XML_NODE_ATTRIBUTE_NODES)
 166:                 ->children();
 167:             foreach ($attributeNodes as $node) {
 168:                 $attributes = Mage::getConfig()->getNode((string)$node)->asArray();
 169:                 $attributes = array_keys($attributes);
 170:                 $this->_systemAttributes = array_unique(array_merge($attributes, $this->_systemAttributes));
 171:             }
 172: 
 173:             $bind = array(
 174:                 'backend_type'      => Mage_Eav_Model_Entity_Attribute_Abstract::TYPE_STATIC,
 175:                 'entity_type_id'    => $this->getEntityTypeId()
 176:             );
 177: 
 178:             $select = $adapter->select()
 179:                 ->from(array('main_table' => $this->getTable('eav/attribute')))
 180:                 ->join(
 181:                     array('additional_table' => $this->getTable('catalog/eav_attribute')),
 182:                     'additional_table.attribute_id = main_table.attribute_id'
 183:                 )
 184:                 ->where('main_table.entity_type_id = :entity_type_id');
 185:             $whereCondition = array(
 186:                 'main_table.backend_type = :backend_type',
 187:                 $adapter->quoteInto('additional_table.is_used_for_promo_rules = ?', 1),
 188:                 $adapter->quoteInto('additional_table.used_in_product_listing = ?', 1),
 189:                 $adapter->quoteInto('additional_table.used_for_sort_by = ?', 1),
 190:                 $adapter->quoteInto('main_table.attribute_code IN(?)', $this->_systemAttributes)
 191:             );
 192:             if ($this->getFlatHelper()->isAddFilterableAttributes()) {
 193:                $whereCondition[] = $adapter->quoteInto('additional_table.is_filterable > ?', 0);
 194:             }
 195: 
 196:             $select->where(implode(' OR ', $whereCondition));
 197:             $attributesData = $adapter->fetchAll($select, $bind);
 198:             Mage::getSingleton('eav/config')
 199:                 ->importAttributesData($this->getEntityType(), $attributesData);
 200: 
 201:             foreach ($attributesData as $data) {
 202:                 $this->_attributeCodes[$data['attribute_id']] = $data['attribute_code'];
 203:             }
 204:             unset($attributesData);
 205:         }
 206: 
 207:         return $this->_attributeCodes;
 208:     }
 209: 
 210:     /**
 211:      * Retrieve entity type
 212:      *
 213:      * @return string
 214:      */
 215:     public function getEntityType()
 216:     {
 217:         return Mage_Catalog_Model_Product::ENTITY;
 218:     }
 219: 
 220:     /**
 221:      * Retrieve Catalog Entity Type Id
 222:      *
 223:      * @return int
 224:      */
 225:     public function getEntityTypeId()
 226:     {
 227:         if ($this->_entityTypeId === null) {
 228:             $this->_entityTypeId = Mage::getResourceModel('catalog/config')
 229:                 ->getEntityTypeId();
 230:         }
 231:         return $this->_entityTypeId;
 232:     }
 233: 
 234:     /**
 235:      * Retrieve attribute objects for flat
 236:      *
 237:      * @return array
 238:      */
 239:     public function getAttributes()
 240:     {
 241:         if ($this->_attributes === null) {
 242:             $this->_attributes = array();
 243:             $attributeCodes    = $this->getAttributeCodes();
 244:             $entity = Mage::getSingleton('eav/config')
 245:                 ->getEntityType($this->getEntityType())
 246:                 ->getEntity();
 247: 
 248:             foreach ($attributeCodes as $attributeCode) {
 249:                 $attribute = Mage::getSingleton('eav/config')
 250:                     ->getAttribute($this->getEntityType(), $attributeCode)
 251:                     ->setEntity($entity);
 252:                 try {
 253:                     // check if exists source and backend model.
 254:                     // To prevent exception when some module was disabled
 255:                     $attribute->usesSource() && $attribute->getSource();
 256:                     $attribute->getBackend();
 257:                     $this->_attributes[$attributeCode] = $attribute;
 258:                 } catch (Exception $e) {
 259:                     Mage::logException($e);
 260:                 }
 261:             }
 262:         }
 263: 
 264:         return $this->_attributes;
 265:     }
 266: 
 267:     /**
 268:      * Retrieve loaded attribute by code
 269:      *
 270:      * @param string $attributeCode
 271:      * @throws Mage_Core_Exception
 272:      * @return Mage_Eav_Model_Entity_Attribute
 273:      */
 274:     public function getAttribute($attributeCode)
 275:     {
 276:         $attributes = $this->getAttributes();
 277:         if (!isset($attributes[$attributeCode])) {
 278:             $attribute = Mage::getModel('catalog/resource_eav_attribute')
 279:                 ->loadByCode($this->getEntityTypeId(), $attributeCode);
 280:             if (!$attribute->getId()) {
 281:                 Mage::throwException(Mage::helper('catalog')->__('Invalid attribute %s', $attributeCode));
 282:             }
 283:             $entity = Mage::getSingleton('eav/config')
 284:                 ->getEntityType($this->getEntityType())
 285:                 ->getEntity();
 286:             $attribute->setEntity($entity);
 287: 
 288:             return $attribute;
 289:         }
 290: 
 291:         return $attributes[$attributeCode];
 292:     }
 293: 
 294:     /**
 295:      * Retrieve Catalog Product Flat Table name
 296:      *
 297:      * @param int $storeId
 298:      * @return string
 299:      */
 300:     public function getFlatTableName($storeId)
 301:     {
 302:         return sprintf('%s_%s', $this->getTable('catalog/product_flat'), $storeId);
 303:     }
 304: 
 305:     /**
 306:      * Retrieve catalog product flat columns array in old format (used before MMDB support)
 307:      *
 308:      * @return array
 309:      */
 310:     protected function _getFlatColumnsOldDefinition()
 311:     {
 312:         $columns = array();
 313:         $columns['entity_id'] = array(
 314:             'type'      => 'int(10)',
 315:             'unsigned'  => true,
 316:             'is_null'   => false,
 317:             'default'   => null,
 318:             'extra'     => null
 319:         );
 320:         if ($this->getFlatHelper()->isAddChildData()) {
 321:             $columns['child_id'] = array(
 322:                 'type'      => 'int(10)',
 323:                 'unsigned'  => true,
 324:                 'is_null'   => true,
 325:                 'default'   => null,
 326:                 'extra'     => null
 327:             );
 328:             $columns['is_child'] = array(
 329:                 'type'      => 'tinyint(1)',
 330:                 'unsigned'  => true,
 331:                 'is_null'   => false,
 332:                 'default'   => 0,
 333:                 'extra'     => null
 334:             );
 335:         }
 336:         $columns['attribute_set_id'] = array(
 337:             'type'      => 'smallint(5)',
 338:             'unsigned'  => true,
 339:             'is_null'   => false,
 340:             'default'   => 0,
 341:             'extra'     => null
 342:         );
 343:         $columns['type_id'] = array(
 344:             'type'      => 'varchar(32)',
 345:             'unsigned'  => false,
 346:             'is_null'   => false,
 347:             'default'   => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
 348:             'extra'     => null
 349:         );
 350: 
 351:         return $columns;
 352:     }
 353: 
 354:     /**
 355:      * Retrieve catalog product flat columns array in DDL format
 356:      *
 357:      * @return array
 358:      */
 359:     protected function _getFlatColumnsDdlDefinition()
 360:     {
 361:         $columns = array();
 362:         $columns['entity_id'] = array(
 363:             'type'      => Varien_Db_Ddl_Table::TYPE_INTEGER,
 364:             'length'    => null,
 365:             'unsigned'  => true,
 366:             'nullable'  => false,
 367:             'default'   => false,
 368:             'primary'   => true,
 369:             'comment'   => 'Entity Id'
 370:         );
 371:         if ($this->getFlatHelper()->isAddChildData()) {
 372:             $columns['child_id'] = array(
 373:                 'type'      => Varien_Db_Ddl_Table::TYPE_INTEGER,
 374:                 'length'    => null,
 375:                 'unsigned'  => true,
 376:                 'nullable'  => true,
 377:                 'default'   => null,
 378:                 'primary'   => true,
 379:                 'comment'   => 'Child Id'
 380:             );
 381:             $columns['is_child'] = array(
 382:                 'type'      => Varien_Db_Ddl_Table::TYPE_SMALLINT,
 383:                 'length'    => 1,
 384:                 'unsigned'  => true,
 385:                 'nullable'  => false,
 386:                 'default'   => '0',
 387:                 'comment'   => 'Checks If Entity Is Child'
 388:             );
 389:         }
 390:         $columns['attribute_set_id'] = array(
 391:             'type'      => Varien_Db_Ddl_Table::TYPE_SMALLINT,
 392:             'length'    => 5,
 393:             'unsigned'  => true,
 394:             'nullable'  => false,
 395:             'default'   => '0',
 396:             'comment'   => 'Attribute Set Id'
 397:         );
 398:         $columns['type_id'] = array(
 399:             'type'      => Varien_Db_Ddl_Table::TYPE_TEXT,
 400:             'length'    => 32,
 401:             'unsigned'  => false,
 402:             'nullable'  => false,
 403:             'default'   => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
 404:             'comment'   => 'Type Id'
 405:         );
 406: 
 407:         return $columns;
 408:     }
 409: 
 410:     /**
 411:      * Retrieve catalog product flat table columns array
 412:      *
 413:      * @return array
 414:      */
 415:     public function getFlatColumns()
 416:     {
 417:         if ($this->_columns === null) {
 418:             if (Mage::helper('core')->useDbCompatibleMode()) {
 419:                 $this->_columns = $this->_getFlatColumnsOldDefinition();
 420:             } else {
 421:                 $this->_columns = $this->_getFlatColumnsDdlDefinition();
 422:             }
 423: 
 424:             foreach ($this->getAttributes() as $attribute) {
 425:                 /** @var $attribute Mage_Eav_Model_Entity_Attribute_Abstract */
 426:                 $columns = $attribute
 427:                     ->setFlatAddFilterableAttributes($this->getFlatHelper()->isAddFilterableAttributes())
 428:                     ->setFlatAddChildData($this->getFlatHelper()->isAddChildData())
 429:                     ->getFlatColumns();
 430:                 if ($columns !== null) {
 431:                     $this->_columns = array_merge($this->_columns, $columns);
 432:                 }
 433:             }
 434: 
 435:             $columnsObject = new Varien_Object();
 436:             $columnsObject->setColumns($this->_columns);
 437:             Mage::dispatchEvent('catalog_product_flat_prepare_columns',
 438:                 array('columns' => $columnsObject)
 439:             );
 440:             $this->_columns = $columnsObject->getColumns();
 441:         }
 442: 
 443:         return $this->_columns;
 444:     }
 445: 
 446:     /**
 447:      * Retrieve catalog product flat table indexes array
 448:      *
 449:      * @return array
 450:      */
 451:     public function getFlatIndexes()
 452:     {
 453:         if ($this->_indexes === null) {
 454:             $this->_indexes = array();
 455: 
 456:             if ($this->getFlatHelper()->isAddChildData()) {
 457:                 $this->_indexes['PRIMARY'] = array(
 458:                     'type'   => Varien_Db_Adapter_Interface::INDEX_TYPE_PRIMARY,
 459:                     'fields' => array('entity_id', 'child_id')
 460:                 );
 461:                 $this->_indexes['IDX_CHILD'] = array(
 462:                     'type'   => Varien_Db_Adapter_Interface::INDEX_TYPE_INDEX,
 463:                     'fields' => array('child_id')
 464:                 );
 465:                 $this->_indexes['IDX_IS_CHILD'] = array(
 466:                     'type'   => Varien_Db_Adapter_Interface::INDEX_TYPE_INDEX,
 467:                     'fields' => array('entity_id', 'is_child')
 468:                 );
 469:             } else {
 470:                 $this->_indexes['PRIMARY'] = array(
 471:                     'type'   => Varien_Db_Adapter_Interface::INDEX_TYPE_PRIMARY,
 472:                     'fields' => array('entity_id')
 473:                 );
 474:             }
 475:             $this->_indexes['IDX_TYPE_ID'] = array(
 476:                 'type'   => Varien_Db_Adapter_Interface::INDEX_TYPE_INDEX,
 477:                 'fields' => array('type_id')
 478:             );
 479:             $this->_indexes['IDX_ATTRIBUTE_SET'] = array(
 480:                 'type'   => Varien_Db_Adapter_Interface::INDEX_TYPE_INDEX,
 481:                 'fields' => array('attribute_set_id')
 482:             );
 483: 
 484:             foreach ($this->getAttributes() as $attribute) {
 485:                 /** @var $attribute Mage_Eav_Model_Entity_Attribute */
 486:                 $indexes = $attribute
 487:                     ->setFlatAddFilterableAttributes($this->getFlatHelper()->isAddFilterableAttributes())
 488:                     ->setFlatAddChildData($this->getFlatHelper()->isAddChildData())
 489:                     ->getFlatIndexes();
 490:                 if ($indexes !== null) {
 491:                     $this->_indexes = array_merge($this->_indexes, $indexes);
 492:                 }
 493:             }
 494: 
 495:             $indexesObject = new Varien_Object();
 496:             $indexesObject->setIndexes($this->_indexes);
 497:             Mage::dispatchEvent('catalog_product_flat_prepare_indexes', array(
 498:                 'indexes'   => $indexesObject
 499:             ));
 500:             $this->_indexes = $indexesObject->getIndexes();
 501:         }
 502: 
 503:         return $this->_indexes;
 504:     }
 505: 
 506:     /**
 507:      * Compare Flat style with Describe style columns
 508:      * If column a different - return false
 509:      *
 510:      * @param array $column
 511:      * @param array $describe
 512:      * @return bool
 513:      */
 514:     protected function _compareColumnProperties($column, $describe)
 515:     {
 516:         return Mage::getResourceHelper('catalog')->compareIndexColumnProperties($column, $describe);
 517:     }
 518: 
 519:     /**
 520:      * Retrieve column definition fragment
 521:      * @deprecated since 1.5.0.0
 522:      *
 523:      * Example: `field_name` smallint(5) unsigned NOT NULL default '0'
 524:      *
 525:      * @param string $fieldName
 526:      * @param array $fieldProp
 527:      * @return string
 528:      */
 529:     protected function _sqlColunmDefinition($fieldName, $fieldProp)
 530:     {
 531:         $fieldNameQuote = $this->_getWriteAdapter()->quoteIdentifier($fieldName);
 532: 
 533:         /**
 534:          * Process the case when 'is_null' prohibits null value, and 'default' proposed to be null
 535:          * It just means that default value not specified
 536:          */
 537:         if ($fieldProp['is_null'] === false && $fieldProp['default'] === null) {
 538:             $defaultValue = '';
 539:         } else {
 540:             $defaultValue = $fieldProp['default'] === null ? ' DEFAULT NULL' : $this->_getReadAdapter()
 541:                 ->quoteInto(' DEFAULT ?', $fieldProp['default']);
 542:         }
 543: 
 544:         return "{$fieldNameQuote} {$fieldProp['type']}"
 545:             . ($fieldProp['unsigned'] ? ' UNSIGNED' : '')
 546:             . ($fieldProp['extra'] ? ' ' . $fieldProp['extra'] : '')
 547:             . ($fieldProp['is_null'] === false ? ' NOT NULL' : '')
 548:             . $defaultValue;
 549:     }
 550: 
 551:     /**
 552:      * Retrieve index definition fragment
 553:      * @deprecated since 1.5.0.0
 554:      *
 555:      * Example: INDEX `IDX_NAME` (`field_id`)
 556:      *
 557:      * @param string $indexName
 558:      * @param array $indexProp
 559:      * @return string
 560:      */
 561:     protected function _sqlIndexDefinition($indexName, $indexProp)
 562:     {
 563:         $fields = $indexProp['fields'];
 564:         if (is_array($fields)) {
 565:             $fieldSql = array();
 566:             foreach ($fields as $field) {
 567:                 $fieldSql[] = $this->_getReadAdapter()->quoteIdentifier($field);
 568:             }
 569:             $fieldSql = join(',', $fieldSql);
 570:         }
 571:         else {
 572:             $fieldSql = $this->_getReadAdapter()->quoteIdentifier($fields);
 573:         }
 574: 
 575:         $indexNameQuote = $this->_getReadAdapter()->quoteIdentifier($indexName);
 576:         switch (strtolower($indexProp['type'])) {
 577:             case 'primary':
 578:                 $condition = 'PRIMARY KEY';
 579:                 break;
 580:             case 'unique':
 581:                 $condition = 'UNIQUE ' . $indexNameQuote;
 582:                 break;
 583:             case 'fulltext':
 584:                 $condition = 'FULLTEXT ' . $indexNameQuote;
 585:                 break;
 586:             default:
 587:                 $condition = 'INDEX ' . $indexNameQuote;
 588:                 break;
 589:         }
 590: 
 591:         return sprintf('%s (%s)', $condition, $fieldSql);
 592:     }
 593: 
 594:     /**
 595:      * Retrieve UNIQUE HASH for a Table foreign key
 596:      *
 597:      * @param string $priTableName  the target table name
 598:      * @param string $priColumnName the target table column name
 599:      * @param string $refTableName  the reference table name
 600:      * @param string $refColumnName the reference table column name
 601:      * @return string
 602:      */
 603:     public function getFkName($priTableName, $priColumnName, $refTableName, $refColumnName)
 604:     {
 605:         return Mage::getSingleton('core/resource')
 606:             ->getFkName($priTableName, $priColumnName, $refTableName, $refColumnName);
 607:     }
 608: 
 609:     /**
 610:      * Prepare flat table for store
 611:      *
 612:      * @param int $storeId
 613:      * @throws Mage_Core_Exception
 614:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
 615:      */
 616:     public function prepareFlatTable($storeId)
 617:     {
 618:         if (isset($this->_preparedFlatTables[$storeId])) {
 619:             return $this;
 620:         }
 621:         $adapter   = $this->_getWriteAdapter();
 622:         $tableName = $this->getFlatTableName($storeId);
 623: 
 624:         // Extract columns we need to have in flat table
 625:         $columns = $this->getFlatColumns();
 626:         if (Mage::helper('core')->useDbCompatibleMode()) {
 627:              /* Convert old format of flat columns to new MMDB format that uses DDL types and definitions */
 628:             foreach ($columns as $key => $column) {
 629:                 $columns[$key] = Mage::getResourceHelper('core')->convertOldColumnDefinition($column);
 630:             }
 631:         }
 632: 
 633:         // Extract indexes we need to have in flat table
 634:         $indexesNeed  = $this->getFlatIndexes();
 635: 
 636:         $maxIndex = Mage::getConfig()->getNode(self::XML_NODE_MAX_INDEX_COUNT);
 637:         if (count($indexesNeed) > $maxIndex) {
 638:             Mage::throwException(Mage::helper('catalog')->__("The Flat Catalog module has a limit of %2\$d filterable and/or sortable attributes. Currently there are %1\$d of them. Please reduce the number of filterable/sortable attributes in order to use this module", count($indexesNeed), $maxIndex));
 639:         }
 640: 
 641:         // Process indexes to create names for them in MMDB-style and reformat to common index definition
 642:         $indexKeys = array();
 643:         $indexProps = array_values($indexesNeed);
 644:         $upperPrimaryKey = strtoupper(Varien_Db_Adapter_Interface::INDEX_TYPE_PRIMARY);
 645:         foreach ($indexProps as $i => $indexProp) {
 646:             $indexName = $adapter->getIndexName($tableName, $indexProp['fields'], $indexProp['type']);
 647:             $indexProp['type'] = strtoupper($indexProp['type']);
 648:             if ($indexProp['type'] == $upperPrimaryKey) {
 649:                 $indexKey = $upperPrimaryKey;
 650:             } else {
 651:                 $indexKey = $indexName;
 652:             }
 653: 
 654:             $indexProps[$i] = array(
 655:                 'KEY_NAME' => $indexName,
 656:                 'COLUMNS_LIST' => $indexProp['fields'],
 657:                 'INDEX_TYPE' => strtolower($indexProp['type'])
 658:             );
 659:             $indexKeys[$i] = $indexKey;
 660:         }
 661:         $indexesNeed = array_combine($indexKeys, $indexProps); // Array with index names as keys, except for primary
 662: 
 663:         // Foreign keys
 664:         $foreignEntityKey = $this->getFkName($tableName, 'entity_id', 'catalog/product', 'entity_id');
 665:         $foreignChildKey  = $this->getFkName($tableName, 'child_id', 'catalog/product', 'entity_id');
 666: 
 667:         // Create table or modify existing one
 668:         if (!$this->_isFlatTableExists($storeId)) {
 669:             /** @var $table Varien_Db_Ddl_Table */
 670:             $table = $adapter->newTable($tableName);
 671:             foreach ($columns as $fieldName => $fieldProp) {
 672:                 $table->addColumn(
 673:                     $fieldName,
 674:                     $fieldProp['type'],
 675:                     isset($fieldProp['length']) ? $fieldProp['length'] : null,
 676:                     array(
 677:                         'nullable' => isset($fieldProp['nullable']) ? (bool)$fieldProp['nullable'] : false,
 678:                         'unsigned' => isset($fieldProp['unsigned']) ? (bool)$fieldProp['unsigned'] : false,
 679:                         'default'  => isset($fieldProp['default']) ? $fieldProp['default'] : false,
 680:                         'primary'  => false,
 681:                     ),
 682:                     isset($fieldProp['comment']) ? $fieldProp['comment'] : $fieldName
 683:                 );
 684:             }
 685: 
 686:             foreach ($indexesNeed as $indexProp) {
 687:                 $table->addIndex($indexProp['KEY_NAME'], $indexProp['COLUMNS_LIST'],
 688:                     array('type' => $indexProp['INDEX_TYPE']));
 689:             }
 690: 
 691:             $table->addForeignKey($foreignEntityKey,
 692:                 'entity_id', $this->getTable('catalog/product'), 'entity_id',
 693:                 Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE);
 694: 
 695:             if ($this->getFlatHelper()->isAddChildData()) {
 696:                 $table->addForeignKey($foreignChildKey,
 697:                     'child_id', $this->getTable('catalog/product'), 'entity_id',
 698:                     Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE);
 699:             }
 700:             $table->setComment("Catalog Product Flat (Store {$storeId})");
 701: 
 702:             $adapter->createTable($table);
 703: 
 704:             $this->_existsFlatTables[$storeId] = true;
 705:         } else {
 706:             $adapter->resetDdlCache($tableName);
 707: 
 708:             // Sort columns into added/altered/dropped lists
 709:             $describe   = $adapter->describeTable($tableName);
 710:             $addColumns     = array_diff_key($columns, $describe);
 711:             $dropColumns    = array_diff_key($describe, $columns);
 712:             $modifyColumns  = array();
 713:             foreach ($columns as $field => $fieldProp) {
 714:                 if (isset($describe[$field]) && !$this->_compareColumnProperties($fieldProp, $describe[$field])) {
 715:                     $modifyColumns[$field] = $fieldProp;
 716:                 }
 717:             }
 718: 
 719:             // Sort indexes into added/dropped lists. Altered indexes are put into both lists.
 720:             $addIndexes = array();
 721:             $dropIndexes = array();
 722:             $indexesNow  = $adapter->getIndexList($tableName); // Note: primary is always stored under 'PRIMARY' key
 723:             $newIndexes = $indexesNeed;
 724:             foreach ($indexesNow as $key => $indexNow) {
 725:                 if (isset($indexesNeed[$key])) {
 726:                     $indexNeed = $indexesNeed[$key];
 727:                     if (($indexNeed['INDEX_TYPE'] != $indexNow['INDEX_TYPE'])
 728:                         || ($indexNeed['COLUMNS_LIST'] != $indexNow['COLUMNS_LIST'])) {
 729:                         $dropIndexes[$key] = $indexNow;
 730:                         $addIndexes[$key] = $indexNeed;
 731:                     }
 732:                     unset($newIndexes[$key]);
 733:                 } else {
 734:                     $dropIndexes[$key] = $indexNow;
 735:                 }
 736:             }
 737:             $addIndexes = $addIndexes + $newIndexes;
 738: 
 739:             // Compose contstraints
 740:             $addConstraints = array();
 741:             $addConstraints[$foreignEntityKey] = array(
 742:                 'table_index'   => 'entity_id',
 743:                 'ref_table'     => $this->getTable('catalog/product'),
 744:                 'ref_index'     => 'entity_id',
 745:                 'on_update'     => Varien_Db_Ddl_Table::ACTION_CASCADE,
 746:                 'on_delete'     => Varien_Db_Ddl_Table::ACTION_CASCADE
 747:             );
 748: 
 749:             // Additional data from childs
 750:             $isAddChildData = $this->getFlatHelper()->isAddChildData();
 751:             if (!$isAddChildData && isset($describe['is_child'])) {
 752:                 $adapter->delete($tableName, array('is_child = ?' => 1));
 753:                 $adapter->dropForeignKey($tableName, $foreignChildKey);
 754:             }
 755:             if ($isAddChildData && !isset($describe['is_child'])) {
 756:                 $adapter->delete($tableName);
 757:                 $dropIndexes['PRIMARY'] = $indexesNow['PRIMARY'];
 758:                 $addIndexes['PRIMARY']  = $indexesNeed['PRIMARY'];
 759: 
 760:                 $addConstraints[$foreignChildKey] = array(
 761:                     'table_index'   => 'child_id',
 762:                     'ref_table'     => $this->getTable('catalog/product'),
 763:                     'ref_index'     => 'entity_id',
 764:                     'on_update'     => Varien_Db_Ddl_Table::ACTION_CASCADE,
 765:                     'on_delete'     => Varien_Db_Ddl_Table::ACTION_CASCADE
 766:                 );
 767:             }
 768: 
 769:             // Drop constraints
 770:             foreach (array_keys($adapter->getForeignKeys($tableName)) as $constraintName) {
 771:                 $adapter->dropForeignKey($tableName, $constraintName);
 772:             }
 773: 
 774:             // Drop indexes
 775:             foreach ($dropIndexes as $indexProp) {
 776:                 $adapter->dropIndex($tableName, $indexProp['KEY_NAME']);
 777:             }
 778: 
 779:             // Drop columns
 780:             foreach (array_keys($dropColumns) as $columnName) {
 781:                 $adapter->dropColumn($tableName, $columnName);
 782:             }
 783: 
 784:             // Modify columns
 785:             foreach ($modifyColumns as $columnName => $columnProp) {
 786:                 $columnProp = array_change_key_case($columnProp, CASE_UPPER);
 787:                 if (!isset($columnProp['COMMENT'])) {
 788:                     $columnProp['COMMENT'] = ucwords(str_replace('_', ' ', $columnName));
 789:                 }
 790:                 $adapter->changeColumn($tableName, $columnName, $columnName, $columnProp);
 791:             }
 792: 
 793:             // Add columns
 794:             foreach ($addColumns as $columnName => $columnProp) {
 795:                 $columnProp = array_change_key_case($columnProp, CASE_UPPER);
 796:                 if (!isset($columnProp['COMMENT'])) {
 797:                     $columnProp['COMMENT'] = ucwords(str_replace('_', ' ', $columnName));
 798:                 }
 799:                 $adapter->addColumn($tableName, $columnName, $columnProp);
 800:             }
 801: 
 802:             // Add indexes
 803:             foreach ($addIndexes as $indexProp) {
 804:                 $adapter->addIndex($tableName, $indexProp['KEY_NAME'], $indexProp['COLUMNS_LIST'],
 805:                     $indexProp['INDEX_TYPE']);
 806:             }
 807: 
 808:             // Add constraints
 809:             foreach ($addConstraints as $constraintName => $constraintProp) {
 810:                 $adapter->addForeignKey($constraintName, $tableName,
 811:                     $constraintProp['table_index'],
 812:                     $constraintProp['ref_table'],
 813:                     $constraintProp['ref_index'],
 814:                     $constraintProp['on_delete'],
 815:                     $constraintProp['on_update']
 816:                 );
 817:             }
 818:         }
 819: 
 820:         $this->_preparedFlatTables[$storeId] = true;
 821: 
 822:         return $this;
 823:     }
 824: 
 825:     /**
 826:      * Add or Update static attributes
 827:      *
 828:      * @param int $storeId
 829:      * @param int|array $productIds update only product(s)
 830:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
 831:      */
 832:     public function updateStaticAttributes($storeId, $productIds = null)
 833:     {
 834:         if (!$this->_isFlatTableExists($storeId)) {
 835:             return $this;
 836:         }
 837:         $adapter   = $this->_getWriteAdapter();
 838:         $websiteId = (int)Mage::app()->getStore($storeId)->getWebsite()->getId();
 839:         /* @var $status Mage_Eav_Model_Entity_Attribute */
 840:         $status    = $this->getAttribute('status');
 841: 
 842:         $fieldList  = array('entity_id', 'type_id', 'attribute_set_id');
 843:         $colsList   = array('entity_id', 'type_id', 'attribute_set_id');
 844:         if ($this->getFlatHelper()->isAddChildData()) {
 845:             $fieldList = array_merge($fieldList, array('child_id', 'is_child'));
 846:             $isChild   = new Zend_Db_Expr('0');
 847:             $colsList  = array_merge($colsList, array('entity_id', $isChild));
 848:         }
 849: 
 850:         $columns    = $this->getFlatColumns();
 851:         $bind       = array(
 852:             'website_id'     => $websiteId,
 853:             'store_id'       => $storeId,
 854:             'entity_type_id' => (int)$status->getEntityTypeId(),
 855:             'attribute_id'   => (int)$status->getId()
 856:         );
 857: 
 858:         $fieldExpr = $adapter->getCheckSql('t2.value_id > 0', 't2.value', 't1.value');
 859:         $select     = $this->_getWriteAdapter()->select()
 860:             ->from(array('e' => $this->getTable('catalog/product')), $colsList)
 861:             ->join(
 862:                 array('wp' => $this->getTable('catalog/product_website')),
 863:                 'e.entity_id = wp.product_id AND wp.website_id = :website_id',
 864:                 array())
 865:             ->joinLeft(
 866:                 array('t1' => $status->getBackend()->getTable()),
 867:                 'e.entity_id = t1.entity_id',
 868:                 array())
 869:             ->joinLeft(
 870:                 array('t2' => $status->getBackend()->getTable()),
 871:                 't2.entity_id = t1.entity_id'
 872:                     . ' AND t1.entity_type_id = t2.entity_type_id'
 873:                     . ' AND t1.attribute_id = t2.attribute_id'
 874:                     . ' AND t2.store_id = :store_id',
 875:                 array())
 876:             ->where('t1.entity_type_id = :entity_type_id')
 877:             ->where('t1.attribute_id = :attribute_id')
 878:             ->where('t1.store_id = ?', Mage_Core_Model_App::ADMIN_STORE_ID)
 879:             ->where("{$fieldExpr} = ?", Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
 880:         foreach ($this->getAttributes() as $attributeCode => $attribute) {
 881:             /** @var $attribute Mage_Eav_Model_Entity_Attribute */
 882:             if ($attribute->getBackend()->getType() == 'static') {
 883:                 if (!isset($columns[$attributeCode])) {
 884:                     continue;
 885:                 }
 886:                 $fieldList[] = $attributeCode;
 887:                 $select->columns($attributeCode, 'e');
 888:             }
 889:         }
 890: 
 891:         if ($productIds !== null) {
 892:             $select->where('e.entity_id IN(?)', $productIds);
 893:         }
 894: 
 895:         $sql = $select->insertFromSelect($this->getFlatTableName($storeId), $fieldList);
 896:         $adapter->query($sql, $bind);
 897: 
 898:         return $this;
 899:     }
 900: 
 901:     /**
 902:      * Remove non website products
 903:      *
 904:      * @param int $storeId
 905:      * @param int|array $productIds
 906:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
 907:      */
 908:     public function cleanNonWebsiteProducts($storeId, $productIds = null)
 909:     {
 910:         if (!$this->_isFlatTableExists($storeId)) {
 911:             return $this;
 912:         }
 913: 
 914:         $websiteId = (int)Mage::app()->getStore($storeId)->getWebsite()->getId();
 915:         $adapter   = $this->_getWriteAdapter();
 916: 
 917:         $joinCondition = array(
 918:             'e.entity_id = wp.product_id',
 919:             'wp.website_id = :website_id'
 920:         );
 921:         if ($this->getFlatHelper()->isAddChildData()) {
 922:             $joinCondition[] = 'e.child_id = wp.product_id';
 923:         }
 924:         $bind   = array('website_id'    => $websiteId);
 925:         $select = $adapter->select()
 926:             ->from(array('e' => $this->getFlatTableName($storeId)), null)
 927:             ->joinLeft(
 928:                 array('wp' => $this->getTable('catalog/product_website')),
 929:                 implode(' AND ', $joinCondition),
 930:                 array());
 931:         if ($productIds !== null) {
 932:             $condition = array(
 933:                 $adapter->quoteInto('e.entity_id IN(?)', $productIds)
 934:             );
 935:             if ($this->getFlatHelper()->isAddChildData()) {
 936:                 $condition[] = $adapter->quoteInto('e.child_id IN(?)', $productIds);
 937:             }
 938:             $select->where(implode(' OR ', $condition));
 939:         }
 940: 
 941:         $sql = $select->deleteFromSelect('e');
 942:         $adapter->query($sql, $bind);
 943: 
 944:         return $this;
 945:     }
 946: 
 947:     /**
 948:      * Update attribute flat data
 949:      *
 950:      * @param Mage_Eav_Model_Entity_Attribute $attribute
 951:      * @param int $storeId
 952:      * @param int|array $productIds update only product(s)
 953:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
 954:      */
 955:     public function updateAttribute($attribute, $storeId, $productIds = null)
 956:     {
 957:         if (!$this->_isFlatTableExists($storeId)) {
 958:             return $this;
 959:         }
 960:         $adapter       = $this->_getWriteAdapter();
 961:         $flatTableName = $this->getFlatTableName($storeId);
 962:         $describe      = $adapter->describeTable($flatTableName);
 963: 
 964:         if ($attribute->getBackend()->getType() == 'static') {
 965:             if (!isset($describe[$attribute->getAttributeCode()])) {
 966:                 return $this;
 967:             }
 968: 
 969:             $select = $adapter->select()
 970:                 ->join(
 971:                     array('main_table' => $this->getTable('catalog/product')),
 972:                     'main_table.entity_id = e.entity_id',
 973:                     array($attribute->getAttributeCode() => 'main_table.' . $attribute->getAttributeCode())
 974:                 );
 975:             if ($this->getFlatHelper()->isAddChildData()) {
 976:                 $select->where('e.is_child = ?', 0);
 977:             }
 978:             if ($productIds !== null) {
 979:                 $select->where('main_table.entity_id IN(?)', $productIds);
 980:             }
 981: 
 982:             $sql = $select->crossUpdateFromSelect(array('e' => $flatTableName));
 983:             $adapter->query($sql);
 984:         } else {
 985:             $columns = $attribute->getFlatColumns();
 986:             if (!$columns) {
 987:                 return $this;
 988:             }
 989:             foreach (array_keys($columns) as $columnName) {
 990:                 if (!isset($describe[$columnName])) {
 991:                     return $this;
 992:                 }
 993:             }
 994: 
 995:             $select = $attribute->getFlatUpdateSelect($storeId);
 996:             if ($select instanceof Varien_Db_Select) {
 997:                 if ($productIds !== null) {
 998:                     $select->where('e.entity_id IN(?)', $productIds);
 999:                 }
1000: 
1001:                 $sql = $select->crossUpdateFromSelect(array('e' => $flatTableName));
1002:                 $adapter->query($sql);
1003:             }
1004:         }
1005: 
1006:         return $this;
1007:     }
1008: 
1009:     /**
1010:      * Update non static EAV attributes flat data
1011:      *
1012:      * @param int $storeId
1013:      * @param int|array $productIds update only product(s)
1014:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1015:      */
1016:     public function updateEavAttributes($storeId, $productIds = null)
1017:     {
1018:         if (!$this->_isFlatTableExists($storeId)) {
1019:             return $this;
1020:         }
1021: 
1022:         foreach ($this->getAttributes() as $attribute) {
1023:             /* @var $attribute Mage_Eav_Model_Entity_Attribute */
1024:             if ($attribute->getBackend()->getType() != 'static') {
1025:                 $this->updateAttribute($attribute, $storeId, $productIds);
1026:             }
1027:         }
1028:         return $this;
1029:     }
1030: 
1031:     /**
1032:      * Update events observer attributes
1033:      *
1034:      * @param int $storeId
1035:      */
1036:     public function updateEventAttributes($storeId = null)
1037:     {
1038:         Mage::dispatchEvent('catalog_product_flat_rebuild', array(
1039:             'store_id' => $storeId,
1040:             'table'    => $this->getFlatTableName($storeId)
1041:         ));
1042:     }
1043: 
1044:     /**
1045:      * Retrieve Product Type Instances
1046:      * as key - type code, value - instance model
1047:      *
1048:      * @return array
1049:      */
1050:     public function getProductTypeInstances()
1051:     {
1052:         if ($this->_productTypes === null) {
1053:             $this->_productTypes = array();
1054:             $productEmulator     = new Varien_Object();
1055: 
1056:             foreach (array_keys(Mage_Catalog_Model_Product_Type::getTypes()) as $typeId) {
1057:                 $productEmulator->setTypeId($typeId);
1058:                 $this->_productTypes[$typeId] = Mage::getSingleton('catalog/product_type')
1059:                     ->factory($productEmulator);
1060:             }
1061:         }
1062:         return $this->_productTypes;
1063:     }
1064: 
1065:     /**
1066:      * Update relation products
1067:      *
1068:      * @param int $storeId
1069:      * @param int|array $productIds Update child product(s) only
1070:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1071:      */
1072:     public function updateRelationProducts($storeId, $productIds = null)
1073:     {
1074:         if (!$this->getFlatHelper()->isAddChildData() || !$this->_isFlatTableExists($storeId)) {
1075:             return $this;
1076:         }
1077: 
1078:         $adapter = $this->_getWriteAdapter();
1079: 
1080:         foreach ($this->getProductTypeInstances() as $typeInstance) {
1081:             if (!$typeInstance->isComposite()) {
1082:                 continue;
1083:             }
1084:             $relation = $typeInstance->getRelationInfo();
1085:             if ($relation
1086:                 && $relation->getTable()
1087:                 && $relation->getParentFieldName()
1088:                 && $relation->getChildFieldName()
1089:             ) {
1090:                 $columns    = $this->getFlatColumns();
1091:                 $fieldList  = array_keys($columns);
1092:                 unset($columns['entity_id']);
1093:                 unset($columns['child_id']);
1094:                 unset($columns['is_child']);
1095: 
1096:                 $select = $adapter->select()
1097:                     ->from(
1098:                         array('t' => $this->getTable($relation->getTable())),
1099:                         array($relation->getParentFieldName(), $relation->getChildFieldName(), new Zend_Db_Expr('1')))
1100:                     ->join(
1101:                         array('e' => $this->getFlatTableName($storeId)),
1102:                         "e.entity_id = t.{$relation->getChildFieldName()}",
1103:                         array_keys($columns)
1104:                     );
1105:                 if ($relation->getWhere() !== null) {
1106:                     $select->where($relation->getWhere());
1107:                 }
1108:                 if ($productIds !== null) {
1109:                     $cond = array(
1110:                         $adapter->quoteInto("{$relation->getChildFieldName()} IN(?)", $productIds),
1111:                         $adapter->quoteInto("{$relation->getParentFieldName()} IN(?)", $productIds)
1112:                     );
1113: 
1114:                     $select->where(implode(' OR ', $cond));
1115:                 }
1116:                 $sql = $select->insertFromSelect($this->getFlatTableName($storeId), $fieldList);
1117:                 $adapter->query($sql);
1118:             }
1119:         }
1120: 
1121:         return $this;
1122:     }
1123: 
1124:     /**
1125:      * Update children data from parent
1126:      *
1127:      * @param int $storeId
1128:      * @param int|array $productIds
1129:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1130:      */
1131:     public function updateChildrenDataFromParent($storeId, $productIds = null)
1132:     {
1133:         if (!$this->getFlatHelper()->isAddChildData() || !$this->_isFlatTableExists($storeId)) {
1134:             return $this;
1135:         }
1136:         $adapter = $this->_getWriteAdapter();
1137: 
1138:         $select = $adapter->select();
1139:         foreach (array_keys($this->getFlatColumns()) as $columnName) {
1140:             if ($columnName == 'entity_id' || $columnName == 'child_id' || $columnName == 'is_child') {
1141:                 continue;
1142:             }
1143:             $select->columns(array($columnName => new Zend_Db_Expr('t1.' . $columnName)));
1144:         }
1145:         $select
1146:             ->joinLeft(
1147:                 array('t1' => $this->getFlatTableName($storeId)),
1148:                 $adapter->quoteInto('t2.child_id = t1.entity_id AND t1.is_child = ?', 0),
1149:                 array())
1150:             ->where('t2.is_child = ?', 1);
1151: 
1152:         if ($productIds !== null) {
1153:             $select->where('t2.child_id IN(?)', $productIds);
1154:         }
1155: 
1156:         $sql = $select->crossUpdateFromSelect(array('t2' => $this->getFlatTableName($storeId)));
1157:         $adapter->query($sql);
1158: 
1159:         return $this;
1160:     }
1161: 
1162:     /**
1163:      * Clean unused relation products
1164:      *
1165:      * @param int $storeId
1166:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1167:      */
1168:     public function cleanRelationProducts($storeId)
1169:     {
1170:         if (!$this->getFlatHelper()->isAddChildData()) {
1171:             return $this;
1172:         }
1173: 
1174:         foreach ($this->getProductTypeInstances() as $typeInstance) {
1175:             if (!$typeInstance->isComposite()) {
1176:                 continue;
1177:             }
1178:             $adapter  = $this->_getWriteAdapter();
1179:             $relation = $typeInstance->getRelationInfo();
1180:             if ($relation
1181:                 && $relation->getTable()
1182:                 && $relation->getParentFieldName()
1183:                 && $relation->getChildFieldName()
1184:             ) {
1185:                 $select = $this->_getWriteAdapter()->select()
1186:                     ->distinct(true)
1187:                     ->from(
1188:                         $this->getTable($relation->getTable()),
1189:                         "{$relation->getParentFieldName()}"
1190:                     );
1191:                 $joinLeftCond = array(
1192:                     "e.entity_id = t.{$relation->getParentFieldName()}",
1193:                     "e.child_id = t.{$relation->getChildFieldName()}"
1194:                 );
1195:                 if ($relation->getWhere() !== null) {
1196:                     $select->where($relation->getWhere());
1197:                     $joinLeftCond[] = $relation->getWhere();
1198:                 }
1199: 
1200:                 $entitySelect = new Zend_Db_Expr($select->__toString());
1201: 
1202:                 $select = $adapter->select()
1203:                     ->from(array('e' => $this->getFlatTableName($storeId)), null)
1204:                     ->joinLeft(
1205:                         array('t' => $this->getTable($relation->getTable())),
1206:                         implode(' AND ', $joinLeftCond),
1207:                         array())
1208:                     ->where('e.is_child = ?', 1)
1209:                     ->where('e.entity_id IN(?)', $entitySelect)
1210:                     ->where("t.{$relation->getChildFieldName()} IS NULL");
1211: 
1212:                 $sql = $select->deleteFromSelect('e');
1213:                 $adapter->query($sql);
1214:             }
1215:         }
1216: 
1217:         return $this;
1218:     }
1219: 
1220:     /**
1221:      * Remove product data from flat
1222:      *
1223:      * @param int|array $productIds
1224:      * @param int $storeId
1225:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1226:      */
1227:     public function removeProduct($productIds, $storeId)
1228:     {
1229:         if (!$this->_isFlatTableExists($storeId)) {
1230:             return $this;
1231:         }
1232:         $adapter = $this->_getWriteAdapter();
1233:         $cond = array(
1234:             $adapter->quoteInto('entity_id IN(?)', $productIds)
1235:         );
1236:         if ($this->getFlatHelper()->isAddChildData()) {
1237:             $cond[] = $adapter->quoteInto('child_id IN(?)', $productIds);
1238:         }
1239:         $cond = implode(' OR ', $cond);
1240:         $adapter->delete($this->getFlatTableName($storeId), $cond);
1241: 
1242:         return $this;
1243:     }
1244: 
1245:     /**
1246:      * Remove children from parent product
1247:      *
1248:      * @param int|array $productIds
1249:      * @param int $storeId
1250:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1251:      */
1252:     public function removeProductChildren($productIds, $storeId)
1253:     {
1254:         if (!$this->getFlatHelper()->isAddChildData()) {
1255:             return $this;
1256:         }
1257:         $whereExpr = array(
1258:             'entity_id IN(?)' => $productIds,
1259:             'is_child = ?'    => 1
1260:         );
1261:         $this->_getWriteAdapter()->delete($this->getFlatTableName($storeId), $whereExpr);
1262: 
1263:         return $this;
1264:     }
1265: 
1266:     /**
1267:      * Update flat data for product
1268:      *
1269:      * @param int|array $productIds
1270:      * @param int $storeId
1271:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1272:      */
1273:     public function updateProduct($productIds, $storeId)
1274:     {
1275:         if (!$this->_isFlatTableExists($storeId)) {
1276:             return $this;
1277:         }
1278: 
1279:         $this->saveProduct($productIds, $storeId);
1280: 
1281:         Mage::dispatchEvent('catalog_product_flat_update_product', array(
1282:             'store_id'      => $storeId,
1283:             'table'         => $this->getFlatTableName($storeId),
1284:             'product_ids'   => $productIds
1285:         ));
1286: 
1287:         return $this;
1288:     }
1289: 
1290:     /**
1291:      * Save product(s) data for store
1292:      *
1293:      * @param int|array $productIds
1294:      * @param int $storeId
1295:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1296:      */
1297:     public function saveProduct($productIds, $storeId)
1298:     {
1299:         if (!$this->_isFlatTableExists($storeId)) {
1300:             return $this;
1301:         }
1302: 
1303:         $this->updateStaticAttributes($storeId, $productIds);
1304:         $this->updateEavAttributes($storeId, $productIds);
1305: 
1306:         return $this;
1307:     }
1308: 
1309:     /**
1310:      * Delete flat table process
1311:      *
1312:      * @param int $storeId
1313:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1314:      */
1315:     public function deleteFlatTable($storeId)
1316:     {
1317:         if ($this->_isFlatTableExists($storeId)) {
1318:             $this->_getWriteAdapter()->dropTable($this->getFlatTableName($storeId));
1319:         }
1320: 
1321:         return $this;
1322:     }
1323: 
1324:     /**
1325:      * Check is flat table for store exists
1326:      *
1327:      * @param int $storeId
1328:      * @return bool
1329:      */
1330:     protected function _isFlatTableExists($storeId)
1331:     {
1332:         if (!isset($this->_existsFlatTables[$storeId])) {
1333:             $tableName     = $this->getFlatTableName($storeId);
1334:             $isTableExists = $this->_getWriteAdapter()->isTableExists($tableName);
1335: 
1336:             $this->_existsFlatTables[$storeId] = $isTableExists ? true : false;
1337:         }
1338: 
1339:         return $this->_existsFlatTables[$storeId];
1340:     }
1341: 
1342:     /**
1343:      * Retrieve previous key from array by key
1344:      *
1345:      * @param array $array
1346:      * @param mixed $key
1347:      * @return mixed
1348:      */
1349:     protected function _arrayPrevKey(array $array, $key)
1350:     {
1351:         $prev = false;
1352:         foreach (array_keys($array) as $k) {
1353:             if ($k == $key) {
1354:                 return $prev;
1355:             }
1356:             $prev = $k;
1357:         }
1358:         return false;
1359:     }
1360: 
1361:     /**
1362:      * Retrieve next key from array by key
1363:      *
1364:      * @param array $array
1365:      * @param mixed $key
1366:      * @return mixed
1367:      */
1368:     protected function _arrayNextKey(array $array, $key)
1369:     {
1370:         $next = false;
1371:         foreach (array_keys($array) as $k) {
1372:             if ($next === true) {
1373:                 return $k;
1374:             }
1375:             if ($k == $key) {
1376:                 $next = true;
1377:             }
1378:         }
1379:         return false;
1380:     }
1381: 
1382:     /**
1383:      * Transactional rebuild Catalog Product Flat Data
1384:      *
1385:      * @return Mage_Catalog_Model_Resource_Product_Flat_Indexer
1386:      */
1387:     public function reindexAll()
1388:     {
1389:         foreach (Mage::app()->getStores() as $storeId => $store) {
1390:             $this->prepareFlatTable($storeId);
1391:             $this->beginTransaction();
1392:             try {
1393:                 $this->rebuild($store);
1394:                 $this->commit();
1395:            } catch (Exception $e) {
1396:                 $this->rollBack();
1397:                 throw $e;
1398:            }
1399:         }
1400:         $flag = $this->getFlatHelper()->getFlag();
1401:         $flag->setIsBuild(true)->save();
1402: 
1403:         return $this;
1404:     }
1405: }
1406: 
Magento 1.7.0.2 API documentation generated by ApiGen 2.8.0