How to custom user url in BuddyPress and WordPress? - wordpress

Thanks for support!
I need to custom user url in my page using WordPress and BuddyPress.
This is example:
From: (current)
http://example.com/user/pum_su411
To
http://example.com/user/548234
With 548234 is ID of the user.
I want after completed the custom, all users will have url like above automatically.
Thanks for all solutions!

add this code to your theme functions.php file.
function _bp_core_get_user_domain($domain, $user_id, $user_nicename = false, $user_login = false) {
if ( empty( $user_id ) ){
return;
}
if( isset($user_nicename) ){
$user_nicename = bp_core_get_username($user_id);
}
$after_domain = bp_get_members_root_slug() . '/' . $user_id;
$domain = trailingslashit( bp_get_root_domain() . '/' . $after_domain );
$domain = apply_filters( 'bp_core_get_user_domain_pre_cache', $domain, $user_id, $user_nicename, $user_login );
if ( !empty( $domain ) ) {
wp_cache_set( 'bp_user_domain_' . $user_id, $domain, 'bp' );
}
return $domain;
}
add_filter('bp_core_get_user_domain', '_bp_core_get_user_domain', 10, 4);
function _bp_core_get_userid($userid, $username){
if(is_numeric($username)){
$aux = get_userdata( $username );
if( get_userdata( $username ) )
$userid = $username;
}
return $userid;
}
add_filter('bp_core_get_userid', '_bp_core_get_userid', 10, 2);
function _bp_get_activity_parent_content($content){
global $bp;
$user = get_user_by('slug', $bp->displayed_user->fullname); // 'slug' - user_nicename
return preg_replace('/href=\"(.*?)\"/is', 'href="'.bp_core_get_user_domain($user->ID, $bp->displayed_user->fullname).'"', $content);
}
add_filter( 'bp_get_activity_parent_content','_bp_get_activity_parent_content', 10, 1 );
function _bp_get_activity_action_pre_meta($content){
global $bp;
$fullname = $bp->displayed_user->fullname; // 'slug' - user_nicename
$user = get_user_by('slug', $fullname);
if(!is_numeric($user->ID) || empty($fullname)){
$args = explode(' ', trim(strip_tags($content)));
$fullname = trim($args[0]);
$user = get_user_by('slug', $fullname);
}
return preg_replace('/href=\"(.*?)\"/is', 'href="'.bp_core_get_user_domain($user->ID, $fullname).'"', $content);
}
add_action('bp_get_activity_action_pre_meta', '_bp_get_activity_action_pre_meta');
add_filter('bp_core_get_userid_from_nicename', '_bp_core_get_userid', 10, 2);

Just spent a bit of time going over the documentation, codex and files of BuddyPress and i can find ways of changing the /user/ part of the url but sadly not the /username side of it.
Reading through, it is controlled within the core of BuddyPress and any changes to the core can cause crashes and more than likely to cause problems or overwrites further down the line.
This isn't to say it's not possible though, it is most certainly possible, but it will require a great deal of editing to many many different files, an edit to a number of BuddyPress functions and there are no guarantee's on it working straight out or even working further down the line when files get update.
I would recommend going onto the BuddyPress Trac and putting in a ticket to have the feature added to change user url structure. It would be a cool feature to be able to swap between a username, full name, ID or any other unique identifiable string.
You can access it here: https://buddypress.trac.wordpress.org/
Alternatively, you can try what aSeptik has done above, but make sure to update that file with any changes when BuddyPress updates as well.

Related

how to change edit url with "Id" to edit url with "Slug" in Wordpress

