Problems with multisite, wp_get_sites, and WP_Query

The goal is to have a list of all the sites, sorted by last name (in ASC order - a, b,c and so on), and displaying certain custom fields. The problem I'm facing is that since it's NOT a post type, (it's pulling from a specific profile page that is using solely custom fields) it doesn't allow me any type of sorting. It also doesn't recognize the limit 10.

I just feel like I'm missing something.

It DOES display the photo, first and last names, country, and bio.

<?php

$blog_list = wp_get_sites();
foreach ($blog_list as $blog) {
	switch_to_blog($blog['blog_id']);
	$args = array(
	'post_type'              =>'page',
        'pagename'               => 'profile',
        'posts_per_page'         => '10',
        'order'                  => 'ASC',
        'orderby'                =>'meta_value',
        'meta_key'               =>'speaker_last_name',
	);

	$query = new WP_Query( $args );

	while ($query->have_posts()) :
		$query->the_post();
				?>
<div class="individual">
<a href="<?php echo site_url(); ?>"><img src="<?php the_field('photo'); ?>" alt="<?php the_field('first_name'); ?> <?php the_field('last_name'); ?>" class="alignleft" /></a>
<div class="intro"><a href="<?php echo site_url(); ?>"><h2><?php the_field('first_name'); ?> <?php the_field('last_name'); ?></h2></a>
Lives in: <?php the_field('country'); ?>
<?php the_field('bio'); ?></div>
<a href="<?php echo site_url(); ?>">View this Speakers Profile</a>
<br style="clear:both" />
</div>

<?php
	endwhile;
	restore_current_blog();
}
wp_reset_query();
?>
  • Tyler Postle
    • CGO

    Hey Jake,

    Hope you're doing well today!

    We actually have a Blogs directory plugin to list all the sites in a multisite and it comes with the option to sort it :slight_smile: you could look into the plugin code if you wanted to keep going with your own custom solution.

    Just a note as well, our Avatars plugin also integrates with Blog Directory so you can give your blogs an avatar.

    If you're still having trouble here, then I can see if one of our coding experts could provide any further direction for you :slight_smile:

    Hope this helps! Have a great weekend, Happy Easter.

    All the best,
    Tyler

  • Jake Marcus
    • WPMU DEV Initiate

    Hi! I tried BOTH of those options actually.

    Basically the Blogs directory plugin doesn't recognize my plugin fields, or I would have gone with that option. I played with the Avatars plugin but I have zero use for it.

    My set up is for people to have access to a custom profile type of page and some custom post types.

    Code from the Blogs directory plugin to try and use my custom field (didn't work, just gives an empty img src).
    $content .= '<td style="background-color:' . $bg_color . '; padding-top:10px;" valign="top" width="10%"><center><a style="text-decoration:none;" href="http://' . $blog['domain'] . $blog['path'] . '"><img src="' . get_field('photo') . '" /></a></center></td>';

    I would really appreciate it if you could do that, get one of your coding experts to see where I'm going wrong in my original code.

  • Jake Marcus
    • WPMU DEV Initiate

    I also tried doing it as a custom post type (set one up for testing purposes) and still unable to:
    1. orderby anything
    2. limit number of posts

    So those would be my biggest issues. Being able to orderby ANYTHING (in this case last name) and being able to limit the number of posts. I don't need pagination but I do want to control the number of posts displayed.

    <?php
    
    $blog_list = wp_get_sites();
    foreach ($blog_list as $blog) {
    	switch_to_blog($blog['blog_id']);
    	$args = array(
    	'post_type'              =>'fancyprofiletest',
            'posts_per_page'         => '2',
            'order'                  => 'ASC',
            'orderby'                =>'meta_value',
            'meta_key'               =>'speaker_last_name',
    	);
    
    	$query = new WP_Query( $args );
    
    	while ($query->have_posts()) :
    		$query->the_post();
    				?>
    <div class="individual">
    <a href="<?php echo site_url(); ?>"><img src="<?php the_field('photo'); ?>" alt="<?php the_field('first_name'); ?> <?php the_field('last_name'); ?>" class="alignleft" /></a>
    <div class="intro"><a href="<?php echo site_url(); ?>"><h2><?php the_field('first_name'); ?> <?php the_field('last_name'); ?></h2></a>
    Lives in: <?php the_field('country'); ?>
    <?php the_field('bio'); ?></div>
    <a href="<?php echo site_url(); ?>">View this Profile</a>
    <br style="clear:both" />
    </div>
    
    <?php
    	endwhile;
    	restore_current_blog();
    }
    wp_reset_query();
    ?>
  • Jake Marcus
    • WPMU DEV Initiate

    OK, I've found I can force a limit this way

    $args2 = array(
    'public'	=> true,
    'limit' => 2
    );
    $blog_list = wp_get_sites( $args2 );

    Which funny enough limits to ONE, not two... but I will take it.

    I still can't get orderby to work. Even doing

    'orderby' =>'rand',

    Doesn't work.

  • Jake Marcus
    • WPMU DEV Initiate

    Another option! (Feeling like I'm just talking to myself at this point!)
    So I chose a different route and created a function instead. THE ONLY ISSUE is pulling the custom fields (data). I see the table in the database (wp_network_postmeta) and the data is there but... I can't access it?

    I've tried:
    get_network_postmeta($post->ID, 'awesomefield');
    network_get_post_meta($post->ID, 'awesomefield');
    get_post_meta($post->ID, 'awesomefield');

    None of them work.

    Here's the full function:

    function display_awesome_posts($tmp_title_characters = 0) {
    
    	global $network_query, $network_post;
    
    	$network_query = network_query_posts( array( 'post_type' => 'awesome', 'posts_per_page' => 1 ));
    	if( network_have_posts() ) {
    
    		while( network_have_posts()) {
    			network_the_post();
    
    			switch_to_blog($network_post->BLOG_ID);         
    
    get_network_postmeta($post->ID, 'awesomefield');
    	        restore_current_blog();
    
    			ob_start();
    			?>
    			<a href="<?php echo network_the_permalink(); ?>" post_ID="<?php echo network_get_the_ID() ?>" blog_ID="<?php echo $network_post->BLOG_ID ?>">
    
    					<h3 class="name"><?php echo network_get_the_title(); ?></h3>
    
    <?php echo get_network_postmeta($post->ID, 'awesomefield', true); ?>
    
    			</a>
      <?php }
    		$html .= ob_get_contents();
    		ob_end_clean();
    	}
    return $html;
    }
  • Jake Marcus
    • WPMU DEV Initiate

    Ok! So at the end of the day the only issues I'm having is orderby not working and pulling in the image URL. For the image issue, the meta_value is numerical, so for example the custom field or meta_key is awesomephoto and the meta_value is 7. How do I find and pull in the custom field photo URL location instead? The following snippet works for all TEXT based fields (so far anyway!).

    <?php switch_to_blog($network_post->BLOG_ID); print_r(get_post_meta( network_get_the_ID(), 'awesome_photo', true ) ); restore_current_blog();?>

    And here's the full function so far. I wish there were a far easier way of doing this!

    function display_recent_posts($tmp_title_characters = 0) {
    
    	global $network_query, $network_post;
    
    	$network_query = network_query_posts( array( 'post_type' => 'awesome', 'posts_per_page' => 2 ));
    	if( network_have_posts() ) {
    
    		while( network_have_posts()) {
    			network_the_post();
    
    			switch_to_blog($network_post->BLOG_ID);
    	        restore_current_blog();
    
    			ob_start();
    			?>
    <div class="awesomeness">
    <a href="<?php echo network_get_permalink() ?>" post_ID="<?php echo network_get_the_ID() ?>" blog_ID="<?php echo $network_post->BLOG_ID ?>"><h3 class="name"><?php echo network_get_the_title(); ?></h3></a>
    
    <h2><?php switch_to_blog($network_post->BLOG_ID);  print_r(get_post_meta( network_get_the_ID(), 'awesome_first_name', true ) );  restore_current_blog();?> <?php switch_to_blog($network_post->BLOG_ID);  print_r(get_post_meta( network_get_the_ID(), 'awesome_last_name', true ) );  restore_current_blog();?></h2>
    
    <img src="<?php the_field('awesome_photo'); ?>" alt=" class="alignleft" />
    <div class="awesome"><a href="<?php echo site_url(); ?>"><h2><?php the_field('awesome_first_name'); ?> <?php the_field('awesome_last_name'); ?></h2></a>
    <br />
    <?php switch_to_blog($network_post->BLOG_ID);  print_r(get_post_meta( network_get_the_ID(), 'awesometextarea', true ) );  restore_current_blog();?>
    </div>
    <a href="<?php echo network_get_permalink() ?>">View this Profile</a>
    <br style="clear:both" />
    </div>
    
      <?php }
    		$html .= ob_get_contents();
    		ob_end_clean();
    	}
    return $html;
    }
  • Jake Marcus
    • WPMU DEV Initiate

    I talk through my process, hopefully this will all help someone some day LOL!

    Instead of using the custom field for the image in my custom post type, I instead went with the featured image default. I managed to pull that info.

    I believe the ONLY ISSUE I still can't fix is the orderby.

    I need orderby RAND to work and order by custom field (for two different queries).

  • Jake Marcus
    • WPMU DEV Initiate

    Hopefully since it's no longer the weekend someone can assist me!

    My original code to format my custom date field (which is stored as yyyymmdd) won't work in this situation however I don't know how to change the format with print_r

    Original
    <?php $date = DateTime::createFromFormat('Ymd', get_field('custom_date'));echo $date->format('m-d-Y'); ?></div>

    Code that pulls in the data from the custom field but I don't know how to change the format display (so it shows for example, April 6, 2015 rather than 20150406).

    <?php switch_to_blog($network_post->BLOG_ID); print_r(get_post_meta( network_get_the_ID(), 'custom_date', true ) ); restore_current_blog();?></div>

  • Jude
    • DEV MAN

    Hey Jake

    So sorry about the monlogue and our response times on this one. Here is how you can fix your date issue

    $date = date("Y M d", strtotime(get_post_meta( network_get_the_ID(), 'custom_date', true )));

    Then $date will have your date in the format you want .

    Cheers
    Jude

  • Jake Marcus
    • WPMU DEV Initiate

    Sort of works! Here's the code that works properly for pulling the information from the post_meta (custom field) in case anyone else needs it.

    <?php switch_to_blog($network_post->BLOG_ID);  $date = date("Y M d", strtotime(get_post_meta( network_get_the_ID(), 'custom_date_field', true ))); restore_current_blog(); ?>
    
    <?php echo $date ?>
  • Jude
    • DEV MAN

    Here is an example on using the date query class. This pulls posts between now and 30 days from now

    $args = array(
        'post_type' => 'post',
        'tax_query' => array(
            array(
                'taxonomy'  => 'post_format',
                'field'     => 'slug',
                'terms'     => array( 'post-format-image' )
            )
        ),
        'cat'           => '-173',
        'post_status'   => 'publish',
        'date_query'    => array(
            'column'  => 'post_date',
            'after'   => '+ 30 days'
        )
    );
    $query = new WP_Query( $args );

    Modify and use in your own code

    Cheers
    Jude

  • Jude
    • DEV MAN

    Hi there @Jake Marcus

    In that case you'd need to have $start_date and $end_date as variables and rewrite the query as

    $args = array(
        'post_type' => 'post',
        'tax_query' => array(
            array(
                'taxonomy'  => 'post_format',
                'field'     => 'slug',
                'terms'     => array( 'post-format-image' )
            )
        ),
        'cat'           => '-173',
        'post_status'   => 'publish',
        'date_query'    => array(
            'column'  => 'post_date',
            'before'   => $start_date,
            'after'   => $end_date
        )
    );
    $query = new WP_Query( $args );

    Jude

  • Jake Marcus
    • WPMU DEV Initiate

    Ok, since the date situation is not important we will skip it.

    How do I EXCLUDE the main site of the multisite from this function?

    function display_mystuff($tmp_title_characters = 0) {
    
    	global $network_query, $network_post;
    remove_all_filters('posts_orderby');
    
    $network_query = network_query_posts( array( 'post_type' => 'awesome','orderby'=>'rand','posts_per_page' => 1 ));
    
    	if( network_have_posts() ) {
    
    		while( network_have_posts()) {
    			network_the_post();
    
    			switch_to_blog($network_post->BLOG_ID);         
    
    	    		        $featured_image_id = get_post_thumbnail_id(network_get_the_ID());
    		        $featured_image_src = '';
    		        if ($featured_image_id) {
    		            $featured_image_src = array_shift(wp_get_attachment_image_src($featured_image_id, 'thumbnail'));
    		        }
    	        restore_current_blog();
    			ob_start();
    			?>
    Stuff and what not here
      <?php }
    		$html .= ob_get_contents();
    		ob_end_clean();
    	}
    return $html;
    }
  • Jake Marcus
    • WPMU DEV Initiate

    I've tried doing this

    add_filter( 'network_posts_where', 'exclude_blogs', 10, 2 );
    
    	function exclude_blogs( $where, Network_Query $query ) {
    		return !empty( $query->query_vars['blogs_not_in'] )
    			? $where . sprintf( ' AND %s.BLOG_ID NOT IN (%s) ', $query->network_posts, implode( ', ', (array)$query->query_vars['blogs_not_in'] ) )
    			: $where;
    	}

    And adding them as such 'post_status'=> 'published','blogs_not_in'=> array( 1 )

    But that doesn't work. The function I posted above still pulls in a blank "post" that doesn't EXIST anywhere.

  • Jake Marcus
    • WPMU DEV Initiate

    Even more weird. I basically have the same function (different function name and showing all posts instead of 1 and order by ASC but everything else the exact same) on a different page and this mysterious "blank" post doesn't show up there.

    Help (fast help!) would be greatly appreciated.

  • Jude
    • DEV MAN

    Hi again @Jake Marcus

    Sorry the response took a while longer than expected. I had connectivity issues and was out of action for a bit. Appreciate your patience.

    This is really strange, I have a feeling its something simple but I've lost the big picture because of the fragmentation. Can you post the whole code here or as a Gist and post the link here.

    Please post what's on both pages as is so I can take a closer look

    Cheers
    Jude

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.