Node сохранение формы во внешнюю таблицу - Дизайн и модификация Invision Power Board

Перейти к содержимому

 

СвернутьПрикрепленные теги

Теги не найдены

Страница 1 из 1

Node сохранение формы во внешнюю таблицу

#1 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 24 Апрель 2019 - 10:20

Здравствуйте. имею две таблицы:

wc3_mapcfgs - основная для Node, используется для добавления, редактирования форм: http://prntscr.com/ng4iwq
wc3_mapcfgs_configuration - настройки, которые выбирает хост бот на C++: http://prntscr.com/ng4jbg

Задача: связать формы и добавление/изменение из них настроек в таблицу wc3_mapcfgs_configuration.

Я всё реализовал кроме сохранения и изменения настроек:

public function form( &$form )
{
	$form->add( new \IPS\Helpers\Form\Text( 'mapcfg_name', $this->mapcfg_name, TRUE, array(), NULL, NULL, NULL ) );
	$form->add( new \IPS\Helpers\Form\Node( 'map_id', isset($this->map_id) ? $this->map_id : NULL, TRUE, array( 'class' => 'IPS\wc3\Map' ) ) );
}

public function formatFormValues( $values )
{
	isset($values['map_id']) ? $values['map_id'] = $values['map_id']->_data['id'] : NULL;

	$this->updateAsSettings($values);

	return $values;
}

public function updateAsSettings( $values )
{
	if ( isset( $values['map_id'] ) )
	{
		$map = \IPS\wc3\Map::load( $values['map_id'] );

		$values['map_localpath'] = $map->_data['map_name'];
		$values['map_path'] = "Maps\\Download\\" . $map->_data['map_name'];

		unset($values['map_id']);
	}

	if ( isset( $values['mapcfg_name'] ) )
	{
		isset($values['mapcfg_name']) ? $cfg_name = $values['mapcfg_name'] : NULL;

		unset($values['mapcfg_name']);
	}
}


updateAsSettings() - функция, которая разбирает значения для сохранения, вставки в таблицу: wc3_mapcfgs_configuration

Два foreach, для обновления и вставки записей, оно работает всё в порядке:

foreach ($values as $key => $value) {
	\IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $value ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $key ) );
}

foreach ($values as $key => $value) {
	\IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $key, 'cfg_value' => $value ) );
}


Вопрос в следующем: Как правильно реализовать вставку, обновление полей?

Сообщение изменено: TemKa_SD (24 Апрель 2019 - 10:21)

0

#2 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 24 Апрель 2019 - 10:34

Сделал через $this->id

if ( !$this->id )
{
	foreach ($values as $key => $value) {
		\IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $key, 'cfg_value' => $value ) );
	}
} else {
	foreach ($values as $key => $value) {
		\IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $value ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $key ) );
	}
}


но оно мне не подходит, дело в том, что, весь конфиг я не хочу записывать, большая его часть использует стандартные значения в C++. Т.е там порядка 15 параметров, а для работы обязательных всего 2, это путь к карте и название карты.

Т.е если я запишу два параметра изначально из формы, потом когда захочу отредактировать её - будут редактироваться только старые параметры, которые, вставлялись через insert при создании $this->id, т.е это два параметра из 15. Нужно как-то проверять на наличие параметров во нешней таблице, которая НЕ используется формой.

Т.е нужна проверка если параметра нет - insert, иначе update и тут не учитывается $this->id. Помогите кодом плиз, это из формы же нужно делать? выборку.

Сообщение изменено: TemKa_SD (24 Апрель 2019 - 10:36)

0

#3 Пользователь не на сайте   siv1987 ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins Team
  • Сообщений: 9 446
  • Регистрация: 20-Март 09
  • Репутация: 2 546
  • IPB version:3.1.x
 

Отправлено 24 Апрель 2019 - 12:28

Цитата

Вопрос в следующем: Как правильно реализовать вставку, обновление полей?

Запросить в бд строку по этому условию, если оно имеется - обновлять. Если отсутствует - вставлять.
0

#4 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 25 Апрель 2019 - 09:47

Ну вот я сделал обновление:

foreach ( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) as $k )
{
	if ($k == key($values)) {
		foreach ($values as $key => $value) {
			$value ? \IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $value ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $key ) ) : NULL;
		}
	}
}


Как теперь вставить? Т.е как написать if foreach else insert.
0

