Генерация карты сайта для пользовательской модели

12

Я разработал специальный модуль, который перечисляет ряд людей на сайте. У каждого человека есть свой собственный URL (заказной контроллер Magento, который выполняет базовое CRUD для моделей Person), и мне нужно вставить эти общедоступные URL-адреса в XML-файл Google Sitemap.

Я хочу использовать собственную генерацию карты сайта Magento и cron, если смогу.

Mage_Sitemap_Model_ObserverУже тянет все Sitemap записи из sitemapsтаблицы и один за другим называет свои generateXml()методы.

$collection = Mage::getModel('sitemap/sitemap')->getCollection();
/* @var $collection Mage_Sitemap_Model_Mysql4_Sitemap_Collection */
foreach ($collection as $sitemap) {
    /* @var $sitemap Mage_Sitemap_Model_Sitemap */

    try {
        $sitemap->generateXml();
    }
    catch (Exception $e) {
        $errors[] = $e->getMessage();
    }
}

Я думаю, что мне нужно добавить мой новый файл Sitemap в sitemapsтаблицу, которая затем будет вызываться для создания моего (отдельного) XML-файла для моих записей пользовательских моделей. Тем не менее, я не знаю, как сказать Magento, чтобы использовать мой расширенный My_Module_Model_Sitemapвместо просто Mage_Sitemap_Model_Sitemap, последний из которых просто даст мне XML-файл, перечисляющий все те же категории, продукты и страницы CMS в качестве основных карт сайта.

В sitemapsтаблице есть sitemap_typeстолбец, но, насколько я могу судить, на кодовую базу Magento на него никогда не ссылаются.

Как я могу использовать встроенный движок карты сайта Magento при перезаписи, Mage_Sitemap_Model_Sitemapчтобы иметь свой собственный generateXml()метод? Или я должен создать альтернативную систему Sitemap только для своих собственных целей?

Аарон Поллок
источник
Вы хотите расширить Mage_Sitemap_Model_Sitemapкласс и переписать generateXml()правильно? что ты пробовал?
FlorinelChis
Пробовал это, но Magento просто использует Mage_Sitemap_Model_Sitemapи дает мне другую карту сайта, содержащую продукты, категории, страницы CMS - он не использует мою расширенную версию. Я не уверен, как сказать, как это сделать.
Аарон Поллок
Работаю над, возможно, переписыванием всего Mage_Sitemap_Model_Sitemapсайта в целом, и добавляю в мою собственную модель категорию и вызовы продуктов. Скоро обновлю с прогрессом.
Аарон Поллок

Ответы:

6

Шаги, которые я в конечном итоге использовал, были следующие, и комментарии и ответы до сих пор заставили меня начать в правильном направлении.

Сначала я добавил строку в таблицу "sitemap". Поскольку у нас настроено несколько хранилищ, и поскольку я хочу сохранить независимость хранилища модулей, я не жестко запрограммировал этот INSERT в миграцию MySQL, а просто запустил его в хранилище вручную:

INSERT INTO sitemap (sitemap_type, sitemap_filename, sitemap_path, store_id)
    VALUES ('people', 'people.xml', '/sitemap/', 2);

Затем я переписал Mage_Sitemap_Model_Sitemapмодель в разделе global / models в файле config.xml моего собственного модуля:

<global>
    <models>
        <sitemap>
            <rewrite>
                <sitemap>Mymod_People_Model_Sitemap</sitemap>
            </rewrite>
        </sitemap>
    </models>
</global>

Это переписывает любые вызовы на Mage_Sitemap_Model_Sitemapвесь сайт с моей пользовательской моделью, но я не хотел копировать и вставлять туда слишком много кода. Пользуясь предложением Петра Джамбазова, я использовал условное условие для передачи родительскому классу, если это sitemap_typeне «люди».

class Mymod_People_Model_Sitemap extends Mage_Sitemap_Model_Sitemap
{
    const PAGE_REFRESH_FREQUENCY = 'weekly';
    const PAGE_PRIORITY = '1.0';

    public function generateXml()
    {
        if ($this->getSitemapType() != 'people') {
            return parent::generateXml();
        }

        $io = new Varien_Io_File();
        $io->setAllowCreateFolders(true);
        $io->open(array('path' => $this->getPath()));

        if ($io->fileExists($this->getSitemapFilename()) && !$io->isWriteable($this->getSitemapFilename())) {
            Mage::throwException(Mage::helper('sitemap')->__('File "%s" cannot be saved. Please, make sure the directory "%s" is writeable by web server.', $this->getSitemapFilename(), $this->getPath()));
        }

        $io->streamOpen($this->getSitemapFilename());

        $io->streamWrite('<?xml version="1.0" encoding="UTF-8"?>' . "\n");
        $io->streamWrite('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');

        $storeId = $this->getStoreId();
        $date    = Mage::getSingleton('core/date')->gmtDate('Y-m-d');
        $baseUrl = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);

        /**
         * Generate people sitemap
         */
        $changefreq = Mymod_People_Model_Sitemap::PAGE_REFRESH_FREQUENCY;
        $priority   = Mymod_People_Model_Sitemap::PAGE_PRIORITY;
        $collection = Mage::getModel('people/person')->getCollection();
        foreach ($collection as $item) {
            $xml = sprintf('<url><loc>%s</loc><lastmod>%s</lastmod><changefreq>%s</changefreq><priority>%.1f</priority></url>',
                htmlspecialchars($item->getUrl()),
                $date,
                $changefreq,
                $priority
            );
            $io->streamWrite($xml);
        }
        unset($collection);

        $io->streamWrite('</urlset>');
        $io->streamClose();

        $this->setSitemapTime(Mage::getSingleton('core/date')->gmtDate('Y-m-d H:i:s'));
        $this->save();

        return $this;
    }
}

Есть ли лучший способ избежать копирования и вставки из родительского класса?

Аарон Поллок
источник
1

Вы можете либо расширить его, Mage_Sitemap_Model_Sitemapи в нем проверить, sitemap_typeотносится ли он к вашему типу, сгенерировать ваш xml или создать родительский xml. Или вы можете добавить наблюдателя для load_afterсобытия коллекции и добавить свою модель сайта в коллекцию.

Петар Джамбазов
источник
0

Есть ли лучший способ избежать копирования и вставки из родительского класса?

Если у вас есть Magento> = 1.9.0.0 и вы не хотите использовать продукты или каталог / изменить частоту, вы можете использовать наблюдателя на sitemap_products_generating_before

public function addPagesToSitemap(Varien_Event_Observer $observer)
{
    $collection = $observer->getCollection();
    $myPages = # your data: array('url_1', 'url_2')
    foreach ($myPages as $url) {
        $item = new Varien_Data_Object;
        $item->setUrl($url);
        $collection->addItem($item);
    }
}

Если вы хотите выполнить другое поведение на страницах карты сайта, прочитайте Sitemap.xml, измените домашнюю страницу и / или отправьте более общее событие .

sv3n
источник