すべての特別価格製品を表示するカテゴリの作成ページ


12

基本的に、「販売中の製品」というカテゴリを作成しました。これには、カタログにすべての製品が自動的に含まれ、特別価格が適用されています(カタログ>製品の管理)。標準のMagentoカテゴリページに含まれる階層化されたナビゲーションおよびソート機能をページに保持したいと思います。

これは大多数のMagentoユーザーにとって価値のあるもののようであり、コア機能の一部として含まれていないことに驚いています。

何十ものStack Exchangeの回答、ブログ投稿、フォーラムを試しましたが、今のところ何も機能していません。誰もこれのためのプログラム的な解決策を持っていますか?

===編集===

以下のコメントでの@pspahnの批判に基づいて、同様の機能を実現する別の方法を追求することにしました。そうは言っても、この行を追求することに興味があるなら、@ sander-mangelは完全に実行可能な方法を説明します。


「すべての特別価格製品を自動的に含める」という要件は少し過剰であるように思えます。最終結果は、特別価格の製品が掲載されたページが必要であり、カテゴリページのように見えることです。代わりに、(特別価格の製品に基づいて)独自のモデル/コレクションを作成し、カテゴリビューページに基づいてテンプレートでそのコレクションを使用することができます。良い解決策として自動的に入力されるカテゴリが表示されないだけです。たとえば、ユーザーがそれを変更できないようにするにはどうすればよいですか?
pspahn

@pspahnお返事ありがとうございます。私はあなたの批判を理解し、あなたの推論に同意します。Sander Mangelによって説明された方法を、category_save_afterオブザーバーを追加して使用することもできますが、それはやり過ぎのようです。別の解決策を進めます。
rokkor

@pspahn-「ユーザーがそれを変更するのを防ぐ方法」とはどういう意味かわかりません-もう少し説明してもらえますか?
ProxiBlue 14

@ProxiBlue基本的に、カテゴリを作成して製品を自動的に入力する場合、管理者ユーザーはバックエンドでそのカテゴリに移動し、製品を手動で追加/削除できます。
pspahn

@pspahnわかりました。ユーザーがフロントエンドユーザーであると誤解していました。
ProxiBlue

回答:


8

これを行う最も簡単な方法は、ObserverとCronjobで動作するカスタム拡張機能を作成することです。

販売製品のカテゴリを作成します。このように、レイヤードナビゲーションなどのフロントエンドで通常のMagento機能を使用できます。

このカテゴリの製品を自動的に取得するには、オブザーバーとcronjobを使用します。オブザーバーはcatalog_product_save_after、製品がバックエンドに保存されるときにトリガーされるイベントを監視します。この場合special_pricespecial_price_from日付とspecial_date_to日付を確認して、製品を販売カテゴリに入れるか、そこから削除する必要があるかを判断できます。

cronjobは、特別な開始日と終了日のためにあります。毎晩真夜中以降、すべての製品の販売カテゴリが最初に空になります。次に、コレクションを使用して、特別価格を持ち、特別な開始日から終了日までのすべての製品を取得します。その場合、それらをこの販売カテゴリに移動します。


7

@SanderMangelが提供するソリューションは最高です。私は現在、私のモジュールで使用している自動化/動的カテゴリ製品-特別な製品のカテゴリルールを実行する機能を備えたコードでこれを拡張することができます

コードは、標準の製品コレクションを調整して、コードの実行日に特別価格が設定されたすべての製品を取得します。cronでこれを使用して、00:00にカテゴリを再入力し、更新されたままであることを確認できます。

コードはより大きなモジュールから抽出されることに注意してください。したがって、ここでは関連する部分を圧縮しました。thsi抽出では表されない変数が1つまたは2つある可能性がありますが、推測するのは簡単です。

$ categoryオブジェクトは、製品が含まれる実際のカテゴリです。以下のコードでは、%値で割引を指定することもできます:)

$collection = $category->getProductCollection();