I have this is WordPress Post editing Url:
https://example.com/wp-admin/post.php?post=ID&action=edit
and I want to change it to Slug Not the ID Like This:
https://example.com/wp-admin/post.php?post=Slug&action=edit
I was trying to edit the post with this Url but is not working:
https://example.com/wp-admin/post.php?post=MyPostSlug&action=edit
In order to change the edit post link structure, you can use the get_edit_post_link filter like so:
add_filter( 'get_edit_post_link', 'so_73914075_get_edit_post_link', 10, 3);
function so_73914075_get_edit_post_link($link, $post_id, $context) {
$post = get_post( $post_id );
if ( ! in_array( $post->post_type, array( 'post', 'page' ) ) ) {
return $link;
}
$post_type_object = get_post_type_object( $post->post_type );
if ( 'revision' === $post->post_type ) {
$action = '';
} elseif ( 'display' === $context ) {
$action = '&action=edit';
} else {
$action = '&action=edit';
}
if ( 'display' === $context ) {
$post_type = '&post-type=' . $post->post_type;
} else {
$post_type = '&post-type=' . $post->post_type;
}
$custom_edit_link = str_replace( '?post=%d', '?post-name=%s', $post_type_object->_edit_link );
return admin_url( sprintf( $custom_edit_link . $action . $post_type, $post->post_name ) );
}
This will change the edit links for regular posts and pages to something like this:
https://example.com/wp-admin/post.php?post-name=the-post-slug&action=edit&post-type=post
WARNING: make sure you limit this to only the post types you need to change the URL for. Making this change global will almost surely
have unintended effects over other plugins
However, making the admin panel actually load the edit screen is not that easy.
Looking at the source code of the wp-admin/post.php file, you will see that there is no way to hook into the flow and populate the $post_id variable with the post id matching the slug you are sending through.
That means you have 2 options:
RECOMMENDED Update the edit link to whatever format you want and then create an admin redirect function that pulls the slug from the initial URL and redirects to the actual edit page with the ?post=%d in it.
NOT RECOMMENDED Create a new admin edit page that will understand your URL structure and include the wp-admin/post.php after the code that pulls the $post_id based on the slug.
The 2nd method might come with lots of extra code you need to write to cover all the cases and all the instances a post reaches the post.php in the admin panel

Create a Cron job after every post publish

