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

Разделение ПОСТА


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

А вот есть в 2.0 такие возможности:

 

- склейка постов

- разделение темы

 

А можно реализовать такую опцию, как разделение поста на два поста, причем с возможностью выбора автора второй части.

 

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

 

Реализуемо?

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

Это видимо, чтобы пожставлять этого "второго автора". Типа разделил пост, оставил во второй части мат, потом предъявляешь "автору" его творение...

 

Я, честно говоря, тож не понимаю, зачем это надо...

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

Если реализуется то можно использовать этот мод и в другой цели - элементарное копирование постов.

 

Иногда бывает нужным.

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

Я объясню для чего это нужно.

 

Вот банальный пример для ДАННОГО сайта. В правилах сказано - "один вопрос - одна тема". Что если пользователь задал в тему ДВА вопроса. Причем предположим, что вопросы важные и нужные для истории, т.е. закрывать и удалять тему не хочется. Что делать? Вот я бы разделила этот пост и разнесла бы его части в разные темы. А так - приходится через phpmyadmin ковырять ibf_posts, а потом ребилд тем и форумов делать.

 

Доступно объясняю?

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

Мне бы тоже очень пригодилось. особенно для раздела "творчество".
Ссылка на комментарий
Поделиться на других сайтах

Anna

Вот банальный пример для ДАННОГО сайта. В правилах сказано - "один вопрос - одна тема". Что если пользователь задал в тему ДВА вопроса. Причем предположим, что вопросы важные и нужные для истории, т.е. закрывать и удалять тему не хочется. Что делать? Вот я бы разделила этот пост и разнесла бы его части в разные темы. А так - приходится через phpmyadmin ковырять ibf_posts, а потом ребилд тем и форумов делать.

 

А вооьбще и правда...щтука неаверно полезная...

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

Ну так что? Раз интерес есть, давайте подумаем. Я думаю, что основываясь на опции "Соединить посты", сделать "Разделить пост" будет не так сложно.

Кто-нить че-нить в таких вещах понимает?

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

  • 5 месяцев спустя...

Никто не прореагировал, поэтому решила написать сама.

Сегодня вроде закончила коддить. Коддер я начинающий, так что наверняка будут глюки. Через некоторое время выложу диффы.

Итак, модификация для разделения поста.

Назначение очевидно - смысл такой же как "разделить тему", только для поста. Модификация по смыслу и коду является обратной функции "объединить сообщения".

 

Понятия.

1. Первичный пост - выбранный для разделения пост

2. Вторичный пост - новый пост (с новым pid).

 

Модификация позволяет.

1. Свободно определять содержимой первичного и вторичного постов.

2. Свободно выбирать автора вторичного поста

3. Свободно выбирать положение вторичного поста относительно первичного (на минуту раньше или на минуту позже).

4. Управлять вложенными файлами (оставить в первичном, перенести во вторичный, удалить).

 

Особенности.

1. Вторичный пост создается в той же теме, что и первичный. Уже после этого вы можете делать с ним что хотите, например переместить в другую тему.

2. Для корректной реализации возможности размещения втричного поста ПЕРЕД первичным, необходимо в настройках админки (секция Posts,Polls,Topics) установить Post Order знаенчие Post date, иначе сортировка постов в теме будет по pid.

3. Для работы мода, надо выбрать в теме ОДИН постинг, а затем выбрать в падающем меню управления выбранными постами функцию "разделить один пост". Все поля появившеся формы являются обязательными.

 

установка

 

1. lang/*/lang_topic.php

 

// split post
'cpt_post_split' => "Разделить один пост",

 

2. lang/*/lang_mod.php

//split_post
'cm_master' => 'Оставить в первичном',
'cm_slave'  => 'Перенести во вторичный',
'split_master_title' => 'Первичный пост',
'split_slave_title' => 'Вторичный пост',
'split_before' => 'Перед первичным',
'split_after' => 'После первичного',
'split_title' => 'Разделение поста',
'split_master_author' => 'Автор первичного поста',
'split_slave_author' => 'Автор вторичного поста',
'split_master_date' => 'Дата первичного поста',
'split_slave_date' => 'Дата вторичного поста',
'split_master_post' => 'Содержание первичного поста',
'split_slave_post' => 'Содержание вторичного поста',
'split_attach' => 'Разнесение присоединенных файлов',
'split_submit' => 'Разделить пост',

 

