Jump to content

Preg Replace Callback Function Replacing Content Twice


ShoeLace1291

Recommended Posts

Ok, I wasn't sure what exactly to title this thread since it could be any number of factors causing this problem.... Anyway, I am trying to write a script for my custom CodeIgniter-powered forum that parses bbcodes... I almost have it working completely, except for one tiny problem... The content of the quote tags is being parsed twice... I cannot figure out why this is happening.  The header displays absolutely fine, it's just the content of the quote(or body) is doubled.  It could be the preg_replace_call_back, or just my poor coding structure... but I can't figure it out.  

 

This is my result:

 

4TbDuVw.gif

 

My String Helper:

 

<?php
 
function parse_bb($str){
        
        $CI =& get_instance();
        
        $str = nl2br($str);
        $str = strip_slashes($str);
        
        $find = array(
            "'\[b\](.*?)\[/b\]'is",
            "'\[i\](.*?)\[/i\]'is",
            "'\[u\](.*?)\[/u\]'is",
            "'\[s\](.*?)\[/s\]'is",
            "'\[img\](.*?)\[\/img\]'is",
            "'\[url\](.*?)\[/url\]'i",
            "'\[url=(.*?)\](.*?)\[/url\]'i",
            "'\[link\](.*?)\[/link\]'i",
            "'\[link=(.*?)\](.*?)\[/link\]'i",
            "'\[h1\](.*?)\[\/h1\]'is",
            "'\[h2\](.*?)\[\/h2\]'is",
            "'\[h3\](.*?)\[\/h3\]'is",
            "'\[ul\](.*?)\[\/ul\]'is",
            "'\[li\](.*?)\[\/li\]'is",
            "'\[p\](.*?)\[\/p\]'is"
            //"'(\[quote (thread_id|message_id)=([0-9]+)\](.*?)\[\/quote\])e'"
        );
        
        $replace = array(
            '<strong>\1</strong>',
            '<em>\1</em>',
            '<u>\1</u>',
            '<s>\1</s>',
            '<img src="\1" \1alt="User Image" />',
            anchor('\1'), //'<a href="\1">\1</a>',
            anchor('\1', '\2'), //'<a href="\1">\2</a>',
            '<a href="\1">\1</a>',
            '<a href="\1">\2</a>',
            '<h1>\1</h1>',
            '<h2>\1</h2>',
            '<h3>\1</h3>',
            '<ul>\1</ul>',
            '<li>\1</li>',
            '<p>\1</p>'
            //parse_quote('\2', '\3')
        );
 
        $str = preg_replace($find, $replace, $str);
                
                //var_dump($matches);
        
        $str = preg_replace_callback("^(\[quote (thread_id|message_id)=([0-9]+)\])^", 'parse_quote', $str);
        
        
        $str = preg_replace("^\[\/quote\]^", "\n</div>", $str);
        
        return $str;
 
    }
    
    function parse_quote($matches){
        
        $post_type = $matches[2];
        $post_id = $matches[3];
        
        $CI =& get_instance();
        
        if($post_type == "thread_id"){
                
                $CI->load->model('forums/thread');
                $CI->thread->get_info($post_id);
                if($CI->thread->error == NULL){
                        
                        $thread = $CI->thread->info;
                        
                        $str = "
                        <div class=\"quote\">
                
                                <div class=\"heading\">
                        
                                        <h1>Posted by ".$thread['author']['display_name']." about ".$thread['date_posted']." ago.</h1>
                                
                                </div>
                        
                                <div class=\"body\">
                                
                                        ".$thread['content_parsed']."
                                        
                                </div>
                                ";
                                
                } else {
                        
                        show_error($CI->thread->error);
                        
                }
                
        } else if($post_type == "message_id"){
             
                $CI->load->model('forums/message');
                
                $CI->message->get_info($post_id);
                if($CI->message->error == NULL){
                        
                        $message = $CI->message->info;
                        
                        $str = "
                        <div class=\"quote\">
                
                                <div class=\"heading\">
                        
                                        <h1>Posted by ".$message['author']['display_name']." about ".$message['date_posted']." ago.</h1>
                                
                                </div>
                        
                                <div class=\"body\">
                                
                                        ".$message['content_parsed']."
                                        
                                </div>
                                ";
 
                
                }
                
        }
        
        return $str;
 
    }
Model thread->get_info()

