Перейти к публикации
Дизайн и модификация IPS Community IPBSkinsBETA
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...
TemKa_SD

$form и \IPS\Patterns\ActiveRecord

Рекомендованные сообщения

05/13/19 07:24 (изменено)

Здравствуйте. Делаю новую форму для контроллеров, которые есть в админке и фронте. Класс реализован с помощью \IPS\Patterns\ActiveRecord, node здесь не нужен. Так как в node есть стандартно parent::form, а в ActiveRecord нету, в связи с этим у меня вопрос: если я просто реализую форму функцией public function formWizard() я смогу обращаться к ней из админки и фронта?

 

2. Спрошу тоже тут, так как вопрос касается этой формы. Сделал 3 шага, первый - указание данных, второй - их подтверждение, 3 - результат будет. При переходе на страницу app=wc3&module=players&controller=players&do=form шаги начинаются со 2, почему?

 

public function formWizard()
{
	return new \IPS\Helpers\Wizard(
		array(
			'wc3_gameplayers_connect_first_step' => function( $data )
			{
				$form = new \IPS\Helpers\Form( 'wc3_gameplayers_connect_first_step', 'wc3_gameplayers_connect_first_step_continue' );
				$form->add(new \IPS\Helpers\Form\Text('wc3_gameplayers_connected_name', NULL, true, array('maxLength' => 15)));
				$form->add(new \IPS\Helpers\Form\Select('wc3_gameplayers_connected_realm', NULL, true, array(
					'options' => array(
						NULL => '',
						'server.wc3.info' => 'WC3.Info',
						'iccup.wc3.info' => 'Iccup',
						'rubattle.net' => 'RuBattle',
						'eurobattle.net' => 'EuroBattle'
					),
				)));
				$form->add( new \IPS\Helpers\Form\Select( 'wc3_gameplayers_connected_role', NULL, TRUE, array( 'options' => \IPS\wc3\Player\Role::roles(), 'parse' => 'normal' ) ) );

				if ( $values = $form->values() )
				{
					$count = \IPS\Db::i()->select( 'COUNT(*)', static::$databaseTable, array( 'name=? AND server=?', mb_strtolower($values['wc3_gameplayers_connected_name']), $values['wc3_gameplayers_connected_realm'] ) )->first();

					if ( $count > 0 )
					{
						$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'wc3_gameplayers_connected_error_count' );
						return $form;
					}

					return $values;
				}

				return $form;
			},
			'wc3_gameplayers_connect_second_step' => function ( $data )
			{
				$players = array();

				foreach ( \IPS\Db::i()->select( 'name, spoofedrealm', 'wc3_gameplayers', array( 'name=?', mb_strtolower($data['wc3_gameplayers_connected_name']) ) ) as $player )
				{
					$players[ $player['name'] ] = $player['spoofedrealm'];
				}

				$form = new \IPS\Helpers\Form( 'wc3_gameplayers_connect_second_step', 'wc3_gameplayers_connected_add' );
				$form->addHeader('wc3_gameplayers_connect_second_step_desc');
				$form->addMessage( 'Мы нашли ' . \count($players) . ' игроков.', 'ipsMessage ipsMessage_warning', TRUE );

				if ( $values = $form->values() )
				{
					$count = \IPS\Db::i()->select( 'COUNT(*)', static::$databaseTable, array( 'name=? AND server=?', mb_strtolower($values['wc3_gameplayers_connected_name']), $values['wc3_gameplayers_connected_realm'] ) )->first();

					if ( $count > 0 )
					{
						$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'wc3_gameplayers_connected_error_count' );
						return $form;
					}

					return $values;
				}

				return $form;
			},
			'wc3_gameplayers_connect_finish_step' => function ( $data )
			{
				$form = new \IPS\Helpers\Form( 'wc3_gameplayers_connect_finish_step', 'continue' );
				$form->addMessage( 'import_date_explain' );

				return $form;
			}
		),
		\IPS\Http\Url::internal( 'app=wc3&module=players&controller=players&do=form' ), TRUE, NULL, TRUE, NULL
	);
}

 

3. Мне в форме в шагах 2 и 3 нужно будет использовать кастомный шаблон, для вывода тех или иных сообщений. Реализовывать его с помощью функций формы или же других?

 

4. На втором шаге мне нужно реализовать две кнопки, вернутся на предыдущий шаг и продолжить, как добавить вторую?

Изменено пользователем TemKa_SD

Поделиться сообщением


