WordPress How can I get post_id from thumbnail_id? - wordpress

I'm developing wordpress plugin.
I need to find out post_id from thumbnail_id(not reverse !).
How can I do this?

You can get result by this code
global $wpdb;
$_thumbnail_id = {thumbnail id};
$sql = "SELECT `post_id` FROM `wp_postmeta` WHERE `meta_value` = $_thumbnail_id";
$result = $wpdb->get_results( $sql, ARRAY_A );
//access first returned post id
var_dump($result[0]['post_id']);
If you added same image for multiple posts there will be multiple returns.

You can use get_the_ID() to get the post id. You can find this function in wp-includes/post-template.php
function get_the_ID() {
$post = get_post();
return ! empty( $post ) ? $post->ID : false;
}

Related

Creating pretty links for URLs with multiple query parameters

I am working on a website that is more of a search directory and haven't been able to find a clear answer on how to automatically create pretty links from long URL's with multiple query parameters (Wordpress).
For example, if the link looks like this: website.com/search/search-results/?address=98101,+seattle,+washington&contractor=plumber&latitude=1234&longitude=9876&filter=20&order=distance
Is there a way to make it look like this: website.com/search/search-results/98101/seattle/washington/plumber/
automatically without having to go through every link and the new pretty link will show the same page as the page with all of the query parameters?
Thanks in advance, I've been trying to figure this out all day and it's not my strong point...
Really interesting and quite technical question.
The following is not production ready. It is a working proof of concept.
I'm just pondering here. You could create a new Table (see Creating Tables with Plugins with a requested_url key and a shortened_url value. The whole system would be based on that approach.
First we creates a custom table in the database, if it doesn’t already exist. This table will be used to store our urls.
<?php
add_action( 'after_switch_theme', function () {
global $wpdb;
$table_name = $wpdb->prefix . 'wpso74035985';
$charset_collate = $wpdb->get_charset_collate();
$create_ddl = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
requested_url varchar(55) DEFAULT '' NOT NULL,
shortened_url varchar(55) DEFAULT '' NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
maybe_create_table( $table_name, $create_ddl );
} );
We could then retrieve the requested url by parsing the $_SERVER['QUERY_STRING'] and verifying the url integrity through get_query_var() as it only retrieves public query variables that are recognized by WP_Query.
We would then search the table for the requested url, and if it doesn't already exist, set a new key pair value.
<?php
add_action( 'pre_get_posts', function ( $wp_query ) {
if ( ! is_admin() && $wp_query->is_main_query() ) {
if ( $wp_query->is_search() ) {
global $wp;
parse_str( filter_input( INPUT_SERVER, 'QUERY_STRING', FILTER_SANITIZE_STRING ), $variables );
$buffer = array();
foreach ( $variables as $variable => $value ) {
if ( get_query_var( $variable ) ) {
array_push( $buffer, array( $variable => $value ) );
};
};
$buffer = array_reduce( $buffer, 'array_merge', array() );
$requested_url = esc_url_raw( add_query_arg( $buffer, home_url( $wp->request ) ) );
global $wpdb;
$table_name = $wpdb->prefix . 'wpso74035985';
$results = $wpdb->get_results(
"SELECT * FROM $table_name"
);
$needle_key = array_search( $requested_url, array_column( $results, 'requested_url' ) );
if ( $needle_key === false ) {
$shortened_url = str_shuffle( base64_encode( random_bytes( 100 ) ) );
$shortened_url = preg_replace( '/\W/s', '', $shortened_url );
$shortened_url = substr( $shortened_url, 0, 7 );
$wpdb->insert(
$table_name,
array(
'requested_url' => sanitize_url( $requested_url ),
'shortened_url' => sanitize_url( home_url( $shortened_url ) ),
)
);
};
};
};
} );
There is no real science here, the $shortened_url is just a 7 bytes alpha numerical string (Why 7? Bit.ly a famous shortener is using 7 characters).
Through the template_redirect hook, we could check the shortened url against our table and redirect based on that.
<?php
add_action( 'template_redirect', function () {
if ( is_404() ) {
global $wp;
$shortened_url = home_url( $wp->request );
global $wpdb;
$table_name = $wpdb->prefix . 'shortener';
$results = $wpdb->get_results(
"SELECT * FROM $table_name"
);
$needle_key = array_search( $shortened_url, array_column( $results, 'shortened_url' ) );
if ( $needle_key !== false ) {
$location = $results[$needle_key]->requested_url;
wp_safe_redirect( $location );
exit();
};
};
} );
As we're checking for a 404 through is_404() first (pretty much limiting the number of empty request), you should also include a 404.php to your root.
On the front end you can access your table through
<?php
global $wpdb;
$table_name = $wpdb->prefix . 'wpso74035985';
$results = $wpdb->get_results(
"SELECT * FROM $table_name"
);
var_dump( $results );
Now, a few thing to understand before you go to production with this, even tho we're generating a pseudo random string through random_bytes() and base64_encode() they're not actually fully randomized, so you could end up with a problem at some point where two shortened url are the same. You could do a while loop and constantly check if that shortened url already exist before using it.
You would also want to restrict the search query as much as you can to improve performance on the long term.
You might want also to add an expiry date.