#5 Пользователь не на сайте   siv1987 ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins Team
  • Сообщений: 9 446
  • Регистрация: 20-Март 09
  • Репутация: 2 546
  • IPB version:3.1.x
 

Отправлено 25 Апрель 2019 - 11:43

$result = \IPS\Db::i()->select( 'mapcfg_name', 'wc3_mapcfgs', array( 'mapcfg_name=?', $cfg_name ) );
if( $result->count() )
{
	foreach( $values as $k => $v )
	{
		\IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $v ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $k ) );
	}
}
else
{
	//INSERT wc3_mapcfgs
	//INSERT static::$cfgTable
}


Как-то так.
0

#6 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 25 Апрель 2019 - 12:19

Нет, это не то.

Давайте заново.

Сначала мне нужно выбрать текущие значения, которые есть в БД с where cfg_name = текущее сохраняемое имя конфига.

Т.е как в моем запросе:

foreach ( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) as $k )


Здесь я выбираю массив с текущими значениями: http://prntscr.com/ngnz7x т.е select cfg_key from static::$cfgTable where cfg_name=map1

Дальше сравниваем найденные значения в БД с теми, которые сохраняем в данный момент:

if ($k == key($values)) {


Т.е если КЛЮЧ в бд равен Ключу сохраняемого значения (map_localpath) то выполняем обновление, значит данные нужно обновить в этом поле а не вставить.
Иначе, нужно выполнить insert.

Т.е код рабочий, мне в него просто insert Нужно добавить ЗА foreach, так как если резульатов в нем не будет, внутри условия не будут выполнены.:

			foreach ( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) as $k )
			{
				if ($k == key($values)) {
					foreach ($values as $key => $value) {
						$value ? \IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $value ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $key ) ) : NULL;
					}
				}
			}

0

#7 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 25 Апрель 2019 - 12:35

Тест: Создаем конфиг: http://prntscr.com/ngo96s (правильно), добавляем в него новое значение (редактируем): http://prntscr.com/ngo9ic здесь вот добавились уже существующие значения и новое (не правильно), должно быть только новое значение.

$result = \IPS\Db::i()->select( 'mapcfg_name', 'wc3_mapcfgs', array( 'mapcfg_name=?', $cfg_name ) );
// Если конфиг уже существует, вы полняем условия.
if( $result->count() )
{	// Выбираем текущие значения ключи из БД
	foreach ( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) as $k )
	{	// Если ключ БД равен срхраняемому, выполняем обновление
		if ($k == key($values)) {
			foreach ($values as $key => $value) {
				$value ? \IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $value ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $key ) ) : NULL;
			}
		}
		// Иначе insert
		else {
			foreach ($values as $key => $value) {
				$value ? \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $key, 'cfg_value' => $value ) ) : NULL;
			}
		}
	}
}
// Если конфига нет, только создаем, записываем все данные.
else
{
	foreach ($values as $key => $value) {
		$value ? \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $key, 'cfg_value' => $value ) ) : NULL;
	}
}

Сообщение изменено: TemKa_SD (25 Апрель 2019 - 12:35)

0

#8 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 25 Апрель 2019 - 12:52

		if ( $this->id )
		{
			foreach ( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) as $k )
			{   // Если ключ БД равен срхраняемому, выполняем обновление
			    if ($k == key($values)) {
					foreach ($values as $key => $value) {
						$value ? \IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $value ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $key ) ) : NULL;
					}
			    }
			    // Иначе insert
			    else {
			    	// здесь должен быть insert, и вставленны те данные, еоторые не равны выше, которые не обновляются и вставляются.
			    }
			}
		} else {
			foreach ($values as $key => $value) {
				$value ? \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $key, 'cfg_value' => $value ) ) : NULL;
			}
		}


Вот так, только дописать insert.
0

#9 Пользователь не на сайте   siv1987 ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins Team
  • Сообщений: 9 446
  • Регистрация: 20-Март 09
  • Репутация: 2 546
  • IPB version:3.1.x
 

Отправлено 25 Апрель 2019 - 12:55

Обновлять нужно если в бд отсутствует такой ключ, а не если он чему-то равен. Ничего сравнивать, тем более таким образом не нужно.

