Automatically update ACF field upon date - automation

Here is what I am trying to accomplish: turn off a True/False Advanced Custom Fields(ACF) option on a post if the current date is on or past a selected date on the same post. Also after that code, turn off a Sample Lesson True/False option inside of the lessons attached to the current post.
At first, all I had was the update_sample_child_lessons function with an 'init' action (i.e.add_action( 'init', 'update_sample_child_lessons' );), but that seemed to only run when I clicked update on the post. It did work and everything switched over, but it only ran when I manually clicked Update on the post. So then I did a little research and found that a Cron job should do the trick if I want the code to run automatically without me having to click update, but for some reason I can't seem to get it to work.
So if you know of a way to accomplish what I am trying to do with the code below, or with other code that is completely different, any suggestions or help would be much appreciated.
//CRON JOB TO RUN EVERYDAY
function myprefix_custom_cron_schedule( $schedules ) {
$schedules['every_day'] = array(
'interval' => 86400, //24 HOURS IN SECONDS
'display' => __( 'Every 24 hours' ),
);
return $schedules;
}
add_filter( 'cron_schedules', 'myprefix_custom_cron_schedule' );
if ( ! wp_next_scheduled( 'myprefix_cron_hook' ) ) {
wp_schedule_event( time(), 'every_day', 'myprefix_cron_hook' );
}
//AUTOMATICALLY ADJUSTS SAMPLE LESSON FREE OPTIONS AND FREE BANNER IF DATE IS PASSED
add_action( 'myprefix_cron_hook', 'update_sample_child_lessons' );
function update_sample_child_lessons() {
$allcourses = array(
'post_type' => 'sfwd-courses', //CUSTOM POST TYPE: COURSES
'posts_per_page' => -1 //QUERY ALL OF THEM
);
$query = new WP_Query($allcourses);
if ($query->have_posts()) {
global $post;
if ( ( in_array( $post->post_type, array( 'sfwd-courses' ), true ) )) { //ONLY DO ACTION IF ON CPT OF COURSES
while ($query->have_posts()) {
$query->the_post();
$course_id = learndash_get_course_id( $post->ID ); //GET THE COURSE ID
$free = get_field('display_free_lessons', $course_id); //GET THE FREE COURSE OPTION (TRUE/FALSE TICKER)
if (!empty($free)) { //ONLY DO REST OF CODE IF FREE OPTION IS TURNED ON
$freeDate = get_field('free_until', $course_id); //GET THE DATE FIELD THAT THE COURSE IS FREE UNTIL
$currentDate = date('Ymd'); //GET CURRENT DATE
$diff = strtotime($freeDate) - strtotime($currentDate); //GET THE DIFFERENCE BETWEEN THE TWO DATES
if ($diff <= 0) { //ONLY DO REST OF CODE IF DATE DIFFERENCE IS LESS THAN OR EQUAL TO ZERO
$value = '';
update_field('display_free_lessons', $value, $course_id); //UPDATES THE FREE OPTION FIELD TO FALSE(OR NOTHING)
//LESSON CODE
$lessons = array_slice(learndash_course_get_lessons($course_id), 1); //GET ALL THE LESSONS FROM THE COURSE EXCEPT FOR THE FIRST ONE
foreach ($lessons as $lesson) {
$lessonID = $lesson->ID; //GET THE LESSON ID
$lesson_meta = get_post_meta($lessonID); //GET THE METADATA FOR THE LESSON
if ( is_array( $lesson_meta ) ) {
foreach ( $lesson_meta as $meta_key => $meta_value ) {
if ( '_sfwd-lessons' === $meta_key ) {
$lesson_settings = maybe_unserialize( $meta_value[0] ); //SOME OF THE ARRAYS ARE SERIALIZED, SO UNSERIALIZE IF NEEDED
if ( isset( $lesson_settings['sfwd-lessons_sample_lesson'] ) ) {
$lesson_settings['sfwd-lessons_sample_lesson'] = ''; //TURN OFF THE SAMPLE LESSON OPTION ON THE LESSONS
}
update_post_meta( $lessonID, $meta_key, $lesson_settings );
}
}
}
} //END FOREACH
} //END IF DIFF IS 0
wp_reset_postdata();
}
}
}
}
}