Check if post_content already exist in database

I need a function to check if post_content already exist in database.
Wordpress built in function post_exists() checks by post post_title.
I need to check by post_content regardless of the post_title.
There such a function exist?
How can I solve this?
Thank you for your help
It looks like a small variation on post_exists() should work. Create a function like this in your child theme's functions.php, and then use it instead of post_exists():
function post_exists_by_content($content) {
global $wpdb;
$post_content = wp_unslash( sanitize_post_field( 'post_content', $content, 0, 'db' ) );
$query = "SELECT ID FROM $wpdb->posts WHERE 1=1";
$args = array();
if ( !empty ( $content ) ) {
$query .= ' AND post_content = %s';
$args[] = $post_content;
}
if ( !empty ( $args ) )
return (int) $wpdb->get_var( $wpdb->prepare($query, $args) );
return 0;
}

WP Learndash plugin, get userdata related to courses and lessons

Hi I am using learndash Wordpress plugin. I want to get the data related to a user tht how many courses he is enrolled in and how many has he completed. Is there a way to check this? does learndash provide any solution for this or should I query data myself?
Any help is appreciated. Thanks in advance.
Please ask for any more details if you want.
You can use the following to get all course ID's the current user is currently enrolled to:
learndash_user_get_enrolled_courses(get_current_user_id())
I found that all is stored inside the table learndash_user_activity and you can query that table to get user stats.
For example I get the list of the in-progress users for a given course with the following query:
public static function get_inprogress_users_for_course( $course_id )
{
global $wpdb;
if( empty( $course_id ) ) return [];
$results = $wpdb->get_results( "SELECT `user_id` FROM `" . $wpdb->prefix . "learndash_user_activity` "
."WHERE `course_id` = '" . intval( $course_id ) . "' "
."AND `activity_type` = 'lesson' "
."GROUP BY `user_id`" );
return $results;
}
In the same way, you can get all the IDs of the users ever enrolled to a course changing activity_type from 'lesson' to 'course' in the query, and if you want to only get enrolled course by a user, you can add the user_id to the query, like this:
public static function get_courses_for_user( $user_id )
{
global $wpdb;
if( empty( $course_id ) ) return [];
$results = $wpdb->get_results( "SELECT * FROM `" . $wpdb->prefix . "learndash_user_activity` "
."WHERE `user_id` = '" . intval( $user_id ) . "' "
."AND `activity_type` = 'course' "
."GROUP BY `course_id`" );
return $results;
}
I know this is not exactly what you were searching for, but it could still be useful.
You can return anything using wp_query. Try this:
function wpso49370180_get_course_name($courseid) {
global $wpdb;
$user_id = the_author_meta( 'ID' ); //alt method below
$query_course = "SELECT post_title
FROM wp_posts
WHERE post_type = 'sfwd-courses'
AND post_status NOT IN ( 'trash','auto-draft','inherit' )
AND post_author='$user_id' LIMIT 10";
return $wpdb->get_var($query_course);
}
You will need to either know the user_id or get it from the post (sfwd-quiz, sfwd-course, sfwd-lesson) -see below.
The data you want can be all (*) You will have to do a meta_query if you want deeper data that is not in the post_type tables.
/**
* Gets the author of the specified post. Can also be used inside the loop
* to get the ID of the author of the current post, by not passing a post ID.
* Outside the loop you must pass a post ID.
*
* #param int $post_id ID of post
* #return int ID of post author
*/
function wpso49370180_get_author( $post_id = 0 ){
$post = get_post( $post_id );
return $post->post_author;
}