$result = iterator_to_array( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) );
if( $result )
{
	$keys = array_map( function( $a ){ return $a['cfg_key']; }, $result );
	
	foreach( $values as $k => $v )
	{
		if( $v )
		{
			if( in_array( $k, $keys ) )
			{
				\IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $v ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $key ) );
			}
			else
			{
				\IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $k, 'cfg_value' => $v ) );
			}
		}
	}
}
else
{
	//INSERT mapеtable
	//INSERT static::$cfgTable
}

1

#10 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 25 Апрель 2019 - 13:14

Спасибо большое, работает!!!!!!!!!!

Добавил this->id

Исправил баг: return $a['cfg_key']; // здесь возвращалась строка, нужен массив.

Да, для меня это сложно еще, с array_map совсем не знаком.

Финальный код:
if ( $this->id )
{
	$result = iterator_to_array( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) );
	if( $result )
	{
	    $keys = array_map( function( $a ){
	    	return $a;
	    }, $result );

	    foreach( $values as $k => $v )
	    {
	        if( $v )
	        {
	            if( \in_array( $k, $keys ) )
	            {
	                \IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $v ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $k ) );
	            }
	            else
	            {
	                \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $k, 'cfg_value' => $v ) );
	            }
	        }
	    }
	}
} else {
	foreach ($values as $key => $value) {
		$value ? \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $key, 'cfg_value' => $value ) ) : NULL;
	}
}

0

#11 Пользователь не на сайте   siv1987 ответил: »

 
 
  • Advanced
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: IPB Skins Team
  • Сообщений: 9 446
  • Регистрация: 20-Март 09
  • Репутация: 2 546
  • IPB version:3.1.x
 

Отправлено 25 Апрель 2019 - 13:29

Просмотреть сообщениеTemKa_SD сказал(а):

Исправил баг: return $a['cfg_key']; // здесь возвращалась строка, нужен массив.

Это не баг. Его суть в том, чтобы из многомерного результат создать одномерный массив со всеми ключами. Только если выбирать одно поле в запросе, результат будет одномерный массив. Так что в принципе он здесь не нужен. Можете удалить. А в условие использовать in_array( $k, $result )
0

#12 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 25 Апрель 2019 - 14:39

		if ( $this->id )
		{
			$result = iterator_to_array( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) );
			if( $result )
			{
			    foreach( $values as $k => $v )
			    {
			        if( $v )
			        {
			            if( \in_array( $k, $result ) )
			            {
			                \IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $v ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $k ) );
			            }
			            else
			            {
			                \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $k, 'cfg_value' => $v ) );
			            }
			        }
			    }
			}
		} else {
			foreach ($values as $key => $value) {
				$value ? \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $key, 'cfg_value' => $value ) ) : NULL;
			}
		}


Верно?
0

#13 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 27 Апрель 2019 - 09:40

Здравствуйте. Я хочу удалить строку, если её значение 0. Т.е http://prntscr.com/nhi2k6 тут 0, я хочу удалить эту строку, так как 0 и так берется в приложении на C++ изначально, и хранить это в конфиге нет смысла, чище бд будет.

Во первых, здесь дописываю если значение не равняется NULL, чтобы проходили нули в проверку: http://prntscr.com/nhi2uu.

Вставляем условие в если id уже есть и если его еще нет. В моем случае 0 передает как строку, наверно потому что у меня в форме RADIO:

$form->add( new \IPS\Helpers\Form\Radio( 'map_loadingame', isset($settings['map_loadingame']) ? $settings['map_loadingame'] : 0, FALSE, array(
	'options' => array
	(
		0 => 'Загрузка карты с заставкой',
		1 => 'В игре'
	)
), NULL, NULL, NULL, 'map_loadingame' ) );


Где бы мне тут в форме указать что это int, не хочется делать новое условие для этого, лучше прям в форме?

public function updateAsSettings( $cfg_name, $settingValues )
{
	if ( $this->id )
	{
		$result = iterator_to_array( \IPS\Db::i()->select( 'cfg_key', static::$cfgTable, array( 'cfg_name=?', $cfg_name ) ) );
		if( $result )
		{
		    foreach( $settingValues as $k => $v )
		    {
				if ($v != '0')
				{
					if( \in_array( $k, $result ) )
					{
					    \IPS\Db::i()->update( static::$cfgTable, array( 'cfg_value' => $v ), array( 'cfg_name=? AND cfg_key=?', $cfg_name, $k ) );
					}
					else
					{
					    \IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $k, 'cfg_value' => $v ) );
					}
				}
				else
				{
					\IPS\Db::i()->delete( static::$cfgTable, array( 'cfg_name=? AND cfg_key=?', $cfg_name, $k ) );
				}
		    }
		}
	} else {
		foreach ($settingValues as $k => $v) {
			if ($v != '0')
			{
				\IPS\Db::i()->insert( static::$cfgTable, array( 'cfg_name' => $cfg_name, 'cfg_key' => $k, 'cfg_value' => $v ) );
			}
		}
	}
}