Ссылка на сообщение

Остался пункт 3 и 4, но с 3 думаю сообщения формы НЕ использовать, лучше наверно IPS/output.

Поделиться сообщением


Ссылка на сообщение

Помогите пожалуйста, я часов 6 эту фигню копаю и не могу сделать. Вот финальная форма:

 

public function formWizard()
{
	\IPS\Output::i()->output = new \IPS\Helpers\Wizard(
		array(
			'wc3_gameplayers_connect_first_step' => function( $data )
			{
				$form = new \IPS\Helpers\Form;
				$form->add(new \IPS\Helpers\Form\Text('wc3_gameplayers_connected_name', NULL, true, array('maxLength' => 15)));
				$form->add(new \IPS\Helpers\Form\Select('wc3_gameplayers_connected_realm', NULL, true, array(
					'options' => array(
						NULL => '',
						'server.wc3.info' => 'WC3.Info',
						'iccup.wc3.info' => 'Iccup',
						'rubattle.net' => 'RuBattle',
						'eurobattle.net' => 'EuroBattle'
					),
				)));
				$form->add( new \IPS\Helpers\Form\Select( 'wc3_gameplayers_connected_role', NULL, TRUE, array( 'options' => \IPS\wc3\Player\Role::roles(), 'parse' => 'normal' ) ) );

				if ( $values = $form->values() )
				{
					$count = \IPS\Db::i()->select( 'COUNT(*)', static::$databaseTable, array( 'name=? AND server=?', mb_strtolower($values['wc3_gameplayers_connected_name']), $values['wc3_gameplayers_connected_realm'] ) )->first();

					if ( $count > 0 )
					{
						$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'wc3_gameplayers_connected_error_count' );
						return $form;
					}

					return $values;
				}

				return (string) $form;
			},
			'wc3_gameplayers_connect_second_step' => function ( $data )
			{
				$message = NULL;
				$class = NULL;

				$form = new \IPS\Helpers\Form( 'wc3_gameplayers_connect_second_step', 'wc3_gameplayers_connect_second_step_button' );
				$form->addHeader('wc3_gameplayers_connect_second_step_desc');

				foreach ( \IPS\Db::i()->select( 'name, spoofedrealm', 'wc3_gameplayers', array( 'name=?', $data['wc3_gameplayers_connected_name'] ), NULL, NULL, NULL, NULL, 1 ) as $player )
				{
					if ($player['spoofedrealm'] === $data['wc3_gameplayers_connected_realm']) {
						$message = 'wc3_gameplayers_connect_second_step_message_success';
						$class = 'ipsMessage_success';
					}
					else {
						$message = 'wc3_gameplayers_connect_second_step_message_warning';
						$class = 'ipsMessage_warning';
					}
				}

				if ($message) {
					$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack($message, NULL, array( 'sprintf' => array( NULL ) ) ), 'ipsMessage ' . $class, FALSE );
				}
				else {
					$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack('wc3_gameplayers_connect_second_step_message_error', NULL, array( 'sprintf' => array( NULL ) ) ), 'ipsMessage ipsMessage_error', FALSE );
				}

				if ( /* ЧТО ЗДЕСЬ УКАЗАТЬ ЧТОБЫ ПРИ НАЖАТИИ НА КНОПКУ СОХРАНИЛИСЬ ДАННЫЕ И ПЕРЕШЛО НА ШАГ 3????????????? */ )
				{
					$conn = new static;

					$conn->name = mb_strtolower($data['wc3_gameplayers_connected_name']);
					$conn->server = $data['wc3_gameplayers_connected_realm'];
					$conn->member_id = \IPS\Member::loggedIn()->member_id;
					$conn->role_id = $data['wc3_gameplayers_connected_role'];
					$conn->save();

					$data['id'] = $conn->id;

					return $data;
				}

				return (string) $form;
			},
			'wc3_gameplayers_connect_finish_step' => function ( $data )
			{
				$form = new \IPS\Helpers\Form( 'wc3_gameplayers_connect_finish_step', 'wc3_gameplayers_connect_finish_step_button' );
				$form->addMessage( $data['wc3_gameplayers_connected_name'] );

				if ( /* ЧТО ЗДЕСЬ УКАЗАТЬ ЧТОБЫ ПРИ НАЖАТИИ НА КНОПКУ ПРОВЕРИЛСЬ УСЛОВИЯ НИЖЕ И ВЫПОЛНИЛСЯ РЕДИРЕКТ????????????? */ )
				{
					$conn = static::load($data['id']);

					if ( $conn->_data['status'] == 'pending' )
					{
						$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'wc3_gameplayers_connect_finish_step_error_status' );
						return $form;
					}

					\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=wc3&module=players&controller=players' ) );

				}

				return (string) $form;
			}
		),
		\IPS\Http\Url::internal( 'app=wc3&module=players&controller=players&do=form' ), TRUE, NULL, TRUE, NULL
	);
}

 

