Changeset 3427994
- Timestamp:
- 12/26/2025 09:57:53 PM (3 months ago)
- Location:
- muslim-prayer-times/trunk
- Files:
-
- 6 edited
-
includes/rest-api.php (modified) (6 diffs)
-
includes/salah-api/Calculations/TimeHelpers.php (modified) (1 diff)
-
includes/upgrade.php (modified) (1 diff)
-
muslim-prayer-times.php (modified) (2 diffs)
-
readme.txt (modified) (3 diffs)
-
settings.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
muslim-prayer-times/trunk/includes/rest-api.php
r3427919 r3427994 52 52 // Build Info Object 53 53 $info = array( 54 'title' => get_bloginfo('name') . ' Prayer Times',55 'description' => 'Islamic prayer times provided by ' . get_bloginfo('name'),54 'title' => sanitize_text_field(get_bloginfo('name')) . ' Prayer Times', 55 'description' => 'Islamic prayer times provided by ' . sanitize_text_field(get_bloginfo('name')), 56 56 'version' => '1.0.0', 57 57 ); … … 59 59 // Get admin email if available 60 60 $admin_email = get_option('admin_email'); 61 if ($admin_email ) {61 if ($admin_email && is_email($admin_email)) { 62 62 $info['contact'] = array( 63 'name' => get_bloginfo('name'),64 'email' => $admin_email,63 'name' => sanitize_text_field(get_bloginfo('name')), 64 'email' => sanitize_email($admin_email), 65 65 ); 66 66 } 67 67 68 68 // Build Location Object 69 // Sanitize and validate timezone 70 $default_timezone = 'America/Los_Angeles'; 71 $timezone = isset($opts['tz']) ? sanitize_text_field($opts['tz']) : $default_timezone; 72 73 // Validate timezone against PHP's list of valid timezones 74 $valid_timezones = timezone_identifiers_list(); 75 if (!in_array($timezone, $valid_timezones, true)) { 76 $timezone = $default_timezone; 77 } 78 69 79 $location = array( 70 80 'latitude' => isset($opts['lat']) ? floatval($opts['lat']) : 47.7623, 71 81 'longitude' => isset($opts['lng']) ? floatval($opts['lng']) : -122.2054, 72 'timezone' => isset($opts['tz']) ? $opts['tz'] : 'America/Los_Angeles',82 'timezone' => $timezone, 73 83 'dateFormat' => 'YYYY-MM-DD', 74 84 'timeFormat' => 'HH:mm', … … 315 325 global $wpdb; 316 326 327 // Check cache first 317 328 $from_date = $request->get_param('fromDate'); 318 329 $to_date = $request->get_param('toDate'); … … 328 339 } 329 340 330 // Validate date format 341 // Validate date format and actual date validity 331 342 if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $from_date) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $to_date)) { 332 343 return new WP_Error('invalid_date', 'Date must be in YYYY-MM-DD format', array('status' => 400)); 333 344 } 334 345 346 // Validate that dates are actually valid (e.g., not 2025-02-30) 347 $from_date_obj = DateTime::createFromFormat('Y-m-d', $from_date); 348 $to_date_obj = DateTime::createFromFormat('Y-m-d', $to_date); 349 350 if (!$from_date_obj || $from_date_obj->format('Y-m-d') !== $from_date || 351 !$to_date_obj || $to_date_obj->format('Y-m-d') !== $to_date) { 352 return new WP_Error('invalid_date', 'Invalid date provided', array('status' => 400)); 353 } 354 355 // Ensure from_date is not after to_date 356 if ($from_date_obj > $to_date_obj) { 357 return new WP_Error('invalid_date_range', 'Start date must be before or equal to end date', array('status' => 400)); 358 } 359 360 // Limit date range to prevent abuse (max 1 year) 361 $date_diff = $from_date_obj->diff($to_date_obj); 362 $days_diff = $date_diff->days; 363 if ($days_diff > 366) { 364 return new WP_Error('date_range_too_large', 'Date range cannot exceed 1 year', array('status' => 400)); 365 } 366 367 // Check cache for this date range 368 $cache_key = 'muslprti_csv_' . md5($from_date . '_' . $to_date); 369 $cached_data = wp_cache_get($cache_key, 'muslim_prayer_times'); 370 371 if (false !== $cached_data) { 372 // Return cached CSV content directly to avoid JSON encoding 373 header('Content-Type: text/csv; charset=utf-8'); 374 header('Content-Disposition: inline; filename="prayer-times.csv"'); 375 header('Content-Length: ' . strlen($cached_data)); 376 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 377 echo $cached_data; 378 exit; 379 } 380 381 // Table name is safe - MUSLPRTI_IQAMA_TABLE is a constant, not user input 335 382 $table_name = $wpdb->prefix . MUSLPRTI_IQAMA_TABLE; 336 383 337 384 // Query prayer times from database 385 // Note: Table name must be escaped outside of prepare() as prepare() only handles placeholders 338 386 $query = $wpdb->prepare( 339 387 "SELECT day, fajr_athan, fajr_iqama, sunrise, dhuhr_athan, dhuhr_iqama, 340 388 asr_athan, asr_iqama, maghrib_athan, maghrib_iqama, isha_athan, isha_iqama 341 FROM {$table_name}389 FROM " . esc_sql($table_name) . " 342 390 WHERE day >= %s AND day <= %s 343 391 ORDER BY day ASC", … … 352 400 } 353 401 354 // Set proper headers for CSV output 355 header('Content-Type: text/csv; charset=utf-8'); 356 header('Content-Disposition: inline; filename="prayer-times.csv"'); 357 358 // Open output stream 359 $output = fopen('php://output', 'w'); 360 361 // Add header row 402 // Build CSV content in memory without using fopen() 403 // Define headers 362 404 $headers = array( 363 405 'day', 'fajr_athan', 'fajr_iqama', 'sunrise', 'dhuhr_athan', 'dhuhr_iqama', 364 406 'asr_athan', 'asr_iqama', 'maghrib_athan', 'maghrib_iqama', 'isha_athan', 'isha_iqama' 365 407 ); 366 fputcsv($output, $headers); 408 409 // Build CSV content as string 410 $csv_lines = array(); 411 412 // Add header row 413 $csv_lines[] = implode(',', array_map(function($header) { 414 return '"' . str_replace('"', '""', $header) . '"'; 415 }, $headers)); 367 416 368 417 // Add data rows … … 370 419 $csv_row = array(); 371 420 foreach ($headers as $header) { 372 $csv_row[] = isset($row[$header]) ? $row[$header] : ''; 373 } 374 fputcsv($output, $csv_row); 375 } 376 377 fclose($output); 421 $value = isset($row[$header]) ? $row[$header] : ''; 422 $csv_row[] = '"' . str_replace('"', '""', $value) . '"'; 423 } 424 $csv_lines[] = implode(',', $csv_row); 425 } 426 427 // Combine all lines 428 $csv_content = implode("\n", $csv_lines); 429 430 // Cache the CSV content for 5 minutes 431 wp_cache_set($cache_key, $csv_content, 'muslim_prayer_times', 300); 432 433 // For CSV, we need to output directly to avoid JSON encoding 434 // Set headers for CSV download 435 header('Content-Type: text/csv; charset=utf-8'); 436 header('Content-Disposition: inline; filename="prayer-times.csv"'); 437 header('Content-Length: ' . strlen($csv_content)); 438 439 // Output CSV content and exit 440 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 441 echo $csv_content; 378 442 exit; 379 443 } -
muslim-prayer-times/trunk/includes/salah-api/Calculations/TimeHelpers.php
r3427919 r3427994 204 204 205 205 if (count($parts) !== 2) { 206 throw new \InvalidArgumentException("Invalid time format: {$timeString}");206 throw new \InvalidArgumentException("Invalid time format: " . esc_html($timeString)); 207 207 } 208 208 -
muslim-prayer-times/trunk/includes/upgrade.php
r3303241 r3427994 22 22 // Only add the column if it doesn't exist 23 23 if (empty($column_exists)) { 24 $wpdb->query("ALTER TABLE $table_name ADD COLUMN sunrise time DEFAULT NULL AFTER fajr_iqama"); 24 // Table name must be escaped separately as wpdb->prepare() doesn't handle identifiers 25 $wpdb->query("ALTER TABLE " . esc_sql($table_name) . " ADD COLUMN sunrise time DEFAULT NULL AFTER fajr_iqama"); 25 26 update_option('muslprti_db_version', '1.1'); 26 27 } -
muslim-prayer-times/trunk/muslim-prayer-times.php
r3427919 r3427994 4 4 Plugin URI: https://github.com/stankovski/wp-prayer-times 5 5 Description: A WordPress plugin for managing and displaying Islamic prayer times. 6 Version: 1.2 6 Version: 1.2.1 7 7 Requires at least: 5.0 8 8 Requires PHP: 7.0 9 Tested up to: 6.9 9 10 Author: stankovski 10 11 Author URI: https://github.com/stankovski … … 25 26 26 27 // Define version for database upgrades 27 define('MUSLPRTI_DB_VERSION', '1.2 ');28 define('MUSLPRTI_DB_VERSION', '1.2.1'); 28 29 29 30 // Include the upgrade script -
muslim-prayer-times/trunk/readme.txt
r3427919 r3427994 3 3 Tags: prayer times, muslim, islamic, mosque, salah 4 4 Requires at least: 5.0 5 Tested up to: 6. 8.36 Stable tag: 1.2 5 Tested up to: 6.9 6 Stable tag: 1.2.1 7 7 Requires PHP: 7.0 8 8 License: MIT … … 19 19 * Monthly prayer times calendar 20 20 * Live prayer times display that updates automatically 21 * SalahAPI 1.0 support for standardized prayer times data exchange 22 * REST API endpoints for integration with other systems 21 23 * Customizable calculation methods (MWL, ISNA, Egypt, etc.) 22 24 * Blocks and shortcodes for easy integration … … 139 141 == Changelog == 140 142 143 = 1.2.1 = 144 * Tested with WordPress 6.9 145 * Minor bug fixes and improvements 146 141 147 = 1.2 = 142 * Added support for SalahAPI (https://github.com/salahapi/salahapi-specification/)148 * Added support for SalahAPI 1.0 (https://github.com/salahapi/salahapi-specification/) 143 149 * REST API endpoint for standardized prayer times data exchange 144 150 * CSV export endpoint for prayer times data -
muslim-prayer-times/trunk/settings.php
r3427919 r3427994 977 977 echo sprintf( 978 978 'Ramadan %d: %s to %s', 979 $current_year,979 esc_html($current_year), 980 980 esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['start']))), 981 981 esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['end']))) … … 986 986 echo sprintf( 987 987 'Next Ramadan (%d): %s to %s', 988 $current_year + 1,988 esc_html($current_year + 1), 989 989 esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['start']))), 990 990 esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['end'])))
Note: See TracChangeset
for help on using the changeset viewer.