Вроде всё правильно?

P.S.: Для NULL тоже самое надо сделать, только я че-то не понял, почему оно так перестает вообще работать:

if ($v != '0' OR $v != NULL)


А так работает:

if ($v != '0' AND $v != NULL)


Условие должно выполнятся: Если V не равно 0 ИЛИ V не равно NULL. // Неужели я что-то не так думаю, сейчас оно должно искать оба параметра, т.е если V 0 и нулл тогда выполняется.

Сообщение изменено: TemKa_SD (27 Апрель 2019 - 10:15)

0

#14 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 27 Апрель 2019 - 10:38

Добавил, чтобы нельзя было редактировать имя конфига:

$this->mapcfg_name ? $disabled = TRUE : $disabled = FALSE;

$form->add( new \IPS\Helpers\Form\Text( 'mapcfg_name', isset($this->mapcfg_name) ? $this->mapcfg_name : NULL, TRUE, array( 'disabled' => $disabled ), NULL, NULL, NULL, 'mapcfg_name' ) );


Вроде всё правильно.
0

#15 Пользователь не на сайте   TemKa_SD ответил: »

 
 
  • Advanced
  • ***
  • Insert nick to fast reply form
  • Quote selected text to fast reply form
  • Группа: Пользователи
  • Сообщений: 614
  • Регистрация: 16-Январь 18
  • Репутация: 7
  • Откуда:Спасск-Дальний
  • IPB version:4.1.x
 

Отправлено 08 Июнь 2019 - 07:41

Здравствуйте. Переписываю сохранение настроек, хочу реализовать через ActiveRecord. Я сейчас напишу задачу и проблемы.

Начнем по порядку, допустим, я подключил форму и всё остальное, выглядит это так:

<?php

namespace IPS\wc3\Bot;

class _Settings extends \IPS\Patterns\ActiveRecord
{
	protected static $multitons;
	public static $databaseTable = 'wc3_bots_configuration';
	public static $databaseColumnId = 'cfg_botid';

	public function form( &$form )
	{
		$form->addTab( 'wc3_bots_settingsBot', 'cogs' );
		$form->add( new \IPS\Helpers\Form\Text( 'autohost_gamename' ));
	}
}


_Settings - через этот класс сохраняются настройки, проблема в том, что, значения полей - это данные в базе данных а не ячейки.

Выглядит это так: http://prntscr.com/nz4yhe

cfg_name = это id поля формы.
cfg_value = значение поля формы.

т.е нужно сделать что-то вроде такого:

if ( $values = $form->values() )
{
	foreach ($values as $key => $value) {
		$values['cfg_botid'] = 1;
		$values['cfg_name'] = $key;
		$values['cfg_value'] = $value;
	}
}


Какой самый правильный способ для реализации этой задачи?

Может как-то через $form->saveAsSettings(); переопределив таблицу сохранения?

Сообщение изменено: TemKa_SD (08 Июнь 2019 - 07:46)

0

Сообщить об этой теме:


Страница 1 из 1


Быстрый ответ

  

1 пользователей читают эту тему
0 зарегистрированных, 1 гостей, 0 скрытых


Контактная информация

Вопросы по работе сайта

+7 (917) 501-4765
C 10 до 20 в рабочие дни (время московское)

Техническая поддержка

Контактные данные специалистов

Дизайн форумов

IPB 3.x ¦ IPB 2.x

Бесплатные шаблоны

IPB 3.2 – 3.4 ¦ IPB 3.1 ¦ IPB 3.0 ¦ IPB 2.2 – 2.3 ¦ IPB 2.1 ¦ Клипарт
Лицензия на использование ¦ Ваша поддержка ¦ О проекте
Copyright © 2005-2019 IPBSkins.ru Team
При копировании материалов с сайта
прямая ссылка на источник обязательна