3. Templates/Topic View/TableFooter

После

      <option value="merge">{ipb.lang['cpt_merge']}</option>

Добавить ниже

      <option value="post_split">{ipb.lang['cpt_post_split']}</option>

 

4. Templates/Moderator Function/

Добавить новый шаблон кнопкой: Add Template Bit

Name: uploadbox_post_split

Incoming Variables: $attach=""

  <tr>
	 <td width="1%" align="center"><select name="attach_{$attach['attach_id']}" class="dropdown"><option value="master">{ipb.lang['cm_master']}</option><option value="slave">{ipb.lang['cm_slave']}</option><option value="delete">{$ibforums->lang['cm_delete']}</option></select></td>
	 <td width="1%"><img src="{ipb.vars['mime_img']}/{$attach['image']}" alt="" /></td>
	 <td width="15%" nowrap="nowrap">{$attach['size']}</td>
	 <td width="95%"><a href="{ipb.script_url}act=Attach&type=post&id={$attach['attach_id']}" target="_blank"><b>{$attach['attach_file']}</b></a> #{$attach['attach_pid']}</td>
 </tr>

 

5. Templates/Moderator Function/

Добавить новый шаблон кнопкой: Add Template Bit

Name: user_pick_box

Incoming variables: $author

  <input name="user_pick" value="{$author}"><br />
 <input type="button" name="findusers" onclick="find_users()" value="{ipb.lang['find_user_names']}" />

 

6. Templates/Moderator Function/

Добавить новый шаблон кнопкой: Add Template Bit

Name: post_split_post_form

Incoming variables: $post="",$master_date="",$slave_date="",$author="",$auth_key="",$upload="",$user_pick=""

<form name="REPLIER" action="{ipb.script_url}act=mod&CODE=postchoice&tact=post_split&checked=1" method="post">
<input type="hidden" name="act" value="mod" />
<input type="hidden" name="selectedpids" value="{ipb.input['selectedpids']}" />
<input type="hidden" name="auth_key" value="{$auth_key}" />
<input type="hidden" name="t" value="{ipb.input['t']}" />
<input type="hidden" name="f" value="{ipb.input['f']}" />
<input type="hidden" name="st" value="{ipb.input['st']}" />

 <div class="borderwrap">
 <div class="maintitle">{ipb.lang['split_title']}</div>
	 <table cellspacing="1">
  	 <td colspan=2 align=center width="50%" class="row2"><b>{ipb.lang['split_master_title']}</b></td>
  	 <td colspan=2 align=center width="50%" class="row2"><b>{ipb.lang['split_slave_title']}</b></td>
   <tr>
  	 <td width="15%" class="row2"><b>{ipb.lang['split_master_date']}</b></td>
  	 <td width="35%" class="row2">{$master_date}</td>
  	 <td width="15%" class="row2"><b>{ipb.lang['split_slave_date']}</b></td>
  	 <td width="35%" class="row2"><select name="slave_date" class="dropdown">{$slave_date}</select></td>
   </tr>
   <tr>
  	 <td class="row2"><b>{ipb.lang['split_master_author']}</b></td>
  	 <td class="row2">{$author}</td>
  	 <td class="row2"><b>{ipb.lang['split_slave_author']}</b></td>
  	 <td class="row2">{$user_pick}
</td>
   </tr>
   <tr>
  	 <td class="row2" valign="top"><b>{ipb.lang['split_master_post']}</b></td>
  	 <td class="row2"><textarea cols="40" rows="20" name="Master" class="textarea">$post</textarea></td>
  	 <td class="row2" valign="top"><b>{ipb.lang['split_slave_post']}</b></td>
  	 <td class="row2"><textarea cols="40" rows="20" name="Slave" class="textarea"></textarea></td>
   </tr>
