Converting Date Format in Wordpress Learndash LMS

Viewed 421

I'm trying to customize an LMS plugin in Wordpress, that is LearnDash. In 'Lesson Access Settings' section, there is an option called 'Specific date'. You can see the section in the following picture: enter image description here

This section just works with Gregorian date while I need it to take Jalali date. When the admin clicks on 'update' button in Wordpress, the data concerning the date and time as inserted in the fields shown in the picture above are inserted into the database in a timestamp format. However, I cannot find where this process is done and how Wordpress does it. There are two blocks of code that I think are somehow related to this process, yet I don't figure out where in these blocks LearnDash or Wordpress saves the date in timestamp format in the Database.

public function create_section_field( $field_args = array() ) {
    global $wp_locale;

    /** This filter is documented in includes/settings/settings-fields/class-ld-settings-fields-checkbox-switch.php */
    $field_args = apply_filters( 'learndash_settings_field', $field_args );

    /** This filter is documented in includes/settings/settings-fields/class-ld-settings-fields-checkbox-switch.php */
    $html       = apply_filters( 'learndash_settings_field_html_before', '', $field_args );

    $date_value = '';

    if ( isset( $field_args['value'] ) ) {

        if ( ! empty( $field_args['value'] ) ) {
            if ( ! is_numeric( $field_args['value'] ) ) {
                $date_value = learndash_get_timestamp_from_date_string( $date_value );
            } else {
                // If we have a timestamp we assume it is GMT. So we need to convert it to local.
                $value_ymd  = get_date_from_gmt( date( 'Y-m-d H:i:s', $field_args['value'] ), 'Y-m-d H:i:s' );
                $date_value = strtotime( $value_ymd );
            }
        }
    }

    if ( ! empty( $date_value ) ) {
        $value_jj = gmdate( 'd', $date_value );
        $value_mm = gmdate( 'm', $date_value );
        $value_aa = gmdate( 'Y', $date_value );
        $value_hh = gmdate( 'H', $date_value );
        $value_mn = gmdate( 'i', $date_value );
    } else {
        $value_jj = '';
        $value_mm = '';
        $value_aa = '';
        $value_hh = '';
        $value_mn = '';
    }

    $field_name  = $this->get_field_attribute_name( $field_args, false );
    $field_class = $this->get_field_attribute_class( $field_args, false );
    $field_id    = $this->get_field_attribute_id( $field_args, false );

    $month_field = '<span class="screen-reader-text">' . esc_html__( 'Month', 'learndash' ) . '</span><select class="ld_date_mm ' . $field_class . '" name="' . $field_name . '[mm]" ><option value="">' . esc_html__( 'MM', 'learndash' ) . '</option>';
    for ( $i = 1; $i < 13; $i = $i + 1 ) {
        $monthnum     = zeroise( $i, 2 );
        $monthtext    = $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) );

        $month_field .= "\t\t\t" . '<option value="' . $monthnum . '" data-text="' . $monthtext . '" ' . selected( $monthnum, $value_mm, false ) . '>';
        $month_field .= sprintf( esc_html_x( '%1$s-%2$s', 'placeholder: month number, month text', 'learndash' ), $monthnum , $monthtext ) . "</option>\n";
    }
    $month_field .= '</select>';
    $day_field    = '<span class="screen-reader-text">' . esc_html__( 'Day', 'learndash' ) . '</span><input type="number" placeholder="روز" min="1" max="31" class="ld_date_jj ' . $field_class . '" name="' . $field_name . '[jj]" value="' . $value_jj . '" size="2" maxlength="2" autocomplete="off" />';
    $year_field   = '<span class="screen-reader-text">' . esc_html__( 'Year', 'learndash' ) . '</span><input  type="number" placeholder="سال" min="0000" max="9999" class="ld_date_aa ' . $field_class . '" name="' . $field_name . '[aa]" value="' . $value_aa . '" size="4" maxlength="4" autocomplete="off" />';
    $hour_field   = '<span class="screen-reader-text">' . esc_html__( 'Hour', 'learndash' ) . '</span><input type="number" min="0" max="23" placeholder="ساعت" class="ld_date_hh ' . $field_class . '" name="' . $field_name . '[hh]" value="' . $value_hh . '" size="2" maxlength="2" autocomplete="off" />';
    $minute_field = '<span class="screen-reader-text">' . esc_html__( 'Minute', 'learndash' ) . '</span><input type="number" min="0" max="59" placeholder="دقیقه" class="ld_date_mn ' . $field_class . '" name="' . $field_name . '[mn]" value="' . $value_mn . '" size="2" maxlength="2" autocomplete="off" />';

    $html .= '<div class="ld_date_selector">' . sprintf(
        // Translators: placeholders Month, Day, Year, Hour, Minute
            esc_html__( '%1$s %2$s, %3$s @ %4$s:%5$s' ),
            $month_field,
            $day_field,
            $year_field,
            $hour_field,
            $minute_field
        ) . '</div>';

    /** This filter is documented in includes/settings/settings-fields/class-ld-settings-fields-checkbox-switch.php */
    $html = apply_filters( 'learndash_settings_field_html_after', $html, $field_args );

    echo $html;
}

add_action(
    'learndash_settings_sections_fields_init',
    function() {
        LearnDash_Settings_Fields_Date_Entry::add_field_instance( 'date-entry' );
    }
);