sort wordpress posts by title, ignore articles like “the”, “a”, “an”

I'm sorting my posts alphabetically by Title, like so:
<?php
{
$posts = get_posts($query_string .
'&orderby=title&order=asc&posts_per_page=-1');
}
get_template_part( 'loop', 'category' );
?>
I'd like to exclude articles such as "the", "a", and "an" from the sort.
What would be the best way to accomplish this?
Thanks!
I don't know any simple way to do that but you can do this,
For achieving this you need to add a custom meta field to the post. Name it mytitle (say).
For the new posts you add, it is simple, you have to add your modified title(removing a, an, the from the title) in the mytitle custom field in the add posts page.
For old posts it is a bit tricky, you have to write a php code to retrieve the titles of the post remove 'a','an','the' from them using php preg_replace and add it to the postmeta table of your wordpress database using something like this:
<?php //inside loop
$query=INSERT INTO xyz_postmeta (post_id, meta_key, meta_value) VALUES ($postid, 'mytitle' $title);
$wpdb->query('$query'); ?>
where $postid is the post id inside the loop and $title is your modified title.
Now you have updated all the previous posts with custom mytitle field.
Now to display, you have to use a custom loop (not the loop included in the theme).
Here is how you can make a basic custom loop to display posts sorted in order of mytitle.
$querystr = "
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wposts.ID = wpostmeta.post_id
AND wpostmeta.meta_key = 'mytitle'
AND wposts.post_type = 'post'
AND wposts.post_status = 'publish'
ORDER BY wpostmeta.meta_value ASC
";
Now you can execute the query by any means you want. Wordpres provides various methods to do so. Here's a link
For example you can do something like this
$pageposts = $wpdb->get_results($querystr, OBJECT);
foreach ( $pageposts as $pagepost )
{
echo $pagepost->post_title;
//do other stuff to display content, meta etc..
}
You can actually achieve this by manipulating the ORDERBY clause using the posts_orderby_request filter, and using TRIM to ignore articles "the", "a", and "an". Here's an example:
<?php
add_filter( 'posts_orderby_request', 'myproject_title_sort', 10, 2 );
/**
* Ignore opening articles when sorting by Title.
*
* #param string $orderby Order by parameter.
* #param WP_Query $query WP Query object.
*
* #return string
*/
function myproject_title_sort( $orderby, $query ) {
global $wpdb;
// Be sure to add a condition that matches your criteria (post type, archive, etc).
// In this example, we bail early if it's an Admin query, or not a main query.
if ( is_admin() || ! $query->is_main_query() ) {
return $orderby;
}
// This is another check to see if we're on a particular post type archive.
if ( ! $query->is_post_type_archive( 'my-post-type' ) ) {
return $orderby;
}
$title_col = $wpdb->posts . '.post_title';
// Check if we are sorting by post_title.
// You may need to use a separate `pre_get_posts` filter to sort by "title" if not already doing so.
if ( false === strpos( $orderby, $title_col ) ) {
return $orderby;
}
$ignore = "TRIM( LEADING 'the ' FROM LOWER( TRIM( LEADING 'a ' FROM LOWER( TRIM( LEADING 'an ' FROM LOWER( $title_col ) ) ) ) ) )";
$orderby = str_replace( $title_col, $ignore, $orderby );
return $orderby;
}