I have a situation where i want to create a cron job after every WordPress blog post publish. Cron job will run after 7 days of publishing post and check if all the users have viewed the posts and email the list of not viewed post by users list. How can i achieve this. Its a WordPress website and there are around 300+ users, after each blog post publish user gets notification. So want to check who has viewed and who has not viewed the post.
If you want to start the cron job only the first time a post is published, you'll want to use the draft_to_publish hook.
draft_to_publish
Well there are Plugins capable of managing Stats and tracking users activities. I'm not sure which one fit to your needs but I'll try to give a simple approach to do it by yourself.
Tracking
We can set a custom field for those (posts/post-types) where we will store a list of users who read that post. Let's call it readerslist
On the single.php file we will add these lines to Update this field.
$list = explode(',',get_post_meta($post->ID, 'readerslist', true));
$user = get_current_user_id();
if (!in_array($user,$list)){
array_push($list, $user);
update_post_meta( $post->ID, 'readerslist', implode(",", $list) );
}
Now that we can retrieve who viewed the article? We could later find those who didn't read it yet.
Then in functions.php we could set up a hook that will execute when a post get published, to set a single scheduled cron job to send the absent readers.
<?php
function wpdocs_run_on_publish_only( $new_status, $old_status, $post ) {
{
if ($new_status != 'publish') {
return;
}
//You better add limitations to choose specific post_types you are targeting
$postid=$post->ID;
add_cron($postid);
}
add_action( 'transition_post_status', 'wpdocs_run_on_publish_only', 10, 3 );
function add_cron($postid){
$nxtweek = strtotime("+1 week");
add_action('sendemail', 'stats_mail', 10, 1);
wp_schedule_single_event(time() + $nxtweek, 'sendemail',array( $postid);
}
function stats_mail($postid)
{
$readerslist = get_post_meta( $postid, 'readerslist', true );
$users = get_users( array( 'fields' => array( 'ID' ) ) );
$absents = array_diff($users, explode(",",$readerslist));
//Now that you got the list of absent users
$names='';
foreach ($absents as $x){
$names.=$x.' : '.get_user_meta( $x,'first_name' , true ).' '.get_user_meta( $x,'last_name' , true ).'<br>';
}
$title=get_the_title($postid);
$to = 'you#example.com';
$subject = 'Users who didn\'t read '.$title;
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail( $to, $subject, $names, $headers );
}
?>
Notice : I didn't tested the above code ! I made you this in order to show you how to do it. But there isn't much work to do here. Good luck
I tried your code, it works fine, but i am not able to make it working as i wanted, can you look into it. I don't know what i am doing wrong.
function wpdocs_run_on_publish_only( $new_status, $old_status, $post ) {
if ($new_status != 'publish') {
return;
}
$postid=$post->ID;
add_cron($postid);
}
add_action( 'transition_post_status', 'wpdocs_run_on_publish_only', 10, 3 );
function add_cron($postid){
$nxtweek = strtotime("+1 week");
add_action('sendemail', 'stats_mail', 10, 1);
if ( ! wp_next_scheduled( 'sendemail') ) {
wp_schedule_event(time() + $nxtweek, $nxtweek, 'sendemail', array($postid));
// i want to run cron every 7 days from the date of publishing post, until all user reads it, i tried this code but not working.
// wp_mail( 'email#company.com', $postid, 'test', null );
// For testing purpose if i send mail from here, it goes.
}
}
function stats_mail($postid) {
wp_mail( 'email#company.com', $postid, 'test', null );
// this doesnt work.
$readerslist = get_post_meta( $postid, 'readerslist', true );
$users = get_users( array( 'fields' => array( 'ID' ) ) );
$absents = array_diff($users, explode(",",$readerslist));
//Now that you got the list of absent users
$names='';
foreach ($absents as $x){
$names.=$x.' : '.get_user_meta( $x,'first_name' , true ).' '.get_user_meta( $x,'last_name' , true ).'<br>';
}
$title=get_the_title($postid);
$to = 'email#company.com';
$subject = 'Users who didn\'t read '.$title;
$headers = array('Content-Type: text/html; charset=UTF-8');
//wp_mail( $to, $subject, $names, $headers );
}

How to mark wordpress posts as read?

I want to make something similar to what Techcrunch have on their site. For now I use wordpress plugin that mark posts as new and think to modified it to achieve similar functionality but the plugin won't work for ajax loading.
What I want to make is when user open new post, automatically after he returns to the front page, title and excerpt of the post to be color faded. How to make this with setting cookie and make it to work for title and excerpt on any page (for post list, grids etc.), instead of single post page. And also I need this to work when new posts are loaded with ajax.
I tried this function and It's work ok, but now I need text label to change to Old after user open the post, and then to inject some css to the title. Also, this is not perfect, because I want all posts to be New on first visit, an then to change to Old after user open them.
function wpb_lastvisit_set_cookie() {
if ( ! is_admin() && ! isset( $_COOKIE['lastvisit'] ) ) {
setcookie( 'lastvisit', $current, time() + 3600 * 24 * 100, COOKIEPATH, COOKIE_DOMAIN, false );
}
}
add_action( 'init', 'wpb_lastvisit_set_cookie');
function wpb_lastvisit_the_title ( $title, $id ) {
if ( !in_the_loop() || is_singular() || get_post_type( $id ) == 'page' ) return $title;
// if no cookie then just return the title
if ( !isset($_COOKIE['lastvisit']) || $_COOKIE['lastvisit'] == '' ) return $title;
$lastvisit = $_COOKIE['lastvisit'];
$publish_date = get_post_time( 'U', true, $id );
if ($publish_date > $lastvisit) $title .= ' New';
if ($publish_date < $lastvisit) $title .= ' Old';
return $title;
}
add_filter( 'the_title', 'wpb_lastvisit_the_title', 10, 2);

after setup theme action creating issue with nonce in wordpress 4.3.1

I am using add_action( 'after_setup_theme', 'custom_login' ); hook in one of my website for auto redirect user to his dashboard page.
Here is my code :---
function custom_login($username, $password='') {
$creds = array();
$creds['user_login'] = $username;
$creds['user_password'] = $password;
$creds['remember'] = true;
$user = wp_signon( $creds, false );
if ( is_wp_error($user) ){
echo $user->get_error_message();
}
}
// run it before the headers and cookies are sent
add_action( 'after_setup_theme', 'custom_login' );
Its working fine on old version, But now I have upgrade wordpress version and its creating problem with nonce.
Are you sure you want to do this?
Everytime this error display on the screen when I do anything like update plugin, theme and permalinks.
When I comment this code then website working fine except auto redirect functionality.
Here is my website url :- https://www.linearrecruitment.co.uk/
Please help me where I do mistake.
That's a normal behaviour - nonce is a token used by Wordpress to check the validity of the form in order to prevent CSRF attacks.
A valid login form in Wordpress should have an hidden input field generated with wp_nonce_field:
wp_nonce_field('my_login_form');
Then in the login function the token is checked with the wp_verify_nonce function:
if (!isset($_POST['my_login_form']) || !wp_verify_nonce($_POST['_wpnonce'], 'my_login_form')) {
die('Invalid form');
}
What you're trying to do (auto login) is done wrong as add_action doesn't send any parameter for the after_setup_theme hook, so your username is probably empty. I don't know how this could possibly work before, maybe it managed to log in somehow with an empty username.
I suggest you to declare some globals vars for your username and password, as it seems to be static inputs:
global $username, $password;
$username = 'my_login';
$password = 'my_password';
And then on the beginning of your function import those globals with:
global $username, $password;
So what about the nonce?
On the last versions of Wordpress, the check_admin_referer have changed a bit, from:
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) {
wp_nonce_ays($action);
die();
}
do_action( 'check_admin_referer', $action, $result );
return $result;
}
To :
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
do_action( 'check_admin_referer', $action, $result );
if ( ! $result && ! ( -1 == $action && strpos( $referer, $adminurl ) === 0 ) ) {
wp_nonce_ays( $action );
die();
}
return $result;
}
As you can see they moved the check_admin_referer hook - now we can change the value of $result before the wp_nonce_ays function (the one that display the message you try to get rid of) as been called.
That mean we could add the following hook in the theme functions.php in order to force the nonce validation:
add_action( 'check_admin_referer', array('custom_check_admin_referer' ) );
function custom_check_admin_referer() {
return 1;
}
That should work around your problem, but you must be aware that this could possibly be a security issue - you maybe want to do more test in that function before returning 1.

