Handle search in Wordpress from WP_List_Table code - php

I need to add support for searching or filter items using WP_List_Table I read and didn't know how to get this done. I've already added the box trough this code:
function ft_list()
{
echo '</pre><div class="wrap"><h2>' . __('Frequent Traveler List') . '</h2>';
$ftList = new FT_WP_Table();
$ftList->search_box('search', 'search_id');
echo '</div>';
}
And this is how my prepare_items() functions looks:
public function prepare_items()
{
$searchcol = array(
'firstname',
'lastname',
'foid',
'no_frequent',
'create_time'
);
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array(
$columns,
$hidden,
$sortable
);
// SQL results
$posts = $this->get_sql_results();
empty($posts) AND $posts = array();
# >>>> Pagination
$per_page = $this->posts_per_page;
$current_page = $this->get_pagenum();
$total_items = count($posts);
$this->set_pagination_args(array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil($total_items / $per_page)
));
$last_post = $current_page * $per_page;
$first_post = $last_post - $per_page + 1;
$last_post > $total_items AND $last_post = $total_items;
// Setup the range of keys/indizes that contain
// the posts on the currently displayed page(d).
// Flip keys with values as the range outputs the range in the values.
$range = array_flip(range($first_post - 1, $last_post - 1, 1));
// Filter out the posts we're not displaying on the current page.
$posts_array = array_intersect_key($posts, $range);
# <<<< Pagination
// Prepare the data
$permalink = __('Edit:');
foreach ($posts_array as $key => $post) {
$link = get_edit_post_link($post->id);
$no_title = __('No title set');
$title = !$post->firstname ? "<em>{$no_title}</em>" : $post->firstname;
$posts[$key]->firstname = "<a title='{$permalink} {$title}' href='{$link}'>{$title}</a>";
}
$this->items = $posts_array;
}
Where I should add the code to filter items based on search parameter?

Looking at other classes that extend WP_List_Table I see they use something like
$search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : false;
and pass that to the prepare_items() method.
In my test plugin I made this (see Percent in wpdb->prepare):
$search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : false;
$do_search = ( $search ) ? $wpdb->prepare(" AND post_content LIKE '%%%s%%' ", $search ) : '';
$sql_results = $wpdb->get_results("
SELECT $sql_select
FROM $wpdb->posts
WHERE post_status = 'publish'
$do_search
ORDER BY $this->orderby $this->order "
);
And in display_tablenav() method I added:
<form action="" method="GET">
<?php
$this->search_box( __( 'Search' ), 'search-box-id' );
?>
<input type="hidden" name="page" value="<?= esc_attr($_REQUEST['page']) ?>"/>
</form>
I haven't created any search_box() method, letting the parent class render it.

Related

make list table with output array value in option table wordpress

