Как в плагине перенаправить на другую страницу после отправки формы?

Пытаюсь разобраться с написанием плагинов. Сделал заготовку, добавляющую шутки на сайт. Пока разобрался с созданием новой таблицы в БД и добавлением в нее информации. Споткнулся на том, что необходимо после отправки формы с текстом перенаправлять пользователя на другую страницу. Подскажите, пожалуйста, каким образом это можно сделать?

Имеем экшен jokes и ивенты index и add. Добавление шутки происходит в ивенте add, после него необходим переход на index. Вот что у меня на данный момент прописано в файле classes\actions\ActionJokes.class.php:

<?php

class PluginJokes_ActionJokes extends ActionPlugin {

    /**
     * Инициализация экшена
     */
    public function Init() {
        $this->SetDefaultEvent('index');
    }

    /**
     * Регистрируем евенты
     */
    protected function RegisterEvent() {
        $this->AddEvent('index','EventIndex');
        $this->AddEvent('add','EventAdd');
    }

    /**********************************************************************************
  	 ************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
  	 **********************************************************************************
  	 */

    protected function EventAdd() {
      /**
  		 * Проверяем отправлена ли форма с данными
  		 */
  		if (!isPost('submit_joke_save')) {
  			return false;
  		}
      /**
  		 * Заполняем свойства
  		 */
      $oJoke=Engine::GetEntity('PluginJokes_Jokes');
      $this->Security_ValidateSendForm();
      $oJoke->setText(getRequest('text'));
      /**
       * Добавляем страницу
       */
      if ($this->PluginJokes_Jokes_AddJoke($oJoke)) {
        $this->Message_AddNotice($this->Lang_Get('plugin.jokes.save_ok'));
      } else {
        $this->Message_AddError($this->Lang_Get('system_error'));
      }
    }

    protected function EventIndex() {

    }

    /**
     * Завершение работы экшена
     */
    public function EventShutdown() {

    }
}
?>

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

avatar
Я не силен в этом, но после отправки можно перенаправить header() или я не о том?
  • dex-
  • 0
avatar
Честно говоря, я вообще не понял о чем Вы.

На сколько я понял, можно после
$this->Message_AddNotice($this->Lang_Get('plugin.jokes.save_ok'));

добавить что-то типа этого
Router::Location($oTopic->getBlog()->getUrlFull());

Где вместо
$oTopic->getBlog()->getUrlFull()

прописать свой путь. А вот в этом и проблема — не могу сообразить что добавить, чтобы на index перекинуло в итоге.
avatar
может так:
Router::Location(Router::GetPath('/'));
avatar
точнее так
Router::Location(Router::GetPath('jokes/index'));
avatar
Ок, спасибо, работает!
avatar
если index объявлен как дефолтный, то лучше так:
Router::Location(Router::GetPath('jokes'));


В LS 2 можно так:
Router::LocationAction('jokes');
avatar
Так и сделал, просто отписываться уже не стал.

А можно еще вопрос по пагинации? Ввод/вывод материалов получился. Выводится все на одной странице, к которой теперь пытаюсь прикрутить постраничность. Вот что имею в итоге:

В файле Jokes.mapper.class.php получаю записи следующим образом:
public function GetJokesByFilter($aFilter,&$iCount,$iCurrPage,$iPerPage) {
    $sWhere=$this->buildFilter($aFilter);

    if(!isset($aFilter['order'])) {
			$aFilter['order'] = 'date_add desc';
		}
		if (!is_array($aFilter['order'])) {
			$aFilter['order'] = array($aFilter['order']);
		}

    $sql = "SELECT * FROM ".Config::Get('plugin.jokes.table.jokes')." ORDER by Id desc";
    $sql = "SELECT
            id
          FROM
            ".Config::Get('plugin.jokes.table.jokes').",
          WHERE
            1=1
            ".$sWhere."
          ORDER BY ".
      implode(', ', $aFilter['order'])
      ."
          LIMIT ?d";
    $aJokes=array();
    if ($aRows=$this->oDb->selectPage($iCount,$sql,($iCurrPage-1)*$iPerPage, $iPerPage)) {
      foreach ($aRows as $aJokes) {
      	$aJokes[]=$aJokes['id'];
      }
    }
    return $aResult;
  }