Thanks for the comment #Luke Chaffey, I was actually able to figure it out after finding I had my cron actions reversed. Below is the final code that I got working so that it runs every day at 12am:
//CRON JOB TO RUN EVERYDAY
function custom_cron_schedule( $schedules ) {
$schedules['every_day'] = array(
'interval' => 86400,
'display' => __( 'Every 24 hours' ),
);
return $schedules;
}
add_filter( 'cron_schedules', 'custom_cron_schedule' );
$ve = get_option('gmt_offset') > 0 ? '-' : '+';
if ( ! wp_next_scheduled('cron_sample_lesson' ) ) {
wp_schedule_event(strtotime('00:00 tomorrow ' . $ve .
absint(get_option('gmt_offset')) . ' HOURS'), 'daily','cron_sample_lesson' );
}
add_action('cron_sample_lesson', 'update_sample_child_lessons' );
function update_sample_child_lessons() {...

Related

Hide Member count in Buddypress groups

I am new to BuddyPress and want to hide the member count in the groups. As mentioned in another forum, I tried using this code in bp-custom.php but it doesn't work.
function john_gettext( $translated, $original_text, $domain ) {
if ( 'buddypress' !== $domain )
return $translated;
switch ( $original_text ) {
case 'All Members <span>%s</span>':
return 'All Members';
default:
return $translated;
}
}
add_filter( 'gettext', 'john_gettext', 20, 3 );
Also tried adding this code and doesn't work:
add_filter( ‘bp_get_total_member_count’, ‘bp_core_number_format’ );
Any ways to hide the member count?
gettext is not used in that context. And changing the count integer will result in a zero being shown. But you can filter the existence of a count and thereby remove it.
Try:
function john_member_count( $count, $item, $nav ) {
if ( $nav == 'directory' )
$count = false;
return $count;
}
add_filter( 'bp_nouveau_nav_has_count', 'john_member_count',30, 3 );

Is there a find and replace functions for SQL

I have some values in my SQL i want to trim and replace.
I want to look in a key field _booking_persons and only store all between "" and remove the rest.
So at the moment i got this in all fields
s:14:"a:1:{i:0;i:4;}“
and i want to keep a:1:{i:0;i:4;} so everything between " ".
I tried to fix it with wordpress post_meta_update. So i tought maybe its easy to do that with SQL.
$args = array('post_type' => 'wc_booking', 'posts_per_page' => '-1' );
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$post_id = get_the_ID();
$array = get_post_meta( $post_id, '_booking_persons', true );
$between = preg_replace('/(.*)"(.*)"(.*)/sm', '\2', $array);
update_post_meta( $post_id, '_booking_persons', $between );
}
/* Restore original Post Data */
wp_reset_postdata();
} else {
// no posts found
}
I expect a:1:{i:0;i:4;} but stay as it is s:14:"a:1:{i:0;i:4;}“
You can do this easily with substring_index function:
SELECT substring_index(substring_index('s:14:\"a:1:{i:0;i:4;}\"', '\"', 2), '\"', -1);
This will return:
a:1:{i:0;i:4;}
Note that you need to escape " character with \
You can see this in action here

SQL to sort nested comments in wordpress by likes