class Kv_subscribers_list extends WP_List_Table {
function __construct(){
global $status, $page;
parent::__construct( array(
'singular' => 'option',
'plural' => 'options',
'ajax' => false
) );
}
function column_default($item, $column_name){
switch($column_name){
case 'option_id':
case 'option_name':
case 'option_value':
return $item[$column_name];
default:
return print_r($item,true); //Show the whole array for troubleshooting purposes
}
}
function column_cb($item){
return sprintf(
'<input type="checkbox" name="%1$s[]" value="%2$s" />',
/*$1%s*/ $this->_args['singular'],
/*$2%s*/ $item['option_id']
);
}
function get_columns(){
$columns = array(
'cb' => '<input type="checkbox" />',
'option_id'=>__('الرقم'),
'option_name'=>__('المصدر'),
'option_value'=>__('النقطة'),
);
return $columns;
}
public function get_sortable_columns() {
$sortable_columns = array(
'option_id' => array('option_id',true),
'option_name' => array('option_name',true)
);
return $sortable_columns;
}
public function get_bulk_actions() {
$actions = array(
'delete' => 'حذÙ',
'email' => 'Email'
);
return $actions;
}
public function process_bulk_action() {
global $wpdb;
$options_tbl = $wpdb->prefix.'options';
if( 'delete'===$this->current_action() ) {
foreach($_POST['option'] as $single_val){
$wpdb->delete( $options_tbl, array( 'option_id' => (int)$single_val ) );
}
$redirect_url = get_admin_url( null, 'admin.php?page=options' );
wp_safe_redirect($redirect_url);
wp_die('Items deleted (or they would be if we had items to delete)!');
}
if( 'email'===$this->current_action() ) {
$result_email_ar = implode("-",$_POST['option']);
$redirect_url = get_admin_url( null, 'admin.php?page=kvcodes&ids='.$result_email_ar );
wp_safe_redirect($redirect_url);
wp_die(' ');
}
}
function prepare_items() {
global $wpdb; //This is used only if making any database queries
$database_name = $wpdb->prefix.'options' ;
$per_page = 10;
$query = "SELECT * FROM $wpdb->options WHERE option_name LIKE 'agl_data_%_%' ";
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
$this->_column_headers = array($columns, $hidden, $sortable);
$this->process_bulk_action();
$data = $wpdb->get_results($query, ARRAY_A );
function usort_reorder($a,$b){
$orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'title'; //If no sort, default to title
$order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc'; //If no order, default to asc
$result = strcmp($a[$orderby], $b[$orderby]); //Determine sort order
return ($order==='asc') ? $result : -$result; //Send final sort direction to usort
}
usort($data, 'usort_reorder');
$current_page = $this->get_pagenum();
$total_items = count($data);
$data = array_slice($data,(($current_page-1)*$per_page),$per_page);
$this->items = $data;
$this->set_pagination_args( array(
'total_items' => $total_items, //WE have to calculate the total number of items
'per_page' => $per_page, //WE have to determine how many items to show on a page
'total_pages' => ceil($total_items/$per_page) //WE have to calculate the total number of pages
) );
}
}//class
function o_add_menu_items(){
//add_menu_page('Plugin List Table', 'Sub', 'activate_plugins', 'options', 'o_render_list_page');
add_menu_page( 'تقرير التتبع', 'تقرير التتبع', 'manage_options', 'options', 'o_render_list_page', 'dashicons-welcome-widgets-menus', 81 );
}
add_action('admin_menu', 'o_add_menu_items');
function ns_contact_form_csv_pull() {
global $wpdb;
$table = 'ns_contact_form';// table name
$file = 'سجلات_التتبع_csv'; // csv file name
$results = $wpdb->get_results("SELECT * FROM $wpdb->options WHERE option_name LIKE 'agl_data_%_%' ",ARRAY_A );
if(count($results) > 0){
foreach($results as $result){
$result = array_values($result);
$result = implode(", ", $result);
$csv_output .= $result."\n";
}
}
$filename = $file."_".date("Y-m-d_H-i",time());
header("Content-type: application/vnd.ms-excel");
header("Content-disposition: csv" . date("Y-m-d") . ".csv");
header( "Content-disposition: filename=".$filename.".csv");
print $csv_output;
exit;
}
add_action('wp_ajax_csv_pull','ns_contact_form_csv_pull');
function o_render_list_page() {
$mydownloads = new Kv_subscribers_list();
$title = __("سجلات نظام التتبع","my_plugin_slug");
?>
<div class="wrap">
<h1>
<?php echo esc_html( $title );?>
<!-- Check edit permissions -->
<a href="<?php echo admin_url( 'admin-ajax.php?action=csv_pull' ); ?>" class="page-title-action">
<?php echo esc_html_x('تصدير كاÙØ© البيانات', 'my-plugin-slug'); ?>
</a>
<?php
?>
</h1>
</div>
<?php $mydownloads->views(); ?>
<form method="post">
<?php
$mydownloads->prepare_items();
$mydownloads->display();
?>
</form>
<?php
}
above is code that filter an data stores in options table
option_value field is contain an array data
example :
a:14:{s:8:"latitude";s:10:"51.5841086";s:9:"longitude";s:17:"89.21324279999999";s:8:"altitude";s:3:"NaN";s:8:"accuracy";s:4:"1612";s:16:"altitudeAccuracy";s:3:"NaN";s:7:"heading";s:3:"NaN";s:5:"speed";s:3:"NaN";s:10:"error_code";s:0:"";s:13:"error_message";s:0:"";s:8:"php_time";i:1529454899;s:8:"php_date";s:19:"2018-06-20 00:34:59";s:15:"php_date_format";s:11:"Y-m-d H:i:s";s:7:"user_id";s:1:"0";s:9:"user_mail";s:1:"0";}
ineed to get this option_value array and make a table of the variable
column header = altitude|
longitude|
altitude
value = altitude => 21.5841086|
longitude => 39.21324279999999|
altitude => NaN
please some one help me to adjust my code above to fit data in array column header and row data

