__("All Level", "acadlix"), "beginner" => __("Beginner", "acadlix"), "intermediate" => __("Intermediate", "acadlix"), "advance" => __("Advance", "acadlix"), ]; return $courseLevels[$level] ?? __("All Level", "acadlix"); } public function formatPrice($price = 0, $asString = false) { // Fallback settings if not provided $decimals = acadlix()->helper()->acadlix_get_option('acadlix_number_of_decimals') ?? 2; $thousandSep = acadlix()->helper()->acadlix_get_option('acadlix_thousand_separator') ?? ','; $decimalSep = acadlix()->helper()->acadlix_get_option('acadlix_decimal_separator') ?? '.'; if (!is_numeric($price)) { return $asString ? number_format(0, $decimals, $decimalSep, $thousandSep) : 0; } if ($asString) { // Return formatted string with thousand & decimal separator return number_format((float) $price, $decimals, $decimalSep, $thousandSep); } // Return numeric (no formatting) return round((float) $price, $decimals); } /** * Format the price according to the currency settings and return it as a string. * * @param float $price The price to be formatted. * * @return string|Wp_Error The formatted price or a Wp_Error object if an error occurs. */ public function getCoursePrice(float $price): string|Wp_Error { $helper = acadlix()->helper(); $currency_option = $helper->acadlix_get_option("acadlix_currency"); $currency_position_option = $helper->acadlix_get_option("acadlix_currency_position"); if (is_null($currency_option) || is_null($currency_position_option)) { return new WP_Error("currency_not_configured", __("Currency settings are not configured properly.", "acadlix")); } $currency_symbols = $helper->acadlix_currency_symbols(); if (!array_key_exists($currency_option, $currency_symbols)) { return new Wp_Error("currency_symbol_not_found", __("Currency symbol not found for the selected currency.", "acadlix")); } $currency_symbol = $currency_symbols[$currency_option]; $price = $this->formatPrice($price, true); return match ($currency_position_option) { "Left ( $99.99 )" => "$currency_symbol$price", "Right ( 99.99$ )" => "$price$currency_symbol", "Left with space ( $ 99.99 )" => "$currency_symbol $price", "Right with space ( 99.99 $ )" => "$price $currency_symbol", default => "$currency_symbol$price", }; } /** * Generates an HTML string containing links to the profile pages of users enrolled in a course. * * @return string An HTML string containing the links to the user profile pages. * * @throws WP_Error If the course object is invalid or if the user objects in the course object are invalid. */ public function getCourseUserHtml($course): string|WP_Error { if (is_null($course)) { return new WP_Error("invalid_course", __("The course object is invalid.", "acadlix")); } if (count($course->users) === 0) { return $this->getUserLinkHtml($course->post_author); } $userLinks = []; foreach ($course->users as $user) { if (is_null($user)) { return new WP_Error("invalid_user", __("The user objects in the course object are invalid.", "acadlix")); } $userLinks[] = $this->getUserLinkHtml($user->ID); } return implode(', ', $userLinks); } /** * Generates an HTML link to a user's profile page. * * @param int $userId The ID of the user to generate a link for. * * @return string An HTML link to the user's profile page. */ public function getUserLinkHtml(int $userId): string { $userInfo = get_userdata($userId); return sprintf( '%s', esc_url(get_author_posts_url($userId)), esc_html($userInfo->display_name) ); } /** * Converts an integer representation of time (hours, minutes, seconds) into a standardized string format (HH:MM:SS). * * @param int $hours The number of hours. * @param int $minutes The number of minutes. * @param int $seconds The number of seconds. * * @return string The time in the standardized string format. */ public function intToTimeFormat(int $hours, int $minutes, int $seconds): string { return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds); } /** * Converts an integer representation of time (weeks, days, hours, minutes) into a readable string format. * * @param int $weeks The number of weeks. * @param int $days The number of days. * @param int $hours The number of hours. * @param int $minutes The number of minutes. * * @return string The time in a readable string format. */ public function getCourseDuration(int $weeks, int $days, int $hours, int $minutes): string { $parts = []; $timeUnits = [ 'week' => $weeks, 'day' => $days, 'hour' => $hours, 'minute' => $minutes, ]; foreach ($timeUnits as $unit => $value) { if ($value > 0) { $parts[] = $value . ' ' . $unit . ($value > 1 ? 's' : ''); } } return implode(' ', $parts); } /** * Checks if a course registration is open based on the given start and end dates. * * @param string $start_date The start date of the registration period. * @param string $end_date The end date of the registration period. * * @return array An associative array containing the status of the registration (true or false) and a message. */ public function checkRegistrationDate($start_date, $end_date) { // Initialize the response array $response = [ 'status' => true, 'message' => __('Registration is open.', 'acadlix'), ]; // Check for null or empty values if (empty($start_date) && empty($end_date)) { return $response; } $timezone_string = acadlix()->helper()->acadlix_get_time_zone_string(); $dateTimeFormat = acadlix()->helper()->acadlix_get_date_time_format(); // Get current date/time in WordPress timezone // $current_timestamp = current_time('timestamp'); $current_timestamp = time(); $wp_timezone = wp_timezone(); // Check start_date if (!empty($start_date)) { $start_datetime = new \DateTime($start_date, $wp_timezone); $start_timestamp = $start_datetime->getTimestamp(); // $start_timestamp = strtotime($start_date); if ($current_timestamp < $start_timestamp) { return [ 'status' => false, 'message' => sprintf( /* translators: 1: Registration start date, 2: Timezone string */ esc_html__('Registration opens after: %1$s %2$s', 'acadlix'), wp_date($dateTimeFormat, $start_timestamp), esc_html($timezone_string) ), ]; } } // Check end_date if (!empty($end_date)) { $end_datetime = new \DateTime($end_date, $wp_timezone); $end_timestamp = $end_datetime->getTimestamp(); // $end_timestamp = strtotime($end_date); if ($current_timestamp > $end_timestamp) { return [ 'status' => false, 'message' => __('Registration is closed', 'acadlix'), ]; } } return $response; } public function courseSingleReviewStar( $type = 'filled', // 'filled', 'half', 'unfilled', $fs = 6 // font size in rem 1-9 ) { $class = ''; match ($type) { 'filled' => $class = 'fas fa-star', 'half' => $class = 'fas fa-star-half-alt', // Placeholder for half star 'unfilled' => $class = 'far fa-star', default => $class = 'far fa-star', }; return [ 'component' => 'div', 'props' => [ 'class' => 'acadlix-rating-star-icon acadlix-fs-' . esc_attr($fs), 'style' => 'color: var(--acadlix-star-color);' // Gold color for stars ], 'children' => [ [ 'component' => 'i', 'props' => [ 'class' => esc_attr($class) ] ], ] ]; } public function courseReviewStar( $rating = 0, $fs = 6 // font size in rem 1-9 ) { $stars = []; $filled_stars = floor($rating); // Number of filled stars $has_half = ($rating - $filled_stars) > 0; // Check if there's a decimal part for ($i = 1; $i <= 5; $i++) { if ($i <= $filled_stars) { $stars[] = $this->courseSingleReviewStar("filled", $fs); } elseif ($has_half && $i == $filled_stars + 1) { $stars[] = $this->courseSingleReviewStar("half", $fs); } else { $stars[] = $this->courseSingleReviewStar("unfilled", $fs); } } return $stars; } } }