Мне только осталось заменить в ней это:

 

/* ЧТО ЗДЕСЬ УКАЗАТЬ ЧТОБЫ ПРИ НАЖАТИИ НА КНОПКУ СОХРАНИЛИСЬ ДАННЫЕ И ПЕРЕШЛО НА ШАГ 3????????????? */

/* ЧТО ЗДЕСЬ УКАЗАТЬ ЧТОБЫ ПРИ НАЖАТИИ НА КНОПКУ ПРОВЕРИЛСЬ УСЛОВИЯ НИЖЕ И ВЫПОЛНИЛСЯ РЕДИРЕКТ????????????? */

  • Upvote 1

Поделиться сообщением


Ссылка на сообщение

Вопрос то в чем? Вот у вас в первом сообщение есть условие которое применяется при отправке формы - if ( $values = $form->values() )

Поделиться сообщением


Ссылка на сообщение
05/13/19 22:53 (изменено)

Да, но в следующих нет формы, там работает уже $date, соответственно, если добавить это условие - оно не будет работать, так как в форме нет данных. Как мне при нажатии кнопки формы перейти на следующий шаг, со 2 на 3 и с 3 редирект, точнее какой условие создать в IF? Если делать что-то вроде $data или isset($data) или я пробовал вообще по разному, добавляя в форму &step2 и &step3 соответственно, ничего работать не хочет.

 

P.S.: hiddenvalue Работает только во 2 шаге, если его передать - обработает как форму, в 3 шаге это уже не работает, $form->values() - пустое.

Изменено пользователем TemKa_SD

Поделиться сообщением


Ссылка на сообщение

P.S.: hiddenvalue Работает только во 2 шаге, если его передать - обработает как форму, в 3 шаге это уже не работает, $form->values() - пустое.

 

Так в 3-ем шаге тоже добавьте.

Поделиться сообщением


Ссылка на сообщение

Я добавлял, сегодня добавил уже полноценные поля, они в принципе там нужны тоже, только без обновления, только для чтения. Я всё сделал правильно, но оно не хочет работать, я этот код вдоль и поперек перекопал, на 3 шаге, когда нажимаешь ЗАВЕРШИТЬ - оно переходит по этой ссылке:

 

\IPS\Http\Url::internal( 'app=wc3&module=players&controller=players&do=form' )

 

Это не выполняет:

 

				if ( $values = $form->values() )
				{
					if ( $conn->_data['status'] == 'pending' )
					{
						$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'wc3_gameplayers_connect_finish_step_error_status' );
						return $form;
					}

					\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=wc3&module=players&controller=players' ) );

				}

 

Потому что тут пустота:

 

$form->values()

 

 