Change user profile URL in Buddypress with nickname or userID

I am using this code which is partially working for changing the profile url everywhere in buddypress and wordpress from “http:/mywebsite/user/username” to “http:/mywebsite/user/userid”
function _bp_core_get_user_domain($domain, $user_id, $user_nicename = false, $user_login = false) {
if ( empty( $user_id ) ){
return;
}
if( isset($user_nicename) ){
$user_nicename = bp_core_get_username($user_id);
}
$after_domain = bp_get_members_root_slug() . '/' . $user_id;
$domain = trailingslashit( bp_get_root_domain() . '/' . $after_domain );
$domain = apply_filters( 'bp_core_get_user_domain_pre_cache', $domain, $user_id, $user_nicename, $user_login );
if ( !empty( $domain ) ) {
wp_cache_set( 'bp_user_domain_' . $user_id, $domain, 'bp' );
}
return $domain;
}
add_filter('bp_core_get_user_domain', '_bp_core_get_user_domain', 10, 4);
function _bp_core_get_userid($userid, $username){
if(is_numeric($username)){
$aux = get_userdata( $username );
if( get_userdata( $username ) )
$userid = $username;
}
return $userid;
}
add_filter('bp_core_get_userid', '_bp_core_get_userid', 10, 2);
function _bp_get_activity_parent_content($content){
global $bp;
$user = get_user_by('slug', $bp->displayed_user->fullname); // 'slug' - user_nicename
return preg_replace('/href=\"(.*?)\"/is', 'href="'.bp_core_get_user_domain($user->ID, $bp->displayed_user->fullname).'"', $content);
}
add_filter( 'bp_get_activity_parent_content','_bp_get_activity_parent_content', 10, 1 );
add_filter('bp_core_get_userid_from_nicename', '_bp_core_get_userid', 10, 2);
It is working perfectly for me at the moment BUT not on this little place (see picture):
http://i.imgur.com/4dX0RUB.png
– url change of the author of an activity starting-message is not working in both groups activities and personnal activities
url change of the author of an activity REPLY is working
I don’t know if I am explaining very well what issue I have got but I hope you will understand.
Thank you for your answers
PS : thanks to aSeptik from StackExchange for the code
It's impossible to do that on a fly gracefully. BuddyPress Activity component is developed in such a way, that those text with the user link in activity stream (for site-wide, personal and groups) is stored directly in the database as an action. Just take a look at wp_bp_activity.action field in your DB.
So you should filter and preg_replace it as well. I guess you know that you are penalting yourself with rendering speed loss.

Resources