| 1 |
<?php |
| 2 |
namespace BetterLinks; |
| 3 |
if ( ! defined( 'ABSPATH' ) ) { exit; } |
| 4 |
|
| 5 |
use BetterLinks\Helper; |
| 6 |
|
| 7 |
class Cron |
| 8 |
{ |
| 9 |
public static function init() |
| 10 |
{ |
| 11 |
$self = new self(); |
| 12 |
add_filter('cron_schedules', [$self, 'add_cron_schedule']); |
| 13 |
add_action('betterlinks/write_json_links', [$self, 'write_json_links']); |
| 14 |
|
| 15 |
// Analytics job runs hourly |
| 16 |
if (!wp_next_scheduled('betterlinks/analytics')) { |
| 17 |
$timestamp = time() + (60 * 60); |
| 18 |
wp_schedule_event($timestamp, 'hourly', 'betterlinks/analytics'); |
| 19 |
} |
| 20 |
add_action('betterlinks/analytics', [$self, 'analytics']); |
| 21 |
} |
| 22 |
|
| 23 |
public function add_cron_schedule($schedules) |
| 24 |
{ |
| 25 |
$schedules['every_one_and_half_hours'] = [ |
| 26 |
'interval' => 5400, // Every 90 Minutes |
| 27 |
'display' => __('Every 90 Minutes', 'betterlinks' ), |
| 28 |
]; |
| 29 |
return $schedules; |
| 30 |
} |
| 31 |
|
| 32 |
/** |
| 33 |
* Sync all missing links from database to JSON |
| 34 |
* Called hourly by CRON job and on-demand via Ajax "Refresh Stats" button |
| 35 |
* |
| 36 |
* @since 2.4.9 |
| 37 |
*/ |
| 38 |
public function sync_missing_links_to_json() |
| 39 |
{ |
| 40 |
try { |
| 41 |
$result = Helper::sync_all_missing_links_to_json(); |
| 42 |
|
| 43 |
// Log if links were synced (for debugging) |
| 44 |
if ( !empty($result['synced']) && $result['synced'] > 0 ) { |
| 45 |
// PCP-DEBUG-DISABLED: error_log( 'BetterLinks CRON: Synced ' . $result['synced'] . ' missing links to JSON (Total: ' . $result['total'] . ')' ); |
| 46 |
} |
| 47 |
|
| 48 |
return $result; |
| 49 |
} catch (\Throwable $th) { |
| 50 |
// PCP-DEBUG-DISABLED: error_log( 'BetterLinks CRON Error (sync_missing_links_to_json): ' . $th->getMessage() ); |
| 51 |
return array( 'total' => 0, 'synced' => 0, 'error' => $th->getMessage() ); |
| 52 |
} |
| 53 |
} |
| 54 |
|
| 55 |
public function write_json_links() |
| 56 |
{ |
| 57 |
// Self-heal the uploads deny rule for installs that predate it. |
| 58 |
\BetterLinks\Installer::ensure_uploads_protected(); |
| 59 |
$formattedArray = \BetterLinks\Helper::get_links_for_json(); |
| 60 |
return file_put_contents(BETTERLINKS_UPLOAD_DIR_PATH . '/links.json', json_encode($formattedArray)); |
| 61 |
} |
| 62 |
|
| 63 |
public function analytics() |
| 64 |
{ |
| 65 |
// Sync missing links to JSON first |
| 66 |
$this->sync_missing_links_to_json(); |
| 67 |
|
| 68 |
Helper::clear_query_cache(); |
| 69 |
Helper::clear_analytics_cache(); |
| 70 |
try { |
| 71 |
// insert clicks json data into db |
| 72 |
if (BETTERLINKS_EXISTS_CLICKS_JSON) { |
| 73 |
$Clicks = json_decode(file_get_contents(BETTERLINKS_UPLOAD_DIR_PATH . '/clicks.json'), true); |
| 74 |
// link id already exists or not in links table |
| 75 |
if (is_array($Clicks)) { |
| 76 |
foreach ($Clicks as $key => $item) { |
| 77 |
$click_id = Helper::insert_click($item); |
| 78 |
if (!empty($click_id) && $item['is_split_enabled']) { |
| 79 |
do_action('betterlinks/link/after_insert_click', $item['link_id'], $click_id, $item['target_url']); |
| 80 |
} |
| 81 |
} |
| 82 |
file_put_contents(BETTERLINKS_UPLOAD_DIR_PATH . '/clicks.json', '{}'); |
| 83 |
} |
| 84 |
} |
| 85 |
|
| 86 |
$is_update = Helper::update_links_analytics(); |
| 87 |
return $is_update; |
| 88 |
} catch (\Throwable $th) { |
| 89 |
return $th->getMessage(); |
| 90 |
} |
| 91 |
return; |
| 92 |
} |
| 93 |
} |
| 94 |
|