<if="upload != """>
<tr>
  	 <td class="row2" valign="top"><b>{ipb.lang['split_attach']}</b><div class="desc">{ipb.lang['cm_attach2']}</div></td>
  	 <td class="row2" colspan=3>
     <table cellspacing="1">
    	 $upload
     </table>
  	 </td>
   </tr>
</if>

	 </table>
	 <div class="formsubtitle" align="center"><input type="submit" value="{ipb.lang['split_submit']}" /></div>
 </div>
</form>

 

7. sources/moderate.php

Найти

	function multi_post_modify()

Найти далее

    case 'merge':
  	 $this->multi_merge_post();
  	 break;

 

Добавить ниже

    case 'post_split':
  	 $this->multi_post_split_post();
  	 break;

 

Найти

}

?>

 

ВЫШЕ добавить

 

--> см. следующий пост - исправленный вариант

 

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

 

Проблема по непонятным мне причинам решается заменой на $DB->do_update и $DB->do_insert соответственно. Странно, ведь в итоге тот же самый запрос подается... странно. Никто не знает почему так?

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

  • 1 месяц спустя...

Вот кину уже отмодифенный и оттестенный варинт функции - тут запросы сделаны стандартными функциями do_update и do_insert

 

	function multi_post_split_post()
{
 global $std, $ibforums, $DB, $print, $forums;
 
 //check moderate permissions
 $passed = 0;
 if ($ibforums->member['g_is_supmod'] == 1)
 {
	 $passed = 1;
 }
 else if ($this->moderator['delete_post'] == 1)
 {
	 $passed = 1;
 }
 else 
 {
	 $passed = 0;
 }
 
 if ($passed != 1) $this->moderate_error();
 

 //check selected pid
 if ( (! count( $this->pids )) or ( count($this->pids)>1 ) )
 {
	 $std->Error( array( 'LEVEL' => 1, 'MSG' => 'incorrect_use') );
 }

 
 //load post parsing lib
 require_once( ROOT_PATH.'sources/lib/post_parser.php' );
 $parser = new post_parser();
 

 //check a required action
 if ( ! $ibforums->input['checked'] )
 {
	 //-----------------------------------------
	 // Get post data
	 //-----------------------------------------
	 
	 $master_post = "";
	 $master_date = "";
	 $master_author = "";
	 $dropdown    = "";
	 $author      = "";
	 $seen_author = array();
	 $upload_html = "";
	 

	 //fetch post data
	 $DB->query("SELECT p.*, m.name as author_name, t.forum_id FROM ibf_posts p LEFT JOIN ibf_members m ON (p.author_id=m.id) LEFT JOIN ibf_topics t ON (p.topic_id=t.tid) WHERE pid='{$this->pids[0]}'");
	 $p = $DB->fetch_row();

	 if ( $std->check_perms( $forums->forum_by_id[ $p['forum_id'] ]['read_perms']) == TRUE )	
	 {
   $master_post = $parser->unconvert( trim($p['post']) );
   $master_date = $std->get_date( $p['post_date'], 'LONG');
   $dropdown = "<option value=0>".$ibforums->lang['split_before'].": ".$std->get_date($p['post_date']-60, 'LONG') ."</option><option value=1 selected>".$ibforums->lang['split_after'].": ".$std->get_date($p['post_date']+60, 'LONG') ."</option>";
   $master_author = $p['author_name'];
	 } else $this->moderate_error();

	 //fetch attachment info 	 
	 $DB->query("SELECT * FROM ibf_attachments WHERE attach_pid='{$this->pids[0]}'");
	 
	 while( $row = $DB->fetch_row() )
	 {
   $row['image'] = $ibforums->cache['attachtypes'][ $row['attach_ext'] ]['atype_img'];
   $row['size']  = $std->size_format( $row['attach_filesize'] );
   
   if ( strlen( $row['attach_file'] ) > 40 )
   {
  	 $row['attach_file'] = substr( $row['attach_file'], 0, 35 ) .'...';
   }
   
   $upload_html .= $this->html->uploadbox_post_split($row);
	 }
	 
	 //print our form 	 
	 $java_picker = <<<HTM
<script type="text/javascript">
<!--
function find_users(){
 url = "index.{$ibforums->vars['php_ext']}?act=legends&CODE=finduser_one&s={$ibforums->session_id}&entry=textarea&name=user_pick&sep=none";
 window.open(url,"FindUsers","width=400,height=250,resizable=yes,scrollbars=yes"); 
}
-->
</script>
HTM;
	 $user_pick = $java_picker.$this->html->user_pick_box($master_author);
	 $this->output .= $this->html->post_split_post_form( trim($master_post), $master_date, $dropdown, $master_author, $std->return_md5_check(), $upload_html, $user_pick );
	 
	 if ( $this->topic['tid'] )
	 {
   $this->nav[] = "<a href='{$ibforums->base_url}showtopic={$this->topic['tid']}'>{$this->topic['title']}</a>";
	 }
	 
	 $this->nav[]      = $ibforums->lang['split_title'];
	 
	 $this->page_title = $ibforums->lang['split_title'];
	 
	 $print->add_output( $this->output );
      	 $print->do_output( array( 'TITLE' => $this->page_title, 'JS' => 0, NAV => $this->nav ) );
 }
 else
 {
	 //start action here
	 $ibforums->input['slave_date'] = intval($ibforums->input['slave_date']);

	 //check for required values
	 if ( !( $ibforums->input['selectedpids'] and $ibforums->input['user_pick'] and $ibforums->input['Master'] and $ibforums->input['Slave']))
	 {
   $std->Error( array( 'LEVEL' => 1, 'MSG' => 'incorrect_use') );
	 }
	 
	 $Master = $parser->convert( array( 'TEXT'    => $ibforums->input['Master'],
           'SMILIES' => 1,
           'CODE'    => 1,
           'HTML'    => 0
           )      );

	 $Slave = $parser->convert( array( 'TEXT'    => $ibforums->input['Slave'],
           'SMILIES' => 1,
           'CODE'    => 1,
           'HTML'    => 0
           )      );
	 
	 //find required user for slave post
	 $DB->query("SELECT id, name FROM ibf_members WHERE LOWER(name)=LOWER('{$ibforums->input[user_pick]}')");
	 if (!$r=$DB->fetch_row())
	 {
   $std->Error( array( 'LEVEL' => 1, 'MSG' => 'incorrect_use') );
	 }
	 
	 //updating Master post 	 
	 $DB->do_update("posts", array('post' => $Master), "pid='{$this->pids[0]}'");

	 //insert Slave post
	 $DB->query("SELECT p.*, m.name as author_name, t.forum_id FROM ibf_posts p LEFT JOIN ibf_members m ON (p.author_id=m.id) LEFT JOIN ibf_topics t ON (p.topic_id=t.tid) WHERE pid='{$this->pids[0]}'");
	 $p = $DB->fetch_row();

	 $slave_date = $ibforums->input[slave_date] ? $p[post_date]+60 : $p[post_date]-60;
	 $slave_post_key = md5(time());

	 $DB->do_insert('posts', array('author_id' => $r[id], 
      	 'author_name' => $r[name], 
      	 'use_sig' => '1',
      	 'use_emo' => '1',
      	 'ip_address' => $p['ip_address'],
      	 'post_date' => $slave_date, 
      	 'post' => $Slave, 
      	 'topic_id' => $p[topic_id],
      	 'post_key' => $slave_post_key));
	 $slave_pid = $DB->get_insert_id();

	 //now fixxing attachments 	 
	 $attach_master = array();
	 $attach_slave = array();
	 $attach_kill = array();
	 
	 foreach ($ibforums->input as $key => $value)
	 {
   if ( preg_match( "/^attach_(\d+)$/", $key, $match ) )
   {
  	 if ( $ibforums->input[$match[0]] == 'master' )
  	 {
     //echo $key." - master";
     $attach_master[] = $match[1];
  	 } 
  	 else if ( $ibforums->input[$match[0]] == 'slave' )
  	 {
     //echo $key." - slave";
     $attach_slave[] = $match[1];
  	 }
  	 else if ( $ibforums->input[$match[0]] == 'delete' )
  	 {
     //echo $key." - delete";
     $attach_kill[] = $match[1];
  	 }
   }
	 }

 
	 //proceed Master attachments 	 
	 //... no any action needed :)

	 //proceed Slave attachments
	 if ( count( $attach_slave ) )
	 {
   //echo "<br>proceed slave...<br>";
   //echo "slave_pid: ".$slave_pid."<br>";
   //echo "slave_post_key: ".$slave_post_key."<br>";
   //echo "slave member id: ".$r[id]."<br>";
   //echo "attach ids: ".implode(",",$attach_slave)."<br>";
   $DB->do_update( 'attachments',
       array( 'attach_pid' => $slave_pid, 'attach_post_key' => $slave_post_key, 'attach_member_id' => $r[id] ),
       'attach_id IN('.implode(",",$attach_slave).')' );
	 }
	 
	 //proceed Kill attachments
	 if ( count( $attach_kill ) )
	 {
   $DB->simple_construct( array( "select" => '*', 'from' => 'attachments',  'where' => 'attach_id IN('.implode(",",$attach_kill).')') );
   $DB->simple_exec();
   
   while ( $killmeh = $DB->fetch_row() )
   {
  	 if ( $killmeh['attach_location'] )
  	 {
     @unlink( $ibforums->vars['upload_dir']."/".$killmeh['attach_location'] );
  	 }
  	 if ( $killmeh['attach_thumb_location'] )
  	 {
     @unlink( $ibforums->vars['upload_dir']."/".$killmeh['attach_thumb_location'] );
  	 }
   }
   
   $DB->simple_construct( array( 'delete' => 'attachments', 'where' => 'attach_id IN('.implode(",",$attach_kill).')' ) );
   $DB->simple_exec();
	 }

	 //recount stats
	 $this->modfunc->rebuild_topic($p[topic_id], 0);
	 $this->modfunc->forum_recount($p[forum_id]);
	 $this->modfunc->stats_recount();

	 //log
	 $this->moderate_log("Split post: Master #{$this->pids[0]}, Slave #{$slave_pid}");

 }
}

 