В файле Jokes.class.php получаю все записи:
public function GetJokes($iPage,$iPerPage) {
    return $this->oMapper->GetJokesByFilter($iPage,$iPerPage);
  }


И в файле ActionJokes.class.php:
/**
	 * Вывод записей
	 *
	 */
  protected function EventIndex() {
    /**
     * Устанавливаем title страницы
     */
    $this->Viewer_AddHtmlTitle($this->Lang_Get('plugin.jokes.jokes'));
    /**
     * Передан ли номер страницы
     */
    $iPage=$this->GetParamEventMatch(0,2) ? $this->GetParamEventMatch(0,2) : 1;
    /**
     * Получаем и загружаем список записей
     */
    $aResult=$this->PluginJokes_Jokes_GetJokes($iPage,Config::Get('plugin.jokes.per_page'));
    $aJokes=$aResult['collection'];
    /**
     * Формируем постраничность
     */
    $aPaging=$this->Viewer_MakePaging($aResult['count'],$iPage,Config::Get('plugin.jokes.per_page'),Config::Get('pagination.pages.count'),Router::GetPath('jokes').'index');
    /**
     * Загружаем переменные в шаблон
     */
    $this->Viewer_Assign('aJokes',$aJokes);
  }


В итоге имею ошибки:
Warning: Missing argument 3 for PluginJokes_ModuleJokes_MapperJokes::GetJokesByFilter(), called in C:\xampp\htdocs\livestreet\plugins\jokes\classes\modules\jokes\Jokes.class.php on line 26 and defined in C:\xampp\htdocs\livestreet\plugins\jokes\classes\modules\jokes\mapper\Jokes.mapper.class.php on line 19

Warning: Missing argument 4 for PluginJokes_ModuleJokes_MapperJokes::GetJokesByFilter(), called in C:\xampp\htdocs\livestreet\plugins\jokes\classes\modules\jokes\Jokes.class.php on line 26 and defined in C:\xampp\htdocs\livestreet\plugins\jokes\classes\modules\jokes\mapper\Jokes.mapper.class.php on line 19

Fatal error: Call to undefined method PluginJokes_ModuleJokes_MapperJokes::buildFilter() in C:\xampp\htdocs\livestreet\plugins\jokes\classes\modules\jokes\mapper\Jokes.mapper.class.php on line 20


На сколько понял, в
public function GetJokesByFilter($aFilter,&$iCount,$iCurrPage,$iPerPage)


Не передаются $iCurrPage и $iPerPage, а откуда они вообще забираются сюда?

И по buildFilter: его где-то надо расписывать или он по какой-то другой причине не работает?
avatar
С buildFilter разобрался — проглядел создание этой функции в Topic.mapper.class.php.
avatar
Ну так вот же, 2 аргумента только при вызове GetJokesByFilter.

public function GetJokes($iPage,$iPerPage) {
    return $this->oMapper->GetJokesByFilter($iPage,$iPerPage);
  }
avatar
А должны быть все четыре? Я правильно понял?
avatar
Ну да, об этом же ошибка гласит, или нужно задать 2м другим значения по умолчанию.
avatar
А данные строчки
if(!isset($aFilter['order'])) {
			$aFilter['order'] = 'date_add desc';
		}

не значат, что если фильтр не задан, то сортировать по date_add?
avatar
Значат. Но вы в определении функции говорите что она принимает 4 аргумента, а передаете только 2. Вот и вылетает ошибка. Для aFilter можно задать значение по умолчанию в определении, типа $aFilter = array(), а вот $iCount я так понимаю придется передать, т.к. он дальше транслируется сюда:
$aRows=$this->oDb->selectPage($iCount,$sql,($iCurrPage-1)*$iPerPage, $iPerPage)
avatar
Спасибо, с этим вроде разобрался.
avatar
очень рекомендую/советую использовать в плагинах ORM, значительно упрощает код и его поддержку
avatar
Можно немножко на пальцах? Это если, например, создаем функцию для вывода материалов по фильтру, а потом в нужных местах просто используем разные фильтры вместо того, чтобы для каждого случая писать свои функции? Я правильно понял?

В последнем варианте плагина я переписывал все по аналогии с топиками и экшеном index. В правильном направлении двигаюсь или речь о чем-то другом?

