• Resolved Dot22

    (@dot22)


    Hello! Sorry me for my bad English but isn’t my native language so I’ll do as best as possible to explain my problem.

    I’ve this code to give the users the front-end option to order a batch of posts by different criteria…

    <?php
      $order = "&orderby=title&order=ASC";
      if ($_POST['select'] == 'titleasc') { $order = "&orderby=title&order=ASC";  }
      if ($_POST['select'] == 'titledesc') { $order = "&orderby=title&order=DESC";  }
      if ($_POST['select'] == 'autorasc') { $order = "&post_type=catit&meta_key=autor&orderby=meta_value&order=ASC";  }
      if ($_POST['select'] == 'autordesc') { $order = "&post_type=catit&meta_key=autor&orderby=meta_value&order=DESC";  }
      if ($_POST['select'] == 'codasc') { $order = "&post_type=catit&meta_key=codigo&orderby=meta_value&order=ASC";  }
      if ($_POST['select'] == 'coddesc') { $order = "&post_type=catit&meta_key=codigo&orderby=meta_value&order=DESC";  }
      if ($_POST['select'] == 'datenew') { $order = "&orderby=date&order=DESC";  }
      if ($_POST['select'] == 'dateold') { $order = "&orderby=date&order=ASC";  }
    ?>
    <form method="post" id="order">
      Ordenar:
      <select name="select" onchange='this.form.submit()'>
        <option value="titleasc"<?php selected( $_POST['select'],'titleasc', 1 ); ?>>Título AZ</option>
        <option value="titledesc"<?php selected( $_POST['select'],'titledesc', 1 ); ?>>Título ZA</option>
        <option value="autorasc"<?php selected( $_POST['select'],'autorasc', 1 ); ?>>Autor AZ</option>
        <option value="autordesc"<?php selected( $_POST['select'],'autordesc', 1 ); ?>>Autor ZA</option>
        <option value="codasc"<?php selected( $_POST['select'],'codasc', 1 ); ?>>Código</option>
        <option value="coddesc"<?php selected( $_POST['select'],'coddesc', 1 ); ?>>Código</option>
        <option value="datenew"<?php selected( $_POST['select'],'datenew', 1 ); ?>>Más recientes</option>
        <option value="dateold"<?php selected( $_POST['select'],'dateold', 1 ); ?>>Más antiguos</option>
      </select>
    </form>
    <br />
    <?php query_posts($query_string . '&posts_per_page=40' . $order ); ?>
    <?php
    // Start the Loop.
    while ( have_posts() ) : the_post(); ?>

    It works, but only on first page. When I click on page 2, 3 the order is “reset”. Is there any way to maintain the order chosen by user on all the pages? Thanks in advance! 🙂

    • This topic was modified 6 years, 2 months ago by Dot22.