Wordpress undefined index issue php

I'm getting the following error in my wordpress dashboard which correlates to a piece of code i've written, however I'm not sure how to fix the error:
Notice: Undefined index: draft in /home/sites/samskirrow.com/public_html/skizzar-test/wp-content/mu-plugins/skizzar-dashboard.php on line 331
Here is the code it's referring to:
/******************************************************************
/* REMOVE BRACKETS AROUND PAGE COUNTS
/******************************************************************/
foreach( array( 'edit-post', 'edit-page', 'edit-movie', 'upload' ) as $hook )
add_filter( "views_$hook" , 'wpse_30331_custom_view_count', 10, 1);
function wpse_30331_custom_view_count( $views )
{
global $current_screen;
switch( $current_screen->id )
{
case 'edit-post':
$views = wpse_30331_manipulate_views( 'post', $views );
break;
case 'edit-page':
$views = wpse_30331_manipulate_views( 'page', $views );
break;
case 'edit-movie':
$views = wpse_30331_manipulate_views( 'movie', $views );
break;
case 'upload':
$views = wpse_30331_manipulate_views( 'attachment', $views );
break;
}
return $views;
}
function wpse_30331_manipulate_views( $what, $views )
{
global $user_ID, $wpdb;
/*
* This is not working for me, 'artist' and 'administrator' are passing this condition (?)
*/
if ( !current_user_can('artist') )
return $views;
/*
* This needs refining, and maybe a better method
* e.g. Attachments have completely different counts
*/
$total = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE (post_status = 'publish' OR post_status = 'draft' OR post_status = 'pending') AND (post_author = '$user_ID' AND post_type = '$what' ) ");
$publish = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'publish' AND post_author = '$user_ID' AND post_type = '$what' ");
$draft = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'draft' AND post_author = '$user_ID' AND post_type = '$what' ");
$pending = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'pending' AND post_author = '$user_ID' AND post_type = '$what' ");
$trash = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'trash' AND post_author = '$user_ID' AND post_type = '$what' ");
/*
* Only tested with Posts/Pages
* - there are moments where Draft and Pending shouldn't return any value
*/
$views['all'] = preg_replace( '/\(.+\)/U', ''.$total.'', $views['all'] );
$views['publish'] = preg_replace( '/\(.+\)/U', ''.$publish.'', $views['publish'] );
$views['draft'] = preg_replace( '/\(.+\)/U', ''.$draft.'', $views['draft'] );
$views['pending'] = preg_replace( '/\(.+\)/U', ''.$pending.'', $views['pending'] );
$views['trash'] = preg_replace( '/\(.+\)/U', ''.$trash.'', $views['trash'] );
return $views;
}
I know that the issue is that certain parameters aren't found in the db (for example, there may not be any "pending" posts) so it throws out an error. How can I code my way around this, for example, to say, if the parameter exists...
The goal here is to remove the '(' ')' brackets from post counts in wordpress. So when you are on the view posts, or view pages screen, there is a sub menu above the lists of posts/pages with the following items 'all', 'published', 'trash', 'pending' - these are filters that the user can click on. Next to each filter is a number, the number of posts/pages within that filter. The format of this count is ([NUMBER]) - This code is to simply get rid of those brackets.
I noticed by google'ing a bit that you're using the code form this Wordpress SE answer. This doesn't match your needs, as this code is here to recalculate the number of posts after some manipulation on that by the OP.
To just remove the parenthesis, look at the following function in class-wp-list-table.php:
public function views() {
$views = $this->get_views();
$views = apply_filters( "views_{$this->screen->id}", $views );
if ( empty( $views ) )
return;
$this->screen->render_screen_reader_content( 'heading_views' );
echo "<ul class='subsubsub'>\n";
foreach ( $views as $class => $view ) {
$views[ $class ] = "\t<li class='$class'>$view";
}
echo implode( " |</li>\n", $views ) . "</li>\n";
echo "</ul>";
}
This is the function that build the user menu that you try to change. If you look closer at this, you will see that the $view being echo'ed come from a $views that is being filtered previously:
$views = apply_filters( "views_{$this->screen->id}", $views )
$this->screen->id stand for the ID of the current screen, like edit-post for example.
So by adding this simple filter you will achieve what you want to do here:
add_filter('views_edit-post', 'remove_count_parenthesis', 10, 1);
function remove_count_parenthesis($views) {
foreach($views as $key => $view) {
$views[$key] = str_replace(array('(', ')'), '', $view);
}
return $views;
}
You need to check if there is a value 'draft' in your array
if (isset( $views['draft'] )) {
$views['draft'] = preg_replace( '/\(.+\)/U', ''.$draft.'', $views['draft'] );
}

