"Currently Playing", "template" => "games", "profile_url" => "", "cache_interval" => 900 ); //constructor //$register_hooks: pass false when instantiating just to reach a render helper (e.g. from the shortcode), so we don't stack duplicate action registrations function __construct($register_hooks = true) { parent::__construct(false, $name = 'Steam Widget', array( 'classname' => 'advanced-steam-widget', 'description' => "Displays Steam profile status and history") ); if (!$register_hooks) return; //settings for cron must be delayed until the widget is registered add_action('wp_loaded', array($this, 'setup_cron')); //hook for cleanup on widget deletion add_action('sidebar_admin_setup', array($this, 'delete_widget')); } //overrides parent function //displays the widget on the frontend function widget($args, $instance) { //make sure cron is scheduled - covers first-render, transient-evicted, and plugin-upgrading cases //cast to int: WP sometimes hands $this->number in as a string, and cron event keys are md5(serialize($args)) so int vs string mismatches orphan the event if (!wp_next_scheduled('advanced_steam_widget_update', array((int)$this->number))) { wp_schedule_event(time(), 'advanced_steam_widget_interval_' . (int)$this->number, 'advanced_steam_widget_update', array((int)$this->number)); } //pull cache from transient. render nothing if unavailable so the widget doesn't appear broken $cache = AdvancedSteamWidget_get_cache($this->number); if ($cache === null) return; print ""; //print widget wrapper and title $title = apply_filters('widget_title', empty($instance['title']) ? '' : $instance['title'], $instance, $this->id_base); print $args['before_widget'] ?? ''; if (!empty($title)) print ($args['before_title'] ?? '') . $title . ($args['after_title'] ?? ''); //render the selected template with steam data in scope $slug = !empty($instance['template']) ? $instance['template'] : $this->default_settings['template']; AdvancedSteamWidget_render_template($slug, $cache['data'], $args); print $args['after_widget'] ?? ''; } //overrides parent function //shows the widget settings fields in the widget option page (or inside the Legacy Widget block wrapper) function form($instance) { $instance = wp_parse_args((array) $instance, $this->default_settings); $title = esc_attr($instance['title']); $profile_url = esc_attr($instance['profile_url']); $cache_interval = $instance['cache_interval']; $template = $instance['template']; //status notices wrapped in a container so the refresh-button JS can replace them in place $cache = AdvancedSteamWidget_get_cache($this->number); $status_ok = isset($instance['last_update_status']) && $instance['last_update_status'] === true; ?>

Last Updated: ago

number))) !== false) { ?>

Next Update:

number)) { ?>

Shortcode: [steam id="number; ?>"]

get_int_option($new_instance['cache_interval'] ?? null, $this->default_settings['cache_interval'], 1, 86400); if (isset($new_instance['profile_url'])) { //normalize any accepted input format to a canonical scheme-less URL; unparseable input becomes '' $instance['profile_url'] = AdvancedSteamWidget_normalize_profile_input($new_instance['profile_url']); } if (isset($new_instance['template'])) { //validate template slug against discovered set; fall back to default if unknown $available = AdvancedSteamWidget_get_templates(); $instance['template'] = isset($available[$new_instance['template']]) ? $new_instance['template'] : $this->default_settings['template']; } //hook for things that need to be done after the instance is updated add_filter('widget_form_callback', array($this, 'post_update')); return $instance; } //makes sure the requested value is valid and numeric //and clamped between an optional minimum and maximum value //if not, returns default, min, or max value private function get_int_option($request_opt, $default_opt = 1, $min_val = NULL, $max_val = NULL) { if (!is_numeric($request_opt)) return $default_opt; if ((!is_null($min_val)) && ($request_opt < $min_val)) return $min_val; if ((!is_null($max_val)) && ($request_opt > $max_val)) return $max_val; return $request_opt; } //updates steam data given a specific widget id //used for cron target function update_and_save_data($id) { //get the selected instances of this widget $all_instances = $this->get_settings(); if (!isset($all_instances[$id])) return; //refresh writes the transient and updates status on the instance $all_instances[$id] = $this->refresh_data($all_instances[$id], $id); //save all instances of this widget $this->save_settings($all_instances); } //fetches fresh steam data via the shared refresh helper and records status on the instance private function refresh_data($instance, $id) { $result = AdvancedSteamWidget_refresh_instance($id, $instance['profile_url'] ?? ''); $instance['last_update_status'] = $result; return $instance; } //called on deletion of a widget from the widget options page function delete_widget() { //gate on capability required to edit widgets; deletion is a state change so we don't touch anything for unprivileged requests if (!current_user_can('edit_theme_options')) return; if (empty($_POST['delete_widget']) || !isset($_POST['widget_number'])) return; //widget_number is a numeric instance id; coerce to non-negative int to be safe $id = absint($_POST['widget_number']); if (!$id) return; //remove all crons for this instance wp_clear_scheduled_hook('advanced_steam_widget_update', array($id)); //drop the transient cache for this instance AdvancedSteamWidget_delete_cache($id); } //called after update has been saved function post_update($instance) { //always reset the cron, because we just updated and the interval should start from now wp_clear_scheduled_hook('advanced_steam_widget_update', array((int)$this->number)); wp_reschedule_event(time(), 'advanced_steam_widget_interval_' . (int)$this->number, 'advanced_steam_widget_update', array((int)$this->number)); return $instance; } //callback for changing the wp cron for the feed update function cron_add_interval($schedules) { //must be done for each instance so they're always available whenever called foreach ($this->get_settings() as $id => $instance) { $interval = $this->get_int_option($instance['cache_interval'], $this->default_settings['cache_interval'], 1, 86400); $schedules['advanced_steam_widget_interval_' . $id] = array( 'interval' => $interval, 'display' => 'Advanced Steam Widget ' . $id ); } return $schedules; } //fired once for all widgets function setup_cron() { //hook for the custom cron interval add_filter('cron_schedules', array($this, 'cron_add_interval')); //action for cron add_action('advanced_steam_widget_update', array($this, 'update_and_save_data')); } } //adds our widget to available ones function AdvancedSteamWidget_register() { register_widget('AdvancedSteamWidget'); } add_action('widgets_init', 'AdvancedSteamWidget_register');