Огромное спасибо Dr.Freddy за исправления по вышеуказанной функции, а так же нижеследующие дополнения-исправления.

 

в файле sources/lib/modfunctions.php в функции rebuild_topic правим:

  //-----------------------------------------
 // Get first post info
 //-----------------------------------------
 
 $DB->simple_construct( array( 'select' => 'post_date, author_id, author_name, pid',
          'from'   => 'posts',
          'where'  => "topic_id=$tid",
          'order'  => 'pid ASC',
          'limit'  => array(0,1) ) );
 $DB->simple_exec();

 

ИЗМЕНИТЬ на:

 

 //-----------------------------------------
// Get first post info
//-----------------------------------------

$DB->simple_construct( array( 'select' => 'post_date, author_id, author_name, pid',
         'from'   => 'posts',
         'where'  => "topic_id=$tid",
         'order'  => 'post_date ASC',
         'limit'  => array(0,1) ) );
$DB->simple_exec();

 

Далее - модифицируем функцию mod_func_get_last_post в файле:

sources/sql/mysql_queries.php

 

  return "SELECT p.post_date, p.topic_id, p.author_id, p.author_name, p.pid, t.forum_id
   FROM ".SQL_PREFIX."posts p
    LEFT JOIN ".SQL_PREFIX."topics t ON (p.topic_id=t.tid)
   WHERE topic_id={$a['tid']} and queued=0
   ORDER BY pid DESC LIMIT 0,1";

 