Notice: is_main_query was called incorrectly

Was searching for two days what makes problem in my WordPress theme, and using debug I found this error, and that what I have in functions about that error code.
It displays notice on place where section box should be shown.
How can I fix this?
Notice: is_main_query was called incorrectly. In pre_get_posts, use the WP_Query->is_main_query() method,
// Filter to "pre_get_posts" to change query vars
add_action( 'pre_get_posts', 'dp_custom_get_posts' );
function dp_custom_get_posts( $query ) {
if(is_admin())
return;
$orderby = $query->get('orderby');
$order = $query->get('order');
// If no 'orderby' specified, get first sort type from selected sort types
$selected_sort_types = dp_selected_sort_types();
if(is_main_query() && !empty($selected_sort_types) && empty($orderby)) {
$_sort_types = array_keys($selected_sort_types);
$orderby = $_sort_types[0];
$query->set('orderby', $orderby);
}
// Reset query vars based orderby parameter
if($orderby == 'comments') {
$query->set('orderby', 'comment_count');
}
elseif($orderby == 'views') {
$query->set('orderby', 'meta_value_num');
$query->set('meta_key', 'views');
// The arguments for BAW Post Views Count plugin
if(function_exists('baw_pvc_main')) {
global $timings;
$views_timing = $query->get('views_timing') ? $query->get('views_timing') : 'all';
$date = $views_timing == 'all' ? '' : '-'. date( $timings[$views_timing] );
$meta_key = apply_filters( 'baw_count_views_meta_key', '_count-views_' . $views_timing . $date, $views_timing, $date );
$query->set('meta_key', $meta_key);
}
}
elseif($orderby == 'likes') {
$query->set('orderby', 'meta_value_num');
$query->set('meta_key', 'likes');
}
elseif($orderby == 'title' && !$order) {
// If order by title, and no order specified, set "ASC" as default order.
$query->set('order', 'ASC');
}
// Only display posts on search results page
if (is_search() && $query->is_main_query())
$query->set('post_type', 'post');
// Make tax_query support "post-format-standard"
$tax_query = $query->get('tax_query');
if(!empty($tax_query)) {
foreach($tax_query as $index => $single_tax_query) {
if(empty($single_tax_query['terms']))
continue;
$in_post_formats = (array)$single_tax_query['terms'];
if($single_tax_query['taxonomy'] == 'post_format'
&& $single_tax_query['field'] == 'slug'
&& in_array('post-format-standard', $in_post_formats)) {
// Get reverse operator
$reverse_operator = 'IN';
if(empty($single_tax_query['operator']) || $single_tax_query['operator'] == 'IN')
$reverse_operator = 'NOT IN';
elseif($single_tax_query['operator'] == 'AND')
break;
// Get "not in post formats"
$post_formats = get_theme_support('post-formats');
$all_post_formats = array();
if(is_array( $post_formats[0])) {
$all_post_formats = array();
foreach($post_formats[0] as $post_format)
$all_post_formats[] = 'post-format-'.$post_format;
}
$not_in_post_formats = array_diff($all_post_formats, $in_post_formats);
// Reset post_format in tax_query
$query->query_vars['tax_query'][$index] = array(
'taxonomy' => 'post_format',
'field' => 'slug',
'terms' => $not_in_post_formats,
'operator' => $reverse_operator
);
}
}
}
return $query;
}
This is the code of an section box, or at least part of it, I'm not sure what I'm doing anymore:
function dp_section_box($args = array()) {
$defaults = array(
'post_type' => 'post',
'cat' => '',
'taxonomies' => array(),
'view' => 'grid-small',
'title' => '',
'link' => '',
'post__in' => '',
'posts_per_page' => '',
'hide_if_empty' => false
);
$args = wp_parse_args($args, $defaults);
extract($args);
$posts_per_page = absint($posts_per_page);
// Set default posts number if no specified
if(empty($posts_per_page)) {
if($view == 'grid-mini')
$posts_per_page = 8;
elseif($view == 'grid-small')
$posts_per_page = 6;
elseif($view == 'grid-medium')
$posts_per_page = 4;
elseif($view == 'list-small')
$posts_per_page = 3;
elseif($view == 'list-medium')
$posts_per_page = 2;
elseif($view == 'list-large')
$posts_per_page = 1;
}
$args['posts_per_page'] = $posts_per_page;
$args = dp_parse_query_args($args);
$query = new WP_Query($args);
// Output nothing if there is no posts
if(!$query->have_posts() && $hide_if_empty)
return;
// Output content before section
if(!empty($before))
echo '<div class="section-box section-before rich-content">'. do_shortcode(wp_kses_stripslashes($before)).'</div><!-- end .section-box -->';
// Section box begin
echo '<div class="section-box">';
global $section_view;
$section_view = $view;
// Get term name as title
$term = '';
$cat = '';
if(!empty($taxonomies['category']))
$cat = $taxonomies['category'];
if($cat)
$term = get_term($cat, 'category');
if(empty($title) && $term)
$title = $term->name;
if(empty($link) && $term)
$link = get_term_link($term, 'category');
$title = '<span class="name">'.$title.'</span>';
// Add link to title and more
$more = '';
if($link) {
$title = '<a class="name-link" href="'.$link.'">'.$title.'</a>';
$more = '<a class="more-link" href="'.$link.'"><span>'.__('More', 'dp').' <i class="mini-arrow-right"></i></span></a>';
}
// Output section header
echo '<div class="section-header"><h2 class="section-title">'.$title.'</h2>'.$more.'</div>';
// Output section content
echo '<div class="section-content '.$view.'"><div class="nag cf">';
while ($query->have_posts()) : $query->the_post();
get_template_part('item-video');
endwhile;
wp_reset_postdata();
echo '</div></div><!-- end .section-content -->';
the solution is given in your error itself "use the WP_Query->is_main_query() method"-
try this -
if($query->is_main_query() && !empty($selected_sort_types) && empty($orderby)) {
$_sort_types = array_keys($selected_sort_types);
$orderby = $_sort_types[0];
$query->set('orderby', $orderby);
}
instead of this -
if(is_main_query() && !empty($selected_sort_types) && empty($orderby)) {
$_sort_types = array_keys($selected_sort_types);
$orderby = $_sort_types[0];
$query->set('orderby', $orderby);
}

Get authors post in wordpress with co-author plus installed

I want to list all posts, a user is assigned as author.
We are using the plugin, co-authors plus, which allows to assign multiple authors to a single post.
The function <?php $user_post_count = count_user_posts( $userid ); ?> returns the correct number of posts, the user is assigned to.
But when trying to list all the posts, with The loop only the post which initially were created by that user are shown.
query_posts( $args );
if (count_user_posts($user->ID) == 0) {
echo "No posts";
}
// The Loop
while ( have_posts() ) : the_post();
echo '<li>';
the_title();
echo '</li>';
endwhile;
Is there an other possibility to get all posts from an user or can we modify our existing code?
EDIT
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'author',
'field' => 'slug',
'terms' => $user_login
)
),
);
$author_query = new WP_Query( $args );
if ( $author_query->have_posts() ) :
while ( $author_query->have_posts() ) : $author_query->the_post();
// Do your presentation
endwhile;
endif;
/**
* #param $user_id
* #param int $paged (if $paged = null return all posts)
* #return array|bool
*/
function get_coauthor_posts_by_author_id($id, $paged = 1)
{
global $wpdb;
$slug = 'cap-' . strtolower(get_userdata($id)->user_nicename);
$max_post = get_option('posts_per_page');
$post_lower_limit = 0;
if ($paged > 1) {
$post_upper_limit = $max_post * $paged;
$post_lower_limit = $post_upper_limit - $max_post;
}
$term_id = $wpdb->get_results($wpdb->prepare("SELECT term_id FROM $wpdb->terms WHERE slug = %s ", $slug))[0]->term_id;
$sql = "SELECT SQL_CALC_FOUND_ROWS $wpdb->posts.id FROM $wpdb->posts LEFT JOIN $wpdb->term_relationships AS tr1 ON ($wpdb->posts.id = tr1.object_id) LEFT JOIN $wpdb->term_taxonomy ON ( tr1.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id ) WHERE 1=1 AND (($wpdb->posts.post_author = %d OR ($wpdb->term_taxonomy.taxonomy = 'author' AND $wpdb->term_taxonomy.term_id = %d))) AND $wpdb->posts.post_type = 'post' AND ($wpdb->posts.post_status = 'publish' OR $wpdb->posts.post_status = 'private') GROUP BY $wpdb->posts.id ORDER BY $wpdb->posts.post_date DESC";
$sql_limit = " LIMIT %d, %d";
if ($paged !== null) {
$sql = $sql . $sql_limit;
}
$result = $wpdb->get_results($wpdb->prepare($sql, $id, $term_id, $post_lower_limit, $max_post), ARRAY_A);
return array_column($result, 'id');
}

