Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 50 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
LinkPrefetch | |
0.00% |
0 / 50 |
|
0.00% |
0 / 7 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
42 | |||
get_current_settings | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
42 | |||
add_to_runtime | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
enqueue_scripts | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
add_defer | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
get_settings | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
update_settings | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace NewfoldLabs\WP\Module\Performance\LinkPrefetch; |
4 | |
5 | use NewfoldLabs\WP\Module\Data\SiteCapabilities; |
6 | use NewfoldLabs\WP\ModuleLoader\Container; |
7 | |
8 | /** |
9 | * Handles link prefetch functionality. |
10 | */ |
11 | class LinkPrefetch { |
12 | |
13 | /** |
14 | * Allowed behavior values. |
15 | * |
16 | * @var array |
17 | */ |
18 | public const VALID_BEHAVIORS = array( 'mouseHover', 'mouseDown' ); |
19 | |
20 | /** |
21 | * Allowed mobile behavior values. |
22 | * |
23 | * @var array |
24 | */ |
25 | public const VALID_MOBILE_BEHAVIORS = array( 'touchstart', 'viewport' ); |
26 | |
27 | /** |
28 | * Dependency injection container. |
29 | * |
30 | * @var Container |
31 | */ |
32 | protected $container; |
33 | |
34 | /** |
35 | * Option name for link prefetch settings. |
36 | * |
37 | * @var string |
38 | */ |
39 | public static $option_name = 'nfd_link_prefetch_settings'; |
40 | |
41 | /** |
42 | * Site capabilities for link prefetch Click. |
43 | * |
44 | * @var bool |
45 | */ |
46 | public static $has_link_prefetch_click = false; |
47 | |
48 | /** |
49 | * Site capabilities for link prefetch Hover. |
50 | * |
51 | * @var bool |
52 | */ |
53 | public static $has_link_prefetch_hover = false; |
54 | |
55 | /** |
56 | * Default settings. |
57 | * |
58 | * @var array |
59 | */ |
60 | public static $default_settings = array( |
61 | 'activeOnDesktop' => false, |
62 | 'behavior' => 'mouseHover', |
63 | 'hoverDelay' => 60, |
64 | 'instantClick' => false, |
65 | 'activeOnMobile' => false, |
66 | 'mobileBehavior' => 'touchstart', |
67 | 'ignoreKeywords' => '#,?', |
68 | ); |
69 | |
70 | /** |
71 | * Constructor. |
72 | * |
73 | * @param Container $container The dependency injection container. |
74 | */ |
75 | public function __construct( Container $container ) { |
76 | $this->container = $container; |
77 | |
78 | $capabilities = ( new SiteCapabilities() )->all(); |
79 | |
80 | self::$has_link_prefetch_click = array_key_exists( 'hasLinkPrefetchClick', $capabilities ) ? $capabilities['hasLinkPrefetchClick'] : null; |
81 | self::$has_link_prefetch_hover = array_key_exists( 'hasLinkPrefetchHover', $capabilities ) ? $capabilities['hasLinkPrefetchHover'] : null; |
82 | |
83 | if ( false === self::$has_link_prefetch_click && false === self::$has_link_prefetch_hover ) { |
84 | delete_option( self::$option_name ); |
85 | return; |
86 | } |
87 | |
88 | add_filter( 'newfold-runtime', array( $this, 'add_to_runtime' ) ); |
89 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); |
90 | if ( ! is_admin() ) { |
91 | add_filter( 'script_loader_tag', array( $this, 'add_defer' ), 10, 2 ); |
92 | } |
93 | } |
94 | |
95 | /** |
96 | * Retrieves the current plugin settings from the options table. |
97 | * If no settings are stored, returns and saves the default settings |
98 | * based on feature flags. |
99 | * |
100 | * @return array The current or default settings. |
101 | */ |
102 | public function get_current_settings() { |
103 | $current_settings = get_option( self::$option_name, false ); |
104 | if ( false !== $current_settings ) { |
105 | return $current_settings; |
106 | } |
107 | |
108 | $final_settings = self::$default_settings; |
109 | if ( self::$has_link_prefetch_click || self::$has_link_prefetch_hover ) { |
110 | $final_settings['activeOnDesktop'] = true; |
111 | $final_settings['activeOnMobile'] = true; |
112 | } |
113 | |
114 | if ( self::$has_link_prefetch_click ) { |
115 | $final_settings['behavior'] = 'mouseDown'; |
116 | $final_settings['mobileBehavior'] = 'touchstart'; |
117 | } |
118 | |
119 | if ( self::$has_link_prefetch_hover ) { |
120 | $final_settings['behavior'] = 'mouseHover'; |
121 | $final_settings['mobileBehavior'] = 'viewport'; |
122 | } |
123 | |
124 | update_option( self::$option_name, $final_settings ); |
125 | return $final_settings; |
126 | } |
127 | |
128 | /** |
129 | * Adds values to the runtime object. |
130 | * |
131 | * @param array $sdk The runtime object. |
132 | * |
133 | * @return array Modified runtime object. |
134 | */ |
135 | public function add_to_runtime( $sdk ) { |
136 | $current_settings = $this->get_current_settings(); |
137 | |
138 | return array_merge( |
139 | $sdk, |
140 | array( 'linkPrefetch' => array( 'settings' => $current_settings ) ) |
141 | ); |
142 | } |
143 | |
144 | /** |
145 | * Enqueues the link prefetch script. |
146 | * |
147 | * @return void |
148 | */ |
149 | public function enqueue_scripts() { |
150 | $settings = $this->get_current_settings(); |
151 | $settings['isMobile'] = wp_is_mobile(); |
152 | wp_enqueue_script( |
153 | 'linkprefetcher', |
154 | NFD_PERFORMANCE_BUILD_URL . '/assets/link-prefetch.min.js', |
155 | array(), |
156 | $this->container->plugin()->version, |
157 | true |
158 | ); |
159 | wp_add_inline_script( |
160 | 'linkprefetcher', |
161 | 'window.LP_CONFIG = ' . wp_json_encode( $settings ), |
162 | 'before' |
163 | ); |
164 | } |
165 | |
166 | /** |
167 | * Adds a defer attribute to the script tag. |
168 | * |
169 | * @param string $tag The HTML script tag. |
170 | * @param string $handle The handle of the script. |
171 | * |
172 | * @return string Modified HTML script tag. |
173 | */ |
174 | public function add_defer( $tag, $handle ) { |
175 | if ( 'linkprefetcher' === $handle && false === strpos( $tag, 'defer' ) ) { |
176 | $tag = preg_replace( ':(?=></script>):', ' defer', $tag ); |
177 | } |
178 | return $tag; |
179 | } |
180 | |
181 | /** |
182 | * Retrieves the current link prefetch settings. |
183 | * |
184 | * @return array Current settings. |
185 | */ |
186 | public static function get_settings() { |
187 | return get_option( self::$option_name, self::$default_settings ); |
188 | } |
189 | |
190 | /** |
191 | * Updates the link prefetch settings. |
192 | * |
193 | * @param array $settings The settings to update. |
194 | * |
195 | * @return boolean |
196 | */ |
197 | public static function update_settings( $settings ) { |
198 | return update_option( self::$option_name, $settings ); |
199 | } |
200 | } |