wordpress get_terms function not working in my plugin

hello again from a far far away place.
you know i`m trying to list all of terms from a custom taxonomy , when i use below code :
$terms = get_terms($taxonomy , 'hide_empty=0');
print_r($terms);
$count = count($terms);
if ( $count > 0 ){
echo "<ul>";
foreach ( $terms as $term ) {
echo "<li>" . $term->name . "</li>";
}
echo "</ul>";
wp return a crazy error that says : INVALID TAXONOMY :
WP_Error Object
(
[errors] => Array
(
[invalid_taxonomy] => Array
(
[0] => Invalid Taxonomy
)
)
[error_data] => Array
(
)
)
it is very interesting that you know , when i use above code in single.php, i have not see any error and it works fine.
somebody please help me !
Resolved
I am trying to use:
get_terms( 'event_category', array('hide_empty'=>FALSE) );
to use my admin theme option and face same problem when using:
add_action( 'init', 'register_features_taxonomy_event_category' );
But now its resolved using:
add_action( 'after_setup_theme', 'register_features_taxonomy_event_category' );
get_terms return invalid taxonomy error because:
you have a custom taxonomy registered in the "init" hook
so in the wp-admin it doesn´t work -> your taxonomy is registered after you call "get_term"
https://wordpress.stackexchange.com/questions/13480/get-terms-return-errors/13482#13482
Oh my ... i solve this by a crazy solution temporary.look below :
function load_terms($taxonomy){
global $wpdb;
$query = 'SELECT DISTINCT
t.name
FROM
`wp-cls`.wp_terms t
INNER JOIN
`wp-cls`.wp_term_taxonomy tax
ON
`tax`.term_id = `t`.term_id
WHERE
( `tax`.taxonomy = \'' . $taxonomy . '\')';
$result = $wpdb->get_results($query , ARRAY_A);
return $result;
}
As you can see i use a query, but i cant apply this plugin to my programming team.i still awaiting for a correct solution/usage for get_terms function in wordpress plugins.
regards.
Nothing really to add but to make it clear: get_terms()doesn't work in "admin_init" action hook!
I did like bizzr3. Just put my code here because I was a bit confuse with bizzr3's code:
function load_terms($taxonomy){
global $wpdb;
$query = 'SELECT DISTINCT
t.name
FROM
wp_terms t
INNER JOIN
wp_term_taxonomy tax
ON
tax.term_id = t.term_id
WHERE
( tax.taxonomy = \'' . $taxonomy . '\')';
$result = $wpdb->get_results($query , ARRAY_A);
return $result;
}
then just call load_terms() in your "admin_init" function:
//get all terms from taxonomy Category
$terms = load_terms('category');
and thanks, works like a charm.
I know I'm late to the party.
To optimise bizzr3's code just a bit; You should use the $wpdb object properties for your table names, as "wp_" is just the default but it could change from site to site. Using the object property you make sure it should work for other WordPress sites as well if they have a different table prefix.
function load_terms( $taxonomy ){
global $wpdb;
$query = "SELECT DISTINCT
t.name
FROM
{$wpdb->terms} t
INNER JOIN
{$wpdb->term_taxonomy} tax
ON
tax.term_id = t.term_id
WHERE
( tax.taxonomy = '{$taxonomy}')";
$result = $wpdb->get_results( $query , ARRAY_A );
return $result;
}
Also changed the single quotes to double quotes to use {$variables}

Resources