ЗАМЕНИТЬ на:

return "SELECT p.post_date, p.topic_id, p.author_id, p.author_name, p.pid, t.forum_id
 FROM ".SQL_PREFIX."posts p
  LEFT JOIN ".SQL_PREFIX."topics t ON (p.topic_id=t.tid)
 WHERE topic_id={$a['tid']} and queued=0
 ORDER BY post_date DESC LIMIT 0,1";

 

и такую же функцию mod_func_get_last_post в файле:

sources/sql/mysql_admin_quries.php

 

  return "SELECT p.post_date, p.topic_id, p.author_id, p.author_name, p.pid, t.forum_id
   FROM ".SQL_PREFIX."posts p
    LEFT JOIN ".SQL_PREFIX."topics t ON (p.topic_id=t.tid)
   WHERE topic_id={$a['tid']} and queued <> 1
   ORDER BY pid DESC LIMIT 0,1";

 

ЗАМЕНИТЬ на:

  return "SELECT p.post_date, p.topic_id, p.author_id, p.author_name, p.pid, t.forum_id
	 FROM ".SQL_PREFIX."posts p
	 LEFT JOIN ".SQL_PREFIX."topics t ON (p.topic_id=t.tid)
	 WHERE topic_id={$a['tid']} and queued <> 1
	 ORDER BY post_date DESC LIMIT 0,1";

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

  • 2 недели спустя...