$todayDate = Mage::app()->getLocale()->date()->toString(Varien_Date::DATE_INTERNAL_FORMAT);
$collection->addAttributeToFilter(array(
    array(
        'attribute' => "special_to_date",
        'null' => true
    ),
    array(
        'attribute' => "special_to_date",
        'from' => $todayDate,
        //'to'      => $todayDate,
        'date' => true
    )
));
$collection->addAttributeToFilter(array(
    array(
        'attribute' => "special_from_date",
        'null' => true
    ),
    array(
        'attribute' => "special_from_date",
        //'from'    => $todayDate,
        'to' => $todayDate,
        'date' => true
    )
));

$collection->addAttributeToSelect('special_price','left');
$collection->addAttributeToSelect('price','left');
$select = $collection->getSelect();

if (strpos($value, '%') > 0) {
    $value = str_replace('%', '', $value);
    $select->where('( 100 - (( at_special_price.value * 100 ) / at_price.value ) )  ' . $operator . ' ' . $value);
} else {
    $select->where('((at_price.value - at_special_price.value)) ' . $operator . ' ' . $value);
}

ここで、注目すべきは、コレクションには通常のカタログ<->製品リンクテーブルへのリンクが含まれているため、製品が返されないことです。現在のリンク製品に興味がないので、コレクションからそのテーブルの関係をクリアする必要があります。

次のコードを使用して、これを実行します。

/**
 * Remove Catalog Product Link elements from collection
 * 
 * @param type $collection
 * @return type
 */
public function removeCatProPart($collection)
{
    $select = $collection->getSelect();
    $fromPart = $select->getPart(Zend_Db_Select::FROM);
    $select->reset(Zend_Db_Select::FROM);

    if (array_key_exists('cat_pro', $fromPart)) {
        unset($fromPart['cat_pro']);
        // also remove any reference to the table in the rest of the query
        $columns = $select->getPart(Zend_Db_Select::COLUMNS);
        $columnRemoved = false;
        foreach ($columns as $columnKey => $column) {
            if ($column[0] == 'cat_pro') {
                unset($columns[$columnKey]);
                $columnRemoved = true;
            }
        }

        if ($columnRemoved) {
            $select->setPart(Zend_Db_Select::COLUMNS, $columns);
        }

        $orderPart = $select->getPart(Zend_Db_Select::ORDER);
        $orderRemoved = false;
        foreach ($orderPart as $orderKey => $order) {
            if ($order[0] == 'cat_pro') {
                unset($orderPart[$orderKey]);
                $orderRemoved = true;
            }
        }

        if ($orderRemoved) {
            $select->setPart(Zend_Db_Select::ORDER, $orderPart);
        }
    }
    $select->setPart(Zend_Db_Select::FROM, $fromPart);
    return $collection;
}

追加のボーナスとして、同じteqniqueを使用してカタログ製品コレクションを調整し、カタログルールのために特別なモードにある製品を見つけることができます。

$storeDate = Mage::app()->getLocale()->storeTimeStamp($this->getStoreId());
$value = $this->getValue();
$conditions = 'price_rule.product_id = e.entity_id AND ';
$conditions .= "(from_time = 0
    OR from_time <= " . $storeDate . ")
    AND (to_time = 0
    OR to_time >= " . $storeDate . ") AND ";
$conditions .= "price_rule.rule_id IN (" . $value . ")";
$collection->getSelect()->joinInner(
        array('price_rule' => $collection->getTable('catalogrule/rule_product')), $conditions);
$collection->setFlag('applied_catalog_rule_id', true);
$collection->setFlag('applied_rule', true);

作業中のコレクションを取得したら、コレクションからすべてのIDを取得し、配列を反転して$category->setPostedProducts($products);、$ category-> save()lを使用するだけです。更新を完了します。

完全を期すために、動的カテゴリーを最新の状態に保つ私の毎日のcronを以下に示します。(繰り返しますが、ここには含まれていないメソッドを指しますが、正しい方向に進むと確信しています

楽しんで :)

