Wordpress Pagination with Custom Query - pagination

I am attempting to write a plugin that searches an SQL table based on input supplied via a form. My code is...
global $table_name_log;
$pagenum = isset( $_GET['pagenum'] ) ? absint( $_GET['pagenum'] ) : 1;
$limit = 25;
$offset = ( $pagenum - 1 ) * $limit;
$l_task=isset( $_POST['l_task'] ) ? $_POST['l_task'] : "a";
$l_val=$_POST['l_val']; if($l_val=="") { $l_task="a"; }
if($l_task=="d")
{
$criteria="where log.Doc_Number='{$l_val}'";
}
elseif($l_task=="e")
{
$criteria="where log.Employee='{$l_val}'";
}
else
{
$criteria="";
}
$SQLQuery="SELECT em.ID, log.Date, em.Payroll, log.Doc_Number, doc.Doc_Name, doc.Replaced_By, log.Trainer, log.Log, log.Type
FROM {$table_name_log} log
join {$table_name_employee} em on log.Employee=em.ID
join {$table_name_documents} doc on log.Doc_Number=doc.Doc_Number
{$criteria}
order by log.Employee asc
";
//Get total number of results
$results=$wpdb->get_results("{$SQLQuery}",ARRAY_A);
$search_total = $wpdb->num_rows;
//Limit results by page
$results=$wpdb->get_results("{$SQLQuery} LIMIT {$offset}, {$limit}",ARRAY_A);
if(! $results)
{
if($pagenum>1)
{
$pagenum=1;
$results=$wpdb->get_results("{$SQLQuery} LIMIT 0, {$limit}",ARRAY_A);
}
}
I then display the results of the query.
At the bottom of the displayed results I have this code...
$total=$search_total;
$num_of_pages = ceil( $total / $limit );
$page_links = paginate_links( array(
'base' => add_query_arg( 'pagenum', '%#%' ),
'format' => '',
'prev_text' => __( '«', 'aag' ),
'next_text' => __( '»', 'aag' ),
'total' => $num_of_pages,
'current' => $pagenum
) );
if ( $page_links ) {
echo '<div class="tablenav"><div class="tablenav-pages" style="margin: 1em 0">' . $page_links . '</div></div>';
}
The problem is that although the number of pages is calculated correctly and page 1 displays the correct results; when selecting another page it displays the results without the $criteria set by $l_task. How do I edit the code so that the pagination links feed the correct query to use for the additional pages?

Works now by adding this at the top...
if(isset($_GET['l_task'])) { $_POST['l_task']=$_GET['l_task']; }
if(isset($_GET['l_val'])) { $_POST['l_val']=$_GET['l_val']; }
I then added this...
'add_args' => array( 'l_task' => $_POST['l_task'], 'l_val' => $_POST['l_val'] )
to...
$page_links = paginate_links( array(
'base' => add_query_arg( 'pagenum', '%#%' ),
'format' => '',
'prev_text' => __( '«', 'aag' ),
'next_text' => __( '»', 'aag' ),
'total' => $num_of_pages,
'current' => $pagenum,
'add_args' => array( 'l_task' => $_POST['l_task'], 'l_val' => $_POST['l_val'] )
) );

Related

WordPress default gallery pagination when call is in page, not post?

