$value) { if (!empty($value) || $value === '0') { $output[] = sprintf('data-al-%s="%s"', esc_attr($key), esc_attr($value)); } } return implode(' ', $output); } /** * Sanitize the optional `path` shortcode attribute to a safe URL path. * Accepts only a-z, 0-9, slash, dash, underscore; trims to 200 chars. */ private function sanitize_path($path) { if (empty($path)) { return ''; } $clean = preg_replace('#[^a-zA-Z0-9/_\-]#', '', (string) $path); return substr($clean, 0, 200); } /** * Render auto-detecting widget (share or claim based on referral code). */ public function render_widget($atts) { $atts = shortcode_atts([ 'type' => 'auto', 'position' => 'inline', 'style' => '', 'path' => '', ], $atts, 'advocate_loop_widget'); $position = !empty($atts['style']) ? $atts['style'] : $atts['position']; $data_attrs = $this->build_data_attributes([ 'widget' => $atts['type'], 'position' => $position, 'path' => $this->sanitize_path($atts['path']), ]); return sprintf('
', $data_attrs); } /** * Render share widget. */ public function render_share_widget($atts) { $atts = shortcode_atts([ 'position' => 'inline', 'style' => '', 'path' => '', ], $atts, 'advocate_loop_share'); $position = !empty($atts['style']) ? $atts['style'] : $atts['position']; $data_attrs = $this->build_data_attributes([ 'widget' => 'share', 'position' => $position, 'path' => $this->sanitize_path($atts['path']), ]); return sprintf('
', $data_attrs); } /** * Render claim widget. */ public function render_claim_widget($atts) { $atts = shortcode_atts([ 'position' => 'inline', 'style' => '', 'path' => '', ], $atts, 'advocate_loop_claim'); $position = !empty($atts['style']) ? $atts['style'] : $atts['position']; $data_attrs = $this->build_data_attributes([ 'widget' => 'claim', 'position' => $position, 'path' => $this->sanitize_path($atts['path']), ]); return sprintf('
', $data_attrs); } /** * Render social share buttons only. */ public function render_share_buttons($atts) { return '
'; } }