Перейти к контенту
  • 0

Баг в ресинхронизации тем?


arigoda

Вопрос

Коллеги, может кто знает, в чем логика именно такой работы функции ресинхронизации тем в админке?

Открываем /sources/lib/func_mod.php, функция rebuild_topic и видим:

$this->ipsclass->DB->do_update( 'topics', array( 
  'last_post'  => $last_post['post_date'] ? $last_post['post_date'] : $first_post['post_date'],
  'last_poster_id'	=> $last_post['author_id'] ? $last_post['author_id'] : $first_post['author_id'],
  'last_poster_name'  => $last_poster_name ? $last_poster_name : $first_poster_name,
...

таким образом, если у темы последний автор - гость, т.е. ID у него - нулевой - мы получаем на выходе в списке тем правильное имя автора ПОСЛЕДНЕГО сообщения, но с ссылкой на профиль автора ПЕРВОГО сообщения!

 

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

Ссылка на комментарий
Поделиться на других сайтах

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

  • 0
А у гостя может быть профиль?

В смысле?

Мне кажется, что тут просто проверка ID пользователя неактуальна.

Она бы была интересна в том случае, если бы учитывались права публикации сообщений в форуме, где находится тема для гостей.

Ссылка на комментарий
Поделиться на других сайтах

  • 0

GiV, у гостя, конечно же, нет никакого профиля - в таких случаях просто имя в ссылку не заворачивается, а отображается как простой текст

- ИМЯ_АВТОРА -

нехорошо то, что профиль с гостя идет на совершенно левого юзера. соответственно, в базе прописывается левый ID вместо нуля.

если я не совсем понятно объяснил как это выглядит - стукнись PM'ом, дам линк и доступ - посмотришь.

 

Мне кажется, что тут просто проверка ID пользователя неактуальна.

sM1Le, увы - актуальна.

тут же идет пересчет тем.

из ibf_posts выбираются сообщения по темам и выстраиваются в соответствии с принятой сортировкой подфорума.

после этого берется последний пост и по его данным обновляются записи в ibf_tables - last_poster_name, last_poster_date, last_poster_name...

как там без ID? по имени что ль искать? имя автора в ibf_posts - совершенно нерепрезентативно - оно вообще сейчас, кажется, нигде не используется, т.к. при выводе постов всегда определяется имя автора по ID в ibf_posts - чтоб не путались всякие display_name.

 

--

легко, конечно, поставить в проверке вместо

$last_post['author_id'] ?

что-нить типа

($last_post['author_id'] || $last_post['author_id']==0) ?

 

но просто стало вдруг интересно - что это за такие ситуации, когда вдруг надо данные последнего постера мешать с данными первого - вот и подумалось, что наверное единственная ситуация - если в теме только одно сообщение. ну и что? почему, собственно, в этом случае массив last_post должен вдруг оказаться пустым? вот, собственно, чаво и хотел спросить ;-)

Ссылка на комментарий
Поделиться на других сайтах

  • 0

arigoda, возможно, просто дополнительная проверка на пустое значение без учета того, что последнее сообщение в теме мог оставить гость.

 

Правда, я не совсем понял про твоё замечание.

Я имел в виду про неактуальность этой проверки:

'last_poster_id'	=> $last_post['author_id'] ? $last_post['author_id'] : $first_post['author_id'],

Я ведь не сказал, что до этого нужно убирать SQL-запросы на получение информации о первом и последнем сообщениях темы. Мне, например, достаточно трудно представить случай, когда при нормальном использование форума поле «last_poster_id» стало бы пустым. Хотя, здраво смотря на вещи, эта проверка включена для поля «last_poster_name» — чтобы не было каши.

 

Я думаю, что просто в своё время забыли учесть гостей.

Ссылка на комментарий
Поделиться на других сайтах

  • 0

там же.

видим:

//-----------------------------------------
// Get last post info
//-----------------------------------------
$this->ipsclass->DB->cache_add_query( 'mod_func_get_last_post', array( 'tid' => $tid, 'orderby' => $this->ipsclass->vars['post_order_column'] ) );
$this->ipsclass->DB->cache_exec_query();
$last_post = $this->ipsclass->DB->fetch_row();

$last_poster_name = $last_post['members_display_name'] ? $last_post['members_display_name'] : $last_post['author_name'];

нетрудно убедиться, что никакого поля members_display_name запрос mod_func_get_last_post никогда не возвратит - он обращается за инфой к таблице posts (ну и заодно - topics), так что даже захоти он вытащить отображаемое имя - не выйдет, нету там такого поля. есть в posts только author_name.

вопрос знатокам: какого лешего понадобилась проверка в последней строке?

 

кстати говоря, из такой проверочки следует еще один неутешительный вывод. если человек сменит свое отображаемое имя, то после ресинхронизации тем имя последнего автора опубликуется старым.

 

все потому, что author_name в posts - не меняется при смене имени и это, как уже было сказано выше, обычно ни на что не влияет - не используется это поле при выводе сообщений не-гостей.

а вот при ресинхронизации скрипт заботливо это старое имя вытащит и опубликует ;-)

 

---

кстати, чуть ниже идет Get first post info - и там все уже делается правильно.

 

--UPD--

ааа, ясно ;-) там тоже хотели использовать другой запрос, который запрашивает и members тоже, а потом забыли видать ;-)

