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;
}
Related
who can hellp with this, i need create post from code, by wp_insert_post
function, so what is going on:
I creating post on each existing laguages, then i update all needed fields and i need to set post term depened of current language.
I have terms (shelters) https://prnt.sc/pklSXojB2jZj - i need that post set to current lang shelter while create, but after creating i got - https://prnt.sc/pz2jFEq1OAMP , 2 posts set in one lang terms. Maybe who know whats goes wrong, below i provided 2 functions who do these actions, Thanks in advance:
function add_pet($form_data, $ready_data, $update_meta = false) {
$allLang = pll_languages_list();
if ($allLang) {
$postsArr = array();
foreach ($allLang as $lang) {
//Add new pet
$post_id = wp_insert_post(array(
'post_title' => $form_data['pet_name'],
'post_status' => 'publish',
'post_author' => $form_data['user_id'],
'post_type' => 'pets',
));
//Check if post created, update all needed fields, and update post terms (shelter)
if ($post_id) {
//Get all translation of term
$shelter_id = pll_get_term(intval($form_data['shelter']), $lang);
$update_meta['shelter'] = $shelter_id;
//In this function we update those terms
$update_success = update_pets_fields($post_id, $ready_data, $update_meta);
$postsArr[$lang] = $post_id;
pll_set_post_language($post_id, $lang);
$postDate = get_post($post_id)->post_date;
$unixDate = strtotime($postDate);
update_post_meta($post_id, 'pet_update_date', $unixDate);
}
}
//Save post translation
if ($postsArr) {
pll_save_post_translations($postsArr);
}
//Old code
// foreach ($allLang as $lang) {
// $cat_id = pll_get_term(intval($form_data['kind_of_animal']), $lang);
// $shelter_id = pll_get_term(intval($form_data['shelter']), $lang);
// $post_id = $postsArr[$lang];
// $update_meta['post_category'] = $cat_id;
// $update_meta['shelter'] = $shelter_id;
// $update_success = update_pets_fields($post_id, $ready_data, $update_meta);
// }
}
if (is_wp_error($post_id)) {
wp_send_json_error($post_id->get_error_message());
}
if ($update_success) {
wp_send_json_success('Post was created.');
} else {
wp_send_json_error('Post was not created.');
}
}
And function who update field
/Update pets fields
function update_pets_fields($post_id, $data, $update_meta = false) {
if (!$post_id) return;
//Update post meta data not acf
if (isset($update_meta) && !empty($update_meta['title'])) {
$post_update = array(
'ID' => $post_id,
'post_title' => $update_meta['title']
);
$result = wp_update_post($post_update);
if (is_wp_error($result)) {
wp_send_json_error('Fields was not updated');
}
}
if (isset($update_meta['shelter']) && !empty($update_meta['shelter']) && intval($update_meta['shelter'])) {
wp_remove_object_terms($post_id, 'uncategorized', 'sholters');
$shelter_id = intval($update_meta['shelter']);
wp_set_post_terms($post_id, array($shelter_id), 'sholters');
if (is_wp_error($result)) {
wp_send_json_error('Term not updated');
}
}
if (isset($update_meta['post_category']) && !empty($update_meta['post_category']) && intval($update_meta['post_category'])) {
wp_remove_object_terms($post_id, 'uncategorized', 'category');
wp_set_post_categories($post_id, intval($update_meta['post_category']));
if (is_wp_error($result)) {
wp_send_json_error('Category not updated');
}
}
if (isset($update_meta['thumbnail']) && !empty($update_meta['thumbnail']) && intval($update_meta['thumbnail'])) {
set_post_thumbnail($post_id, intval($update_meta['thumbnail']));
}
if (is_null($data)) {
wp_send_json_error('No data.');
}
foreach ($data as $field) {
if ($field[3] === 'where_is') {
$field_array['field_62169d3cffb5b'] = array(
$field[2] => $field[1],
);
} else {
$field_array = array(
$field[2] => $field[1],
);
}
if (!empty($field[1])) {
$result = update_field('field_621696a7ffb4e', $field_array, $post_id);
}
}
if ($result) {
return false;
} else {
return true;
}
}
I try update it in diferent variants but it does't work, i check ids that come in args all ids is right and all posts ids is right.But on at the exit we got 2 posts in 1 term
I have a custom post type and on the admin edit post screen I'm using wp.media to attach the track to the post. And I'm attaching some post meta to that track also.
Is there easy way to force wp.media JS returns track with meta data?
trackMediaUploader = wp.media.frames.file_frame = wp.media( { ... } );
trackMediaUploader.on( 'select', () => {
const attachment = trackMediaUploader.state().get( 'selection' ).first().toJSON();
// want to get post meta of this attachment
console.log( attachment );
});
I've tried to use wp_get_attachment_metadata filter, but it's wont works with wp.media js:
function add_attachment_metadata( $data, $id ) {
$lyrics = get_post_meta( $id, '_track_lyrics', true );
if( $lyrics ) {
$data[ 'track-lyrics' ] = $lyrics;
}
return $data;
}
You can use wp_prepare_attachment_for_js hook:
add_filter( 'wp_prepare_attachment_for_js', 'prepare_attachment_for_js', 10, 3 );
function prepare_attachment_for_js( $response, $attachment, $meta ) {
$response[ 'trackLyrics' ] = get_post_meta( $attachment->ID, '_track_lyrics', true );
return $response;
}
// in admin js:
trackMediaUploader = wp.media.frames.file_frame = wp.media( { ... } );
trackMediaUploader.on( 'select', () => {
const attachment = trackMediaUploader.state().get( 'selection' ).first().toJSON();
console.log( attachment.trackLyrics );
});
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' );
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?
I'm working on a WordPress plugin, and part of that plugin requires extending WP_List_Table and storing any of the items which are checked in that table to an option. I've managed to figure out how to properly setup and display the required table, but how do I handle storing the checked options?
Here's what I've got so far...
class TDBar_List_Table extends WP_List_Table {
// Reference parent constructor
function __construct() {
global $status, $page;
// Set defaults
parent::__construct( array(
'singular' => 'theme',
'plural' => 'themes',
'ajax' => false
));
}
// Set table classes
function get_table_classes() {
return array('widefat', 'wp-list-table', 'themes');
}
// Setup default column
function column_default($item, $column_name) {
switch($column_name) {
case 'Title':
case 'URI':
case'Description':
return $item[$column_name];
default:
return print_r($item, true);
}
}
// Displaying checkboxes!
function column_cb($item) {
return sprintf(
'<input type="checkbox" name="%1$s" id="%2$s" value="checked" />',
//$this->_args['singular'],
$item['Stylesheet'] . '_status',
$item['Stylesheet'] . '_status'
);
}
// Display theme title
function column_title($item) {
return sprintf(
'<strong>%1$s</strong>',
$item['Title']
);
}
// Display theme preview
function column_preview($item) {
if (file_exists(get_theme_root() . '/' . $item['Stylesheet'] . '/screenshot.png')) {
$preview = get_theme_root_uri() . '/' . $item['Stylesheet'] . '/screenshot.png';
} else {
$preview = '';
}
return sprintf(
'<img src="%3$s" style="width: 150px;" />',
$preview,
$item['Title'],
$preview
);
}
// Display theme description
function column_description($item) {
if (isset($item['Version'])) {
$version = 'Version ' . $item['Version'];
if (isset($item['Author']) || isset($item['URI']))
$version .= ' | ';
} else {
$version = '';
}
if (isset($item['Author'])) {
$author = 'By ' . $item['Author'];
if (isset($item['URI']))
$author .= ' | ';
} else {
$author = '';
}
if (isset($item['URI'])) {
$uri = $item['URI'];
} else {
$uri = '';
}
return sprintf(
'<div class="theme-description"><p>%1$s</p></div><div class="second theme-version-author-uri">%2$s%3$s%4$s',
$item['Description'],
$version,
$author,
$uri
);
}
// Setup columns
function get_columns() {
$columns = array(
'cb' => '<input type="checkbox" />',
'title' => 'Theme',
'preview' => 'Preview',
'description' => 'Description'
);
return $columns;
}
// Make title column sortable
function get_sortable_columns() {
$sortable_columns = array(
'title' => array('Title', true)
);
return $sortable_columns;
}
// Setup bulk actions
function get_bulk_actions() {
$actions = array(
'update' => 'Update'
);
return $actions;
}
// Handle bulk actions
function process_bulk_action() {
// Define our data source
if (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE == true) {
$themes = get_allowed_themes();
} else {
$themes = get_themes();
}
if ('update' === $this->current_action()) {
foreach ($themes as $theme) {
if ($theme['Stylesheet'] . '_status' == 'checked') {
// Do stuff - here's the problem
}
}
}
}
// Handle data preparation
function prepare_items() {
// How many records per page?
$per_page = 10;
// Define column headers
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
// Build the array
$this->_column_headers = array($columns, $hidden, $sortable);
// Pass off bulk action
$this->process_bulk_action();
// Define our data source
if (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE == true) {
$themes = get_allowed_themes();
} else {
$themes = get_themes();
}
// Handle sorting
function usort_reorder($a,$b) {
$orderby = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby'] : 'Title';
$order = (!empty($_REQUEST['order'])) ? $_REQUEST['order'] : 'asc';
$result = strcmp($a[$orderby], $b[$orderby]);
return ($order === 'asc') ? $result : -$result;
}
usort($themes, 'usort_reorder');
//MAIN STUFF HERE
//for ($i = 0; i < count($themes); $i++) {
//}
// Figure out the current page and how many items there are
$current_page = $this->get_pagenum();
$total_items = count($themes);
// Only show the current page
$themes = array_slice($themes,(($current_page-1)*$per_page),$per_page);
// Display sorted data
$this->items = $themes;
// Register pagination options
$this->set_pagination_args( array(
'total_items' => $total_items,
'per_page' => $per_page,
'total_pages' => ceil($total_items/$per_page)
));
}
}
Problem is, I can't get it to save properly. I select the rows I want, hit save and it just resets.
I assume you are talking about the checkboxes in your table listing, so this will be how to process bulk actions.
All you need to do is add two new methods to your class and initialize it in the prepare_items method. I use the code below in one of my plugins to delete or export, but you can just as easily run an update.
/**
* Define our bulk actions
*
* #since 1.2
* #returns array() $actions Bulk actions
*/
function get_bulk_actions() {
$actions = array(
'delete' => __( 'Delete' , 'visual-form-builder'),
'export-all' => __( 'Export All' , 'visual-form-builder'),
'export-selected' => __( 'Export Selected' , 'visual-form-builder')
);
return $actions;
}
/**
* Process our bulk actions
*
* #since 1.2
*/
function process_bulk_action() {
$entry_id = ( is_array( $_REQUEST['entry'] ) ) ? $_REQUEST['entry'] : array( $_REQUEST['entry'] );
if ( 'delete' === $this->current_action() ) {
global $wpdb;
foreach ( $entry_id as $id ) {
$id = absint( $id );
$wpdb->query( "DELETE FROM $this->entries_table_name WHERE entries_id = $id" );
}
}
}
Now, call this method inside prepare_items() like so:
function prepare_items() {
//Do other stuff in here
/* Handle our bulk actions */
$this->process_bulk_action();
}
There's a fantastic helper plugin called Custom List Table Example that makes figuring out the WP_List_Table class much easier.