Просто неполная неделя изучения всего этого… многие вещи я не знаю даже как называются и делаю больше интуитивно, нежели осознанно. Прошу понять и простить. :)
avatar
В топиках сейчас сделано по старому без ORM.
Про ORM есть информация здесь livestreet.ru/blog/5083.html, там же в комментах я выкладывал пример плагина. Этот же плагин есть в комплекте с админкой к LS 2.0
avatar
Спасибо! Буду вникать.
avatar
Вроде с большего разобрался, но только не пойму как здесь вывести все записи с пагинацией:

/**
	 * Вывод записей
	 *
	 */
  protected function EventIndex() {
    /**
     * Устанавливаем title страницы
     */
    $this->Viewer_AddHtmlTitle($this->Lang_Get('plugin.jokes.jokes'));
    /**
		 * Передан ли номер страницы
		 */
		$iPage=$this->GetParamEventMatch(0,2) ? $this->GetParamEventMatch(0,2) : 1;
    /**
		 * Получаем список топиков
		 */
    //$aJokes=$this->PluginJokes_Jokes_GetJokesAll(array('#page' => array(1,15), '#cache'=>''));

    $aResult=$this->PluginJokes_Jokes_GetJokesItemsAll($iPage,Config::Get('plugin.jokes.per_page'));
		$aJokes=$aResult['collection'];
    /**
		 * Формируем постраничность
		 */
		$aPaging=$this->Viewer_MakePaging($aResult['count'],$iPage,Config::Get('plugin.jokes.per_page'),Config::Get('pagination.pages.count'),Router::GetPath('jokes').'index');
		/**
		 * Загружаем переменные в шаблон
		 */
		$this->Viewer_Assign('aJokes',$aJokes);
		$this->Viewer_Assign('aPaging',$aPaging);
    /**
		 * Устанавливаем шаблон вывода
		 */
		$this->SetTemplateAction('index');
  }
avatar
Извиняюсь за беспокойство, разобрался сам: не глянул на плагин в 2.0.
avatar
В топиках сейчас сделано по старому без ORM.
А в пределах шаблона можно переделать вывод топиков на ORM?
avatar
Подскажите, пожалуйста, а как с помощью ORM вывести последние записи пользователя за последние N секунд? Пишу условие для ACL и не могу разобраться с фильтром.

$aTestimonial=$this->PluginTestimonials_Testimonials_GetTestimonialsItemsByFilter(array(
      '#user' => $oUser->getId(),
      '#date_add'  => date("Y-m-d H:i:s",time()-Config::Get('plugin.testimonials.acl.create.limit_time'))
    ));
		if(isset($aTestimonial['count']) and $aTestimonial['count']>0){
			return false;
		}
		return true;