---------------------------------

UPD

---------------

 

в общем, на скорую руку предлагаю пофиксить так.

sources/lib/func_mod.php, функция rebuild_topic

находим:

$this->ipsclass->DB->cache_add_query( 'mod_func_get_last_post', array( 'tid' => $tid, 'orderby' => $this->ipsclass->vars['post_order_column'] ) );

меняем на:

$this->ipsclass->DB->build_query( array( 'select'   => 'p.post_date, p.author_id, p.author_name, p.pid',
				'from'	 => array( 'posts' => 'p' ),
				'where'	=> "p.topic_id=$tid",
				'order'	=> "p.{$this->ipsclass->vars['post_order_column']} DESC",
				'limit'	=> array(0,1),
				'add_join' => array( 0 => array( 'select' => 'm.id, m.members_display_name',
										  'from'   => array( 'members' => 'm' ),
										  'where'  => "p.author_id=m.id",
										  'type'   => 'left' ) )
						)	  );

ниже в той же функции находим:

'last_poster_id'	=> $last_post['author_id'] ? $last_post['author_id'] : $first_post['author_id'],

меняем на

'last_poster_id'	=> ($last_post['author_id'] || $last_post['author_id']==0) ? $last_post['author_id'] : $first_post['author_id'],

 

по идее в функции два совершенно одинаковых запроса с джойнами, каждый из которых выбирает всего одну строчку. наверное можно все это как-то сделать одним запросом?

тут я, к сожалению, не силен...

Ссылка на комментарий
Поделиться на других сайтах

  • 0
Мне, например, достаточно трудно представить случай, когда при нормальном использование форума поле «last_poster_id» стало бы пустым.

например при удалении/переносе всех топиков из раздела.

Ссылка на комментарий
Поделиться на других сайтах

  • 0

ой-ой-ой, sM1Le, Song, позвольте вмешаться, ИМХО вы в другую степь ушли.

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

sM1Le, собственно этот скрипт вообще забивает на поля last_poster, starter - он их, собственно, и обновляет, что хорошо, потому что ресинхронизация после фикса этого бага убрала все созданные ранее ошибки.

 

просто сколько я ни смотрел - ну так и не понял, что же на самом деле за ситуация, когда запрос из posts окажется пустым. наверное это возможно только если база была наглым образом покорежена [кривыми ] руками и мы имеем совершенно пустую запись о теме вообще без постов.

но тогда упоминавшееся выше присвоение данных первого поста последнему все равно не имеет никакого смысла - первый-то запрос тоже будет пустым ;-)))

 

чем, собственно, отличается оригинальный запрос последнего поста? он похоже предназначен для обновления последнего поста форума, а не темы, ибо выдергивает еще и сведения, к какому форуму относится пост, что, согласитесь, мало интересно нам при поиске последнего сообщения в теме ;-) с другой стороны, он ничего не спрашивает из таблицы members и, как следствие, теоретически должен неправильно работать с отображаемыми именами, если они менялись.

Ссылка на комментарий
Поделиться на других сайтах

  • 0

много букав а ничего не понятно.

Давай так:

по идее в функции два совершенно одинаковых запроса с джойнами, каждый из которых выбирает всего одну строчку. наверное можно все это как-то сделать одним запросом?

давай оба напиши здесь

1... ..

2... ..

Ссылка на комментарий
Поделиться на других сайтах

  • 0

запросто ;-)

 

Нумер раз:

$this->ipsclass->DB->build_query( array( 
'select'   => 'p.post_date, p.author_id, p.author_name, p.pid',
'from'	 => array( 'posts' => 'p' ),
'where'	=> "p.topic_id=$tid",
'order'	=> "p.{$this->ipsclass->vars['post_order_column']} DESC",
'limit'	=> array(0,1),
'add_join' => array( 0 => array( 'select' => 'm.id, m.members_display_name',
'from'   => array( 'members' => 'm' ),
'where'  => "p.author_id=m.id",
'type'   => 'left' ) )
   )	  );

 

Нумер два:

$this->ipsclass->DB->build_query( array( 
'select'   => 'p.post_date, p.author_id, p.author_name, p.pid',
'from'	 => array( 'posts' => 'p' ),
'where'	=> "p.topic_id=$tid",
'order'	=> "p.{$this->ipsclass->vars['post_order_column']} ASC",
'limit'	=> array(0,1),
'add_join' => array( 0 => array( 'select' => 'm.id, m.members_display_name',
'from'   => array( 'members' => 'm' ),
'where'  => "p.author_id=m.id",
'type'   => 'left' ) )
   )	  );

Ссылка на комментарий
Поделиться на других сайтах

  • 0

Не, одним нельзя.

Только разве если только pid запросить.

Ссылка на комментарий
Поделиться на других сайтах

Присоединиться к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить на вопрос...

×   Вы вставили отформатированный текст.   Удалить форматирование

  Допустимо не более 75 смайлов.

×   Ваша ссылка была автоматически заменена на медиа-контент.   Отображать как ссылку

×   Ваши публикации восстановлены.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Зарузка...
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, вы соглашаетесь на использование файлов cookie, а также с нашим положением о конфиденциальности Политика конфиденциальности и пользовательским соглашением Условия использования.