I hope some kind person can help me out here.
I want to sort nested comments in wordpress by likes. I have only found one plugin that does this and it doesn't meet my needs, so I'm attempting to write my own. Most of it is actually pretty straightforward, but the sql is eluding me (not really my strength).
I need an SQL Query to sort comments by likes, with replies immediately following their parent, and replies to each parent also sorted by likes. Top level comments and replies are differentiated by 'layer'. There is only one level of replies. My table looks like this:
ID (Int)
Comment_Name (VarChar)
Layer (Int)... 1 for top level comment, 2 for reply
ID_of_Parent_Comment (Int)... replys must be grouped under top level comment with this id
Likes (Int)
For example, if top level comments are represented by numbers and replies by letters, it would look something like this:
1, 2, 3, 3a, 3b, 4, 5, 5a... etc
Anyone have any ideas?
It turns out that the other answer did not quite work out after all. It sure looked right. Replies were grouped nicely beneath the appropriate parent comment, everthing was sorted by likes. But if you look closely, the sqlfiddle test returned 14 records where there are only 12 available.
After spending way too much time fiddling with it on my site, I couldn't resolve it any further. One group or the other (top level comments or replies) were always either left off or duplicated.
I finally gave up, assuming that it could not be done with SQL, so I went back to something I was familiar with: php. Here is my solution. Hopefully someone will find it useful. If nothing else, it was a fun project.
myComments.php
<?php
global $wpdb;
$post_ID = get_the_ID();
// Get Comment Table
$sql =
" SELECT *"
." FROM wp_comments"
." WHERE comment_post_ID = " . $post_ID // only retrieve comments for this post
." AND comment_parent = '0'" // only retrieve top level comments
." ORDER BY likes DESC"
.";";
$tlc = $wpdb->get_results($sql, ARRAY_A); // Retrieve all records into $tlc
// this should never be
// large enough to be a problem.
$commentCount = count( $tlc ); // Number of TopLevelComments
// Adjust Comments
for ( $i = 0; $i <= $commentCount-1; $i++ ) {
$tlc[$i]['layer'] = 0; // Layer 0 indicates top level comment
$tlc[$i]['index'] = $i; // index is used to group parents
// with children
}
// Get Reply Table
$sql =
" SELECT *"
." FROM wp_comments"
." WHERE comment_post_ID = " . $post_ID
." AND comment_parent > '0'" // only retrieve replies
." ORDER BY likes DESC"
.";";
$replies = $wpdb->get_results($sql, ARRAY_A);
$replyCount = count( $replies );
// Adjust Replies
for ( $i = 0; $i <= $commentCount-1; $i++ ) {
$replies[$i]['layer'] = 1; // Layer 1 indicates replies
}
// Set child index to that of parent
// then add child record to parent array
for ( $i = 0; $i <= $replyCount-1; $i++ ) {
$x = $replies[$i]['comment_parent']; // Get ID of parent
for ( $j = 0; $j <= $commentCount-1; $j++ ) {
if ( $tlc[$j]['comment_ID'] == $x ) { // If parent found
$value = $tlc[$j]['index']; // Get parent's index
$replies[$i]['index'] = $value; // Give child parent's index
array_push ( $tlc, $replies[$i]);
}
}
}
// Sort comments
// Note that $tlc was sorted by select
// and index was assigned while in that order
$tlc = array_orderby($tlc, 'index', SORT_ASC,
'layer', SORT_ASC,
'likes', SORT_DESC);
// Display comments
$commentCount = count($tlc);
if ( $commentCount ) {
echo "<ol class='commentNumbering'>";
// Used to determine if we have opened a second <ol> for nested comments
// and ensure we close it before we are done.
$inReplyList = false;
// We don't want to close the <ol> before we've opened it.
$firstComment = true;
for ( $i = 0; $i <= $commentCount-1; $i++ ) {
$myComment = $tlc[$i];
// Set $depth (needed by reply-link on myCommentTemplate page)
$depth = 0;
$comment_ID = $myComment['comment_ID'];
while( $comment_ID > 0 ) {
$tempComment = get_comment( $comment_ID );
$comment_ID = $tempComment->comment_parent;
$depth++;
}
// Treat each group of nested comments as a separate ordered group
if ( $depth == 2 ) {
if ( ! $inReplyList ) {
echo "<ol>";
$inReplyList = true;
}
} else {
if ( ! $firstComment ) {
if ( $inReplyList ) {
echo "</ol>";
$inReplyList = false;
}
}
}
$firstComment = false;
// Display each comment
include ('myCommentTemplate.php');
}
if ( $inReplyList ) {
echo "</ol>";
}
echo "</ol>";
} else {
echo 'No comments found.';
}
// Where comments are made
include('myCommentForm.php');
$wpdb->flush();
?>
function array_orderby() (located in functions.php)
/* SORT PHP ARRAYS OF RECORDS */
// PHP function 'array_multisort' requires columns //
// This function handles the conversion from row to col and back again //
// Example:
// $sorted = array_orderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC);
function array_orderby()
{
$args = func_get_args();
$data = array_shift($args);
foreach ($args as $n => $field) {
if (is_string($field)) {
$tmp = array();
foreach ($data as $key => $row)
$tmp[$key] = $row[$field];
$args[$n] = $tmp;
}
}
$args[] = &$data;
call_user_func_array('array_multisort', $args);
return array_pop($args);
}
Looks like this should be close:
select
post.ID,
post.likes as postLikes,
reply.ID,
reply.likes as replyLikes
from MyTable post
left join MyTable reply
on post.ID = reply.ID_of_Parent_Comment
where post.ID_of_Parent_Comment is null
order by post.likes desc, reply.likes desc
;
It will give you the parent ID's sorted by parent likes and the related child ID's for each parent (if any) sorted by most liked child

