PluginProbe
Themify Builder / trunk
Themify Builder vtrunk
7.8.1 7.8.0 7.7.9 7.7.8 7.7.7 7.7.6 7.7.5 7.7.4 7.7.3 7.7.2 trunk 7.6.0 7.6.1 7.6.2 7.6.3 7.6.4 7.6.5 7.6.6 7.6.7 7.6.8 7.6.9 7.7.0 7.7.1
themify-builder / themify / themify-admin.php

themify-admin.php in Themify Builder trunk, at themify/themify-admin.php

3,554 lines 179.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Themify admin page
4 *
5 * @package Themify
6 */
7
8 defined( 'ABSPATH' ) || exit;
9
10 /**
11 * Enqueue JS and CSS for Themify settings page and meta boxes
12 * @param String $page
13 * @since 1.1.1
14 *******************************************************/
15 function themify_enqueue_scripts($page){
16 $pagenow = isset( $_GET['page'] ) ? $_GET['page'] : '';
17
18 // Don't do anything while updating the theme
19 if ( 'themify' === $pagenow && isset( $_GET['action'] ) && 'upgrade' === $_GET['action'] ) {
20 return;
21 }
22
23 global $typenow;
24 $types = themify_post_types();
25 $pages = apply_filters( 'themify_top_pages', array( 'post.php', 'post-new.php', 'toplevel_page_themify', 'nav-menus.php' ) );
26 $pagenows = apply_filters( 'themify_pagenow', array( 'themify' ) );
27
28 wp_register_style( 'tf_base', THEMIFY_URI . '/css/base.min.css', null, THEMIFY_VERSION);
29 wp_register_style( 'themify-ui', THEMIFY_URI . '/css/themify-ui.css', array('tf_base'), THEMIFY_VERSION );
30 wp_register_style( 'themify-ui-rtl', THEMIFY_URI . '/css/themify-ui-rtl.css', array('themify-ui'), THEMIFY_VERSION );
31 wp_register_style( 'themify-colorpicker', THEMIFY_METABOX_URI . 'css/jquery.minicolors.css', null, THEMIFY_VERSION );
32 wp_register_script( 'markjs', THEMIFY_URI . '/js/admin/jquery-mark.min.js', array('jquery'), THEMIFY_VERSION,true );
33 wp_register_script( 'themify-colorpicker', THEMIFY_METABOX_URI . 'js/jquery.minicolors.js', array('jquery'), THEMIFY_VERSION,true );
34 wp_localize_script( 'themify-colorpicker', 'themifyCM', Themify_Metabox::themify_localize_cm_data() );
35 wp_register_script( 'themify-scripts', THEMIFY_URI . '/js/admin/scripts.js', array('jquery', 'jquery-ui-tabs'), THEMIFY_VERSION,true );
36 wp_register_script( 'themify-plupload', THEMIFY_METABOX_URI . 'js/plupload.js', array('jquery', 'themify-scripts'), THEMIFY_VERSION,true);
37 wp_register_style ( 'magnific', THEMIFY_URI . '/css/modules/lightbox.css', array(), THEMIFY_VERSION );
38 wp_register_script( 'magnific', THEMIFY_URI . '/js/modules/lightbox.min.js', array('jquery'), THEMIFY_VERSION, true );
39
40 // Custom Write Panel
41 if( ($page === 'post.php' || $page === 'post-new.php') && in_array($typenow, $types,true) ){
42 wp_enqueue_script( 'meta-box-tabs' );
43 wp_enqueue_script( 'media-library-browse' );
44 }
45
46 // Register icon assets for later enqueueing.
47 wp_register_style( 'themify-icons', THEMIFY_URI . '/themify-icons/themify-icons.css', array(), THEMIFY_VERSION );
48
49 $admin_vars=array(
50 'nonce' => wp_create_nonce('tf_nonce'),
51 'admin_url' => admin_url( 'admin.php?page=themify' ),
52 'page_not_found' => esc_html__( 'Page not found', 'themify' )
53 );
54 // Settings Panel
55 if( $page === 'toplevel_page_themify' ){
56
57
58 wp_enqueue_script( 'jquery-ui-sortable' );
59 // Load main.js for using fontawsome function
60 themify_enque_script( 'themify-main-script', THEMIFY_URI.'/js/main.js', THEMIFY_VERSION, array('jquery'));
61 Themify_Enqueue_Assets::addLocalization('url', THEMIFY_URI, false);
62
63 $admin_vars['empty_li']=__('The fileds could not be empty!','themify');
64 $admin_vars['theme']=get_template();
65 $admin_vars['erase']=array(
66 'processing'=>__('Erasing... ','themify'),
67 'done'=>__('Erasing complete','themify'),
68 'error'=>__('An error occurred: %error%','themify')
69 );
70 $admin_vars['license']=array(
71 'title'=>__('Themify License','themify'),
72 'labels'=>array(
73 'name'=>__('Themify Username','themify'),
74 'key'=>__('License Key','themify'),
75 'update'=>__('Update','themify'),
76 ),
77 'link'=> sprintf('%s<a href="https://themify.me/member/softsale/license" target="_blank" rel="noopener">%s</a>%s',__('Please enter your Themify username and ','themify'),__('license key','themify'),__('. Make sure your membership/license key is active (not expired).','themify'))
78 );
79 $admin_vars['import']=array(
80 'posts' => __('Importing Posts (%from%/%to%): %post%', 'themify'),
81 'terms' => __('Importing Taxonomies (%from%/%to%): %post%', 'themify'),
82 'menu_items' => __('Importing menu items (%from%/%to%): %post%', 'themify'),
83 'menu' => __('Importing menus', 'themify'),
84 'theme' => __('Importing theme Settings', 'themify'),
85 'done'=>__('Import successfully finished', 'themify'),
86 'import_gs_data' => __('Importing Global Styling', 'themify'),
87 'download_images'=> __( 'Downloading images (%from%/%to%):', 'themify' ),
88 'upload_images'=> __( 'Uploading images (%from%/%to%):', 'themify' ),
89 'import_skip' => __('Failed import. Skip importing %post%', 'tbp'),
90 'import_failed' => __('Failed import: %post%', 'themify'),
91 'download_fail' => __('download failed.', 'themify'),
92 'upload_fail' => __('upload failed (%msg%)', 'themify'),
93 'memory'=>(int)(wp_convert_hr_to_bytes(WP_MEMORY_LIMIT)*MB_IN_BYTES)
94 );
95
96 if ( ! class_exists( 'Themify_Updater_utils', false ) ) {
97 $tf_tu_utils = WP_PLUGIN_DIR . '/themify-updater/includes/class.utils.php';
98 if ( is_readable( $tf_tu_utils ) ) {
99 require_once $tf_tu_utils;
100 }
101 }
102 $license_username = '';
103 $license_key = '';
104 $license_hide_name = false;
105 $license_hide_key = false;
106 if ( class_exists( 'Themify_Updater', false ) ) {
107 $themify_updater = Themify_Updater::get_instance();
108 $license_username = (string) $themify_updater->get_setting( 'username' );
109 $license_key = (string) $themify_updater->get_setting( 'key' );
110 $license_hide_name = (bool) $themify_updater->get_setting( 'hideName' );
111 $license_hide_key = (bool) $themify_updater->get_setting( 'hideKey' );
112 unset( $themify_updater );
113 } else {
114 $license_opt = get_option( 'themify_updater_licence', '' );
115 if ( is_string( $license_opt ) && $license_opt !== '' ) {
116 $license_dec = json_decode( $license_opt, true );
117 if ( is_array( $license_dec ) ) {
118 $license_username = isset( $license_dec['username'] ) ? preg_replace( '/[^0-9A-Za-z_-]/', '', (string) $license_dec['username'] ) : '';
119 $license_key = isset( $license_dec['key'] ) ? preg_replace( '/[^0-9A-Za-z]/', '', (string) $license_dec['key'] ) : '';
120 $license_hide_name = ! empty( $license_dec['hideName'] );
121 $license_hide_key = ! empty( $license_dec['hideKey'] );
122 }
123 }
124 }
125 if ( class_exists( 'Themify_Updater_utils', false ) ) {
126 if ( $license_hide_name && $license_username !== '' ) {
127 $license_username = Themify_Updater_utils::preg_replace( $license_username, 'username', '*' );
128 }
129 if ( $license_hide_key && $license_key !== '' ) {
130 $license_key = Themify_Updater_utils::preg_replace( $license_key, 'key', '*' );
131 }
132 }
133 $admin_vars['license']['username'] = $license_username;
134 $admin_vars['license']['key'] = $license_key;
135
136 //used icons
137 themify_get_icon('info','ti');
138 themify_get_icon('alert','ti');
139 themify_get_icon('check','ti');
140 themify_get_icon('cog','fa');
141 }
142 if( in_array( $page, $pages,true ) ) {
143 //Enqueue styles
144 wp_enqueue_style( 'themify-ui' );
145 wp_enqueue_style( 'themify-metabox' );
146 if ( is_rtl() ) {
147 wp_enqueue_style( 'themify-ui-rtl' );
148 }
149 wp_enqueue_style( 'themify-colorpicker' );
150
151 //Enqueue scripts
152 wp_enqueue_script( 'jquery' );
153 wp_enqueue_script( 'jquery-ui-core' );
154 wp_enqueue_script( 'jquery-ui-tabs' );
155 wp_enqueue_script( 'jquery-ui-slider' );
156 if( 'themify' === $pagenow){
157 wp_enqueue_script( 'jquery-ui-autocomplete' );
158 }
159 wp_enqueue_script( 'json2' );
160 wp_enqueue_script( 'plupload-all' );
161 wp_enqueue_script( 'markjs' );
162 wp_enqueue_script( 'themify-colorpicker' );
163 if( in_array($typenow, $types,true) || in_array( $pagenow, $pagenows,true ) ){
164 //Don't include Themify JavaScript if we're not in one of the Themify-managed pages
165 wp_enqueue_script( 'themify-scripts' );
166 wp_enqueue_script( 'themify-plupload' );
167 Themify_Metabox::get_instance()->enqueue();
168 }
169 // Enqueue font icon assets.
170
171 wp_enqueue_style( 'themify-icons' );
172 Themify_Icon_Font::enqueue();
173 wp_enqueue_style ( 'magnific' );
174 wp_enqueue_script( 'magnific' );
175 }
176
177
178 wp_localize_script('themify-scripts', 'themify_js_vars', $admin_vars);
179
180 wp_localize_script('themify-scripts', 'themify_lang', array(
181 'confirm_reset_settings' => __('Are you sure you want to reset your theme settings?', 'themify'),
182 'check_backup' => __('Make sure to backup before upgrading. Files and settings may get lost or changed.', 'themify'),
183 'confirm_delete_image' => __('Do you want to delete this image permanently?', 'themify'),
184 'confirm_demo' => __( 'This will import demo and override current Themify panel settings.', 'themify' ),
185 )
186 );
187
188 wp_localize_script('themify-plupload', 'themify_plupload_lang', array(
189 'enable_zip_upload' => sprintf(
190 __('Install the "File Upload Types" plugin and add the file extension upload support.', 'themify'),
191 esc_url( network_admin_url('settings.php').'#upload_filetypes' )
192 ),
193 'filesize_error' => __('The file you are trying to upload exceeds the maximum file size allowed.', 'themify'),
194 'filesize_error_fix' => sprintf(
195 __('Go to your <a href="%s">Network Settings</a> and increase the value of the <strong>Max upload file size</strong>.', 'themify'),
196 esc_url( network_admin_url('settings.php').'#fileupload_maxk' )
197 )
198 )
199 );
200
201 // Enqueu admin widgets stuff
202 if( $page === 'index.php' && themify_is_themify_theme()) {
203 wp_enqueue_style( 'themify-admin-widgets-css' );
204 wp_enqueue_script( 'themify-admin-widgets-js' );
205 }
206 }
207
208 /**
209 * Checks if current user is allowed to view the update interface.
210 *
211 * @since 2.0.0
212 *
213 * @return bool
214 */
215 function themify_allow_update() {
216 return current_user_can( 'update_themes' );
217 }
218
219 ///////////////////////////////////////////
220 // Create Nav Options
221 ///////////////////////////////////////////
222 function themify_admin_nav() {
223 global $submenu;
224 $theme = wp_get_theme();
225 $name = $theme->display('Name');
226 $can_manage_option = current_user_can( 'manage_options' );
227 /**
228 * Add Themify menu entry
229 * @since 2.0.2
230 */
231
232 $themify_page = add_menu_page( 'themify',$name , 'edit_posts', 'themify', $can_manage_option?'themify_page':'', THEMIFY_URI . '/img/favicon.svg', '49.3' );
233
234 /**
235 * Add Themify settings page
236 * @since 2.0.2
237 */
238 if($can_manage_option){
239 add_submenu_page( 'themify', $name, __('Themify Settings', 'themify'), 'manage_options', 'themify', 'themify_page' );
240 }
241 if ( class_exists('Themify_Builder_Model',false) && Themify_Builder_Model::builder_check() ) {
242 /**
243 * Add Themify Builder Layouts page
244 * @since 2.0.2
245 */
246 add_submenu_page ( 'themify', __( 'Saved Layouts', 'themify' ), __( 'Saved Layouts', 'themify' ), 'edit_posts', 'edit.php?post_type=tbuilder_layout' );
247 /**
248 * Add Themify Builder Layout Parts page
249 * @since 2.0.2
250 */
251 add_submenu_page( 'themify', __( 'Layout Parts', 'themify' ), __( 'Layout Parts', 'themify' ), 'edit_posts', 'edit.php?post_type=tbuilder_layout_part' );
252 /**
253 * Add Themify Global Styles page
254 * @since 4.5.0
255 */
256 add_submenu_page ( 'themify', __( 'Global Styles', 'themify' ), __( 'Global Styles', 'themify' ), 'edit_posts', 'themify-global-styles', 'themify_global_styles_page' );
257 }
258 /**
259 * Add Themify Custom Fonts page
260 * @since 4.6.3
261 */
262 add_submenu_page( 'themify', __( 'Custom Fonts', 'themify' ), __( 'Custom Fonts', 'themify' ), 'edit_posts', 'edit.php?post_type=tb_cf' );
263 /**
264 * Add Themify Customize submenu entry
265 * @since 2.0.2
266 */
267 add_submenu_page( 'themify', 'themify_customize', __( 'Customize', 'themify' ), 'manage_options', 'customize.php?themify=1' );
268 if ( is_plugin_active( 'themify-updater/themify-updater.php' ) ) {
269 /**
270 * Add Themify Updater License page link
271 * @since 4.2.2
272 */
273 add_submenu_page ( 'themify', __( 'Themify License', 'themify' ), __( 'Themify License', 'themify' ), 'manage_options', 'index.php?page=themify-license' );
274 }
275 if ( $can_manage_option ) {
276 $submenu['themify'][] = array( __( 'Documentation', 'themify' ), 'manage_options', 'https://themify.me/docs/' . str_replace( 'themify-', '', $theme->get_template() ) );
277 $submenu['themify'][] = array( __( 'Contact Support', 'themify' ), 'manage_options', 'https://themify.me/new-topic/' );
278 } else {
279 remove_submenu_page('themify','themify');
280 }
281 }
282
283 function themify_get_theme_required_plugins() {
284 $info = get_file_data( trailingslashit( get_template_directory() ) . 'style.css', array( 'Required Plugins' ) );
285 return isset( $info[0] )?$info[0]:'';
286 }
287
288 /* Pages
289 /***************************************************************************/
290
291 function themify_sort_config($themify_config) {
292 $themify_config['panel']['settings']['tab']['theme_settings']['custom-module'][] = array(
293 'title' => __('Accessibility', 'themify'),
294 'function' => 'accessibility_options'
295 );
296 $defaultModules=array(
297 'general'=>array(
298 array(
299 'title' => __('Favicon', 'themify'),
300 'function' => 'favicon',
301 'target' => 'uploads/favicon/'
302 ),
303 array(
304 'title' => __('Header Code', 'themify'),
305 'function' => 'header_html'
306 ),
307 array(
308 'title' => __('Footer Code', 'themify'),
309 'function' => 'footer_html'
310 ),
311 array(
312 'title' => __('Google Analytics', 'themify'),
313 'function' => 'themify_google_analytics_settings'
314 ),
315 array(
316 'title' => __('Search Settings', 'themify'),
317 'function' => 'search_settings'
318 ),
319 array(
320 'title' => __('Error 404 Page', 'themify'),
321 'function' => 'page_404_settings'
322 ),
323 array(
324 'title' => __('Google Fonts', 'themify'),
325 'function' => 'themify_webfonts_subsets'
326 ),
327 array(
328 'title' => __('Schema Microdata', 'themify'),
329 'function' => 'themify_framework_theme_microdata_config_callback'
330 ),
331 array(
332 'title' => __('Maintenance Mode', 'themify'),
333 'function' => 'themify_maintenance_mode_settings'
334 ),
335 array(
336 'title' => __('Feed Settings', 'themify'),
337 'function' => 'feed_settings'
338 ),
339 array(
340 'title' => __('Custom Feed URL', 'themify'),
341 'function' => 'custom_feed_url'
342 ),
343 ),
344 'performance'=>array(
345 array(
346 'title' => '',
347 'function' => 'performance_settings'
348 )
349 ),
350 'social_links'=>array(
351 array(
352 'title' => __('Manage Social Links', 'themify'),
353 'function' => 'themify_manage_links'
354 )
355 ),
356 'image_script'=> array(
357 array(
358 'title' => __('Image Script Settings', 'themify'),
359 'function' => 'img_settings'
360 )
361 ),
362 'integration-api'=>array(
363 array(
364 'title' => __('Google Map API Settings', 'themify'),
365 'function' => 'themify_google_map_key'
366 ),
367 array(
368 'title' => __('Bing Map API Settings', 'themify'),
369 'function' => 'themify_bing_map_key'
370 ),
371 array(
372 'title' => __('Azure Map API Settings', 'themify'),
373 'function' => 'themify_azure_map_key'
374 ),
375 array(
376 'title' => __('Cloudflare API Settings', 'themify'),
377 'function' => 'themify_cloudflare_setting'
378 ),
379 array(
380 'title' => __('reCaptcha API Settings', 'themify'),
381 'function' => 'themify_recaptcha_setting'
382 ),
383 array(
384 'title' => __( 'hCaptcha API Settings', 'themify' ),
385 'function' => 'themify_hcaptcha_setting'
386 ),
387 array(
388 'title' => __('Cloudflare Turnstile API Settings', 'themify'),
389 'function' => 'themify_turnstile_setting'
390 ),
391 // array(
392 //'title' => __('Youtube/Vimeo GDPR', 'themify'),
393 //'function' => 'themify_video_gdpr'
394 // ),
395 ),
396 'custom-icon-font'=>array(
397 array(
398 'title' => __('Custom Icon Font', 'themify'),
399 'function' => 'themify_fontello_input_callback',
400 ),
401 )
402 );
403 foreach($defaultModules as $k=>$def){
404 if(isset($themify_config['panel']['settings']['tab'][$k]['custom-module'])){
405 $defaultModules[$k]=array_merge($def,$themify_config['panel']['settings']['tab'][$k]['custom-module']);
406 }
407 }
408 $themify_config['panel']['settings']['tab']['general'] = array(
409 'title' => __('General', 'themify'),
410 'id' => 'general',
411 'custom-module' =>$defaultModules['general']
412 );
413
414
415 $themify_config['panel']['settings']['tab']['performance'] = array(
416 'title' => __('Performance', 'themify'),
417 'id' => 'performance',
418 'custom-module' => $defaultModules['performance']
419 );
420 $themify_config['panel']['settings']['tab']['social_links'] = array(
421 'title' => __('Social Links', 'themify'),
422 'id' => 'social_links',
423 'custom-module' => $defaultModules['social_links']
424 );
425 $themify_config['panel']['settings']['tab']['image_script'] = array(
426 'title' => __('Image Script', 'themify'),
427 'id' => 'image_script',
428 'custom-module' =>$defaultModules['image_script']
429 );
430 $themify_config['panel']['settings']['tab']['integration-api'] = array(
431 'title' => __('Integration API', 'themify'),
432 'id' => 'integration-api',
433 'custom-module' => $defaultModules['integration-api']
434 );
435
436
437 $themify_config['panel']['settings']['tab']['custom-icon-font'] = array(
438 'title' => __('Custom Icon Font', 'themify'),
439 'id' => 'custom-icon-font',
440 'custom-module' => $defaultModules['custom-icon-font']
441 );
442 unset($defaultModules);
443 $ordered=array();
444 $sort=array('general','default_layouts','performance','theme_settings','shop_settings','portfolio_layouts','page_builder','social_links','hook-content','image_script','integration-api','role_access','custom-icon-font');
445 foreach($sort as $v){
446 if(isset($themify_config['panel']['settings']['tab'][$v])){
447 $ordered['panel']['settings']['tab'][$v]=$themify_config['panel']['settings']['tab'][$v];
448 unset($themify_config['panel']['settings']['tab'][$v]);
449 }
450 }
451 if(!empty($themify_config['panel']['settings']['tab'])){
452 foreach($themify_config['panel']['settings']['tab'] as $k=>$v){
453 $ordered['panel']['settings']['tab'][$k]=$v;
454 }
455 }
456 return apply_filters('themify_theme_config_sort',$ordered);
457 }
458
459 ///////////////////////////////////////////
460 // Themify Page
461 ///////////////////////////////////////////
462 function themify_page() {
463
464 if ( ! current_user_can( 'manage_options' ) )
465 wp_die( __( 'You do not have sufficient permissions to update this site.', 'themify' ) );
466
467 if (isset($_GET['action'])) {
468 $action = 'upgrade';
469 themify_updater();
470 }
471
472
473 /**
474 * Load themify_config
475 */
476 $themify_theme_config=array();
477 include locate_template(array('custom-config.php', 'theme-config.php'));
478 $themify_config = apply_filters('themify_theme_config_setup', $themify_theme_config);
479 unset($themify_theme_config);
480 $themify_config=themify_sort_config($themify_config);
481
482 // check theme information
483 $theme = wp_get_theme();
484 $is_child = is_child_theme();
485 $check_theme_name = $is_child? $theme->parent()->Name : $theme->display('Name');
486 $check_theme_version = $is_child ? $theme->parent()->Version : $theme->display('Version');
487
488 /**
489 * Markup for Themify skins. It's empty if there are no skins
490 * @since 2.1.8
491 * @var string
492 */
493 $themify_skins = themify_get_skins();
494
495 /* special admin tab that shows available skins with option to import demo separately for each */
496 $skins_and_demos = current_theme_supports( 'themify-skins-and-demos' );
497 ?>
498 <!-- alerts -->
499 <div class="tb_alert"></div>
500 <!-- /alerts -->
501
502 <div id="tf_message" data-dismiss="<?php _e( 'Dismiss', 'themify' ); ?>"></div>
503
504 <!-- gzip issue detection -->
505 <script>document.body.classList.add( 'tf_litespeed' );</script>
506 <style>
507 .tf_litespeed #wpbody-content > * { display: none; }
508 .tf_litespeed #tf_gz_message { margin: 2em; display: block !important; }
509 </style>
510 <div id="tf_gz_message" style="display: none"><?php printf( __( 'It appears your server doesn\'t load .gz file correctly. Please contact your host provide to fix the issue. As a temporary solution, you may <a href="%s">install this plugin</a> or delete all gz files packed in the theme (which it would load the original scripts).', 'themify' ), 'https://themify.me/files/themify-gzip-cleaner.zip' ); ?> <a class="button button-primary" href="<?php echo esc_url( add_query_arg( 'tf_clean_gz', 1 ) ); ?>"><?php _e( 'Remove all GZIP files', 'themify' ); ?></a></div>
511 <script async src="<?php echo THEMIFY_URI . '/js/admin/litespeed-gzip.min.js'; ?>"></script>
512
513 <!-- html -->
514 <form id="themify" method="post" action="" enctype="multipart/form-data">
515 <p id="theme-title"><?php echo esc_html( $check_theme_name ); ?> <em><?php echo esc_html( $check_theme_version ); ?> (<a href="<?php echo themify_https_esc( 'https://themify.org/changelogs/' ); ?><?php echo get_template(); ?>.txt" class="themify_changelogs" target="_blank" rel="noopener" data-changelog="<?php echo themify_https_esc( 'https://themify.org/changelogs/' ); ?><?php echo get_template(); ?>.txt"><?php _e('changelogs', 'themify'); ?></a>)</em></p>
516 <p class="top-save-btn">
517 <a href="#" class="save-button"><?php _e('Save', 'themify'); ?></a>
518 </p>
519 <div id="content">
520
521 <!-- nav -->
522 <ul id="maintabnav">
523 <li class="setting"><a href="#setting"><?php _e( 'Settings', 'themify' ); ?></a></li>
524 <?php if( $skins_and_demos ) : ?>
525 <li class="skins"><a href="#skins"><?php _e( 'Skins & Demos', 'themify' ); ?></a></li>
526 <?php elseif ( ! empty( $themify_skins ) ) : ?>
527 <li class="skins"><a href="#skins"><?php _e( 'Skins', 'themify' ); ?></a></li>
528 <?php endif; ?>
529
530 <li class="transfer"><a href="#transfer"><?php _e( 'Transfer', 'themify' ); ?></a></li>
531 <?php if( ! $skins_and_demos ) : ?>
532 <li class="demo-import"><a href="#demo-import"><?php _e( 'Demo Import', 'themify' ); ?></a></li>
533 <?php endif;?>
534 <?php if ( themify_allow_update() ) : ?>
535 <li class="update-check"><a href="#update-check"><?php _e( 'Update', 'themify' ); ?></a></li>
536 <?php endif; ?>
537 </ul>
538 <!-- /nav -->
539
540 <!------------------------------------------------------------------------------------>
541
542 <!--setting tab -->
543 <div id="setting" class="maintab">
544
545 <ul class="subtabnav">
546 <div class="search-setting-holder">
547 <label for="search-setting" class="search-icon"><?php echo themify_get_icon('search','ti')?></label>
548 <input id="search-setting" type="text" class="search-setting" name="search-setting">
549 <span class="clear-search"><?php echo themify_get_icon('close','ti')?></span>
550 </div>
551 <?php
552 $x = true;
553 foreach($themify_config['panel']['settings']['tab'] as $tab):?>
554 <?php if ( isset( $tab['id'] )):?>
555 <li<?php if( $x===true):?> class="selected"<?php $x = false;?><?php endif;?>><a href="<?php esc_attr_e( '#setting-' . themify_scrub_func( $tab['id'] ) )?>"><?php echo $tab['title']?></a></li>
556 <?php endif;?>
557 <?php endforeach;?>
558 </ul>
559
560 <?php $themify_settings_notice = false; ?>
561 <?php foreach($themify_config['panel']['settings']['tab'] as $tab){ ?>
562 <!-- subtab: setting-<?php echo themify_scrub_func($tab['id']); ?> -->
563 <div id="<?php echo esc_attr( 'setting-' . themify_scrub_func( $tab['id'] ) ); ?>" class="subtab">
564 <?php
565 if(is_array($tab['custom-module'])){
566 if(isset($tab['custom-module']['title'],$tab['custom-module']['function']) ){
567 echo themify_fieldset( $tab['custom-module']['title'], $tab['custom-module']['function'], $tab['custom-module'] );
568 } else {
569 foreach($tab['custom-module'] as $module){
570 $wrap = ( ! isset( $module['wrap'] ) || $module['wrap'] ) ? true : false;
571 echo themify_fieldset( $module['title'], $module['function'], $module, $wrap );
572 }
573 }
574 }
575 ?>
576 <?php
577 if ( ! $themify_settings_notice ) :
578 ?>
579 <div class="themify-info-link"><?php printf( __( 'For more info about the options below, refer to the <a href="%s">General Settings</a> documentation.', 'themify' ), 'https://themify.me/docs/general-settings' ); ?></div>
580 <?php
581 $themify_settings_notice = true;
582 endif; // themify settings notice
583
584 if (themify_scrub_func($tab['id'])== 'default_layouts') {
585 echo '<div class="themify-info-link">' . __( 'Here you can set the <a href="https://themify.me/docs/default-layouts">Default Layouts</a> for WordPress archive post layout (category, search, archive, tag pages, etc.), single post layout (single post page), and the static Page layout. The default single post and page layout can be override individually on the post/page &gt; edit &gt; Themify Custom Panel.', 'themify' ) . '</div>';
586 }
587
588 ?>
589 </div>
590
591 <!-- /subtab: setting-<?php echo themify_scrub_func($tab['id']); ?> -->
592 <?php } ?>
593
594 </div><!--/setting tab -->
595
596 <!------------------------------------------------------------------------------------>
597
598 <!--skins tab -->
599 <?php
600 if ( ! empty( $themify_skins ) ) : ?>
601 <div id="skins" class="maintab">
602 <ul class="subtabnav">
603 <li class="selected"><a href="#setting-general"><?php _e('Skins', 'themify'); ?></a></li>
604 </ul>
605
606 <div id="load-load" class="subtab">
607 <div class="tf_skins_toolbar">
608 <div class="tf_skins_search">
609 <span class="tf_skins_search_icon"><?php echo themify_get_icon( 'search', 'ti' ); ?></span>
610 <input type="search" class="tf_skins_search_input" placeholder="<?php esc_attr_e( 'Search', 'themify' ); ?>" autocomplete="off" />
611 </div>
612 </div>
613 <div class="themify-skins">
614 <input type="hidden" name="skin" value="<?php echo esc_attr( themify_get( 'skin','',true ) ); ?>">
615 <?php echo themify_get_skins_admin(); ?>
616 </div>
617 <?php if( $skins_and_demos ) : ?>
618 <div class="themify-info-link tf_skins_notice"><?php _e( 'Select a skin and import the demo content (demo import is optional). Importing the demo content will override your Themify settings, including your menu and widget configurations. It will also add content (posts, pages, featured images, widgets, menus, etc.) to your site based on our demo setup. It is recommended to perform this only on a fresh or development site. Erase demo will delete all the imported posts/pages (either modified or unmodified). Themify panel settings, user&rsquo;s created content, and widgets will not be removed.', 'themify' ); ?></div>
619 <?php endif; ?>
620 </div>
621 </div>
622 <!--/skins tab -->
623 <?php endif; ?>
624
625 <!------------------------------------------------------------------------------------>
626
627 <!--transfer tab -->
628 <div id="transfer" class="maintab">
629 <ul class="subtabnav">
630 <li><a href="#transfer-import"><?php _e( 'Theme Settings', 'themify' ); ?></a></li>
631 </ul>
632
633 <div id="transfer-import" class="subtab">
634 <div class="themify-info-link"><?php _e( 'Click "Export" to export the Themify panel data which you can use to import in the future by clicking the "Import" button. Note: this will only export/import the data within the Themify panel (the WordPress settings, widgets, content, comments, page/post settings, etc. are not included).', 'themify' ) ?></div>
635
636 <div class="biggest-transfer-btn">
637 <a class="themify_button big-button" id="tf_import_settings"
638 data-msg-confirm="<?php esc_attr_e( 'Import will overwrite all settings and configurations. Press OK to continue, Cancel to stop.', 'themify' ); ?>"
639 data-msg-invalid="<?php esc_attr_e( 'Invalid file format. Please upload .txt or .zip file containing the exported data.', 'themify' ); ?>"
640 data-msg-error="<?php esc_attr_e( 'Failed to import, please try again later.', 'themify' ); ?>"
641 data-msg-importing="<?php esc_attr_e( 'Importing...', 'themify' ); ?>"
642 data-nonce="<?php esc_attr_e( wp_create_nonce( 'themify_import_settings' ) ); ?>"
643 ><?php _e( 'Import', 'themify' ); ?></a>
644 <em><?php _e('or', 'themify'); ?></em>
645 <a href="#" class="themify_button big-button" id="tf_export_settings" data-nonce="<?php esc_attr_e( wp_create_nonce( 'themify_export_settings' ) ); ?>" data-filename="<?php echo esc_attr( $theme->display('Name') . '_themify_export_' . date('Y_m_d') ); ?>"><?php _e('Export', 'themify'); ?></a>
646 </div>
647 </div>
648
649 </div>
650 <!--/transfer tab -->
651
652 <?php if( ! $skins_and_demos ) : ?>
653 <!--demo import tab -->
654 <div id="demo-import" class="maintab">
655 <ul class="subtabnav">
656 <li><a href="#demo-import"><?php _e( 'Demo Import', 'themify' ); ?></a></li>
657 </ul>
658
659 <div id="demo-import" class="subtab demo-import-main">
660 <div>
661 <a href="#" class="themify_button big-button import-sample-content" data-plugins="<?php echo esc_attr(themify_get_theme_required_plugins()); ?>" data-default="<?php _e( 'Import Demo', 'themify' ); ?>" data-success="<?php _e( 'Done', 'themify' ); ?>" data-importing="<?php _e( 'Importing', 'themify' ) ?>"> <i class="ti-arrow-down"></i> <span><?php _e( 'Import Demo', 'themify' ); ?></span> </a>
662 </div>
663 <p><?php _e( 'Import demo will replicate your site like our demo setup.', 'themify' ); ?> <br><br>
664
665 <small><?php _e( 'WARNING: Importing the demo content will override your Themify settings, including your menu and widget configurations. It will also add content (posts, pages, featured images, widgets, menus, etc.) to your site based on our demo setup. It is recommended to perform this only on a fresh or development site.', 'themify' ); ?></small></p>
666 <div>
667 <a href="#" class="themify_button big-button erase-sample-content" data-default="<?php _e( 'Erase Demo', 'themify' ); ?>" data-erasing="<?php _e( 'Erasing', 'themify' ); ?>" data-success="<?php _e( 'Done', 'themify' ); ?>"> <i class="tf_close"></i> <span><?php _e( 'Erase Demo', 'themify' ); ?></span> </a>
668 </div>
669 <p><small><?php _e( 'Erase demo will delete all the imported posts/pages (either modified or unmodified). Themify panel settings, user&rsquo;s created content, and widgets will not be removed. You may import the content again later.', 'themify' ); ?></small></p>
670 </div>
671
672 </div>
673 <!--/demo import tab -->
674 <?php endif; ?>
675
676 <?php if ( themify_allow_update() ) : ?>
677 <!--update theme/framework tab -->
678 <div id="update-check" class="maintab">
679 <ul class="subtabnav">
680 <li><a href="#update-main"><?php _e( 'Update', 'themify' ); ?></a></li>
681 <li><a href="#child-theme"><?php _e( 'Child Theme', 'themify' ); ?></a></li>
682 </ul>
683 <div id="update-main" class="subtab update-main">
684 <?php if ( defined('THEMIFY_UPDATER') ) :
685
686 $updater = Themify_Updater::get_instance();
687 $theme = is_child_theme() ? $theme->parent() : $theme;
688 if ( ! method_exists($updater, 'themify_reinstall_theme') ) : ?>
689
690 <div class="note">
691 <?php _e( 'For theme re-installation feature, please update the Themify Updater plugin to latest version.', 'themify' ); ?>
692 </div>
693
694 <?php
695 elseif ( ( method_exists( $updater, 'should_block_themify_reinstall_for_missing_license' ) ? $updater->should_block_themify_reinstall_for_missing_license( $theme->stylesheet ) : ( $updater->has_error() && ! $updater->has_attribute( $theme->stylesheet, 'free' ) ) ) ) :
696 printf( __( 'To use theme re-installation, add your Themify username and license key under <a class="license-link" data-src="update" href="#">Themify License</a>.', 'themify' ) );
697 $license_modal=true;
698 else:
699 $updater->themify_reinstall_theme( $theme->stylesheet );
700 endif;
701 else : ?>
702 <div class="note">
703 <?php
704 if(!empty($GLOBALS['tgmpa'])){
705 $tgmpa_instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) );
706 $action = ! $tgmpa_instance->is_plugin_installed( 'themify-updater' )?'install':'activate';
707 $url='#';
708 $ajax_url = wp_nonce_url(
709 add_query_arg(
710 array(
711 'plugin' => urlencode( 'themify-updater' ),
712 'tgmpa-' . $action => $action . '-plugin',
713 'auto_activate' => 1,
714 ),
715 $tgmpa_instance->get_tgmpa_url()
716 ),
717 'tgmpa-' . $action,
718 'tgmpa-nonce'
719 );
720 }else{
721 $url=admin_url( 'admin.php?page=themify-install-plugins' );
722 }
723 ?>
724 <?php printf( __( 'To update theme automatically, please activate <a class="themify-ajax-installer" href="%s"%s>Themify Updater</a> plugin and insert your Themify username/license key.', 'themify' ), $url,('#'!==$url ? ' target="_blank" rel="noopener"' : ' data-ajax="'.esc_url($ajax_url).'"') ); ?>
725 </div>
726 <?php endif; ?>
727 </div>
728 <div id="child-theme" class="subtab">
729 <?php if ( is_child_theme() ) : ?>
730 <p><?php echo themify_get_icon( 'far thumbs-up' ); ?> <?php _e( 'You\'re already using a child theme. Well done!', 'themify' ); ?></p>
731 <?php else : ?>
732 <?php Themify_Child_Theme_Generator::form(); ?>
733 <?php endif; ?>
734 </div>
735 </div>
736 <!--/update theme/framework tab -->
737 <?php endif; // user can update_themes ?>
738
739 <!------------------------------------------------------------------------------------>
740
741 </div>
742 <!--/content -->
743
744 <?php if( get_option( get_template() . '_themify_import_notice', 1 ) ) : ?>
745 <div id="demo-import-notice" class="themify-modal tf_scrollbar">
746
747 <?php if ( ! is_child_theme() ) : ?>
748 <?php Themify_Child_Theme_Generator::form(); ?>
749 <hr>
750 <?php endif; ?>
751
752 <?php if( $skins_and_demos ) : ?>
753 <h3><?php _e( 'Skins & Demos', 'themify' ); ?></h3>
754 <p><?php _e( 'Select a skin and import the demo content as per our demo (optional). You can do this later at the Skins & Demos tab.', 'themify' ); ?></p>
755 <div class="themify-skins">
756 <?php echo themify_get_skins_admin(); ?>
757 </div>
758 <?php else : ?>
759 <h3><?php _e( 'Import Demo', 'themify' ); ?></h3>
760 <p><?php _e( 'Would you like to import the demo content to have the exact look as our demo?', 'themify' ); ?></p>
761 <p><?php _e( 'You may import or erase demo content later at the Import tab of the Themify panel.', 'themify' ); ?></p>
762 <a href="#" class="themify_button import-sample-content" data-plugins="<?php echo esc_attr(themify_get_theme_required_plugins()); ?>" data-default="<?php _e( 'Import Demo', 'themify' ); ?>" data-success="<?php _e( 'Done', 'themify' ); ?>" data-importing="<?php _e( 'Importing', 'themify' ) ?>"> <i class="ti-arrow-down"></i> <span><?php _e( 'Yes, import', 'themify' ); ?></span> </a>
763 <a href="#" class="thanks-button dismiss-import-notice"> <?php _e( 'No, thanks', 'themify' ); ?> </a>
764 <div class="note"><?php _e( 'WARNING: Importing the demo content will override your Themify settings, including your menu and widget configurations. It will also add content (posts, pages, featured images, widgets, menus, etc.) to your site based on our demo setup. It is recommended to perform this only on a fresh or development site.', 'themify' ); ?></div>
765 <?php endif; ?>
766 <a href="#" class="close dismiss-import-notice"><i class="tf_close"></i></a>
767 </div>
768 <?php
769 // disable the demo import modal after first visit
770 $_key=get_template() . '_themify_import_notice';
771 delete_option($_key);
772 add_option($_key,0, '', false );
773 ?>
774 <?php endif; ?>
775
776 <!-- footer -->
777 <div id="bottomtab">
778 <p id="logo">v<?php echo THEMIFY_VERSION; ?></p>
779 <div class="reset">
780 <strong><a href="#" id="reset-setting" class="reset-button"><?php _e( 'Reset Settings', 'themify' ); ?></a></strong>
781 </div>
782 <p class="btm-save-btn">
783 <a href="#" class="save-button"><?php _e('Save', 'themify'); ?></a>
784 </p>
785 </div>
786 <!--/footer -->
787 </form>
788 <script>
789 /**
790 * Ensure checkboxes are included in the data sent to server
791 * Fixes checkboxes not being saved
792 */
793 const items=document.querySelectorAll('#themify input[type="checkbox"]');
794 for(var i=items.length-1;i>-1;--i){
795 let name=items[i].getAttribute('name');
796 if(name && (!items[i].previousElementSibling || items[i].previousElementSibling.type!=='hidden')){
797 let hidden=document.createElement('input');
798 hidden.type='hidden';
799 hidden.name=name;
800 items[i].before(hidden);
801 }
802 }
803 </script>
804 <div class="clearBoth"></div>
805 <!-- /html -->
806
807 <?php
808 do_action('themify_settings_panel_end');
809 }
810
811 /**
812 * Return an array of available theme skins
813 *
814 * @since 2.7.8
815 * @return array
816 */
817 function themify_get_skins(){
818 // Open Styles Folder
819 $dir = trailingslashit( get_template_directory() ) . 'skins';
820
821 $skins = array(
822 1 => array(
823 array(
824 'name' => __( 'Default', 'themify' ),
825 'version' => null,
826 'description' => null,
827 'screenshot' => get_template_directory_uri() . '/themify/img/non-skin.gif',
828 ),
829 ),
830 );
831 if ( is_dir( $dir ) && ($handle = opendir( $dir ) )) {
832 // Grab Folders
833 while ( false !== ( $dirTwo = readdir($handle) ) ) {
834 if( $dirTwo !== '.' && $dirTwo !== '..' ) {
835 $path = trailingslashit( $dir ) . $dirTwo;
836 if( is_file( $path . '/style.css' ) ) {
837 $info = get_file_data( $path . '/style.css', array( 'Skin Name', 'Version', 'Description', 'Demo URI', 'Required Plugins', 'Display Order' ) );
838 $order = empty( $info[5] ) ? 10 : $info[5];
839 $skins[ $order ][ $dirTwo ] = array(
840 'name' => $info[0],
841 'version' => $info[1],
842 'description' => $info[2],
843 'demo_uri' => $info[3],
844 'required_plugins' => $info[4],
845 );
846 }
847 }
848 }
849 closedir($handle);
850 }
851 ksort( $skins ); // sort skin groups
852 ksort( $skins[10] ); // sort by skin name
853 $skins = call_user_func_array( 'array_merge', $skins );
854
855 return apply_filters( 'themify_theme_skins', $skins );
856 }
857
858 /**
859 * Display the admin field for the theme skins
860 *
861 * @return string
862 */
863 function themify_get_skins_admin(){
864 $skins = themify_get_skins();
865 $output = '';
866 $template = get_template();
867 $skins_with_demos = current_theme_supports( 'themify-skins-and-demos' );
868
869 if( ! empty( $skins ) ) {
870 $current=themify_get_skin();
871 $canImport = current_user_can('manage_options');
872 $hasDemo=current_user_can('delete_pages') && Themify_Import_Helper::has_demo_content();
873 foreach( $skins as $id => $skin ) {
874 $selected = $current === $id ? 'selected' : '';
875 $screenshot = 0 === $id ? get_template_directory_uri() . '/themify/img/screenshot-na.png' : 'https://themify.org/public-api/screenshots/' . $template . '/' . $id . '/screenshot.jpg';
876
877 if( ($id === 'default' || 0 === $id) &&(!$current || $current==='default')) {
878 $selected = 'selected';
879 }
880
881 $output .= '
882 <div class="skin-preview '. $selected .'" data-skin="'. $id .'">
883 <a href="#"><img src="' . $screenshot . '" alt="' . esc_attr__( 'Skin', 'themify' ) . '" loading="lazy" decoding="async" width="300" height="225" /></a>
884 <br />' . $skin['name'];
885 if(! empty( $skin['demo_uri'] ) ) {
886 $output .= sprintf( ' <span class="view-demo"><a href="%s" target="_blank" rel="noopener">%s</a></span>', $skin['demo_uri'], __( 'demo', 'themify' ) );
887 }
888 if( $skins_with_demos && $canImport) {
889 $output .= '<div class="skin-demo-content" data-skin="' . esc_attr( $id ) . '">';
890 $output .= __( 'Demo:', 'themify' );
891 $output .= ' <a href="#" class="skin-demo-import" data-id="'.esc_attr($id).'" data-plugins="'.esc_attr($skin['required_plugins']).'">' . __( 'Import', 'themify' ).'</a>';
892 if($hasDemo===true){
893 $output.='<a href="#" class="skin-erase-link">' . __( 'Erase', 'themify' ) . '</a>';
894 $output .='<div class="tf_erase_box tf_abs_t tf_hide" tabindex="-1"><label><input type="checkbox" class="tf_modify_demo" id="_tf_modify_demo" checked="checked">'.__('Keep modified posts/pages','themify').'</label><a href="#" class="skin-erase-demo">'.__( 'Erase Demo', 'themify' ).'</a></div>';
895 }
896 $output .= '</div>';
897 }
898
899 $output .= '</div>';
900 }
901 }
902
903 return $output;
904 }
905
906 /**
907 * Create Settings Fieldset
908 *
909 * @param string $title
910 * @param string $module
911 * @param string $attr
912 * @param bool $wrap whether to output the module wrapper
913 *
914 * @return string
915 */
916 function themify_fieldset( $title = '', $module = '', $attr = '', $wrap = true ) {
917 $data = themify_get_data();
918 $data_param = isset( $data['setting'][$title] )? $data['setting'][$title] : '';
919 if( is_array( $module ) && is_callable( $module ) ) {
920 $function = $module;
921 } else {
922 $function = '';
923 $module = trim( $module );
924 $module = themify_scrub_func( $module );
925 if ( function_exists( 'themify_' . $module ) ) {
926 $function = 'themify_' . $module;
927 } else if ( function_exists( $module ) ) {
928 $function = $module;
929 }
930 if ( '' == $function ) {
931 return '';
932 }
933 }
934 $output = call_user_func( $function, array(
935 'data' => $data_param,
936 'attr' => $attr )
937 );
938 if ( $wrap ) {
939 $tmp_id = is_string( $function ) ? 'id="'. esc_attr( $function ) .'"' : '' ;
940 $output = '<fieldset '.$tmp_id.'><legend><span>' . esc_html( $title ) . '</span><i class="tf_plus_icon"></i></legend><div class="themify_panel_fieldset_wrap">'
941 . $output
942 . '</div></fieldset>';
943 }
944 return $output;
945 }
946
947
948 /**
949 * Get details about a known plugin
950 *
951 * @param $name if omitted, returns the entire list
952 * @since 2.8.6
953 */
954 function themify_get_known_plugin_info( $name = '' ) {
955 $plugins = array(
956 'builder-ab-image' => array(
957 'name' => __( 'Builder A/B Image', 'themify' ),
958 'image' => 'https://themify.me/wp-content/product-img/addons/ab-image.jpg',
959 'desc' => 'Compare 2 images side by side',
960 'page' => 'https://themify.me/addons/ab-image',
961 'path' => 'builder-ab-image/init.php',
962 ),
963 'builder-audio' => array(
964 'name' => __( 'Builder Audio', 'themify' ),
965 'image' => 'https://themify.me/wp-content/product-img/addons/audio.jpg',
966 'desc' => 'Elegant audio playlist',
967 'page' => 'https://themify.me/addons/audio',
968 'path' => 'builder-audio/init.php'
969 ),
970 'builder-button' => array(
971 'name' => __( 'Builder Button Pro', 'themify' ),
972 'image' => 'https://themify.me/wp-content/product-img/addons/button.jpg',
973 'desc' => 'Custom designed action buttons',
974 'page' => 'https://themify.me/addons/button',
975 'path' => 'builder-button/init.php'
976 ),
977 'builder-contact' => array(
978 'name' => __( 'Builder Contact', 'themify' ),
979 'image' => 'https://themify.me/wp-content/product-img/addons/contact.jpg',
980 'desc' => 'Simple contact form',
981 'page' => 'https://themify.me/addons/contact',
982 'path' => 'builder-contact/init.php'
983 ),
984 'builder-countdown' => array(
985 'name' => __( 'Builder Countdown', 'themify' ),
986 'image' => 'https://themify.me/wp-content/product-img/addons/countdown.jpg',
987 'desc' => 'Count down events and promotions',
988 'page' => 'https://themify.me/addons/countdown',
989 'path' => 'builder-countdown/init.php'
990 ),
991 'builder-counter' => array(
992 'name' => __( 'Builder Counter', 'themify' ),
993 'image' => 'https://themify.me/wp-content/product-img/addons/counter.jpg',
994 'desc' => 'Animated circles and number counters',
995 'page' => 'https://themify.me/addons/counter',
996 'path' => 'builder-counter/init.php'
997 ),
998 'builder-fittext' => array(
999 'name' => __( 'Builder FitText', 'themify' ),
1000 'image' => 'https://themify.me/wp-content/product-img/addons/fittext.jpg',
1001 'desc' => 'Auto fit text in the container',
1002 'page' => 'https://themify.me/addons/fittext',
1003 'path' => 'builder-fittext/init.php'
1004 ),
1005 'builder-image-pro' => array(
1006 'name' => __( 'Builder Image Pro', 'themify' ),
1007 'image' => 'https://themify.me/wp-content/product-img/addons/image-pro.jpg',
1008 'desc' => 'Beautify images with image filters, color/image overlay, and animation effects',
1009 'page' => 'https://themify.me/addons/image-pro',
1010 'path' => 'builder-image-pro/init.php'
1011 ),
1012 'builder-infinite-posts' => array(
1013 'name' => __( 'Builder Infinite Posts', 'themify' ),
1014 'image' => 'https://themify.me/wp-content/product-img/addons/infinite-posts.jpg',
1015 'desc' => 'Display posts in infinite scrolling on parallax, grid, overlay, or list view',
1016 'page' => 'https://themify.me/addons/infinite-posts',
1017 'path' => 'builder-infinite-posts/init.php'
1018 ),
1019 'builder-bar-chart' => array(
1020 'name' => __( 'Builder Bat Chart', 'themify' ),
1021 'image' => 'https://themify.me/wp-content/product-img/addons/bar-chart.jpg',
1022 'desc' => 'Display bar graphs',
1023 'page' => 'https://themify.me/addons/bar-chart',
1024 'path' => 'builder-bar-chart/init.php'
1025 ),
1026 'builder-maps-pro' => array(
1027 'name' => __( 'Builder Maps Pro', 'themify' ),
1028 'image' => 'https://themify.me/wp-content/product-img/addons/maps-pro.jpg',
1029 'desc' => 'Multiple markers, custom icons, tooltips, and 40+ map styles',
1030 'page' => 'https://themify.me/addons/maps-pro',
1031 'path' => 'builder-maps-pro/init.php'
1032 ),
1033 'builder-pie-chart' => array(
1034 'name' => __( 'Builder Pie Chart', 'themify' ),
1035 'image' => 'https://themify.me/wp-content/product-img/addons/pie-chart.jpg',
1036 'desc' => '',
1037 'page' => 'https://themify.me/addons/pie-chart',
1038 'path' => 'builder-pie-chart/init.php'
1039 ),
1040 'builder-pointers' => array(
1041 'name' => __( 'Builder Pointers', 'themify' ),
1042 'image' => 'https://themify.me/wp-content/product-img/addons/pointers.jpg',
1043 'desc' => 'Highlight certain areas of your image',
1044 'page' => 'https://themify.me/addons/pointers',
1045 'path' => 'builder-pointers/init.php'
1046 ),
1047 'builder-pricing-table' => array(
1048 'name' => __( 'Builder Pricing Table', 'themify' ),
1049 'image' => 'https://themify.me/wp-content/product-img/addons/pricing-table.jpg',
1050 'desc' => 'Beautiful and responsive pricing table addon',
1051 'page' => 'https://themify.me/addons/pricing-table',
1052 'path' => 'builder-pricing-table/init.php'
1053 ),
1054 'builder-progress-bar' => array(
1055 'name' => __( 'Builder Progress Bar', 'themify' ),
1056 'image' => 'https://themify.me/wp-content/product-img/addons/progress-bar.jpg',
1057 'desc' => 'Animated bars based on input percentage',
1058 'page' => 'https://themify.me/addons/progress-bar',
1059 'path' => 'builder-progress-bar/init.php'
1060 ),
1061 'builder-slider-pro' => array(
1062 'name' => __( 'Builder Slider Pro', 'themify' ),
1063 'image' => 'https://themify.me/wp-content/product-img/addons/slider-pro.jpg',
1064 'desc' => 'Make stunning sliders with transition and animation effects',
1065 'page' => 'https://themify.me/addons/slider-pro',
1066 'path' => 'builder-slider-pro/init.php'
1067 ),
1068 'builder-tiles' => array(
1069 'name' => __( 'Builder Tiles', 'themify' ),
1070 'image' => 'https://themify.me/wp-content/product-img/addons/tiles.jpg',
1071 'desc' => 'Drag & drop tiles to create Windows 8 Metro layouts',
1072 'page' => 'https://themify.me/addons/tiles',
1073 'path' => 'builder-tiles/init.php'
1074 ),
1075 'builder-timeline' => array(
1076 'name' => __( 'Builder Timeline', 'themify' ),
1077 'image' => 'https://themify.me/wp-content/product-img/addons/timeline.jpg',
1078 'desc' => 'Display content in a timeline-styled layouts',
1079 'page' => 'https://themify.me/addons/timeline',
1080 'path' => 'builder-timeline/init.php'
1081 ),
1082 'builder-typewriter' => array(
1083 'name' => __( 'Builder Typewriter', 'themify' ),
1084 'image' => 'https://themify.me/wp-content/product-img/addons/typewriter.jpg',
1085 'desc' => 'Display your text with eye-catching typing animation',
1086 'page' => 'https://themify.me/addons/typewriter',
1087 'path' => 'builder-typewriter/init.php'
1088 ),
1089 'builder-woocommerce' => array(
1090 'name' => __( 'Builder WooCommerce', 'themify' ),
1091 'image' => 'https://themify.me/wp-content/product-img/addons/woocommerce.jpg',
1092 'desc' => 'Show WooCommerce products anywhere in the Builder',
1093 'page' => 'https://themify.me/addons/woocommerce',
1094 'path' => 'builder-woocommerce/init.php'
1095 ),
1096 'contact-form-7' => array(
1097 'name' => __( 'Contact Form 7', 'themify' ),
1098 'image' => 'https://themify.me/wp-content/product-img/addons/ab-image.jpg',
1099 'desc' => '',
1100 'page' => 'https://wordpress.org/plugins/contact-form-7/',
1101 'path' => 'contact-form-7/wp-contact-form-7.php',
1102 'wp_hosted'=>true
1103 ),
1104 'themify-portfolio-post' => array(
1105 'name' => __( 'Portfolio Posts', 'themify' ),
1106 'image' => 'https://themify.me/wp-content/product-img/addons/ab-image.jpg',
1107 'desc' => '',
1108 'page' => 'https://wordpress.org/plugins/themify-portfolio-post/',
1109 'path' => 'themify-portfolio-post/themify-portfolio-post.php',
1110 'wp_hosted'=>true
1111 ),
1112 'mailchimp-for-wp' => array(
1113 'name' => __( 'MailChimp for WordPress', 'themify' ),
1114 'image' => 'https://themify.me/wp-content/product-img/addons/ab-image.jpg',
1115 'desc' => '',
1116 'page' => 'https://wordpress.org/plugins/mailchimp-for-wp/',
1117 'path' => 'mailchimp-for-wp/mailchimp-for-wp.php',
1118 'wp_hosted'=>true
1119 ),
1120 'woocommerce' => array(
1121 'name' => __( 'WooCommerce', 'themify' ),
1122 'image' => 'https://themify.me/wp-content/product-img/addons/ab-image.jpg',
1123 'desc' => '',
1124 'page' => 'https://wordpress.org/plugins/woocommerce/',
1125 'path' => 'woocommerce/woocommerce.php',
1126 'wp_hosted'=>true
1127 ),
1128 'themify-wc-product-filter' => array(
1129 'name' => __( 'Themify Product Filter', 'themify' ),
1130 'image' => 'https://themify.me/wp-content/product-img/addons/ab-image.jpg',
1131 'desc' => '',
1132 'page' => 'https://themify.me/themify-product-filter',
1133 'path' => 'themify-wc-product-filter/themify-wc-product-filter.php'
1134 ),
1135 'themify-shortcodes' => array(
1136 'name' => __( 'Themify Shortcodes', 'themify' ),
1137 'image' => 'https://themify.me/wp-content/product-img/addons/themify-shortcodes.jpg',
1138 'desc' => '',
1139 'page' => 'https://wordpress.org/plugins/themify-shortcodes/',
1140 'path' => 'themify-shortcodes/init.php',
1141 'wp_hosted'=>true
1142 ),
1143 'themify-event-post' => array(
1144 'name' => __( 'Themify Event Post', 'themify' ),
1145 'image' => 'https://themify.me/wp-content/product-img/addons/themify-shortcodes.jpg',
1146 'desc' => '',
1147 'page' => 'https://wordpress.org/plugins/themify-event-post/',
1148 'path' => 'themify-event-post/themify-event-post.php',
1149 'wp_hosted'=>true
1150 ),
1151 'learnpress' => array(
1152 'name' => __( 'LearnPress', 'themify' ),
1153 'image' => 'https://ps.w.org/learnpress/assets/icon-256x256.png',
1154 'desc' => '',
1155 'page' => 'https://wordpress.org/plugins/learnpress/',
1156 'path' => 'learnpress/learnpress.php',
1157 'wp_hosted'=>true
1158 ),
1159 'themify-store-locator'=>array(
1160 'name' => __( 'Themify Store Locator', 'themify' ),
1161 'image' => 'https://themify.me/wp-content/uploads/2016/12/store-locator-blog-image.jpg',
1162 'desc' => '',
1163 'page' => 'https://wordpress.org/plugins/themify-store-locator/',
1164 'path' => 'themify-store-locator/store_locator.php',
1165 'wp_hosted'=>true
1166 ),
1167 'themify-updater' => array(
1168 'name' => __( 'Themify Updater', 'themify' ),
1169 'image' => '',
1170 'desc' => '',
1171 'page' => 'https://themify.me/docs/themify-updater-documentation',
1172 'path' => 'themify-updater/themify-updater.php'
1173 ),
1174 'give' => array(
1175 'name' => __( 'Give', 'themify' ),
1176 'image' => 'https://ps.w.org/give/assets/icon-256x256.jpg',
1177 'desc' => '',
1178 'page' => 'https://wordpress.org/plugins/give/',
1179 'path' => 'give/give.php',
1180 'wp_hosted'=>true
1181 ),
1182 );
1183 return $name===''?$plugins:(isset( $plugins[$name] )?$plugins[$name]:false);
1184 }
1185
1186 /**
1187 * Themify Admin Widgets
1188 */
1189
1190 if( !function_exists( 'themify_add_admin_widgets' ) ):
1191 function themify_add_admin_widgets() {
1192 wp_add_dashboard_widget( 'themify_news', esc_html__( 'Themify News', 'themify' ), 'themify_news_admin_widget' );
1193 }
1194 endif;
1195 add_action( 'wp_dashboard_setup', 'themify_add_admin_widgets' );
1196
1197 // Themify News Admin Widget
1198 function themify_news_admin_widget() {
1199 $cache_key = 'themify_news_dashboard_widget';
1200
1201 echo '<div class="rss-widget">';
1202 if ( false !== ( $output = Themify_Storage::get( $cache_key ) ) ) {
1203 echo $output;
1204 } else {
1205 echo '<script async src="' . THEMIFY_URI . '/js/admin/admin-dashboard.min.js"></script>';
1206 }
1207 echo '</div>';
1208 }
1209
1210
1211 function themify_check_update_link( $plugin, $type ) {
1212 global $admin_page_hooks;
1213 if( !empty($admin_page_hooks[$plugin]) && $type === 'plugin' && strpos( 'builder-' , $plugin) === false ) {
1214 return esc_url( admin_url( 'admin.php?page=' . $plugin ) );
1215 }
1216
1217 return esc_url( admin_url( 'admin.php?page=themify#update-check' ) );
1218 }
1219
1220 ///////////////////////////////////////////
1221 // Favicon Module
1222 ///////////////////////////////////////////
1223 function themify_favicon( $data = array() ) {
1224 if($data['attr']['target'] != ''){
1225 $target = "<span class='hide target'>".$data['attr']['target']."</span>";
1226 } else {
1227 $target = '';
1228 }
1229 $setting_favicon = themify_get( 'setting-favicon','',true );
1230 return '<div class="themify_field_row">
1231 <span class="label">'. __('Custom Favicon', 'themify') . '</span>
1232 <input id="setting-favicon" type="text" class="width10" name="setting-favicon" value="' . esc_attr( $setting_favicon ) . '" /> <br />
1233 '.$target.'
1234 <span class="pushlabel" style="display:block;">
1235 ' . themify_get_uploader('setting-favicon', array('tomedia' => true)) . '
1236 </span>
1237 </div>';
1238 }
1239
1240 ///////////////////////////////////////////
1241 // Default Layouts
1242 ///////////////////////////////////////////
1243 if (!function_exists('themify_custom_post_type_layouts')) :
1244 /**
1245 * Default Custom Post sidebar Module
1246 * @param array $data Theme settings data
1247 * @return string Markup for module.
1248 * @since 4.0.0
1249 */
1250 function themify_custom_post_type_layouts($data = array()){
1251 $data = themify_get_data();
1252
1253 /**
1254 * Theme Settings Option Key Prefix
1255 * @var string
1256 */
1257 $prefix = 'setting-custom_post_';
1258
1259 /**
1260 * Module markup
1261 * @var string
1262 */
1263
1264 $output = '';
1265
1266 $custom_posts = null;
1267
1268 $post_types = get_post_types(array('public' => true, 'publicly_queryable' => 'true'), 'objects');
1269 $excluded_types = apply_filters( 'themify_exclude_CPT_for_sidebar', array('post', 'page', 'attachment', 'tbuilder_layout', 'tbuilder_layout_part', 'section','tglobal_style'));
1270
1271
1272 foreach ($post_types as $key => $value) {
1273 if (!in_array($key, $excluded_types)) {
1274 $custom_posts[$key] = array( 'name' => $value->labels->singular_name, 'archive' => $value->has_archive );
1275 }
1276 }
1277
1278 $custom_posts = apply_filters('themify_get_public_post_types', $custom_posts);
1279
1280 /**
1281 * Sidebar placement options
1282 * @var array
1283 */
1284 $sidebar_location_options = apply_filters('themify_post_type_theme_sidebars' , array(
1285 array('value' => 'sidebar1', 'img' => 'images/layout-icons/sidebar1.png', 'title' => __('Sidebar Right', 'themify')),
1286 array('value' => 'sidebar1 sidebar-left', 'img' => 'images/layout-icons/sidebar1-left.png', 'title' => __('Sidebar Left', 'themify')),
1287 array('value' => 'sidebar-none', 'img' => 'images/layout-icons/sidebar-none.png', 'title' => __('No Sidebar ', 'themify'))
1288 ), false );
1289 /**
1290 * Page sidebar placement
1291 */
1292
1293 if(is_array($custom_posts)){
1294 foreach($custom_posts as $key => $cPost){
1295 $output .= sprintf('<h4>%s %s</h4>', strtoupper($cPost['name']), __('POST TYPE', 'themify'));
1296
1297 if ($cPost['archive']) {
1298
1299 $output .= '<p>'. sprintf('<span class="label">%s %s</span>', ucfirst($cPost['name']), __('Archive Sidebar', 'themify'));
1300 $val = isset( $data[$prefix.$key.'_archive'] ) ? $data[$prefix.$key.'_archive'] : '';
1301
1302 foreach ( $sidebar_location_options as $option ) {
1303 if ( ( '' == $val || ! $val || ! isset( $val ) ) && ( isset( $option['selected'] ) && $option['selected'] ) ) {
1304 $val = $option['value'];
1305 }
1306 $class = $val == $option['value']?'selected':'';
1307 $w= isset($option['w'])?$option['w']:'46';
1308 $h= isset($option['w'])?$option['w']:'35';
1309 $output .= '<a href="#" class="preview-icon '.$class.'" title="'.$option['title'].'"><img width="'.$w.'" height="'.$h.'" loading="lazy" decoding="async" src="'.THEME_URI.'/'.$option['img'].'" alt="'.$option['value'].'" /></a>';
1310 }
1311
1312 $output .= '<input type="hidden" name="'.$prefix.$key.'_archive" class="val" value="'.$val.'" /></p>';
1313
1314 $content_width = isset( $data[ $prefix . $key . '_archive_content_width'] ) ? $data[ $prefix . $key . '_archive_content_width'] : 'default_width';
1315 $output .=
1316 '<p data-show-if-element="[name=' . ( $prefix . $key) . '_archive]" data-show-if-value=\'["sidebar-none"]\'>
1317 <span class="label">' . sprintf( __( '%s Archive Content Width', 'themify' ), $cPost['name'] ) . '</span>
1318 <a href="#" class="preview-icon' . ( $content_width === 'default_width' ? ' selected' : '' ) . '" title="' . __( 'Default Width', 'themify' ) . '"><img src="' . THEME_URI . '/themify/img/default.svg" alt="default_width" loading="lazy" decoding="async" width="46" height="35"></a>
1319 <a href="#" class="preview-icon' . ( $content_width === 'full_width' ? ' selected' : '' ) . '" title="' . __( 'Fullwidth', 'themify' ) . '"><img src="' . THEME_URI . '/themify/img/fullwidth.svg" alt="full_width" loading="lazy" decoding="async" width="46" height="35"></a>
1320 <input type="hidden" name="' . $prefix . $key . '_archive_content_width" value="' . esc_attr( $content_width ) . '" class="val">
1321 </p>';
1322 }
1323
1324 $output .= '<p>'. sprintf('<span class="label">%s %s</span>', ucfirst($cPost['name']), __('Single Sidebar', 'themify'));
1325 $val = isset( $data[$prefix.$key.'_single'] ) ? $data[$prefix.$key.'_single'] : '';
1326
1327 foreach ( $sidebar_location_options as $option ) {
1328 if ( ( '' == $val || ! $val || ! isset( $val ) ) && ( isset( $option['selected'] ) && $option['selected'] ) ) {
1329 $val = $option['value'];
1330 }
1331 $class = $val == $option['value']?'selected':'';
1332 $w= isset($option['w'])?$option['w']:'46';
1333 $h= isset($option['w'])?$option['w']:'35';
1334 $output .= '<a href="#" class="preview-icon '.$class.'" title="'.$option['title'].'"><img width="'.$w.'" height="'.$h.'" loading="lazy" decoding="async" src="'.THEME_URI.'/'.$option['img'].'" alt="'.$option['value'].'" /></a>';
1335 }
1336 $output .= '<input type="hidden" name="'.$prefix.$key.'_single" class="val" value="'.$val.'" /></p>';
1337
1338 $content_width = isset( $data[ $prefix . $key . '_single_content_width'] ) ? $data[ $prefix . $key . '_single_content_width'] : 'default_width';
1339 $output .=
1340 '<p data-show-if-element="[name=' . ( $prefix . $key) . '_single]" data-show-if-value=\'["sidebar-none"]\'>
1341 <span class="label">' . __( 'Default Single Content Width', 'themify' ) . '</span>
1342 <a href="#" class="preview-icon' . ( $content_width === 'default_width' ? ' selected' : '' ) . '" title="' . __( 'Default Width', 'themify' ) . '"><img src="' . THEME_URI . '/themify/img/default.svg" alt="default_width" loading="lazy" decoding="async" width="46" height="35"></a>
1343 <a href="#" class="preview-icon' . ( $content_width === 'full_width' ? ' selected' : '' ) . '" title="' . __( 'Fullwidth', 'themify' ) . '"><img src="' . THEME_URI . '/themify/img/fullwidth.svg" alt="full_width" loading="lazy" decoding="async" width="46" height="35"></a>
1344 <input type="hidden" name="' . $prefix . $key . '_single_content_width" value="' . esc_attr( $content_width ) . '" class="val">
1345 </p>';
1346 }
1347 }
1348
1349 return $output;
1350 }
1351
1352 endif;
1353
1354 ///////////////////////////////////////////
1355 // Custom Feed URL Module
1356 ///////////////////////////////////////////
1357 function themify_custom_feed_url( $data = array() ) {
1358 $custom_feed_url = themify_get( 'setting-custom_feed_url','',true );
1359 return '<p><span class="label">' . __( 'Custom Feed URL', 'themify' ) . '</span> <input type="text" class="width10" name="setting-custom_feed_url" value="' . esc_attr( $custom_feed_url ) . '" /> <br />
1360 <span class="pushlabel"><small>' . __( 'e.g. http://feedburner.com/userid', 'themify' ) . '</small></span></p>';
1361 }
1362
1363 ///////////////////////////////////////////
1364 // Meta Description Module
1365 ///////////////////////////////////////////
1366 function themify_meta_description( $data = array() ) {
1367 $data = themify_get_data();
1368 return '<p><textarea name="setting-meta_description" class="widthfull" rows="4">'.$data['setting-meta_description'].'</textarea></p>';
1369 }
1370
1371 /**
1372 * Header HTML Module
1373 * @param array $data
1374 * @return string
1375 */
1376 function themify_header_html( $data = array() ) {
1377 $header_html = themify_get( 'setting-header_html','',true );
1378 return '<p>' . __('The following code will add to the &lt;head&gt; tag.', 'themify') . '</p>
1379 <p><textarea class="widthfull tf_code_editor" rows="10" name="setting-header_html" id="setting-header_html">'. esc_html( $header_html ) .'</textarea><br />
1380 <small>' . __('Useful if you need to add additional scripts such as CSS or JS.', 'themify') . '</small></p>';
1381 }
1382
1383
1384 /**
1385 * Footer HTML Module
1386 * @param array $data
1387 * @return string
1388 */
1389 function themify_footer_html( $data = array() ) {
1390 $footer_html = themify_get( 'setting-footer_html','',true );
1391 return '<p>' . __('The following code will be added to the footer before the closing &lt;/body&gt; tag.', 'themify') . '</p>
1392 <p><textarea type="text" class="widthfull tf_code_editor" rows="10" name="setting-footer_html" id="setting-footer_html">' . esc_html( $footer_html ) . '</textarea><br />
1393 <small>' . __('Useful if you need to Javascript or tracking code.', 'themify') . '</small></p>';
1394 }
1395
1396 ///////////////////////////////////////////
1397 // Search Settings Module
1398 ///////////////////////////////////////////
1399 function themify_search_settings( $data = array() ) {
1400 $data = themify_get_data();
1401 $post_checked = '';
1402 $checked = '';
1403 $search_settings = themify_get( 'setting-search_settings','',true );
1404 if ( themify_check( 'setting-search_settings_exclude',true ) ) {
1405 $checked = 'checked="checked"';
1406 }
1407 if ( themify_check( 'setting-search_exclude_post',true ) ) {
1408 $post_checked = 'checked="checked"';
1409 }
1410 $out = '<p>
1411 <span class="label">' . __( 'Search in Category IDs', 'themify' ) .themify_help(__( 'Use minus sign (-) to exclude categories. Example: (1,4,-7) = search only in Category 1 &amp; 4, and exclude Category 7.', 'themify' )) . ' </span>
1412 <input type="text" class="width6" name="setting-search_settings" value="' . esc_attr( $search_settings ) . '" />
1413 </p>
1414 <p>
1415 <span class="pushlabel"><label for="setting-search_exclude_post"><input type="checkbox" id="setting-search_exclude_post" name="setting-search_exclude_post" ' . $post_checked . '/> ' . __( 'Exclude Posts in search results', 'themify' ) . '</label></span>
1416 </p>
1417 <p>
1418 <span class="pushlabel"><label for="setting-search_settings_exclude"><input type="checkbox" id="setting-search_settings_exclude" name="setting-search_settings_exclude" ' . $checked . '/> ' . __( 'Exclude Pages in search results', 'themify' ) . '</label></span>
1419 </p>';
1420
1421
1422 $pre = 'setting-search_exclude_';
1423 $checkboxes = '';
1424
1425 $exclude_types = apply_filters( 'themify_types_excluded_in_search', get_post_types( array(
1426 '_builtin' => false,
1427 'public' => true,
1428 'exclude_from_search' => false
1429 ) ) );
1430
1431 foreach ( array_keys( $exclude_types ) as $post_type ) {
1432
1433 $type = get_post_type_object( $post_type );
1434
1435 if ( is_object( $type ) ) {
1436 $checkboxes .= '
1437 <p>
1438 <span class="pushlabel">
1439 <label for="' . $pre . $type->name . '">
1440 <input type="checkbox" id="' . $pre . $type->name . '" name="' . esc_attr( $pre . $type->name ) . '" ' . checked( isset( $data[ $pre . $type->name ] ) ? $data[ $pre . $type->name ] : '', 'on', false ) . '/> ' . sprintf( __( 'Exclude %s in search results', 'themify' ), $type->labels->name ) . '
1441 </label>
1442 </span>
1443 </p>';
1444 }
1445 }
1446
1447 if ( '' != $checkboxes ) {
1448 $out .= $checkboxes;
1449 }
1450
1451 return apply_filters('themify_search_settings_output', $out);
1452 }
1453
1454 ///////////////////////////////////////////
1455 // 404 Page Settings Module
1456 ///////////////////////////////////////////
1457 if( !function_exists( 'page_404_settings' ) ){
1458 function page_404_settings(){
1459 $data = themify_get_data();
1460 $page_404 = themify_get( 'setting-page_404','',true );
1461 $max = 100;
1462 $args = array(
1463 'sort_order' => 'asc',
1464 'sort_column' => 'post_title',
1465 'post_type' => 'page',
1466 'ignore_sticky_posts'=>true,
1467 'post_status' => 'publish',
1468 'cache_results'=>false,
1469 'update_post_term_cache'=>false,
1470 'update_post_meta_cache'=>false,
1471 'posts_per_page' => $max
1472 );
1473 $pages = new WP_Query( $args );
1474 $front = get_option('page_on_front');
1475 $out = '<p><span class="label">' . __( 'Custom 404 Page', 'themify' ) .themify_help(__('First create a new Page (eg. 404) and then select it here. The selected page will be used for error 404 (when a URL is not found on your site).', 'themify')). ' </span>';
1476 if($pages->max_num_pages>1){
1477 $post_name = '';
1478 if($page_404){
1479 $post_name = get_post($page_404);
1480 if(!empty($post_name)){
1481 $post_name = esc_attr($post_name->post_title);
1482 }
1483 }
1484 $out .= '<span class="themify_404_autocomplete_wrap">';
1485 $out .= '<input type="text" value="'.$post_name.'" id="themify_404_page_autocomplete" /><input type="hidden" name="setting-page_404" value="'.$page_404.'" />';
1486 $out .= '</span>';
1487 }
1488 else{
1489 $out.='<select name="setting-page_404">
1490 <option value="0">'.esc_attr( __( 'Select page', 'themify' ) ).'</option>';
1491 while ( $pages->have_posts() ) {
1492 $pages->the_post();
1493 $id = get_the_ID();
1494 if($id!=$front){
1495 $selected = '';
1496 if ( $page_404 == $id ) {
1497 $selected = 'selected="selected"';
1498 }
1499 $out .= '<option '.$selected.' value="' . $id . '">';
1500 $out .= get_the_title();
1501 $out .= '</option>';
1502 }
1503 }
1504 $out .= '</select>';
1505 }
1506 wp_reset_postdata();
1507 return $out;
1508 }
1509 }
1510
1511 ///////////////////////////////////////////
1512 // RSS Feed Settings Module
1513 ///////////////////////////////////////////
1514 function themify_feed_settings( $data = array() ) {
1515 $checked_use = '';
1516 $feed_settings = themify_get( 'setting-feed_settings','',true );
1517 $feed_custom_post = themify_get( 'setting-feed_custom_post','',true );
1518 $custom_posts = array_diff( get_post_types( array('public' => true, 'publicly_queryable' => 'true' ) )
1519 , array('attachment', 'tbuilder_layout', 'tbuilder_layout_part', 'section','tglobal_style') );
1520 $custom_posts_options = '<option></option>';
1521
1522 if ( 'on' === themify_get( 'setting-exclude_img_rss','',true ) ) {
1523 $checked_use = 'checked="checked"';
1524 }
1525
1526 if( ! empty( $custom_posts ) ) {
1527 array_unshift( $custom_posts, 'all' );
1528 $feed_custom_post_arr = explode( ',', trim( $feed_custom_post ) );
1529
1530 foreach( $custom_posts as $c_post ) {
1531 $custom_posts_options .= sprintf( '<option %s value="%s">%s</option>'
1532 , in_array( $c_post, $feed_custom_post_arr ) ? 'selected="selected"' : ''
1533 , $c_post
1534 , ucfirst( preg_replace( "/[-_]/", ' ', $c_post ) ) );
1535 }
1536 }
1537
1538 return '<p><span class="label">' . __('Feed Category', 'themify') .themify_help(__('Use minus sign (-) to exclude categories. <br/> Example: (2,-9) = include only Category 2 in feeds and exclude Category 9.', 'themify')) . '</span> <input type="text" class="width6" name="setting-feed_settings" value="' . esc_attr( $feed_settings ) . '" /></p>
1539 <p><span class="label">' . __('Post Image in RSS', 'themify') .themify_help(__('Check this to exclude post image in RSS feeds', 'themify')) . '</span> <label for="setting-exclude_img_rss"><input type="checkbox" id="setting-exclude_img_rss" name="setting-exclude_img_rss" '.$checked_use.'/> ' . __('Exclude featured image in RSS feeds', 'themify') . '</label></p>
1540 <p><span class="label">' . __('Custom Posts in RSS', 'themify') .themify_help(__( 'Select "All" to add all available posts in your feed or select the specific ones.', 'themify')) . '</span>
1541 <select size="6" multiple="multiple" class="width10 themify_multiselect">' . $custom_posts_options . '</select>
1542 <input type="hidden" name="setting-feed_custom_post" value="' . esc_attr( $feed_custom_post ) . '" />
1543 </p>';
1544 }
1545
1546 /**
1547 * Outputs Image Script module in theme settings.
1548 */
1549 function themify_img_settings( $data = array() ) {
1550 $feature_sizes = themify_get_image_sizes_list();
1551 $checked_use = '';
1552 $disable = '';
1553 $imaging_library = wp_image_editor_supports();
1554 $imaging_library_error = '';
1555 if ( ! $imaging_library || themify_is_image_script_disabled() ) {
1556 $checked_use = "checked='checked'";
1557 if ( ! $imaging_library ) {
1558 $disable = ' style="pointer-events: none;"';
1559 $imaging_library_error = '<div class="pushlabel themify_warning note">' . sprintf( __( 'This feature requires an <a href="%s">image processing library</a> to be installed on the server. Please contact your hosting provider to enable this.', 'themify' ), 'https://www.php.net/manual/en/refs.utilspec.image.php' ) . '</div>';
1560 }
1561 }
1562 $size = themify_get( 'setting-img_php_base_size', 'large',true );
1563 $global = themify_get( 'setting-global_feature_size','',true );
1564 $output = '
1565 <div class="module">
1566 <div class="themify-info-link">' . sprintf( __( 'The image script is used to generate featured images dynamically in any dimension. If your images are cropped manually, disable it for faster performance. For more info about the image script, refer to the <a href="%s">Image Script</a> documentation.', 'themify' ), 'https://themify.me/docs/image-script' ) . '
1567 </div>
1568 <fieldset>
1569 <div class="label">' . __( 'Disable', 'themify' ) .themify_help(__( 'Default WordPress image sizes or original images will be used.', 'themify' )) . '</div>
1570 <div class="row">
1571 <label for="setting-img_settings_use"' . $disable . '><input type="checkbox" id="setting-img_settings_use" name="setting-img_settings_use" class="disable_img_php" ' . $checked_use . '/> ' . __( 'Disable image script globally', 'themify' ) . '</label>
1572 ' . $imaging_library_error . '
1573 </div>
1574 <div class="show_if_enabled_img_php">
1575 <div class="label">' . __('Base Image Size', 'themify') .themify_help(__( 'Select the image size that image script will resize thumbnails from. If you\'re not sure, leave it as "Large". Note that this does not affect images already generated.', 'themify' )) . '</div>
1576 <div class="row">
1577 <select name="setting-img_php_base_size">';
1578 foreach ( $feature_sizes as $option ) {
1579 $selected = $option['value'] === $size?' selected="selected"':'';
1580 $output .= '<option'.$selected.' value="' . esc_attr( $option['value'] ) . '">' . $option['name'] . '</option>';
1581 }
1582 $output .= '
1583 </select>
1584 </div>
1585 </div>
1586 <div class="show_if_disabled_img_php">
1587 <div class="label">' . __('Default Featured Image Size', 'themify') . '</div>
1588 <div class="show_if_disabled_img_php row">
1589 <select name="setting-global_feature_size">';
1590 foreach ( $feature_sizes as $option ) {
1591 $selected = $option['value'] === $global?' selected="selected"':'';
1592 $output .= '<option'. $selected.' value="' . esc_attr( $option['value'] ) . '">' . $option['name'] . '</option>';
1593 }
1594 $output .= '
1595 </select>
1596 </div>
1597 </div>
1598 </fieldset>
1599
1600 </div>';
1601 return $output;
1602 }
1603
1604 /**
1605 * Outputs module for user to select whether to use a lightbox or not. The lightbox choices can be filtered using the 'themify_lightbox_module_options' filter in a custom-functions.php file.
1606 * @param array $data
1607 * @return string
1608 * @since 1.2.5
1609 */
1610 function themify_gallery_plugins( $data = array() ) {
1611
1612 $display_options = apply_filters('themify_lightbox_module_options', array(
1613 __( 'Enable', 'themify' ) => 'lightbox',
1614 __( 'Disable', 'themify' ) => 'none'
1615 ));
1616
1617 $gallery_lightbox = themify_get( 'setting-gallery_lightbox',null,true );
1618
1619 $out = '<p>
1620 <span class="label">' . __( 'WordPress Gallery', 'themify' ) . ' </span>
1621 <select class="gallery_lightbox_type" name="setting-gallery_lightbox">';
1622 foreach ( $display_options as $option => $value ) {
1623 $out .= '<option value="' . $value . '" '.selected( $value, $gallery_lightbox, false ).'>' . esc_html( $option ) . '</option>';
1624 }
1625 $out .= ' </select>
1626 </p>';
1627 $out .= '<p>
1628 <span class="pushlabel"><label for="setting-lightbox_disable_share">
1629 <input type="checkbox" id="setting-lightbox_disable_share" name="setting-lightbox_disable_share" '. checked( themify_get( 'setting-lightbox_disable_share',false,true ), 'on', false ) .'/> ' . __('Hide social share buttons on lightbox', 'themify') . '</label>
1630 </span>
1631 </p>';
1632 $out .= '<p>
1633 <span class="pushlabel"><label for="setting-lightbox_content_images">
1634 <input type="checkbox" id="setting-lightbox_content_images" name="setting-lightbox_content_images" '. checked( themify_get( 'setting-lightbox_content_images',false,true ), 'on', false ) .'/> ' . __('Apply lightbox to image links automatically', 'themify') . '</label>
1635 </span>
1636 <small class="pushlabel">'. __( 'All links to jpg, png, and gif will open in lightbox.', 'themify' ) .'</small>
1637 </p>';
1638 return $out;
1639 }
1640
1641 /**
1642 * Template to display a link in Links module, also used when creating a link.
1643 * @param array $data
1644 * @return string
1645 * @since 1.2.7
1646 */
1647 function themify_add_link_template( $fid, $data = array(), $ajax = false, $type = 'image-icon' ) {
1648 $pre = 'setting-link_';
1649
1650 $type_name = $pre.'type_'.$fid;
1651 if ( $ajax ) {
1652 $type_val = $type;
1653 } else {
1654 $type_val = isset($data[$type_name])? $data[$type_name] : 'image-icon';
1655 }
1656
1657 $title_name = $pre.'title_'.$fid;
1658 $title_val = isset($data[$title_name])? esc_attr(trim($data[$title_name])): '';
1659
1660 $link_name = $pre.'link_'.$fid;
1661 $link_val = isset($data[$link_name])? esc_attr(trim($data[$link_name])) : '';
1662
1663 $img_name = $pre.'img_'.$fid;
1664 $img_val = ! isset( $data[$img_name] ) || '' == $data[$img_name]? '' : esc_attr($data[$img_name]);
1665
1666 $ficon_name = $pre.'ficon_'.$fid;
1667 $ficon_val = trim( isset($data[$ficon_name])? esc_attr($data[$ficon_name]) : '' );
1668
1669 $ficolor_name = $pre.'ficolor_'.$fid;
1670 $ficolor_val = isset($data[$ficolor_name])? esc_attr($data[$ficolor_name]) : '';
1671
1672 $fibgcolor_name = $pre.'fibgcolor_'.$fid;
1673 $fibgcolor_val = isset($data[$fibgcolor_name])? esc_attr($data[$fibgcolor_name]) : '';
1674
1675 /**
1676 * TODO: Add appearance checkboxes
1677 */
1678
1679 $out = '<li id="' . $fid . '" class="social-link-item ' . $type_val . '">';
1680
1681 $out .= '<div class="social-drag">' . esc_html__('Drag to Sort', 'themify') . '<i class="ti-arrows-vertical"></i></div>';
1682
1683 $out .= '<input type="hidden" name="' . $type_name . '" value="' . trim( $type_val ) . '">';
1684
1685 $out .= '<div class="row">
1686 <span class="label">' . __( 'Title', 'themify' ) . '</span> <input type="text" name="' . $title_name. '" class="width6" value="' . $title_val . '">
1687 </div>
1688 <!-- /row -->';
1689
1690 $out .= '<div class="row">
1691 <span class="label">' . __( 'Link', 'themify' ) . '</span> <input type="text" name="' . $link_name . '" class="width10" value="' . $link_val . '">
1692 </div>
1693 <!-- /row -->';
1694
1695 if ( 'font-icon' === $type_val ) {
1696
1697 $out .= '<div class="row">
1698 <span class="label">' . __( 'Icon', 'themify' ) . '</span>';
1699
1700 $out .= sprintf('<input type="text" id="%s" name="%s" value="%s" size="55" class="themify_input_field themify_fa %s" /> <a class="button button-secondary hide-if-no-js themify_fa_toggle" href="#" data-target="#%s">%s</a>',
1701 $ficon_name, $ficon_name, $ficon_val, 'small', $ficon_name, __( 'Insert Icon', 'themify' ) );
1702
1703 $out .= '</div>
1704 <!-- /row -->';
1705
1706 $out .= '<div class="icon-preview font-icon-preview">
1707 <i>'.themify_get_icon( $ficon_val ).'</i>
1708 </div>
1709 <!-- /icon-preview -->';
1710
1711 $out .= '<div class="themify_field_row">
1712 <span class="label">' . __('Icon Color', 'themify') . '</span>
1713 <div class="themify_field-color">
1714 <input type="text" data-format="rgba" class="colorSelectInput width4" value="' . $ficolor_val. '" name="' . $ficolor_name . '" />
1715 </div>
1716 </div>';
1717
1718 $out .= '<div class="themify_field_row">
1719 <span class="label">' . __('Background', 'themify') . '</span>
1720 <div class="themify_field-color">
1721 <input type="text" data-format="rgba" class="colorSelectInput width4" value="' . $fibgcolor_val . '" name="' . $fibgcolor_name . '" />
1722 </div>
1723 </div>';
1724
1725 } else {
1726
1727 $out .= '<div class="row">
1728 <span class="label">' . __( 'Image', 'themify' ) . '</span>
1729 <div class="uploader-fields image">
1730 <input type="text" id="' . $img_name . '" name="' . $img_name. '" class="width10" value="' . $img_val. '">
1731 <div class="clear image">' . themify_get_uploader( $img_name, array( 'tomedia' => true, 'preview' => true ) ) . '</div>
1732 </div>
1733 </div>
1734 <!-- /row -->';
1735 $out .= '<div class="icon-preview">
1736 <img id="' . $img_name . '-preview" src="' . $img_val . '" loading="lazy" decoding="async" />
1737 </div>
1738 <!-- /icon-preview -->';
1739 }
1740
1741 $out .= '<a href="#" class="remove-item" data-removelink="' . $fid . '"><span class="tf_close"></span></a>
1742 </li>
1743 <!-- /social-links-item -->';
1744
1745 return $out;
1746 }
1747
1748 /**
1749 * Outputs module to manage links to be shown using the corresponding widget
1750 * @param array $data
1751 * @return string
1752 * @since 1.2.7
1753 */
1754 function themify_manage_links( $data = array() ) {
1755 $data = themify_get_data();
1756 $pre = 'setting-link_';
1757 $field_hash = !empty( $data[$pre.'field_hash'] )? (int)$data[$pre.'field_hash'] : 8;
1758 $start = array();
1759 for ( $i=0; $i < $field_hash; ++$i ) {
1760 $start['themify-link-'.$i] = 'themify-link-'.$i;
1761 }
1762 //$data[$pre.'field_ids'] = json_encode($start);
1763 $field_ids=themify_get( $pre.'field_ids',false,true );
1764 if ( $field_ids) {
1765 $field_ids=json_decode( $field_ids, true );
1766 if ( ! is_array( $field_ids ) ) {
1767 $field_ids = array();
1768 }
1769 } else {
1770 $field_ids = $start;
1771
1772 // Image Icons
1773
1774 $data[$pre.'type_themify-link-0'] = 'image-icon';
1775 $data[$pre.'type_themify-link-1'] = 'image-icon';
1776 $data[$pre.'type_themify-link-2'] = 'image-icon';
1777 $data[$pre.'type_themify-link-3'] = 'image-icon';
1778
1779 $data[$pre.'title_themify-link-0'] = 'Twitter';
1780 $data[$pre.'title_themify-link-1'] = 'Facebook';
1781 $data[$pre.'title_themify-link-2'] = 'YouTube';
1782 $data[$pre.'title_themify-link-3'] = 'Pinterest';
1783
1784 $data[$pre.'link_themify-link-0'] = '';
1785 $data[$pre.'link_themify-link-1'] = '';
1786 $data[$pre.'link_themify-link-2'] = '';
1787 $data[$pre.'link_themify-link-3'] = '';
1788
1789 $data[$pre.'img_themify-link-0'] = THEMIFY_URI . '/img/social/twitter.png';
1790 $data[$pre.'img_themify-link-1'] = THEMIFY_URI . '/img/social/facebook.png';
1791 $data[$pre.'img_themify-link-2'] = THEMIFY_URI . '/img/social/youtube.png';
1792 $data[$pre.'img_themify-link-3'] = THEMIFY_URI . '/img/social/pinterest.png';
1793
1794 // Font Icons
1795
1796 $data[$pre.'type_themify-link-4'] = 'font-icon';
1797 $data[$pre.'type_themify-link-5'] = 'font-icon';
1798 $data[$pre.'type_themify-link-6'] = 'font-icon';
1799 $data[$pre.'type_themify-link-7'] = 'font-icon';
1800
1801 $data[$pre.'title_themify-link-4'] = 'Twitter';
1802 $data[$pre.'title_themify-link-5'] = 'Facebook';
1803 $data[$pre.'title_themify-link-6'] = 'YouTube';
1804 $data[$pre.'title_themify-link-7'] = 'Pinterest';
1805
1806 $data[$pre.'link_themify-link-4'] = '';
1807 $data[$pre.'link_themify-link-5'] = '';
1808 $data[$pre.'link_themify-link-6'] = '';
1809 $data[$pre.'link_themify-link-7'] = '';
1810
1811 $data[$pre.'ficon_themify-link-4'] = 'fa-twitter';
1812 $data[$pre.'ficon_themify-link-5'] = 'fa-facebook';
1813 $data[$pre.'ficon_themify-link-6'] = 'fa-youtube';
1814 $data[$pre.'ficon_themify-link-7'] = 'fa-pinterest';
1815
1816 $data[$pre.'ficolor_themify-link-4'] = '';
1817 $data[$pre.'ficolor_themify-link-5'] = '';
1818 $data[$pre.'ficolor_themify-link-6'] = '';
1819 $data[$pre.'ficolor_themify-link-7'] = '';
1820
1821 $data[$pre.'fibgcolor_themify-link-4'] = '';
1822 $data[$pre.'fibgcolor_themify-link-5'] = '';
1823 $data[$pre.'fibgcolor_themify-link-6'] = '';
1824 $data[$pre.'fibgcolor_themify-link-7'] = '';
1825
1826 $data = apply_filters('themify_default_social_links', $data);
1827 }
1828
1829 $out = '<div class="themify-info-link">' . sprintf( __( 'To display the links: go to Appearance > <a href="%s">Widgets</a> and drop a Themify - Social Links widget in a widget area (<a href="%s" target="_blank" rel="noopener">learn more</a>)', 'themify' ), admin_url('widgets.php'), 'https://themify.me/docs/social-media-links') . '</div>';
1830
1831 $out .= '<div id="social-link-type">';
1832 // Icon Font
1833 $out .= '<label for="' . $pre . 'font_icon">';
1834 $out .= '<input ' . checked( isset( $data[$pre.'icon_type'] )? $data[$pre.'icon_type'] : 'font-icon', 'font-icon', false) . ' type="radio" id="' . $pre . 'font_icon" name="' . $pre . 'icon_type" value="font-icon" data-hide="image-icon" /> ';
1835 $out .= __( 'Icon Font', 'themify' ) . '</label>';
1836
1837 // Image
1838 $out .= '<label for="' . $pre . 'image_icon">';
1839 $out .= '<input ' . checked( isset( $data[$pre.'icon_type'] )? $data[$pre.'icon_type'] : '', 'image-icon', false ) . ' type="radio" id="' . $pre . 'image_icon" name="' . $pre . 'icon_type" value="image-icon" data-hide="font-icon" /> ';
1840 $out .= __( 'Image', 'themify' ) . '</label>';
1841 $out .= '</p>';
1842
1843 $out .= '<ul id="social-links-wrapper">';
1844 foreach ( $field_ids as $fid ) {
1845 $out .= themify_add_link_template( $fid, $data );
1846 }
1847 $out .= '</ul>';
1848
1849 $out .= '<p class="add-link add-social-link"><a href="#">' . __('Add Link', 'themify') . '</a></p>';
1850
1851 $out .= '<input type="hidden" id="' . $pre . 'field_ids" name="' . $pre . 'field_ids" value=\'' . json_encode( $field_ids ) . '\'/>';
1852 $out .= '<input type="hidden" id="' . $pre . 'field_hash" name="' . $pre . 'field_hash" value="' . esc_attr( $field_hash ) . '"/>';
1853 //$out .= '<p>Fields: '.json_encode($field_ids).'</p><p>Hash: '.$field_hash.'</p>';
1854
1855 return $out;
1856 }
1857
1858 /**
1859 * Outputs post meta options
1860 * @param string $pmkey Key used to get data from theme settings array
1861 * @param array $data Theme settings data
1862 * @param array $metas Optional array stating the metas available.
1863 * @return string $out Markup for options
1864 */
1865 function themify_post_meta_options( $pmkey, $data, $metas = array(), $states = array(), $group_label = false ) {
1866
1867 if ( empty($metas ) ) {
1868 $metas = array (
1869 '' => __( 'Hide All', 'themify' ),
1870 'author' => __( 'Author', 'themify' ),
1871 'category' => __( 'Category', 'themify' ),
1872 'comment' => __( 'Comment', 'themify' ),
1873 'tag' => __( 'Tag', 'themify' )
1874 );
1875 }
1876 if ( empty( $states ) ) {
1877 $states = array(
1878 array(
1879 'name' => __( 'Hide', 'themify' ),
1880 'value' => 'yes',
1881 'icon' => THEMIFY_URI . '/img/ddbtn-cross.svg',
1882 'title' => __( 'Hide this meta', 'themify' )
1883 ),
1884 array(
1885 'name' => __( 'Show', 'themify' ),
1886 'value' => 'no',
1887 'icon' => THEMIFY_URI . '/img/ddbtn-check.svg',
1888 'title' => __( 'Show this meta', 'themify' )
1889 )
1890 );
1891 }
1892 if ( ! $group_label ) {
1893 $group_label = __( 'Post Meta', 'themify' );
1894 }
1895
1896 $default = array(
1897 'name' => __( 'Theme', 'themify' ),
1898 'value' => '',
1899 'icon' => THEMIFY_URI . '/img/ddbtn-blank.png',
1900 'title' => esc_attr(__( 'Use theme settings', 'themify' ))
1901 );
1902
1903 $out = '<div class="themify_field_row dropdownbutton-group"><span class="label">' . esc_html( $group_label ) . '</span>';
1904
1905 foreach ( $metas as $meta => $name ) {
1906 if ( '' == $meta ) {
1907 $metakey = $pmkey;
1908 $meta_class = 'ddbtn-all';
1909 } else {
1910 $metakey = $pmkey.'_'.$meta;
1911 $meta_class = 'ddbtn-sub ddbtn-'.$meta;
1912 }
1913 $name=esc_html( $name );
1914 $others = '';
1915 $out .= '<div id="' . $metakey. '" class="dropdownbutton-list" data-name="' . $name . '" data-def-icon="' . $default['icon']. '">';
1916
1917 // default state
1918 $first = '
1919 <div class="first-ddbtn">
1920 <a href="#" data-val="' . $default['value'] . '" data-name="' . $default['name'] . '" title="' . $default['title'] . '">
1921 <img src="' . $default['icon'] . '" title="' . $default['title'] . '" loading="lazy" decoding="async" />
1922 <span class="ddbtn-name">' . $name . '</span>
1923 </a>
1924 </div>';
1925
1926 foreach ( $states as $state ) {
1927 $title=esc_attr($state['title']);
1928 if ( isset( $state['value'] ) && isset( $data[$metakey] ) && $state['value'] === $data[$metakey] ) {
1929 $first = '<div class="first-ddbtn">
1930 <a href="#" data-val="' . $state['value'] . '" data-name="' . $state['name'] . '" title="' . $title. '">
1931 <img src="' . $state['icon']. '" title="' . $title . '" loading="lazy" decoding="async" />
1932 <span class="ddbtn-name">' . $name . '</span>
1933 </a>
1934 </div>';
1935 $selected = 'selected';
1936 } else {
1937 $selected = '';
1938 }
1939
1940 $others .= '
1941 <div class="ddbtn">
1942 <a href="#" data-sel="' . $selected. '" data-val="' . $state['value'] . '" data-name="' . $state['name'] . '" title="' . $title . '">
1943 <img src="' . $state['icon'] . '" title="' . $title. '" loading="lazy" decoding="async" />
1944 <span class="ddbtn-label">' . esc_html( $state['name'] ) . '</span>
1945 </a>
1946 </div>';
1947 }
1948 $out .= $first . '<div class="dropdownbutton">' . $others . '</div>';
1949 $out .= '
1950 </div>';
1951 $out .= '<input type="hidden" value="' . esc_attr( themify_get( $metakey ) ) . '" class="' . $meta_class. '" id="' . $metakey . '" name="' . $metakey . '" />';
1952 }
1953
1954 $out .= '</div>';
1955 return $out;
1956 }
1957
1958 /**
1959 * Outputs post sorting options
1960 * @param string $key Key used to get data from theme settings array
1961 * @param array $data Theme settings data
1962 * @return string $out Markup for options
1963 */
1964 if ( ! function_exists( 'themify_post_sorting_options' ) ) {
1965 function themify_post_sorting_options( $key = 'setting-index_order', $data = array() ) {
1966
1967 $orderby = themify_get( $key . 'by','');
1968 $orderby_options = apply_filters( 'themify_index_orderby_options', array(
1969 __( 'Date (default)', 'themify' ) => 'date',
1970 __( 'Random', 'themify' ) => 'rand',
1971 __( 'Author', 'themify' ) => 'author',
1972 __( 'Post Title', 'themify' ) => 'title',
1973 __( 'Comments Number', 'themify' ) => 'comment_count',
1974 __( 'Modified Date', 'themify' ) => 'modified',
1975 __( 'Post Slug', 'themify' ) => 'name',
1976 __( 'Post ID', 'themify' ) => 'ID',
1977 __( 'Custom Field String', 'themify' ) => 'meta_value',
1978 __( 'Custom Field Numeric', 'themify' ) => 'meta_value_num' ) );
1979
1980 $order = themify_get( $key,'');
1981 $order_options = array(
1982 __( 'Descending (default)', 'themify' ) => 'DESC',
1983 __( 'Ascending', 'themify' ) => 'ASC' );
1984
1985 $order_meta_key = 'setting-index_meta_key';
1986
1987 $out = '<p><span class="label">' . __( 'Order By', 'themify' ) . ' </span>
1988 <select name="' .$key . 'by">';
1989 foreach ( $orderby_options as $option => $value ) {
1990 $out .= '<option value="' . esc_attr( $value ) . '" '.selected( $value, $orderby, false ).'>' . esc_html( $option ) . '</option>';
1991 }
1992 $out .= ' </select>
1993 </p>
1994 <p data-show-if-element="[name=' . $key . 'by]" data-show-if-value=\'["meta_value", "meta_value_num"]\'>
1995 <span class="label">' . __( 'Custom Field Key', 'themify' ) . ' </span>
1996 <input type="text" id="' . $order_meta_key . '" name="' . $order_meta_key . '" value="' . esc_attr( themify_get( $order_meta_key,'',true ) ) . '" />
1997 </p>
1998 <p>
1999 <span class="label">' . __( 'Order', 'themify' ) . ' </span>
2000 <select name="' . $key. '">';
2001 foreach ( $order_options as $option => $value ) {
2002 $out .= '<option value="' . esc_attr( $value ) . '" '.selected( $value, $order, false ).'>' . esc_html( $option ) . '</option>';
2003 }
2004 $out .= ' </select>
2005 </p>';
2006
2007 return $out;
2008 }
2009 }
2010
2011 if ( ! function_exists( 'themify_homepage_welcome' ) ) {
2012 /**
2013 * Homepage Welcome Function
2014 * @return string Markup for welcome text control
2015 */
2016 function themify_homepage_welcome() {
2017 return '<p><textarea class="widthfull" name="setting-homepage_welcome" rows="4">' . esc_textarea( themify_get( 'setting-homepage_welcome','',true ) ) . '</textarea></p>';
2018 }
2019 }
2020
2021 if ( ! function_exists( 'themify_exclude_rss' ) ) {
2022 /**
2023 * Exclude RSS
2024 * @return string
2025 */
2026 function themify_exclude_rss() {
2027 return '<p><label for="setting-exclude_rss"><input type="checkbox" id="setting-exclude_rss" name="setting-exclude_rss" ' . checked( themify_get( 'setting-exclude_rss','',true ), 'on', false ) . '/> ' . __( 'Check here to exclude RSS icon/button in the header', 'themify' ) . '</label></p>';
2028 }
2029 }
2030
2031 if ( ! function_exists( 'themify_exclude_search_form' ) ) {
2032 /**
2033 * Exclude Search Form
2034 * @return string
2035 */
2036 function themify_exclude_search_form() {
2037 return '<p><label for="setting-exclude_search_form"><input type="checkbox" id="setting-exclude_search_form" name="setting-exclude_search_form" ' . checked( themify_get( 'setting-exclude_search_form','',true ), 'on', false ) . '/> ' . __( 'Check here to exclude search form in the header', 'themify' ) . '</label></p>';
2038 }
2039 }
2040
2041 if( ! function_exists( 'footer_text_settings' ) ) {
2042 /**
2043 * Footer Text Settings
2044 * @return string
2045 */
2046 function footer_text_settings() {
2047 return '<div class="themify-info-link">' . __( 'Enter your text to replace the copyright and credit links in the footer. HTML tags allowed. Type %year% to display the current year.', 'themify' ) . '</div>' . themify_footer_text_left() . themify_footer_text_right();
2048 }
2049 }
2050
2051 if ( ! function_exists( 'themify_footer_text_left' ) ) {
2052 /**
2053 * Footer Text Left Function
2054 * @return string
2055 */
2056 function themify_footer_text_left() {
2057 return '<h4>' . __('Footer Text One', 'themify') . '</h4><div data-show-if-element="[name=setting-footer_text_left_hide]" data-show-if-value="false"><textarea class="widthfull" rows="4" name="setting-footer_text_left">' . esc_textarea( themify_get( 'setting-footer_text_left','',true ) ) . '</textarea></div><div><label><input type="checkbox" name="setting-footer_text_left_hide" value="hide" ' . checked( themify_get( 'setting-footer_text_left_hide','',true ), 'hide', false ) . ' />' . __( 'Hide Footer Text One', 'themify' ) . '</label></div>';
2058 }
2059 }
2060
2061 if ( ! function_exists( 'themify_footer_text_right' ) ) {
2062 /**
2063 * Footer Text Right Function
2064 * @return string
2065 */
2066 function themify_footer_text_right(){
2067 return '<h4>' . __('Footer Text Two', 'themify') . '</h4><div data-show-if-element="[name=setting-footer_text_right_hide]" data-show-if-value="false"><textarea class="widthfull" rows="4" name="setting-footer_text_right">' . esc_textarea( themify_get( 'setting-footer_text_right','',true ) ) . '</textarea></div><div><label><input type="checkbox" name="setting-footer_text_right_hide" value="hide" ' . checked( themify_get( 'setting-footer_text_right_hide','',true ), 'hide', false ) . ' />' . __( 'Hide Footer Text Two', 'themify' ) . '</label></div>';
2068 }
2069 }
2070
2071 if(!function_exists('themify_homepage_widgets')){
2072 /**
2073 * Widgets module function
2074 * @return string Module markup
2075 */
2076 function themify_homepage_widgets(){
2077 $val = themify_get( 'setting-homepage_widgets',false,true );
2078 $options = array(
2079 array(
2080 'value' => 'homewidget-4col',
2081 'img' => 'themify/img/sidebars/4col.png',
2082 'title' => __('Widgets 4 Columns', 'themify')),
2083 array(
2084 'value' => 'homewidget-3col',
2085 'img' => 'themify/img/sidebars/3col.png',
2086 'title' => __('Widgets 3 Columns', 'themify'),
2087 'selected' => true),
2088 array(
2089 'value' => 'homewidget-2col',
2090 'img' => 'themify/img/sidebars/2col.png',
2091 'title' => __('Widgets 3 Columns', 'themify')),
2092 array(
2093 'value' => 'homewidget-1col',
2094 'img' => 'themify/img/sidebars/1col.png',
2095 'title' => __('Widgets 1 Column', 'themify')),
2096 array(
2097 'value' => 'none',
2098 'img' => 'themify/img/sidebars/none.png',
2099 'title' => __('No Widgets', 'themify'))
2100 );
2101 $output = '';
2102 foreach($options as $option){
2103 if(!$val && !empty($option['selected'])){
2104 $val = $option['value'];
2105 }
2106 $class = $val === $option['value']?' selected':'';
2107 $output .= '<a href="#" class="preview-icon' . $class . '" title="' . esc_attr( $option['title'] ) . '"><img src="' . THEME_URI.'/'.$option['img']. '" alt="' . esc_attr( $option['value'] ) . '" loading="lazy" decoding="async" width="46" height="35"/></a>';
2108 }
2109 $output .= '<input type="hidden" name="setting-homepage_widgets" class="val" value="' . esc_attr( $val ) . '" />';
2110 return $output;
2111 }
2112 }
2113
2114 if(!function_exists('themify_footer_widgets')){
2115 /**
2116 * Widgets module function
2117 * @return string Module markup
2118 */
2119 function themify_footer_widgets(){
2120 $val = themify_get( 'setting-footer_widgets',false,true );
2121 $options = array(
2122 array(
2123 'value' => 'footerwidget-4col',
2124 'img' => 'themify/img/sidebars/4col.png',
2125 'title' => __('Widgets 4 Columns', 'themify')),
2126 array(
2127 'value' => 'footerwidget-3col',
2128 'img' => 'themify/img/sidebars/3col.png',
2129 'title' => __('Widgets 3 Columns', 'themify'),
2130 'selected' => true),
2131 array(
2132 'value' => 'footerwidget-2col',
2133 'img' => 'themify/img/sidebars/2col.png',
2134 'title' => __('Widgets 2 Columns', 'themify')),
2135 array(
2136 'value' => 'footerwidget-1col',
2137 'img' => 'themify/img/sidebars/1col.png',
2138 'title' => __('Widgets 1 Column', 'themify')),
2139 array(
2140 'value' => 'none',
2141 'img' => 'themify/img/sidebars/none.png',
2142 'title' => __('No Widgets', 'themify'))
2143 );
2144 $output = '';
2145 foreach($options as $option){
2146 if(!$val &&!empty($option['selected'])){
2147 $val = $option['value'];
2148 }
2149 $class = $val === $option['value']?' selected':'';
2150 $output .= '<a href="#" class="preview-icon' . $class. '" title="' . esc_attr( $option['title'] ) . '"><img src="' . THEME_URI.'/'.$option['img']. '" alt="' . esc_attr( $option['value'] ) . '" loading="lazy" decoding="async" width="46" height="35" /></a>';
2151 }
2152 $output .= '<input type="hidden" name="setting-footer_widgets" class="val" value="' . esc_attr( $val ) . '" />';
2153 return $output;
2154 }
2155 }
2156
2157 if ( ! function_exists( 'themify_entries_navigation' ) ) {
2158 /**
2159 * Display module to select numbered pagination or links to previous and next posts.
2160 * @param array $data
2161 * @return string $html Module markup.
2162 * @since 1.6.0
2163 */
2164 function themify_entries_navigation( $data = array() ) {
2165 $key = 'setting-entries_nav';
2166 $v= themify_get( $key,'numbered',true );
2167 $html = '<p>';
2168 // Numbered pagination
2169 $html .= '<label for="' . $key . '_numbered">';
2170 $html .= '<input ' . checked( $v, 'numbered', false) . ' type="radio" id="' . $key . '_numbered" name="' . $key . '" value="numbered" /> ';
2171 $html .= __( 'Numbered Pagination (page 1, 2, 3, etc.)', 'themify' ) . '</label>';
2172 $html .= '<br/>';
2173
2174 // Previous / Next links
2175 $html .= '<label for="' . $key . '_prevnext">';
2176 $html .= '<input ' . checked( $v, 'prevnext', false ) . ' type="radio" id="' . $key . '_prevnext" name="' . $key . '" value="prevnext" /> ';
2177 $html .= __( 'Previous Posts and Next Posts Links', 'themify' ) . '</label>';
2178 $html .= '</p>';
2179 return $html;
2180 }
2181 }
2182
2183
2184 /**
2185 * Renders Accessibility options
2186 *
2187 * @return string
2188 */
2189 function themify_accessibility_options( $data = array() ) {
2190 $key = 'setting-acc_';
2191 $out = '<p>
2192 <span class="label">' . __( 'Link Focus Outline', 'themify' ) . '</span>
2193 <select name="' . $key.'lfo' . '">' . themify_options_module( array(
2194 array( 'name' => __( 'Light', 'themify' ), 'value' => '' ),
2195 array( 'name' => __( 'Heavy', 'themify' ), 'value' => 'h' ),
2196 array( 'name' => __( 'None', 'themify' ), 'value' => 'n' )
2197 ), $key.'lfo' ) . '
2198 </select>
2199 </p>';
2200 $out .= '<p>
2201 <span class="label">' . __( 'General Font Size', 'themify' ) . '</span>
2202 <select name="' . $key.'fs' . '">' . themify_options_module( array(
2203 array( 'name' => __( 'Normal', 'themify' ), 'value' => '' ),
2204 array( 'name' => __( 'Large', 'themify' ), 'value' => 'l' ),
2205 ), $key . 'fs' ) . '
2206 </select>
2207 </p>';
2208 return $out;
2209 }
2210
2211 /**
2212 * Render the input field to allow uploading font packages
2213 *
2214 * @return string
2215 */
2216 function themify_fontello_input_callback( $data = array() ) {
2217 return '
2218 <div class="themify_field_row">
2219 <span class="label">'. __('Fontello Icon Package', 'themify') . '</span>
2220 <input id="setting-fontello" type="text" class="width10" name="setting-fontello" value="' . esc_attr( themify_get( 'setting-fontello','',true ) ) . '" /> <br />
2221 <div class="pushlabel" style="display:block;">
2222 <div class="themify_medialib_wrapper">
2223 <a href="#" class="themify-media-lib-browse" data-submit=\'' . json_encode( array( 'action' => 'themify_handle_fontello_upload', 'field_name' => 'setting-fontello' ) ) . '\' data-uploader-title="' . __( 'Upload package', 'themify' ) .'" data-uploader-button-text="'. __( 'Upload package', 'themify' ) .'" data-fields="setting-fontello" data-type="application/zip">'. __( 'Browse Library', 'themify' ) . '</a>
2224 </div>
2225 <small class="description">' . __( 'Go to <a target="_blank" rel="noopener" href="http://fontello.com">fontello.com</a>, pick your icons, download the webfont zip, upload and insert the zip URL here. The icon package will be auto detected on Themify\'s icon library where you click "Insert Icon".', 'themify' ) . '</small>
2226 <small class="description">' . sprintf( __( '<a href="%s">Full Tutorial</a>' ), 'https://themify.me/blog/how-to-add-custom-icon-fonts' ) . '</small>
2227 </div>
2228 </div>';
2229 }
2230
2231 if(!function_exists('themify_performance_settings')) {
2232 /**
2233 * Script Minification Settings
2234 * @param array Themify data
2235 * @return string Module markup
2236 * @since 1.3.9
2237 */
2238 function themify_performance_settings($data = array()){
2239 $server=themify_get_server();
2240 $htaccess_file=$server==='nginx'?null:Themify_Enqueue_Assets::getHtaccessFile();
2241 $isMultiSite=is_multisite();
2242 $cache_dir=TFCache::get_wp_content_dir();
2243 if ($htaccess_file!==null && Themify_Filesystem::is_file($htaccess_file) && Themify_Filesystem::is_writable($htaccess_file)) {
2244 $message= sprintf(__('Enabling Gzip will add code to your .htaccess file (%s)','themify'),$htaccess_file);
2245 $gzip=themify_check( 'setting-cache_gzip',true );
2246 $browser_cache=themify_check( 'setting-cache_browser',true );
2247 }
2248 else{
2249 $message= $server!=='apache'?sprintf(__('It looks like you are using Nginx server. Please <a href="%s" target="_blank" rel="noopener">follow</a> this tutorial to enable this feature.','themify'),'https://themify.me/docs/enable-gzip-nginx-servers'):sprintf(__('The htaccess file %s isn`t writable. Please allow to write to enable this feauture','themify'),$htaccess_file);
2250 $gzip=$browser_cache=null;
2251 }
2252 $cache_plugins=false!==TFCache::get_cache_plugins();
2253 $menuCache='data-show-if-element="[name$=setting-cache-html]" data-show-if-value="false"';
2254 $warning=$tmp='';
2255 if($cache_plugins===true){
2256 $menuCache='style="display:none"';
2257 $warning=__('Themify Cache can not be enabled due to another cache plugin is activated.','themify');
2258 }
2259 elseif(!Themify_Filesystem::is_writable($cache_dir)){
2260 $warning=sprintf(__('The directory %s isn`t writable. Please allow to write to enable this feauture','themify'),$cache_dir);
2261 }
2262 elseif(!WP_CACHE){
2263 $tmp='<div class="pushlabel themify_warning note">'.__('WP_CACHE is not enabled. Please enable it on wp-config.php file. ','themify');
2264 $tmp.=' <a href="https://wordpress.org/support/article/editing-wp-config-php/#cache" target="_blank" rel="noopener">'.__('Read details','themify').'</a>.';
2265 if(Themify_Filesystem::is_writable(ABSPATH . 'wp-config.php' )){
2266 $tmp.='<br/><br/><a href="#" data-action="themify_write_config" data-send="all" data-clearing-text="'.__('Writing...','themify').'" data-done-text="'.__('Done','themify').'" data-default-text="'.__('Try to fix it','themify').'" data-default-icon="ti-eraser" class="button button-outline js-clear-cache"> <span>'.__('Try to fix it','themify').'</span></a>';
2267 }
2268 $tmp.='</div>';
2269 }
2270
2271
2272 $ignore_cache=array(
2273 'is_single'=>__('Exclude Single Posts','themify'),
2274 'is_page'=>__('Exclude Pages','themify'),
2275 'is_front_page'=>__('Exclude Front Page','themify'),
2276 'is_home'=>__('Exclude Home','themify'),
2277 'is_archives'=>__('Exclude Archives','themify'),
2278 'is_tags'=>__('Exclude Tags','themify'),
2279 'is_category'=>__('Exclude Category','themify'),
2280 'is_feed'=>__('Exclude Feeds','themify'),
2281 'is_author'=>__('Exclude Author Pages','themify')
2282 );
2283 if(themify_is_woocommerce_active()){
2284 $ignore_cache['is_shop']=__('Exclude Shop Page','themify');
2285 $ignore_cache['is_product']=__('Exclude Single Products','themify');
2286 $ignore_cache['is_product_category']=__('Exclude Product Categories','themify');
2287 $ignore_cache['is_product_tag']=__('Exclude Product Tags','themify');
2288 }
2289 $key='setting-cache-live';
2290 $tmp.='<p><span class="label">' . __( 'Cache Expires', 'themify' ) . '</span><label class="pushlabel"><input type="text" name="'.$key.'" value="'.themify_get($key,(WEEK_IN_SECONDS/60),true).'" class="width4"> '.__('Minutes (default 1 week)','themify').'</label></p>';
2291
2292 $key='setting-cache-ignore';
2293 $tmp.='<span class="label">' . __( 'Exclude Caching On', 'themify' ) . '</span><div class="pushlabel">';
2294 foreach($ignore_cache as $k=>$v){
2295 $tmp.='<label>';
2296 $tmp.='<input type="checkbox" value="'.$k.'" id="'.$key.'" name="'.$key.'_'.$k.'" '. checked( themify_check($key.'_'.$k,true ),true,false ) .'/> ' . $v . '</label>';
2297 $tmp.='</label><br/>';
2298 }
2299 $tmp.='</div>';
2300 $ignore_cache=null;
2301 $pageCache=$warning==='' && Themify_Filesystem::is_file(TFCache::get_cache_config_file());
2302 $key = 'setting-disable-lazy';
2303 $output='<div>
2304 <div class="themify-info-link">To maximize your pagespeeed performance, please follow <a href="https://themify.me/blog/get-90-score-google-pagespeed-insights" target="_blank">this tutorial</a> to setup your theme and content.</div>
2305 <span class="label">' . __( 'Themify Lazy Load', 'themify' ) .themify_help(__('Lazy load can speed up pagespeed by loading media (image, audio, video, iframe, etc.) when they are visible in the viewport.','themify')) . '</span>';
2306
2307 $output.='<label for="'.$key.'"><input type="checkbox" id="'.$key.'" name="'.$key.'" '. checked( themify_check($key,true ),true, false ) .'/> ' . __('Disable lazy load', 'themify') . '</label><br/>';
2308
2309 $output.='<div data-show-if-element="[name$='.$key.']" data-show-if-value="false" class="tf_clearfix">';
2310 $output .= sprintf( '<div class="label">%s</div><div class="label input-range width10"><div class="range-slider width8"></div><input type="text" name="%s" value="%s" data-min="0" data-max="100" data-default-min="0" data-default-max="100" class="width4" readonly> px</div>',
2311 esc_html__( 'Blur Image', 'themify' ),
2312 'setting-lazy-blur',
2313 themify_get('setting-lazy-blur',25,true )
2314 );
2315 $output.='</div>';
2316
2317 $output.='<div data-show-if-element="[name$='.$key.']" data-show-if-value="false" class="tf_clearfix">';
2318 $output .= sprintf( '<div class="label">%s %s</div><div class="label width10"><input type="number" name="%s" value="%s" min="0" max="2000" class="width4"> px</div>',
2319 esc_html__( 'LazyLoad Threshold', 'themify' ),
2320 themify_help(__('Distance from viewport before content are loaded in. Recommendation: 300px to 500px.','themify')),
2321 'setting-lazy-threshold',
2322 themify_get('setting-lazy-threshold', 300, true )
2323 );
2324 $output.='</div>';
2325
2326 $key = 'setting-dev-mode';
2327 $disabled = defined( 'THEMIFY_DEV' ) && THEMIFY_DEV ? ' disabled' : '';
2328 $output.='<hr><p><span class="label">' . __( 'Development Mode', 'themify' ) .themify_help(__('Warning: the following will be disabled: Themify cache, menu cache, concate CSS caching, Gzip scripts. Only enable this for development purposes (eg. preview child theme CSS/script changes).','themify')) . '</span>';
2329
2330 $output.='<label for="'.$key.'"><input type="checkbox"' . $disabled . ' id="'.$key.'" name="'.$key.'" '. checked(themify_check($key,true ),true, false ) .'/> ' . __('Enable development mode', 'themify') . '</label><br/>';
2331 if ( $disabled ) {
2332 $output .= '<p class="description">' . __( 'This option is being overriden due to THEMIFY_DEV constant being defined. Try checking wp-config.php.', 'themify' ) . '</p>';
2333 }
2334 unset( $disabled );
2335
2336 $output.='<span data-show-if-element="[name$='.$key.']" data-show-if-value="true">';
2337
2338 $output.='<label for="'.$key.'-concate" class="pushlabel"><input type="checkbox" id="'.$key.'-concate" name="'.$key.'-concate" '. checked(themify_check($key.'-concate',true ),true, false ) .'/> ' . __('Disable Concate CSS in development mode', 'themify') . '</label><br/>';
2339
2340 $output.='<span class="themify_warning">'.__('Warning: the following will be disabled: Themify cache, menu cache, concate CSS caching, Gzip scripts. Only enable this for development purposes (eg. preview child theme CSS/script changes).','themify').'</span></span>';
2341
2342 $output.='</p>';
2343 $output.='<div data-show-if-element="[name$='.$key.']" data-show-if-value="false">';//dev mode
2344
2345 $key = 'setting-cache-html';
2346 $output.='<hr><p>
2347 <span class="label">' . __( 'Themify Cache', 'themify' ) .themify_help(__('Caching can reduce page size and server responses (only frontend public viewing will be cached). Themify Cache can not be used with third party cache plugins to avoid conflicts.','themify')) . '</span>
2348 <label for="'.$key.'"'.($warning!==''?' class="themify_field_disable"':'').'><input type="checkbox"'.($warning!==''?' disabled="disabled"':'').' id="'.$key.'" name="'.$key.'" '. checked( ($pageCache===true ?themify_check($key,true ):false),true,false ) .'/> ' . __('Enable Themify Cache (recommended)', 'themify') . '</label>
2349 <small class="pushlabel'.($warning!==''?' themify_warning':'').'" style="margin:20px 0;">'.$warning.'</small></p>';
2350
2351 $output.='<div data-show-if-element="[name$='.$key.']" data-show-if-value="true">
2352 '.$tmp.'
2353 <span class="label">'. __( 'Excluding Caching URLs', 'themify' ) .'</span>
2354 <div class="pushlabel">
2355 <textarea class="widthfull" rows="5" name="setting-cache-rule" id="setting-cache-rule">'. esc_html( themify_get( 'setting-cache-rule','',true ) ).'</textarea>'
2356 .'<small>'.__('Enter the URLs to exclude caching (supports regular expressions). Separate each rule with a line break.','themify').'</small>';
2357 $output.='<br/><br/><a href="#" data-action="themify_clear_all_html" data-send="all" data-clearing-text="'.__('Clearing...','themify').'" data-done-text="'.__('Done','themify').'" data-default-text="'.__('Clear Themify Cache','themify').'" data-default-icon="ti-eraser" class="button button-outline js-clear-cache"><i class="ti-eraser"></i> <span>'.__('Clear Themify Cache','themify').'</span></a>';
2358 if($isMultiSite){
2359 $output.='<br/><label><input type="checkbox" value="1" id="tmp_cache_network" name="tmp_cache_network"/>'.__('Clear all network sites','themify').'</label>';
2360 }
2361 $output.='</div></div>';
2362 $tmp=null;
2363 $output.='<hr><p>
2364 <span class="label">' . __( 'Browser Caching', 'themify' ) .themify_help(__("Cache static assets (CSS, JS, images, etc.) on user's browser. HTML is not cached",'themify')) . '</span>
2365 <label for="setting-cache_browser"'.($browser_cache===null?' class="themify_field_disable"':'').'><input type="checkbox"'.($browser_cache===null?' disabled="disabled"':'').'id="setting-cache_browser" name="setting-cache_browser" '.checked( $browser_cache, true, false ).'/> ' . __('Enable Browser Caching (recommended)', 'themify').'</label>
2366 </p>';
2367 $output.='<hr><p>
2368 <span class="label">' . __( 'Gzip Scripts', 'themify' ) .themify_help(__('Using Gzip version of scripts can reduce script file size by 60-80%.','themify')) . '</span>
2369 <label for="setting-cache_gzip"'.($gzip===null?' class="themify_field_disable"':'').'><input type="checkbox"'.($gzip===null?' disabled="disabled"':'').'id="setting-cache_gzip" name="setting-cache_gzip" '.checked( $gzip, true, false ).'/> ' . __('Enable Gzip scripts (recommended)', 'themify').'</label>
2370 <small class="pushlabel'.($gzip===null?' themify_warning':'').'" >'.$message.'</small>
2371 </p>';
2372 if ( ! wp_image_editor_supports() ) {
2373 $message=__('The GD library or Imagick extensions are not installed. Ask your host provider to enable them to use this feature.','themify');
2374 $webp=null;
2375 }
2376 else{
2377 $message='';
2378 $webp=themify_check( 'setting-webp',true );
2379 if ( $server === 'litespeed' ) {
2380 $message = sprintf( __( 'It looks like you are using LiteSpeed server. Please follow <a href="%s" target="_blank" rel="noopener">this tutorial</a> to enable WebP images on your server.', 'themify' ), 'https://docs.litespeedtech.com/lscache/lscwp/imageopt/' );
2381 $webp = null;
2382 } else if ( $server !== 'apache' ) {
2383 $message=sprintf(__('It looks like you are using %s server. Please <a href="%s" target="_blank" rel="noopener">follow</a> this tutorial to enable this feature.','themify'), ucfirst($server),'https://themify.me/docs/enable-webp-nginx-servers');
2384 }
2385 }
2386 $webp_quality = (int) themify_get( 'setting-webp-quality', '5', true );
2387 $output.='</p>';
2388 $key='setting-disable-concate-css';
2389 $output.='<hr><p>
2390 <span class="label">' . __( 'Concate CSS', 'themify' ) . themify_help(__('Concate CSS combines all CSS files to reduce HTTP requests. Do not disable it unless your cache or optimization plugin requires separate files.','themify')) . '</span>
2391 <a href="#" data-action="themify_clear_all_concate" data-send="all" data-clearing-text="'.__('Clearing...','themify').'" data-done-text="'.__('Done','themify').'" data-default-text="'.__('Clear Concate & Builder CSS Cache','themify').'" data-default-icon="ti-eraser" class="button button-outline js-clear-cache"><i class="ti-eraser"></i> <span>'.__('Clear Concate & Builder CSS Cache','themify').'</span></a>
2392 ';
2393 if(!Themify_Enqueue_Assets::createDir()){
2394 $output.='<span class="pushlabel themify_warning">'.__('It looks like the WordPress upload folder path is set wrong or have file permission issue. Please check the upload path on WP Settings > Media. Make sure the folder is set correctly and it has correct file permission.','themify').'</span>';
2395 }
2396 elseif($isMultiSite){
2397 $output.='<br/><label class="pushlabel"><input type="checkbox" value="1" id="tmp_cache_concte_network" name="tmp_cache_concte_network"/>'.__('Clear Concate cache in the whole network site','themify').'</label>';
2398 }
2399 $output.='<br/><label for="'.$key.'" class="pushlabel"><input type="checkbox" id="'.$key.'" name="'.$key.'" '. checked(themify_check($key,true),true,false ) .'/> ' . __('Disable Concate CSS', 'themify') . '</label>
2400 <small class="pushlabel">'.__('Concate CSS combines all CSS files to reduce HTTP requests. Do not disable it unless your cache or optimization plugin requires separate files. Disabling it may cause a brief styling delay while individual CSS files load.','themify').'</small>';
2401 $output.='</p>';
2402 $key='setting-cache-menu';
2403 $output.='<div '.$menuCache.'><hr><p>
2404 <span class="label">' . __( 'WordPress Menus Cache', 'themify' ) .themify_help(__('Caching WordPress menus can reduce queries. Will only work when there is no active cache plugin. If you have server cache, you can disable this feature.', 'themify')) . '</span>';
2405 if ( defined( 'POLYLANG_VERSION' ) ) {
2406 $output .= '<small class="pushlabel themify_warning">' . __( 'Themify menu cache has been disabled because Polylang is detected and it can not work with menu caching.', 'themify' ) . '</small>';
2407 } else {
2408 $output .= '<label for="'. $key.'"><input type="checkbox" id="'. $key.'" name="'. $key.'" '.checked(themify_check( $key,true ), true, false ).'/> ' . __('Disable menu cache', 'themify').'</label>';
2409 }
2410 $output .= '</p></div>';
2411
2412 $output.='</div>';//end of dev mode
2413
2414 $output.='<hr><p>
2415 <span class="label">' . __( 'WebP Image', 'themify' ) .themify_help(__('Using WebP image format can reduce file size by 50-90%. Only local images will be converted. The CDN and external images can not be converted. For background images of Themify Builder, you have to regenerate CSS and .htaccess file must be writeable.','themify')) . '</span>
2416 <label for="setting-webp"'.($webp===null?' class="themify_field_disable"':'').'><input type="checkbox"'.($webp===null?' disabled="disabled"':'').'id="setting-webp" name="setting-webp" '.checked( $webp, true, false ).'/> ' . __('Enable WebP image (recommended)', 'themify').'</label>
2417 </p>
2418 <p>
2419 <span class="label">' . __( 'WebP Image Quality', 'themify' ) . themify_help( __( 'Lower quality has smaller file size, but image might appear pixelated/blurry.', 'themify' ) ) . '</span> <select' . ($webp===null ? ' disabled="disabled"' : '' ) . ' id="setting-webp-quality" name="setting-webp-quality">'
2420 . '<option value="1" ' . selected( $webp_quality, 1, false ) . '>' . __( 'Lowest', 'themify' ) . '</option>'
2421 . '<option value="2" ' . selected( $webp_quality, 2, false ) . '>' . __( 'Low', 'themify' ) . '</option>'
2422 . '<option value="3" ' . selected( $webp_quality, 3, false ) . '>' . __( 'Medium', 'themify' ) . '</option>'
2423 . '<option value="4" ' . selected( $webp_quality, 4, false ) . '>' . __( 'Good', 'themify' ) . '</option>'
2424 . '<option value="5" ' . selected( $webp_quality, 5, false ) . '>' . __( 'High', 'themify' ) . '</option>'
2425 . '<option value="6" ' . selected( $webp_quality, 6, false ) . '>' . __( 'Highest', 'themify' ) . '</option>'
2426 . '</select>
2427 </p>
2428 <span class="pushlabel"><a href="#" data-action="themify_clear_all_webp" data-clearing-text="'.__('Clearing...','themify').'" data-done-text="'.__('Done','themify').'" data-default-text="'.__('Clear WebP Images','themify').'" data-default-icon="ti-eraser" class="button button-outline js-clear-cache"><i class="ti-eraser"></i> <span>'.__('Clear WebP Images','themify').'</span></a></span>';
2429 if($message!==''){
2430 $output.='<small class="pushlabel themify_warning" >'.$message.'</small>';
2431 }
2432 $key='setting-jquery';
2433 $output.='<hr><p>
2434 <span class="label">' . __( 'jQuery Script', 'themify' ) .themify_help(__('Defer jQuery and all scripts can prevent render blocking. If your site/plugin(s) have inline jQuery code conflicting it, disable this option.','themify')) . '</span>
2435 <label for="'. $key.'"><input type="checkbox" id="'. $key.'" name="'. $key.'" '.checked(themify_check( $key,true ), true, false ).'/> ' . __('Defer jQuery script loading', 'themify').'</label>
2436 </p>';
2437 $key = 'setting-jquery-migrate';
2438 $output.='<p>
2439 <span class="label">' . __( 'jQuery Migrate', 'themify' ) .themify_help(__('Only enable this if your plugin(s) use the deprecated jQuery versions.','themify')) . '</span>
2440 <label for="'. $key.'"><input type="checkbox" id="'. $key.'" name="'. $key.'" '.checked(themify_check( $key,true ), true, false ).'/> ' . __('Enable jQuery Migrate', 'themify').'</label>
2441 </p>';
2442
2443 if(themify_is_woocommerce_active()){
2444 $key='setting-optimize-wc';
2445 $output.='<hr><p>
2446 <span class="label">' . __( 'WooCommerce Script Optimization', 'themify' ) .themify_help(__('Themify loads WooCommerce scripts on demand for faster page load. If you are encountering issues with third party WooCommerce extensions, try to disable WooCommerce script optimization.','themify')) . '</span>
2447 <label for="'. $key.'"><input type="checkbox" id="'. $key.'" name="'. $key.'" '.checked(themify_check( $key,true ), true, false ).'/> ' . __('Disable WooCommerce script loading optimization', 'themify').'</label>
2448 </p>';
2449 $key='setting-defer-wc';
2450 $output.='<div data-show-if-element="[name$=setting-jquery]" data-show-if-value="false"><p data-show-if-element="[name$=setting-optimize-wc]" data-show-if-value="false">
2451 <span class="label">' . __( 'WooCommerce Script Defer', 'themify' ) .themify_help(__('WooCommerce scripts are deferred for faster page load. If you are encountering issues with third party WooCommerce extensions, try to disable script defer.','themify')) . '</span>
2452 <label for="'. $key.'"><input type="checkbox" id="'. $key.'" name="'. $key.'" '.checked(themify_check( $key,true ), true, false ).'/> ' . __('Disable WooCommerce script defer', 'themify').'</label>
2453 </p></div>';
2454 }
2455 $key='setting-emoji';
2456 $output.='<hr><p>
2457 <span class="label">' . __( 'WordPress Emoji', 'themify' ) .themify_help(__('If you are not using WordPress Emoji icons, keep it disabled to reduce script load.','themify')) . '</span>
2458 <label for="'. $key.'"><input type="checkbox" id="'. $key.'" name="'. $key.'" '.checked(themify_check( $key,true ), true, false ).'/> ' . __('Enable Emoji script loading', 'themify').'</label>
2459 </p>';
2460 return $output;
2461 }
2462 }
2463
2464 if(!function_exists('themify_webfonts_subsets')) {
2465 /**
2466 * Module to specify additional characters subsets
2467 * @param array Themify data
2468 * @return string Module markup
2469 * @since 1.3.9
2470 */
2471 function themify_webfonts_subsets($data = array()){
2472
2473 $html='';
2474 // List of fonts, recommended or full
2475 if(!defined('THEMIFY_GOOGLE_FONTS') || THEMIFY_GOOGLE_FONTS == true){
2476 $key = 'setting-gf';
2477 $html='<p>
2478 <span class="label">' . __( 'Download Google Fonts', 'themify' ) .'</span>
2479 <label for="'.$key.'"><input type="checkbox" id="'.$key.'" name="'.$key.'" '. checked( themify_check($key,true ),true, false ) .'/> ' . __('Download Google Fonts to Local', 'themify') . '</label>
2480 <small class="pushlabel">'.__('Downloads all Google Fonts used in the theme and Builder to your local server. Note: Google Maps, YouTube and any embeds loaded in iframe are excluded as they are loaded in the iframe.','themify').'</small>
2481 ';
2482 $html.='<br/><span class="pushlabel"><a href="#" data-action="themify_clear_gfonts" data-send="all" data-clearing-text="'.__('Clearing...','themify').'" data-done-text="'.__('Done','themify').'" data-default-text="'.__('Clear Google Fonts Cache','themify').'" data-default-icon="ti-eraser" class="button button-outline js-clear-cache"><i class="ti-eraser"></i> <span>'.__('Clear Google Fonts Cache','themify').'</span></a></span></p><hr>';
2483 }
2484 $key = 'setting-webfonts_list';
2485 $html.= '<p>
2486 <span class="label">' . __('Google Fonts List', 'themify') . '</span>';
2487
2488 // Disable Google fonts
2489 $html .= '<label for="' . esc_attr( $key . '_disabled' ) . '">
2490 <input ' . checked( themify_check( $key ) ? themify_get( $key ) : '', 'disabled', false ) . ' type="radio" id="' . esc_attr( $key . '_disabled' ) . '" name="' . esc_attr( $key ) . '" value="disabled" /> ' . __( 'Disable Google fonts', 'themify' ) . '</label><br/>';
2491
2492 // Recommended list
2493 $html .= '<span class="pushlabel">
2494 <label for="' . esc_attr( $key . '_recommended' ) . '">
2495 <input ' . checked( themify_check( $key )? themify_get( $key ) : 'recommended', 'recommended', false) . ' type="radio" id="' . esc_attr( $key . '_recommended' ) . '" name="' . esc_attr( $key ) . '" value="recommended" /> ' . __( 'Show recommended Google Fonts only', 'themify' ) . '</label><br/>';
2496
2497 // Full list
2498 $html .= '
2499 <label for="' . esc_attr( $key . '_full' ) . '">
2500 <input ' . checked( themify_check( $key )? themify_get( $key ) : '', 'full', false ) . ' type="radio" id="' . esc_attr( $key . '_full' ) . '" name="' . esc_attr( $key ) . '" value="full" /> ' . __( 'Show all Google Fonts (showing all fonts will take longer to load)', 'themify' ) . '</label>
2501 </span>
2502 </p>';
2503 return $html;
2504 }
2505 }
2506
2507
2508 /**
2509 * Renders the option to responsive design
2510 *
2511 * @since 2.1.5
2512 * @return string
2513 */
2514 function themify_disable_responsive_design_option( $data = array() ) {
2515 $out = sprintf( '<p class="tf_clearfix"><span class="label width10">%s</span></p>', esc_html__( 'Responsive Breakpoints:', 'themify' ) );
2516
2517 $opt_data = themify_get_data();
2518 $break_points = themify_get_breakpoints('',true);
2519 $pre = 'setting-customizer_responsive_design_';
2520 $bp_tablet_landscape = !empty( $opt_data[ $pre . 'tablet_landscape'] ) ? $opt_data[ $pre . 'tablet_landscape'] : 1024;
2521 $bp_tablet = !empty( $opt_data[ $pre . 'tablet'] ) ? $opt_data[ $pre . 'tablet'] : 768;
2522 $bp_mobile =!empty( $opt_data[ $pre . 'mobile'] ) ? $opt_data[ $pre . 'mobile'] : 600;
2523
2524 $out .= sprintf( '<div class="tf_clearfix"><div class="label">%s</div><div class="label input-range width10"><div class="range-slider width8"></div><input type="text" name="%s" value="%s" data-min="%d" data-max="%d" data-default-min="%d" data-default-max="%d" class="width4"> px</div></div>',
2525 esc_html__( 'Tablet Landscape', 'themify' ),
2526 $pre . 'tablet_landscape',
2527 $bp_tablet_landscape,
2528 $bp_tablet_landscape < $break_points['tablet_landscape'][0] ? $bp_tablet_landscape : $break_points['tablet_landscape'][0],//min
2529 $bp_tablet_landscape > $break_points['tablet_landscape'][1] ? $bp_tablet_landscape : $break_points['tablet_landscape'][1],//max
2530 $break_points['tablet_landscape'][0],// default min
2531 $break_points['tablet_landscape'][1]// default max
2532 );
2533 $out .= sprintf( '<div class="tf_clearfix"><div class="label">%s</div><div class="label input-range width10"><div class="range-slider width8"></div><input type="text" name="%s" value="%s" data-min="%d" data-max="%d" data-default-min="%d" data-default-max="%d" class="width4"> px</div></div>',
2534 esc_html__( 'Tablet Portrait', 'themify' ),
2535 $pre . 'tablet',
2536 $bp_tablet,
2537 $bp_tablet < $break_points['tablet'][0] ? $bp_tablet : $break_points['tablet'][0],//min
2538 $bp_tablet > $break_points['tablet'][1] ? $bp_tablet : $break_points['tablet'][1],//max
2539 $break_points['tablet'][0],
2540 $break_points['tablet'][1]
2541 );
2542 $out .= sprintf( '<div class="tf_clearfix"><div class="label">%s</div><div class="label input-range width10"><div class="range-slider width8"></div><input type="text" name="%s" value="%s" data-min="%d" data-max="%d" data-default-min="%d" data-default-max="%d" class="width4"> px</div></div>',
2543 esc_html__( 'Mobile', 'themify' ),
2544 $pre . 'mobile',
2545 $bp_mobile,
2546 $bp_mobile < 320 ? $bp_mobile : 320,//min
2547 $bp_mobile > $break_points['mobile'] ? $bp_mobile : $break_points['mobile'],//max
2548 320,
2549 $break_points['mobile']
2550 );
2551 $out .= '
2552 <p>
2553 <span class="label">' . __( 'Mobile Menu', 'themify' ) .themify_help(__( 'Main menu will toggle to mobile menu style when viewport width meets the entered value.', 'themify' )) . '</span>
2554 <input type="text" name="setting-mobile_menu_trigger_point" value="' . esc_attr( Themify_Enqueue_Assets::$mobileMenuActive ) . '" class="width2">' . __( 'Mobile menu viewport (px)', 'themify' ) .'
2555 </p>';
2556
2557 return $out;
2558 }
2559
2560
2561 if ( ! function_exists( 'themify_generic_slider_controls' ) ) {
2562 /**
2563 * Creates a general module to setup slider parameters
2564 * @param $prefix
2565 * @return string
2566 */
2567 function themify_generic_slider_controls( $prefix ) {
2568 /**
2569 * Associative array containing theme settings
2570 * @var array
2571 */
2572
2573 $auto_options = apply_filters( 'themify_generic_slider_auto',
2574 array(
2575 __('4 Secs (default)', 'themify') => 4000,
2576 __('Off', 'themify') => 'off',
2577 __('1 Sec', 'themify') => 1000,
2578 __('2 Secs', 'themify') => 2000,
2579 __('3 Secs', 'themify') => 3000,
2580 __('4 Secs', 'themify') => 4000,
2581 __('5 Secs', 'themify') => 5000,
2582 __('6 Secs', 'themify') => 6000,
2583 __('7 Secs', 'themify') => 7000,
2584 __('8 Secs', 'themify') => 8000,
2585 __('9 Secs', 'themify') => 9000,
2586 __('10 Secs', 'themify')=> 10000
2587 )
2588 );
2589 $speed_options = apply_filters( 'themify_generic_slider_speed',
2590 array(
2591 __('Fast', 'themify') => 500,
2592 __('Normal', 'themify') => 1000,
2593 __('Slow', 'themify') => 1500
2594 )
2595 );
2596 $effect_options = array(
2597 array('name' => __('Slide', 'themify'), 'value' => 'slide'),
2598 array('name' => __('Fade', 'themify'), 'value' =>'fade')
2599 );
2600
2601 /**
2602 * Auto Play
2603 */
2604 $output = '<p>
2605 <span class="label">' . __('Auto Play', 'themify') . '</span>
2606 <select name="' . $prefix . 'autoplay">';
2607 foreach ( $auto_options as $name => $val ) {
2608 $v=themify_get( $prefix . 'autoplay' );
2609 $output .= '<option value="' . $val . '" ' . selected( $v, $v ? $val : 4000, false ) . '>' . esc_html( $name ) . '</option>';
2610 }
2611 $output .= ' </select>
2612 </p>';
2613
2614 /**
2615 * Effect
2616 */
2617 $output .= '<p>
2618 <span class="label">' . __( 'Effect', 'themify' ) . '</span>
2619 <select name="' . $prefix. 'effect">' .
2620 themify_options_module( $effect_options, $prefix . 'effect' ) . '
2621 </select>
2622 </p>';
2623
2624 /**
2625 * Transition Speed
2626 */
2627 $output .= '<p>
2628 <span class="label">' . __( 'Transition Speed', 'themify' ) . '</span>
2629 <select name="' . $prefix . 'transition_speed">';
2630 $transition=themify_get( $prefix . 'transition_speed' );
2631 foreach ( $speed_options as $name => $val ) {
2632 $output .= '<option value="' . $val . '" ' . selected( $transition, $transition? $val : 500, false ) . '>' . esc_html( $name ) . '</option>';
2633 }
2634 $output .= ' </select>
2635 </p>';
2636
2637 return apply_filters( 'themify_generic_slider_controls', $output );
2638 }
2639 }
2640
2641 /**
2642 * Display select element with featured image sizes + blank slot
2643 * @param String $key setting name
2644 * @return String
2645 * @since 1.1.5
2646 */
2647 function themify_feature_image_sizes_select($key = ''){
2648 /** Define WP Featured Image sizes + blank + Themify's image script
2649 * @var array */
2650 $themify_layout_feature_sizes = themify_get_image_sizes_list();
2651
2652 $output = '<p class="show_if_disabled_img_php">
2653 <span class="label">' . __('Featured Image Size', 'themify') . '</span>
2654 <select name="setting-' . $key . '">';
2655 $val=themify_get('setting-'.$key,false,true);
2656 foreach($themify_layout_feature_sizes as $option){
2657 $sel=$option['value']===$val?' selected="selected"':'';
2658 $output .= '<option'.$sel.' value="' . $option['value'] . '">' . esc_html( $option['name'] ) . '</option>';
2659 }
2660 $output .= '</select></p>';
2661
2662 return $output;
2663 }
2664
2665 if ( ! function_exists( 'themify_theme_mega_menu_controls' ) ) {
2666 /**
2667 * Mega Menu Controls
2668 * @param array $data Theme settings data
2669 * @return string Markup for module.
2670 * @since 3.5.8
2671 */
2672 function themify_theme_mega_menu_controls( $data = array() ) {
2673 /**
2674 * Theme Settings Option Key Prefix
2675 *
2676 * @var string
2677 */
2678 $key = 'setting-mega_menu';
2679 $orderby = [
2680 'date' => __('Date', 'ptb'),
2681 'id' => __('Id', 'ptb'),
2682 'author' => __('Author', 'ptb'),
2683 'title' => __('Title', 'ptb'),
2684 'name' => __('Name', 'ptb'),
2685 'modified' => __('Modified', 'ptb'),
2686 'rand' => __('Random', 'ptb'),
2687 'comment_count' => __('Comment count', 'ptb'),
2688 'menu_order' => __('Menu Order', 'ptb')
2689 ];
2690
2691 /**
2692 * Module markup
2693 * @var string
2694 */
2695 $out = '
2696 <p>
2697 <span class="label">' . __( 'Mega Menu Posts', 'themify' ) .themify_help(__( 'Number of posts to show on mega menu.', 'themify' )) . '</span>
2698 <input type="text" name="'.$key.'_posts" value="' . esc_attr( themify_get( $key.'_posts', 5,true ) ) . '" class="width2">' . __( 'Posts', 'themify' ) .'
2699 </p>';
2700 $out .= '
2701 <p>
2702 <span class="label">' . __( 'Mega Menu Posts Order', 'themify' ) . '</span>
2703 <select name="' . $key . '_orderby">';
2704 foreach ( $orderby as $option_key => $label ) :
2705 $out .= '<option value="' . esc_attr( $option_key ) . '" ' . selected( themify_get( $key . '_orderby', null, true ), $option_key, false ) . '>' . esc_html( $label ) . '</option>';
2706 endforeach;
2707 $out .='
2708 </select>
2709 <select name="' . $key . '_order">
2710 <option value="desc" ' . selected( themify_get( $key . '_order', null, true ), 'desc', false ) . '>' . __( 'Descending', 'themify' ) . '</option>
2711 <option value="asc" ' . selected( themify_get( $key . '_order', null, true ), 'asc', false ) . '>' . __( 'Ascending', 'themify' ) . '</option>
2712 </select>
2713 </p>';
2714 $out .= '
2715 <p>
2716 <span class="label">' . __( 'Mega Post Image', 'themify' ) .themify_help(__( 'Enter featured image size on mega menu posts.', 'themify' )) . '</span>
2717 <input type="text" name="'.$key.'_image_width" value="' . esc_attr( themify_get( $key.'_image_width', 180,true ) ) . '" class="width2"> X <input type="text" name="'.$key.'_image_height" value="' . esc_attr( themify_get( $key.'_image_height', 120,true ) ) . '" class="width2"> ' . __( 'px', 'themify' ) .'
2718 </p>';
2719
2720 return apply_filters('themify_mega_menu_settings',$out);
2721 }
2722
2723 }
2724
2725 /**
2726 * Display google map api key input
2727 * @return String
2728 * @since 2.7.7
2729 */
2730 function themify_google_map_key($data=array()){
2731 $value = themify_get( 'setting-google_map_key','',true);
2732 $validate = !empty($value) && strip_tags( $value ) !== $value ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2733
2734 return '
2735 <p>
2736 <span class="label">' . __( 'Google Map Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-google_map_key" value="' . esc_attr( $value ) . '" /> <br />' .
2737 '<span class="pushlabel"><small>' . sprintf( __( 'Google API key is required to use Builder Map module and Map shortcode. <a href="%s" target="_blank" rel="noopener">Generate an API key</a> and insert it here. Also, please ensure you\'ve setup a <a href="%s" target="_blank" rel="noopener">billing plan</a>.', 'themify' ), '//developers.google.com/maps/documentation/javascript/get-api-key#key', 'https://support.google.com/googleapi/answer/6158867' ) . '</small></span>' .
2738 $validate .
2739 '</p>';
2740 }
2741
2742 /**
2743 * Display bing map api key input
2744 * @return String
2745 * @since 2.8.0
2746 */
2747 function themify_bing_map_key($data=array()){
2748 $value = themify_get( 'setting-bing_map_key','',true );
2749 $validate = !empty($value) && strip_tags( $value ) !== $value ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2750 $dep_notice = '<div class="themify-info-link">' . sprintf( __( 'Bing Map service <a href="%s" target="_blank">ends in June 30, 2028</a>. Please switch to Azure maps instead.', 'themify' ), 'https://www.microsoft.com/en-us/maps/bing-maps/discontinued-services' ) . '</div>';
2751
2752 return '<p><span class="label">' . __( 'Bing Maps Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-bing_map_key" value="' . esc_attr( $value ) . '" /> <br />
2753 <span class="pushlabel"><small>' . sprintf( __( 'To use Bing Maps, <a href="%s" target="_blank" rel="noopener">generate an API key</a> and insert it here.', 'themify' ), 'https://msdn.microsoft.com/en-us/library/ff428642.aspx' ) . '</small></span>' . $validate . $dep_notice . '</p>';
2754 }
2755
2756 function themify_azure_map_key($data=array()){
2757 $value = themify_get( 'setting-azure_map_key','',true );
2758 $validate = !empty($value) && strip_tags( $value ) !== $value ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2759
2760 $output = '<p><span class="label">' . __( 'Azure Subscription Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-azure_map_key" value="' . esc_attr( $value ) . '" /> <br /><span class="pushlabel">';
2761 $output .= '<h4>' . __( 'To get your key:', 'themify' ) . '</h4><small><ol>';
2762 $output .= '<li>' . sprintf( __( 'Sign in to <a href="%s" target="_blank" rel="noopener">Azure portal</a>', 'themify' ), 'https://portal.azure.com/' ) . '</li>';
2763 $output .= '<li>' . sprintf( __( '<a href="%s" target="_blank" rel="noopener">Create an Azure Map resource</a> if you haven\'t already.', 'themify' ), 'https://learn.microsoft.com/en-us/azure/azure-maps/quick-demo-map-app#create-an-azure-maps-account' ) . '</li>';
2764 $output .= '<li>' . sprintf( __( 'Get your <a href="%s" target="_blank" rel="noopener">subscription key (Primary Key)</a> and paste it here.', 'themify' ), 'https://learn.microsoft.com/en-us/azure/azure-maps/quick-demo-map-app#get-the-subscription-key-for-your-account' ) . '</li>';
2765 $output .= '</ol></small></span>' . $validate . '</p>';
2766
2767 return $output;
2768 }
2769
2770 /**
2771 * Display Cloudflare api key input
2772 * @return String
2773 * @since 2.8.0
2774 */
2775 function themify_cloudflare_setting($data=array()){
2776 $key='setting-clf_email';
2777 $email=themify_get( $key,'',true );
2778 $output = '<p><span class="label">' . __( 'Account Email', 'themify' ) . '</span> <input type="email" class="width8" name="'.$key.'" value="' . esc_attr( $email ) . '" /></p>';
2779 $key='setting-clf_key';
2780 $api=themify_get( $key,'',true );
2781 $validate = !empty($api) && strip_tags( $api ) !== $api ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2782
2783 $output .= '<p><span class="label">' . __( 'API Key', 'themify' ) . '</span> <input type="text" class="width10" name="'.$key.'" value="' . esc_attr( $api ) . '" />' . $validate . '</p>';
2784 $key='setting-clf_z_'.crc32($email.$api);
2785 $zone=themify_get( $key,'',true );
2786 if(!empty($zone)){
2787 $output .= '<input type="hidden" name="'.$key.'" value="' . esc_attr( $zone ) . '" />';
2788 }
2789 $output .= '<p><span class="pushlabel"><small>' . __( 'To clear Cloudflare cache upon theme update or purge Themify cache, please login to your Cloudflare account and insert your information here.', 'themify' ) . '</small></span></p>';
2790 return $output;
2791 }
2792
2793 /**
2794 * Display recaptcha api key input
2795 */
2796 function themify_recaptcha_setting($data=array()) : string {
2797 $version=Themify_Builder_Model::getReCaptchaOption( 'version');
2798 $options='';
2799 for($i=2;$i<4;$i++){
2800 $selected = $version=='v'.$i?' selected="selected"':'';
2801 $options.='<option value="v'.$i.'"'.$selected.'>Version '.$i.'</option>';
2802 }
2803 $public_key = Themify_Builder_Model::getReCaptchaOption( 'public_key' );
2804 $private_key = Themify_Builder_Model::getReCaptchaOption( 'private_key' );
2805 $output='<p><span class="label">' . __( 'ReCaptcha Version', 'themify' ) . '</span><select name="setting-recaptcha_version">'.$options.'</select></p>';
2806 $validate = !empty($public_key) && strip_tags( $public_key ) !== $public_key ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2807 $output.='<p><span class="label">' . __( 'ReCaptcha Site Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-recaptcha_site_key" value="' . esc_attr( $public_key ) . '" /> ' . $validate . ' </p>';
2808
2809 $validate = !empty($private_key) && strip_tags( $private_key ) !== $private_key ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2810 $output.='<p><span class="label">' . __( 'ReCaptcha Secret Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-recaptcha_secret_key" value="' . esc_attr( $private_key ) . '" /><br/><span class="pushlabel"><small>'.sprintf( __( 'Go to <a target="_blank" href="%s" rel="noopener">reCAPTCHA Admin Console</a> to create API keys for your domain. A Google account is required.', 'themify' ), 'https://www.google.com/recaptcha/admin' ).'</small></span> ' . $validate . '</p>';
2811 return $output;
2812 }
2813
2814 /**
2815 * Display hcaptcha api key input
2816 */
2817 function themify_hcaptcha_setting($data=array()) : string {
2818 $secret_key = themify_builder_get( 'setting-hcaptcha_secret', 'hcaptcha_secret' );
2819 $site_key = themify_builder_get( 'setting-hcaptcha_site', 'hcaptcha_site' );
2820 $validate = !empty($secret_key) && strip_tags( $secret_key ) !== $secret_key ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2821 $output = '<p><span class="label">' . __( 'hCaptcha Secret Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-hcaptcha_secret" value="' . esc_attr( $secret_key ) . '" /><br/><span class="pushlabel"><small>' . sprintf( __( 'You can find the secret key on your hCaptcha <a href="%s" target="_blank">profile page</a>.', 'themify' ), 'https://dashboard.hcaptcha.com/settings' ) . '</small></span> ' . $validate . '</p>';
2822
2823 $validate = !empty($site_key) && strip_tags( $site_key ) !== $site_key ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2824 $output .= '<p><span class="label">' . __( 'hCaptcha Site Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-hcaptcha_site" value="' . esc_attr( $site_key ) . '" /><br/><span class="pushlabel"><small>' . sprintf( __( 'You can find the site key from the <a href="%s" target="_blank">sites page</a> on your hCaptcha profile. Note that you also need to add your site domain(s) in the site key.', 'themify' ), 'https://dashboard.hcaptcha.com/sites' ) . '</small></span> ' . $validate . '</p>';
2825 return $output;
2826 }
2827
2828 /**
2829 * Display Cloudflare Turnstile api key input
2830 */
2831 function themify_turnstile_setting($data=array()) : string {
2832 $secret_key = themify_builder_get( 'setting-turnstile_secret', 'turnstile_secret' );
2833 $site_key = themify_builder_get( 'setting-turnstile_site', 'turnstile_site' );
2834 $validate = !empty($secret_key) && strip_tags( $secret_key ) !== $secret_key ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2835 $output = '<p><span class="label">' . __( 'Secret Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-turnstile_secret" value="' . esc_attr( $secret_key ) . '" />' . $validate . '</p>';
2836
2837 $validate = !empty($site_key) && strip_tags( $site_key ) !== $site_key ? sprintf( '<div class="notice notice-error"><p>%s</p></div>', __( 'This field must not contain HTML tags, please enter just the API key.', 'themify' ) ) : '';
2838 $output .= '<p><span class="label">' . __( 'Site Key', 'themify' ) . '</span> <input type="text" class="width10" name="setting-turnstile_site" value="' . esc_attr( $site_key ) . '" /><br/><span class="pushlabel"><small>' . sprintf( __( 'Get API keys at Cloudflare Dashboard &gt; Application Security &gt; Turnstile (<a href="%s" target="_blank">more info</a>).', 'themify' ), 'https://developers.cloudflare.com/turnstile/get-started/#get-a-sitekey-and-secret-key' ) . '</small></span> ' . $validate . '</p>';
2839 return $output;
2840 }
2841
2842
2843 /**
2844 * Display video gdpr
2845 * @return String
2846 */
2847 function themify_video_gdpr($data=array()){
2848 $key='setting-gdpr';
2849 $imgKey=$key.'-img';
2850 $media=array(
2851 'fields' => $imgKey,
2852 'medialib'=>1,
2853 'preview' => true
2854 );
2855 $imgVal=themify_get( $imgKey,'',true );
2856 $output = '
2857 <p>
2858 <label class="label" for="'.$key.'">' . __( 'GDPR', 'themify' ) . '</label>
2859 <select name="'.$key.'" .id="'.$key.'">
2860 <option value="">' . __( 'Disabled', 'themify' ) . '</option>
2861 <option value="1" ' . selected( 'on', themify_get($key,'',true ), false ) . '>' . __( 'Enable', 'themify' ) . '</option>
2862 </select>
2863 <span class="pushlabel">
2864 <small class="description">' . __( 'Once it is enabled, only logged-in users can see your site.', 'themify' ) . '</small>
2865 </span>
2866 </p>';
2867 $output .= '
2868 <div data-show-if-element="[name='.$key.']" data-show-if-value="1">
2869 <label class="label" for="'.$imgKey.'">' . __( 'Show Image', 'themify' ) . '</label>
2870 <div class="icon-preview">
2871 <img id="' . $imgKey . '-preview" src="' . $imgVal . '" loading="lazy" decoding="async" />
2872 </div>
2873 <input id="'.$imgKey.'" type="text" class="width10" name="'.$imgKey.'" value="' . $imgVal . '" />
2874 '.themify_get_uploader($imgKey,$media).'
2875 </div>
2876 ';
2877 return $output;
2878 }
2879
2880 /**
2881 * Add Maintenance mode option
2882 * @return string
2883 * @since 4.5.8
2884 */
2885 function themify_maintenance_mode_settings() {
2886 global $wp_roles;
2887
2888 $pre = 'setting-page_builder_';
2889 $value = themify_builder_get( $pre . 'maintenance_mode', 'tools_maintenance_mode' );
2890 $output = '
2891 <p>
2892 <label class="label" for="tb_maintenance_mode">' . __( 'Maintenance', 'themify' ) . '</label>
2893 <select name="' . $pre . 'maintenance_mode">
2894 <option value="">' . __( 'Disabled', 'themify' ) . '</option>
2895 <option value="on" ' . selected( 'on', $value, false ) . '>' . __( 'Enable and display a page', 'themify' ) . '</option>
2896 <option value="message" ' . selected( 'message', $value, false ) . '>' . __( 'Enable and display a message', 'themify' ) . '</option>
2897 </select>
2898 <span class="pushlabel">
2899 <small class="description">' . __( 'Once it is enabled, only logged-in users can see your site.', 'themify' ) . '</small>
2900 </span>
2901 </p>';
2902
2903 $message = themify_builder_get( 'setting-maintenance_message', 'tools_maintenance_message' );
2904 $output .= '
2905 <div data-show-if-element="[name=setting-page_builder_maintenance_mode]" data-show-if-value="message">
2906 <div class="pushlabel">
2907 <textarea name="setting-maintenance_message" class="width10">' . esc_html( $message ) . '</textarea>
2908 </div>
2909 </div>
2910 ';
2911
2912 $selected_value = themify_builder_get( 'setting-page_builder_maintenance_page', 'tools_maintenance_page' );
2913 $selected_page = empty($selected_value) ? '' : get_page_by_path( $selected_value, OBJECT, 'page' );
2914 $output .= sprintf( '<div data-show-if-element="[name=setting-page_builder_maintenance_mode]" data-show-if-value="on"><label class="label" for="%s">%s</label><select id="%s" name="%s">%s<option>%s</option></select><div data-show-if-element="[name=page_builder_maintenance_mode]" data-show-if-value="true" class="pushlabel"><small>%s</small></div></div>',
2915 $pre . 'maintenance_page',
2916 __( 'Maintenance Page', 'themify' ),
2917 $pre . 'maintenance_page',
2918 $pre . 'maintenance_page',
2919 !is_object($selected_page) ? '<option></option>' : sprintf('<option value="%s" selected="selected">%s</option>',$selected_value,$selected_page->post_title),
2920 __( 'Loading...', 'themify' ),
2921 __( 'Select a page to show for public users.', 'themify' )
2922 );
2923
2924 $output .= '<div data-show-if-element="[name=setting-page_builder_maintenance_mode]" data-show-if-value=\'["on", "message"]\'><label class="label">' . __( 'Allow Access', 'themify' ) . themify_help( __('Select the user role(s) to allow viewing when maintenance mode is enabled.', 'themify')) .
2925 '</label><div class="pushlabel">';
2926 $roles = $wp_roles->get_names();
2927 /* administrator role always has access */
2928 unset( $roles['administrator'] );
2929 foreach ( $roles as $key => $label ) {
2930 $selected = themify_builder_get( 'setting-maintenance_access_' . $key, 'maintenance_access_' . $key ) ? ' checked' : '';
2931 $output .= '<label><input name="setting-maintenance_access_' . $key . '" type="checkbox" ' . $selected . ' value="1"> ' . esc_html( $label ) . '</label>';
2932 }
2933 $output .= '</div></div>';
2934
2935 return $output;
2936 }
2937
2938 /**
2939 * Add Google Analytics option
2940 * @return string
2941 * @since 5.5.5
2942 */
2943 function themify_google_analytics_settings() {
2944 $m_id = themify_get( 'setting-ga_m_id','',true );
2945 return '<p><span class="label">' . __( 'Measurement ID', 'themify' ) . '</span> <input type="text" name="setting-ga_m_id" value="' . esc_attr( $m_id ) . '" /> <br />
2946 <span class="pushlabel"><small>' .
2947 sprintf( __( '<a href="%s">Set up Analytics for your website</a>. Afterwards, go to your <a href="%s">Analytics admin dashboard</a> and select Data Streams, click on the item you want, then copy the Measurement ID (starts with "G-") and paste it here.', 'themify' ), 'https://support.google.com/analytics/answer/9304153', 'https://support.google.com/analytics/answer/6132368' )
2948 . '</small></span></p>';
2949 }
2950
2951
2952 /**
2953 * Callback for themify_framework_theme_microdata_config(), to display the options
2954 *
2955 * @return string
2956 */
2957 function themify_framework_theme_microdata_config_callback() {
2958 return '<p><span class="label">' . __('Schema Microdata', 'themify') . '</span> <label for="setting-disable_microdata"><input type="checkbox" id="setting-disable_microdata" name="setting-disable_microdata" '. checked( 'on', themify_get( 'setting-disable_microdata','',true ), false ) .'/> ' . __('Disable schema.org microdata output.', 'themify') . '</label></p>';
2959 }
2960
2961
2962 /**
2963 * Display Builder Styles page content
2964 * @return String
2965 * @since 4.5.0
2966 */
2967 function themify_global_styles_page(){
2968
2969 if ( ! current_user_can( 'edit_posts' ) )
2970 wp_die( __( 'You do not have sufficient permissions to update this site.', 'themify' ) );
2971
2972 return Themify_Global_Styles::page_content();
2973 }
2974
2975
2976 ///////////////////////////////////////////
2977 // Scrub Function
2978 ///////////////////////////////////////////
2979 function themify_scrub_func($string=''){
2980 return str_replace(array(' ', '/', ','), array('_', '_', '-'), strtolower($string));
2981 }
2982
2983 ///////////////////////////////////////////
2984 // Scrub
2985 ///////////////////////////////////////////
2986 function themify_scrub($string=''){
2987 return str_replace(array('#','-',' ','.',':',',','[',']','=','<','>'), array('_id_','_dash_','_space_','_class_','_colon_','_comma_','_opensquare_','_closesquare_','_equal_','_openbracket_','_closebracket_'), $string);
2988 }
2989 /**
2990 * Check if multiple plugins are active, returns true only if all of them are
2991 *
2992 * @return bool
2993 * @since 2.8.6
2994 */
2995 function themify_are_plugins_active( $plugins ) {
2996 foreach( $plugins as $plugin ) {
2997 if( ! is_plugin_active( $plugin ) ) {
2998 return false;
2999 }
3000 }
3001
3002 return true;
3003 }
3004
3005 if ( ! function_exists( 'themify_lightbox_link_field' ) ) {
3006 /**
3007 * Returns Lightbox Link field definition for themify custom panel
3008 * @return array
3009 */
3010 function themify_lightbox_link_field( $args = array() ) {
3011
3012 $defaults = array(
3013 'name' => 'multi_lightbox_link',
3014 'title' => __('Lightbox Link', 'themify'),
3015 'description' => '',
3016 'type' => 'multi',
3017 'meta' => array(
3018 'fields' => array(
3019 // Lightbox link field
3020 array(
3021 'name' => 'lightbox_link',
3022 'label' => '',
3023 'description' => __('Link Featured Image and Post Title to lightbox image, video or iframe URL <br/>(<a href="https://themify.me/docs/lightbox" target="_blank" rel="noopener">learn more</a>)', 'themify'),
3024 'type' => 'textbox',
3025 'meta' => array(),
3026 'before' => '',
3027 'after' => '',
3028 ),
3029 array(
3030 'name' => 'iframe_url',
3031 'label' => __('iFrame URL', 'themify'),
3032 'description' => '',
3033 'type' => 'checkbox',
3034 'before' => '',
3035 'after' => '',
3036 ),
3037 array(
3038 'name' => 'lightbox_icon',
3039 'label' => __('Add zoom icon on lightbox link', 'themify'),
3040 'description' => '',
3041 'type' => 'checkbox',
3042 'before' => '',
3043 'after' => '',
3044 )
3045 ),
3046 'description' => '',
3047 'before' => '',
3048 'after' => '',
3049 'separator' => ''
3050 )
3051 );
3052
3053 $field = wp_parse_args( $args, $defaults );
3054
3055 return apply_filters( 'themify_lightbox_link_field', $field );
3056 }
3057 }
3058
3059 if( ! function_exists( 'themify_image_dimensions_field' ) ) {
3060 /**
3061 * Multi field: Image dimensions fields to enter width and height.
3062 * @param array $args
3063 * @param string $prefix
3064 * @return mixed|void
3065 * @since 1.5.2
3066 */
3067 function themify_image_dimensions_field( $args = array(), $prefix = 'image' ) {
3068 if(!themify_is_image_script_disabled()){
3069 $defaults = array(
3070 'type' => 'multi',
3071 'name' => $prefix . '_dimensions',
3072 'title' => __('Featured Image Size', 'themify'),
3073 'meta' => array(
3074 'fields' => array(
3075 // Image Width
3076 array(
3077 'name' => $prefix . '_width',
3078 'label' => __('width', 'themify'),
3079 'description' => '',
3080 'type' => 'textbox',
3081 'meta' => array('size' => 'small')
3082 ),
3083 // Image Height
3084 array(
3085 'name' => $prefix . '_height',
3086 'label' => __('height', 'themify'),
3087 'type' => 'textbox',
3088 'meta' => array( 'size' => 'small')
3089 ),
3090 ),
3091 'description' => __('Enter height = 0 to disable vertical cropping with image script enabled', 'themify'),
3092 'before' => '',
3093 'after' => '',
3094 'separator' => ''
3095 )
3096 );
3097 } else {
3098 $defaults = array( 'name'=>'','type'=>'' );
3099 }
3100 $field = wp_parse_args( $args, $defaults );
3101
3102 return apply_filters( 'themify_image_dimensions_field', $field );
3103 }
3104 }
3105
3106
3107 /**
3108 * Returns a collection of options: yes, no and default which means the theme settings will be used.
3109 *
3110 * @since 2.1.3
3111 *
3112 * @param string $yes
3113 * @param string $no
3114 * @param string $default
3115 * @param array $args
3116 *
3117 * @return array
3118 */
3119 function themify_ternary_options( $yes = '', $no = '', $default = '', $args = array() ) {
3120 return wp_parse_args( $args, array(
3121 array(
3122 'value' => 'default',
3123 'name' => !empty( $default ) ? $default : __( 'Default', 'themify' ),
3124 'selected' => true
3125 ),
3126 array(
3127 'value' => 'yes',
3128 'name' => !empty( $yes ) ? $yes : __( 'Yes', 'themify' ),
3129 ),
3130 array(
3131 'value' => 'no',
3132 'name' => !empty( $no ) ? $no : __( 'No', 'themify' ),
3133 ),
3134 ));
3135 }
3136
3137 /**
3138 * Returns a collection of states: yes, no and default which means the theme settings will be used.
3139 *
3140 * @since 2.1.3
3141 *
3142 * @param string $yes
3143 * @param string $no
3144 * @param string $default
3145 * @param array $args
3146 *
3147 * @return array
3148 */
3149 function themify_ternary_states( $args = array(), $all = array() ) {
3150 $args = wp_parse_args( $args, array(
3151 'icon_yes' => THEMIFY_URI . '/img/ddbtn-check.svg',
3152 'icon_no' => THEMIFY_URI . '/img/ddbtn-cross.svg',
3153 'value_default' => '',
3154 ) );
3155 return wp_parse_args( $all, array(
3156 array(
3157 'name' => empty( $args['label_yes'] ) ? __('Hide', 'themify') : $args['label_yes'],
3158 'value' => 'yes',
3159 'icon' => $args['icon_no'],
3160 'title' => __('Hide this', 'themify')
3161 ),
3162 array(
3163 'name' => empty( $args['label_no'] ) ? __('Show', 'themify') : $args['label_no'],
3164 'value' => 'no',
3165 'icon' => $args['icon_yes'],
3166 'title' => __('Show this', 'themify')
3167 ),
3168 array(
3169 'name' => empty( $args['default'] ) ? __('Theme default', 'themify') : $args['default'],
3170 'value' => $args['value_default'],
3171 'icon' => THEMIFY_URI . '/img/ddbtn-blank.png',
3172 'title' => __('Use theme settings', 'themify'),
3173 'default' => true
3174 )
3175 ));
3176 }
3177 if( ! function_exists( 'themify_multi_meta_field' ) ) {
3178 /**
3179 * Definition for tri-state hide meta buttons
3180 *
3181 * @param array $args
3182 * @param string $prefix
3183 *
3184 * @return mixed|void
3185 * @since 1.5.2
3186 */
3187 function themify_multi_meta_field( $args = array(), $prefix = 'hide_meta' ) {
3188
3189 $states = themify_ternary_states( array( 'label_no' => __('Show', 'themify') ) );
3190
3191 $defaults = array(
3192 'name' => $prefix . '_multi',
3193 'title' => __('Post Meta', 'themify'),
3194 'description' => '',
3195 'type' => 'multi',
3196 'meta' => array (
3197 'fields' => array(
3198 array(
3199 'name' => $prefix . '_all',
3200 'title' => __('Hide All', 'themify'),
3201 'description' => '',
3202 'type' => 'dropdownbutton',
3203 'states' => $states,
3204 'main' => true,
3205 'disable_value' => 'yes'
3206 ),
3207 array(
3208 'name' => $prefix . '_author',
3209 'title' => __('Author', 'themify'),
3210 'description' => '',
3211 'type' => 'dropdownbutton',
3212 'states' => $states,
3213 'sub' => true
3214 ),
3215 array(
3216 'name' => $prefix . '_category',
3217 'title' => __('Category', 'themify'),
3218 'description' => '',
3219 'type' => 'dropdownbutton',
3220 'states' => $states,
3221 'sub' => true
3222 ),
3223 array(
3224 'name' => $prefix . '_comment',
3225 'title' => __('Comment', 'themify'),
3226 'description' => '',
3227 'type' => 'dropdownbutton',
3228 'states' => $states,
3229 'sub' => true
3230 ),
3231 array(
3232 'name' => $prefix . '_tag',
3233 'title' => __('Tag', 'themify'),
3234 'description' => '',
3235 'type' => 'dropdownbutton',
3236 'states' => $states,
3237 'sub' => true
3238 ),
3239 ),
3240 'description' => '',
3241 'before' => '',
3242 'after' => '',
3243 'separator' => ''
3244 )
3245 );
3246
3247 $field = wp_parse_args( $args, $defaults );
3248
3249 return apply_filters( 'themify_multi_meta_field', $field );
3250 }
3251 }
3252
3253 function themify_meta_field_fontawesome( $args, $call_before_after = true, $echo = true ) {
3254
3255 $meta_box = $args['meta_box'];
3256 $meta_value = $args['meta_value'];
3257 $class = isset( $meta_box['meta']['size'] ) && 'small' === $meta_box['meta']['size']?'small': '';
3258
3259 $html = '<div class="icon-preview font-icon-preview">
3260 <i class="fa ' . esc_attr( $meta_value ) . '"></i>
3261 </div>
3262 <!-- /icon-preview -->';
3263 $html .= sprintf( '<input type="text" id="%s" name="%s" value="%s" size="55" class="themify_input_field themify_fa %s" /> <a class="button button-secondary hide-if-no-js themify_fa_toggle" href="#" data-target="#%s">%s</a>',
3264 esc_attr( $meta_box['name'] ),
3265 esc_attr( $meta_box['name'] ),
3266 esc_attr( $meta_value ),
3267 $class,
3268 esc_attr( $meta_box['name'] ),
3269 __( 'Insert Icon', 'themify' ) );
3270
3271 if ( !empty( $meta_box['label'] )) {
3272 $html = sprintf( '<label for="%s">%s %s</label>',
3273 esc_attr( $meta_box['name'] ),
3274 $html,
3275 esc_html( $meta_box['label'] )
3276 );
3277 }
3278
3279 if ( isset( $meta_box['description'] ) ) {
3280 $html .= themify_meta_field_get_description( $meta_box['description'] );
3281 }
3282
3283 if ( !empty( $meta_box['before'] )) {
3284 $html = $meta_box['before'] . $html;
3285 }
3286 if ( !empty( $meta_box['after'] )) {
3287 $html .= $meta_box['after'];
3288 }
3289
3290 if ( $echo ) echo $html;
3291 return $html;
3292 }
3293 /**
3294 * Build custom write panels
3295 * This function is required to provide backward compatibility
3296 */
3297 function themify_build_write_panels( $args = null ) {
3298 }
3299 /**
3300 * featimgdropdown field type, creates an option to select image sizes
3301 *
3302 * @since 2.8.8
3303 */
3304 function themify_meta_field_featimgdropdown( $args ) {
3305 /** Define WP Featured Image sizes + blank + Themify's image script*/
3306 $themify_fi_sizes = themify_get_image_sizes_list();
3307 $meta_box = $args['meta_box'];
3308 ?>
3309 <select name="<?php esc_attr_e( $meta_box['name'] ); ?>">
3310 <?php foreach($themify_fi_sizes as $option): ?>
3311 <option value="<?php esc_attr_e( $option['value'] ); ?>" <?php selected( $option['value'], $args['meta_value'] ); ?>><?php echo esc_html( $option['name'] ); ?></option>
3312 <?php endforeach; ?>
3313 </select>
3314 <?php if ( isset( $meta_box['description'] ) ) : ?>
3315 <span class="themify_field_description"><?php echo wp_kses_post( $meta_box['description'] ); ?></span>
3316 <?php endif; // meta_box description
3317 }
3318 /**
3319 * Outputs html to display alert messages in post edit/new screens. Excludes pages.
3320 * @since 1.2.2
3321 */
3322 function themify_prompt_message() {
3323 if(class_exists('Themify_Builder_Model',false)){
3324 Themify_Builder_Model::check_plugins_compatible();
3325 }
3326 if(!Themify_Enqueue_Assets::createDir()){
3327 if ( class_exists( 'Themify_System_Status', false ) && Themify_System_Status::is_optional_notice_dismissed_for_key( 'updir' ) ) {
3328 return;
3329 }
3330 echo '<div class="notice notice-error"><p><strong>'.__('Themify:','themify').'</strong></p><p>'.__('It looks like the WordPress upload folder path is set wrong or have file permission issue. Please check the upload path on WP Settings > Media. Make sure the folder is set correctly and it has correct file permission.','themify').'</p>';
3331 if ( current_user_can( 'manage_options' ) && class_exists( 'Themify_System_Status', false ) ) {
3332 $dismiss_url = Themify_System_Status::get_optional_notice_dismiss_url( 'updir' );
3333 if ( $dismiss_url ) {
3334 echo '<p class="tf-status-notice-dismiss"><a href="' . esc_url( $dismiss_url ) . '">' . esc_html__( 'Dismiss (do not show again)', 'themify' ) . '</a></p>';
3335 }
3336 }
3337 echo '</div>';
3338 }
3339 }
3340 add_action( 'admin_enqueue_scripts', 'themify_enqueue_scripts', 12 );
3341
3342 // register custom field types only available in the framework
3343 function themify_meta_field_page_layout( $args ) {
3344 $option_name = isset( $args['meta_box']['name'] ) ? $args['meta_box']['name'] : 'page_layout';
3345 $page_layout = get_post_meta( get_the_ID(), $option_name, true );
3346 $content_width = get_post_meta( get_the_ID(), 'content_width', true );
3347 $section_scroll = get_post_meta( get_the_ID(), 'section_full_scrolling', true );
3348 if ( $section_scroll === 'yes' ) {
3349 $args['meta_value'] = 'section_scroll';
3350 } else if ( $content_width === 'full_width' ) {
3351 $args['meta_value'] = 'full_width';
3352 }
3353
3354 echo '<div class="themify_field-layout">';
3355 $meta_box = $args['meta_box'];
3356 $meta_value = $args['meta_value'];
3357 extract( $args, EXTR_OVERWRITE );
3358 $ops_html = '';
3359
3360 foreach ( $meta_box['meta'] as $options ) {
3361 if ( ( '' == $meta_value || !$meta_value || !isset($meta_value)) && ( isset( $options['selected'] ) && $options['selected'] ) ) {
3362 $meta_value = $options['value'];
3363 }
3364 $class = $meta_value == $options['value']?'selected':'';
3365
3366 if(isset($meta_box['show_title'])){
3367 $title = isset($options['title'])? $options['title']: ucwords(str_replace('-', ' ', $options['value']));
3368 } else {
3369 $title = '';
3370 }
3371 $w= isset($option['w'])?$option['w']:'46';
3372 $h= isset($option['w'])?$option['w']:'35';
3373 // Check image src whether absolute url or relative url
3374 $img_src = ( '' != parse_url( $options['img'], PHP_URL_SCHEME) ) ? $options['img'] : get_template_directory_uri() . '/' . $options['img'];
3375
3376 $ops_html .= sprintf('<a href="#" class="preview-icon %s"><img src="%s" alt="%s" width="'.$w.'" height="'.$h.'" loading="lazy" decoding="async"/><span class="tm-option-title">%s</span></a>',
3377 $class,
3378 esc_url( $img_src ),
3379 esc_attr( $options['value'] ),
3380 $title
3381 );
3382 }
3383
3384 $page_layout = empty( $page_layout ) ? 'default' : $page_layout;
3385
3386 /* data-selected is the selected option, whereas 'value' is the thing stored in db */
3387 $html = sprintf('%s<input type="hidden" name="%s" value="%s" class="val" data-selected="%s" />',
3388 $ops_html, esc_attr( $meta_box['name'] ), esc_attr( $page_layout ), $meta_value );
3389
3390 if(isset($meta_box['label']) && '' != $meta_box['label'])
3391 $html = sprintf('<label for="%s">%s %s</label>', esc_attr( $meta_box['name'] ), $html, esc_attr( $meta_box['label'] ));
3392
3393 $html .= isset( $meta_box['description'] )? themify_meta_field_get_description($meta_box['description']) : '';
3394
3395 if( isset( $meta_box['before'] ) ) $html = $meta_box['before'] . $html;
3396 if( isset( $meta_box['after'] ) ) $html .= $meta_box['after'];
3397
3398 echo $html;
3399 echo '</div>';
3400 }
3401 add_action( 'themify_metabox/field/page_layout', 'themify_meta_field_page_layout', 10, 3 );
3402 add_action( 'themify_metabox/field/fontawesome', 'themify_meta_field_fontawesome', 10, 1 );
3403 add_action( 'themify_metabox/field/sidebar_visibility', 'themify_meta_field_sidebar_visibility', 10, 1 );
3404 add_action( 'themify_metabox/field/featimgdropdown', 'themify_meta_field_featimgdropdown', 10, 1 );
3405 add_action( 'themify_metabox/field/page_builder', 'themify_meta_field_page_builder', 10, 1 );
3406 add_action( 'admin_notices', 'themify_prompt_message' );
3407
3408 require_once THEMIFY_DIR . '/themify-import-functions.php';
3409 if(themify_is_ajax()){
3410 require_once THEMIFY_DIR . '/themify-wpajax.php';
3411 }
3412 if ( themify_is_themify_theme() ) {
3413
3414 /**
3415 * In this hook current user is authenticated so we can check for capabilities.
3416 *
3417 * @since 2.1.8
3418 */
3419 function themify_after_user_is_authenticated() {
3420 if ( current_theme_supports( 'themify-exclude-theme-from-wp-update' ) ) {
3421 add_filter( 'http_request_args', 'themify_hide_themes', 10, 2 );
3422 }
3423 /**
3424 * Themify - Admin Menu
3425 *******************************************************/
3426 add_action( 'admin_menu', 'themify_admin_nav', 1 );
3427 if ( current_user_can( 'manage_options' ) ) {
3428 add_action( 'load-toplevel_page_themify', function() {
3429 if ( isset( $_GET['tf_clean_gz'] ) ) {
3430 // clean gz files from the theme
3431 themify_remove_gzip( THEME_DIR );
3432 // clean gz files from all Themify plugins
3433 $plugins = get_plugins();
3434 foreach ( $plugins as $path => $data ) {
3435 if ( isset( $data['Author'] ) && $data['Author'] === 'Themify' ) {
3436 themify_remove_gzip( trailingslashit( WP_PLUGIN_DIR ) . dirname( $path ) );
3437 }
3438 }
3439 }
3440 } );
3441 }
3442 }
3443 add_action( 'init', 'themify_after_user_is_authenticated' );
3444
3445 /**
3446 * Hijacks themes passed for upgrade checking and remove those from Themify
3447 *
3448 * This feature is only required for legacy themes without "themify-" prefix,
3449 * to prevent updates from wp.org overwriting theme files.
3450 *
3451 * @param Bool
3452 * @param Array $r List of themes
3453 * @param String $url URL of upgrade check
3454 * @return Array
3455 * @since 1.1.8
3456 */
3457 function themify_hide_themes( $response, $url ){
3458 if ( 0 === strpos( $url, 'https://api.wordpress.org/themes/update-check' ) ) {
3459 $themes = json_decode( $response['body']['themes'] );
3460 unset( $themes->themes->{get_option( 'template' )},$themes->themes->{get_option( 'stylesheet' )} );
3461 $response['body']['themes'] = json_encode( $themes );
3462 }
3463
3464 return $response;
3465 }
3466
3467 require_once THEMIFY_DIR . '/class-tgm-plugin-activation.php';
3468 }
3469
3470 /**
3471 * List all files in a directory, recursively
3472 *
3473 * @return array
3474 */
3475 function themify_glob_recursive( $pattern, $flags = 0 ) {
3476 $files = glob( $pattern, $flags );
3477 foreach ( glob( dirname( $pattern ) . '/*', GLOB_ONLYDIR|GLOB_NOSORT ) as $dir ) {
3478 $files = array_merge( $files, themify_glob_recursive( $dir . '/' . basename( $pattern ), $flags ) );
3479 }
3480
3481 return $files;
3482 }
3483
3484 /**
3485 * Removes all .gz files found in the $path
3486 */
3487 function themify_remove_gzip( $path ) {
3488 $search = themify_glob_recursive( $path . '/*.gz' );
3489 foreach ( $search as $file ) {
3490 @unlink( $file );
3491 }
3492 }
3493
3494 /**
3495 * Loads Term Cover feature, an option to add an image to taxonomy terms
3496 *
3497 * @since 7.0
3498 * @return void
3499 */
3500 function themify_load_term_cover_feature() {
3501 if ( current_theme_supports( 'themify-term-cover' ) ) {
3502 require_once THEMIFY_DIR . '/class-tf-term-image.php';
3503 }
3504 }
3505 add_action( 'admin_init', 'themify_load_term_cover_feature' );
3506
3507 function themify_gutenberg_admin_css() {
3508 if ( ! is_admin() ) {
3509 return;
3510 }
3511 $screen = get_current_screen();
3512 if ( empty( $screen ) || ! $screen->is_block_editor() ) {
3513 return;
3514 }
3515 $handle = 'themify-gutenberg-content';
3516 if ( ! wp_style_is( $handle, 'registered' ) ) {
3517 wp_register_style( $handle, false, array(), THEMIFY_VERSION );
3518 }
3519 wp_enqueue_style( $handle );
3520 wp_add_inline_style( $handle, '
3521 .wp-block-post-content{
3522 padding:0 3%
3523 }
3524 :is(.wp-block-post-title,.editor-post-title,.block-editor-block-list__layout){
3525 padding-inline:3%
3526 }
3527 ' );
3528 }
3529 add_action( 'enqueue_block_assets', 'themify_gutenberg_admin_css' );
3530
3531 /**
3532 * WordPress 6.2 and earlier do not route enqueue_block_assets styles into the
3533 * editor canvas. Keep the previous admin-head behaviour for those versions.
3534 */
3535 function themify_gutenberg_admin_css_legacy() {
3536 global $wp_version;
3537 if ( version_compare( (string) $wp_version, '6.3', '>=' ) ) {
3538 return;
3539 }
3540 $screen = get_current_screen();
3541 if ( empty( $screen ) || ! $screen->is_block_editor() ) {
3542 return;
3543 }
3544 echo '<style>
3545 .wp-block-post-content{
3546 padding:0 3%
3547 }
3548 .themify-gutenberg-editor :is(.editor-post-title,.block-editor-block-list__layout){
3549 padding-inline:3%
3550 }
3551 </style>';
3552 }
3553 add_action( 'admin_head', 'themify_gutenberg_admin_css_legacy' );
3554