Установил модификацию. При попытке разделения выбранного единичного сообщения открывается форма следующего вида.

 

Anna, вы забыли указать входные параметры для бита post_split_post_form.

$post, $master_date, $slave_date, $author, $auth_key, $upload, $user_pick

Всё верно?

 

При частой распилке неудобно каждый раз прописывать имя посетителя, которому будет принадлежать вторичный пост. Поэтому в moderate.php строчку

$user_pick = $java_picker.$this->html->user_pick_box();

меняем на

$user_pick = $java_picker.$this->html->user_pick_box([b]$master_author[/b]);

В шаблоне user_pick_box прописываем incoming bit variable: $author, а весь шаблон заменяем на:

<input name="user_pick" [b]value="{$author}"[/b]><br />
<input type="button" name="findusers" onclick="find_users()" value="{ipb.lang['find_user_names']}" />

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

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

Да, совершенно верно.

Эти изменения я внесла в свои посты выше. Большое спасибо за правки и дополнения.

:D

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

Ещё один фикс. Во вторичном сообщении не проставлялся IP-адрес постера.

 

В multi_post_split_post() дополняем запрос на вставку slave post:

$DB->do_insert('posts', array('author_id' => $r[id],
       'author_name' => $r[name],
       'use_sig' => '1',
       'use_emo' => '1',
       [b]'ip_address' => $p['ip_address'],[/b]
       'post_date' => $slave_date,
       'post' => $Slave,
       'topic_id' => $p[topic_id],
       'post_key' => $slave_post_key));

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

Большое спасибо за фикс и интерес к моду.

 

По поводу переноса в архив - если до завтра еще никаких багов не найдешь - конечно выложу в архив :D

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

Хм... После разделения поста время последнего обновления темы становится временем появления первичного поста (плюс-минус одна минута, в зависимости от того, как разделили). Если это старый пост, тема, естественно, скатывается вниз по списку.

 

Это правильно только в том случае, если пост находится в самом конце. А так берем большую тему, разрезаем пост в начале и наблюдаем, что последний раз в тему постили полгода назад и она уже успела «утонуть» на несколько страниц. :D

 

Расследование установило: вызываемая в самом конце функции multi_post_split_post функция rebuild_topic для получения сведений о последнем посте и его постере юзает функцию mod_func_get_last_post (из sources/sql/mysql_queries.php), которая вытаскивает последний пост не по времени, а по его ID. Поскольку ID slave post однозначно больше, чем ID реального последнего поста в теме, запрос именно его и возвращает.

 

В общем, если изменить запрос вот так:

  return "SELECT p.post_date, p.topic_id, p.author_id, p.author_name, p.pid, t.forum_id
   FROM ".SQL_PREFIX."posts p
    LEFT JOIN ".SQL_PREFIX."topics t ON (p.topic_id=t.tid)
   WHERE topic_id={$a['tid']} and queued=0
   ORDER BY [b]post_date[/b] DESC LIMIT 0,1";

... то всё работает правильно. По крайней мере глюков пока не вижу.

 

Не знаю, правда, не поломалось ли от этого что-нибудь не относящееся к сабжу. Позже будет ясно. ;)

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

