$value) { $attributes .= sprintf(' %s="%s"', esc_attr(sanitize_key($name)), esc_attr($value)); } if (!str_contains($tag, ' defer')) { $attributes .= ' defer'; } return str_replace(' src=', $attributes . ' src=', $tag); } public function enqueue(): void { if (!$this->shouldLoad()) { return; } $deps = []; if (self::assetsAreServed()) { $script = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? 'html2canvas.js' : 'html2canvas.min.js'; wp_register_script( self::SCREENSHOT_HANDLE, plugins_url('assets/vendor/html2canvas/' . $script, SARCIO_WP_FILE), [], self::SCREENSHOT_VERSION, false, ); $deps[] = self::SCREENSHOT_HANDLE; } wp_enqueue_script(self::HANDLE, Options::widgetSrc(), $deps, null, false); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- cache-busted by the control plane } /** * Whether the plugin's own files are reachable over the web: true for a * normal install under wp-content/plugins or mu-plugins. A Composer install * elsewhere (a vendor directory outside the web root) has no URL for its * assets, so the bundled screenshot library is skipped and the widget loads * its own copy instead. */ public static function assetsAreServed(?string $pluginFile = null): bool { $dir = wp_normalize_path(dirname($pluginFile ?? SARCIO_WP_FILE)); foreach (['WP_PLUGIN_DIR', 'WPMU_PLUGIN_DIR'] as $constant) { if (defined($constant) && str_starts_with($dir . '/', trailingslashit(wp_normalize_path((string) constant($constant))))) { return true; } } return false; } public function enqueueAdmin(): void { if (!Options::get('widget_in_admin')) { return; } $this->enqueue(); } /** * Whether this pageview gets the reporter. Filterable with * `sarcio_load_widget` for anything the three built-in audiences don't * express (a staging host, a query flag, a specific post type). */ public function shouldLoad(): bool { $configured = Options::get('widget_enabled') && (string) Options::get('site_key') !== '' && Options::widgetSrc() !== ''; $allowed = $configured && match ((string) Options::get('widget_audience')) { 'everyone' => true, 'logged_in' => is_user_logged_in(), default => current_user_can((string) Options::get('widget_capability')), }; return (bool) apply_filters('sarcio_load_widget', $allowed); } }