There is another function I have traced to somehow be related to this operation. This function tries to update the timestamp, I guess. But I couldn't find where this function is called for, or even is it really related to what I am looking for. It comes below:

/**
 * Updates the course access time for a user.
 *
 * @since 2.6.0
 *
 * @param int        $course_id Course ID for update.
 * @param int        $user_id   User ID for update.
 * @param string|int $access    Optional. Value can be a date string (YYYY-MM-DD hh:mm:ss or integer value. Default empty.
 * @param boolean    $is_gmt    Optional. True if the access value is GMT or false if it is relative to site timezone. Default false.
 *
 * @return boolean Returns true if the value is updated successfully.
 */
function ld_course_access_from_update( $course_id, $user_id, $access = '', $is_gmt = false ) {

    if ( ( ! empty( $course_id ) ) && ( ! empty( $user_id ) ) && ( ! empty( $access ) ) ) {
        if ( ! is_numeric( $access ) ) {
            // If we a non-numberic value like a date stamp Y-m-d hh:mm:ss we want to convert it to a GMT timestamp.
            $access_time = learndash_get_timestamp_from_date_string( $access, !$is_gmt );
        } elseif ( is_string( $access ) ) {
            if ( ! $is_gmt ) {
                $access = get_gmt_from_date( $access, 'Y-m-d H:i:s' );

            }
            $access_time = strtotime( $access );
        } else {
            return false;
        }

        if ( ( ! empty( $access_time ) ) && ( $access_time > 0 ) ) {
            // We don't allow dates greater than now.
            if ( $access_time > time() ) {
                $access_time = time();
            }
            
            $course_args = array(
                'course_id'     => $course_id,
                'post_id'       => $course_id,
                'activity_type' => 'course',
                'user_id'       => $user_id,
                'activity_started' => $access_time,
            );
            $activity_id = learndash_update_user_activity( $course_args ); 

//          return update_user_meta( $user_id, 'course_' . $course_id . '_access_from', $access_time );
            return update_user_meta( $user_id, 'course_' . $course_id . '_access_from', 'access_time' );
        }
    }
}

The following string is also what Wordpress is saving in the Database:

a:29:{i:0;s:0:"";s:37:"sfwd-lessons_lesson_materials_enabled";s:0:"";s:29:"sfwd-lessons_lesson_materials";s:0:"";s:33:"sfwd-lessons_lesson_video_enabled";s:0:"";s:29:"sfwd-lessons_lesson_video_url";s:0:"";s:31:"sfwd-lessons_lesson_video_shown";s:0:"";s:36:"sfwd-lessons_lesson_video_auto_start";s:0:"";s:39:"sfwd-lessons_lesson_video_show_controls";s:0:"";s:37:"sfwd-lessons_lesson_video_focus_pause";s:0:"";s:36:"sfwd-lessons_lesson_video_track_time";s:0:"";s:39:"sfwd-lessons_lesson_video_auto_complete";s:0:"";s:45:"sfwd-lessons_lesson_video_auto_complete_delay";s:0:"";s:46:"sfwd-lessons_lesson_video_show_complete_button";s:0:"";s:37:"sfwd-lessons_lesson_assignment_upload";s:0:"";s:47:"sfwd-lessons_assignment_upload_limit_extensions";s:0:"";s:41:"sfwd-lessons_assignment_upload_limit_size";s:0:"";s:45:"sfwd-lessons_lesson_assignment_points_enabled";s:0:"";s:44:"sfwd-lessons_lesson_assignment_points_amount";s:0:"";s:42:"sfwd-lessons_assignment_upload_limit_count";s:0:"";s:47:"sfwd-lessons_lesson_assignment_deletion_enabled";s:0:"";s:36:"sfwd-lessons_auto_approve_assignment";s:0:"";s:39:"sfwd-lessons_forced_lesson_time_enabled";s:0:"";s:31:"sfwd-lessons_forced_lesson_time";s:0:"";s:46:"sfwd-lessons_lesson_video_hide_complete_button";s:0:"";s:28:"sfwd-lessons_lesson_schedule";s:27:"visible_after_specific_date";s:19:"sfwd-lessons_course";i:161;s:26:"sfwd-lessons_sample_lesson";s:0:"";s:26:"sfwd-lessons_visible_after";s:0:"";s:40:"sfwd-lessons_visible_after_specific_date";s:10:"1588555800";}

out of this long thread, the latest part is what is important for me, that is:

sfwd-lessons_visible_after_specific_date";s:10:"1588555800";}

As you can see Wordpress is just taking the date and then converts it into a timestamp and then saves it in the database. If I just knew where this process is done, I could turn the Gregorian date into Jalali and then save it in timestamp format in the database.

I think there might be something like an add_action hook to do the task, yet I cannot trace it.

Any help would be more than welcome. Millions of thanks in advance.

1 Answers

$access_time = strtotime( $access ); is the function that is converting your date to a timestamp like that.

If you want to store it in another format you need to do something like this

$access_time = date('jS F Y', strtotime($access));

Where the first parameter of date is from the following documentation https://www.php.net/manual/en/datetime.formats.date.php

I wouldn't however modify how that data is saved to the database as it could lead to more headaches down the line with other functions trying to use that timestamp as a timestamp and not a date. I would recommend either using the date function above when outputting the date, or create another post meta with your formatted date inside of it.

Related