Свои переменные в виджете (решено)

Добрый день.
AltoCMS 0.9.7.1
Код виджета:
<?php

/**
 * Обработка виджета карты
 *
 * @package widgets
 * @since 1.0
 */
class WidgetYandexmap extends Widget {
    /**
     * Запуск обработки
     */
    public function Exec() {
        /**
         * Получаем список топиков
         */
        if ($aTopics = $this->Topic_GetTopicsForMap()) {
            $oViewer = $this->Viewer_GetLocalViewer();
            $oViewer->Assign('aMyTopics', $aTopics);

            // * Формируем результат в виде шаблона и возвращаем
            $sTextResult = $oViewer->FetchWidget('yandexmap.tpl');
            $this->Viewer_Assign('sYandexmap', $sTextResult);
        }
    }
}

    /**
     * Возвращает список топиков для карты
     *
     * @return array
     */ 
    public function GetTopicsForMap()  {
        $aFilter = array(
            'topic_type' => 'need_help',
        );
        $aTopicsId = $this->oMapperTopic->GetAllTopics($aFilter);
        if (!is_array($aTopicId)) {
            $aTopicId = array($aTopicId);
        }
        $aTopicId = array_unique($aTopicId);
        $aTopics = array();
        $s = join(',', $aTopicId);
        if (false === ($data = $this->Cache_Get("topic_id_for_map_{$s}"))) {
		$data = $this->GetTopicsAdditionalData($aTopicsId);
		foreach ($data as $oTopic) {
                	$aTopics[$oTopic->getId()] = $oTopic;
            	}
            	$this->Cache_Set($aTopics, "topic_id_for_map_{$s}", array(), 60 * 1);
            	return $aTopics;
        }
        return $data;
    }



В логах sql я вижу, что данные в массиве $aTopics должны быть. (Как проверить сам массив не знаю).
В шаблоне
{$aMyTopics|@count}

Получаю значение 0.
Я не понял можно ли свои произвольные переменные передавать в шаблон?


UPD.
$this->Viewer_Assign('aMyTopics', $aTopics);

Не копируйте чужой код, если его не до конца поняли :)

12 комментариев

0
попробуйте в коде вывести содержимое $aTopics в момент передачи в шаблон $oViewer->Assign('aMyTopics', $aTopics); и посмотрите, передается тем самым с шаблон или нет.
И надеюсь вы ожидаете увидеть aMyTopics в шаблоне yandexmap.tpl.

Пробежавшись глаза вроде все правильно написано
0
Остаётся всё равно ноль, при заходе в блоги.
Шаблон block.yandexmap.tpl в /templates/skin/bootstrap/blocks

Подключаю в widgets.php:
<code>$config['widgets'][] = array(
    'name' => 'yandexmap',     // исполняемый виджет
    'wgroup' => 'header',    // группа, куда нужно добавить виджет
    'priority' => 100,      // приоритет
    'action' => array(
        'index',
        'community',
        'filter',
        'blogs',
        'blog' => array('{topics}', '{topic}', '{blog}'),
        'tag',
    ),
    'title' => 'Карта',
);</code>

В основном шаблоне:
{include file='blocks.tpl' group='header'}
Отредактирован:
0
pomogi-sosedyam.ru/filter/need_help/
Под лого сейчас цифры 0 0 1
$oViewer->Assign('aNeedTopics', $aTopics);
$oViewer->Assign('aCanTopics', $aTopics);

{$aNeedTopics|@count}
{$aCanTopics|@count}
{$aTopics|@count}
Отредактирован:
0
подождите, я что-то запутался тогда. У вас получается есть только файл block.yandexmap.tpl и aMyTopics вы хотите передать туда? Тогда я несколько не понимаю вашего кода. Он должен быть вместо
$oViewer = $this->Viewer_GetLocalViewer();
$oViewer->Assign('aMyTopics', $aTopics);

// * Формируем результат в виде шаблона и возвращаем
$sTextResult = $oViewer->FetchWidget('yandexmap.tpl');
$this->Viewer_Assign('sYandexmap', $sTextResult);

$this->Viewer_Assign('aMyTopics', $aTopics);

Я конечно могу путаться в особенностях версий, потому как сам живу на чем-то промежуточном.
0
Так тоже не помогло.
Может разработчики подскажут?

Изменёны:
/templates/skin/bootstrap/header.tpl
/classes/modules/topic/Topic.class.php
/config/widgets.php
Добавлены:
/templates/skin/bootstrap/blocks/block.yandexmap.tpl
/classes/widgets/WidgetYandexmap.class.php