It seems I have found the way to make WordPress default gallery pagination to work and to have control over URL forming: https://wordpress.stackexchange.com/questions/401034/pagination-with-wordpress-default-gallery But when gallery call is in post.
When gallery call is in page, it works only if URL is like this: domain.com/pagename/page/2/, domain.com/pagename/page/3/ etc. Trying to have a different URL ends up in stopping it to work.
The part of code handling pagination in functions.php:
// Pagination Setup
$current = (get_query_var('paged')) ? get_query_var( 'paged' ) : 1;
$per_page = 3;
$offset = ($current-1) * $per_page;
$big = 999999999;
$total = sizeof($attachments);
$total_pages = round($total/$per_page);
if( $total_pages < ( $total/$per_page ) ){
$total_pages = $total_pages+1;
}
// Pagination output
$output .= paginate_links( array(
'base' => str_replace($big,'%#%',esc_url(get_pagenum_link($big))),
'format' => '?paged=%#%',
'current' => $current,
'total' => $total_pages,
'prev_text' => __('«'),
'next_text' => __('»')
) );
As long as I keep URL like this domain.com/pagename/page/2/ , other ways for 'base' also work:
'base' => get_permalink( $post->post_parent ) . '%_%',
'format' => 'page/%#%/',
And like this:
'base' => get_pagenum_link( 1 ) . '%_%',
'format' => 'page/%#%/',
But when I try some other URL scheme:
'base' => get_permalink( $post->post_parent ) . '%_%',
'format' => 'paging-%#%',
pagination stops working.
The filter with rewrite tag and rule:
add_filter('init', 'post_gallery_add_rewrite_tag_rule_2022');
function post_gallery_add_rewrite_tag_rule_2022() {
add_rewrite_tag('%current%','(.+)');
add_rewrite_rule('(.+)/paging-/?([0-9]{1,})/?$', 'index.php?name=$matches[1]&paged=$matches[2]', 'top');
}
It seems like add_rewrite_rule is not functioning when gallery call is in page? Or what? Any ideas?

Buddypress new profile tabs and sub tabs: How to set up url slug properly?