public function formWizard()
{
	\IPS\Output::i()->output = new \IPS\Helpers\Wizard(
		array(
			'wc3_gameplayers_connect_first_step' => function( $data )
			{
				$form = new \IPS\Helpers\Form;
				$form->add(new \IPS\Helpers\Form\Text('wc3_gameplayers_connected_name', NULL, true, array('maxLength' => 15)));
				$form->add(new \IPS\Helpers\Form\Select('wc3_gameplayers_connected_realm', NULL, true, array(
					'options' => array(
						NULL => '',
						'server.wc3.info' => 'WC3.Info',
						'iccup.wc3.info' => 'Iccup',
						'rubattle.net' => 'RuBattle',
						'eurobattle.net' => 'EuroBattle'
					),
				)));
				$form->add( new \IPS\Helpers\Form\Select( 'wc3_gameplayers_connected_role', NULL, TRUE, array( 'options' => \IPS\wc3\Player\Role::roles(), 'parse' => 'normal' ) ) );

				if ( $values = $form->values() )
				{
					$count = \IPS\Db::i()->select( 'COUNT(*)', static::$databaseTable, array( 'name=? AND server=?', $values['wc3_gameplayers_connected_name'], $values['wc3_gameplayers_connected_realm'] ) )->first();

					if ( $count > 0 )
					{
						$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'wc3_gameplayers_connected_error_count' );
						return $form;
					}

					return $values;
				}

				return (string) $form;
			},
			'wc3_gameplayers_connect_second_step' => function ( $data )
			{
				$message = NULL;
				$class = NULL;

				$form = new \IPS\Helpers\Form( 'wc3_gameplayers_connect_second_step', FALSE, \IPS\Http\Url::internal( 'app=wc3&module=players&controller=players&do=form&_step=wc3_gameplayers_connect_second_step' ) );

				foreach ( \IPS\Db::i()->select( 'name, spoofedrealm', 'wc3_gameplayers', array( 'name=?', $data['wc3_gameplayers_connected_name'] ), NULL, NULL, NULL, NULL, 1 ) as $player )
				{
					if ($player['spoofedrealm'] === $data['wc3_gameplayers_connected_realm']) {
						$message = 'wc3_gameplayers_connect_second_step_message_success';
						$class = 'ipsMessage_success';
					}
					else {
						$message = 'wc3_gameplayers_connect_second_step_message_warning';
						$class = 'ipsMessage_warning';
					}
				}

				if ($message) {
					$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack($message, NULL, array( 'sprintf' => array( $data['wc3_gameplayers_connected_realm'] ) ) ), 'ipsMessage ' . $class, FALSE );
				}
				else {
					$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack('wc3_gameplayers_connect_second_step_message_error', NULL, array( 'sprintf' => array( NULL ) ) ), 'ipsMessage ipsMessage_error', FALSE );
				}

				$form->add(new \IPS\Helpers\Form\Text('wc3_gameplayers_connected_name', $data['wc3_gameplayers_connected_name'], true, array('maxLength' => 15, 'disabled' => TRUE)));
				$form->add(new \IPS\Helpers\Form\Text('wc3_gameplayers_connected_realm', $data['wc3_gameplayers_connected_realm'], true, array('disabled' => TRUE)));

				$form->addButton( 'wc3_gameplayers_connect_second_step_button_prev', 'link', \IPS\Http\Url::internal( "app=wc3&module=players&controller=players&do=form&_step=wc3_gameplayers_connect_first_step")->csrf(), 'ipsButton ipsButton_primary' );
				$form->addButton( 'wc3_gameplayers_connect_second_step_button', 'submit', null, 'ipsButton ipsButton_primary', array( 'tabindex' => '2', 'accesskey' => 's' ) );

				if ( $values = $form->values() )
				{
					$conn = new static;

					$conn->name = mb_strtolower($data['wc3_gameplayers_connected_name']);
					$conn->server = $data['wc3_gameplayers_connected_realm'];
					$conn->member_id = \IPS\Member::loggedIn()->member_id;
					$conn->role_id = $data['wc3_gameplayers_connected_role'];
					$conn->save();

					$data['id'] = $conn->id;

					return $data;
				}

				return (string) $form;
			},
			'wc3_gameplayers_connect_finish_step' => function ( $data )
			{
				$form = new \IPS\Helpers\Form( 'wc3_gameplayers_connect_finish_step', FALSE, \IPS\Http\Url::internal( 'app=wc3&module=players&controller=players&do=form&_step=wc3_gameplayers_connect_finish_step' ) );
				$form->addMessage( 'wc3_gameplayers_connect_finish_step_message' );

				$conn = static::load($data['id']);

				$form->add(new \IPS\Helpers\Form\Text('wc3_gameplayers_connect_finish_step_command', '!verify ' . $conn->_data['token'], true, array()));

				$form->addButton( 'wc3_gameplayers_connect_finish_step_button', 'submit', null, 'ipsButton ipsButton_primary', array( 'tabindex' => '2', 'accesskey' => 's' ) );

				if ( $values = $form->values() )
				{
					if ( $conn->_data['status'] == 'pending' )
					{
						$form->error = \IPS\Member::loggedIn()->language()->addToStack( 'wc3_gameplayers_connect_finish_step_error_status' );
						return $form;
					}

					\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=wc3&module=players&controller=players' ) );

				}

				return (string) $form;
			}
		),
		\IPS\Http\Url::internal( 'app=wc3&module=players&controller=players&do=form' ), TRUE, NULL, TRUE, NULL
	);
}

Поделиться сообщением


Ссылка на сообщение
Потому что тут пустота:

Откуда Вы это знаете?

 

