Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Okay so I'm trying to create a wordpress shortcode called chapter, i.e. [chapter]text[/chapter].

What this does is it first checks if the content entered is already in the database, if it's not it will add it to the database and will also add a count to another table. Then it outputs this in a div

This is the code I have

function chapters( $atts, $content ) {
    $postid = get_post($my_id);

    $result_chaptertitle = mysql_query("SELECT * FROM ltd_chapters_titles WHERE chaptertitle='$content' AND postid='$postid'");
    $num_rows_chaptertitle = mysql_num_rows($result_chaptertitle);

    $result_chaptercount = mysql_query("SELECT * FROM ltd_chapters WHERE postid='$postid'");
    $num_rows_chaptercount = mysql_num_rows($result_chaptercount);

    if ($num_rows_chaptertitle == 0) {
        mysql_query("INSERT INTO ltd_chapters_titles (postid, chaptertitle) VALUES ('$postid','$content')");
    }

    if ($num_rows_chaptercount == 0) {
        mysql_query("INSERT INTO ltd_chapters (postid, chapter) VALUES ('$postid', 1)");
    } else {
        mysql_query("UPDATE ltd_chapters SET chapter=chapter+1 WHERE postid='$postid'");
    }

    $chaptercount = mysql_query("SELECT chapter FROM table WHERE postid='$postid'");

    mysql_query("UPDATE ltd_chapters SET count='$chaptercount' WHERE postid='$postid' AND chaptertitle='$content'");

    return '<div id="chapter'.$chaptercount.'"><h3>'.$content.'</h3></div>';

}
add_shortcode('chapter', 'chapters');

When I apply this in a post, the entire content of the post doesn't show up on the page and everything afterwards isn't rendered as well (so no footer etc.) However the div that the the_content(); is in is closed of like it should though

Can anyone offer me any insight into what I have been doing wrong? I'm pretty new to PHP

share|improve this question
add comment

2 Answers

Is the $my_id variable supposed to come from an attribute on the shortcode? E.g. [chapter my_id="123"]Lorum ipsum...[/chapter]

If so, at the beginning of your chapters() function, you need to retrieve the attributes out of the array being passed in. Something like:

extract( shortcode_atts( array(
    'foo' => 'something',
    'bar' => 'something else',
), $atts ) );

The values in that array are defaults which can be set if the keys don't exist in your $attr (which comes from the shortcode tag in your content).

Otherwise, we need to know more about where $my_id is getting set in the first place. If you're just trying to get the post ID of the current post that contains the shortcode, then maybe try this:

global $post;
$my_id = $post->ID;

Lastly, just as a best-practice, instead of directly calling MySQL functions, you might want to read up on the $wpdb interface, and use the core database access functions. It will help your code stay future-proof.

share|improve this answer
    
Hey there, I've copy pasted the get_post($my_id); from the WP codex site to get the ID of the post. I thought that this would then store the ID of the post into the $postid variable. Is that any help? –  Jiri Krewinkel Jul 6 '12 at 17:01
    
Give TheDeadMedic's code a try and see if it works for you. It's what I was suggesting to do. –  Dougal Campbell Jul 6 '12 at 18:38
add comment
  • No variable $my_id on line [3], $postid will default to the current post object
  • Unescaped data in queries, likely to fail
  • Use of object $postid as string, typically fatal error

I hope the code will speak for itself, but I highly recommend you improve your understanding of both WordPress & PHP - check out the manuals, read blogs, get a book if it suits!

function chapters( $atts, $content )
{
    // We need access to some variables outside the function, so globalise them.
    global $wpdb, $post;

    $chapter_title = $wpdb->get_row(
        $wpdb->prepare(
            'SELECT * FROM ltd_chapters_titles WHERE chaptertitle = %s AND postid= %d',
            $content, $post->ID
        )
    );

    if ( ! $chapter_title ) {
        // Make use of all the handy methods $wpdb has to offer!
        $wpdb->insert( 'ltd_chapters_titles',
            array( 'chaptertitle' => $content, 'postid' => $post->ID ),
            array( '%s', '%d' )
        );
    }

    // For sanity to inject straight into string rather than prepare()
    $post_id = absint( $post->ID );

    if ( $wpdb->get_var( "SELECT postid FROM ltd_chapters WHERE postid = $post_id" ) ) {
        $wpdb->query( "UPDATE ltd_chapters SET chapter=chapter+1 WHERE postid = $postid" );
    } else {
        $wpdb->insert( 'ltd_chapters',
            array( 'chapter' => 1, 'postid' => $post->ID ),
            array( '%d', '%d' )
        );
    }

    $chapter = $wpdb->get_var( "SELECT chapter FROM ltd_chapters WHERE postid = $post_id" );
    $wpdb->update( 'ltd_chapters',
        array( 'count', $count ),
        array( 'postid' => $post_id ),
        '%s',
        '%d'
    );

    return sprintf( '<div id="chapter%d"<h3>%s</h3></div>', $chapter, $content );
}

Have faith, and don't give up!

share|improve this answer
    
That was amazing! After a lot of hard work and with the help of this code I have finally successfully added the feature. I have just been learning PHP since the past week, this was my first real own project; your code really helped me understand some of the concepts, thanks again –  Jiri Krewinkel Jul 6 '12 at 19:32
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.