Get Product Media Gallery Images from a Product Collection in Magento

I have a collection of products in Magento that I would like to be able to get the media gallery images out of. However I am finding that I have to iterate though my collection and load the product again to get the getMediaGalleryImages() function to work properly.
$products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('visibility', 4)
->addAttributeToFilter('status', 1);
foreach($products as $product) {
$_product = Mage::getModel('catalog/product')->load($product->getId());
$product->getMediaGalleryImages(); // This returns nothing
$_product->getMediaGalleryImages(); // Returns the Collection of Images
}
Obviously I could continue just reloading the product each time, but that would add quite a bit of overhead to the time required to run this code.
Is there a way to add in the media gallery images to the collection?
You can use
$product->load('media_gallery');
before getMediaGalleryImages (on the products you loaded in the collection).
One simple method for future reference:
Outside your foreach add
$mediaBackend = Mage::getModel('catalog/product_attribute_backend_media');
$mediaGalleryAttribute = Mage::getModel('eav/config')->getAttribute(Mage::getModel('catalog/product')->getResource()->getTypeId(), 'media_gallery');
$mediaBackend->setAttribute($mediaGalleryAttribute);
and then do the foreach:
foreach ($productCollection as $product) {
$mediaBackend->afterLoad($product);
}
You will have then the gallery loaded on product.
load product's cached image using collection by following codes
Mage::helper('catalog/image')->init($_product, 'small_image')->resize(135);
//or
Mage::helper('catalog/image')->init($_product, 'thumbnail')->resize(135);
//or
Mage::helper('catalog/image')->init($_product, 'image')->resize(135);
this is the collection which i used
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('small_image') //or
->addAttributeToSelect('thumbnail') //or
->addAttributeToSelect('image');
You can create a helper class, and use it every time you need media gallery images to be loaded for a collection of products:
class My_Package_Helper_Media extends Mage_Core_Helper_Abstract {
public function addMediaGalleryAttributeToProductCollection( &$productCollection )
{
$storeId = Mage::app()->getStore()->getId();
$ids = array();
foreach ( $productCollection as $product ) {
$ids[] = $product->getEntityId();
}
$resource = Mage::getSingleton( 'core/resource' );
$conn = Mage::getSingleton( 'core/resource' )->getConnection( 'catalog_read' );
$select = $conn->select()
->from(
array( 'mg' => $resource->getTableName( 'catalog/product_attribute_media_gallery' ) ),
array(
'mg.entity_id', 'mg.attribute_id', 'mg.value_id', 'file' => 'mg.value',
'mgv.label', 'mgv.position', 'mgv.disabled',
'label_default' => 'mgdv.label',
'position_default' => 'mgdv.position',
'disabled_default' => 'mgdv.disabled'
)
)
->joinLeft(
array( 'mgv' => $resource->getTableName( 'catalog/product_attribute_media_gallery_value' ) ),
'(mg.value_id=mgv.value_id AND mgv.store_id=' . $storeId . ')',
array()
)
->joinLeft(
array( 'mgdv' => $resource->getTableName( 'catalog/product_attribute_media_gallery_value' ) ),
'(mg.value_id=mgdv.value_id AND mgdv.store_id=0)',
array()
)
->where( 'entity_id IN(?)', $ids );
$mediaGalleryByProductId = array();
$stmt = $conn->query( $select );
while ( $gallery = $stmt->fetch() ) {
$k = $gallery[ 'entity_id' ];
unset( $gallery[ 'entity_id' ] );
if ( !isset($mediaGalleryByProductId[$k]) ) {
$mediaGalleryByProductId[$k] = array();
}
$mediaGalleryByProductId[$k][] = $gallery;
}
unset( $stmt ); // finalize statement
// Updating collection ...
foreach ( $productCollection as &$product ) {
$productId = $product->getEntityId();
if ( isset( $mediaGalleryByProductId[ $productId ] ) ) {
$product->setData( 'media_gallery', array( 'images' => $mediaGalleryByProductId[ $productId ] ) );
}
}
unset( $mediaGalleryByProductId );
}
}
Sample usage:
$coll = Mage::getResourceModel('catalog/product_collection')
->setStoreId( Mage::app()->getStore()->getId() )
->addAttributeToFilter( 'sku', array( 'in' => array( 'AAA', 'BBB' ) ) );
Mage::helper('my_package/media')->addMediaGalleryAttributeToProductCollection( $coll );
Here the code you were looking for, sorry for the delay :)
It come from this discussion:
http://www.magentocommerce.com/boards/viewthread/17414/
I just added some extra check on the number of id a and pagination
function addMediaGalleryAttributeToCollection(Mage_Catalog_Model_Resource_Product_Collection $_productCollection)
{
if (Mage::getStoreConfig('color_selector_plus/colorselectorplusgeneral/showonlist', Mage::app()->getStore())) {
$_mediaGalleryAttributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'media_gallery')->getAttributeId();
$_read = Mage::getSingleton('core/resource')->getConnection('catalog_read');
$pageCur = $_productCollection->getCurPage();
$pageSize = $_productCollection->getPageSize();
$offset = $pageSize * ($pageCur - 1);
$ids = $_productCollection->getAllIds($pageSize, $offset);
// added check on products number: if 0 ids the following query breaks
if (count($ids) > 0) {
$sql = '
SELECT
main.entity_id, `main`.`value_id`, `main`.`value` AS `file`, `value`.`disabled`,
/*`value`.`label`, `value`.`position`, */
/*`default_value`.`label` AS `label_default`, */
/*`default_value`.`position` AS `position_default`, */
`default_value`.`disabled` AS `disabled_default`
FROM `catalog_product_entity_media_gallery` AS `main`
LEFT JOIN `catalog_product_entity_media_gallery_value` AS `value`
ON main.value_id=value.value_id AND value.store_id=' . Mage::app()->getStore()->getId() . '
LEFT JOIN `catalog_product_entity_media_gallery_value` AS `default_value`
ON main.value_id=default_value.value_id AND default_value.store_id=0
WHERE (
main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
AND (main.entity_id IN (' . $_read->quote($_productCollection->getAllIds()) . '))
/*ORDER BY IF(value.position IS NULL, default_value.position, value.position) ASC */
';
$_mediaGalleryData = $_read->fetchAll($sql);
$_mediaGalleryByProductId = array();
foreach ($_mediaGalleryData as $_galleryImage) {
$k = $_galleryImage['entity_id'];
unset($_galleryImage['entity_id']);
if (!isset($_mediaGalleryByProductId[$k])) {
$_mediaGalleryByProductId[$k] = array();
}
$_mediaGalleryByProductId[$k][] = $_galleryImage;
}
unset($_mediaGalleryData);
foreach ($_productCollection as &$_product) {
$_productId = $_product->getData('entity_id');
if (isset($_mediaGalleryByProductId[$_productId])) {
$_product->setData('media_gallery', array('images' => $_mediaGalleryByProductId[$_productId]));
}
}
unset($_mediaGalleryByProductId);
}
}
return $_productCollection;
}

Categories