PluginProbe
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) / 2.0.1
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) v2.0.1
2.1.3 2.1.2 2.1.1 2.1.0 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 1.5.5 1.5.4 1.5.3 1.5.2 1.5.1 1.5.0 trunk 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 All 57 releases
darkify / src / Includes / Darkify.php

Darkify.php in Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) 2.0.1, at src/Includes/Darkify.php

337 lines 15.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The file of the Darkify class.
5 *
6 * @link https://themeatelier.net
7 * @since 1.0.0
8 *
9 * @package Darkify
10 */
11
12 namespace ThemeAtelier\Darkify\Includes;
13
14 use ThemeAtelier\Darkify\Admin\Admin;
15 use ThemeAtelier\Darkify\Admin\Assets;
16 use ThemeAtelier\Darkify\Admin\Menu;
17 use ThemeAtelier\Darkify\Admin\Rest\HelpRest;
18 use ThemeAtelier\Darkify\Admin\Rest\PreviewRest;
19 use ThemeAtelier\Darkify\Admin\Rest\SettingsRest;
20 use ThemeAtelier\Darkify\Frontend\Frontend;
21
22
23 // don't call the file directly.
24 if (!defined('ABSPATH')) {
25 exit;
26 }
27
28 /**
29 * The main class of the plugin.
30 *
31 * Handle all the class and methods of the plugin.
32 *
33 * @author ThemeAtelier <themeatelierbd@gmail.com>
34 */
35 class Darkify
36 {
37 /**
38 * Plugin version
39 *
40 * @since 1.0.0
41 * @access protected
42 * @var string
43 */
44 protected $version;
45
46 /**
47 * Plugin slug
48 *
49 * @since 1.0.0
50 * @access protected
51 * @var string
52 */
53 protected $plugin_slug;
54
55 /**
56 * Main Loader.
57 *
58 * The loader that's responsible for maintaining and registering all hooks that empowers
59 * the plugin.
60 *
61 * @since 1.0.0
62 * @access protected
63 * @var object
64 */
65 protected $loader;
66 /**
67 * Constructor for the Darkify class.
68 *
69 * Sets up all the appropriate hooks and actions within the plugin.
70 */
71 public function __construct()
72 {
73 $this->version = DARKIFY_VERSION;
74 $this->plugin_slug = 'darkify';
75 $this->load_dependencies();
76 $this->define_constants();
77 $this->define_admin_hooks();
78 $this->define_public_hooks();
79 $this->init_action();
80 add_action('plugin_loaded', array($this, 'init_plugin'));
81
82 add_action('elementor/controls/register', [$this, 'register_controls']);
83 add_action('elementor/widgets/register', array($this, 'register_darkify_widget'));
84
85 add_action('init', [$this, 'create_darkify_block_init']);
86 }
87
88 /**
89 * Run the loader to execute all of the hooks with WordPress.
90 *
91 * @since 1.0.0
92 */
93 public function run()
94 {
95 $this->loader->run();
96 }
97
98 public function darkify_redirect_to($plugin)
99 {
100 if (DARKIFY_BASENAME === $plugin) {
101 $redirect_url = esc_url(admin_url('admin.php?page=darkify'));
102 exit(wp_kses_post(wp_safe_redirect($redirect_url)));
103 }
104 }
105
106 /**
107 * The slug of the plugin used to uniquely identify it within the context of
108 * WordPress and to define internationalization functionality.
109 *
110 * @since 1.0.0
111 * @return string The name of the plugin.
112 */
113 public function get_plugin_name()
114 {
115 return $this->plugin_slug;
116 }
117
118 /**
119 * Retrieve the version number of the plugin.
120 *
121 * @since 1.0.0
122 * @return string The version number of the plugin.
123 */
124 public function get_version()
125 {
126 return $this->version;
127 }
128
129
130 public function register_controls($controls_manager)
131 {
132 require_once DARKIFY_PATH . 'src/Admin/elementor/controls/class-elementor-control-switch.php';
133
134 $controls_manager->register_control(
135 'darkify_switch',
136 new \Elementor_Darkify_Switcher()
137 );
138 }
139 public function register_darkify_widget($widgets_manager)
140 {
141 require_once DARKIFY_PATH . 'src/Admin/elementor/widgets/elementor-widget.php';
142 $widgets_manager->register(new \Elementor_Darkify());
143 }
144
145 /**
146 * Define the constants
147 *
148 * @return void
149 */
150 public function define_constants()
151 {
152 define('DARKIFY_URL', plugins_url('', DARKIFY_FILE));
153 define('DARKIFY_ASSETS', DARKIFY_URL . '/src/assets/');
154 define('DARKIFY_ADMIN', DARKIFY_URL . '/src/Admin');
155 }
156
157 /**
158 * Load the plugin after all plugins are loaded.
159 *
160 * @return void
161 */
162 public function init_plugin()
163 {
164 do_action('darkify_loaded');
165 load_plugin_textdomain('darkify', false, DARKIFY_DIR_NAME . "/languages");
166 }
167
168 /**
169 * Load the required dependencies for this plugin.
170 *
171 * Include the following files that make up the plugin:
172 *
173 * - Loader. Orchestrates the hooks of the plugin.
174 * - Teamproi18n. Defines internationalization functionality.
175 * - Admin. Defines all hooks for the admin area.
176 * - Frontend. Defines all hooks for the public side of the site.
177 *
178 * Create an instance of the loader which will be used to register the hooks
179 * with WordPress.
180 *
181 * @since 1.0.0
182 * @access private
183 */
184 private function load_dependencies()
185 {
186 /**
187 * The class responsible for orchestrating the actions and filters of the
188 * core plugin.
189 */
190 $this->loader = new Loader();
191 }
192
193 /**
194 * Register all of the hooks related to the admin dashboard functionality
195 * of the plugin.
196 *
197 * @since 1.0.0
198 * @access private
199 */
200 private function define_admin_hooks()
201 {
202 $plugin_admin = new Admin($this->get_plugin_name(), $this->get_version());
203 $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_styles');
204 $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts');
205 $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'admin_dequeue_for_specefic_pages', 999);
206
207 // The React admin: its menu page, its bundle, and the REST endpoints it
208 // talks to. The controllers hook themselves onto `rest_api_init`, so they
209 // must be constructed on every request, not only in wp-admin.
210 new Menu();
211 new Assets();
212 new SettingsRest();
213 // Backs the Get Help page's Recommended tab (ThemeAtelier plugin
214 // directory with one-click install/activate).
215 new HelpRest();
216 // Constructed unconditionally (not admin-only): its `init` hook also has
217 // to fire on the frontend iframe request to swap in the preview values.
218 new PreviewRest();
219 }
220
221 /**
222 * Register all of the hooks related to the public-facing functionality
223 * of the plugin.
224 *
225 * @since 1.0.0
226 * @access private
227 */
228 private function define_public_hooks()
229 {
230 $plugin_public = new Frontend($this->get_plugin_name(), $this->get_version());
231 }
232
233 public static function switcher($variant, $unique_id)
234 {
235 if ('classic' == $variant) {
236 return '<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="0px" height="0px" fill="currentColor" stroke-linecap="round" class="theme-toggle__classic" viewBox="0 0 32 32"><clipPath id="theme-toggle__classic__cutout_' . esc_attr($unique_id) . '"><path d="M0-5h30a1 1 0 0 0 9 13v24H0Z" /></clipPath><g clip-path="url(#theme-toggle__classic__cutout_' . esc_attr($unique_id) . ')"><circle cx="16" cy="16" r="9.34" /><g stroke="currentColor" stroke-width="1.5"><path d="M16 5.5v-4" /><path d="M16 30.5v-4" /><path d="M1.5 16h4" /><path d="M26.5 16h4" /><path d="m23.4 8.6 2.8-2.8" /><path d="m5.7 26.3 2.9-2.9" /><path d="m5.8 5.8 2.8 2.8" /><path d="m23.4 23.4 2.9 2.9" /></g></g></svg>';
237 } else if ('expand' == $variant) {
238 return '<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="0px" height="0px" fill="currentColor" class="theme-toggle__expand" viewBox="0 0 32 32"><clipPath id="theme-toggle__expand__cutout_' . esc_attr($unique_id) . '"><path d="M0-11h25a1 1 0 0017 13v30H0Z" /></clipPath><g clip-path="url(#theme-toggle__expand__cutout_' . esc_attr($unique_id) . ')"><circle cx="16" cy="16" r="8.4" /><path d="M18.3 3.2c0 1.3-1 2.3-2.3 2.3s-2.3-1-2.3-2.3S14.7.9 16 .9s2.3 1 2.3 2.3zm-4.6 25.6c0-1.3 1-2.3 2.3-2.3s2.3 1 2.3 2.3-1 2.3-2.3 2.3-2.3-1-2.3-2.3zm15.1-10.5c-1.3 0-2.3-1-2.3-2.3s1-2.3 2.3-2.3 2.3 1 2.3 2.3-1 2.3-2.3 2.3zM3.2 13.7c1.3 0 2.3 1 2.3 2.3s-1 2.3-2.3 2.3S.9 17.3.9 16s1-2.3 2.3-2.3zm5.8-7C9 7.9 7.9 9 6.7 9S4.4 8 4.4 6.7s1-2.3 2.3-2.3S9 5.4 9 6.7zm16.3 21c-1.3 0-2.3-1-2.3-2.3s1-2.3 2.3-2.3 2.3 1 2.3 2.3-1 2.3-2.3 2.3zm2.4-21c0 1.3-1 2.3-2.3 2.3S23 7.9 23 6.7s1-2.3 2.3-2.3 2.4 1 2.4 2.3zM6.7 23C8 23 9 24 9 25.3s-1 2.3-2.3 2.3-2.3-1-2.3-2.3 1-2.3 2.3-2.3z" /></g></svg>';
239 } else if ('inner-moon' === $variant) {
240 return '<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="0px" height="0px" fill="currentColor" class="theme-toggle__inner-moon" viewBox="0 0 32 32"><path d="M27.5 11.5v-7h-7L16 0l-4.5 4.5h-7v7L0 16l4.5 4.5v7h7L16 32l4.5-4.5h7v-7L32 16l-4.5-4.5zM16 25.4a9.39 9.39 0 1 1 0-18.8 9.39 9.39 0 1 1 0 18.8z" /><circle cx="16" cy="16" r="8.1" /></svg>';
241 } else if ('within' === $variant) {
242 return '<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="theme-toggle__within" height="1em" width="1em" viewBox="0 0 32 32" fill="currentColor"><clipPath id="theme-toggle__within__clip_' . esc_attr($unique_id) . '"><path d="M0 0h32v32h-32ZM6 16A1 1 0 0026 16 1 1 0 006 16" /></clipPath><g clip-path="url(#theme-toggle__within__clip_' . esc_attr($unique_id) . ')"><path d="M30.7 21.3 27.1 16l3.7-5.3c.4-.5.1-1.3-.6-1.4l-6.3-1.1-1.1-6.3c-.1-.6-.8-.9-1.4-.6L16 5l-5.4-3.7c-.5-.4-1.3-.1-1.4.6l-1 6.3-6.4 1.1c-.6.1-.9.9-.6 1.3L4.9 16l-3.7 5.3c-.4.5-.1 1.3.6 1.4l6.3 1.1 1.1 6.3c.1.6.8.9 1.4.6l5.3-3.7 5.3 3.7c.5.4 1.3.1 1.4-.6l1.1-6.3 6.3-1.1c.8-.1 1.1-.8.7-1.4zM16 25.1c-5.1 0-9.1-4.1-9.1-9.1 0-5.1 4.1-9.1 9.1-9.1s9.1 4.1 9.1 9.1c0 5.1-4 9.1-9.1 9.1z" /></g><path class="theme-toggle__within__circle" d="M16 7.7c-4.6 0-8.2 3.7-8.2 8.2s3.6 8.4 8.2 8.4 8.2-3.7 8.2-8.2-3.6-8.4-8.2-8.4zm0 14.4c-3.4 0-6.1-2.9-6.1-6.2s2.7-6.1 6.1-6.1c3.4 0 6.1 2.9 6.1 6.2s-2.7 6.1-6.1 6.1z" />
243 <path class="theme-toggle__within__inner" d="M16 9.5c-3.6 0-6.4 2.9-6.4 6.4s2.8 6.5 6.4 6.5 6.4-2.9 6.4-6.4-2.8-6.5-6.4-6.5z" /></svg>';
244 } elseif ('orbit' === $variant) {
245 return '<span class="toggle-track"><span class="toggle-sun"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M277.3 32h-42.7v64h42.7V32zm129.1 43.7L368 114.1l29.9 29.9 38.4-38.4-29.9-29.9zm-300.8 0l-29.9 29.9 38.4 38.4 29.9-29.9-38.4-38.4zM256 128c-70.4 0-128 57.6-128 128s57.6 128 128 128 128-57.6 128-128-57.6-128-128-128zm224 106.7h-64v42.7h64v-42.7zm-384 0H32v42.7h64v-42.7zM397.9 368L368 397.9l38.4 38.4 29.9-29.9-38.4-38.4zm-283.8 0l-38.4 38.4 29.9 29.9 38.4-38.4-29.9-29.9zm163.2 48h-42.7v64h42.7v-64z"></path></svg></span><span class="toggle-thumb"></span><span class="toggle-moon"><svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 384 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z"></path></svg></span></span>';
246 }
247 }
248
249 public static function switcher_wrapper($type, $unique_id, $variant, $switch_size, $position_class = '', $floating_switch_position = '', $tooltip_classes = '', $hide_dark_mode_on_mobile_screen = '', $floating_switch_width = '', $tooltip_on_floating_switch = '')
250 {
251
252 // A single `style` attribute: this used to be emitted TWICE (once with
253 // just the scale variable, then — for `shortcode` — a second `style="..."`
254 // appended after `class`). HTML only honors the FIRST of two duplicate
255 // attributes, so that second one (the only place `position: relative` was
256 // set) was silently dropped by every browser. Without it, an absolutely-
257 // positioned inner element (e.g. a pill variant's sliding thumb) has no
258 // guarantee of being positioned relative to THIS wrapper — it falls back
259 // to whatever positioned ancestor happens to exist (or none), which is
260 // exactly the kind of thing a page's content wrapper (often already
261 // `position: relative`) can accidentally paper over while a theme's nav
262 // `<li>` — the Menu Switch's actual context — usually doesn't.
263 $style = '--darkify-switch-scale: ' . esc_attr($switch_size) . ';' . ($type === 'shortcode' ? ' position: relative;' : '');
264 $classes = 'darkify_switch darkify_switch_style switch-' . esc_attr($variant)
265 . ($type !== 'shortcode' ? ' ' . esc_attr($position_class) . ' ' . esc_attr($floating_switch_position) . ' ' . esc_attr($tooltip_classes) . ' ' . esc_attr($hide_dark_mode_on_mobile_screen) : '');
266 return '<div style="' . $style . '" id="darkify_switch_' . esc_attr($unique_id) . '" onclick="darkify_switch_trigger()" class="' . $classes . '"><div class="theme-toggle">' . self::switcher($variant, $unique_id) . '</div>' . ($type !== 'shortcode' && $floating_switch_width ? '<span class="darkify_tooltiptext">' . esc_attr($tooltip_on_floating_switch) . '</span>' : '') . '</div>';
267 }
268
269 private function init_action()
270 {
271 add_action('activated_plugin', [$this, 'darkify_redirect_to']);
272 }
273
274
275 public function create_darkify_block_init()
276 {
277 register_block_type_from_metadata(
278 DARKIFY_PATH . 'src/Admin/blocks/',
279 array(
280 'render_callback' => [$this, 'render_darkify_block_callback'],
281 )
282 );
283
284 wp_localize_script(
285 'darkify-switcher-editor-script',
286 'darkify',
287 array(
288 'dir_url' => DARKIFY_DIR_URL,
289 )
290 );
291 }
292
293 /**
294 * Render callback for the Darkify Pro block.
295 */
296 public function render_darkify_block_callback($attributes)
297 {
298 $style = $attributes['style'] ?? 'classic';
299 $size = $attributes['size'] ?? '1.0';
300 $custom_size = $attributes['custom_size'] ?? 100;
301 $bg_light = $attributes['switch_bg_light'] ?? '#121116';
302 $bg_dark = $attributes['switch_bg_dark'] ?? '#ffffff';
303 $light_icon_color = $attributes['light_icon_color'] ?? '#ffffff';
304 $dark_icon_color = $attributes['dark_icon_color'] ?? '#121116';
305 $light_text_color = $attributes['light_text_color'] ?? '#121116';
306 $dark_text_color = $attributes['dark_text_color'] ?? '#ffffff';
307 $border_width = $attributes['border_width'] ?? 0;
308 $border_light_color = $attributes['border_light_color'] ?? '#121116';
309 $border_dark_color = $attributes['border_dark_color'] ?? '#ffffff';
310 $border_radius = $attributes['border_radius'] ?? 7;
311 $alignment = $attributes['alignment'] ?? 'left';
312
313 // Size logic
314 if ('custom' === $size) {
315 $switcher_size = $custom_size;
316 } else {
317 $switcher_size = (float) $size * 100;
318 }
319
320 return '<div style="display: flex; justify-content: ' . esc_attr($alignment) . '">' . do_shortcode(wp_sprintf(
321 '[darkify switch="%s" icon_size="40px" light_mode_bg="%s" dark_mode_bg="%s" light_mode_color="%s" dark_mode_color="%s" border="%spx" border_light_color="%s" border_dark_color="%s" border_radius="%spx" text_light_mode_color="%s" text_dark_mode_color="%s" switch_size="%s"]',
322 $style,
323 $bg_light,
324 $bg_dark,
325 $light_icon_color,
326 $dark_icon_color,
327 $border_width,
328 $border_light_color,
329 $border_dark_color,
330 $border_radius,
331 $light_text_color,
332 $dark_text_color,
333 $switcher_size
334 )) . '</div>';
335 }
336 }
337