I'm a Laravel developer. I develop one ecommerce plugin with Laravel and I just want to combine WordPress with Laravel. So I need to share or make common login session between Laravel and WordPress.
How could I implement this? And are there special plugins available for this? Or could I use laravel-Auth?
The right way of doing it is to Have a Laravel (or Wordpress) as an Auth server
And create like an SSO plugin.
I was doing the same with NodeBB Forum login from Laravel.
Steps that I suggest:
Look at this package Laravel OAuth Server
Create or find any SSO plugin for wordpress
So you have all users in laravel (Registration and etc)
and if they want to login to Wordpress they login to Laravel App and give permission to login to wordpress.
Think of it Like you add Facebook Login to your site
Reading more for wordpress SSO
But to play with session and cookies it can be security issues.
Hope Helped.
Enabling Single-Sign-On in WordPress took me 18+ hours of struggle but might take you only a few minutes:
I experimented with all sorts of things: Laravel Passport (OAuth2), OpenID Connect, etc.
But the only solution I could get to work was to have the WordPress login page redirect to an auth-protected Laravel route that generates a JWT (JSON Web Token) and redirects back to a special callback URL on WordPress that either creates a new user or logs in an existing user.
It works well.
class JwtController extends Controller {
/**
* Inspired by https://github.com/WebDevStudios/aad-first-party-sso-wordpress/tree/master/lib/php-jwt
*
* #param Request $request
* #return ResponseInterface
*/
public function redirectWithToken(Request $request) {
$key = config('jwt.key');
$wpJwtUrl = $request->input('callback');
$redirectUrlAfterLogin = $request->input('redirect_to'); //Get the original intended destination and append as URL param to /jwt.
$tokenArray = $this->getToken(auth()->user(), $redirectUrlAfterLogin);
$jwt = \Firebase\JWT\JWT::encode($tokenArray, $key);
$wpJwtUrlWithTokenAsParam = $wpJwtUrl . '?token=' . $jwt;
return redirect()->away($wpJwtUrlWithTokenAsParam);
}
/**
*
* #param \App\User $user
* #param string $redirectUrlAfterLogin
* #return array
*/
public function getToken($user, $redirectUrlAfterLogin) {
$now = \Carbon\Carbon::now();
$aud = config('jwt.audience'); //root URL of the WordPress site
$firstName = StrT::getFirstNameFromFullName($user->name);
$expirationMins = config('jwt.expirationMins');
$token = [
"iss" => url("/"),
"aud" => $aud, //"audience" https://tools.ietf.org/html/rfc7519#section-4.1.3
"iat" => $now->timestamp, //"issued at" https://tools.ietf.org/html/rfc7519#section-4.1.6
"exp" => $now->addMinutes($expirationMins)->timestamp, //"expiration" https://tools.ietf.org/html/rfc7519#section-4.1.4
"attributes" => [
'emailAddress' => $user->email,
'firstName' => $firstName,
'lastName' => StrT::getLastNameFromFullName($user->name),
'nickname' => $firstName,
'displayName' => $user->name,
'redirectUrlAfterLogin' => $redirectUrlAfterLogin//In plugin: use redirectUrlAfterLogin from attributes after login.
]
];
return $token;
}
}
Install this WordPress plugin, but don't activate it until you're finished with everything else: https://wordpress.org/plugins/wp-force-login/
Install this WordPress plugin: https://as.wordpress.org/plugins/jwt-authenticator/
And then edit its auth.php to be this:
// register the callback
add_action('rest_api_init', function () {
register_rest_route('jwt-auth/v1', 'callback', [
'methods' => 'GET',
'callback' => 'ja_login'
], true);
});
require_once('JWT.php');
function ja_login() {
//get all attributes
$options = get_option('ja_settings');
$token_name = $options['token_name'];
$secret_key = $options['secret_key'];
$iss = $options['iss'];
$aud = $options['aud'];
// decode the token
$token = $_GET[$token_name];
$key = $secret_key;
$JWT = new JWT;
$json = $JWT->decode($token, $key);
$jwt = json_decode($json, true);
// use unix time for comparision
$exp = is_int($jwt['exp']) ? $jwt['exp'] : strtotime($jwt['exp']);
$nbf = $jwt['nbf'] ?? null;
$now = strtotime("now");
// if authentication successful
if (($jwt['iss'] == $iss) && ($jwt['aud'] == $aud) && ($exp > $now) && ($now > $nbf)) {
return getUserFromValidToken($options, $jwt);
} else {
return 'Login failed. Please let us know exactly what happened, and we will help you out right away.';
}
}
/**
*
* #param array $options
* #param array $jwt
* #return string
*/
function getUserFromValidToken($options, $jwt) {
$attributesKey = $options['attributes'];
$mail = $options['mail'];
$givenname = $options['first_name'];
$surname = $options['last_name'];
$nickname = $options['nickname'];
$displayname = $options['displayname'];
$default_role = $options['default_role'];
$attributes = $jwt[$attributesKey];
$redirectUrlAfterLogin = $attributes['redirectUrlAfterLogin'] ?? get_site_url();
$_SESSION['attributes'] = $attributes;
$_SESSION['jwt'] = $jwt;
// find or create user
$user = ja_find_or_create_user($attributes[$mail], $attributes[$mail], $attributes[$givenname], $attributes[$surname], $attributes[$nickname], $attributes[$displayname], $default_role);
// login user
if ($user) {
wp_clear_auth_cookie();
wp_set_current_user($user->ID, $user->user_login);
wp_set_auth_cookie($user->ID);
do_action('wp_login', $user->user_login);
wp_safe_redirect($redirectUrlAfterLogin);
exit();
} else {
return 'getUserFromValidToken failed!';
}
}
/**
*
* #param string $username
* #param string $emailAddress
* #param string $firstName
* #param string $lastName
* #param string $nickname
* #param string $displayName
* #param string $defaultRole
* #return mixed
*/
function ja_find_or_create_user($username, $emailAddress, $firstName, $lastName, $nickname, $displayName, $defaultRole) {
// if user exists, return user
if (username_exists($username)) {
return get_user_by('login', $username);
} elseif (email_exists($emailAddress)) {
return get_user_by('email', $emailAddress);
} else {// create user
$length = 16;
$include_standard_special_chars = false;
$random_password = wp_generate_password($length, $include_standard_special_chars);
// create user
$user_id = wp_create_user($username, $random_password, $emailAddress);
// update user metadata and return user id
$userData = [
'ID' => $user_id,
'first_name' => $firstName,
'last_name' => $lastName,
'nickname' => $nickname,
'display_name' => $displayName,
'role' => $defaultRole
];
return wp_update_user($userData);//(If successful, returns the user_id, otherwise returns a WP_Error object.)
}
}
/**
* Get login message link HTML for adding to the login form
* #return string
*/
function getLoginMessage() {
$options = get_option('ja_settings');
$redirect_to = $_GET['redirect_to'] ?? null;
$login_url = $options['login_url'] . '?callback=' . urlencode(site_url('/wp-json/jwt-auth/v1/callback'));
if($redirect_to){
$login_url .= '&redirect_to=' . urlencode($redirect_to);
}
$login_message = $options['login_message'];
return "<a id='jwt_link' href='{$login_url}'>{$login_message}</a>";
}
add_filter('login_message', 'getLoginMessage');
add_action( 'load-profile.php', function() {//https://wordpress.stackexchange.com/a/195370/51462 Redirect from profile.php to the dashboard since there is no reason for WordPress users to see or manage their profile since their main account is on the other site.
if( ! current_user_can( 'manage_options' ) ){
$redirectUrl = get_site_url();//admin_url()
exit( wp_safe_redirect( $redirectUrl ) );
}
} );
function show_admin_bar_conditionally(){//remove the WordPress admin toolbar https://premium.wpmudev.org/blog/remove-the-wordpress-admin-toolbar/
return current_user_can( 'manage_options' );
}
add_filter('show_admin_bar', 'show_admin_bar_conditionally');//can use 'show_admin_bar_conditionally' or '__return_false' for never.
//------------------------------------------------------------------
//for https://wordpress.org/support/topic/rest-api-26/#post-9915078
//and https://github.com/kevinvess/wp-force-login/issues/35
//and https://wordpress.org/support/topic/rest-api-26/page/2/#post-10000740
//and https://wordpress.org/support/topic/jwt-authentication/#post-10698307
add_filter( 'rest_authentication_errors', '__return_true' );
This belongs in functions.php of your theme in WordPress:
// https://codex.wordpress.org/Customizing_the_Login_Form
function my_custom_login_page() { ?>
<style type="text/css">
#loginform, #login #nav{display: none;}
#jwt_link{font-weight: bold; font-size: 20px;}
</style>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById('jwt_link').click();//immediately upon load of login page, click the JWT link automatically
});
</script>
<?php }
add_action( 'login_enqueue_scripts', 'my_custom_login_page' );
Related
I have created this plugin to prevent certain posts being deleted.
This plugin removes the TRASH option from the page list.
register_activation_hook( __FILE__, 'prevent_page_delete_activate' );
function prevent_page_delete_activate() {
add_action('admin_menu', 'prevent_page_delete');
}
add_filter ('user_has_cap', 'prevent_default_theme_deletion', 10, 3);
function prevent_default_theme_deletion($allcaps, $caps, $args) {
$ids = [2000,2333,4444];
// trash will ve removed for this page IDs
$numElementos = count($ids);
for ($i=0; $i < $numElementos; $i++) {
$post_id = $ids[$i];
if ( isset( $args[0] ) && isset( $args[2] ) && $args[2] == $post_id && $args[0] == 'delete_post' ) {
$allcaps[ $caps[0] ] = false;
}
}
return $allcaps;
}
What would be the equivalent to remove the EDIT link from certain page ids?
As per your last comment, there is a few thing to consider:
Visually hiding any hints to edit/delete ... etc.
Removing any default link styling.
Preventing direct access.
Preventing database update.
You can intercept the post edit via the pre_post_update action hook which fires immediately before an existing post is updated in the database..
We can use post_row_actions which filters the array of row action links on the Posts list table to prevent edits actions.
Finally we use the admin_head-{$hook_suffix} hook to remove any visual style and prevent the direct access through URL.
Everything is wrapped up in a single class to make it easier.
<?php
if ( ! class_exists( 'wpso70412723' ) ) {
class wpso70412723 {
public $protected_posts_IDs = [ //Define the protected posts IDs
2000,
2333,
4444,
];
public function __construct() {
add_action( 'pre_post_update', array( $this, 'wpso_70412723_prevent_database_update_on_specific_post_edit' ), 10, 2 );
add_filter( 'post_row_actions', array( $this, 'wpso_70412723_remove_edit_related_actions_from_post_action_row' ), 10, 2 );
add_action( 'admin_head-edit.php', array( $this, 'wpso_70412723_prevent_link_style_and_click_ability_from_post_title' ));
add_action( 'admin_head-post.php', array( $this, 'wpso_70412723_prevent_direct_access_to_a_specific_post_through_URL' ));
} //public function __construct() {
/**
* Prevent specific posts edits actions.
* Any post modifications (edit, delete, etc.) will be prevented.
*
* #param Integer $post_ID
* #param Array $data
*/
public function wpso_70412723_prevent_database_update_on_specific_post_edit($post_ID, $data) {
if (in_array($post_ID, $this->protected_posts_IDs))
wp_die('You are not allowed to edit this post.', 'Something went wrong...', [
'back_link' => true
]);
} //public function wpso_70412723_prevent_database_update_on_specific_post_edit() {
/**
* Filters-out edit related actions from the array of row action links on the Posts list table.
*
* #param String $actions An array of row action links.
* #param Object (WP_Post) The post object.
*/
public function wpso_70412723_remove_edit_related_actions_from_post_action_row($actions, $post) {
if (in_array($post->ID, $this->protected_posts_IDs)) {
unset( $actions['edit'] );
unset( $actions['inline hide-if-no-js'] );
unset( $actions['trash'] );
};
return $actions;
} //public function wpso_70412723_prevent_database_update_on_specific_post_edit() {
/**
* Prevent link style and click ability from the post title.
* Fires in head section for a specific admin page.
* In our case, the admin posts listing edit page.
*
* #see https://developer.wordpress.org/reference/hooks/admin_head-hook_suffix/
*/
public function wpso_70412723_prevent_link_style_and_click_ability_from_post_title() {
if ( 'edit' !== get_current_screen()->base )
return;
global $wp_query;
$posts = $wp_query->posts;
foreach ($posts as $post) {
if (in_array($post->ID, $this->protected_posts_IDs)) {
echo '<style type="text/css">
#the-list .post-' . $post->ID . ' strong a {
pointer-events: none;
color: initial;
text-decoration: none;
}
</style>';
};
};
} //public function wpso_70412723_prevent_link_style_and_click_ability_from_post_title() {
/**
* Prevent direct access to a specific post through URL.
* Fires in head section for a specific admin page.
* In our case, the admin posts listing edit page.
*
* #see https://developer.wordpress.org/reference/hooks/admin_head-hook_suffix/
*/
public function wpso_70412723_prevent_direct_access_to_a_specific_post_through_URL() {
if ( 'post' !== get_current_screen()->base )
return;
if (in_array(get_the_ID(), $this->protected_posts_IDs)) {
wp_die('You are not allowed to edit this post.', 'Something went wrong...', [
'back_link' => true
]);
};
} //public function wpso_70412723_prevent_direct_access_to_a_specific_post_through_URL() {
}; //class wpso70412723 {
new wpso70412723();
}; //if ( ! class_exists( 'wpso70412723' ) ) {
By the way, deleting a post is considered an edit.
You don't need your prevent_default_theme_deletion() function.
You could be tempted to use the edit_post action hook tho this wouldn't work because:
edit_post: Fires once an existing post has been updated.
The "once" statement is why we need to use pre_post_update.
pre_post_update: Fires immediately before an existing post is updated in the database.
For security reasons I want every user from a certain domain (for now I've used #company.com) to be forced to login using the login with Google button, so I wrote this check.
Which works fine but the error message on the login page doesn't change, it says FOUT: Verkeerde logingegevens. which is Dutch for ERROR: Wrong credentials.. I did return a new error with a different message, so how would I display this message?
function check_login($user, $username, $password) {
if (!empty($username)) {
if (substr($user->user_email, -12) == "#company.com") {
$user = new WP_Error( 'authentication_failed', __( '<strong>ERROR</strong>: Please login using Google.' ) );
}
}
return $user;
}
add_filter('authenticate', 'check_login', 100, 3);
Wordpress Core
Your issue comes from the fact that the $user variable you are filtering is already a WP_Error and not a WP_User, so your filter cannot work because $user->user_email is null, hopefully Wordpress uses another intermediate hook in it's login function
You should use this filter instead wp_authenticate_user which will fire after the user is retrieved from the database but before the password is checked, converting the user into a WP_Error
function check_login($user) {
if ($user instanceof WP_User) {
if (substr($user->user_email, -12) == "#company.com") {
$user = new WP_Error( 'authentication_failed', __( '<strong>ERROR</strong>: Please login using Google.' ) );
}
}
return $user;
}
add_filter('wp_authenticate_user', 'check_login', 9, 1);
Third Party plugin
If you are using a security plugin, they usually have an option that disable error login messages, here's how to disable it in some major ones
IThemes Security
One option this plugin provides is to hide all login error messages, you can disable this in the settings of the plugin > Wordpress Tweaks > Uncheck Login Error Messages
Or access this page by appending this url to your website /wp-admin/admin.php?page=itsec&module=wordpress-tweaks&module_type=recommended
Wordfence
This plugin gives the user a generic error message to prevent revealing if it's the password or the username that is incorrect, you can disable this option there
You'll need to remove the original authenticate filter and replace it with your own.
This way, you can set a custom error message for each different case.
Just make sure to add your custom #company.com check at the top, before checking for other cases.
remove_filter('authenticate', 'wp_authenticate_username_password');
add_filter('authenticate', 'wpse_115539_authenticate_username_password', 20, 3);
/**
* Remove Wordpress filer and write our own with changed error text.
*/
function wpse_115539_authenticate_username_password($user, $username, $password) {
if (!empty($username)) {
if (substr($user->user_email, -12) == "#company.com") {
return new WP_Error('authentication_failed', __('<strong>ERROR</strong>: Please login using Google.'));
}
}
if (is_a($user, 'WP_User'))
return $user;
if (empty($username) || empty($password)) {
if (is_wp_error($user))
return $user;
$error = new WP_Error();
if (empty($username))
$error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.'));
if (empty($password))
$error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.'));
return $error;
}
$user = get_user_by('login', $username);
if (!$user)
return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. Lost your password?'), wp_lostpassword_url()));
$user = apply_filters('wp_authenticate_user', $user, $password);
if (is_wp_error($user))
return $user;
if (!wp_check_password($password, $user->user_pass, $user->ID))
return new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: The password you entered for the username <strong>%1$s</strong> is incorrect. Lost your password?'),
$username, wp_lostpassword_url()));
return $user;
}
FYI, I found this code here.
function wp_authenticate( $username, $password ) {
$username = sanitize_user( $username );
$password = trim( $password );
$user = apply_filters( 'authenticate', null, $username, $password );
if ( $user == null ) {
// TODO what should the error message be? (Or would these even happen?)
// Only needed if all authentication handlers fail to return anything.
$user = new WP_Error( 'authentication_failed', __( '<strong>ERROR</strong>: Invalid username, email address or incorrect password.' ) );
}
$ignore_codes = array( 'empty_username', 'empty_password' );
if ( is_wp_error( $user ) && ! in_array( $user->get_error_code(), $ignore_codes ) ) {
do_action( 'wp_login_failed', $username );
}
return $user;
}
I'm having issues with drupal_mail(). I receive the email but the subject and body are empty.
Drupal version 7
code below
$params = array(
'subject' => t('Client Requests Quote'),
'body' => t("Body of the email goes here"),
);
drupal_mail("samplemail", "samplemail_html_mail", "email#email.com", language_default(), $params, "email#email.com", TRUE);
I have even tried it with the hook below and I get the same result.
function hook_mail($key, &$message, $params) {
switch ($key) {
case 'samplemail_html_mail':
/*
* Emails with this key will be HTML emails,
* we therefore cannot use drupal default headers, but set our own headers
*/
/*
* $vars required even if not used to get $language in there since t takes in: t($string, $args = array(), $langcode = NULL) */
$message['subject'] = t($params['subject'], $var, $language->language);
/* the email body is here, inside the $message array */
$body = "<html><body>
<h2>HTML Email Sample with Drupal</h2>
<hr /><br /><br />
{$params['body']}
</body></html>";
$message['body'][] = $body;
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
break;
}
}
drupal_mail_system() works but it comes in plain text.
in your module you shouldn't use hook_mail it should be <MODULE_NAME>_hook().
change
function hook_mail($key, &$message, $params) {
With
function samplemail_mail($key, &$message, $params) {
Try using the following snippet.
// Use these two lines when you want to send a mail.
global $user;
drupal_mail('test', 'test_mail', 'your_mail_id', user_preferred_language($user), $params, $from_mail_id, TRUE);
/**
* Implements hook_mail().
*/
function test_mail($key, &$message, $params) {
switch ($key) {
case 'test_mail':
$params['subject'] = t('Subject is here');
$params['message'] = 'message is here';
$message['subject'] = $params['subject'];
$message['body'][] = $params['message'];
break;
}
}
Note: 'test' is module name.
Solution !
Try with below code in your "registration_form" module. This code will send mail often on page refresh since mail trigger is done in hook_init. Use where ever you want.
/**
* Implements hook_init();
*/
function registration_form_init() {
$first_name = 'Shankar';
$params = array(
'subject' => 'Signup Invitation',
'body' => '<p>Dear ' . $first_name . ',</p>
<p>Congratulations! Your account <b> ' . $first_name . ' </b>has been successfully created with SOME portal.</p>
<p>Thanks,SOME portal POSTMASTER</p>',
'first_name' => $first_name
);
drupal_mail('registration_form', 'invitation', $email, language_default(), $params);
}
/**
* Implements hook_mail();
*/
function registration_form_mail($key, &$message, $params) {
switch ($key) {
case 'invitation':
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
}
}
I got this code that was working fine until WP 3.5.1 upgrade. Now it doesn't display anything, and I can't figure it out.
When I put inn the shortcode in admin panel the resulting post or page doesn't display anything. Not even the raw shortcode?
Basically this code display expiring links for amazon s3 content to prevent leaching.
define('FPEAS3', __FILE__);
define('FPEAS3_DIR', dirname(__FILE__));
#define('FPEAS3_AWS_S3_ACCESS_ID', '');
#define('FPEAS3_AWS_S3_SECRET', '');
add_action('init', 'fpeas3_init');
function fpeas3_init() {
add_shortcode('s3', 'fpeas3_shortcode');
}
function fpeas3_shortcode($atts, $content = null) {
extract(shortcode_atts(array(
'expires' => '5',
'bucket' => '',
'path' => ''
), $atts));
if (!$content = trim($content)) {
$content = 'Download';
}
$keys = array(
'access_id' => get_post_meta(get_the_ID(), 'aws_s3_access_id', true),
'secret' => get_post_meta(get_the_ID(), 'aws_s3_secret', true)
);
if (empty($keys['access_id']) || empty($keys['secret'])) {
$keys = fpeas3_get_static_keys();
}
if (empty($keys['access_id']) || empty($keys['secret'])) {
$error = "Expiring Amazon S3 Links not setup correctly: missing Access ID or Secret.";
error_log($error);
if (current_user_can('admin')) {
return $error;
} else {
return '';
}
}
return sprintf('<a rel="nofollow" href="%s" class="s3-temp-link">%s</a>',
fpeas3_get_temporary_link($keys['access_id'], $keys['secret'], $bucket, $path, $expires), $content);
}
function fpeas3_get_static_keys() {
return array(
'access_id' => FPEAS3_AWS_S3_ACCESS_ID,
'secret' => FPEAS3_AWS_S3_SECRET
);
}
/**
* Calculate the HMAC SHA1 hash of a string.
* #param string $key The key to hash against
* #param string $data The data to hash
* #param int $blocksize Optional blocksize
* #return string HMAC SHA1
*/
function fpeas3_crypto_hmacSHA1($key, $data, $blocksize = 64) {
if (strlen($key) > $blocksize) $key = pack('H*', sha1($key));
$key = str_pad($key, $blocksize, chr(0x00));
$ipad = str_repeat(chr(0x36), $blocksize);
$opad = str_repeat(chr(0x5c), $blocksize);
$hmac = pack( 'H*', sha1(
($key ^ $opad) . pack( 'H*', sha1(
($key ^ $ipad) . $data
))
));
return base64_encode($hmac);
}
/**
* Create temporary URLs to your protected Amazon S3 files.
* #param string $accessKey Your Amazon S3 access key
* #param string $secretKey Your Amazon S3 secret key
* #param string $bucket The bucket (bucket.s3.amazonaws.com)
* #param string $path The target file path
* #param int $expires In minutes
* #return string Temporary Amazon S3 URL
* #see http://awsdocs.s3.amazonaws.com/S3/20060301/s3-dg-20060301.pdf
*/
function fpeas3_get_temporary_link($accessKey, $secretKey, $bucket, $path, $expires = 5) {
// Calculate expiry time
$expires = time() + intval(floatval($expires) * 60);
// Fix the path; encode and sanitize
$path = str_replace('%2F', '/', rawurlencode($path = ltrim($path, '/')));
// Path for signature starts with the bucket
$signpath = '/'. $bucket .'/'. $path;
// S3 friendly string to sign
$signsz = implode("\n", $pieces = array('GET', null, null, $expires, $signpath));
// Calculate the hash
$signature = fpeas3_crypto_hmacSHA1($secretKey, $signsz);
// Glue the URL ...
$url = sprintf('http://%s.s3.amazonaws.com/%s', $bucket, $path);
// ... to the query string ...
$qs = http_build_query($pieces = array(
'AWSAccessKeyId' => $accessKey,
'Expires' => $expires,
'Signature' => $signature,
));
// ... and return the URL!
$tempUrl = $url.'?'.$qs;
return $tempUrl;
}
Ok, So I looked at this code again with fresh eyes. And I got it to work I think. Still testing some things.
I changed this line of code very slightly:
**return** sprintf('<a rel="nofollow" href="%s"
class="s3-temp-link">%s</a>',
fpeas3_get_temporary_link($keys['access_id'], $keys['secret'], $bucket, $path, $expires), $content);
Changed to:
**echo** sprintf('<a rel="nofollow" href="%s" class="s3-temp-link">%s</a>',
fpeas3_get_temporary_link($keys['access_id'], $keys['secret'], $bucket, $path, $expires), $content);
I'm not a programmer, but after some digging I found there are various ways to display the output.
Any opinions on if this is good way to code it?
Is it possible to change the user avatar in WordPress programmatically? I'm asking because I'm facing a problem right now in displaying the user avatar in WordPress multisite: the Avatar is not displaying.
I had to do three things to be able to programmatically insert user avatars into my WordPress starting with an avatar that is hosted at a remote URL.
Install the WP User Avatar plugin.
Borrow an upload function from WooCommerce. See below.
Adapt some code from a similar support post
Suppose you have a user whose avatar is $avatar_url = 'http://cdn.sstatic.net/stackoverflow/img/apple-touch-icon#2.png?v=73d79a89bded&a';
I use the upload_product_image() from WooCommerce's class-wc-api-products.php to get the avatar into my local server.
Then, using some of the code from this support post, create an attachment.
Then associate the attachment with the user.
This works only with the WP User Avatar plugin.
function se13911452_set_avatar_url($avatar_url, $user_id) {
global $wpdb;
$file = upload_product_image($avatar_url);
$wp_filetype = wp_check_filetype($file['file']);
$attachment = array(
'guid' => $file['url'],
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($file['file'])),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $file['file']);
$attach_data = wp_generate_attachment_metadata($attach_id, $file['file']);
wp_update_attachment_metadata($attach_id, $attach_data);
update_user_meta($user_id, $wpdb->get_blog_prefix() . 'user_avatar', $attach_id);
}
From WooCommerce's class-wc-api-products.php
/**
* WooCommerce class-wc-api-products.php
* See https://github.com/justinshreve/woocommerce/blob/master/includes/api/class-wc-api-products.php
* Upload image from URL
*
* #since 2.2
* #param string $image_url
* #return int|WP_Error attachment id
*/
function upload_product_image($image_url) {
$file_name = basename(current(explode('?', $image_url)));
$wp_filetype = wp_check_filetype($file_name, null);
$parsed_url = #parse_url($image_url);
// Check parsed URL
if(!$parsed_url || !is_array($parsed_url)) {
throw new WC_API_Exception('woocommerce_api_invalid_product_image', sprintf(__('Invalid URL %s', 'woocommerce'), $image_url), 400);
}
// Ensure url is valid
$image_url = str_replace(' ', '%20', $image_url);
// Get the file
$response = wp_safe_remote_get($image_url, array(
'timeout' => 10
));
if(is_wp_error($response) || 200 !== wp_remote_retrieve_response_code($response)) {
throw new WC_API_Exception('woocommerce_api_invalid_remote_product_image', sprintf(__('Error getting remote image %s', 'woocommerce'), $image_url), 400);
}
// Ensure we have a file name and type
if(!$wp_filetype['type']) {
$headers = wp_remote_retrieve_headers($response);
if(isset($headers['content-disposition']) && strstr($headers['content-disposition'], 'filename=')) {
$disposition = end(explode('filename=', $headers['content-disposition']));
$disposition = sanitize_file_name($disposition);
$file_name = $disposition;
}
elseif(isset($headers['content-type']) && strstr($headers['content-type'], 'image/')) {
$file_name = 'image.' . str_replace('image/', '', $headers['content-type']);
}
unset($headers);
}
// Upload the file
$upload = wp_upload_bits($file_name, '', wp_remote_retrieve_body($response));
if($upload['error']) {
throw new WC_API_Exception('woocommerce_api_product_image_upload_error', $upload['error'], 400);
}
// Get filesize
$filesize = filesize($upload['file']);
if(0 == $filesize) {
#unlink($upload['file']);
unset($upload);
throw new WC_API_Exception('woocommerce_api_product_image_upload_file_error', __('Zero size file downloaded', 'woocommerce'), 400);
}
unset($response);
return $upload;
}
Most likely somewhere the get_avatar filter is being called and doing something. I recommend searching your plugins and themes for get_avatar and looking at things that look like: add_filter ('get_avatar', .....
Otherwise, you can write your own behavior with the code below.
<?php // in a plugin file or in a theme functions.php
function SO13911452_override_avatar ($avatar_html, $id_or_email, $size, $default, $alt) {
// check all values
return $avatar_html
}
add_filter ('get_avatar', 'SO13911452_override_avatar', 10, 5);
This will works :
add_filter('get_avatar_data', 'ht1_change_avatar', 100, 2);
function ht1_change_avatar($args, $id_or_email) {
if($id_or_email == 1) {
$args['url'] = 'https://uinames.com/api/photos/female/1.jpg';
}
if($id_or_email == 2) {
$args['url'] = 'https://uinames.com/api/photos/male/19.jpg';
}
return $args;
} // end of function
If you have avatar dir location metas for users, then use this for all users :
add_filter('get_avatar_data', 'ht1_change_avatar', 100, 2);
function ht1_change_avatar($args, $id_or_email) {
$avatar_url = get_user_meta($id_or_email, 'avatar', true);
$args['url'] = $avatar_url;
return $args;
} // end of function
Hope you get the point.
first add author_pic meta to user profile:
update_usermeta( $user_id, 'author_pic', trim($_POST['author_pic']) );
and add this filter to template function:
add_filter('get_avatar_data', 'ow_change_avatar', 100, 2);
function ow_change_avatar($args, $user_data) {
if(is_object($user_data)){
$user_id = $user_data->user_id;
} else{
$user_id = $user_data;
}
if($user_id){
$author_pic = get_user_meta($user_id, 'author_pic', true);
if($author_pic){
$args['url'] = $author_pic;
} else {
$args['url'] = 'registerd user default img url';
}
} else {
$args['url'] = 'guast user img url';
}
return $args;
}