Прямо хоть на 1.0 RC3 пробовать сразу…
Очень трудно новичку, когда нет документации.
Пробую на 0.9.7, так как оно ближе к LS, а на LS очень много статей.
Да и плагины под 0.9 пока что только есть. Не факт что карты там подключить получится…
Отредактирован:
0
Этот многострочный код я брал из другого виджета за образец.
0
Пара замечаний по функции GetTopicsForMap():

1) Сначала используется переменная $aTopicsId, а потом для ключа кеша — $aTopicsId, т.е. пропущена буква s. Я так понимаю, это просто опечатка. Если ее исправить, то проверка на is_array($aTopicId) будет уже не нужна, т.к. вызов метода маппера GetAllTopics() всегда вернет массив.

2) Вы сначала получаете список ID, а потом сами топики. Но кешируете только вторую часть получения данных. Думаю, лучше было б кешировать полный набор данных, чтоб уменьшить число запросов к базе. Плюс Ваш кеш не учитывает того, что данные топиков могут меняться (Ваш кеш не будет сбрасываться).

В общем, я бы код написал примерно так:

    public function GetTopicsForMap()  {
        // Задаем фильтр для топиков
        $aFilter = array(
            'topic_type' => 'need_help',
        );
        // Создаем ключ кеша
        $sCacheKey = 'topics_filter_' . serialize($aFilter);

        // Если топиков в кеше нет, то получаем их
        if (false === ($aTopics = $this->Cache_Get($sCacheKey))) {
            // Сначала получим список ID топиков по фильтру
            $aTopicsId = $this->oMapperTopic->GetAllTopics($aFilter);

            // Теперь получим сами топики
            $aData = $this->GetTopicsAdditionalData($aTopicsId);

            // Формируем массив топиков со всеми требуемыми данными
            foreach ($aData as $oTopic) {
                $aTopics[$oTopic->getId()] = $oTopic;
            }
            /* Сохраняем массив в кеше. При этом указываем:
             *
             * 1) Дополнительные кеш-ключи (в нашем случае - 'topic_new' и 'topic_update')
             * При добавлении/обновлении любого топика будет выполнена очистка кеша по этим ключам,
             * и наш кеш тоже очистится, чтоб при следующем запросе получить новые данные
             *
             * 2) Время жизни кеша. Его можно указывать в виде числа (количество секунд) либо
             * в виде строки задания периода, например:
             *   P1D - 1 день
             *   P1M - 1 месяц
             *   P2DT8H - 2 дня и 8 часов
             *   PT3600S - 3600 секунд  
             */
            $this->Cache_Set($aTopics, $sCacheKey, array('topic_new', 'topic_update'), 'P1D');
        }
        // Возвращаем массив топиков
        return $aTopics;
    }
0
Спасибо
После корректировки функция выглядит теперь так:
/**
     * Возвращает список топиков для карты
     *
     * @return array
     */ 
    public function GetTopicsForMap($sType)  {
        $aFilter = array(
            'topic_type' => $sType,
        );
	$sCacheKey = 'topics_filter_' . serialize($aFilter);
        if (false === ($aTopics = $this->Cache_Get($sCacheKey))) {
	        $aTopicId = $this->oMapperTopic->GetAllTopics($aFilter);
        	$aTopicId = array_unique($aTopicId);
	        $aTopics = array();
		$aData = $this->GetTopicsAdditionalData($aTopicId, array('user' => array(), 'blog' => array('owner' => array()), 'fields' ));
		foreach ($aData as $oTopic) {
                	$aTopics[$oTopic->getId()] = $oTopic;
            	}
            	$this->Cache_Set($aTopics, $sCacheKey, array('topic_new', 'topic_update'), 60 * 60 * 24 * 1);
        }
        return $aTopics;
    }
0
$aTopicId = array_unique($aTopicId);

там нет
комментарий отредактировать почему-то не даёт
0
Просьба: большие тексты убирать под кат. Такая кнопочка есть на панели редактора с ножницами. Либо руками надо указать тег <cut> в нужном месте
0
Учту
0
Ещё маленький подвопрос.
Получается, что сейчас нет функционала для построения фильтра с критериями для fields?
Я сейчас ещё дополнительно обрабатываю массив топиков в шаблоне.
{foreach from=$aNeedTopics item=oTopic}
		        {if $LS->Topic_IsAllowTopicType($oTopic->getType())}
				{$oFieldActual = $oTopic->getField(9)}
				{if $oFieldActual->getValue() == 'Да'}
...
	        		{/if}
        		{/if}
	        {/foreach}
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.