гм. странно как....

мне кажется на этот запрос должна влиять переключалка из админки: ID Или дата поста.

 

Надо проверить где еще используется функция mod_func_get_last_post()

быть может есть какие-то архиважные вызовы.... :D

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

У меня сортируется по дате поста.

 

Смотрим modfunctions.php:

function rebuild_topic($tid, $doforum=1)

[i]<skipped>[/i]

 //-----------------------------------------
 // Get last post info
 //-----------------------------------------

 $DB->cache_add_query( 'mod_func_get_last_post', array( 'tid' => $tid ) );
 $DB->cache_exec_query();

 $last_post = $DB->fetch_row();

[i]<skipped>[/i]

 //-----------------------------------------
 // Update topic
 //-----------------------------------------

 $DB->do_update( 'topics', array( [b]'last_post'         => $last_post['post_date'],
          'last_poster_id'    => $last_post['author_id'],
          'last_poster_name'  => $last_post['author_name'],[/b]
          'topic_queuedposts' => $qpcount,
          'posts'             => $pcount,
          'starter_id'        => $first_post['author_id'],
          'starter_name'      => $first_post['author_name'],
          'start_date'        => $first_post['post_date'],
          'topic_firstpost'   => $first_post['pid'],
          'topic_hasattach'   => intval($attach['count'])
           ), 'tid='.$tid );

Никаких проверок на настройки там нет.

 

Порылся в движке. mod_func_get_last_post используется только в функции rebuild_topic и более нигде. ;) Так что поводов для опасений нет.

 

Найдена ещё одна бага — бага разделения первого поста топика. Если при разделении выбрать размещение вторичного поста перед первичным, у нас меняется инициирующий пост темы. Учитывая то, что автора этого поста мод может изменить, нам нужно проапдейтить rebuild_topic, чтобы он получал первый пост не по pid, а по post_date.

 

Правится вот так:

  //-----------------------------------------
 // Get first post info
 //-----------------------------------------

 $DB->simple_construct( array( 'select' => 'post_date, author_id, author_name, pid',
          'from'   => 'posts',
          'where'  => "topic_id=$tid",
          'order'  => '[b]post_date[/b] ASC',
          'limit'  => array(0,1) ) );
 $DB->simple_exec();

Больше глюков пока не нашёл. Думаю, можно выкладывать. :)

 

Кстати. При поиске mod_func_get_last_post обнаружил её клона (с тем же именем и тем же содержанием) в файле mysql_admin_queries.php :D Честно порылся, но так и не понял, зачем она там нужна. На всякий случай переставил сортировку с pid на post_date и там, хотя, думаю, это необязательно.

 

В принципе, я так подумал — имхо, настройка в админпанели сортировки постов в топиках на rebuild_topic влиять и не должна. Порядок постингов стандартными механизмами 2.0.x сменить нельзя, так что у программистов было два равнозначных варианта — получить последний пост либо по времени, либо по его идентификатору. Они получили по идентификатору, откуда им было знать, что ты напишешь эту модификацию :)

 

Так что, имхо, всё в порядке.

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

Значит, как я понимаю, предлагается изменить в mysql_queries функцию mod_func_get_last_post вот так:

 

return "SELECT p.post_date, p.topic_id, p.author_id, p.author_name, p.pid, t.forum_id
  FROM ".SQL_PREFIX."posts p
   LEFT JOIN ".SQL_PREFIX."topics t ON (p.topic_id=t.tid)
  WHERE topic_id={$a['tid']} and queued=0
  ORDER BY post_date DESC LIMIT 0,1";

 

аналогично сделать в mysql_admin_quries и еще...

 

вот это в каком месте предлагается добавить/изменить не совсем вникла (поздно уже спать хочу) :D

 

Правится вот так:
  //-----------------------------------------
 // Get first post info
 //-----------------------------------------

 $DB->simple_construct( array( 'select' => 'post_date, author_id, author_name, pid',
          'from'   => 'posts',
          'where'  => "topic_id=$tid",
          'order'  => '[b]post_date[/b] ASC',
          'limit'  => array(0,1) ) );
 $DB->simple_exec();