Viewing 12 replies - 1 through 12 (of 12 total)
  • Hello there,

    You are setting the order with the POST variable. But when a user clicks on a navigation link, no form is being posted so you lose the POSTed information. What you may want to do is use the $_REQUEST array instead of $POST (http://php.net/manual/en/reserved.variables.request.php). This gives you access to $_POST and $_GET variables. Then, you will also want to add the chose ‘select’ option to your navigation links so it is passed in the query string. So a user would be hitting an address like:

    http://your.wordpress.site/page/2/?select=titleasc

    If the page links are being generated using WordPress’s pagination functions, you can add arguments by passing an array to the add_args parameter as explained here:

    https://codex.wordpress.org/Function_Reference/paginate_links

    So it might look something like:

    
    // Previous/next page navigation.
    $nav_arguments = array(
    	'prev_text'          => __( 'Previous page', 'twentyfifteen' ),
    	'next_text'          => __( 'Next page', 'twentyfifteen' ),
    	'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'twentyfifteen' ) . ' </span>',
    	'add_args'           => array(
    		'select' => $_REQUEST['select']
    	)
    );
    
    the_posts_pagination( $nav_arguments );
    

    When accepting information from a user, you will also want to look into sanitizing it so they don’t alter it and put something malicious in the data. Check out:

    https://developer.wordpress.org/reference/functions/sanitize_text_field/

    At the top of your code, you could do something like this:

    
    if( ! empty( $_REQUEST['select'] ) ) {
    	$select = sanitize_text_field( $_REQUEST['select'] );
    }
    

    and then use $select for your variable for the user’s selected order.

    I hope this helps!
    Scott

    Thread Starter Dot22

    (@dot22)

    Thanks for your reply stirrell42! Changed the $_POST variable to $_REQUEST and added the following code as you said…

    <?php
    if( ! empty( $_REQUEST['select'] ) ) {
    	$select = sanitize_text_field( $_REQUEST['select'] );
    }
      $order = "&orderby=title&order=ASC";
      if ($_REQUEST['select'] == 'titleasc') { $order = "&orderby=title&order=ASC";  }
      if ($_REQUEST['select'] == 'titledesc') { $order = "&orderby=title&order=DESC";  }
      if ($_REQUEST['select'] == 'autorasc') { $order = "&post_type=catitem&meta_key=audiovisual_director&orderby=meta_value&order=ASC";  }
      if ($_REQUEST['select'] == 'autordesc') { $order = "&post_type=catitem&meta_key=audiovisual_director&orderby=meta_value&order=DESC";  }

    But for pagination I’m using this code on functions.php…

    function numeric_posts_nav() {
    
    	if( is_singular() )
    		return;
    
    	global $wp_query;
    
    	if( $wp_query->max_num_pages <= 1 )
    		return;
    
    	$paged = get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1;
    	$max   = intval( $wp_query->max_num_pages );
    
    	if ( $paged >= 1 )
    		$links[] = $paged;
    
    	if ( $paged >= 3 ) {
    		$links[] = $paged - 1;
    		$links[] = $paged - 2;
    	}
    
    	if ( ( $paged + 2 ) <= $max ) {
    		$links[] = $paged + 2;
    		$links[] = $paged + 1;
    	}
    
    	echo '<ul>' . "\n";
    
    	if ( get_previous_posts_link() )
    previous_posts_link( __( '<div class="btn-pagination"><span class="reply" style="padding: 0px 8px 0px 0px;"></span>PREVIOUS</div>' . "\n" ) );
    
    	/**	Link to first page, plus ellipses if necessary */
    	if ( ! in_array( 1, $links ) ) {
    		$class = 1 == $paged ? ' class="active"' : '';
    
    		printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( get_pagenum_link( 1 ) ), '1' );
    
    		if ( ! in_array( 2, $links ) )
    			echo '<li>...</li>';
    	}
    
    	sort( $links );
    	foreach ( (array) $links as $link ) {
    		$class = $paged == $link ? ' class="active"' : '';
    		printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( get_pagenum_link( $link ) ), $link );
    	}
    
    	if ( ! in_array( $max, $links ) ) {
    		if ( ! in_array( $max - 1, $links ) )
    			echo '<li>...</li>' . "\n";
    
    		$class = $paged == $max ? ' class="active"' : '';
    		printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( get_pagenum_link( $max ) ), $max );
    	}
    
    	/**	Next Post Link */
    	if ( get_next_posts_link() )
    next_posts_link( __( '<div class="btn-pagination">NEXT<span class="share" style="padding: 0px 0px 0px 8px;"></span></div>' . "\n" ) );
    
    	echo '</ul>' . "\n";
    }

    Don’t know where to add ‘add_args’ => array(‘select’ => $_REQUEST[‘select’]). :/

    Hi Dot22,

    You would use the function on the link. In this case, it is happening here for you:

    get_pagenum_link( $max ) and get_pagenum_link( $link )

    So you could alter these lines to:

    
    printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( add_query_arg( 'select', $select, get_pagenum_link( $link ) ) ), $link );
    
    
    printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( add_query_arg( 'select', $select, get_pagenum_link( $max ) ) ), $max );
    

    I think :-). Also, I would recommend adding a default value to select at the top of your file like:

    
    <?php
    $select = '';
    if( ! empty( $_REQUEST['select'] ) ) {
    

    The reason is that PHP will give you warnings if you are using an undefined variable. If a person has not submitted the form, and you have nothing for $_REQUEST[‘select’] to set to your $select variable, $select never gets set and then you try to use it and PHP will log the error to your PHP error log or, depending how the server is set up, display the warnings to the screen.

    Hope this helps!
    Scott

    Thread Starter Dot22

    (@dot22)

    Thanks again for your help Scott! For some reason the changes didn’t impact on the site. The select still works on the first page only. When I click on page 2, 3 the order is “reset”.

    Don’t know where have to look to fix this =(

    The list of changes…

    • Changed all the $_POST[‘select’] for $_REQUEST[‘select’]
    • Added the following code at the top of the original one
      <?php
      $select = '';
      if( ! empty( $_REQUEST['select'] ) ) {
      	$select = sanitize_text_field( $_REQUEST['select'] );
      }
    • Added the two lines on get_pagenum_link( $max ) and get_pagenum_link( $link )

    Thanks in advance! 🙂

    Hello there. Hmmmm… when you click on a link to go to another page, are you seeing the “select” argument in the browser’s address bar? The first thing to do is to determine if we’re not passing the order correctly in the first place or, if for some reason, the page is not reading the order that we do pass to it. The address should have something like ?select= titleasc in it.

    Scott

    Thread Starter Dot22

    (@dot22)

    No, the link remains the same… for example: http://my.wordpress.site/page/2/

    Hmmmm… looks like the links aren’t being changed for some reason. I would add some test text in your link code to verify that your page links are being created there. For example, try:

    printf( '<li%s>Hello, world!<a href="%s">%s</a></li>' . "\n", $class, esc_url( add_query_arg( 'select', $select, get_pagenum_link( $link ) ) ), $link );

    Note the “Hello, world!” or something similar. That way you can see if the links are being generated there.

    If you go to:

    http://my.wordpress.site/page/2/?select=titleasc

    Does the sort work as you would expect?

    Hope this helps!
    Scott

    Thread Starter Dot22

    (@dot22)

    Now all the page numbers display before them the words “Hello, world” so I think the link are generated there. If I go to the url http://my.wordpress.site/page/2/?select=titleasc it works successfully.

    Don’t know why the selected array isn’t included on the page link… 🙁

    So the link isn’t being appended correctly. Could you past in your numeric_posts_nav function as it exists now?

    Thanks!
    Scott

    Thread Starter Dot22

    (@dot22)

    This is the code right now…

    function numeric_posts_nav() {
    
    	if( is_singular() )
    		return;
    
    	global $wp_query;
    
    	if( $wp_query->max_num_pages <= 1 )
    		return;
    
    	$paged = get_query_var( 'paged' ) ? absint( get_query_var( 'paged' ) ) : 1;
    	$max   = intval( $wp_query->max_num_pages );
    
    	if ( $paged >= 1 )
    		$links[] = $paged;
    
    	if ( $paged >= 3 ) {
    		$links[] = $paged - 1;
    		$links[] = $paged - 2;
    	}
    
    	if ( ( $paged + 2 ) <= $max ) {
    		$links[] = $paged + 2;
    		$links[] = $paged + 1;
    	}
    
    	echo '<ul>' . "\n";
    
    	if ( get_previous_posts_link() )
    previous_posts_link( __( '<div class="btn-pagination"><span class="fa fa-reply" style="padding: 0px 8px 0px 0px;"></span>PREVIOUS</div>' . "\n" ) );
    
    	if ( ! in_array( 1, $links ) ) {
    		$class = 1 == $paged ? ' class="active"' : '';
    
    		printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( add_query_arg( 'select', $select, get_pagenum_link( 1 ) ) ), '1' );
    
    		if ( ! in_array( 2, $links ) )
    			echo '<li>...</li>';
    	}
    
    	sort( $links );
    	foreach ( (array) $links as $link ) {
    		$class = $paged == $link ? ' class="active"' : '';
    		printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( add_query_arg( 'select', $select, get_pagenum_link( $link ) ) ), $link );
    	}
    
    	if ( ! in_array( $max, $links ) ) {
    		if ( ! in_array( $max - 1, $links ) )
    			echo '<li>...</li>' . "\n";
    
    		$class = $paged == $max ? ' class="active"' : '';
    		printf( '<li%s><a href="%s">%s</a></li>' . "\n", $class, esc_url( add_query_arg( 'select', $select, get_pagenum_link( $max ) ) ), $max );
    	}
    
    	/**	Next Post Link */
    	if ( get_next_posts_link() )
    next_posts_link( __( '<div class="btn-pagination">NEXT<span class="fa fa-share" style="padding: 0px 0px 0px 8px;"></span></div>' . "\n" ) );
    
    	echo '</ul>' . "\n";
    }

    Oh, you know, the $select isn’t being passed to the function so I suspect it would not be available. My oversight. Try to add $select as a global to make it available under $wp_query.

    
    global $wp_query;
    global $select
    

    See if that makes it available and adds it to the link.

    Scott

    Thread Starter Dot22

    (@dot22)

    Thank you a lot for your help and patience Scott! It works perfect now 🙂

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘Front end post order by user’ is closed to new replies.