public static function rebuildAllDynamic($schedule)
{
    try {
        $tempDir = sys_get_temp_dir() . "/";
        $fp = fopen($tempDir . "dyncatprod_rebuild.lock", "w+");
        if (flock($fp, LOCK_EX | LOCK_NB)) {
            if (Mage::getStoreConfig('dyncatprod/debug/enabled')) {
                   mage::log("DynCatProd - rebuildAllDynamic");
            }
            if (!Mage::getStoreConfig('dyncatprod/rebuild/max_exec')) {
                ini_set('max_execution_time', 3600); // 1 hour
            }
            $categories = Mage::getModel('catalog/category')
                ->getCollection()
                ->addAttributeToSelect('*')
                ->addIsActiveFilter()
                ->addAttributeToFilter('dynamic_attributes', array('notnull' => true));

            foreach ($categories as $category) {
                $products = Mage::helper('dyncatprod')->getDynamicProductIds($category);
                if (is_array($products)) {
                    if (Mage::getStoreConfig('dyncatprod/debug/enabled')) {
                        mage::log("rebuilding :" . $category->getName() . ' ' . $category->getPath() );
                    }
                    $products = array_flip($products);
                    $category->setPostedProducts($products);
                    $category->setIsDynamic(true);
                    $category->save();
                }
            }
            flock($fp, LOCK_UN); 
            unlink($tempDir . "dyncatprod_rebuild.lock");
        } else {
            mage::log('Could not execute cron for rebuildAllDynamic -file lock is in place, job may be running');
        }
    } catch (Exception $e) {
        flock($fp, LOCK_UN); 
        unlink($tempDir . "dyncatprod_rebuild.lock");
        mage::logException($e);
        return $e->getMessage();
    }
}

ref:http : //www.proxiblue.com.au/magento-dynamic-category-products.html


5

これは、1ページに表示できるカタログ内のすべての特別価格製品の結果セットを提供するコレクションです。

$collection = Mage::getResourceModel('catalog/product_collection')
    ->addAttributeToSelect('price')
    ->setStoreId($this->getStoreId());

$date = strtotime(date('Y-m-d')); $current_date = date("Y-m-d hh:mm:ss",$date);

$collection = $collection
    ->addAttributeToFilter('price',
        array('gt'=>0))
    ->addAttributeToFilter('visibility',
        array('neq'=>Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE));

if (Mage::getStoreConfigFlag(Mage_Catalog_Helper_Product_Flat::XML_PATH_USE_PRODUCT_FLAT, $this->getStoreId())){
    $collection = $collection->addAttributeToFilter('special_price',array('lt'=>new Zend_Db_Expr('e.price')));
}
else{
    $collection = $collection->addAttributeToFilter(array(
        array('attribute'=>'special_price','lt'=>new Zend_Db_Expr('at_price.value'))
    ));
}

$collection = $collection->addAttributeToFilter(array(
        array('attribute'=>'special_from_date','lteq'=>$current_date),
        array('attribute'=>'special_from_date','eq'=>''),
        array('attribute'=>'special_from_date','null'=>true)
    ),'','left')
    ->addAttributeToFilter(array(
        array('attribute'=>'special_to_date','gteq'=>$current_date),
        array('attribute'=>'special_to_date','eq'=>''),
        array('attribute'=>'special_to_date','null'=>true)
            ),'','left');

$collection->getSelect()->group('e.entity_id');

return $collection;

これを行うにはいくつかの方法があります。独自のコントローラー、ブロック、およびモデルを持つMageカテゴリモジュールに非常に類似した新しいモジュールを作成するか、Mageカテゴリモジュールをオーバーライドして、特別なカテゴリが顧客によって選択された場合にのみ上記のコレクションを実行します。これは、システム->モジュールの構成で簡単に構成できます。

あなたが少しのお金を使うことができるなら、Magento connectで次の拡張をお勧めします

Magento 1の場合::

http://www.magentocommerce.com/magento-connect/dynamic-sale-category.htmlhttp://www.scommerce-mage.co.uk/magento-dynamic-sale-category.html

Magento 2の場合::

https://www.scommerce-mage.com/magento2-dynamic-sale-category.html

それが役に立てば幸い!

乾杯


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.