First of all, I’ve seen alot of people trying to do a similar task, which is simply to create a new tab, with sub tabs in the user profile menu. I’ve managed to do this, but I can’t seem to get the url slug to work properly. When I click on the first sub tab, it simply takes me back to the main page for the user profile, and when I click on any additional sub tabs I get 404 errors. I have a feeling I’m missing something pretty simple, and I’ve been trying to learn over the last couple weeks how to make this work without any luck. If someone could help guide me on how to get this working properly, I would very grateful, and I imagine many others would find this post useful in the future.
For the record the main profile tab works properly, but the sub-tabs do not.
Here is the code I currently have in my bp-custom.php file
// My Membership Profile Tab
function profile_new_nav_item() {
global $bp;
bp_core_new_nav_item(
array(
'name' => 'My Membership',
'slug' => 'my-membership',
'default_subnav_slug' => 'extra_sub_tab', // We add this submenu item below
'screen_function' => 'view_manage_tab_main'
)
);
}
add_action( 'bp_setup_nav', 'profile_new_nav_item', 10 );
function view_manage_tab_main() {
add_action( 'bp_template_content', 'bp_template_content_main_function' );
bp_core_load_template( 'template_content' );
}
function bp_template_content_main_function() {
if ( ! is_user_logged_in() ) {
wp_login_form( array( 'echo' => true ) );
}
}
function profile_new_subnav_item() {
global $bp;
bp_core_new_subnav_item( array(
'name' => 'Membership Level',
'slug' => 'extra_sub_tab',
'parent_url' => $bp->loggedin_user->domain . $bp->bp_nav[ 'extra_tab' ][ 'slug' ] . '/',
'parent_slug' => $bp->bp_nav[ 'my-membership' ][ 'slug' ],
'position' => 10,
'screen_function' => 'view_manage_sub_tab_main'
) );
}
add_action( 'bp_setup_nav', 'profile_new_subnav_item', 10 );
function view_manage_sub_tab_main() {
add_action( 'bp_template_content', 'bp_template_content_sub_function' );
bp_core_load_template( 'template_content' );
}
function bp_template_content_sub_function() {
if ( is_user_logged_in() ) {
//Add shortcode to display content in sub tab
echo do_shortcode( '[membership]' );
} else {
wp_login_form( array( 'echo' => true ) );
}
}
// My Billing Profile Tab
function profile_new_subnav_item_billing() {
global $bp;
bp_core_new_subnav_item( array(
'name' => 'Billing',
'slug' => 'extra_sub_tab_billing',
'parent_url' => $bp->loggedin_user->domain . $bp->bp_nav[ 'extra_tab' ][ 'slug' ] . '/',
'parent_slug' => $bp->bp_nav[ 'my-membership' ][ 'slug' ],
'position' => 20,
'screen_function' => 'view_manage_sub_tab_billing'
) );
}
add_action( 'bp_setup_nav', 'profile_new_subnav_item_billing', 20 );
function view_manage_sub_tab_billing() {
add_action( 'bp_template_content', 'bp_template_content_sub_function_billing' );
bp_core_load_template( 'template_content' );
}
function bp_template_content_sub_function_billing() {
if ( is_user_logged_in() ) {
//Add shortcode to display content in sub tab
echo do_shortcode( '[billing]' );
} else {
wp_login_form( array( 'echo' => true ) );
}
}
You may use this:
// define your parent slug
$parent_slug = 'activity';
bp_core_new_subnav_item( array( .........
'parent_url' => $bp->loggedin_user->domain . $parent_slug.'/',
'parent_slug' => $parent_slug,
It works for me.

Extending Drupal 7 search

I want to extend default Drupal 7 node search with one additional field.
I alter search form with the following new field:
function mymodule_form_search_form_alter(&$form, &$form_state, $form_id) {
$form['basic']['site'] = array(
'#type' => 'select',
'#options' => array(
'KEY1' => 'TITLE1',
'KEY2' => 'TITLE2',
'KEY3' => 'TITLE3'
)
);
}
I have a field called field_data_field_site.field_site_value which i need to use as a filter in this search.
I've tried to read about hook_search_* functions but didn't get the idea.
My question is the following. How can I extend search form? Anyone have live examples?
The following is the best way I solve this problem.
First of all I need to alter Drupal's search block and search form with my field and define new submit function.
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_search_block_form_alter(&$form, &$form_state, $form_id) {
$form['#submit'][] = 'search_form_alter_submit';
$form['site'] = array(
'#type' => 'select',
'#options' => _options(),
'#default_value' => (($_GET['site']) ? $_GET['site'] : '')
);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_search_form_alter(&$form, &$form_state, $form_id) {
$form['#submit'][] = 'search_form_alter_submit';
$form['basic']['site'] = array(
'#type' => 'select',
'#options' => _options(),
'#default_value' => (($_GET['site']) ? $_GET['site'] : '')
);
}
function _options() {
return array(
'' => 'Select site',
'site-1' => 'Site 1',
'site-2' => 'Site 2'
);
}
Submit function will forward us to default search/node page but with our query. Page would look like search/node/Our-query-string?site=Our-option-selected.
function search_form_alter_submit($form, &$form_state) {
$path = $form_state['redirect'];
$options = array(
'query' => array(
'site' => $form_state['values']['site']
)
);
drupal_goto($path, $options);
}
Next step is to use hook_search_info (Don't forget to turn it on and set as default on admin/config/search/settings page).
/**
* Implements hook_search_info().
*/
function mymodule_search_info() {
return array(
'title' => 'Content',
'path' => 'node',
'conditions_callback' => '_conditions_callback',
);
}
Conditions callback function defined in hook_search_info. We need to provide additional queries to our search.
function _conditions_callback($keys) {
$conditions = array();
if (!empty($_REQUEST['site'])) {
$conditions['site'] = $_REQUEST['site'];
}
return $conditions;
}
Finally, hook_search_execute will filter our content by our query. I used default code from this hook with modifications I need.
/**
* Implements hook_search_execute().
*/
function mymodule_search_execute($keys = NULL, $conditions = NULL) {
// Build matching conditions
$query = db_select('search_index', 'i', array('target' => 'slave'))
->extend('SearchQuery')
->extend('PagerDefault');
$query->join('node', 'n', 'n.nid = i.sid');
// Here goes my filter where I joined another table and
// filter by required field
$site = (isset($conditions['site'])) ? $conditions['site'] : NULL;
if ($site) {
$query->leftJoin('field_data_field_site', 's', 's.entity_id = i.sid');
$query->condition('s.field_site_value', $site);
}
// End of my filter
$query
->condition('n.status', 1)
->addTag('node_access')
->searchExpression($keys, 'node');
// Insert special keywords.
$query->setOption('type', 'n.type');
$query->setOption('language', 'n.language');
if ($query->setOption('term', 'ti.tid')) {
$query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
}
// Only continue if the first pass query matches.
if (!$query->executeFirstPass()) {
return array();
}
// Add the ranking expressions.
_node_rankings($query);
// Load results.
$find = $query
->limit(10)
->execute();
$results = array();
foreach ($find as $item) {
// Build the node body.
$node = node_load($item->sid);
node_build_content($node, 'search_result');
$node->body = drupal_render($node->content);
// Fetch comments for snippet.
$node->rendered .= ' ' . module_invoke('comment', 'node_update_index', $node);
// Fetch terms for snippet.
$node->rendered .= ' ' . module_invoke('taxonomy', 'node_update_index', $node);
$extra = module_invoke_all('node_search_result', $node);
$results[] = array(
'link' => url("node/{$item->sid}", array('absolute' => TRUE)),
'type' => check_plain(node_type_get_name($node)),
'title' => $node->title,
'user' => theme('username', array('account' => $node)),
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
'score' => $item->calculated_score,
'snippet' => search_excerpt($keys, $node->body)
);
}
return $results;
}
I'd be happy if anyone would give me a better answer.

Module development: hook_form(), hook_menu() and how to get $_POST

I want to improve my knowledge in module development (which is far away from basic), so I try to develop a perimeter search module.
What I've achieved for now is a block containing a form:
function perimeter_search_block_view($delta = '') {
// Define an empty array for the block output.
$block = array();
switch($delta) {
case 'perimeter_search_box':
$block['subject'] = t('Perimeter search box');
$block['content'] = drupal_get_form('perimeter_search_form');;
break;
}
return $block;
}
/**
* Implementation of the perimeter search form
* #return array with form data
*/
function perimeter_search_form($form, &$form_state) {
$form = array(
'#action' => 'perimeter-search-results',
'keyword' => array(
'#type' => 'textfield'
),
'location' => array(
'#type' => 'textfield'
),
'perimeter' => array(
'#type' => 'select',
'#title' => t('Perimeter'),
'#options' => array('15 km', '30 km', '60 km', '120 km')
),
'submit' => array(
'#type' => 'submit',
'#value' => t('Start search')
)
);
return $form;
}
I also have a function to output the search results:
/**
* Implementation of hook_menu()
* #return defined menu/page items
*/
function perimeter_search_menu() {
$items = array();
// Search results page
$items['perimeter-search-results'] = array(
'title' => t('Perimeter search results'),
'page callback' => 'perimeter_search_results',
'access arguments' => array('view perimeter search'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}
/**
* Processing job search queries
*/
function perimeter_search_results() {
$page_content = t('Search results');
return $page_content;
}
My (simple?) question is: how to get the post data (keyword, location, perimeter) in my perimeter_search_results() function?
Easy, you have to create the _submit function for your form, here an example:
function perimeter_search_form_submit($form, &$form_state) {
/*
* Your data handling goes here on the $form_state['values']['myfieldname']
* variable.
*/
drupal_set_message(t('Awesome, you managed to fill the form!'));
}
And if you need to validate..
function perimeter_search_form_validate($form, &$form_state) {
if($form_state['values'['myfieldname'] == '') {
form_set_error('', t('Hey, it doesn't work like that!'));
}
}
Just remember that if you add the attribute '#required' => TRUE to a form field, the field will be automatically validated to always require that field, so you don't need to use the validator for that field if you just need that it get compiled.

drupal form api checkboxes

I am using drupal form api and using checkboxes. I am getting problem in default checked values with it. following is the code snippet...
$result = db_query("SELECT nid, filepath FROM {content_type_brand}, {files} WHERE content_type_brand.field_brand_image_fid
= files.fid");
$items = array();
while ($r = db_fetch_array($result)) {
array_push($items, $r);
}
$options = array();
foreach( $items as $i ) {
$imagePath = base_path().$i['filepath'];
$options[$i['nid']] = '<img src="'.$imagePath.'"></img>';
}
$form['favorite_brands'] = array (
'#type' => 'fieldset',
'#title' => t('Favorite Brands'),
//'#weight' => 5,
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['favorite_brands']['brands_options']
= array(
'#type' => 'checkboxes',
'#options' => $options,
'#default_value' => $options_checked,// $options_checked is an array similar to $options but having elements which need to be checked by default...
'#multicolumn' => array('width' => 3)
);
but values are not checked by default... can anyone help what I am missing??
Thanks
Your $options_checked array should not be in the same format as your $options array. Your $options array contains nid => img tag pairs. Your $options_checked array should simply contain the nid values of the options that should be checked by default:
$options_checked = array(8,17);

Resources