Я всё сделал правильно, но оно не хочет работать, я этот код вдоль и поперек перекопал,

Нужно не копать, а смотреть, как работает wizard.

	/**
 * Constructor
 *
 * @param	array			$steps			An array of callback functions. Each function should return either a string to output or (if the step is done) an array (which can be blank) of arbitrary data to retain between steps (which will be passed to each callback function). The keys should be langauge keys for the title of the step.
 * @param	\IPS\Http\Url	$baseUrl		The base URL (used when moving between steps)
 * @param	bool			$showSteps		Whether or not to show the step bar
 * @param	array|NULL		$initialData	The initial data, if any
 * @param	bool			$resetWhenDone	Whether or not to reset the session data when the wizard completes
 * @param	string|array|null $ignoreQueryParams	String or array of URL params to ignore. For example, the base URL may be /submit/ but your userland code adds params /submit/?foo=bar, this changes the baseUrl and creates a new wizard session
 * @return	void
 */

У Вас $resetWhenDone = TRUE

Смотрим дальше

				/* Last step? */
			if ( $this->resetWhenDone and ( $lastStep === $activeStep ) )
			{
				/* Wipe session data */
				unset( $_SESSION[ 'wizard-' . md5( $this->baseUrl ) . '-step' ] );
				unset( $_SESSION[ 'wizard-' . md5( $this->baseUrl ) . '-data' ] );
			}

На последнем шаге визард обнуляется

Поделиться сообщением


Ссылка на сообщение
05/14/19 11:38 (изменено)

$resetWhenDone - это я специально установил, чтобы сессии не кешировались в базу.

 

Спасибо, заработало. У меня вопрос короткий, вот так это сейчас выглядит: http://prntscr.com/nodkdr я думаю как лучше вывести на фронте, в виде контроллера или может в настройках аккаунта, где loginhandler, но классов не нашел для переопределения этого метода. Что посоветуете?

Изменено пользователем TemKa_SD

Поделиться сообщением


Ссылка на сообщение

Делайте, где хотите.

Поделиться сообщением


Ссылка на сообщение
05/14/19 13:59 (изменено)

http://prntscr.com/nofvmi Я уже всё завершил пол часа назад, сейчас вернулся другой аккаунт добавить - осталось на последнем шаге, хотя я его проходил уже и меня редиректило с формы.

 

Еще если удалить запись - её всё равно будет пытаться грузить, и ошибка 500. Что-то почистить надо наверно на финальном шаге, сейчас копаю.

 

Похоже, это условие не срабатывает: http://prntscr.com/nogc41

 

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

 

					unset($_SESSION[ 'wizard-' . md5( \IPS\Http\Url::internal( 'app=wc3&module=gameplayers&controller=connected&do=form' ) ) . '-step' ]);
					unset($_SESSION[ 'wizard-' . md5( \IPS\Http\Url::internal( 'app=wc3&module=gameplayers&controller=connected&do=form' ) ) . '-data' ]);

 

В функцию удаления тоже добавил.

Изменено пользователем TemKa_SD

Поделиться сообщением


Ссылка на сообщение

А я вообще не понимаю - зачем тут визард используется, все эти проверки, запросы, сохранение и сообщения об ошибке прекрасно реализуются в одной первой форме.

 

Класс \IPS\Helpers\Wizard нужен если вы хотите выводить разные формы, в зависимости от выбора на предыдущем шаге или для формирования и обработки внешнего запроса, типа проверки телефонного номера посредством API СМС-сервиса, для ввода полученного по СМС ключа. Здесь же ничего такого не вижу в упор.

Поделиться сообщением


Ссылка на сообщение

Он симпотичней, на втором шаге пользователю выводятся данные которые он указал с form text disabled, на последнем шаге выводится код после сохранения данных уже в БД, этот код нужно ввести на сервере чтобы изменился статус подтверждения.

Поделиться сообщением


Ссылка на сообщение

Скажите еще вот что, здесь в форме указана ссылка: \IPS\Http\Url::internal( 'app=wc3&module=players&controller=players&do=form' ) я вывожу эту форму сейчас еще и во front, в принципе контроллеры и модули одинаковые, проблем не будет с этим? Или лучше использовать IPS\реквест > сетквери стринг? Ну чтобы адрес брался из запроса и добавлялось к нему просто form?

Поделиться сообщением


Ссылка на сообщение

Если адреса одинаковые то не будет.

Поделиться сообщением


Ссылка на сообщение

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.

×
×
  • Создать...