Stumped on this little SQL query

This SQL query is currently returning all values with the word anywhere in it. For instance, typing Mon will return Armoring, Behemoth, Emotion, etc etc. I'd like it to return words that start with the value, like, Monkey, Moment, Monday, etc.
Hope my explanation makes sense, code is below.
function action_ajax_drug_suggest() {
global $wpdb;
if ( empty( $_GET['term'] ) ) {
die();
}
$drug_name = $wpdb->esc_like( $_GET['term'] );
$table = $wpdb->prefix . self::TABLE_DRUG;
$posts = $wpdb->get_results( $wpdb->prepare( "
SELECT name
FROM {$table}
WHERE name LIKE '%%%s%%'
AND details <> ''
LIMIT 5",
$drug_name ) );
foreach( $posts as $post ) {
$names[] = array(
'label' => $post->name,
);
}
wp_send_json( $names );
}
try leaving out the first two %% signs
LIKE '%%%s%%' becomes LIKE '%s%%'

How set quantity to out of stock in Prestashop

i'd like that when my product quantity is equal to 1, the product is out of stock ( and not when quantity is equal to 0 ).
Is it possible ?
How ?
In PrestaShop 1.6 (tested and confirmed working in v1.6.0.14) you can accomplish this by the following method, where the website will always show an available stock quantity that is the real quantity minue one. If you have 6 in stock this modification will change your website to report the stock as 5 to your customers, when you have only 1 stock available, customers will see the product with 0 quantity and marked as out of stock.
Copy the file /classes/stock/StockAvailable.php to /override/classes/stock/StockAvailable.php.
Edit the file /override/classes/stock/StockAvailable.php as follows.
At lines 357-380 is the function AvailableStock::getQuantityAvailableByProduct() that will normally read like this (formatting may vary slightly):
public static function getQuantityAvailableByProduct( $id_product,
$id_product_attribute = null, $id_shop = null ) {
if( $id_product_attribute === null ) $id_product_attribute = 0;
$skey = 'StockAvailable::getQuantityAvailableByProduct_' . (int)$id_product . '-' .
(int)$id_product_attribute . '-' . (int)$id_shop;
if( !Cache::isStored( $key )) {
$query = new DbQuery();
$query->select( 'SUM(quantity)' );
$query->from( 'stock_available' );
if( $id_product !== null ) $query->where( 'id_product = ' . (int)$id_product );
$query->where( 'id_product_attribute = ' . (int)$id_product_attribute );
$query = StockAvailable::addSqlShopRestriction( $query, $id_shop );
Cache::store( $key, (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue( $query ));
}
return Cache::retrieve( $key );
}
Replace the last line of the function beginning with the keyword return to the following:
$iStockQty = Cache::retrieve( $key );
if( $iStockQty > 0 ) $iStockQty--;
return $iStockQty;
Delete the file /cache/class_index.php so that Prestashop automatically re-creates this file taking into account the new override file.
I also found the method self::removeProductFromStockAvailable($id_product) in StockAvailable.php to do some similar stuff.