function get_info($thread_id){
        
        $this->db->select('board_id, thread_id, author_id, title, content, UNIX_TIMESTAMP(date_posted) AS date_posted, views, status, type');
        $this->db->from('forum_threads');
        $this->db->where('thread_id', $thread_id);
        $this->db->limit(1);
        
        if($query_thread = $this->db->get()){
            
            if($query_thread->num_rows() > 0){
                
                $thread = $query_thread->row_array();
                
                $this->member->get_info($thread['author_id']);
                $author = $this->member->info;
                
                $update = '';
                
                
                /* Get the total number of replies to this thread, excluding the first message. */
                $total_replies = 0;
                                        
                $this->db->select('thread_id, message_id');
                $this->db->from('forum_messages');
                $this->db->where('thread_id', $thread['thread_id']);
                        
                if($query_replies = $this->db->get()){
                            
                    $total_replies = $query_replies->num_rows();
                    
                }  
                
                $thread_update = "";
                /*Get the info of the thread's last message... */
               $this->db->select('thread_id, message_id, author_id, date_posted, date_modified');
               $this->db->from('forum_messages');
               $this->db->where('thread_id', $thread['thread_id']);
               $this->db->order_by('message_id', 'desc');
               $this->db->limit(1);
                    
                if($query_last_msg = $this->db->get()){
                
                    if($query_last_msg->num_rows() > 0){
                        
                        $last_msg = $query_last_msg->row_array();
                        
                        $this->member->get_info($last_msg['author_id']);
                        $author = $this->member->info;
                        
                        if($last_msg['date_modified']  == NULL){
                            
                            $update_time = $last_msg['date_posted'];
                            
                        } else {
                            
                            $update_time = $last_msg['date_modified'];
                            
                        }
                        
                        $thread_update = $author['member_profile'].' posted about '.timespan(strtotime($update_time), time()).' ago.';
                        
                    }
                    
                }
                
                $has_new_posts = FALSE;
                
                /* Determine whether or not there are new messages in this thread for the current user... */
                $this->db->select('mark_id, thread_id, member_id, UNIX_TIMESTAMP(date_marked) AS date_marked');
                $this->db->from('forum_thread_marks');
                $this->db->where('thread_id', $thread['thread_id']);
                $this->db->where('member_id', $this->user['id']);
                $this->db->order_by('date_marked', 'desc');
                $this->db->limit(1);
                
                if($query_mark = $this->db->get()){
                    
                    if($query_mark->num_rows() > 0){
                        
                        $mark = $query_mark->row_array();
                    
                        $this->db->select('message_id, thread_id, UNIX_TIMESTAMP(date_posted) AS date_posted');
                        $this->db->from('forum_messages');
                        $this->db->where('thread_id', $thread['thread_id']);
                        $this->db->where('date_posted > '.$mark['date_marked']);
                        
                        if($query_new = $this->db->get()){
                            
                            if($query_new->num_rows() > 0){
                                
                                $has_new_posts = TRUE;
                                
                            }
                            
                        }
                        
                    }
                    
                }
                
                /* Put it all together and we get... the array of information! */
                $info = array(
                    'id' => $thread['thread_id'],
                    'title' => $thread['title'],
                    'author' => $author,
                    'content' => $thread['content'],
                    'content_parsed' => parse_bb($thread['content']),
                    'date_posted' => timespan(strtotime($thread['date_posted']), time()),
                    'board_id' => $thread['board_id'],
                    'status' => $thread['status'],
                    'update' => $thread_update,
                    'reply_count' => $total_replies,
                    'view_count' => $thread['views'],
                    'uri' => 'forums/threads/'.url_title($thread['title']).'/'.$thread['thread_id'],
                    'actions' => $this->actions($thread['thread_id']),
                    'has_new_posts' => $has_new_posts
                );
                
            } else {
                
                $this->error = "The thread you have requested no longer exists in the database.";
            }
            
        } else {
            
            $this->error = "An error occurred while attempting to retrieve the data of the requested thread: ".$this->db->_error_message();
            
        }
        
        $this->info = $info;
        
    }
Model message->get_info()

function get_info($message_id){
        
        $this->db->select('message_id, thread_id, author_id, modifier_id, content, date_posted, date_modified');
        $this->db->where('message_id', $message_id);
        $this->db->limit(1);
        
        if($query = $this->db->get('forum_messages')){
            
            if($query->num_rows() > 0){
                
                $message = $query->row_array();
                
                $this->member->get_info($message['author_id']);
                $author = $this->member->info;
                
                $info = array(
                    'id' => $message['message_id'],
                    'thread_id' => $message['thread_id'],
                    'author' => $author,
                    'content' => $message['content'],
                    'content_parsed' => parse_bb($message['content']),
                    'date_posted' => timespan(strtotime($message['date_posted']), time()),
                    'actions' => $this->actions($message['message_id'])
                );
                
                if($message['modifier_id'] == NULL){
                    
                    $last_modified = '';
                    
                } else {
                    
                    $this->member->get_info($message['modifier_id']);
                    $modifier = $this->member->info;
                    
                    $modification = array(
                        'by' => $modifier,
                        'date' => $message['date_modified']
                    );
                    
                }
                
                $this->info = $info;
                
            } else {
                
                $this->error = "The message you are attempting to retrieve does not exist in the database.";
                
            }
            
        } else {
            
            $this->error = $this->db->_error_message();
            
        }
        
    }
Edited by ShoeLace1291
Link to comment
Share on other sites

I figure the markup looks like

[quote message_id=123]This is another test. This is only another test.[/quote]
Right?

 

When you replace the opening

you automatically include the content of the message/thread being looked up.

"<div class=\"body\">

".$thread['content_parsed']."

</div>"
However the message/thread content is already present in the source string, so you end up with markup (with comments added for clarity) like

<!-- [quote] -->
<div class="quote">
<div class="heading">
<h1>Posted by HigH VolTagE about 1 Week, 4 Days, 1 Hour, 8 Minutes ago.</h1>
</div>
<div class="body">
This is another test. This is only another rest.
</div>
<!-- end of [quote] -->

This is another test. This is only another rest.

<!-- [/quote] -->
</div>
<!-- end of [/quote]-->
Either

1. Do not include the contents of the message/thread during the parsing and instead add in strictly the HTML markup needed to make the quote. In other words,

<div class="quote">
<div class="heading">
<h1>Posted by * about * ago.</h1>
</div>
<div class="body">
This is how quoting is normally done.

 

2. Use

as a placeholder with no contents at all, and allow it to insert the quoted text automatically.

[quote message_id=123]
That's short and sweet but it has the significant downside that a poster cannot see what they're replying to.
Edited by requinix
Link to comment
Share on other sites

Your suggestion worked for one-level quotes, but the nested quotes are working almost the same way as before. The post body of the quote tag appears once per quote tag, but the whole quote tag(at the nested level) appears twice. Any ideas?

 

[quote message_id=10]
[quote message_id=9]
[/quote]
[/quote]
iDNnqc7.gif Edited by ShoeLace1291
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.