Больше глюков пока не нашёл. Думаю, можно выкладывать. ;)

 

 

верно? я правильно понимаю?

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

Как интересно :D Шарил бы я в РНР на необходимом уровне так бы и сам помог... ;) Мод реально полезный, на любом форуме рано или позно пригодится
Ссылка на комментарий
Поделиться на других сайтах

pid - это первичный ключ. Имейте ввиду, что по нему сортировка выполняется быстрее чем по post_date !
Ссылка на комментарий
Поделиться на других сайтах

вот это в каком месте предлагается добавить/изменить не совсем вникла
Anna, это нужно исправить в той самой rebuild_topic() из modfunctions.php. Она выполняет апдейт информации о топике в ibf_topics, в процессе определяет первый и последний посты. Из-за того, что она определяет их по pid'у, и возникла проблема. :D

 

Song, да, но я ни вижу другого выхода в данном случае. Я думал насчет написать два запроса на получения последнего поста (и вызывать получающий по post_date только в случае вызова rebuild_topics из разделялки), но даже просто переключая сортировку с ID поста на дату поста в админке, мы уже сбрасываем скорости с форума.

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

подожди.

 

Т.к. по умолчанию сортировка по pid. Т.е. получается что вторая часть разделённого сообщения появляется "где-то" а не сразу за тем от которого отделили? В этом проблема?

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

Anna, это нужно исправить в той самой rebuild_topic() из modfunctions.php. Она выполняет апдейт информации о топике в ibf_topics, в процессе определяет первый и последний посты. Из-за того, что она определяет их по pid'у, и возникла проблема. :D

 

Song, да, но я ни вижу другого выхода в данном случае. Я думал насчет написать два запроса на получения последнего поста (и вызывать получающий по post_date только в случае вызова rebuild_topics из разделялки), но даже просто переключая сортировку с ID поста на дату поста в админке, мы уже сбрасываем скорости с форума.

 

Изменения в инструкцию я внесла - проверь корректность пожалуйста.

Жду с нетерпением очередных багрепортов ;)

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

Song, да, примерно так. Модификация, «разделяя» сообщение, просто предлагает удобный интерфейс для добавления поста в тему — устанавливая время его постинга за минуту до «разделяемого» поста или через минуту после. Таким образом, «по идее», в топике он должен располагаться непосредственно перед или сразу после «разделённого» сообщения.

 

Глобальную идиллию ;) портит то, что создаваемый пост всегда будет иметь pid однозначно больший, чем любой пост в топике и, как итог, при pid-сортировке станет последним постом в топике вне зависимости от того, какой давности пост был «разделён».

 

Если включить сортировку по Post Date, посты начинают размещаться «правильно» и проблема остаётся только в получении первого и последнего поста в топике.

 

Anna, mod_func_get_last_post в sources/sql/mysql_admin_quries.php отличается от своего собрата по синтаксису — по твоей квоте её не найдут. Вот запрос:

return "SELECT p.post_date, p.topic_id, p.author_id, p.author_name, p.pid, t.forum_id
   FROM ".SQL_PREFIX."posts p
    LEFT JOIN ".SQL_PREFIX."topics t ON (p.topic_id=t.tid)
   WHERE topic_id={$a['tid']} and [b]queued <> 1[/b]
   ORDER BY post_date DESC LIMIT 0,1";
}

Т.е. логика «пост не скрыт» по-другому записана.

 

Хотя это неважно, название функции есть и конечный вариант есть. Всё остальное правильно. :D

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

Ну тогда просто введите ещё одно поле.

И сортировать не только по pid, а ещё по нему.

Например поле назвать sort. И устанавливать его в в 1, если это следующее разделённое сообщение. В 2-ку, если если одно разделённое уже есть и т.д.

 

И далее:

 

... ORDER BY p.pid,p.sort

[1124081317:1124081549]А чтобы стартующее сообщение было первым нужно соответственно:

... ORDER BY p.new_topic DESC, p.post_date

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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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

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

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