Jump to content
Дизайн и модификация IPS Community IPBSkinsBETA
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
TemKa_SD

$form и \IPS\Patterns\ActiveRecord

Recommended Posts

Здравствуйте. Делаю новую форму для контроллеров, которые есть в админке и фронте. Класс реализован с помощью \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. На втором шаге мне нужно реализовать две кнопки, вернутся на предыдущий шаг и продолжить, как добавить вторую?

Edited by TemKa_SD

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Помогите пожалуйста, я часов 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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

 

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

Edited by TemKa_SD

Share this post


Link to post
Share on other sites

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

 

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

Share this post


Link to post
Share on other sites

Я добавлял, сегодня добавил уже полноценные поля, они в принципе там нужны тоже, только без обновления, только для чтения. Я всё сделал правильно, но оно не хочет работать, я этот код вдоль и поперек перекопал, на 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
	);
}

Share this post


Link to post
Share on other sites
Потому что тут пустота:

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

 

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

Нужно не копать, а смотреть, как работает 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' ] );
			}

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

Share this post


Link to post
Share on other sites

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

 

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

Edited by TemKa_SD

Share this post


Link to post
Share on other sites

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' ]);

 

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

Edited by TemKa_SD

Share this post


Link to post
Share on other sites

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

 

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...