I am using the following snippet in my theme to get the logged-in user's avatar of the default wp user's setting page.
<?php echo get_avatar($id_or_email, $size='64', $default, $alt='User name' ); ?>
However, After installing the buddypress; I wanted to display the uploaded profile's photo of the user where the above snippet only shows the default wp avatar.
Any idea on how to achieve that?
You should enable both options:
<?php
if ( empty ( bp_loggedin_user_id() == false ) ) {
$user_id = bp_loggedin_user_id();
echo bp_core_fetch_avatar( array( 'item_id' => $user_id) );
} else {
echo get_avatar($id_or_email, $size='64', $default, $alt='User name' );
}
?>
Use the BuddyPress function bp_core_fetch_avatar
$user_id = bp_loggedin_user_id();
echo bp_core_fetch_avatar( array( 'item_id' => $user_id) );
Review the function in bp-core/bp-core-avatars.php to see the available arguments.
Related
I get all my products from an API and those who are variations to each other all share a custom meta key called "api_product_family". The products with the same api_product_family are variants to each other, so on the single page I have a hook where I display the other variants with image and anchor to it's variants.
My code:
function mv_variations() {
global $post;
global $wpdb;
$product_id = $post->ID;
$product_family = get_post_meta( $post->ID, 'api_product_family', true );
if(!empty($product_family)) {
$query = "
SELECT post_id
FROM " . $wpdb->prefix . "postmeta
WHERE meta_value = '" . $product_family . "'
";
$products = $wpdb->get_col($query);
if(count($products) > 0) {
for($i=0; $i<count($products); $i++) {
if($products[$i] == $product_id) {
unset($products[$i]);
}
}
if(count($products) > 0) {
print '<h3>Choose other variants: </h3>';
foreach($products as $product) {
$image = wp_get_attachment_image_src(get_post_thumbnail_id($product));
print '<img src="' . $image[0] . '" alt="img"/> ';
}
}
}
}
}
add_action( 'woocommerce_single_product_summary', 'mv_variations' );
The problem:
I have a LOT of posts, and a lot of post_meta's, so it's taking an eternity to load so I was thinking to move this whole function inside and AJAX call so it's doesn't slow down the initial load. The problem is that I have no idea how to do that with wordpress
Are you simply looking to run a WP function via AJAX?
1) Add ajax actions
This needs to run inside the main plugin file. If you run this only on the public code, it will not work. WP is a little weird and all ajax uses admin-ajax.php
if ( wp_doing_ajax() ){
add_action( 'wp_ajax_yourcustomfunction', array($this, 'yourcustomfunction') );
add_action( 'wp_ajax_nopriv_yourcustomfunction', array($this, 'yourcustomfunction') );
}
function yourcustomfunction(){
echo 'success';
exit();
}
2) In JavaScript
in the backend, you have the global: ajaxurl for the ajax url
BUT in the front end you need to pass this as a variable via wp_localize_script
$datatoBePassed = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
);
wp_localize_script( 'your_javascript_script', 'plugin_display_settings', $datatoBePassed );
In JS:
var datavar = {
action: 'yourcustomfunction',
};
$.post(plugin_display_settings.ajaxurl, datavar, function(response){
//response received here. It will be 'success' which is echoed in PHP
});
3)
If you also want to run a security nonce check (to check the request truly originates from the WP website, prevents some attacks), it gets a little more complicated:
$datatoBePassed should also include 'security' => wp_create_nonce( 'yourplugin_security_nonce' ),
datavar in JS includes security: plugin_display_settings.security,
Finally, your PHP custom function begins with:
// Check security nonce.
if ( ! check_ajax_referer( 'yourplugin_security_nonce', 'security' ) ) {
wp_send_json_error( 'Invalid security token sent.' );
wp_die();
}
// If security check passed, run further
So I think you might get better performance using WP_Query. Below I converted what you have into a custom WP_Query. May need some slight adjustment but should be the right direction.
function mv_variations() {
global $post_id;
// get current post "product family"
$product_family = get_post_meta( $post_id, 'api_product_family', true );
// build related "product family" products query
$products_query_args = array(
'post_type' => 'product', // may need to update this for your case
'posts_per_page' => -1, // return all found
'post__not_in' => array($post_id), // exclude current post
'post_status' => 'publish',
// use a meta query to pull only posts with same "product family" as current post
'meta_query' => array(
array(
'key' => 'api_product_family',
'value' => $product_family,
'compare' => '='
)
)
);
$products_query = new WP_Query($products_query);
// use "the loop" to display your products
if ( $products_query->have_posts() ) :
print '<h3>Choose other variants: </h3>';
while ( $products_query->have_posts() ) : $products_query->the_post();
print ''. wp_get_attachment_image() .'';
endwhile;
// restore global post
wp_reset_postdata();
endif;
}
add_action( 'woocommerce_single_product_summary', 'mv_variations' );
Good afternoon devs, I develop a project that consists of users profiles with a record created with fields from the ACF, including the image gallery field, my problem is ... as I only use one page to display this profile, the image gallery is makes it shared even with the option of "attached to the post", as I only use one page for this, example "/profile?userid=userid".
Is there any other good practice for doing this?
I would like suggestions.
one part profile edit
function acf_profile_edit( $atts ) {
$a = shortcode_atts( array(
'field_group' => ''
), $atts );
$uid = get_current_user_id();
if ( ! empty ( $a['field_group'] ) && ! empty ( $uid ) ) {
$options = array(
'post_id' => 'user_'.$uid,
'field_groups' => array( intval( $a['field_group'] ) ),
'return' => add_query_arg( 'updated', 'true', get_permalink() )
);
ob_start();
acf_form( $options );
$form = ob_get_contents();
ob_end_clean();
}
return $form;
}
add_shortcode( 'profile_edit', 'acf_profile_edit' );
Edit...
This code resolved my problem
add_filter('ajax_query_attachments_args', 'restrict_images_to_user');
function restrict_images_to_user($query) {
$gallery_images = 'field_5e4d799b34145';
$gallery_videos = 'field_5e5597e37f2c7';
if ( isset($_POST['query']['_acfuploader'] )
&& ( isset($_POST['query']['_acfuploader']) == $gallery_images || isset($_POST['query']['_acfuploader']) == $gallery_videos ) ) {
$author = get_current_user_id();
$query['author'] = $author;
}
return $query;
}
If you are using one page, use a page template called page-profile.php, the bit after page- must match the name of the page you have assigned.
Then use the WordPress Post Loop:
if (have_posts()) :
while (have_posts()) :
the_post();
the_content();
endwhile;
endif;
You can assign a username to the posts and the posts loop will only return the stuff associate with that username.
Another way would be to get the current username, then can you make an extra acf field with the username in and then do a check.
This is an example and will be exactly correct, but may be able to help you with suggestions.
If(content && username == currentuser)
{
$content = acf content;
}
then later in your page you can echo the content where you need it and will only be the content for the current username, or you can also do it with the user id.
I have found .canUser() method. But it returns undefined for me.
I'm calling it in UI with:
wp.data.select( 'core' ).canUser('create', 'users')
Where am I wrong?
Here are the docs for reference:
enter link description here
Is there any known plausible way to do it in JS UI plugin code itself? Or how did you do it maybe?
You need to use useSelect in order to achieve this:
wp.data.useSelect( (select) => select( 'core' ).canUser( 'create', 'users' ) );
After Analyzing Gutenberg source for a bit found out I was semi right.
The way to check this is around users (only admin can do that).
Here is how one could do it in Gutenberg UI Block code.
wp.data.select( 'core' ).canUser( 'create', 'users' )
THe only problem it did not work while the breakpoint was set.
You can use current_user_can() to check the user roles.
https://developer.wordpress.org/reference/functions/current_user_can/
function current_user_can( $capability ) {
$current_user = wp_get_current_user();
if ( empty( $current_user ) ) {
return false;
}
$args = array_slice( func_get_args(), 1 );
$args = array_merge( array( $capability ), $args );
return call_user_func_array( array( $current_user, 'has_cap' ), $args );
}
To check if the user is editor or administrator:
<?php if( current_user_can('editor') || current_user_can('administrator') ) { ?>
// Stuff here for administrators or editors
<?php } ?>
I am writing a 404.php for wordpress. I have the plugin 'rolescoper' installed, and some pages require the user be logged in to view. Rolescoper doesn't offer any way to distinguish between a page not found (404) and a permission denied (403).
I've been able to build this functionality into my pages using the following code:
$the_query = new WP_Query ( 'pagename=' . $_SERVER['REQUEST_URI'] );
$is_valid_page = ! empty ( $the_query -> queried_object -> post_title );
But, surprisingly, the same method does does not work for posts:
$args = array (
'post_type' => 'post',
'name' => str_replace ( "/", "", $_SERVER['REQUEST_URI'] )
);
$the_post_query = new WP_Query ( $args );
$is_valid_post = ! empty ( $the_post_query -> queried_object -> post_title );
When I do a var_dump on $the_post_query i get something that shows 0 results found. I am sure that the page I'm checking for exists.
Any idea how to use wp_query() to query for a post by slug?
Thanks!
After digging through the docs, I found that Rolescoper provided a nice function, is_restricted_rs(), for solving this problem:
//get the slug requested
$slug = $_SERVER [ 'REQUEST_URI' ];
//First check if it's a page and restricted
$page_id = get_page_by_path ( $slug )->ID;
$page_restricted = is_restricted_rs ( $page_id );
//Then check if it's a post and restricted
$args = array(
'name' => $slug,
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => 1
);
$my_posts = get_posts($args);
if ( $my_posts ) {
$post_id = $my_posts[0]->ID;
}
$post_restricted = is_restricted_rs ( $post_id );
//then set $content_restricted for use below
$content_restricted = $post_restricted || $page_restricted;
The rolescoper plugin has become defunct and we developed a solution which does not require any external plugin. Instead, we added some code to our theme and added a custom field to each page that we wanted to restrict access to.
This isn't as robust as rolescoper was, but for our use case it was perfect. We have only a few user classes and so I just hardcode the different classes and that's enough for us. I'm sure a similar solution could be used for more complex cases, especially if you expanded on the custom UI code.
I happened to name the field "dhamma_perms" but you could name it anything you want:
function is_restricted() {
return item_restricted(get_post(), wp_get_current_user());
}
function item_restricted($page, $user) {
$dhamma_perms = get_post_meta($page->ID, "dhamma_perms", true);
$requires_os = $dhamma_perms == "oldstudents";
$requires_worker = $dhamma_perms == "workers";
if (!is_user_logged_in()) {
return $requires_os || $requires_worker;
} else if (get_userdata($user->ID)->user_login == "oldstudent") {
return $requires_worker;
} else {
//dhammaworkers and all named users have full read access
return false;
}
}
I then modified any page which could be restricted to have code like this at the top:
<?php get_header(); ?>
<?php if (is_restricted()) : ?>
<?php show_404(); ?> //I just pasted the full content of our 404 page into a function. The 404 page shows a faux-403 page (WP doesn't have real 403 pages) if the content exists but is restricted.
<?php else: ?>
//show normal page stuff
I also modified the header.php to have a proper title for 404 and 403 pages:
<?php if (is_restricted()) : ?>
<title> <?php echo "Login Required " . get_theme_mod('dhamma_title_separator') . " " . get_bloginfo('name'); ?></title>
<?php else: ?>
<title><?php wp_title( get_theme_mod('dhamma_title_separator'), true, "right" ); bloginfo('name'); ?></title>
<? endif; ?>
Finally, I added a custom UI to posts and pages so it's easy to select permissions:
//Register the permissions metabox for posts and pages
function add_perms_box( $post ) {
$screens = [ 'post', 'page', 'wporg_cpt' ];
foreach ( $screens as $screen ) {
add_meta_box(
'dhamma_perms_box', // Unique ID
'Permissions', // Box title
'perms_box_html', // Content callback, must be of type callable
$screens // Post type
);
}
}
function perms_box_html() {
$value = get_post_meta(get_the_ID(), "dhamma_perms", true);
?>
<select name="dhamma_perms" id="dhamma_perms" class="postbox">
<option value="public" <?php selected($value, 'public');?>>Public</option>
<option value="oldstudents" <?php selected($value, 'oldstudents');?>>Old Students Only</option>
<option value="workers" <?php selected($value, 'workers');?>>Dhamma Workers Only</option>
</select>
<?php
}
add_action('add_meta_boxes', 'add_perms_box');
function dhamma_meta_save( $post_id ) {
// Checks save status
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
// Exits script depending on save status
if ( $is_autosave || $is_revision ) {
return;
}
// Checks for input and sanitizes/saves if needed
if( isset( $_POST[ 'dhamma_perms' ] ) ) {
update_post_meta( $post_id, 'dhamma_perms', $_POST[ 'dhamma_perms' ] );
}
}
add_action( 'save_post', 'dhamma_meta_save' );
This created a new dropdown on each page and post for us:
I hope this is helpful for anyone else trying to get some simple permissions on a wordpress site!
I've got two custom post types called Artists and Paintings. Both the post types have a custom field called artist name created using Advanced Custom Fields plugin. I need to be able to match the custom fields from both these post types, with each other, in order to display more information.
Pasting below only the args and loop from the query. Will post more of the code if it is necessary.
<?php
$artist_name = get_field('artist');
$args = array(
'post_type' => 'artists',
'meta_value' => $artist_name
);
$query_artist = new WP_Query( $args );
if ( $query_artist->have_posts() ) {
while ( $query_artist->have_posts() ) {
$query_artist->the_post(); ?>
<p class="artist-name"><?php the_title(); ?></p>
<?php }
} else {
echo 'Artist not found';
}
wp_reset_postdata(); ?>
This code works properly when in the template file for the homepage but always prints out 'Artist not found' when in the search results page. I copied this code directly from the homepage template so spelling mistakes are not the problem. Been breaking my head over this for a long time. Will anyone reading this have a clue on what's happening?
Thanks.
Ok, so I've managed to finally get what I want to work but I'm not sure why the below code worked and my original didn't since both of them are similar methods to do a new query.
Here's the code if anyone else had the same problem:
<?php
// Permalink for artist
$artist_name = get_field('artist');
global $post;
$posts = get_posts( array( 'post_type' => 'artists', 'meta_value' => $artist_name ) );
if( $posts ):
foreach( $posts as $post ) :
setup_postdata($post); ?>
<p class="artist-name"><?php the_title(); ?></p>
<?php endforeach;
wp_reset_postdata();
endif; ?>
I think that wordpress doesn't include custom types in the search automaticaly.
You can use a plugin like https://wordpress.org/plugins/advanced-custom-post-search/ or write your own function in the functions.php
function rc_add_cpts_to_search($query) {
// Check to verify it's search page
if( is_search() ) {
// Get post types
$post_types = get_post_types(array('public' => true, 'exclude_from_search' => false), 'objects');
$searchable_types = array();
// Add available post types
if( $post_types ) {
foreach( $post_types as $type) {
$searchable_types[] = $type->name;
}
}
$query->set( 'post_type', $searchable_types );
}
return $query;
}
add_action( 'pre_get_posts', 'rc_add_cpts_to_search' );
Example from http://www.remicorson.com/include-all-your-wordpress-custom-post-types-in-search/