wordpress num rows, how? - wordpress

I'm creating a plugin for wordpress and I need to check if a post with a specific title exist or not. This to prevent duplicates, how can I query this and see if it returned true or false?

I’m using this code to get the ID of a post/page by title:
function get_id_by_name($name)
{
global $wpdb;
$id = $wpdb->get_col(
"SELECT ID FROM $wpdb->posts
WHERE post_status = 'publish'
AND post_title = '$name'
LIMIT 1");
return empty ( $id ) ? -1: (int) $id[0];
}
If the post doesn’t exists, the function return -1.

Related

How to manipulate the WooCommerce order key by removing the "wc_" prefix?

I would like to manipulate the order key by removing wc_ from it.
Problem is, no matter what I do, wc_ is not removed.
Is there any way to do this?
add_filter( 'woocommerce_generate_order_key', 'woocommerce_generate_custom_order_key', 10, 1 );
function woocommerce_generate_custom_order_key($order_key){
$order_key = str_replace( 'wc_', '', $order_key );
return $order_key;
}
The _order_key (Order Key) and post_id (Order ID) fields are different.
The order number you see in the WooCommerce backend is the post_id
field of the wp_posts table of the Wordpress database.
The order key instead refers to the _order_key (meta_key) field of the wp_postmeta table of the Wordpress database.
The woocommerce_generate_order_key filter is documented here and as you can see you cannot use it to remove the wc_ prefix from the _order_key field of the order. Here is the extract of the source code:
/**
* Generate an order key with prefix.
*
* #since 3.5.4
* #param string $key Order key without a prefix. By default generates a 13 digit secret.
* #return string The order key.
*/
function wc_generate_order_key( $key = '' ) {
if ( '' === $key ) {
$key = wp_generate_password( 13, false );
}
return 'wc_' . apply_filters( 'woocommerce_generate_order_key', 'order_' . $key );
}
If you want to manipulate the WooCommerce order key you have to use the set_order_key() method of the WC_Order class. Here you find the documentation.
You will also need to update the order post_password field in the wp_posts table.
So, for example, if you wanted to set a custom order key (removing the wc_ prefix) for each new order you could use this function:
// removes the "wc_" prefix from the WooCommerce order key field for each new order
add_action( 'woocommerce_new_order', 'set_custom_order_key', 99, 2 );
function set_custom_order_key( $order_id, $order ) {
// get the order object
$order = wc_get_order( $order_id );
// gets the current order key
$order_key = $order->get_order_key();
// remove the "wc_" prefix
$new_order_key = str_replace( 'wc_', '', $order_key );
// updates the "_order_key" field of the "wp_postmeta" table
$order->set_order_key( $new_order_key );
$order->save();
// updates the "post_password" field of the "wp_posts" table
$post = get_post( $order_id );
$post->post_password = $new_order_key;
wp_update_post( $post );
}
The code has been tested and works. Add it to your active theme's functions.php.
If you want to manipulate the WooCommerce order id you have to use the woocommerce_order_number filter. The documentation can be found here.
You can find some examples here:
Adding suffix and prefix to WooCommerce order number without using a plugin
Woocommerce for Wordpress: How to modify the order number/id?
Add in a custom prefix and suffix to WooCommerce Order Number

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;
}

Woocommerce: order by custom taxonomy

I'm having the following problem. I have set up a Wordpress site with WooCommerce to serve a webshop with only books.
I have created some product attributes that are based on taxonomies like 'publisher' and 'author' (as multiple products can share an author or a publisher)
I would like to be able to sort my products not only on the Woocommerce default fields like 'title' and 'price' but also on these taxonomy fields.
Say for example:
order by Author ASC or order by publisher DESC
As far as I have discovered there is no way to do this with Wordpress core functions. Some say this is because it makes no sense to sort by taxonomy fields, but with the above example I can't understand why you don't want to sort by for example author.
I have played around with sortby meta_value, but this is just querying the direct postmeta, not the taxonomies.
I have knowledge of php, so any solutions involving additional code in my functions.php file will do.
I found out a way how to solve this:
https://gist.github.com/jayarnielsen/12f3a586900aa6759639
I slightly modified the code so it equals the way Woocommerce uses to sort by the system fields "title" and "price" which is adding a url query-param named "sortby" a value structured like this: "field"-"direction"
So to sort by a product property called "pa_tax1" ascending you'll need to add to the url: sortby=pa_tax1-asc
add_filter('posts_clauses', 'posts_clauses_with_tax', 10, 2);
function posts_clauses_with_tax( $clauses, $wp_query ) {
global $wpdb;
// Array of taxonomies you want to sort on
// in case of Woocommerce Properties, be sure to add the pa_ prefix
$taxonomies = array('pa_tax1', 'pa_tax2', 'pa_tax3');
// If no orderby query param is found, do nothing
if( !isset($wp_query->query['orderby']) ) {
return $clauses;
}
// Explode the orderby query-param
$orderQuery = explode('-', $wp_query->query['orderby']);
$orderBy = [];
$orderBy['field'] = $orderQuery[0];
$orderBy['direction'] = (isset($orderQuery[1])) ? strtoupper($orderQuery[1]) : 'ASC';
// Only add clauses, if the sortby field is in our array
if( in_array($orderBy['field'], $taxonomies) ) {
$clauses['join'] .= "
LEFT OUTER JOIN {$wpdb->term_relationships} AS rel2 ON {$wpdb->posts}.ID = rel2.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} AS tax2 ON rel2.term_taxonomy_id = tax2.term_taxonomy_id
LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
";
$clauses['where'] .= " AND (taxonomy = '".$orderBy['field']."' OR taxonomy IS NULL)";
$clauses['groupby'] = "rel2.object_id";
$clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
$clauses['orderby'] .= ( 'ASC' == strtoupper( $orderBy['direction'] ) ) ? 'ASC' : 'DESC';
return $clauses;
}
else {
return $clauses;
}
}

wordpress get post_id where meta_value =

I am trying to query the wordpress post_meta table by meta_value.
I would like to output all post_id's where the meta_value is = to _parent_product. Here is my code:
$posts = $wpdb->get_results("SELECT *, FROM $table WHERE meta_key='_parent_product' ");
foreach ( $posts as $post ){
$id = $post->post_id;
echo $id;
}
The above outputs nothing and im not quite sure why? Can anyone see anything wrong?
As stated in the comment,
There is a comma (,) behind SELECT *,. Therefor the given SQL is invalid and will fail to retrieve any results.

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;
}

Resources