Можно пару слов как в нем параметры задавать (#order, #page)?
avatar
$aTestimonial=$this->PluginTestimonials_Testimonials_GetTestimonialsItemsByFilter(array(
      '#page' => array(1,20),
      '#order' => array('id' => 'desc'),
      'user_id' => $oUser->getId(),
      'date_add >'  => date("Y-m-d H:i:s",time()-Config::Get('plugin.testimonials.acl.create.limit_time'))
    ));

Условия для полей нужно писать без решетки (#), она используется только для служебных параметров.
avatar
Спасибо, а время здесь правильно прописано? А то что-то с ним не срабатывает условие.
avatar
верно
можно включить в конфиге логирование SQL запросов и посмотреть результирующий запрос
avatar
Спасибо! Невнимательность… пропустил знак ">" у date_add.
avatar
Добрался до вывода материлов в профиле пользователя. Подскажите, а можно как-то увеличивать цифру публикаций пользователя в меню сайдбара на колличество его записей в плагине?
avatar
github.com/livestreet/livestreet/blob/master/application/classes/actions/ActionProfile.class.php
Подсчет происходит в методе:
public function EventShutdown()
Переопределить можно и посчитать как тебя надо.
avatar
Подсчет видел. Но… я правильно понимаю, что если на сайте будет стоять еще один плагин переобределяющий подсчет, то в итоге будет выведено только одно значение? Или можно как-то разрулить это?
avatar
public function EventShutdown() {
if (!$this->oUserProfile) {
return;
}
parent::EventShutdown();
$iCountTestTopic=$this->PluginTest_Test_GetCountItemsByFilter(array('#where'=>array('user_id = ?d' => array($this->oUserProfile->getId()))),'Post');
$iCountCreated = (int)$this->Viewer_GetSmartyObject()->getTemplateVars('iCountCreated');
$this->Viewer_Assign('iCountCreated',$iCountCreated+$iCountTestTopic);
}
avatar
Спасибо!
avatar
Мужики, может у кого будет свободная минута, гляньте, пожалуйста, в чем у меня проблема. Вот плагин в котором пытаюсь прикрутить пагинацию. А вот старая его версия где все работает, но без пагинации.

В последнем варианте вроде как все разрулил, но сыплются ошибки при попытке вывести информацию. Всю голову уже сломал. :)
avatar
Немного допилил плагин, вот обновленная версия. Выпилил фильтр и поправил регистрацию евента.

При попытке вывести записи, ошибка: Fatal error: Call to a member function getUser() on a non-object

В файле шаблона убираю в цикле вывод данных записи (юзер, текст, дата) и потставляю набор символов, чтоб проверить работает ли что-нибудь. В итоге пагинация появляется и количество страниц в ней правильное (записей в базе 11, записей на страницу — 2, соответственно и выводятся 6 страниц), но на каждой странице выводится по пять раз подставленный набор символов, хотя, по идее, должен по два раза + на последней один раз.

На сколько могу судить у меня не вытягиваются необходимые данные (юзер, текст, дата) + что-то не так с выводом. Но найти проблемное место так и не получается. Все делал по аналогии с выводом всех новых материалов в ActionIndex.class.php.
avatar
Не актуально, справился сам.
avatar
Последний, надеюсь, вопрос: как добавить событие плагина в активность?

В Stream.class.php видел, что добавление нового типа события для плагинов заложено, но что с этим делать, вопрос.
avatar
Разобрался?
avatar
Неа, так и не понял.
avatar
Много писать. Посмотри плагин форум. Поиском пройдись с Stream_. Много мест куда код прописать надо. И если, что спрашивай.
avatar
Думал что только в галерее-про данный функционал есть, уже подумывал прикупить, чтобы поковыряться… Спасибо!
avatar
Спрашиваю. :) Добавил следующее: github.com/vakulesh/testimonials/commit/b303d1934ea6c361123d6343db0353129f0b5bb3

В итоге: при добавлении записей в таблицу активности записи добавляются, но на странице активности они не выводятся. Смотрел логи БД — запрос возвращает количество строк равное общему количеству строк в таблице. Подозреваю, что проблема может быть в этом месте:

class PluginTestimonials_ModuleStream extends PluginTestimonials_Inherit_ModuleStream {

  /**
	 * Получает список записей
	 */
	protected function loadRelatedTestimonials($aIds) {
		return $this->PluginTestimonials_Testimonials_GetTestimonialsItemsByArrayTestimonialsId($aIds);
	}

}


но не уверен и не пойму, как проверить.
avatar
PluginTestimonials.class.php
$this->Stream_AddEventType('add_testimonial', array('related' => 'Testimonials','unique'=>true));
Stream.class.php
	protected function loadRelatedTestimonials($aIds) {
		return $this->PluginTestimonials_Testimonials_GetTestimonialsItemsByArrayId($aIds);
	}
event.add_testimonials.tpl
{assign var=oTestimonial value=$oStreamEvent->getTarget()}
{$aLang.plugin.testimonials.event_add_testimonial} {$oTestimonial->getText()|escape:'html'}
avatar
А я вчера близок к решению был :) оставалось только это правильно прописать:

$this->Stream_AddEventType('add_testimonial', array('related' => 'Testimonials','unique'=>true));


Можно, кстати, немного пояснить данную строчку? Testimonials — вот это и это: 'unique'=>true.

Да, и я правильно понимаю, что здесь: GetTestimonialsItemsByArrayId, Testimonials — это название сущности, а ByArrayId пишем потому, как имена столбцов в БД без префиксов?
avatar
related — связь для получения записей.
unique — указывает, что событие уникальное (дважды не записывать).
Да. Верно.
avatar
Спасибо за помощь!
avatar
Пожалуйста! Хоть какую-нибудь активность на сайте производить…
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.