first commit
@@ -0,0 +1,575 @@
|
||||
<?php
|
||||
namespace Nimble;
|
||||
// Exit if accessed directly
|
||||
if ( !defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REGISTER PAGE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// function nb_register_settings() {
|
||||
// add_option( 'myplugin_option_name', 'This is my option value.');
|
||||
// register_setting( 'myplugin_options_group', 'myplugin_option_name', '\Nimble\myplugin_callback' );
|
||||
// }
|
||||
// add_action( 'admin_init', '\Nimble\nb_register_settings' );
|
||||
|
||||
function nb_register_options_page() {
|
||||
if ( !sek_current_user_can_access_nb_ui() )
|
||||
return;
|
||||
add_options_page(
|
||||
apply_filters( 'nb_admin_settings_title', __('Nimble Builder', 'text-domain') ),
|
||||
apply_filters( 'nb_admin_settings_title', __('Nimble Builder', 'text-domain') ),
|
||||
'manage_options',
|
||||
NIMBLE_OPTIONS_PAGE,
|
||||
'\Nimble\nb_options_page'
|
||||
);
|
||||
}
|
||||
add_action( 'admin_menu', '\Nimble\nb_register_options_page');
|
||||
|
||||
// callback of add_options_page()
|
||||
// fired @'admin_menu'
|
||||
function nb_options_page() {
|
||||
$option_tabs = Nimble_Manager()->admin_option_tabs;
|
||||
$active_tab_id = nb_get_active_option_tab();
|
||||
$default_title = esc_html( get_admin_page_title() );
|
||||
$page_title = isset( $option_tabs[$active_tab_id] ) ? $option_tabs[$active_tab_id]['page_title'] : $default_title;
|
||||
$page_title = empty($page_title) ? $default_title : $page_title;
|
||||
?>
|
||||
|
||||
<div id="nimble-options" class="wrap">
|
||||
<h1 class="nb-option-page-title">
|
||||
<?php
|
||||
printf('<span class="sek-nimble-title-icon"><img src="%1$s" alt="Build with Nimble Builder"></span>',
|
||||
esc_url( NIMBLE_BASE_URL.'/assets/img/nimble/nimble_icon.svg?ver='.NIMBLE_VERSION )
|
||||
);
|
||||
echo apply_filters( 'nimble_parse_admin_text', esc_html( $page_title ) ) . wp_kses_post( apply_filters( 'nimble_option_title_icon_after', '' ) );
|
||||
?>
|
||||
</h1>
|
||||
<div class="nav-tab-wrapper">
|
||||
<?php
|
||||
$allowed_tags = array(
|
||||
'div' => array('class'=>true),
|
||||
'span' => array('class'=>true),
|
||||
'img' => array('class'=>true, 'src'=>true, 'alt'=>true),
|
||||
);
|
||||
foreach ($option_tabs as $tab_id => $tab_data ) {
|
||||
printf('<a class="nav-tab %1$s" href="%2$s">%3$s</a>',
|
||||
$tab_id === nb_get_active_option_tab() ? 'nav-tab-active' : '',
|
||||
esc_url( admin_url( NIMBLE_OPTIONS_PAGE_URL ) . '&tab=' . $tab_id ),
|
||||
wp_kses($tab_data['title'], $allowed_tags)
|
||||
);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="tab-content-wrapper">
|
||||
<?php
|
||||
$_cb = $option_tabs[$active_tab_id]['content'];
|
||||
if( is_string( $_cb ) && !empty( $_cb ) ) {
|
||||
if ( function_exists( $_cb ) ) {
|
||||
call_user_func( $_cb );
|
||||
} else {
|
||||
echo esc_attr($_cb);
|
||||
}
|
||||
} else if ( is_array($_cb) && 2 == count($_cb) ) {
|
||||
if ( is_object($_cb[0]) ) {
|
||||
$to_return = call_user_func( array( $_cb[0] , $_cb[1] ) );
|
||||
}
|
||||
//instantiated with an instance property holding the object ?
|
||||
else if ( class_exists($_cb[0]) ) {
|
||||
|
||||
/* PHP 5.3- compliant*/
|
||||
$class_vars = get_class_vars( $_cb[0] );
|
||||
|
||||
if ( isset( $class_vars[ 'instance' ] ) && method_exists( $class_vars[ 'instance' ], $_cb[1]) ) {
|
||||
$to_return = call_user_func( array( $class_vars[ 'instance' ] , $_cb[1] ) );
|
||||
}
|
||||
|
||||
else {
|
||||
$_class_obj = new $_cb[0]();
|
||||
if ( method_exists($_class_obj, $_cb[1]) )
|
||||
$to_return = call_user_func( array( $_class_obj, $_cb[1] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div>
|
||||
</div><!-- .wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* ADD SETTINGS LINKS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
function nb_settings_link($links) {
|
||||
$doc_link = sprintf('<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>', 'https://docs.presscustomizr.com/article/337-getting-started-with-the-nimble-builder-plugin', __('Docs', 'text-doma') );
|
||||
array_unshift($links, $doc_link );
|
||||
$settings_link = sprintf('<a href="%1$s">%2$s</a>',
|
||||
add_query_arg( array( 'tab' => 'options' ), admin_url( NIMBLE_OPTIONS_PAGE_URL ) ),
|
||||
__('Settings', 'text-doma')
|
||||
);
|
||||
array_unshift($links, $settings_link );
|
||||
return $links;
|
||||
}
|
||||
add_filter("plugin_action_links_".plugin_basename(NIMBLE_PLUGIN_FILE), '\Nimble\nb_settings_link' );
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SAVE OPTION HOOK + CUSTOMIZABLE REDIRECTION
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// fired @'admin_post'
|
||||
function nb_save_options() {
|
||||
do_action('nb_admin_post');
|
||||
//wp_safe_redirect( urldecode( admin_url( NIMBLE_OPTIONS_PAGE_URL ) ) );
|
||||
nb_admin_redirect();
|
||||
}
|
||||
add_action( 'admin_post', '\Nimble\nb_save_options' );
|
||||
|
||||
|
||||
// fired @'admin_post'
|
||||
function nb_admin_redirect() {
|
||||
$url = sanitize_text_field(
|
||||
wp_unslash( $_POST['_wp_http_referer'] ) // Input var okay.
|
||||
);
|
||||
// Default option url : urldecode( admin_url( NIMBLE_OPTIONS_PAGE_URL ) )
|
||||
$url = urldecode( $url );
|
||||
$url = empty($url) ? urldecode( admin_url( NIMBLE_OPTIONS_PAGE_URL ) ) : $url;
|
||||
// Finally, redirect back to the admin page.
|
||||
// Note : filter 'nimble_admin_redirect_url' is used in NB pro to add query params used to display warning/error messages
|
||||
wp_safe_redirect( apply_filters('nimble_admin_redirect_url', $url ) );
|
||||
exit;
|
||||
}
|
||||
|
||||
// @return bool
|
||||
function nb_has_valid_nonce( $option_group = 'nb-options-save', $nonce = 'nb-options-nonce' ) {
|
||||
// If the field isn't even in the $_POST, then it's invalid.
|
||||
if ( !isset( $_POST[$nonce] ) ) { // Input var okay.
|
||||
return false;
|
||||
}
|
||||
return wp_verify_nonce( wp_unslash( $_POST[$nonce] ), $option_group );
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REGISTER TABS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
Nimble_Manager()->admin_option_tabs = array();
|
||||
// @return void
|
||||
function nb_register_option_tab( $tab ) {
|
||||
$tab = wp_parse_args( $tab, array(
|
||||
'id' => '',
|
||||
'title' => '',
|
||||
'page_title' => '',
|
||||
'content' => '',
|
||||
));
|
||||
Nimble_Manager()->admin_option_tabs[$tab['id']] = $tab;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function nb_get_active_option_tab() {
|
||||
// check that we have a tab param and that this tab is registered
|
||||
$tab_id = isset( $_GET['tab'] ) ? sanitize_text_field($_GET['tab']) : 'welcome';
|
||||
if ( !array_key_exists( $tab_id, Nimble_Manager()->admin_option_tabs ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => invalid tab');
|
||||
$tab_id = 'welcome';
|
||||
}
|
||||
return $tab_id;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* WELCOME PAGE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
nb_register_option_tab([
|
||||
'id' => 'welcome',
|
||||
'title' => __('Welcome', 'text-doma'),
|
||||
'page_title' => __('Nimble Builder', 'nimble' ),
|
||||
'content' => '\Nimble\print_welcome_page',
|
||||
]);
|
||||
function print_welcome_page() {
|
||||
?>
|
||||
<div class="nimble-welcome-content">
|
||||
<?php echo wp_kses_post(sek_get_welcome_block()); ?>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<hr/>
|
||||
<div>
|
||||
<h2><?php _e('Watch the video below for a brief overview of Nimble Builder features', 'text-doma'); ?></h2>
|
||||
<iframe src="https://player.vimeo.com/video/328473405?loop=1&title=0&byline=0&portrait=0" width="640" height="424" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* DATA CLEANING for #826
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Fired when click on button in admin options
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/826
|
||||
function sek_clean_all_nimble_data() {
|
||||
if ( !isset( $_GET['clean_nb'] ) )
|
||||
return;
|
||||
|
||||
// Do we have a nonce passed ?
|
||||
if ( !isset( $_GET['ecnon'] ) )
|
||||
return;
|
||||
|
||||
// validate the nonce and verify the user as permission to save.
|
||||
if ( !wp_verify_nonce( wp_unslash( $_GET['ecnon'] ), 'nb-base-options' ) || !current_user_can( 'manage_options' ) )
|
||||
return;
|
||||
|
||||
// Nimble CPT for skoped sections, for user templates, for user sections
|
||||
$nb_cpt_list = [ 'NIMBLE_CPT', 'NIMBLE_TEMPLATE_CPT', 'NIMBLE_SECTION_CPT' ];
|
||||
foreach( $nb_cpt_list as $nb_cpt ) {
|
||||
if ( !defined( $nb_cpt ) )
|
||||
continue;
|
||||
$nb_cpt = constant($nb_cpt);
|
||||
$query = new \WP_Query(
|
||||
array(
|
||||
'post_type' => $nb_cpt,
|
||||
'post_status' => get_post_stati(),
|
||||
'posts_per_page' => -1,
|
||||
'no_found_rows' => true,
|
||||
'cache_results' => true,
|
||||
'update_post_meta_cache' => false,
|
||||
'update_post_term_cache' => false,
|
||||
'lazy_load_term_meta' => false,
|
||||
)
|
||||
);
|
||||
if ( !is_array( $query->posts ) || empty( $query->posts ) ) {
|
||||
continue;
|
||||
}
|
||||
foreach ( $query->posts as $post_object ) {
|
||||
//permanently delete post ( unlike wp_trash_post() )
|
||||
wp_delete_post($post_object->ID);
|
||||
}
|
||||
}
|
||||
|
||||
// Nimble options
|
||||
$nb_opts = [
|
||||
'NIMBLE_OPT_SEKTION_POST_INDEX',
|
||||
'NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS',
|
||||
'NIMBLE_OPT_FOR_MODULE_CSS_READING_STATUS',
|
||||
'NIMBLE_OPT_NAME_FOR_MOST_USED_FONTS',
|
||||
'NIMBLE_OPT_FOR_GLOBAL_CSS',
|
||||
'NIMBLE_OPT_NAME_FOR_SECTION_JSON',
|
||||
'NIMBLE_OPT_NAME_FOR_BACKWARD_FIXES',
|
||||
// admin options
|
||||
'NIMBLE_OPT_NAME_FOR_SHORTCODE_PARSING',
|
||||
'NIMBLE_OPT_NAME_FOR_DEBUG_MODE'
|
||||
];
|
||||
foreach( $nb_opts as $opt_name ) {
|
||||
if ( !defined( $opt_name ) )
|
||||
continue;
|
||||
$opt_name = constant($opt_name);
|
||||
delete_option( $opt_name );
|
||||
}
|
||||
|
||||
// clean other options like : nimble_start_date, nimble_started_with_version, nimble_version,
|
||||
foreach( [
|
||||
'nimble_start_date',
|
||||
'nimble_started_with_version',
|
||||
'nimble_version_upgraded_from',
|
||||
'nimble_version',
|
||||
'nimble_last_update_notice',
|
||||
'__nimble_options__'//<= deprecated option name
|
||||
] as $opt_name ) {
|
||||
delete_option( $opt_name );
|
||||
}
|
||||
|
||||
// clean options like nimble___skp__post_page_1010 ( old way to map skope_id and skoped post )
|
||||
sek_clean_options_starting_like( 'nimble___');
|
||||
sek_clean_options_starting_like( 'nimblebuilder_pro_');
|
||||
|
||||
// Nimble transients
|
||||
$nb_transients = [
|
||||
'NIMBLE_FEEDBACK_NOTICE_ID',
|
||||
'NIMBLE_FAWESOME_TRANSIENT_ID',
|
||||
'NIMBLE_GFONTS_TRANSIENT_ID',
|
||||
'NIMBLE_FEEDBACK_STATUS_TRANSIENT_ID',
|
||||
'NIMBLE_API_CHECK_TRANSIENT_ID'
|
||||
];
|
||||
foreach( $nb_transients as $trans_id ) {
|
||||
if ( !defined( $trans_id ) )
|
||||
continue;
|
||||
$trans_id = constant($trans_id);
|
||||
delete_transient( $trans_id );
|
||||
}
|
||||
// => remove all other transients
|
||||
sek_clean_transients_like( 'nimble_' );//'nimble_api_posts', 'nimble_api_tmpl_' . $tmpl_name
|
||||
sek_clean_transients_like( 'nimble_preset_sections_' );//old transient for storing preset sections. Now fetched remotely. See #802
|
||||
sek_clean_transients_like( 'section_params_transient' );//old transient that may still be there
|
||||
sek_clean_transients_like( 'section_params_transient' );//old transient that may still be there
|
||||
|
||||
|
||||
// Nimble CSS stylesheets
|
||||
$css_dir_list = [ 'NIMBLE_DEPREC_ONE_CSS_FOLDER_NAME', 'NIMBLE_DEPREC_TWO_CSS_FOLDER_NAME', 'NIMBLE_CSS_FOLDER_NAME' ];
|
||||
global $wp_filesystem;
|
||||
require_once ( ABSPATH . '/wp-admin/includes/file.php' );
|
||||
WP_Filesystem();
|
||||
$upload_dir = wp_get_upload_dir();
|
||||
|
||||
foreach( $css_dir_list as $css_dir ) {
|
||||
if ( !defined( $css_dir ) )
|
||||
continue;
|
||||
$css_dir = constant( $css_dir );
|
||||
if ( is_multisite() ) {
|
||||
$site = get_site();
|
||||
$network_id = $site->site_id;
|
||||
$site_id = $site->blog_id;
|
||||
$css_dir = trailingslashit( $css_dir ) . trailingslashit( $network_id ) . $site_id;
|
||||
}
|
||||
|
||||
$folder_path = wp_normalize_path( trailingslashit( $upload_dir['basedir'] ) . $css_dir );
|
||||
if ( $wp_filesystem->exists( $folder_path ) ) {
|
||||
$wp_filesystem->rmdir( $folder_path, true );
|
||||
}
|
||||
}
|
||||
return 'success';
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* OPTIONS PAGE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
nb_register_option_tab([
|
||||
'id' => 'options',
|
||||
'title' => __('Options', 'text-doma'),
|
||||
'page_title' => __('Nimble Builder Options', 'nimble' ),
|
||||
'content' => '\Nimble\print_options_page',
|
||||
]);
|
||||
function print_options_page() {
|
||||
?>
|
||||
<form method="post" action="<?php echo esc_html( admin_url( 'admin-post.php' ) ); ?>">
|
||||
<table class="form-table" role="presentation">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Shortcodes', 'text_doma'); ?></th>
|
||||
<td>
|
||||
<fieldset><legend class="screen-reader-text"><span><?php _e('Shortcodes', 'text_doma'); ?></span></legend>
|
||||
<?php
|
||||
$shortcode_opt_val = get_option( NIMBLE_OPT_NAME_FOR_SHORTCODE_PARSING );
|
||||
?>
|
||||
<label for="nb_shortcodes_parsed_in_czr"><input name="nb_shortcodes_parsed_in_czr" type="checkbox" id="nb_shortcodes_parsed_in_czr" value="on" <?php checked( $shortcode_opt_val, 'on' ); ?>>
|
||||
<?php _e('Parse shortcodes when building your pages in the customizer', 'text_doma'); ?></label>
|
||||
<p class="description"><?php _e('Shortcodes are disabled by default when customizing to prevent any conflicts with Nimble Builder interface.', 'text_doma'); ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Widgets Module', 'text_doma'); ?></th>
|
||||
<td>
|
||||
<fieldset><legend class="screen-reader-text"><span><?php _e('Widgets module', 'text_doma'); ?></span></legend>
|
||||
<?php
|
||||
$widget_disabled_opt_val = get_option( NIMBLE_OPT_NAME_FOR_DISABLING_WIDGET_MODULE );
|
||||
?>
|
||||
<label for="nb_widgets_disabled_in_czr"><input name="nb_widgets_disabled_in_czr" type="checkbox" id="nb_widgets_disabled_in_czr" value="on" <?php checked( $widget_disabled_opt_val, 'on' ); ?>>
|
||||
<?php _e('Disable the Widgets Module', 'text_doma'); ?></label>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Debug Mode', 'text_doma'); ?></th>
|
||||
<td>
|
||||
<fieldset><legend class="screen-reader-text"><span><?php _e('Debug Mode', 'text_doma'); ?></span></legend>
|
||||
<?php
|
||||
$nb_debug_mode_opt_val = get_option( NIMBLE_OPT_NAME_FOR_DEBUG_MODE );
|
||||
?>
|
||||
<label for="nb_debug_mode_active"><input name="nb_debug_mode_active" type="checkbox" id="nb_debug_mode_active" value="on" <?php checked( $nb_debug_mode_opt_val, 'on' ); ?>>
|
||||
<?php _e('Activate the debug mode when customizing', 'text_doma'); ?></label>
|
||||
<p class="description"><?php _e('In debug mode, during customization Nimble Builder deactivates all modules content and prints only the structure of your sections. This lets you troubleshoot, remove or edit your modules safely.', 'text_doma'); ?></p>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
do_action('nb_admin_options_tab_after_content');
|
||||
wp_nonce_field( 'nb-base-options', 'nb-base-options-nonce' );
|
||||
submit_button();
|
||||
?>
|
||||
</form>
|
||||
<hr/>
|
||||
<table class="form-table" role="presentation">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><?php _e('Remove all Nimble Builder data', 'text_doma'); ?></th>
|
||||
<td>
|
||||
<fieldset><legend class="screen-reader-text"><span><?php _e('Remove all Nimble Builder data', 'text_doma'); ?></span></legend>
|
||||
<?php
|
||||
$refresh_url = add_query_arg( array( 'tab' => 'options', 'clean_nb' => 'true' ), admin_url( NIMBLE_OPTIONS_PAGE_URL ));
|
||||
ob_start();
|
||||
?>
|
||||
var nb_toggle_clean_button = function() {
|
||||
jQuery( function($) {
|
||||
$('.nb-clean-traces-confirm').stop().slideToggle('fast');
|
||||
});
|
||||
};
|
||||
var _nonce_value, _url
|
||||
var nb_refresh_opt_page = function() {
|
||||
jQuery( function($) {
|
||||
_nonce_value = $('#nb-base-options-nonce').val();
|
||||
_url = '<?php echo esc_url($refresh_url); ?>';
|
||||
// add nonce as param so NB can verify it when the page reloads
|
||||
if ( _nonce_value ) {
|
||||
_url = _url + '&ecnon=' + _nonce_value;// looks like site.com/wp-admin/options-general.php?page=nb-options&tab=options&clean_nb=true&ecnon=7cc5758b65
|
||||
}
|
||||
window.location.href = _url;
|
||||
});
|
||||
};
|
||||
<?php
|
||||
$script = ob_get_clean();
|
||||
wp_register_script( 'nb_options_js', '');
|
||||
wp_enqueue_script( 'nb_options_js' );
|
||||
wp_add_inline_script( 'nb_options_js', $script );
|
||||
?>
|
||||
<?php $clean_nb = isset( $_GET['clean_nb'] ) ? sanitize_text_field($_GET['clean_nb']) : false; ?>
|
||||
<?php if ( $clean_nb ) : ?>
|
||||
<?php $status = sek_clean_all_nimble_data(); ?>
|
||||
<?php if ( 'success' === $status ) : ?>
|
||||
<div id="message" class="updated notice">
|
||||
<p class="nb-clean-traces-success"><strong><?php _e('All Nimble Builder data have been successfully removed from your WordPress website.', 'text_doma'); ?></strong></p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div id="message" class="error notice">
|
||||
<p><strong><?php _e('Security problem when trying to remove Nimble Builder data.', 'text_doma'); ?></strong></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<p class="description"><?php _e('This will permanently remove all data created by Nimble Builder and stored in your database or as stylesheets : page customizations, custom sections, custom templates, options, CSS stylesheets.', 'text_doma'); ?></p><br/>
|
||||
<button class="button" onclick="window.nb_toggle_clean_button()"><?php _e('Remove now', 'text_doma'); ?></button>
|
||||
<div class="nb-clean-traces-confirm" style="display:none">
|
||||
<p class="description"><?php _e('Once you delete Nimble Builder data, there is no going back. Please be certain. ', 'text_doma'); ?></p><br/>
|
||||
<button class="button nb-permanent-removal-btn" onclick="window.nb_refresh_opt_page()"><?php _e('Yes I want to clean all data', 'text_doma'); ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
add_action( 'nb_admin_post', '\Nimble\nb_save_base_options' );
|
||||
// hook : nb_admin_post
|
||||
function nb_save_base_options() {
|
||||
// First, validate the nonce and verify the user as permission to save.
|
||||
if ( !nb_has_valid_nonce( 'nb-base-options', 'nb-base-options-nonce' ) || !current_user_can( 'manage_options' ) )
|
||||
return;
|
||||
|
||||
// Shortcode parsing when customizing
|
||||
nb_maybe_update_checkbox_option( NIMBLE_OPT_NAME_FOR_SHORTCODE_PARSING, 'off' );
|
||||
// Widgets disabled when customizing
|
||||
nb_maybe_update_checkbox_option( NIMBLE_OPT_NAME_FOR_DISABLING_WIDGET_MODULE, 'off' );
|
||||
// Debug mode
|
||||
nb_maybe_update_checkbox_option( NIMBLE_OPT_NAME_FOR_DEBUG_MODE, 'off' );
|
||||
}
|
||||
|
||||
// helper to update a checkbox option
|
||||
// the option is updated only if different than the default val or if the option exists already
|
||||
function nb_maybe_update_checkbox_option( $opt_name, $unchecked_value ) {
|
||||
$opt_value = get_option( $opt_name );
|
||||
$posted_value = array_key_exists( $opt_name, $_POST ) ? sanitize_text_field($_POST[$opt_name]) : $unchecked_value;
|
||||
if ( $unchecked_value !== $posted_value ) {
|
||||
update_option( $opt_name, esc_attr( $posted_value ), 'no' );
|
||||
} else {
|
||||
// if the option was never set before, then leave it not set
|
||||
// otherwise update it to 'off'
|
||||
if ( false !== $opt_value ) {
|
||||
update_option( $opt_name, $unchecked_value, 'no' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_action('nb_base_admin_options_registered');
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* RESTRICT USERS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
//register option tab and print the form
|
||||
if ( sek_is_pro() || sek_is_upsell_enabled() ) {
|
||||
$restrict_users_title = __('Manage authorized users', 'text-doma');
|
||||
if ( !sek_is_pro() ) {
|
||||
$restrict_users_title = sprintf( '<span class="sek-pro-icon"><img src="%1$s" alt="Pro feature"></span><span class="sek-title-after-icon">%2$s</span>',
|
||||
NIMBLE_BASE_URL.'/assets/czr/sek/img/pro_orange.svg?ver='.NIMBLE_VERSION,
|
||||
__('Manage authorized users', 'nimble' )
|
||||
);
|
||||
}
|
||||
nb_register_option_tab([
|
||||
'id' => 'restrict_users',
|
||||
'title' => $restrict_users_title,
|
||||
'page_title' => __('Manage authorized users', 'nimble' ),
|
||||
'content' => '\Nimble\print_restrict_users_options_content',
|
||||
]);
|
||||
|
||||
function print_restrict_users_options_content() {
|
||||
if ( !sek_is_pro() ) {
|
||||
?>
|
||||
<h4><?php _e('Nimble Builder can be used by default by all users with an administrator role. With Nimble Builder Pro you can decide which administrators are allowed to use the plugin.', 'text_domain'); ?></h4>
|
||||
<h4><?php _e('Unauthorized users will not see any reference to Nimble Builder when editing a page, in the customizer and in the WordPress admin screens.', 'text_domain') ?></h4>
|
||||
<a class="sek-pro-link" href="https://presscustomizr.com/nimble-builder-pro/" rel="noopener noreferrer" title="Go Pro" target="_blank"><?php _e('Go Pro', 'text_domain'); ?> <span class="dashicons dashicons-external"></span></a>
|
||||
<?php
|
||||
}
|
||||
do_action( 'nb_restrict_user_content' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SYSTEM INFO
|
||||
/* ------------------------------------------------------------------------- */
|
||||
nb_register_option_tab([
|
||||
'id' => 'system-info',
|
||||
'title' => __('System info', 'text-doma'),
|
||||
'page_title' => __('System info', 'nimble' ),
|
||||
'content' => '\Nimble\print_system_info',
|
||||
]);
|
||||
function print_system_info() {
|
||||
require_once( NIMBLE_BASE_PATH . '/inc/admin/system-info.php' );
|
||||
?>
|
||||
<h3><?php _e( 'System Informations', 'text_domain_to_be_chg' ); ?></h3>
|
||||
<h4><?php _e( 'Please include your system informations when posting support requests.' , 'text_domain_to_be_chg' ) ?></h4>
|
||||
<textarea readonly="readonly" onclick="this.focus();this.select()" id="system-info-textarea" name="tc-sysinfo" title="<?php _e( 'To copy the system info, click below then press Ctrl + C (PC) or Cmd + C (Mac).', 'text_domain_to_be_chg' ); ?>" style="width: 800px;min-height: 800px;font-family: Menlo,Monaco,monospace;background: 0 0;white-space: pre;overflow: auto;display:block;"><?php echo wp_kses_post(sek_config_infos()); ?></textarea>
|
||||
<?php
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* DOCUMENTATION
|
||||
/* ------------------------------------------------------------------------- */
|
||||
nb_register_option_tab([
|
||||
'id' => 'doc',
|
||||
'title' => __('Documentation', 'text-doma'),
|
||||
'page_title' => __('Nimble Builder knowledge base', 'nimble' ),
|
||||
'content' => '\Nimble\print_doc_page',
|
||||
]);
|
||||
function print_doc_page() {
|
||||
?>
|
||||
<div class="nimble-doc">
|
||||
<ul>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/337-getting-started-with-the-nimble-builder-plugin"><span>Getting started with Nimble Page Builder for WordPress</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/386-how-to-access-the-live-customization-interface-of-the-nimble-builder"><span>How to access the live customization interface of Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/371-how-to-start-building-from-a-blank-page-with-the-wordpress-nimble-builder"><span>How to start building from a blank ( full width ) page with WordPress Nimble Builder?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href=" https://docs.presscustomizr.com/article/427-how-to-insert-and-edit-a-module-with-nimble-builder"><span>How to insert and edit a module with Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/358-building-your-header-and-footer-with-the-nimble-builder"><span>How to build your WordPress header and footer with Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/350-how-to-use-shortcodes-from-other-plugins-with-the-nimble-builder-plugin"><span>How to embed WordPress shortcodes in your pages with Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/366-how-to-add-an-anchor-to-a-section-and-integrate-it-into-the-menu-with-the-nimble-page-builder"><span>How to add an anchor to a section and integrate it into the menu with Nimble Page Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/380-how-to-set-a-parallax-background-for-a-section-in-wordpress-with-the-nimble-builder"><span>How to set a parallax background for a section in WordPress with Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/343-designing-for-mobile-devices-with-wordpress-nimble-builder"><span>Designing for mobile devices with the WordPress Nimble Builder</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/414-nimble-builder-and-website-performances"><span>Nimble Builder and website performance 🚀</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/393-how-to-add-post-grids-to-any-wordpress-page-with-nimble-builder"><span>How to add post grids to any WordPress page with Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/372-design-your-404-page-with-the-nimble-builder"><span>How to design your 404 error page with Nimble Builder</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/391-how-to-export-and-import-templates-with-nimble-builder"><span>How to reuse sections and templates with the export / import feature of Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/401-how-to-create-a-video-background-with-nimble-builder-wordpress-plugin"><span>How to create a video background with Nimble Builder WordPress plugin ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/408-how-to-insert-a-responsive-carousel-in-your-wordpress-pages-with-nimble-builder"><span>How to insert a responsive carousel in your WordPress pages with Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/389-how-to-visualize-the-structure-of-the-content-created-with-nimble-builder"><span>How to visualize the structure of the content created with Nimble Builder ?</span></a></li>
|
||||
<li><a target="_blank" rel="noopener noreferrer" href="https://docs.presscustomizr.com/article/383-how-to-customize-the-height-of-your-sections-and-columns-with-the-nimble-builder"><span>How to customize the height of your sections and columns with Nimble Builder ?</span></a></li>
|
||||
|
||||
</ul>
|
||||
<a href="https://docs.presscustomizr.com/collection/334-nimble-page-builder" target="_blank" class="button button-primary button-hero" rel="noopener noreferrer"><span class="dashicons dashicons-search"></span> <?php _e('Explore Nimble Builder knowledge base', 'text-doma'); ?></a>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
namespace Nimble;
|
||||
// Exit if accessed directly
|
||||
if ( !defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
/**
|
||||
* Get system info
|
||||
* Inspired by the system infos page for Easy Digital Download plugin
|
||||
* @return string $return A string containing the info to output
|
||||
*/
|
||||
function sek_config_infos() {
|
||||
global $wpdb;
|
||||
|
||||
if ( !class_exists( 'Browser' ) ) {
|
||||
require_once( NIMBLE_BASE_PATH . '/inc/libs/browser.php' );
|
||||
}
|
||||
|
||||
$browser = new \Browser();
|
||||
|
||||
// Get theme info
|
||||
$theme_data = wp_get_theme();
|
||||
$theme = $theme_data->Name . ' ' . $theme_data->Version;
|
||||
$parent_theme = $theme_data->Template;
|
||||
if ( !empty( $parent_theme ) ) {
|
||||
$parent_theme_data = wp_get_theme( $parent_theme );
|
||||
$parent_theme = $parent_theme_data->Name . ' ' . $parent_theme_data->Version;
|
||||
}
|
||||
|
||||
$return = '### Begin System Info (Generated ' . date( 'Y-m-d H:i:s' ) . ') ###' . "";
|
||||
|
||||
// Site infos
|
||||
$return .= "\n" .'------------ SITE INFO' . "\n";
|
||||
$return .= 'Site URL: ' . site_url() . "\n";
|
||||
$return .= 'Home URL: ' . home_url() . "\n";
|
||||
$return .= 'Multisite: ' . ( is_multisite() ? 'Yes' : 'No' ) . "\n";
|
||||
|
||||
// Browser infos
|
||||
$return .= "\n\n" . '------------ USER BROWSER' . "\n";
|
||||
$return .= $browser;
|
||||
|
||||
$locale = get_locale();
|
||||
|
||||
// WordPress config
|
||||
$return .= "\n\n" . '------------ WORDPRESS CONFIG' . "\n";
|
||||
$return .= 'WP Version: ' . get_bloginfo( 'version' ) . "\n";
|
||||
$return .= 'Language: ' . ( !empty( $locale ) ? $locale : 'en_US' ) . "\n";
|
||||
$return .= 'Permalink Structure: ' . ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ) . "\n";
|
||||
$return .= 'Active Theme: ' . $theme . "\n";
|
||||
if ( $parent_theme !== $theme ) {
|
||||
$return .= 'Parent Theme: ' . $parent_theme . "\n";
|
||||
}
|
||||
$return .= 'Show On Front: ' . get_option( 'show_on_front' ) . "\n";
|
||||
|
||||
// Only show page specs if frontpage is set to 'page'
|
||||
if( get_option( 'show_on_front' ) == 'page' ) {
|
||||
$front_page_id = get_option( 'page_on_front' );
|
||||
$blog_page_id = get_option( 'page_for_posts' );
|
||||
|
||||
$return .= 'Page On Front: ' . ( $front_page_id != 0 ? get_the_title( $front_page_id ) . ' (#' . $front_page_id . ')' : 'Unset' ) . "\n";
|
||||
$return .= 'Page For Posts: ' . ( $blog_page_id != 0 ? get_the_title( $blog_page_id ) . ' (#' . $blog_page_id . ')' : 'Unset' ) . "\n";
|
||||
}
|
||||
|
||||
$return .= 'ABSPATH: ' . ABSPATH . "\n";
|
||||
|
||||
$return .= 'WP_DEBUG: ' . ( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' ) . "\n";
|
||||
$return .= 'WP Memory Limit: ' . ( sek_let_to_num( WP_MEMORY_LIMIT )/( 1024 ) ) ."MB" . "\n";
|
||||
//$return .= 'Registered Post Stati: ' . implode( ', ', get_post_stati() ) . "\n";
|
||||
|
||||
// Nimble configuration
|
||||
$return .= "\n\n" . '------------ NIMBLE CONFIGURATION' . "\n";
|
||||
$return .= 'Version: ' . NIMBLE_VERSION . "\n";
|
||||
$return .= 'Upgraded From: ' . get_option( 'nimble_version_upgraded_from', 'None' ) . "\n";
|
||||
$return .= 'Started With: ' . get_option( 'nimble_started_with_version', 'None' ) . "\n";
|
||||
|
||||
// sept 2020 : filter added to allow printing NB Pro versions info
|
||||
$return = apply_filters('nb_admin_syst_info_after_nb_config', $return);
|
||||
|
||||
// Get plugins that have an update
|
||||
$updates = get_plugin_updates();
|
||||
|
||||
// Must-use plugins
|
||||
// NOTE: MU plugins can't show updates!
|
||||
$muplugins = get_mu_plugins();
|
||||
if( count( $muplugins ) > 0 ) {
|
||||
$return .= "\n\n" . '------------ MU PLUGINS' . "\n";
|
||||
|
||||
foreach( $muplugins as $plugin => $plugin_data ) {
|
||||
$return .= $plugin_data['Name'] . ': ' . $plugin_data['Version'] . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// WordPress active plugins
|
||||
$return .= "\n\n" . '------------ WP ACTIVE PLUGINS' . "\n";
|
||||
|
||||
$plugins = get_plugins();
|
||||
$active_plugins = get_option( 'active_plugins', array() );
|
||||
|
||||
foreach( $plugins as $plugin_path => $plugin ) {
|
||||
if( !in_array( $plugin_path, $active_plugins ) )
|
||||
continue;
|
||||
|
||||
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[$plugin_path]->update->new_version . ')' : '';
|
||||
$return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
|
||||
}
|
||||
|
||||
// WordPress inactive plugins
|
||||
$return .= "\n\n" . '------------ WP INACTIVE PLUGINS' . "\n";
|
||||
|
||||
foreach( $plugins as $plugin_path => $plugin ) {
|
||||
if( in_array( $plugin_path, $active_plugins ) )
|
||||
continue;
|
||||
|
||||
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[$plugin_path]->update->new_version . ')' : '';
|
||||
$return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
|
||||
}
|
||||
|
||||
if( is_multisite() ) {
|
||||
// WordPress Multisite active plugins
|
||||
$return .= "\n\n" . '------------ NETWORK ACTIVE PLUGINS' . "\n";
|
||||
|
||||
$plugins = wp_get_active_network_plugins();
|
||||
$active_plugins = get_site_option( 'active_sitewide_plugins', array() );
|
||||
|
||||
foreach( $plugins as $plugin_path ) {
|
||||
$plugin_base = plugin_basename( $plugin_path );
|
||||
|
||||
if( !array_key_exists( $plugin_base, $active_plugins ) )
|
||||
continue;
|
||||
|
||||
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[$plugin_path]->update->new_version . ')' : '';
|
||||
$plugin = get_plugin_data( $plugin_path );
|
||||
$return .= $plugin['Name'] . ': ' . $plugin['Version'] . $update . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Server configuration
|
||||
$return .= "\n\n" . '------------ WEBSERVER CONFIG' . "\n";
|
||||
$return .= 'PHP Version: ' . PHP_VERSION . "\n";
|
||||
$return .= 'MySQL Version: ' . $wpdb->db_version() . "\n";
|
||||
$return .= 'Webserver Info: ' . sanitize_text_field($_SERVER['SERVER_SOFTWARE']) . "\n";
|
||||
$return .= 'Write/Read permissions: ' . sek_get_write_permissions_status() . "\n";
|
||||
|
||||
// PHP configs
|
||||
$return .= "\n\n" . '------------ PHP CONFIG' . "\n";
|
||||
$return .= 'Memory Limit: ' . ini_get( 'memory_limit' ) . "\n";
|
||||
$return .= 'Upload Max Size: ' . ini_get( 'upload_max_filesize' ) . "\n";
|
||||
$return .= 'Post Max Size: ' . ini_get( 'post_max_size' ) . "\n";
|
||||
$return .= 'Upload Max Filesize: ' . ini_get( 'upload_max_filesize' ) . "\n";
|
||||
$return .= 'Time Limit: ' . ini_get( 'max_execution_time' ) . "\n";
|
||||
$return .= 'Max Input Vars: ' . ini_get( 'max_input_vars' ) . "\n";
|
||||
$return .= 'Display Errors: ' . ( ini_get( 'display_errors' ) ? 'On (' . ini_get( 'display_errors' ) . ')' : 'N/A' ) . "\n";
|
||||
$return .= 'PHP Arg Separator: ' . ini_get( 'arg_separator.output' ) . "\n";
|
||||
$return .= 'PHP Allow URL File Open: ' . ini_get( 'allow_url_fopen' ) . "\n";
|
||||
|
||||
// PHP extensions and such
|
||||
// $return .= "\n\n" . '------------ PHP EXTENSIONS' . "\n";
|
||||
// $return .= 'cURL: ' . ( function_exists( 'curl_init' ) ? 'Supported' : 'Not Supported' ) . "\n";
|
||||
// $return .= 'fsockopen: ' . ( function_exists( 'fsockopen' ) ? 'Supported' : 'Not Supported' ) . "\n";
|
||||
// $return .= 'SOAP Client: ' . ( class_exists( 'SoapClient' ) ? 'Installed' : 'Not Installed' ) . "\n";
|
||||
// $return .= 'Suhosin: ' . ( extension_loaded( 'suhosin' ) ? 'Installed' : 'Not Installed' ) . "\n";
|
||||
|
||||
$return .= "\n\n" . '### End System Info ###';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does Size Conversions
|
||||
*/
|
||||
function sek_let_to_num( $v ) {
|
||||
$l = substr( $v, -1 );
|
||||
$ret = substr( $v, 0, -1 );
|
||||
|
||||
switch ( strtoupper( $l ) ) {
|
||||
case 'P': // fall-through
|
||||
case 'T': // fall-through
|
||||
case 'G': // fall-through
|
||||
case 'M': // fall-through
|
||||
case 'K': // fall-through
|
||||
$ret *= 1024;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function sek_get_write_permissions_status() {
|
||||
$permission_issues = array();
|
||||
$writing_path_candidates = array();
|
||||
|
||||
$wp_upload_dir = wp_upload_dir();
|
||||
if ( $wp_upload_dir['error'] ) {
|
||||
$permission_issues[] = 'WordPress root uploads folder';
|
||||
}
|
||||
|
||||
$nimble_css_folder_path = $wp_upload_dir['basedir'] . '/' . NIMBLE_CSS_FOLDER_NAME;
|
||||
|
||||
if ( is_dir( $nimble_css_folder_path ) ) {
|
||||
$writing_path_candidates[ $nimble_css_folder_path ] = 'Nimble uploads folder';
|
||||
}
|
||||
$writing_path_candidates[ ABSPATH ] = 'WP root directory';
|
||||
|
||||
foreach ( $writing_path_candidates as $dir => $description ) {
|
||||
if ( !is_writable( $dir ) ) {
|
||||
$permission_issues[] = $description;
|
||||
}
|
||||
}
|
||||
|
||||
// oct 2020, for https://github.com/presscustomizr/nimble-builder/issues/749
|
||||
$base_module_css_uri = NIMBLE_BASE_PATH . '/assets/front/css/modules/';
|
||||
if ( !is_readable($base_module_css_uri) ) {
|
||||
$permission_issues[] = 'module css folder not readable';
|
||||
}
|
||||
|
||||
if ( $permission_issues ) {
|
||||
$message = 'NOK => issues with : ';
|
||||
$message .= implode( ' and ', $permission_issues );
|
||||
} else {
|
||||
$message = 'OK';
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
namespace Nimble;
|
||||
|
||||
if ( did_action('nimble_base_fmk_loaded') ) {
|
||||
if ( ( defined( 'CZR_DEV' ) && CZR_DEV ) || ( defined( 'NIMBLE_DEV' ) && NIMBLE_DEV ) ) {
|
||||
error_log( __FILE__ . ' => The czr_base_fmk has already been loaded' );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the namsepace as a global so we can use it when fired from another theme/plugin using the fmk
|
||||
global $czr_base_fmk_namespace;
|
||||
$czr_base_fmk_namespace = __NAMESPACE__ . '\\';
|
||||
|
||||
do_action( 'nimble_base_fmk_loaded' );
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CZR_Fmk_Base
|
||||
if ( !class_exists( 'CZR_Fmk_Base_Construct' ) ) :
|
||||
class CZR_Fmk_Base_Construct {
|
||||
static $instance;
|
||||
|
||||
public $registered_modules = array();//stores the collection of dynamic modules registration candidates
|
||||
public $registered_settings = array();//stores the collection of dynamic settings registration candidates
|
||||
|
||||
public $default_dynamic_setting_params = array();
|
||||
public $default_dynamic_module_params = array();
|
||||
|
||||
public $czr_css_attr = array();
|
||||
|
||||
public $current_module_params_when_ajaxing;// store the params when ajaxing and allows us to access the currently requested module params at any point of the ajax action
|
||||
|
||||
public static function czr_fmk_get_instance( $params ) {
|
||||
if ( !isset( self::$instance ) && !( self::$instance instanceof CZR_Fmk_Base ) ) {
|
||||
self::$instance = new CZR_Fmk_Base( $params );
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
//@param $params = array(
|
||||
// 'base_url' => '' <= path to root class folder
|
||||
//)
|
||||
function __construct( $params = array() ) {
|
||||
if ( !is_array( $params ) || empty( $params ) ) {
|
||||
error_log( 'CZR_Fmk_Base => constructor => missing params');
|
||||
return;
|
||||
}
|
||||
if ( empty( $params['base_url'] ) ) {
|
||||
error_log( 'CZR_Fmk_Base => constructor => wrong params');
|
||||
return;
|
||||
}
|
||||
|
||||
// DEFINITIONS
|
||||
if ( !defined( 'NIMBLE_FMK_BASE_URL' ) ) { define( 'NIMBLE_FMK_BASE_URL' , $params['base_url'] ); }
|
||||
if ( !defined( 'NIMBLE_FMK_BASE_VERSION' ) ) { define( 'NIMBLE_FMK_BASE_VERSION' , isset( $params['version'] ) ? $params['version'] : '1.0.0' ); }
|
||||
|
||||
// Cache the css attr used in the tmpl builder and in the localized params
|
||||
$this->czr_css_attr = $this->czr_fmk_get_customizer_controls_css_attr();
|
||||
|
||||
// Cache the default dynamic params
|
||||
$this->default_dynamic_setting_params = $this->czr_fmk_get_default_dynamic_setting_params();
|
||||
$this->default_dynamic_module_params = $this->czr_fmk_get_default_dynamic_module_params();
|
||||
|
||||
// Enqueue the fmk control js + a module tmpl
|
||||
$this->czr_enqueue_fmk_resources();
|
||||
|
||||
// ajax filters + template generator
|
||||
$this->czr_setup_ajax_tmpl();
|
||||
|
||||
// Dynamic Module Registration
|
||||
$this->czr_setup_dynamic_settings_registration();
|
||||
$this->czr_setup_dynamic_modules_registration();
|
||||
|
||||
// Content picker
|
||||
$this->czr_setup_content_picker_ajax_actions();
|
||||
}//__construct
|
||||
|
||||
|
||||
// fired in the constructor to cache the params in a property
|
||||
private function czr_fmk_get_default_dynamic_setting_params() {
|
||||
return array(
|
||||
'setting_id' => '',
|
||||
'dynamic_registration' => true,
|
||||
'module_type' => '',
|
||||
'option_value' => array(),
|
||||
|
||||
'setting' => array(
|
||||
'type' => 'option',
|
||||
'default' => array(),
|
||||
'transport' => 'refresh',
|
||||
'setting_class' => '',//array( 'path' => '', 'name' => '' )
|
||||
'sanitize_callback' => '',
|
||||
'validate_callback' => '',
|
||||
),
|
||||
|
||||
'section' => array(
|
||||
'id' => '',
|
||||
'title' => '',
|
||||
'panel' => '',
|
||||
'priority' => 10
|
||||
),
|
||||
|
||||
'control' => array(
|
||||
'label' => '',
|
||||
'type' => 'czr_module',
|
||||
'priority' => 10,
|
||||
'control_class' => ''//array( 'path' => '', 'name' => '' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// fired in the constructor to cache the params in a property
|
||||
private function czr_fmk_get_default_dynamic_module_params() {
|
||||
return array(
|
||||
'dynamic_registration' => true,
|
||||
'module_type' => '',
|
||||
|
||||
'sanitize_callback' => '', //<= used when dynamically registering a setting
|
||||
'validate_callback' => '', //<= used when dynamically registering a setting
|
||||
|
||||
'customizer_assets' => array(
|
||||
'control_js' => array(),
|
||||
'localized_control_js' => array()
|
||||
),
|
||||
'tmpl' => array()
|
||||
);
|
||||
}
|
||||
|
||||
// Copy of czr_fn_get_controls_css_attr() and the equivalent in Hueman Pro
|
||||
public function czr_fmk_get_customizer_controls_css_attr() {
|
||||
return apply_filters('czr_fmk_controls_css_attr',
|
||||
array(
|
||||
'multi_input_wrapper' => 'czr-multi-input-wrapper',
|
||||
'sub_set_wrapper' => 'czr-sub-set',
|
||||
'sub_set_input' => 'czr-input',
|
||||
'img_upload_container' => 'czr-imgup-container',
|
||||
|
||||
'edit_modopt_icon' => 'czr-toggle-modopt',
|
||||
'close_modopt_icon' => 'czr-close-modopt',
|
||||
'mod_opt_wrapper' => 'czr-mod-opt-wrapper',
|
||||
|
||||
|
||||
'items_wrapper' => 'czr-items-wrapper',
|
||||
'single_item' => 'czr-single-item',
|
||||
'item_content' => 'czr-item-content',
|
||||
'item_header' => 'czr-item-header',
|
||||
'item_title' => 'czr-item-title',
|
||||
'item_btns' => 'czr-item-btns',
|
||||
'item_sort_handle' => 'czr-item-sort-handle',
|
||||
|
||||
//remove dialog
|
||||
'display_alert_btn' => 'czr-display-alert',
|
||||
'remove_alert_wrapper' => 'czr-remove-alert-wrapper',
|
||||
'cancel_alert_btn' => 'czr-cancel-button',
|
||||
'remove_view_btn' => 'czr-remove-button',
|
||||
|
||||
'edit_view_btn' => 'czr-edit-view',
|
||||
//pre add dialog
|
||||
'open_pre_add_btn' => 'czr-open-pre-add-new',
|
||||
'adding_new' => 'czr-adding-new',
|
||||
'pre_add_wrapper' => 'czr-pre-add-wrapper',
|
||||
'pre_add_item_content' => 'czr-pre-add-view-content',
|
||||
'cancel_pre_add_btn' => 'czr-cancel-add-new',
|
||||
'add_new_btn' => 'czr-add-new',
|
||||
'pre_add_success' => 'czr-add-success'
|
||||
)
|
||||
);
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,274 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CZR_Fmk_Base
|
||||
if ( !class_exists( 'CZR_Fmk_Base_Load_Resources' ) ) :
|
||||
class CZR_Fmk_Base_Load_Resources extends CZR_Fmk_Base_Construct {
|
||||
|
||||
// fired in the constructor
|
||||
function czr_enqueue_fmk_resources() {
|
||||
// Enqueue the fmk control js
|
||||
add_action ( 'customize_controls_enqueue_scripts' , array( $this, 'ac_load_additional_controls_js' ) );
|
||||
add_action ( 'customize_controls_enqueue_scripts' , array( $this, 'ac_load_additional_controls_css' ) );
|
||||
|
||||
// Enqueue the base preview js
|
||||
//hook : customize_preview_init
|
||||
add_action ( 'customize_preview_init' , array( $this, 'ac_customize_load_preview_js' ) );
|
||||
|
||||
// adds specific js templates for the czr_module control
|
||||
add_action( 'customize_controls_print_footer_scripts', array( $this, 'ac_print_module_control_templates' ) , 1 );
|
||||
|
||||
add_action( 'customize_controls_print_footer_scripts', array( $this, 'ac_print_img_uploader_template' ) , 1 );
|
||||
}
|
||||
|
||||
|
||||
// hook : 'customize_controls_enqueue_scripts'
|
||||
function ac_load_additional_controls_js() {
|
||||
// Enqueue scripts/styles for the color picker.
|
||||
// Probably already enqueued by the theme controls, but let's make sure they are.
|
||||
wp_enqueue_script( 'wp-color-picker' );
|
||||
wp_enqueue_style( 'wp-color-picker' );
|
||||
|
||||
// July 2020 : compatibility with WP5.5 => wpColorPickerL10n are not loaded by WP core anymore, but we need them for the custom czr-alpha-colorpicker.js
|
||||
// see https://github.com/presscustomizr/nimble-builder/issues/729
|
||||
global $wp_version;
|
||||
if ( version_compare( $wp_version, '5.4.2' , '>=' ) ) {
|
||||
wp_localize_script(
|
||||
'wp-color-picker',
|
||||
'nb_wpColorPickerL10n',
|
||||
array(
|
||||
'clear' => __( 'Clear' ),
|
||||
'clearAriaLabel' => __( 'Clear color' ),
|
||||
'defaultString' => __( 'Default' ),
|
||||
'defaultAriaLabel' => __( 'Select default color' ),
|
||||
'pick' => __( 'Select Color' ),
|
||||
'defaultLabel' => __( 'Color value' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//'czr-customizer-fmk' will be enqueued as a dependency of 'font-customizer-control' only in plugin mode
|
||||
wp_enqueue_script(
|
||||
'czr-customizer-fmk',
|
||||
//dev / debug mode mode?
|
||||
sprintf(
|
||||
'%1$s/assets/js/%2$s',
|
||||
NIMBLE_FMK_BASE_URL,
|
||||
defined('CZR_DEV') && true === CZR_DEV ? '_0_ccat_czr-base-fmk.js' : '_0_ccat_czr-base-fmk.min.js'
|
||||
),
|
||||
array('customize-controls' , 'jquery', 'underscore'),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : NIMBLE_FMK_BASE_VERSION,
|
||||
$in_footer = true
|
||||
);
|
||||
|
||||
// When used with Customizr or Hueman, free and pro, we also need to load the theme js part
|
||||
if ( false !== strpos( czr_get_parent_theme_slug(), 'customizr' ) || false !== strpos( czr_get_parent_theme_slug(), 'hueman' ) ) {
|
||||
wp_enqueue_script(
|
||||
'czr-theme-customizer-fmk',
|
||||
//dev / debug mode mode?
|
||||
sprintf(
|
||||
'%1$s/assets/js/%2$s',
|
||||
NIMBLE_FMK_BASE_URL,
|
||||
defined('CZR_DEV') && true === CZR_DEV ? '_1_ccat_czr-theme-fmk.js' : '_1_ccat_czr-theme-fmk.min.js'
|
||||
),
|
||||
array( 'czr-customizer-fmk' ),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : NIMBLE_FMK_BASE_VERSION,
|
||||
$in_footer = true
|
||||
);
|
||||
}
|
||||
|
||||
$theme_data = wp_get_theme();
|
||||
$theme = $theme_data->Name . ' ' . $theme_data->Version;
|
||||
$parent_theme = $theme_data->Template;
|
||||
if ( !empty( $parent_theme ) ) {
|
||||
$parent_theme_data = wp_get_theme( $parent_theme );
|
||||
$parent_theme = $parent_theme_data->Name;
|
||||
}
|
||||
$parent_theme =strtolower($parent_theme);
|
||||
|
||||
//additional localized param when standalone plugin mode
|
||||
wp_localize_script(
|
||||
'czr-customizer-fmk',
|
||||
'serverControlParams',
|
||||
apply_filters( 'czr_js_customizer_control_params' ,
|
||||
array(
|
||||
'css_attr' => $this->czr_css_attr,
|
||||
'isDevMode' => ( defined('WP_DEBUG') && true === WP_DEBUG ) || ( defined('CZR_DEV') && true === CZR_DEV ),
|
||||
'docURL' => esc_url('docs.presscustomizr.com/'),
|
||||
'i18n' => array(
|
||||
'edit' => __('Edit', 'text_doma'),
|
||||
'close' => __('Close', 'text_doma'),
|
||||
'notset' => __('Not set', 'text_doma'),
|
||||
'successMessage' => __('Done !', 'text_doma'),
|
||||
|
||||
'readDocumentation' => __('Learn more about this in the documentation', 'text_doma'),
|
||||
'Settings' => __('Settings', 'text_doma'),
|
||||
'Options for' => __('Options for', 'text_doma'),
|
||||
|
||||
// img upload translation
|
||||
'select_image' => __( 'Select Image', 'text_doma' ),
|
||||
'change_image' => __( 'Change Image', 'text_doma' ),
|
||||
'remove_image' => __( 'Remove', 'text_doma' ),
|
||||
'default_image' => __( 'Default', 'text_doma' ),
|
||||
'placeholder_image' => __( 'No image selected', 'text_doma' ),
|
||||
'frame_title_image' => __( 'Select Image', 'text_doma' ),
|
||||
'frame_button_image' => __( 'Choose Image', 'text_doma' ),
|
||||
|
||||
'Customizing' => __('Customizing', 'text_doma'),
|
||||
),
|
||||
'paramsForDynamicRegistration' => apply_filters( 'czr_fmk_dynamic_setting_js_params', array() ),
|
||||
'activeTheme' => $parent_theme
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Enqueue the fmk css when standalone plugin
|
||||
// hook : 'customize_controls_enqueue_scripts'
|
||||
function ac_load_additional_controls_css() {
|
||||
wp_enqueue_style(
|
||||
'czr-fmk-controls-style',
|
||||
sprintf('%1$s/assets/css/czr-ccat-control-base%2$s.css', NIMBLE_FMK_BASE_URL, ( defined('WP_DEBUG') && true === WP_DEBUG ) ? '' : '.min'),
|
||||
array( 'customize-controls' ),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : NIMBLE_FMK_BASE_VERSION,
|
||||
$media = 'all'
|
||||
);
|
||||
|
||||
//select2 stylesheet
|
||||
//overriden by some specific style in czr-control-base.css
|
||||
wp_enqueue_style(
|
||||
'czr-select2-css',
|
||||
sprintf('%1$s/assets/css/lib/czrSelect2.min.css', NIMBLE_FMK_BASE_URL ),
|
||||
array( 'customize-controls' ),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : NIMBLE_FMK_BASE_VERSION,
|
||||
$media = 'all'
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'czr-font-awesome',
|
||||
sprintf('%1$s/assets/fonts/css/fontawesome-all.min.css', NIMBLE_FMK_BASE_URL ),
|
||||
array(),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : NIMBLE_FMK_BASE_VERSION,
|
||||
$media = 'all'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//hook : customize_preview_init
|
||||
function ac_customize_load_preview_js() {
|
||||
global $wp_version;
|
||||
|
||||
wp_enqueue_script(
|
||||
'czr-customizer-preview' ,
|
||||
sprintf(
|
||||
'%1$s/assets/js/%2$s',
|
||||
NIMBLE_FMK_BASE_URL,
|
||||
defined('CZR_DEV') && true === CZR_DEV ? 'czr-preview-base.js' : 'czr-preview-base.min.js'
|
||||
),
|
||||
array( 'customize-preview', 'underscore'),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : NIMBLE_FMK_BASE_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
//localizes
|
||||
wp_localize_script(
|
||||
'czr-customizer-preview',
|
||||
'serverPreviewParams',
|
||||
apply_filters('czr_base_fmk_customizer_preview_params' ,
|
||||
array(
|
||||
'themeFolder' => get_template_directory_uri(),
|
||||
//patch for old wp versions which don't trigger preview-ready signal => since WP 4.1
|
||||
'preview_ready_event_exists' => version_compare( $wp_version, '4.1' , '>=' ),
|
||||
'blogname' => get_bloginfo('name'),
|
||||
'isRTL' => is_rtl()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// DO WE STILL NEED TO PRINT THIS TMPL ?
|
||||
/////////////////////////////////////////////////////
|
||||
/// WHEN EMBEDDED IN A CONTROL //////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
//add specific js templates for the czr_module control
|
||||
//this is usually called in the manager for "registered" controls that need to be rendered with js
|
||||
//for this control, we'll do it another way because we need several js templates
|
||||
//=> that's why this control has not been "registered" and js templates are printed with the following action
|
||||
function ac_print_module_control_templates() {
|
||||
//Render the control wrapper for the CRUD types modules
|
||||
?>
|
||||
<?php //Render the control wrapper for the CRUD types modules ?>
|
||||
<script type="text/html" id="tmpl-customize-control-czr_module-content">
|
||||
<label for="{{ data.settings['default'] }}-button">
|
||||
|
||||
<# if ( data.label ) { #>
|
||||
<span class="customize-control-title">{{ data.label }}</span>
|
||||
<# } #>
|
||||
<# if ( data.description ) { #>
|
||||
<span class="description customize-control-description">{{{ data.description }}}</span>
|
||||
<# } #>
|
||||
</label>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
// this template is used in setupImageUploaderSaveAsId and setupImageUploaderSaveAsUrl
|
||||
// @see js CZRInputMths
|
||||
function ac_print_img_uploader_template() {
|
||||
?>
|
||||
<script type="text/html" id="tmpl-czr-img-uploader">
|
||||
<?php // case when a regular attachement object is provided, fetched from an id with wp.media.attachment( id ) ?>
|
||||
<# if ( ( data.attachment && data.attachment.id ) ) { #>
|
||||
<div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}">
|
||||
<div class="thumbnail thumbnail-{{ data.attachment.type }}">
|
||||
<# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #>
|
||||
<img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" alt="" />
|
||||
<# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #>
|
||||
<img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" alt="" />
|
||||
<# } #>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<# if ( data.canUpload ) { #>
|
||||
<button type="button" class="button remove-button">{{ data.button_labels.remove }}</button>
|
||||
<button type="button" class="button upload-button control-focus" id="{{ data.settings['default'] }}-button">{{ data.button_labels.change }}</button>
|
||||
<div style="clear:both"></div>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
<?php // case when an url is provided ?>
|
||||
<# } else if ( !_.isEmpty( data.fromUrl ) ) { #>
|
||||
<div class="attachment-media-view">
|
||||
<div class="thumbnail thumbnail-thumb">
|
||||
<img class="attachment-thumb" src="{{ data.fromUrl }}" draggable="false" alt="" />
|
||||
</div>
|
||||
<div class="actions">
|
||||
<# if ( data.canUpload ) { #>
|
||||
<button type="button" class="button remove-button">{{ data.button_labels.remove }}</button>
|
||||
<button type="button" class="button upload-button control-focus" id="{{ data.settings['default'] }}-button">{{ data.button_labels.change }}</button>
|
||||
<div style="clear:both"></div>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
<?php // case when neither attachement or url are provided => placeholder ?>
|
||||
<# } else { #>
|
||||
<div class="attachment-media-view">
|
||||
<div class="placeholder">
|
||||
{{ data.button_labels.placeholder }}
|
||||
</div>
|
||||
<div class="actions">
|
||||
<# if ( data.canUpload ) { #>
|
||||
<button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button">{{ data.button_labels.select }}</button>
|
||||
<# } #>
|
||||
<div style="clear:both"></div>
|
||||
</div>
|
||||
</div>
|
||||
<# } #>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CZR_Fmk_Base
|
||||
if ( !class_exists( 'CZR_Fmk_Base_Ajax_Filter' ) ) :
|
||||
class CZR_Fmk_Base_Ajax_Filter extends CZR_Fmk_Base_Load_Resources {
|
||||
|
||||
// fired in the constructor
|
||||
function czr_setup_ajax_tmpl() {
|
||||
// this dynamic filter is declared on wp_ajax_ac_get_template
|
||||
// It allows us to populate the server response with the relevant module html template
|
||||
// $html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl );
|
||||
add_filter( "ac_set_ajax_czr_tmpl___all_modules", array( $this, 'ac_get_all_modules_tmpl' ), 10, 3 );
|
||||
|
||||
// fetch templates
|
||||
add_action( 'wp_ajax_ac_get_template', array( $this, 'ac_set_ajax_czr_tmpl' ) );
|
||||
}
|
||||
|
||||
// hook : 'wp_ajax_ac_get_template'
|
||||
function ac_set_ajax_czr_tmpl() {
|
||||
if ( !is_user_logged_in() ) {
|
||||
wp_send_json_error( 'ac_set_ajax_czr_tmpl => unauthenticated' );
|
||||
}
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
status_header( 403 );
|
||||
wp_send_json_error( 'ac_set_ajax_czr_tmpl => customize_not_allowed' );
|
||||
} else if ( !isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
|
||||
status_header( 405 );
|
||||
wp_send_json_error( 'ac_set_ajax_czr_tmpl => bad_method' );
|
||||
}
|
||||
$action = 'save-customize_' . get_stylesheet();
|
||||
if ( !check_ajax_referer( $action, 'nonce', false ) ) {
|
||||
wp_send_json_error( array(
|
||||
'code' => 'invalid_nonce',
|
||||
'message' => __( 'ac_set_ajax_czr_tmpl => Security check failed.' ),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( !isset( $_POST['module_type'] ) || empty( $_POST['module_type'] ) ) {
|
||||
wp_send_json_error( 'ac_set_ajax_czr_tmpl => missing module_type property in posted data' );
|
||||
}
|
||||
if ( !isset( $_POST['tmpl'] ) || empty( $_POST['tmpl'] ) ) {
|
||||
wp_send_json_error( 'ac_set_ajax_czr_tmpl => missing tmpl property in posted data' );
|
||||
}
|
||||
$tmpl = sanitize_text_field($_POST['tmpl']);
|
||||
$module_type = sanitize_text_field($_POST['module_type']);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// @param $tmpl = 'item-inputs'
|
||||
//
|
||||
// @param $_POST = {
|
||||
// [tmpl] => item-inputs
|
||||
// [module_type] => czr_heading_child
|
||||
// [module_id] => __nimble__51b2f35191b3__main_settings_czr_module
|
||||
// [cache] => true
|
||||
// [nonce] => b4b0aea848
|
||||
// [control_id] => __nimble__51b2f35191b3__main_settings
|
||||
// [item_model] => Array
|
||||
// (
|
||||
// [id] => czr_heading_child_0
|
||||
// [title] =>
|
||||
// [heading_text] => This is a heading.
|
||||
// [heading_tag] => h1
|
||||
// [h_alignment_css] => Array
|
||||
// (
|
||||
// [desktop] => center
|
||||
// )
|
||||
|
||||
// [heading_title] =>
|
||||
// [link-to] =>
|
||||
// [link-custom-url] =>
|
||||
// [link-target] =>
|
||||
// )
|
||||
|
||||
// [action] => ac_get_template
|
||||
// }
|
||||
$html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl, $_POST );
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if ( empty( $html ) ) {
|
||||
wp_send_json_error( 'ac_set_ajax_czr_tmpl => module ' . $module_type . ' => template empty for requested tmpl : ' . $tmpl );
|
||||
} else {
|
||||
wp_send_json_success( apply_filters( 'tmpl_results', $html, $tmpl ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// hook : ac_set_ajax_czr_tmpl___all_modules
|
||||
// this dynamic filter is declared on wp_ajax_ac_get_template
|
||||
// It allows us to populate the server response with the relevant module html template
|
||||
// $html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl );
|
||||
//
|
||||
// For all modules, there are 3 types of templates :
|
||||
// 1) the pre-item, rendered when adding an item
|
||||
// 2) the module meta options, or mod-opt
|
||||
// 3) the item input options
|
||||
function ac_get_all_modules_tmpl( $html, $requested_tmpl = '', $posted_params = array() ) {
|
||||
$css_attr = $this->czr_css_attr;
|
||||
if ( empty( $requested_tmpl ) ) {
|
||||
wp_send_json_error( 'ac_get_all_modules_tmpl => the requested tmpl is empty' );
|
||||
}
|
||||
ob_start();
|
||||
switch ( $requested_tmpl ) {
|
||||
case 'crud-module-part' :
|
||||
?>
|
||||
<button class="<?php echo esc_attr($css_attr['open_pre_add_btn']); ?>"><?php _e('Add New', 'text_doma'); ?> <span class="fas fa-plus-square"></span></button>
|
||||
<div class="<?php echo esc_attr($css_attr['pre_add_wrapper']); ?>">
|
||||
<div class="<?php echo esc_attr($css_attr['pre_add_success']); ?>"><p></p></div>
|
||||
<div class="<?php echo esc_attr($css_attr['pre_add_item_content']); ?>">
|
||||
|
||||
<span class="<?php echo esc_attr($css_attr['cancel_pre_add_btn']); ?> button"><?php _e('Cancel', 'text_doma'); ?></span> <span class="<?php echo esc_attr($css_attr['add_new_btn']); ?> button"><?php _e('Add it', 'text_doma'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
case 'rud-item-part' :
|
||||
?>
|
||||
<div class="<?php echo esc_attr($css_attr['item_header']); ?> czr-custom-model">
|
||||
<# if ( ( true === data.is_sortable ) ) { #>
|
||||
<div class="<?php echo esc_attr($css_attr['item_title']); ?> <?php echo esc_attr($css_attr['item_sort_handle']); ?>"><h4>{{ data.title }}</h4></div>
|
||||
<# } else { #>
|
||||
<div class="<?php echo esc_attr($css_attr['item_title']); ?>"><h4>{{ data.title }}</h4></div>
|
||||
<# } #>
|
||||
<div class="<?php echo esc_attr($css_attr['item_btns']); ?>"><a title="<?php _e('Edit', 'text_doma'); ?>" href="javascript:void(0);" class="fas fa-pencil-alt <?php echo esc_attr($css_attr['edit_view_btn']); ?>"></a> <a title="<?php _e('Remove', 'text_doma'); ?>" href="javascript:void(0);" class="fas fa-trash <?php echo esc_attr($css_attr['display_alert_btn']); ?>"></a></div>
|
||||
<div class="<?php echo esc_attr($css_attr['remove_alert_wrapper']); ?>"></div>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case 'rud-item-alert-part' :
|
||||
?>
|
||||
<p class="czr-item-removal-title"><?php _e('Are you sure you want to remove : <strong>{{ data.title }} ?</strong>', 'text_doma'); ?></p>
|
||||
<span class="<?php echo esc_attr($css_attr['remove_view_btn']); ?> button"><?php _e('Yes', 'text_doma'); ?></span> <span class="<?php echo esc_attr($css_attr['cancel_alert_btn']); ?> button"><?php _e('No', 'text_doma'); ?></span>
|
||||
<?php
|
||||
break;
|
||||
|
||||
// this template is used in setupImageUploaderSaveAsId and setupImageUploaderSaveAsUrl
|
||||
case 'img-uploader' :
|
||||
?>
|
||||
<?php // case when a regular attachement object is provided, fetched from an id with wp.media.attachment( id ) ?>
|
||||
<# if ( ( data.attachment && data.attachment.id ) ) { #>
|
||||
<div class="attachment-media-view attachment-media-view-{{ data.attachment.type }} {{ data.attachment.orientation }}">
|
||||
<div class="thumbnail thumbnail-{{ data.attachment.type }}">
|
||||
<# if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.medium ) { #>
|
||||
<img class="attachment-thumb" src="{{ data.attachment.sizes.medium.url }}" draggable="false" alt="" />
|
||||
<# } else if ( 'image' === data.attachment.type && data.attachment.sizes && data.attachment.sizes.full ) { #>
|
||||
<img class="attachment-thumb" src="{{ data.attachment.sizes.full.url }}" draggable="false" alt="" />
|
||||
<# } #>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<# if ( data.canUpload ) { #>
|
||||
<button type="button" class="button remove-button">{{ data.button_labels.remove }}</button>
|
||||
<button type="button" class="button upload-button control-focus" id="{{ data.settings['default'] }}-button">{{ data.button_labels.change }}</button>
|
||||
<div style="clear:both"></div>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
<?php // case when an url is provided ?>
|
||||
<# } else if ( !_.isEmpty( data.fromUrl ) ) { #>
|
||||
<div class="attachment-media-view">
|
||||
<div class="thumbnail thumbnail-thumb">
|
||||
<img class="attachment-thumb" src="{{ data.fromUrl }}" draggable="false" alt="" />
|
||||
</div>
|
||||
<div class="actions">
|
||||
<# if ( data.canUpload ) { #>
|
||||
<button type="button" class="button remove-button">{{ data.button_labels.remove }}</button>
|
||||
<button type="button" class="button upload-button control-focus" id="{{ data.settings['default'] }}-button">{{ data.button_labels.change }}</button>
|
||||
<div style="clear:both"></div>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
<?php // case when neither attachement or url are provided => placeholder ?>
|
||||
<# } else { #>
|
||||
<div class="attachment-media-view">
|
||||
<div class="placeholder">
|
||||
{{ data.button_labels.placeholder }}
|
||||
</div>
|
||||
<div class="actions">
|
||||
<# if ( data.canUpload ) { #>
|
||||
<button type="button" class="button upload-button" id="{{ data.settings['default'] }}-button">{{ data.button_labels.select }}</button>
|
||||
<# } #>
|
||||
<div style="clear:both"></div>
|
||||
</div>
|
||||
</div>
|
||||
<# } #>
|
||||
<?php
|
||||
break;
|
||||
}//switch
|
||||
|
||||
$html = ob_get_clean();
|
||||
if ( empty( $html ) ) {
|
||||
wp_send_json_error( 'ac_get_all_modules_tmpl => no template was found for tmpl => ' . $requested_tmpl );
|
||||
}
|
||||
|
||||
return $html;//will be sent by wp_send_json_success() in ::ac_set_ajax_czr_tmpl()
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CZR_Fmk_Base
|
||||
if ( !class_exists( 'CZR_Fmk_Base_Tmpl_Builder' ) ) :
|
||||
class CZR_Fmk_Base_Tmpl_Builder extends CZR_Fmk_Base_Ajax_Filter {
|
||||
/*********************************************************
|
||||
** TMPL BUILDER
|
||||
*********************************************************/
|
||||
// This is the standard method to be used in a module to generate the item input template
|
||||
// for pre-item, mod-opts and item-inputs
|
||||
// fired in self::ac_get_ajax_module_tmpl
|
||||
function ac_generate_czr_tmpl_from_map( $tmpl_map ) {
|
||||
$html = '';
|
||||
$default_input_entries = array(
|
||||
'input_type' => 'text',
|
||||
'title' => '',
|
||||
'default' => '',
|
||||
|
||||
'html_before' => '',
|
||||
'notice_before_title' => '',
|
||||
'notice_before' => '',
|
||||
'notice_after' => '',
|
||||
'placeholder' => '',
|
||||
'html_after' => '',
|
||||
|
||||
// typically used for the number and range inputs
|
||||
'step' => '',
|
||||
'min' => '',
|
||||
'max' => '',
|
||||
'orientation' => '',//vertical / horizontal
|
||||
'unit' => '',//% or px for example
|
||||
|
||||
'transport' => '',//<= can be set as a data property of the input wrapper, and used when instanciating the input
|
||||
|
||||
'input_template' => '',//<= a static html template can be provided to render the input, in this case it will be used in priority
|
||||
'tmpl_callback' => '',//<= a callback function to be used to print the entire input template, including the wrapper
|
||||
|
||||
'width-100' => false,//<= to force a width of 100%
|
||||
'title_width' => '',//width-80
|
||||
'input_width' => '',//width-20
|
||||
|
||||
'code_type' => '',//<= used for to specify the language type of the codemirror editor (if not specified full a html editor will be instantiated)
|
||||
|
||||
'refresh_markup' => null,
|
||||
'refresh_stylesheet' => null,
|
||||
'refresh_fonts' => null,
|
||||
'refresh_preview' => null,
|
||||
|
||||
'sanitize_cb' => '',
|
||||
'validate_cb' => '',
|
||||
|
||||
'css_selectors' => array(), //<= used to specify css selectors on which we will apply the dynamically generated css for a given input id @see \Nimble\sek_add_css_rules_for_generic_css_input_types'
|
||||
'css_identifier' => '',//<= the identifier allowing us to map a css generation rule. @see \Nimble\sek_add_css_rules_for_css_sniffed_input_id
|
||||
'important_input_list' => array(),//<= the list of input_id that an important input can flag !important @see \Nimble\sek_add_css_rules_for_css_sniffed_input_id
|
||||
|
||||
'choices' => array(), // <= used to declare the option list of a select input
|
||||
|
||||
'has_device_switcher' => false, // <= indicates if the input value shall be saved by device or not
|
||||
|
||||
'scope' => 'local',// <= used when resetting the sections
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/403
|
||||
'editor_params' => array(),
|
||||
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/431
|
||||
'section_collection' => array()
|
||||
);
|
||||
foreach( $tmpl_map as $input_id => $input_data ) {
|
||||
if ( !is_string( $input_id ) || empty( $input_id ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . ' => wrong input id' );
|
||||
break;
|
||||
}
|
||||
if ( !is_array( $input_data ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . ' => wrong var type for the input_data of input id : ' . esc_attr($input_id) );
|
||||
break;
|
||||
}
|
||||
// check that we have no unknown entries in the provided input_data
|
||||
$maybe_diff = array_diff_key( $input_data, $default_input_entries );
|
||||
if ( !empty( $maybe_diff ) ) {
|
||||
error_log('<' . __FUNCTION__ . '>');
|
||||
error_log( '=> at least one unknown param in the registered input params for input id : ' . esc_attr($input_id) );
|
||||
error_log( print_r( $maybe_diff, true ) );
|
||||
error_log('</' . __FUNCTION__ . '>');
|
||||
break;
|
||||
}
|
||||
|
||||
// we're clear, let's go
|
||||
$input_data = wp_parse_args( $input_data, $default_input_entries );
|
||||
|
||||
// Do we have a specific template provided ?
|
||||
if ( !empty( $input_data[ 'tmpl_callback' ] ) && function_exists( $input_data[ 'tmpl_callback' ] ) ) {
|
||||
$html .= call_user_func_array( $input_data[ 'tmpl_callback' ], array( $input_data ) );
|
||||
} else {
|
||||
$html .= $this->ac_get_default_input_tmpl( $input_id, $input_data );
|
||||
}
|
||||
|
||||
}
|
||||
return $html;////will be sent by wp_send_json_success() in ::ac_set_ajax_czr_tmpl()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Fired in ac_generate_czr_tmpl_from_map
|
||||
function ac_get_default_input_tmpl( $input_id, $input_data ) {
|
||||
if ( !array_key_exists( 'input_type', $input_data ) || empty( $input_data[ 'input_type' ] ) ) {
|
||||
wp_send_json_error( 'ac_get_input_tmpl => missing input type for input id : ' . esc_attr($input_id) );
|
||||
}
|
||||
$input_type = $input_data[ 'input_type' ];
|
||||
|
||||
// some inputs have a width of 100% even if not specified in the input_data
|
||||
$is_width_100 = true === $input_data[ 'width-100' ];
|
||||
if ( in_array( $input_type, array( 'color', 'radio', 'textarea' ) ) ) {
|
||||
$is_width_100 = true;
|
||||
}
|
||||
|
||||
$css_attr = $this->czr_css_attr;
|
||||
|
||||
ob_start();
|
||||
// <INPUT WRAPPER>
|
||||
printf( '<div class="%1$s %2$s %3$s" data-input-type="%4$s" %5$s>',
|
||||
esc_attr($css_attr['sub_set_wrapper']),
|
||||
$is_width_100 ? 'width-100' : '',
|
||||
'hidden' === $input_type ? 'hidden' : '',
|
||||
esc_attr($input_type),
|
||||
esc_attr(!empty( $input_data['transport'] ) ? 'data-transport="'. $input_data['transport'] .'"' : '')
|
||||
);
|
||||
?>
|
||||
<?php if ( !empty( $input_data['html_before'] ) ) : ?>
|
||||
<div class="czr-html-before"><?php echo wp_kses_post($input_data['html_before']); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( !empty( $input_data['notice_before_title'] ) ) : ?>
|
||||
<span class="czr-notice"><?php echo wp_kses_post($input_data['notice_before_title']); ?></span><br/>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
// no need to print a title for an hidden input
|
||||
if ( $input_type !== 'hidden' ) {
|
||||
printf( '<div class="customize-control-title %1$s">%2$s</div>',
|
||||
esc_attr(!empty( $input_data['title_width'] ) ? $input_data['title_width'] : ''),
|
||||
wp_kses_post($input_data['title'])
|
||||
);
|
||||
}
|
||||
?>
|
||||
<?php if ( !empty( $input_data['notice_before'] ) ) : ?>
|
||||
<span class="czr-notice"><?php echo wp_kses_post($input_data['notice_before']); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php printf( '<div class="czr-input %1$s">', esc_attr(!empty( $input_data['input_width'] ) ? $input_data['input_width'] : '' ) ); ?>
|
||||
|
||||
<?php
|
||||
if ( !empty( $input_data['input_template'] ) && is_string( $input_data['input_template'] ) ) {
|
||||
echo wp_kses_post($input_data['input_template']);
|
||||
} else {
|
||||
// THIS IS WHERE THE ACTUAL INPUT CONTENT IS SET
|
||||
$this->ac_set_input_tmpl_content( $input_type, $input_id, $input_data );
|
||||
}
|
||||
?>
|
||||
</div><?php // class="czr-input" ?>
|
||||
<?php if ( !empty( $input_data['notice_after'] ) ) : ?>
|
||||
<span class="czr-notice"><?php echo wp_kses_post($input_data['notice_after']); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( !empty( $input_data['html_after'] ) ) : ?>
|
||||
<div class="czr-html-after"><?php echo wp_kses_post($input_data['html_after']); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div> <?php //class="$css_attr['sub_set_wrapper']" ?>
|
||||
<?php
|
||||
// </INPUT WRAPPER>
|
||||
|
||||
$tmpl_html = apply_filters( "czr_set_input_tmpl___{$input_type}", ob_get_clean(), $input_id, $input_data );
|
||||
//error_log( print_r($tmpl_html, true ) );
|
||||
if ( empty( $tmpl_html ) ) {
|
||||
wp_send_json_error( 'ac_get_input_tmpl => no html returned for input ' . esc_attr($input_id) );
|
||||
}
|
||||
return $tmpl_html;
|
||||
}//ac_get_input_tmpl()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fired in ::ac_get_default_input_tmpl();
|
||||
private function ac_set_input_tmpl_content( $input_type, $input_id, $input_data ) {
|
||||
$css_attr = $this->czr_css_attr;
|
||||
$input_tmpl_content = null;
|
||||
// First fires a hook to allow the input content to be remotely set
|
||||
// For example the module_picker, the spacing, h_text_alignment... are printed this way
|
||||
ob_start();
|
||||
do_action( 'czr_set_input_tmpl_content', $input_type, $input_id, $input_data );
|
||||
$input_tmpl_content = ob_get_clean();
|
||||
|
||||
if ( !empty( $input_tmpl_content ) ) {
|
||||
echo wp_kses_post($input_tmpl_content);
|
||||
} else {
|
||||
// Then, if we have no content yet, let's go thought the default input cases
|
||||
switch ( $input_type ) {
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* HIDDEN
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'hidden':
|
||||
?>
|
||||
<input data-czrtype="<?php echo esc_attr($input_id); ?>" type="hidden" value=""></input>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SELECT
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'czr_layouts'://<= specific to the hueman theme
|
||||
case 'select'://<= used in the customizr and hueman theme
|
||||
case 'simpleselect'://<=used in Nimble Builder
|
||||
?>
|
||||
<select data-czrtype="<?php echo esc_attr($input_id); ?>"></select>
|
||||
<?php
|
||||
break;
|
||||
// multiselect with select2() js library
|
||||
case 'multiselect':
|
||||
case 'category_picker':
|
||||
?>
|
||||
<select multiple="multiple" data-czrtype="<?php echo esc_attr($input_id); ?>"></select>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* TEXT
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'text' :
|
||||
?>
|
||||
<input data-czrtype="<?php echo esc_attr($input_id); ?>" type="text" value="" placeholder="<?php echo esc_attr($input_data['placeholder']); ?>"></input>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* NUMBER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'number' :
|
||||
?>
|
||||
<?php
|
||||
printf( '<input data-czrtype="%4$s" type="number" %1$s %2$s %3$s value="{{ data[\'%4$s\'] }}" />',
|
||||
esc_attr(!empty( $input_data['step'] ) ? 'step="'. $input_data['step'] .'"' : ''),
|
||||
esc_attr(!empty( $input_data['min'] ) ? 'min="'. $input_data['min'] .'"' : ''),
|
||||
esc_attr(!empty( $input_data['max'] ) ? 'max="'. $input_data['max'] .'"' : ''),
|
||||
esc_attr($input_id)
|
||||
);
|
||||
?>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* COLOR
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'wp_color_alpha' :
|
||||
?>
|
||||
<input data-czrtype="<?php echo esc_attr($input_id); ?>" class="width-100" data-alpha="true" type="text" value="{{ data['<?php echo esc_attr($input_id); ?>'] }}"></input>
|
||||
<?php
|
||||
break;
|
||||
case 'color' :
|
||||
?>
|
||||
<input data-czrtype="<?php echo esc_attr($input_id); ?>" type="text" value="{{ data['<?php echo esc_attr($input_id); ?>'] }}"></input>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CHECK
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'checkbox' :
|
||||
case 'check' :
|
||||
?>
|
||||
<#
|
||||
var _checked = ( false != data['<?php echo esc_attr($input_id); ?>'] ) ? "checked=checked" : '';
|
||||
#>
|
||||
<input data-czrtype="<?php echo esc_attr($input_id); ?>" type="checkbox" {{ _checked }}></input>
|
||||
<?php
|
||||
break;
|
||||
|
||||
// DEPRECATED since april 2nd 2019
|
||||
case 'gutencheck' :
|
||||
?>
|
||||
<#
|
||||
var _checked = ( false != data['<?php echo esc_attr($input_id); ?>'] ) ? "checked=checked" : '';
|
||||
#>
|
||||
<span class="czr-toggle-check"><input class="czr-toggle-check__input" data-czrtype="<?php echo esc_attr($input_id); ?>" type="checkbox" {{ _checked }}><span class="czr-toggle-check__track"></span><span class="czr-toggle-check__thumb"></span></span>
|
||||
<?php
|
||||
break;
|
||||
|
||||
case 'nimblecheck' :
|
||||
?>
|
||||
<#
|
||||
var _checked = ( false != data['<?php echo esc_attr($input_id); ?>'] ) ? "checked=checked" : '';
|
||||
#>
|
||||
<?php
|
||||
// when input and label are tied by an id - for relationship
|
||||
// clicking on any of them changes the input
|
||||
// => We need a unique ID here so that input and label are tied by a unique link
|
||||
// @see https://www.w3.org/TR/html401/interact/forms.html#h-17.9.1
|
||||
// @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input/checkbox
|
||||
$unique_id = sprintf('%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535));
|
||||
?>
|
||||
<div class="nimblecheck-wrap">
|
||||
<input id="nimblecheck-<?php echo esc_attr($unique_id); ?>" data-czrtype="<?php echo esc_attr($input_id); ?>" type="checkbox" {{ _checked }} class="nimblecheck-input">
|
||||
<label for="nimblecheck-<?php echo esc_attr($unique_id); ?>" class="nimblecheck-label">Switch</label>
|
||||
</div>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* TEXTAREA
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'textarea' :
|
||||
// Added an id attribute for https://github.com/presscustomizr/nimble-builder/issues/403
|
||||
// needed to instantiate wp.editor.initialize(...)
|
||||
?>
|
||||
<textarea id="textarea-{{ data.id }}" data-czrtype="<?php echo esc_attr($input_id); ?>" class="width-100" name="textarea" rows="10" cols="">{{ data.value }}</textarea>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* IMG UPLOAD AND UPLOAD URL
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'upload' :
|
||||
case 'upload_url' :
|
||||
?>
|
||||
<input data-czrtype="<?php echo esc_attr($input_id); ?>" type="hidden"/>
|
||||
<div class="<?php echo esc_attr($css_attr['img_upload_container']); ?>"></div>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* RANGE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'range_slider' :
|
||||
case 'range' :
|
||||
?>
|
||||
<?php //<# //console.log( 'IN php::ac_get_default_input_tmpl() => data range_slide => ', data ); #> ?>
|
||||
<?php
|
||||
printf( '<input data-czrtype="%5$s" type="range" %1$s %2$s %3$s %4$s value="{{ data[\'%5$s\'] }}" />',
|
||||
esc_attr(!empty( $input_data['orientation'] ) ? 'data-orientation="'. $input_data['orientation'] .'"' : ''),
|
||||
esc_attr(!empty( $input_data['unit'] ) ? 'data-unit="'. $input_data['unit'] .'"' : ''),
|
||||
esc_attr(!empty( $input_data['min'] ) ? 'min="'. $input_data['min'] .'"' : ''),
|
||||
esc_attr(!empty( $input_data['max'] ) ? 'max="'. $input_data['max'] .'"' : ''),
|
||||
esc_attr($input_id)
|
||||
);
|
||||
?>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CONTENT PICKER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
case 'content_picker' :
|
||||
?>
|
||||
<?php
|
||||
printf( '<span data-czrtype="%1$s"></span>', esc_attr($input_id) );
|
||||
?>
|
||||
<?php
|
||||
break;
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* PROBLEM : if we reach this case, it means that
|
||||
* - the input template has not been populated by the first do_action('czr_set_input_tmpl_content')
|
||||
* - no default input template is defined for the requested input type
|
||||
/* ------------------------------------------------------------------------- */
|
||||
default :
|
||||
// this input type has no template, this is a problem
|
||||
wp_send_json_error( 'ERROR => ' . __CLASS__ . '::' . __FUNCTION__ . ' this input type has no template : ' . $input_type );
|
||||
break;
|
||||
}//switch ( $input_type ) {
|
||||
}//if ( empty( $input_tmpl_content ) )()
|
||||
}//function()
|
||||
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,343 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CZR_Fmk_Base
|
||||
if ( !class_exists( 'CZR_Fmk_Dyn_Setting_Registration' ) ) :
|
||||
class CZR_Fmk_Dyn_Setting_Registration extends CZR_Fmk_Base_Tmpl_Builder {
|
||||
|
||||
//fired in the constructor
|
||||
function czr_setup_dynamic_settings_registration() {
|
||||
add_action( 'customize_register', array( $this, 'czr_setup_dynamic_setting_registration' ), 10 );
|
||||
|
||||
// if we have dynamic setting params, let's add a filter to serverControlParams
|
||||
// filter declared when localizing 'serverControlParams' @see resources
|
||||
add_filter( 'czr_fmk_dynamic_setting_js_params', array( $this, 'czr_setup_localized_params_for_dynamic_js_registration' ), 20 );
|
||||
|
||||
// when not dynamically registered
|
||||
// TO DEPRECATE ?
|
||||
//add_action( 'customize_register', array( $this, 'czr_register_not_dynamic_settings' ), 20 );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// PRE REGISTRATION FOR SETTINGS
|
||||
// Default params
|
||||
// array(
|
||||
// 'setting_id' => '',
|
||||
// 'dynamic_registration' => true,
|
||||
// 'module_type' => '',
|
||||
// 'option_value' => array(),
|
||||
|
||||
// 'setting' => array(
|
||||
// 'type' => 'option',
|
||||
// 'default' => array(),
|
||||
// 'transport' => 'refresh',
|
||||
// 'setting_class' => '',//array( 'path' => '', 'name' => '' )
|
||||
// 'sanitize_callback' => '',
|
||||
// 'validate_callback' => '',
|
||||
// ),
|
||||
|
||||
// 'section' => array(
|
||||
// 'id' => '',
|
||||
// 'title' => '',
|
||||
// 'panel' => '',
|
||||
// 'priority' => 10
|
||||
// ),
|
||||
|
||||
// 'control' => array(
|
||||
// 'label' => '',
|
||||
// 'type' => 'czr_module',
|
||||
// 'priority' => 10,
|
||||
// 'control_class' => ''//array( 'path' => '', 'name' => '' )
|
||||
// )
|
||||
// )
|
||||
function czr_pre_register_dynamic_setting( $setting_params ) {
|
||||
if ( !is_array( $setting_params ) || empty( $setting_params ) ) {
|
||||
error_log( 'czr_pre_register_dynamic_setting => empty $setting_params submitted' );
|
||||
return;
|
||||
}
|
||||
if ( !array_key_exists( 'setting_id', $setting_params ) || empty( $setting_params['setting_id'] ) ) {
|
||||
error_log( 'czr_pre_register_dynamic_setting => missing setting id' );
|
||||
return;
|
||||
}
|
||||
|
||||
// normalize
|
||||
$setting_params = wp_parse_args( $setting_params, $this -> default_dynamic_setting_params );
|
||||
|
||||
$registered = $this->registered_settings;
|
||||
$setting_id_candidate = $setting_params['setting_id'];
|
||||
|
||||
// A setting id can be registered only once.
|
||||
// Already registered ?
|
||||
if ( array_key_exists( $setting_id_candidate, $registered ) ) {
|
||||
error_log( 'czr_pre_register_dynamic_setting => setting id already registered => ' . $setting_id_candidate );
|
||||
return;
|
||||
}
|
||||
$registered[ $setting_id_candidate ] = $setting_params;
|
||||
$this->registered_settings = $registered;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// FILTER DYNAMIC SETTING AND CLASS ARGS
|
||||
// hook : customize_register
|
||||
// Those filters are declared by WP core in class-wp-customize-manager.php
|
||||
// in => add_action( 'customize_register', array( $this, 'register_dynamic_settings' ), 11 );
|
||||
function czr_setup_dynamic_setting_registration( $wp_customize ) {
|
||||
add_filter( 'customize_dynamic_setting_args', array( $this, 'czr_setup_customizer_dynamic_setting_args' ), 10, 2 );
|
||||
add_filter( 'customize_dynamic_setting_class', array( $this, 'czr_setup_customizer_dynamic_setting_class' ), 10, 3 );
|
||||
}
|
||||
|
||||
// hook : 'customize_dynamic_setting_args'
|
||||
function czr_setup_customizer_dynamic_setting_args( $setting_args, $setting_id ) {
|
||||
//sek_error_log( __CLASS__ . '::' . __FUNCTION__ , $this->registered_settings );
|
||||
|
||||
if ( !is_array( $this->registered_settings ) || empty( $this->registered_settings ) )
|
||||
return $setting_args;
|
||||
|
||||
// let's initialize the args to the provided param
|
||||
$registered_setting_args = $setting_args;
|
||||
|
||||
// loop on each registered modules
|
||||
foreach ( $this->registered_settings as $registerered_setting_id => $params ) {
|
||||
|
||||
if ( array_key_exists('dynamic_registration', $params) && true !== $params['dynamic_registration'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$params = wp_parse_args( $params, $this -> default_dynamic_setting_params );
|
||||
|
||||
if ( $registerered_setting_id != $setting_id || empty( $registerered_setting_id ) )
|
||||
continue;
|
||||
|
||||
$setting_args = is_array( $params['setting'] ) ? $params['setting'] : array();
|
||||
$setting_args = wp_parse_args( $setting_args, array(
|
||||
'type' => 'option',
|
||||
'default' => array(),
|
||||
'transport' => 'refresh',
|
||||
'sanitize_callback' => '',
|
||||
'validate_callback' => ''
|
||||
) );
|
||||
|
||||
// Provide new setting args
|
||||
$registered_setting_args = array(
|
||||
'type' => empty( $setting_args[ 'type' ] ) ? 'option' : $setting_args[ 'type' ],
|
||||
'default' => array(),
|
||||
'transport' => $setting_args[ 'transport' ],
|
||||
'sanitize_callback' => ( !empty( $setting_args[ 'sanitize_callback' ] ) && function_exists( $setting_args[ 'sanitize_callback' ] ) ) ? $setting_args[ 'sanitize_callback' ] : '',
|
||||
'validate_callback' => ( !empty( $setting_args[ 'validate_callback' ] ) && function_exists( $setting_args[ 'validate_callback' ] ) ) ? $setting_args[ 'validate_callback' ] : ''
|
||||
);
|
||||
|
||||
// if this is a module setting, it can have specific sanitize and validate callback set for the module
|
||||
// Let's check if the module_type is registered, and if there are any callback set.
|
||||
// If a match is found, we'll use those callback
|
||||
$module_params = $this -> czr_get_registered_dynamic_module( $params[ 'module_type' ] );
|
||||
if ( false !== $module_params && is_array( $module_params ) ) {
|
||||
if ( array_key_exists( 'validate_callback', $module_params ) && function_exists( $module_params[ 'validate_callback' ] ) ) {
|
||||
$registered_setting_args[ 'validate_callback' ] = $module_params[ 'validate_callback' ];
|
||||
}
|
||||
if ( array_key_exists( 'sanitize_callback', $module_params ) && function_exists( $module_params[ 'sanitize_callback' ] ) ) {
|
||||
$registered_setting_args[ 'sanitize_callback' ] = $module_params[ 'sanitize_callback' ];
|
||||
}
|
||||
}
|
||||
//error_log( 'REGISTERING DYNAMICALLY for setting =>'. $setting_id );
|
||||
}
|
||||
return $registered_setting_args;
|
||||
}
|
||||
|
||||
|
||||
// hook : 'customize_dynamic_setting_class'
|
||||
function czr_setup_customizer_dynamic_setting_class( $class, $setting_id, $args ) {
|
||||
if ( !is_array( $this->registered_settings ) || empty( $this->registered_settings ) )
|
||||
return $class;
|
||||
|
||||
|
||||
// let's initialize the args to the provided class
|
||||
$registered_setting_class = $class;//'WP_Customize_Setting' by default
|
||||
|
||||
// loop on each registered modules
|
||||
foreach ( $this->registered_settings as $registerered_setting_id => $params ) {
|
||||
$params = wp_parse_args( $params, $this -> default_dynamic_setting_params );
|
||||
if ( true !== $params['dynamic_registration'] ) {
|
||||
continue;
|
||||
}
|
||||
if ( $registerered_setting_id != $setting_id || empty( $registerered_setting_id ) )
|
||||
continue;
|
||||
|
||||
$setting_args = $params['setting'];
|
||||
|
||||
if ( is_array( $setting_args ) && array_key_exists( 'setting_class', $setting_args ) ) {
|
||||
// provide new setting class if exists and not yet loaded
|
||||
if ( is_array( $setting_args[ 'setting_class' ] ) && array_key_exists( 'name', $setting_args[ 'setting_class' ] ) && array_key_exists( 'path', $setting_args[ 'setting_class' ] ) ) {
|
||||
if ( !class_exists( $setting_args[ 'setting_class' ][ 'name' ] ) && file_exists( $setting_args[ 'setting_class' ]['path'] ) ) {
|
||||
require_once( $setting_args[ 'setting_class' ]['path'] );
|
||||
}
|
||||
if ( class_exists( $setting_args[ 'setting_class' ][ 'name' ] ) ) {
|
||||
$registered_setting_class = $setting_args[ 'setting_class' ][ 'name' ];
|
||||
}
|
||||
}
|
||||
}
|
||||
//error_log( 'REGISTERING CLASS DYNAMICALLY for setting =>'. $setting_id );
|
||||
}
|
||||
|
||||
return $registered_setting_class;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Print js params for dynamic control and section registration
|
||||
// hook : czr_fmk_dynamic_setting_js_params'
|
||||
// @param js_param = array()
|
||||
function czr_setup_localized_params_for_dynamic_js_registration( $js_params ) {
|
||||
// error_log( '<REGISTERED SETTINGS>' );
|
||||
// error_log( print_r( $this->registered_settings, true ) );
|
||||
// error_log( '</REGISTERED SETTINGS>' );
|
||||
if ( !is_array( $this->registered_settings ) || empty( $this->registered_settings ) )
|
||||
return $js_params;
|
||||
$js_params = !is_array( $js_params ) ? array() : $js_params;
|
||||
|
||||
// 'localized_control_js' => array(
|
||||
// 'deps' => 'czr-customizer-fmk',
|
||||
// 'global_var_name' => 'socialLocalized',
|
||||
// 'params' => array(
|
||||
// //Social Module
|
||||
// 'defaultSocialColor' => 'rgb(90,90,90)',
|
||||
// 'defaultSocialSize' => 14,
|
||||
// //option value for dynamic registration
|
||||
//
|
||||
// )
|
||||
// 'dynamic_setting_registration' => array(
|
||||
// 'values' => $args['option_value'],
|
||||
// 'section' => $args['section']
|
||||
// )
|
||||
// )
|
||||
// loop on each registered modules
|
||||
foreach ( $this->registered_settings as $registerered_setting_id => $params ) {
|
||||
$params = wp_parse_args( $params, $this -> default_dynamic_setting_params );
|
||||
// We need the 'option_value' entry, even if empty
|
||||
if ( !array_key_exists( 'option_value', $params ) || !is_array( $params['option_value'] ) )
|
||||
continue;
|
||||
// Check if not already setup
|
||||
if ( array_key_exists( $registerered_setting_id, $params ) ) {
|
||||
error_log( 'czr_setup_localized_params_for_dynamic_js_registration => js_params already setup for setting : ' . $registerered_setting_id );
|
||||
}
|
||||
|
||||
$js_params[ $registerered_setting_id ] = array(
|
||||
'setting_id' => $registerered_setting_id,
|
||||
'module_type' => $params[ 'module_type' ],
|
||||
'module_registration_params' => $this -> czr_get_registered_dynamic_module( $params[ 'module_type' ] ),
|
||||
'option_value' => $params['option_value'],
|
||||
|
||||
// 'setting' => array(
|
||||
// 'type' => 'option',
|
||||
// 'default' => array(),
|
||||
// 'transport' => 'refresh',
|
||||
// 'setting_class' => '',//array( 'path' => '', 'name' => '' )
|
||||
// 'sanitize_callback' => '',
|
||||
// 'validate_callback' => '',
|
||||
// ),
|
||||
'setting' => array_key_exists( 'setting', $params ) ? $params[ 'setting' ] : array(),
|
||||
|
||||
// 'section' => array(
|
||||
// 'id' => '',
|
||||
// 'title' => '',
|
||||
// 'panel' => '',
|
||||
// 'priority' => 10
|
||||
// ),
|
||||
'section' => array_key_exists( 'section', $params ) ? $params[ 'section' ] : array(),
|
||||
|
||||
// 'control' => array(
|
||||
// 'label' => '',
|
||||
// 'type' => 'czr_module',
|
||||
// 'priority' => 10,
|
||||
// 'control_class' => ''//array( 'path' => '', 'name' => '' )
|
||||
// ),
|
||||
'control' => array_key_exists( 'control', $params ) ? $params[ 'control' ] : array(),
|
||||
);
|
||||
}
|
||||
return $js_params;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// TO DEPRECATE ?
|
||||
// REGISTER IF NOT DYNAMIC
|
||||
// hook : customize_register
|
||||
function czr_register_not_dynamic_settings( $wp_customize ) {
|
||||
// error_log('<MODULE REGISTRATION>');
|
||||
// error_log(print_r( $this->registered_settings, true ));
|
||||
// error_log('</MODULE REGISTRATION>');
|
||||
|
||||
if ( !is_array( $this->registered_settings ) || empty( $this->registered_settings ) )
|
||||
return;
|
||||
|
||||
// loop on each registered modules
|
||||
foreach ( $this->registered_settings as $setting_id => $params ) {
|
||||
$params = wp_parse_args( $params, $this -> default_dynamic_setting_params );
|
||||
if ( true === $params['dynamic_registration'] )
|
||||
continue;
|
||||
|
||||
|
||||
// SETTING
|
||||
$setting_args = $params['setting'];
|
||||
$registered_setting_class = 'WP_Customize_Setting';
|
||||
if ( is_array( $setting_args ) && array_key_exists( 'setting_class', $setting_args ) ) {
|
||||
// provide new setting class if exists and not yet loaded
|
||||
if ( is_array( $setting_args[ 'setting_class' ] ) && array_key_exists( 'name', $setting_args[ 'setting_class' ] ) && array_key_exists( 'path', $setting_args[ 'setting_class' ] ) ) {
|
||||
if ( !class_exists( $setting_args[ 'setting_class' ][ 'name' ] ) && file_exists( $setting_args[ 'setting_class' ]['path'] ) ) {
|
||||
require_once( $setting_args[ 'setting_class' ]['path'] );
|
||||
}
|
||||
if ( class_exists( $setting_args[ 'setting_class' ][ 'name' ] ) ) {
|
||||
$registered_setting_class = $setting_args[ 'setting_class' ][ 'name' ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$wp_customize->add_setting( new $registered_setting_class( $wp_customize, $setting_id, array(
|
||||
'default' => $setting_args[ 'default' ],
|
||||
'type' => $setting_args[ 'type' ],
|
||||
'sanitize_callback' => isset( $settings_args[ 'sanitize_callback' ] ) ? $settings_args[ 'sanitize_callback' ] : ''
|
||||
) ) );
|
||||
|
||||
|
||||
// CONTROL
|
||||
$control_args = $params['control'];
|
||||
$registered_control_class = 'WP_Customize_Control';
|
||||
if ( is_array( $control_args ) && array_key_exists( 'control_class', $control_args ) ) {
|
||||
// provide new setting class if exists and not yet loaded
|
||||
if ( is_array( $control_args[ 'control_class' ] ) && array_key_exists( 'name', $control_args[ 'control_class' ] ) && array_key_exists( 'path', $control_args[ 'control_class' ] ) ) {
|
||||
if ( !class_exists( $control_args[ 'control_class' ][ 'name' ] ) && file_exists( $control_args[ 'control_class' ]['path'] ) ) {
|
||||
require_once( $control_args[ 'control_class' ]['path'] );
|
||||
}
|
||||
if ( class_exists( $control_args[ 'control_class' ][ 'name' ] ) ) {
|
||||
$registered_control_class = $control_args[ 'control_class' ][ 'name' ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$wp_customize -> add_control( new $registered_control_class( $wp_customize, $setting_id, array(
|
||||
'type' => $control_args[ 'type' ],
|
||||
'label' => $control_args[ 'label' ],
|
||||
'section' => $params[ 'section' ]['id'],
|
||||
'module_type' => $params[ 'module_type' ]
|
||||
) ) );
|
||||
|
||||
}//foreach
|
||||
}//czr_register_not_dynamic_settings
|
||||
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CZR_Fmk_Base
|
||||
if ( !class_exists( 'CZR_Fmk_Dyn_Module_Registration' ) ) :
|
||||
class CZR_Fmk_Dyn_Module_Registration extends CZR_Fmk_Dyn_Setting_Registration {
|
||||
|
||||
//fired in the constructor
|
||||
function czr_setup_dynamic_modules_registration() {
|
||||
// Dynamic Module Registration
|
||||
add_action( 'init', array( $this, 'czr_schedule_ajax_tmpl' ) );
|
||||
// Enqueue the module customizer control assets
|
||||
add_action( 'customize_controls_enqueue_scripts' , array( $this, 'czr_register_dynamic_modules_customizer_control_assets' ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// PRE REGISTRATION FOR MODULES
|
||||
// Default params
|
||||
// array(
|
||||
// 'module_type' => '',
|
||||
// 'customizer_assets' => array(
|
||||
// 'control_js' => array(),
|
||||
// 'localized_control_js' => array()
|
||||
// ),
|
||||
// 'tmpl' => array()
|
||||
// )
|
||||
function czr_pre_register_dynamic_module( $module_params ) {
|
||||
// error_log( '<czr_pre_register_dynamic_module>' );
|
||||
// error_log( print_r( $module_params, true ) );
|
||||
// error_log( '</czr_pre_register_dynamic_module>' );
|
||||
|
||||
if ( !is_array( $module_params ) || empty( $module_params ) ) {
|
||||
sek_error_log( 'czr_pre_register_dynamic_module => empty $module_params submitted' );
|
||||
return;
|
||||
}
|
||||
if ( !array_key_exists( 'module_type', $module_params ) || empty( $module_params['module_type'] ) ) {
|
||||
sek_error_log( 'czr_pre_register_dynamic_module => missing module_type' );
|
||||
return;
|
||||
}
|
||||
|
||||
// normalize
|
||||
$module_params = wp_parse_args( $module_params, $this->default_dynamic_module_params );
|
||||
|
||||
$registered = $this->registered_modules;
|
||||
$module_type_candidate = $module_params['module_type'];
|
||||
|
||||
// A module type can be registered only once.
|
||||
// Already registered ?
|
||||
if ( array_key_exists( $module_type_candidate, $registered ) ) {
|
||||
//sek_error_log( 'czr_pre_register_dynamic_module => module type already registered => ' . $module_type_candidate );
|
||||
return;
|
||||
}
|
||||
$registered[ $module_type_candidate ] = $module_params;
|
||||
$this->registered_modules = $registered;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// HELPER
|
||||
// @return boolean or array of module params
|
||||
function czr_get_registered_dynamic_module( $module_type = '' ) {
|
||||
$registered = $this->registered_modules;
|
||||
if ( empty( $module_type ) || !is_array( $registered ) || empty( $registered ) )
|
||||
return;
|
||||
return array_key_exists( $module_type , $registered ) ? $registered[ $module_type ] : false;
|
||||
}
|
||||
|
||||
// @return bool
|
||||
function czr_is_module_registered( $module_type = '' ) {
|
||||
$registered = $this->registered_modules;
|
||||
if ( empty( $module_type ) || !is_array( $registered ) || empty( $registered ) )
|
||||
return;
|
||||
return array_key_exists( $module_type , $registered );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// ENQUEUE ASSETS
|
||||
// hook : customize_controls_enqueue_scripts
|
||||
//
|
||||
// 'customizer_assets' => array(
|
||||
// 'control_js' => array(
|
||||
// // handle + params for wp_enqueue_script()
|
||||
// // @see https://developer.wordpress.org/reference/functions/wp_enqueue_script/
|
||||
// 'czr-social-links-module' => array(
|
||||
// 'src' => sprintf(
|
||||
// '%1$s/assets/js/%2$s',
|
||||
// $args['base_url_path'],
|
||||
// '_2_7_socials_module.js'
|
||||
// ),
|
||||
// 'deps' => array('customize-controls' , 'jquery', 'underscore'),
|
||||
// 'ver' => ( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : $args['version'],
|
||||
// 'in_footer' => true
|
||||
// )
|
||||
// ),
|
||||
// 'localized_control_js' => array(
|
||||
// 'deps' => 'czr-customizer-fmk',
|
||||
// 'global_var_name' => 'socialLocalized',
|
||||
// 'params' => array(
|
||||
// //Social Module
|
||||
// 'defaultSocialColor' => 'rgb(90,90,90)',
|
||||
// 'defaultSocialSize' => 14,
|
||||
// //option value for dynamic registration
|
||||
// )
|
||||
// )
|
||||
// ),
|
||||
function czr_register_dynamic_modules_customizer_control_assets() {
|
||||
if ( !is_array( $this->registered_modules ) || empty( $this->registered_modules ) )
|
||||
return;
|
||||
|
||||
$wp_scripts = wp_scripts();
|
||||
|
||||
// loop on each registered modules
|
||||
foreach ( $this->registered_modules as $module_type => $params ) {
|
||||
$params = wp_parse_args( $params, $this->default_dynamic_module_params );
|
||||
//error_log( print_r( $params, true ) );
|
||||
$control_js_params = $params[ 'customizer_assets' ][ 'control_js' ];
|
||||
// Enqueue the list of registered scripts
|
||||
if ( !empty( $control_js_params ) ) {
|
||||
foreach ( $control_js_params as $handle => $script_args ) {
|
||||
if ( !isset( $wp_scripts->registered[$handle] ) ) {
|
||||
wp_enqueue_script(
|
||||
$handle,
|
||||
array_key_exists( 'src', $script_args ) ? $script_args['src'] : null,
|
||||
array_key_exists( 'deps', $script_args ) ? $script_args['deps'] : null,
|
||||
array_key_exists( 'ver', $script_args ) ? $script_args['ver'] : null,
|
||||
array_key_exists( 'in_footer', $script_args ) ? $script_args['in_footer'] : false
|
||||
);
|
||||
} else {
|
||||
error_log( __CLASS__ . '::' . __FUNCTION__ . " => handle already registered : " . $handle . " , this asset won't be enqueued => " . $script_args['src'] );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 'localized_control_js' => array(
|
||||
// 'deps' => 'czr-customizer-fmk',
|
||||
// 'global_var_name' => 'socialLocalized',
|
||||
// 'params' => array(
|
||||
// //Social Module
|
||||
// 'defaultSocialColor' => 'rgb(90,90,90)',
|
||||
// 'defaultSocialSize' => 14,
|
||||
// //option value for dynamic registration
|
||||
// )
|
||||
// )
|
||||
// Print localized params if any
|
||||
if ( array_key_exists( 'localized_control_js', $params[ 'customizer_assets' ] ) ) {
|
||||
$localized_control_js_params = is_array( $params[ 'customizer_assets' ][ 'localized_control_js' ] ) ? $params[ 'customizer_assets' ][ 'localized_control_js' ] : array();
|
||||
|
||||
if ( is_array( $localized_control_js_params ) && !empty( $localized_control_js_params ) ) {
|
||||
wp_localize_script(
|
||||
array_key_exists( 'deps', $localized_control_js_params ) ? $localized_control_js_params['deps'] : '',
|
||||
array_key_exists( 'global_var_name', $localized_control_js_params ) ? $localized_control_js_params['global_var_name'] : '',
|
||||
array_key_exists( 'params', $localized_control_js_params ) ? $localized_control_js_params['params'] : array()
|
||||
);
|
||||
}
|
||||
}
|
||||
}//foreach
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// AJAX TEMPLATE FILTERS
|
||||
// hook : init
|
||||
function czr_schedule_ajax_tmpl() {
|
||||
if ( !is_array( $this->registered_modules ) || empty( $this->registered_modules ) )
|
||||
return;
|
||||
|
||||
foreach ( $this->registered_modules as $module_type => $params ) {
|
||||
$params = wp_parse_args( $params, $this->default_dynamic_module_params );
|
||||
if ( !empty( $params['tmpl'] ) ) {
|
||||
$module_type = $params['module_type'];
|
||||
// filter declared with $html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl, $_POST );
|
||||
add_filter( "ac_set_ajax_czr_tmpl___{$module_type}", array( $this, 'ac_get_ajax_module_tmpl'), 10, 3 );
|
||||
}
|
||||
}//foreach
|
||||
}
|
||||
|
||||
|
||||
// AJAX TMPL FILTERS
|
||||
// this dynamic filter is declared on wp_ajax_ac_get_template
|
||||
// It allows us to populate the server response with the relevant module html template
|
||||
// $html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl );
|
||||
//
|
||||
// Each template is built from a map, each input type having its own unique piece of tmpl
|
||||
//
|
||||
// 3 types of templates :
|
||||
// 1) the pre-item, rendered when adding an item
|
||||
// 2) the module meta options, or mod-opt
|
||||
// 3) the item input options
|
||||
// @param $posted_params is the $_POST
|
||||
// hook : ac_set_ajax_czr_tmpl___{$module_type}
|
||||
function ac_get_ajax_module_tmpl( $html, $requested_tmpl = '', $posted_params = array() ) {
|
||||
// error_log( '<REGISTERED MODULES>' );
|
||||
// error_log( print_r( $this->registered_modules, true ) );
|
||||
// error_log( '</REGISTERED MODULES>' );
|
||||
// error_log( '<GET AJAX MODULE TMPL>' );
|
||||
// error_log( print_r( $posted_params, true ) );
|
||||
// error_log( '</GET AJAX MODULE TMPL>' );
|
||||
// the module type is sent in the $posted_params
|
||||
if ( !is_array( $posted_params ) || empty( $posted_params ) ) {
|
||||
wp_send_json_error( 'ac_get_ajax_module_tmpl => empty posted_params' );
|
||||
}
|
||||
if ( !array_key_exists( 'module_type', $posted_params ) || empty( $posted_params['module_type'] ) ) {
|
||||
wp_send_json_error( 'ac_get_ajax_module_tmpl => missing module_type' );
|
||||
}
|
||||
// if ( !array_key_exists( 'control_id', $posted_params ) || empty( $posted_params['control_id'] ) ) {
|
||||
// wp_send_json_error( 'ac_get_ajax_module_tmpl => missing control_id' );
|
||||
// }
|
||||
|
||||
// find the requested module_id in the list of registered modules
|
||||
$registered_modules = $this->registered_modules;
|
||||
$module_type = $posted_params['module_type'];
|
||||
if ( !array_key_exists( $module_type, $registered_modules ) || empty( $registered_modules[ $module_type ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$module_params = $registered_modules[ $module_type ];
|
||||
// Store the params now, so we can access them when rendering the input templates
|
||||
$this->current_module_params_when_ajaxing = $module_params;
|
||||
|
||||
$tmpl_params = $module_params[ 'tmpl' ];
|
||||
// Enqueue the list of registered scripts
|
||||
if ( empty( $tmpl_params ) ) {
|
||||
return;
|
||||
}
|
||||
// the requested_tmpl can be pre-item, mod-opt or item-inputs
|
||||
$tmpl_map = array_key_exists( $requested_tmpl, $tmpl_params ) ? $tmpl_params[ $requested_tmpl ] : array();
|
||||
if ( empty( $tmpl_map ) ) {
|
||||
return;
|
||||
}
|
||||
// Do we have tabs ?
|
||||
// With tabs
|
||||
// 'tabs' => array(
|
||||
// array(
|
||||
// 'title' => __('Spacing', 'text_doma'),
|
||||
// 'inputs' => array(
|
||||
// 'padding' => array(
|
||||
// 'input_type' => 'number',
|
||||
// 'title' => __('Padding', 'text_doma')
|
||||
// ),
|
||||
// 'margin' => array(
|
||||
// 'input_type' => 'number',
|
||||
// 'title' => __('Margin', 'text_doma')
|
||||
// )
|
||||
// )
|
||||
// ),
|
||||
// array( ... )
|
||||
//
|
||||
//
|
||||
// Without tabs :
|
||||
// 'padding' => array(
|
||||
// 'input_type' => 'number',
|
||||
// 'title' => __('Padding', 'text_doma')
|
||||
// ),
|
||||
// 'margin' => array(
|
||||
// 'input_type' => 'number',
|
||||
// 'title' => __('Margin', 'text_doma')
|
||||
// )
|
||||
if ( array_key_exists( 'tabs', $tmpl_map ) ) {
|
||||
ob_start();
|
||||
?>
|
||||
<div class="tabs tabs-style-topline">
|
||||
<nav>
|
||||
<ul>
|
||||
<?php
|
||||
// print the tabs nav
|
||||
foreach ( $tmpl_map['tabs'] as $_key => $tab ) {
|
||||
printf( '<li data-tab-id="section-topline-%1$s" %2$s><a href="#"><span>%3$s</span></a></li>',
|
||||
esc_attr($_key + 1),
|
||||
esc_attr(array_key_exists('attributes', $tab) ? $tab['attributes'] : ''),
|
||||
esc_html($tab['title'])
|
||||
);
|
||||
}//foreach
|
||||
?>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="content-wrap">
|
||||
<?php
|
||||
foreach ( $tmpl_map['tabs'] as $_key => $tab ) {
|
||||
printf( '<section id="section-topline-%1$s">%2$s</section>',
|
||||
esc_attr($_key + 1),
|
||||
wp_kses_post($this->ac_generate_czr_tmpl_from_map( $tab['inputs'] ))
|
||||
);
|
||||
}//foreach
|
||||
?>
|
||||
</div><?php //.content-wrap ?>
|
||||
</div><?php //.tabs ?>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
} else {
|
||||
return $this->ac_generate_czr_tmpl_from_map( $tmpl_map );
|
||||
}
|
||||
}
|
||||
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,449 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Customizer ajax content picker actions
|
||||
*
|
||||
*/
|
||||
// CZR_Fmk_Base
|
||||
if ( !class_exists( 'CZR_Fmk_Base' ) ) :
|
||||
class CZR_Fmk_Base extends CZR_Fmk_Dyn_Module_Registration {
|
||||
|
||||
//fired in the constructor
|
||||
public function czr_setup_content_picker_ajax_actions() {
|
||||
if ( current_user_can( 'customize' ) ) {
|
||||
add_action( 'wp_ajax_load-available-content-items-customizer' , array( $this, 'ajax_load_available_items' ) );
|
||||
add_action( 'wp_ajax_search-available-content-items-customizer' , array( $this, 'ajax_search_available_items' ) );
|
||||
}
|
||||
|
||||
// CONTENT PICKER INPUT
|
||||
//add the _custom_ item to the content picker retrieved in ajax
|
||||
//add_filter( 'content_picker_ajax_items', array( $this, 'czr_add_custom_item_to_ajax_results' ), 10, 3 );
|
||||
}
|
||||
|
||||
// hook : 'content_picker_ajax_items'
|
||||
function czr_add_custom_item_to_ajax_results( $items, $page, $context ) {
|
||||
if ( is_numeric( $page ) && $page < 1 ) {
|
||||
return array_merge(
|
||||
array(
|
||||
array(
|
||||
'title' => sprintf( '<span style="font-weight:bold">%1$s</span>', __('Set a custom url', 'text_doma') ),
|
||||
'type' => '',
|
||||
'type_label' => '',
|
||||
'object' => '',
|
||||
'id' => '_custom_',
|
||||
'url' => ''
|
||||
)
|
||||
),
|
||||
$items
|
||||
);
|
||||
} else {
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//hook : 'pre_post_link'
|
||||
function dont_use_fancy_permalinks() {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* LOAD
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Ajax handler for loading available content items.
|
||||
* hook : wp_ajax_load-available-content-items-customizer
|
||||
*/
|
||||
public function ajax_load_available_items() {
|
||||
$action = 'save-customize_' . get_stylesheet();
|
||||
if ( !check_ajax_referer( $action, 'nonce', false ) ) {
|
||||
wp_send_json_error( array(
|
||||
'code' => 'invalid_nonce',
|
||||
'message' => __( 'ajax_load_available_items => Security check failed.' ),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
wp_send_json_error('ajax_load_available_items => user_cant_edit_theme_options');
|
||||
}
|
||||
if ( !isset( $_POST['wp_object_types'] ) || empty( $_POST['wp_object_types'] ) ) {
|
||||
wp_send_json_error( 'czr_ajax_content_picker_missing_type_or_object_parameter' );
|
||||
}
|
||||
|
||||
if ( !isset( $_POST['page'] ) ) {
|
||||
wp_send_json_error( 'czr_ajax_content_picker_missing_pagination_param' );
|
||||
}
|
||||
|
||||
//error_log( print_r($_POST, true ) );
|
||||
|
||||
$wp_object_types = json_decode( wp_unslash( $_POST['wp_object_types'] ), true );
|
||||
|
||||
//$wp_object_types should look like :
|
||||
//array(
|
||||
// post : '',//<= all post types
|
||||
// taxonomy : ''//<= all taxonomy types
|
||||
//) OR
|
||||
//array(
|
||||
// post : [ 'page', 'cpt1', ...]
|
||||
// taxonomy : [ 'category', 'tag', 'Custom_Tax_1', ... ]
|
||||
//) OR
|
||||
//array(
|
||||
// post : [ 'page', 'cpt1', ...]
|
||||
// taxonomy : '_none_'//<= don't load or search taxonomies
|
||||
//)
|
||||
if ( !is_array( $wp_object_types ) || empty( $wp_object_types ) ) {
|
||||
wp_send_json_error( 'czr_ajax_content_picker_missing_object_types' );
|
||||
}
|
||||
$page = empty( $_POST['page'] ) ? 0 : absint( $_POST['page'] );
|
||||
//do we need that ?
|
||||
// if ( $page < 1 ) {
|
||||
// $page = 1;
|
||||
// }
|
||||
|
||||
$items = array();
|
||||
|
||||
add_filter( 'pre_post_link', array( $this, 'dont_use_fancy_permalinks' ), 999 );
|
||||
foreach ( $wp_object_types as $_type => $_obj_types ) {
|
||||
if ( '_none_' == $_obj_types )
|
||||
continue;
|
||||
$item_candidates = $this -> load_available_items_query(
|
||||
array(
|
||||
'type' => $_type, //<= post or taxonomy
|
||||
'object_types' => $_obj_types,//<= '' or array( type1, type2, ... )
|
||||
'page' => $page
|
||||
)
|
||||
);
|
||||
if ( is_array( $item_candidates ) ) {
|
||||
$items = array_merge(
|
||||
$items,
|
||||
$item_candidates
|
||||
);
|
||||
}
|
||||
}
|
||||
remove_filter( 'pre_post_link', array( $this, 'dont_use_fancy_permalinks' ), 999 );
|
||||
|
||||
if ( is_wp_error( $items ) ) {
|
||||
wp_send_json_error( $items->get_error_code() );
|
||||
} else {
|
||||
wp_send_json_success( array(
|
||||
'items' => apply_filters( 'content_picker_ajax_items', $items, $page, 'ajax_load_available_items' )
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs the post_type and taxonomy queries for loading available items.
|
||||
*
|
||||
* @since
|
||||
* @access public
|
||||
*
|
||||
* @param string $type Optional. Accepts any custom object type and has built-in support for
|
||||
* 'post_type' and 'taxonomy'. Default is 'post_type'.
|
||||
* @param string $object Optional. Accepts any registered taxonomy or post type name. Default is 'page'.
|
||||
* @param int $page Optional. The page number used to generate the query offset. Default is '0'.
|
||||
* @return WP_Error|array Returns either a WP_Error object or an array of menu items.
|
||||
*/
|
||||
public function load_available_items_query( $args ) {
|
||||
//normalize args
|
||||
$args = wp_parse_args( $args, array(
|
||||
'type' => 'post',
|
||||
'object_types' => '_all_',//could be page, post, or any CPT
|
||||
'page' => 0
|
||||
) );
|
||||
|
||||
$type = $args['type'];
|
||||
$object_types = $args['object_types'];
|
||||
$page = $args['page'];
|
||||
|
||||
$items = array();
|
||||
if ( 'post' === $type ) {
|
||||
//What are the post types we need to fetch ?
|
||||
if ( '_all_' == $object_types || !is_array( $object_types ) || ( is_array( $object_types ) && empty( $object_types ) ) ) {
|
||||
$post_types = get_post_types( array( 'public' => true ) );
|
||||
} else {
|
||||
$post_types = $object_types;
|
||||
}
|
||||
if ( !$post_types || !is_array( $post_types ) || empty( $post_types ) ) {
|
||||
return new \WP_Error( 'czr_contents_invalid_post_type' );
|
||||
}
|
||||
|
||||
$posts = get_posts( array(
|
||||
'numberposts' => 5,
|
||||
'offset' => 5 * $page,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'post_type' => $post_types,
|
||||
) );
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$post_title = $post->post_title;
|
||||
if ( '' === $post_title ) {
|
||||
// translators: %d: ID of a post
|
||||
$post_title = sprintf( __( '#%d (no title)', 'text_doma' ), $post->ID );
|
||||
}
|
||||
$items[] = array(
|
||||
'title' => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ),
|
||||
'type' => 'post',
|
||||
'type_label' => get_post_type_object( $post->post_type )->labels->singular_name,
|
||||
'object' => $post->post_type,
|
||||
'id' => intval( $post->ID ),
|
||||
'url' => get_permalink( intval( $post->ID ) ),
|
||||
);
|
||||
}
|
||||
|
||||
} elseif ( 'taxonomy' === $type ) {
|
||||
//What are the taxonomy types we need to fetch ?
|
||||
if ( '_all_' == $object_types || !is_array( $object_types ) || ( is_array( $object_types ) && empty( $object_types ) ) ) {
|
||||
$taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'names' );
|
||||
} else {
|
||||
$taxonomies = $object_types;
|
||||
}
|
||||
if ( !$taxonomies || !is_array( $taxonomies ) || empty( $taxonomies ) ) {
|
||||
return new \WP_Error( 'czr_contents_invalid_post_type' );
|
||||
}
|
||||
$terms = get_terms( $taxonomies, array(
|
||||
'child_of' => 0,
|
||||
'exclude' => '',
|
||||
'hide_empty' => false,
|
||||
'hierarchical' => 1,
|
||||
'include' => '',
|
||||
'number' => 5,
|
||||
'offset' => 5 * $page,
|
||||
'order' => 'DESC',
|
||||
'orderby' => 'count',
|
||||
'pad_counts' => false,
|
||||
) );
|
||||
if ( is_wp_error( $terms ) ) {
|
||||
return $terms;
|
||||
}
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
$items[] = array(
|
||||
'title' => html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ),
|
||||
'type' => 'taxonomy',
|
||||
'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name,
|
||||
'object' => $term->taxonomy,
|
||||
'id' => intval( $term->term_id ),
|
||||
'url' => get_term_link( intval( $term->term_id ), $term->taxonomy ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the available items.
|
||||
*
|
||||
* @since
|
||||
*
|
||||
* @param array $items The array of menu items.
|
||||
* @param string $type The object type.
|
||||
* @param string $object The object name.
|
||||
* @param int $page The current page number.
|
||||
*/
|
||||
$items = apply_filters( 'czr_customize_content_picker_available_items', $items, $type, $object_types, $page );
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SEARCH
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Ajax handler for searching available menu items.
|
||||
* hook : wp_ajax_search-available-content-items-customizer
|
||||
*/
|
||||
public function ajax_search_available_items() {
|
||||
$action = 'save-customize_' . get_stylesheet();
|
||||
if ( !check_ajax_referer( $action, 'nonce', false ) ) {
|
||||
wp_send_json_error( array(
|
||||
'code' => 'invalid_nonce',
|
||||
'message' => __( 'ajax_load_available_items => Security check failed.' ),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
wp_send_json_error('ajax_load_available_items => user_cant_edit_theme_options');
|
||||
}
|
||||
if ( !isset( $_POST['wp_object_types'] ) || empty( $_POST['wp_object_types'] ) ) {
|
||||
wp_send_json_error( 'czr_ajax_content_picker_missing_type_or_object_parameter' );
|
||||
}
|
||||
if ( empty( $_POST['search'] ) ) {
|
||||
wp_send_json_error( 'czr_contents_missing_search_parameter' );
|
||||
}
|
||||
|
||||
$p = isset( $_POST['page'] ) ? absint( $_POST['page'] ) : 0;
|
||||
if ( $p < 1 ) {
|
||||
$p = 1;
|
||||
}
|
||||
$s = sanitize_text_field( wp_unslash( $_POST['search'] ) );
|
||||
|
||||
$wp_object_types = json_decode( wp_unslash( $_POST['wp_object_types'] ), true );
|
||||
|
||||
//$wp_object_types should look like :
|
||||
//array(
|
||||
// post : '',//<= all post types
|
||||
// taxonomy : ''//<= all taxonomy types
|
||||
//) OR
|
||||
//array(
|
||||
// post : [ 'page', 'cpt1', ...]
|
||||
// taxonomy : [ 'category', 'tag', 'Custom_Tax_1', ... ]
|
||||
//) OR
|
||||
//array(
|
||||
// post : [ 'page', 'cpt1', ...]
|
||||
// taxonomy : '_none_'//<= don't load or search taxonomies
|
||||
//)
|
||||
if ( !is_array( $wp_object_types ) || empty( $wp_object_types ) ) {
|
||||
wp_send_json_error( 'czr_ajax_content_picker_missing_object_types' );
|
||||
}
|
||||
|
||||
$items = array();
|
||||
|
||||
add_filter( 'pre_post_link', array( $this, 'dont_use_fancy_permalinks' ), 999 );
|
||||
|
||||
foreach ( $wp_object_types as $_type => $_obj_types ) {
|
||||
if ( '_none_' == $_obj_types )
|
||||
continue;
|
||||
$item_candidates = $this -> search_available_items_query(
|
||||
array(
|
||||
'type' => $_type, //<= post or taxonomy
|
||||
'object_types' => $_obj_types,//<= '' or array( type1, type2, ... )
|
||||
'pagenum' => $p,
|
||||
's' => $s
|
||||
)
|
||||
);
|
||||
if ( is_array( $item_candidates ) ) {
|
||||
$items = array_merge(
|
||||
$items,
|
||||
$item_candidates
|
||||
);
|
||||
}
|
||||
}
|
||||
remove_filter( 'pre_post_link', array( $this, 'dont_use_fancy_permalinks' ), 999 );
|
||||
|
||||
if ( empty( $items ) ) {
|
||||
wp_send_json_success( array( 'message' => __( 'No results found.', 'text_doma') ) );
|
||||
} else {
|
||||
wp_send_json_success( array(
|
||||
'items' => apply_filters( 'content_picker_ajax_items', $items, $p, 'ajax_search_available_items' )
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs post queries for available-item searching.
|
||||
*
|
||||
* Based on WP_Editor::wp_link_query().
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
|
||||
* @return array Menu items.
|
||||
*/
|
||||
public function search_available_items_query( $args = array() ) {
|
||||
//normalize args
|
||||
$args = wp_parse_args( $args, array(
|
||||
'pagenum' => 1,
|
||||
's' => '',
|
||||
'type' => 'post',
|
||||
'object_types' => '_all_'//could be page, post, or any CPT
|
||||
) );
|
||||
$object_types = $args['object_types'];
|
||||
|
||||
//TODO: need a search only on the allowed types
|
||||
$items = array();
|
||||
if ( 'post' === $args['type'] ) {
|
||||
//What are the post types we need to fetch ?
|
||||
if ( '_all_' == $object_types || !is_array( $object_types ) || ( is_array( $object_types ) && empty( $object_types ) ) ) {
|
||||
$post_types = get_post_types( array( 'public' => true ) );
|
||||
} else {
|
||||
$post_types = $object_types;
|
||||
}
|
||||
if ( !$post_types || empty( $post_types ) ) {
|
||||
return new \WP_Error( 'czr_contents_invalid_post_type' );
|
||||
}
|
||||
|
||||
$query = array(
|
||||
'suppress_filters' => true,
|
||||
'update_post_term_cache' => false,
|
||||
'update_post_meta_cache' => false,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => 10,
|
||||
);
|
||||
$args['pagenum'] = isset( $args['pagenum'] ) ? absint( $args['pagenum'] ) : 1;
|
||||
$query['offset'] = $args['pagenum'] > 1 ? $query['posts_per_page'] * ( $args['pagenum'] - 1 ) : 0;
|
||||
$query['post_type'] = $post_types;
|
||||
|
||||
if ( isset( $args['s'] ) ) {
|
||||
$query['s'] = $args['s'];
|
||||
}
|
||||
|
||||
// Query posts.
|
||||
$get_posts = new \WP_Query( $query );
|
||||
// Check if any posts were found.
|
||||
if ( $get_posts->post_count ) {
|
||||
foreach ( $get_posts->posts as $post ) {
|
||||
$post_title = $post->post_title;
|
||||
if ( '' === $post_title ) {
|
||||
/* translators: %d: ID of a post */
|
||||
$post_title = sprintf( __( '#%d (no title)', 'text_doma' ), $post->ID );
|
||||
}
|
||||
$items[] = array(
|
||||
'title' => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ),
|
||||
'type' => 'post',
|
||||
'type_label' => get_post_type_object( $post->post_type )->labels->singular_name,
|
||||
'object' => $post->post_type,
|
||||
'id' => intval( $post->ID ),
|
||||
'url' => get_permalink( intval( $post->ID ) ),
|
||||
);
|
||||
}
|
||||
}
|
||||
} elseif ( 'taxonomy' === $args['type'] ) {
|
||||
//What are the taxonomy types we need to fetch ?
|
||||
if ( '_all_' == $object_types || !is_array( $object_types ) || ( is_array( $object_types ) && empty( $object_types ) ) ) {
|
||||
$taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'names' );
|
||||
} else {
|
||||
$taxonomies = $object_types;
|
||||
}
|
||||
if ( !$taxonomies || !is_array( $taxonomies ) || empty( $taxonomies ) ) {
|
||||
return new \WP_Error( 'czr_contents_invalid_post_type' );
|
||||
}
|
||||
$terms = get_terms( $taxonomies, array(
|
||||
'name__like' => $args['s'],
|
||||
'number' => 10,
|
||||
'offset' => 10 * ( $args['pagenum'] - 1 )
|
||||
) );
|
||||
|
||||
// Check if any taxonomies were found.
|
||||
if ( !empty( $terms ) ) {
|
||||
foreach ( $terms as $term ) {
|
||||
$items[] = array(
|
||||
'title' => html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ),
|
||||
'type' => 'taxonomy',
|
||||
'type_label' => get_taxonomy( $term->taxonomy )->labels->singular_name,
|
||||
'object' => $term->taxonomy,
|
||||
'id' => intval( $term->term_id ),
|
||||
'url' => get_term_link( intval( $term->term_id ), $term->taxonomy ),
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Filters the available menu items during a search request.
|
||||
*
|
||||
* @since 4.5.0
|
||||
*
|
||||
* @param array $items The array of menu items.
|
||||
* @param array $args Includes 'pagenum' and 's' (search) arguments.
|
||||
*/
|
||||
$items = apply_filters( 'czr_customize_content_picker_searched_items', $items, $args );
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* @uses wp_get_theme() the optional stylesheet parameter value takes into account the possible preview of a theme different than the one activated
|
||||
*/
|
||||
function czr_get_parent_theme_slug() {
|
||||
$theme_slug = get_option( 'stylesheet' );
|
||||
// $_REQUEST['theme'] is set both in live preview and when we're customizing a non active theme
|
||||
$theme_slug = sanitize_text_field( isset($_REQUEST['theme']) ? $_REQUEST['theme'] : $theme_slug ); //old wp versions
|
||||
$theme_slug = sanitize_text_field( isset($_REQUEST['customize_theme']) ? $_REQUEST['customize_theme'] : $theme_slug );
|
||||
|
||||
//gets the theme name (or parent if child)
|
||||
$theme_data = wp_get_theme( $theme_slug );
|
||||
if ( $theme_data -> parent() ) {
|
||||
$theme_slug = $theme_data -> parent() -> Name;
|
||||
}
|
||||
|
||||
return sanitize_file_name( strtolower( $theme_slug ) );
|
||||
}
|
||||
|
||||
|
||||
//@return boolean
|
||||
function czr_is_multi_item_module( $module_type ) {
|
||||
$is_multi_item = false;
|
||||
$module_params = CZR_Fmk_Base() -> czr_get_registered_dynamic_module( $module_type );
|
||||
if ( is_array( $module_params ) ) {
|
||||
if ( array_key_exists( 'is_crud', $module_params ) ) {
|
||||
$is_multi_item = (bool)$module_params['is_crud'];
|
||||
}
|
||||
if ( array_key_exists( 'is_multi_item', $module_params ) ) {
|
||||
$is_multi_item = (bool)$module_params['is_multi_item'];
|
||||
}
|
||||
}
|
||||
return $is_multi_item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Creates a new instance
|
||||
//@params ex :
|
||||
//array(
|
||||
// 'base_url' => NIMBLE_BASE_URL . '/inc/czr-base-fmk'
|
||||
// )
|
||||
function CZR_Fmk_Base( $params = array() ) {
|
||||
return CZR_Fmk_Base::czr_fmk_get_instance( $params );
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,22 @@
|
||||
.czr-sub-set[data-input-type="content_picker"] .customize-control-title {
|
||||
width: 100%;
|
||||
}
|
||||
.czr-sub-set[data-input-type="content_picker"] .czr-input {
|
||||
width: 100%;
|
||||
}
|
||||
.content-item-bar {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.czr-sub-set[data-input-type="content_picker"] span.item-title {
|
||||
display: block;
|
||||
float: left;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.czr-sub-set[data-input-type="content_picker"] span.item-type {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
padding-right: 10px;
|
||||
float: right;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.czr-sub-set[data-input-type=content_picker] .customize-control-title{width:100%}.czr-sub-set[data-input-type=content_picker] .czr-input{width:100%}.content-item-bar{line-height:1.5em}.czr-sub-set[data-input-type=content_picker] span.item-title{display:block;float:left;max-width:80%}.czr-sub-set[data-input-type=content_picker] span.item-type{display:inline-block;padding:0;padding-right:10px;float:right}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Rate link */
|
||||
#customize-footer-actions .collapse-sidebar-label {
|
||||
display: none;
|
||||
}
|
||||
.czr-rate-link {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 40px;
|
||||
right: 0;
|
||||
padding: 4px 12px 4px 0;
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
text-align: right;
|
||||
}
|
||||
.rtl .tc-rate-link {
|
||||
text-align: left;
|
||||
left: auto;
|
||||
right: 40px;
|
||||
padding: 4px 0 4px 12px;
|
||||
}
|
||||
.wp-full-overlay.collapsed .czr-rate-link {
|
||||
display: none;
|
||||
}
|
||||
.czr-rate-link .czr-stars {
|
||||
color: #E6B800;
|
||||
text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1025px) {
|
||||
.wp-customizer .expanded #customize-footer-actions {
|
||||
height: 85px;
|
||||
background: inherit;
|
||||
}
|
||||
.wp-customizer #customize-controls .wp-full-overlay-sidebar-content {
|
||||
bottom: 85px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#customize-footer-actions .collapse-sidebar-label{display:none}.czr-rate-link{position:absolute;bottom:0;left:40px;right:0;padding:4px 12px 4px 0;font-size:10px;line-height:14px;text-align:right}.rtl .tc-rate-link{text-align:left;left:auto;right:40px;padding:4px 0 4px 12px}.wp-full-overlay.collapsed .czr-rate-link{display:none}.czr-rate-link .czr-stars{color:#e6b800;text-shadow:0 1px 0 rgba(0,0,0,.6)}@media screen and (min-width:1025px){.wp-customizer .expanded #customize-footer-actions{height:85px;background:inherit}.wp-customizer #customize-controls .wp-full-overlay-sidebar-content{bottom:85px}}
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 306 B |
@@ -0,0 +1,482 @@
|
||||
.czrSelect2-container {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
vertical-align: middle; }
|
||||
.czrSelect2-container .czrSelect2-selection--single {
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
height: 28px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none; }
|
||||
.czrSelect2-container .czrSelect2-selection--single .czrSelect2-selection__rendered {
|
||||
display: block;
|
||||
padding-left: 8px;
|
||||
padding-right: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap; }
|
||||
.czrSelect2-container .czrSelect2-selection--single .czrSelect2-selection__clear {
|
||||
position: relative; }
|
||||
.czrSelect2-container[dir="rtl"] .czrSelect2-selection--single .czrSelect2-selection__rendered {
|
||||
padding-right: 8px;
|
||||
padding-left: 20px; }
|
||||
.czrSelect2-container .czrSelect2-selection--multiple {
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
min-height: 32px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none; }
|
||||
.czrSelect2-container .czrSelect2-selection--multiple .czrSelect2-selection__rendered {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
padding-left: 8px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap; }
|
||||
.czrSelect2-container .czrSelect2-search--inline {
|
||||
float: left; }
|
||||
.czrSelect2-container .czrSelect2-search--inline .czrSelect2-search__field {
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
font-size: 100%;
|
||||
margin-top: 5px;
|
||||
padding: 0; }
|
||||
.czrSelect2-container .czrSelect2-search--inline .czrSelect2-search__field::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none; }
|
||||
|
||||
.czrSelect2-dropdown {
|
||||
background-color: white;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: -100000px;
|
||||
width: 100%;
|
||||
z-index: 1051; }
|
||||
|
||||
.czrSelect2-results {
|
||||
display: block; }
|
||||
|
||||
.czrSelect2-results__options {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
.czrSelect2-results__option {
|
||||
padding: 6px;
|
||||
user-select: none;
|
||||
-webkit-user-select: none; }
|
||||
.czrSelect2-results__option[aria-selected] {
|
||||
cursor: pointer; }
|
||||
|
||||
.czrSelect2-container--open .czrSelect2-dropdown {
|
||||
left: 0; }
|
||||
|
||||
.czrSelect2-container--open .czrSelect2-dropdown--above {
|
||||
border-bottom: none;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0; }
|
||||
|
||||
.czrSelect2-container--open .czrSelect2-dropdown--below {
|
||||
border-top: none;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0; }
|
||||
|
||||
.czrSelect2-search--dropdown {
|
||||
display: block;
|
||||
padding: 4px; }
|
||||
.czrSelect2-search--dropdown .czrSelect2-search__field {
|
||||
padding: 4px;
|
||||
width: 100%;
|
||||
box-sizing: border-box; }
|
||||
.czrSelect2-search--dropdown .czrSelect2-search__field::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none; }
|
||||
.czrSelect2-search--dropdown.czrSelect2-search--hide {
|
||||
display: none; }
|
||||
|
||||
.czrSelect2-close-mask {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
min-height: 100%;
|
||||
min-width: 100%;
|
||||
height: auto;
|
||||
width: auto;
|
||||
opacity: 0;
|
||||
z-index: 99;
|
||||
background-color: #fff;
|
||||
filter: alpha(opacity=0); }
|
||||
|
||||
.czrSelect2-hidden-accessible {
|
||||
border: 0 !important;
|
||||
clip: rect(0 0 0 0) !important;
|
||||
height: 1px !important;
|
||||
margin: -1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
position: absolute !important;
|
||||
width: 1px !important; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-selection--single {
|
||||
background-color: #fff;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--single .czrSelect2-selection__rendered {
|
||||
color: #444;
|
||||
line-height: 28px; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--single .czrSelect2-selection__clear {
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
font-weight: bold; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--single .czrSelect2-selection__placeholder {
|
||||
color: #999; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--single .czrSelect2-selection__arrow {
|
||||
height: 26px;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
width: 20px; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--single .czrSelect2-selection__arrow b {
|
||||
border-color: #888 transparent transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 4px 0 4px;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
margin-left: -4px;
|
||||
margin-top: -2px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 0; }
|
||||
|
||||
.czrSelect2-container--default[dir="rtl"] .czrSelect2-selection--single .czrSelect2-selection__clear {
|
||||
float: left; }
|
||||
|
||||
.czrSelect2-container--default[dir="rtl"] .czrSelect2-selection--single .czrSelect2-selection__arrow {
|
||||
left: 1px;
|
||||
right: auto; }
|
||||
|
||||
.czrSelect2-container--default.czrSelect2-container--disabled .czrSelect2-selection--single {
|
||||
background-color: #eee;
|
||||
cursor: default; }
|
||||
.czrSelect2-container--default.czrSelect2-container--disabled .czrSelect2-selection--single .czrSelect2-selection__clear {
|
||||
display: none; }
|
||||
|
||||
.czrSelect2-container--default.czrSelect2-container--open .czrSelect2-selection--single .czrSelect2-selection__arrow b {
|
||||
border-color: transparent transparent #888 transparent;
|
||||
border-width: 0 4px 5px 4px; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-selection--multiple {
|
||||
background-color: white;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
cursor: text; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--multiple .czrSelect2-selection__rendered {
|
||||
box-sizing: border-box;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0 5px;
|
||||
width: 100%; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--multiple .czrSelect2-selection__placeholder {
|
||||
color: #999;
|
||||
margin-top: 5px;
|
||||
float: left; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--multiple .czrSelect2-selection__clear {
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
margin-right: 10px; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--multiple .czrSelect2-selection__choice {
|
||||
background-color: #e4e4e4;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
cursor: default;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
margin-top: 5px;
|
||||
padding: 0 5px; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--multiple .czrSelect2-selection__choice__remove {
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
margin-right: 2px; }
|
||||
.czrSelect2-container--default .czrSelect2-selection--multiple .czrSelect2-selection__choice__remove:hover {
|
||||
color: #333; }
|
||||
|
||||
.czrSelect2-container--default[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-selection__choice, .czrSelect2-container--default[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-selection__placeholder, .czrSelect2-container--default[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-search--inline {
|
||||
float: right; }
|
||||
|
||||
.czrSelect2-container--default[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-selection__choice {
|
||||
margin-left: 5px;
|
||||
margin-right: auto; }
|
||||
|
||||
.czrSelect2-container--default[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-selection__choice__remove {
|
||||
margin-left: 2px;
|
||||
margin-right: auto; }
|
||||
|
||||
.czrSelect2-container--default.czrSelect2-container--focus .czrSelect2-selection--multiple {
|
||||
border: solid black 1px;
|
||||
outline: 0; }
|
||||
|
||||
.czrSelect2-container--default.czrSelect2-container--disabled .czrSelect2-selection--multiple {
|
||||
background-color: #eee;
|
||||
cursor: default; }
|
||||
|
||||
.czrSelect2-container--default.czrSelect2-container--disabled .czrSelect2-selection__choice__remove {
|
||||
display: none; }
|
||||
|
||||
.czrSelect2-container--default.czrSelect2-container--open.czrSelect2-container--above .czrSelect2-selection--single, .czrSelect2-container--default.czrSelect2-container--open.czrSelect2-container--above .czrSelect2-selection--multiple {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0; }
|
||||
|
||||
.czrSelect2-container--default.czrSelect2-container--open.czrSelect2-container--below .czrSelect2-selection--single, .czrSelect2-container--default.czrSelect2-container--open.czrSelect2-container--below .czrSelect2-selection--multiple {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-search--dropdown .czrSelect2-search__field {
|
||||
border: 1px solid #aaa; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-search--inline .czrSelect2-search__field {
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: 0;
|
||||
box-shadow: none;
|
||||
-webkit-appearance: textfield; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-results > .czrSelect2-results__options {
|
||||
max-height: 200px;
|
||||
overflow-y: auto; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-results__option[role=group] {
|
||||
padding: 0; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-results__option[aria-disabled=true] {
|
||||
color: #999; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-results__option[aria-selected=true] {
|
||||
background-color: #ddd; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-results__option .czrSelect2-results__option {
|
||||
padding-left: 1em; }
|
||||
.czrSelect2-container--default .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__group {
|
||||
padding-left: 0; }
|
||||
.czrSelect2-container--default .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option {
|
||||
margin-left: -1em;
|
||||
padding-left: 2em; }
|
||||
.czrSelect2-container--default .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option {
|
||||
margin-left: -2em;
|
||||
padding-left: 3em; }
|
||||
.czrSelect2-container--default .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option {
|
||||
margin-left: -3em;
|
||||
padding-left: 4em; }
|
||||
.czrSelect2-container--default .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option {
|
||||
margin-left: -4em;
|
||||
padding-left: 5em; }
|
||||
.czrSelect2-container--default .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option .czrSelect2-results__option {
|
||||
margin-left: -5em;
|
||||
padding-left: 6em; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-results__option--highlighted[aria-selected] {
|
||||
background-color: #5897fb;
|
||||
color: white; }
|
||||
|
||||
.czrSelect2-container--default .czrSelect2-results__group {
|
||||
cursor: default;
|
||||
display: block;
|
||||
padding: 6px; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-selection--single {
|
||||
background-color: #f7f7f7;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
outline: 0;
|
||||
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
|
||||
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
|
||||
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--single:focus {
|
||||
border: 1px solid #5897fb; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--single .czrSelect2-selection__rendered {
|
||||
color: #444;
|
||||
line-height: 28px; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--single .czrSelect2-selection__clear {
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
margin-right: 10px; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--single .czrSelect2-selection__placeholder {
|
||||
color: #999; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--single .czrSelect2-selection__arrow {
|
||||
background-color: #ddd;
|
||||
border: none;
|
||||
border-left: 1px solid #aaa;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
height: 26px;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
width: 20px;
|
||||
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
||||
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
|
||||
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--single .czrSelect2-selection__arrow b {
|
||||
border-color: #888 transparent transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 4px 0 4px;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
margin-left: -4px;
|
||||
margin-top: -2px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 0; }
|
||||
|
||||
.czrSelect2-container--classic[dir="rtl"] .czrSelect2-selection--single .czrSelect2-selection__clear {
|
||||
float: left; }
|
||||
|
||||
.czrSelect2-container--classic[dir="rtl"] .czrSelect2-selection--single .czrSelect2-selection__arrow {
|
||||
border: none;
|
||||
border-right: 1px solid #aaa;
|
||||
border-radius: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
left: 1px;
|
||||
right: auto; }
|
||||
|
||||
.czrSelect2-container--classic.czrSelect2-container--open .czrSelect2-selection--single {
|
||||
border: 1px solid #5897fb; }
|
||||
.czrSelect2-container--classic.czrSelect2-container--open .czrSelect2-selection--single .czrSelect2-selection__arrow {
|
||||
background: transparent;
|
||||
border: none; }
|
||||
.czrSelect2-container--classic.czrSelect2-container--open .czrSelect2-selection--single .czrSelect2-selection__arrow b {
|
||||
border-color: transparent transparent #888 transparent;
|
||||
border-width: 0 4px 5px 4px; }
|
||||
|
||||
.czrSelect2-container--classic.czrSelect2-container--open.czrSelect2-container--above .czrSelect2-selection--single {
|
||||
border-top: none;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
|
||||
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
|
||||
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
|
||||
|
||||
.czrSelect2-container--classic.czrSelect2-container--open.czrSelect2-container--below .czrSelect2-selection--single {
|
||||
border-bottom: none;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
|
||||
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
|
||||
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-selection--multiple {
|
||||
background-color: white;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
cursor: text;
|
||||
outline: 0; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--multiple:focus {
|
||||
border: 1px solid #5897fb; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--multiple .czrSelect2-selection__rendered {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0 5px; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--multiple .czrSelect2-selection__clear {
|
||||
display: none; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--multiple .czrSelect2-selection__choice {
|
||||
background-color: #e4e4e4;
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 4px;
|
||||
cursor: default;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
margin-top: 5px;
|
||||
padding: 0 5px; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--multiple .czrSelect2-selection__choice__remove {
|
||||
color: #888;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
margin-right: 2px; }
|
||||
.czrSelect2-container--classic .czrSelect2-selection--multiple .czrSelect2-selection__choice__remove:hover {
|
||||
color: #555; }
|
||||
|
||||
.czrSelect2-container--classic[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-selection__choice {
|
||||
float: right; }
|
||||
|
||||
.czrSelect2-container--classic[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-selection__choice {
|
||||
margin-left: 5px;
|
||||
margin-right: auto; }
|
||||
|
||||
.czrSelect2-container--classic[dir="rtl"] .czrSelect2-selection--multiple .czrSelect2-selection__choice__remove {
|
||||
margin-left: 2px;
|
||||
margin-right: auto; }
|
||||
|
||||
.czrSelect2-container--classic.czrSelect2-container--open .czrSelect2-selection--multiple {
|
||||
border: 1px solid #5897fb; }
|
||||
|
||||
.czrSelect2-container--classic.czrSelect2-container--open.czrSelect2-container--above .czrSelect2-selection--multiple {
|
||||
border-top: none;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0; }
|
||||
|
||||
.czrSelect2-container--classic.czrSelect2-container--open.czrSelect2-container--below .czrSelect2-selection--multiple {
|
||||
border-bottom: none;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-search--dropdown .czrSelect2-search__field {
|
||||
border: 1px solid #aaa;
|
||||
outline: 0; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-search--inline .czrSelect2-search__field {
|
||||
outline: 0;
|
||||
box-shadow: none; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-dropdown {
|
||||
background-color: white;
|
||||
border: 1px solid transparent; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-dropdown--above {
|
||||
border-bottom: none; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-dropdown--below {
|
||||
border-top: none; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-results > .czrSelect2-results__options {
|
||||
max-height: 200px;
|
||||
overflow-y: auto; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-results__option[role=group] {
|
||||
padding: 0; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-results__option[aria-disabled=true] {
|
||||
color: grey; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-results__option--highlighted[aria-selected] {
|
||||
background-color: #3875d7;
|
||||
color: white; }
|
||||
|
||||
.czrSelect2-container--classic .czrSelect2-results__group {
|
||||
cursor: default;
|
||||
display: block;
|
||||
padding: 6px; }
|
||||
|
||||
.czrSelect2-container--classic.czrSelect2-container--open .czrSelect2-dropdown {
|
||||
border-color: #5897fb; }
|
||||
|
After Width: | Height: | Size: 730 KiB |
@@ -0,0 +1,801 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||
<metadata>
|
||||
Created by FontForge 20200314 at Wed Jan 13 11:57:54 2021
|
||||
By Robert Madole
|
||||
Copyright (c) Font Awesome
|
||||
</metadata>
|
||||
<!-- Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><defs>
|
||||
<font id="FontAwesome5Free-Regular" horiz-adv-x="512" >
|
||||
<font-face
|
||||
font-family="Font Awesome 5 Free Regular"
|
||||
font-weight="400"
|
||||
font-stretch="normal"
|
||||
units-per-em="512"
|
||||
panose-1="2 0 5 3 0 0 0 0 0 0"
|
||||
ascent="448"
|
||||
descent="-64"
|
||||
bbox="-0.0663408 -64.0662 640.004 448.1"
|
||||
underline-thickness="25"
|
||||
underline-position="-50"
|
||||
unicode-range="U+0020-F5C8"
|
||||
/>
|
||||
<missing-glyph />
|
||||
<glyph glyph-name="heart" unicode=""
|
||||
d="M458.4 383.7c75.2998 -63.4004 64.0996 -166.601 10.5996 -221.3l-175.4 -178.7c-10 -10.2002 -23.2998 -15.7998 -37.5996 -15.7998c-14.2002 0 -27.5996 5.69922 -37.5996 15.8994l-175.4 178.7c-53.5996 54.7002 -64.5996 157.9 10.5996 221.2
|
||||
c57.8008 48.7002 147.101 41.2998 202.4 -15c55.2998 56.2998 144.6 63.5996 202.4 15zM434.8 196.2c36.2002 36.8994 43.7998 107.7 -7.2998 150.8c-38.7002 32.5996 -98.7002 27.9004 -136.5 -10.5996l-35 -35.7002l-35 35.7002
|
||||
c-37.5996 38.2998 -97.5996 43.1992 -136.5 10.5c-51.2002 -43.1006 -43.7998 -113.5 -7.2998 -150.7l175.399 -178.7c2.40039 -2.40039 4.40039 -2.40039 6.80078 0z" />
|
||||
<glyph glyph-name="star" unicode="" horiz-adv-x="576"
|
||||
d="M528.1 276.5c26.2002 -3.7998 36.7002 -36.0996 17.7002 -54.5996l-105.7 -103l25 -145.5c4.5 -26.3008 -23.1992 -45.9004 -46.3994 -33.7002l-130.7 68.7002l-130.7 -68.7002c-23.2002 -12.2998 -50.8994 7.39941 -46.3994 33.7002l25 145.5l-105.7 103
|
||||
c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2998l65.2998 132.4c11.7998 23.8994 45.7002 23.5996 57.4004 0l65.2998 -132.4zM388.6 135.7l100.601 98l-139 20.2002l-62.2002 126l-62.2002 -126l-139 -20.2002l100.601 -98l-23.7002 -138.4l124.3 65.2998
|
||||
l124.3 -65.2998z" />
|
||||
<glyph glyph-name="user" unicode="" horiz-adv-x="448"
|
||||
d="M313.6 144c74.2002 0 134.4 -60.2002 134.4 -134.4v-25.5996c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v25.5996c0 74.2002 60.2002 134.4 134.4 134.4c28.7998 0 42.5 -16 89.5996 -16s60.9004 16 89.5996 16zM400 -16v25.5996
|
||||
c0 47.6006 -38.7998 86.4004 -86.4004 86.4004c-14.6992 0 -37.8994 -16 -89.5996 -16c-51.2998 0 -75 16 -89.5996 16c-47.6006 0 -86.4004 -38.7998 -86.4004 -86.4004v-25.5996h352zM224 160c-79.5 0 -144 64.5 -144 144s64.5 144 144 144s144 -64.5 144 -144
|
||||
s-64.5 -144 -144 -144zM224 400c-52.9004 0 -96 -43.0996 -96 -96s43.0996 -96 96 -96s96 43.0996 96 96s-43.0996 96 -96 96z" />
|
||||
<glyph glyph-name="clock" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM317.8 96.4004l-84.8994 61.6992
|
||||
c-3.10059 2.30078 -4.90039 5.90039 -4.90039 9.7002v164.2c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12v-141.7l66.7998 -48.5996c5.40039 -3.90039 6.5 -11.4004 2.60059 -16.7998l-18.8008 -25.9004c-3.89941 -5.2998 -11.3994 -6.5 -16.7998 -2.59961z
|
||||
" />
|
||||
<glyph glyph-name="list-alt" unicode=""
|
||||
d="M464 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h416zM458 16c3.31152 0 6 2.68848 6 6v340c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-340
|
||||
c0 -3.31152 2.68848 -6 6 -6h404zM416 108v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 204v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12
|
||||
v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM416 300v-24c0 -6.62695 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h200c6.62695 0 12 -5.37305 12 -12zM164 288c0 -19.8818 -16.1182 -36 -36 -36
|
||||
s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 192c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36zM164 96c0 -19.8818 -16.1182 -36 -36 -36s-36 16.1182 -36 36s16.1182 36 36 36s36 -16.1182 36 -36z" />
|
||||
<glyph glyph-name="flag" unicode=""
|
||||
d="M336.174 368c35.4668 0 73.0195 12.6914 108.922 28.1797c31.6406 13.6514 66.9043 -9.65723 66.9043 -44.1162v-239.919c0 -16.1953 -8.1543 -31.3057 -21.7129 -40.1631c-26.5762 -17.3643 -70.0693 -39.9814 -128.548 -39.9814c-68.6084 0 -112.781 32 -161.913 32
|
||||
c-56.5674 0 -89.957 -11.2803 -127.826 -28.5566v-83.4434c0 -8.83691 -7.16309 -16 -16 -16h-16c-8.83691 0 -16 7.16309 -16 16v406.438c-14.3428 8.2998 -24 23.7979 -24 41.5615c0 27.5693 23.2422 49.71 51.2012 47.8965
|
||||
c22.9658 -1.49023 41.8662 -19.4717 44.4805 -42.3379c0.213867 -1.83398 0.308594 -3.65918 0.308594 -5.5498c0 -5.30273 -0.860352 -10.4053 -2.4502 -15.1768c22.418 8.68555 49.4199 15.168 80.7207 15.168c68.6084 0 112.781 -32 161.913 -32zM464 112v240
|
||||
c-31.5059 -14.6338 -84.5547 -32 -127.826 -32c-59.9111 0 -101.968 32 -161.913 32c-41.4365 0 -80.4766 -16.5879 -102.261 -32v-232c31.4473 14.5967 84.4648 24 127.826 24c59.9111 0 101.968 -32 161.913 -32c41.4365 0 80.4775 16.5879 102.261 32z" />
|
||||
<glyph glyph-name="bookmark" unicode="" horiz-adv-x="384"
|
||||
d="M336 448c26.5098 0 48 -21.4902 48 -48v-464l-192 112l-192 -112v464c0 26.5098 21.4902 48 48 48h288zM336 19.5703v374.434c0 3.31348 -2.68555 5.99609 -6 5.99609h-276c-3.31152 0 -6 -2.68848 -6 -6v-374.43l144 84z" />
|
||||
<glyph glyph-name="image" unicode=""
|
||||
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM458 48c3.31152 0 6 2.68848 6 6v276c0 3.31152 -2.68848 6 -6 6h-404c-3.31152 0 -6 -2.68848 -6 -6v-276
|
||||
c0 -3.31152 2.68848 -6 6 -6h404zM128 296c22.0908 0 40 -17.9092 40 -40s-17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40zM96 96v48l39.5137 39.5146c4.6875 4.68652 12.2852 4.68652 16.9717 0l39.5146 -39.5146l119.514 119.515
|
||||
c4.6875 4.68652 12.2852 4.68652 16.9717 0l87.5146 -87.5146v-80h-320z" />
|
||||
<glyph glyph-name="edit" unicode="" horiz-adv-x="576"
|
||||
d="M402.3 103.1l32 32c5 5 13.7002 1.5 13.7002 -5.69922v-145.4c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h273.5c7.09961 0 10.7002 -8.59961 5.7002 -13.7002l-32 -32c-1.5 -1.5 -3.5 -2.2998 -5.7002 -2.2998h-241.5v-352h352
|
||||
v113.5c0 2.09961 0.799805 4.09961 2.2998 5.59961zM558.9 304.9l-262.601 -262.601l-90.3994 -10c-26.2002 -2.89941 -48.5 19.2002 -45.6006 45.6006l10 90.3994l262.601 262.601c22.8994 22.8994 59.8994 22.8994 82.6992 0l43.2002 -43.2002
|
||||
c22.9004 -22.9004 22.9004 -60 0.100586 -82.7998zM460.1 274l-58.0996 58.0996l-185.8 -185.899l-7.2998 -65.2998l65.2998 7.2998zM524.9 353.7l-43.2002 43.2002c-4.10059 4.09961 -10.7998 4.09961 -14.7998 0l-30.9004 -30.9004l58.0996 -58.0996l30.9004 30.8994
|
||||
c4 4.2002 4 10.7998 -0.0996094 14.9004z" />
|
||||
<glyph glyph-name="times-circle" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM357.8 254.2l-62.2002 -62.2002l62.2002 -62.2002
|
||||
c4.7002 -4.7002 4.7002 -12.2998 0 -17l-22.5996 -22.5996c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-62.2002 62.2002l-62.2002 -62.2002c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-22.5996 22.5996c-4.7002 4.7002 -4.7002 12.2998 0 17l62.2002 62.2002l-62.2002 62.2002
|
||||
c-4.7002 4.7002 -4.7002 12.2998 0 17l22.5996 22.5996c4.7002 4.7002 12.2998 4.7002 17 0l62.2002 -62.2002l62.2002 62.2002c4.7002 4.7002 12.2998 4.7002 17 0l22.5996 -22.5996c4.7002 -4.7002 4.7002 -12.2998 0 -17z" />
|
||||
<glyph glyph-name="check-circle" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200z
|
||||
M396.204 261.733c4.66699 -4.70508 4.63672 -12.3037 -0.0673828 -16.9717l-172.589 -171.204c-4.70508 -4.66797 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66797 4.70605 -4.63672 12.3047 0.0683594 16.9717l22.7188 22.5361
|
||||
c4.70508 4.66699 12.3027 4.63574 16.9697 -0.0693359l59.792 -60.2773l141.353 140.216c4.70508 4.66797 12.3027 4.6377 16.9697 -0.0673828z" />
|
||||
<glyph glyph-name="question-circle" unicode=""
|
||||
d="M256 440c136.957 0 248 -111.083 248 -248c0 -136.997 -111.043 -248 -248 -248s-248 111.003 -248 248c0 136.917 111.043 248 248 248zM256 -8c110.569 0 200 89.4697 200 200c0 110.529 -89.5088 200 -200 200c-110.528 0 -200 -89.5049 -200 -200
|
||||
c0 -110.569 89.4678 -200 200 -200zM363.244 247.2c0 -67.0518 -72.4209 -68.084 -72.4209 -92.8633v-6.33691c0 -6.62695 -5.37305 -12 -12 -12h-45.6475c-6.62695 0 -12 5.37305 -12 12v8.65918c0 35.7451 27.1006 50.0342 47.5791 61.5156
|
||||
c17.5615 9.84473 28.3242 16.541 28.3242 29.5791c0 17.2461 -21.999 28.6934 -39.7842 28.6934c-23.1885 0 -33.8936 -10.9775 -48.9424 -29.9697c-4.05664 -5.11914 -11.46 -6.07031 -16.666 -2.12402l-27.8232 21.0986
|
||||
c-5.10742 3.87207 -6.25098 11.0654 -2.64453 16.3633c23.627 34.6934 53.7217 54.1846 100.575 54.1846c49.0713 0 101.45 -38.3037 101.45 -88.7998zM298 80c0 -23.1592 -18.8408 -42 -42 -42s-42 18.8408 -42 42s18.8408 42 42 42s42 -18.8408 42 -42z" />
|
||||
<glyph glyph-name="eye" unicode="" horiz-adv-x="576"
|
||||
d="M288 304c0.114258 0 0.240234 -0.0175781 0.354492 -0.0175781c61.6543 0 111.71 -50.0557 111.71 -111.71s-50.0557 -111.71 -111.71 -111.71s-111.71 50.0557 -111.71 111.71c0 10.7422 1.51953 21.1328 4.35547 30.9678
|
||||
c7.95898 -4.52637 17.2129 -7.17188 27 -7.24023c30.9072 0 56 25.0928 56 56c-0.0683594 9.78711 -2.71387 19.041 -7.24023 27c9.88379 3.07617 20.3896 4.83008 31.2402 5zM572.52 206.6c2.21387 -4.37793 3.46094 -9.38965 3.46094 -14.626
|
||||
c0 -5.2373 -1.24707 -10.1855 -3.46094 -14.5635c-54.1992 -105.771 -161.59 -177.41 -284.52 -177.41s-230.29 71.5898 -284.52 177.4c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635
|
||||
c54.1992 105.771 161.59 177.41 284.52 177.41s230.29 -71.5898 284.52 -177.4zM288 48c98.6602 0 189.1 55 237.93 144c-48.8398 89 -139.27 144 -237.93 144s-189.09 -55 -237.93 -144c48.8398 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="eye-slash" unicode="" horiz-adv-x="640"
|
||||
d="M634 -23c3.66895 -2.93262 6.00391 -7.45117 6.00391 -12.5088c0 -3.7832 -1.31543 -7.26074 -3.51367 -10.001l-10 -12.4902c-2.93359 -3.66309 -7.44824 -5.99414 -12.502 -5.99414c-3.77637 0 -7.25 1.31152 -9.98828 3.50391l-598 467.49
|
||||
c-3.66895 2.93262 -6.00391 7.45117 -6.00391 12.5088c0 3.7832 1.31543 7.26074 3.51367 10.001l10 12.4902c2.93359 3.66309 7.44824 5.99414 12.502 5.99414c3.77637 0 7.25 -1.31152 9.98828 -3.50391zM296.79 301.53c7.51172 1.60254 15.2266 2.45508 23.21 2.46973
|
||||
c60.4805 0 109.36 -47.9102 111.58 -107.85zM343.21 82.46c-7.51367 -1.59375 -15.2285 -2.44336 -23.21 -2.45996c-60.4697 0 -109.35 47.9102 -111.58 107.84zM320 336c-19.8799 0 -39.2803 -2.7998 -58.2197 -7.09961l-46.4102 36.29
|
||||
c32.9199 11.8096 67.9297 18.8096 104.63 18.8096c122.93 0 230.29 -71.5898 284.57 -177.4c2.21289 -4.37793 3.45996 -9.38965 3.45996 -14.626c0 -5.2373 -1.24707 -10.1855 -3.45996 -14.5635c-14.1924 -27.5625 -31.9229 -52.6689 -52.9004 -75.1104l-37.7402 29.5
|
||||
c17.2305 18.0527 31.9385 38.1318 44 60.2002c-48.8398 89 -139.279 144 -237.93 144zM320 48c19.8896 0 39.2803 2.7998 58.2197 7.08984l46.4102 -36.2803c-32.9199 -11.7598 -67.9297 -18.8096 -104.63 -18.8096c-122.92 0 -230.28 71.5898 -284.51 177.4
|
||||
c-2.21387 4.37793 -3.46094 9.38965 -3.46094 14.626c0 5.2373 1.24707 10.1855 3.46094 14.5635c14.1885 27.5586 31.916 52.6621 52.8896 75.1006l37.7402 -29.5c-17.249 -18.0469 -31.9727 -38.1221 -44.0498 -60.1904c48.8496 -89 139.279 -144 237.93 -144z" />
|
||||
<glyph glyph-name="calendar-alt" unicode="" horiz-adv-x="448"
|
||||
d="M148 160h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM256 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-40zM352 172c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM256 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40
|
||||
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM160 76c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM352 76c0 -6.59961 -5.40039 -12 -12 -12h-40
|
||||
c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="comment" unicode=""
|
||||
d="M256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5c-3.80078 8.7998 -2 19 4.59961 26
|
||||
c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004
|
||||
l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
|
||||
<glyph glyph-name="folder" unicode=""
|
||||
d="M464 320c26.5098 0 48 -21.4902 48 -48v-224c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h146.74c8.49023 0 16.6299 -3.37012 22.6299 -9.37012l54.6299 -54.6299h192zM464 48v224h-198.62
|
||||
c-8.49023 0 -16.6299 3.37012 -22.6299 9.37012l-54.6299 54.6299h-140.12v-288h416z" />
|
||||
<glyph glyph-name="folder-open" unicode="" horiz-adv-x="576"
|
||||
d="M527.9 224c37.6992 0 60.6992 -41.5 40.6992 -73.4004l-79.8994 -128c-8.7998 -14.0996 -24.2002 -22.5996 -40.7002 -22.5996h-400c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h160l64 -64h160c26.5 0 48 -21.5 48 -48v-48h47.9004zM48 330v-233.4l62.9004 104.2
|
||||
c8.69922 14.4004 24.2998 23.2002 41.0996 23.2002h280v42c0 3.2998 -2.7002 6 -6 6h-173.9l-64 64h-134.1c-3.2998 0 -6 -2.7002 -6 -6zM448 48l80 128h-378.8l-77.2002 -128h376z" />
|
||||
<glyph glyph-name="chart-bar" unicode=""
|
||||
d="M396.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v230.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-230.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM204.8 96
|
||||
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v198.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-198.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM300.8 96
|
||||
c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v134.4c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-134.4c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004zM496 48c8.83984 0 16 -7.16016 16 -16v-16
|
||||
c0 -8.83984 -7.16016 -16 -16 -16h-464c-17.6699 0 -32 14.3301 -32 32v336c0 8.83984 7.16016 16 16 16h16c8.83984 0 16 -7.16016 16 -16v-320h448zM108.8 96c-6.39941 0 -12.7998 6.40039 -12.7998 12.7998v70.4004c0 6.39941 6.40039 12.7998 12.7998 12.7998h22.4004
|
||||
c6.39941 0 12.7998 -6.40039 12.7998 -12.7998v-70.4004c0 -6.39941 -6.40039 -12.7998 -12.7998 -12.7998h-22.4004z" />
|
||||
<glyph glyph-name="comments" unicode="" horiz-adv-x="576"
|
||||
d="M532 61.7998c15.2998 -30.7002 37.4004 -54.5 37.7998 -54.7998c6.2998 -6.7002 8 -16.5 4.40039 -25c-3.7002 -8.5 -12 -14 -21.2002 -14c-53.5996 0 -96.7002 20.2998 -125.2 38.7998c-19 -4.39941 -39 -6.7998 -59.7998 -6.7998
|
||||
c-86.2002 0 -159.9 40.4004 -191.3 97.7998c-9.7002 1.2002 -19.2002 2.7998 -28.4004 4.90039c-28.5 -18.6006 -71.7002 -38.7998 -125.2 -38.7998c-9.19922 0 -17.5996 5.5 -21.1992 14c-3.7002 8.5 -1.90039 18.2998 4.39941 25
|
||||
c0.400391 0.399414 22.4004 24.1992 37.7002 54.8994c-27.5 27.2002 -44 61.2002 -44 98.2002c0 88.4004 93.0996 160 208 160c86.2998 0 160.3 -40.5 191.8 -98.0996c99.7002 -11.8008 176.2 -77.9004 176.2 -157.9c0 -37.0996 -16.5 -71.0996 -44 -98.2002zM139.2 154.1
|
||||
l19.7998 -4.5c16 -3.69922 32.5 -5.59961 49 -5.59961c86.7002 0 160 51.2998 160 112s-73.2998 112 -160 112s-160 -51.2998 -160 -112c0 -28.7002 16.2002 -50.5996 29.7002 -64l24.7998 -24.5l-15.5 -31.0996c-2.59961 -5.10059 -5.2998 -10.1006 -8 -14.8008
|
||||
c14.5996 5.10059 29 12.3008 43.0996 21.4004zM498.3 96c13.5 13.4004 29.7002 35.2998 29.7002 64c0 49.2002 -48.2998 91.5 -112.7 106c0.299805 -3.2998 0.700195 -6.59961 0.700195 -10c0 -80.9004 -78 -147.5 -179.3 -158.3
|
||||
c29.0996 -29.6006 77.2998 -49.7002 131.3 -49.7002c16.5 0 33 1.90039 49 5.59961l19.9004 4.60059l17.0996 -11.1006c14.0996 -9.09961 28.5 -16.2998 43.0996 -21.3994c-2.69922 4.7002 -5.39941 9.7002 -8 14.7998l-15.5 31.0996z" />
|
||||
<glyph glyph-name="star-half" unicode="" horiz-adv-x="576"
|
||||
d="M288 62.7002v-54.2998l-130.7 -68.6006c-23.3994 -12.2998 -50.8994 7.60059 -46.3994 33.7002l25 145.5l-105.7 103c-19 18.5 -8.5 50.7998 17.7002 54.5996l146.1 21.2002l65.2998 132.4c5.90039 11.8994 17.2998 17.7998 28.7002 17.7998v-68.0996l-62.2002 -126
|
||||
l-139 -20.2002l100.601 -98l-23.7002 -138.4z" />
|
||||
<glyph glyph-name="lemon" unicode=""
|
||||
d="M484.112 420.111c28.1221 -28.123 35.9434 -68.0039 19.0215 -97.0547c-23.0576 -39.584 50.1436 -163.384 -82.3311 -295.86c-132.301 -132.298 -256.435 -59.3594 -295.857 -82.3291c-29.0459 -16.917 -68.9219 -9.11426 -97.0576 19.0205
|
||||
c-28.1221 28.1221 -35.9434 68.0029 -19.0215 97.0547c23.0566 39.5859 -50.1436 163.386 82.3301 295.86c132.308 132.309 256.407 59.3496 295.862 82.332c29.0498 16.9219 68.9307 9.09863 97.0537 -19.0234zM461.707 347.217
|
||||
c13.5166 23.2031 -27.7578 63.7314 -50.4883 50.4912c-66.6025 -38.7939 -165.646 45.5898 -286.081 -74.8457c-120.444 -120.445 -36.0449 -219.472 -74.8447 -286.08c-13.542 -23.2471 27.8145 -63.6953 50.4932 -50.4883
|
||||
c66.6006 38.7949 165.636 -45.5996 286.076 74.8428c120.444 120.445 36.0449 219.472 74.8447 286.08zM291.846 338.481c1.37012 -10.96 -6.40332 -20.957 -17.3643 -22.3271c-54.8467 -6.85547 -135.779 -87.7871 -142.636 -142.636
|
||||
c-1.37305 -10.9883 -11.3984 -18.7334 -22.3262 -17.3643c-10.9609 1.37012 -18.7344 11.3652 -17.3643 22.3262c9.16211 73.2852 104.167 168.215 177.364 177.364c10.9531 1.36816 20.9561 -6.40234 22.3262 -17.3633z" />
|
||||
<glyph glyph-name="credit-card" unicode="" horiz-adv-x="576"
|
||||
d="M527.9 416c26.5996 0 48.0996 -21.5 48.0996 -48v-352c0 -26.5 -21.5 -48 -48.0996 -48h-479.801c-26.5996 0 -48.0996 21.5 -48.0996 48v352c0 26.5 21.5 48 48.0996 48h479.801zM54.0996 368c-3.2998 0 -6 -2.7002 -6 -6v-42h479.801v42c0 3.2998 -2.7002 6 -6 6
|
||||
h-467.801zM521.9 16c3.2998 0 6 2.7002 6 6v170h-479.801v-170c0 -3.2998 2.7002 -6 6 -6h467.801zM192 116v-40c0 -6.59961 -5.40039 -12 -12 -12h-72c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h72c6.59961 0 12 -5.40039 12 -12zM384 116v-40
|
||||
c0 -6.59961 -5.40039 -12 -12 -12h-136c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h136c6.59961 0 12 -5.40039 12 -12z" />
|
||||
<glyph glyph-name="hdd" unicode="" horiz-adv-x="576"
|
||||
d="M567.403 212.358c5.59668 -8.04688 8.59668 -17.6113 8.59668 -27.4121v-136.946c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v136.946c0 10.167 3.19531 19.6465 8.59668 27.4121l105.08 151.053
|
||||
c8.67383 12.4678 23.0791 20.5889 39.4043 20.5889h269.838c16.3252 0 30.7305 -8.12109 39.4043 -20.5889zM153.081 336l-77.9131 -112h425.664l-77.9131 112h-269.838zM528 48v128h-480v-128h480zM496 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32
|
||||
s14.3271 32 32 32s32 -14.3271 32 -32zM400 112c0 -17.6729 -14.3271 -32 -32 -32s-32 14.3271 -32 32s14.3271 32 32 32s32 -14.3271 32 -32z" />
|
||||
<glyph glyph-name="hand-point-right" unicode=""
|
||||
d="M428.8 310.4c45.0996 0 83.2002 -38.1016 83.2002 -83.2002c0 -45.6162 -37.7646 -83.2002 -83.2002 -83.2002h-35.6475c-1.71387 -7.70605 -4.43555 -15.2051 -7.92969 -22.0645c2.50586 -22.0059 -3.50293 -44.9775 -15.9844 -62.791
|
||||
c-1.14062 -52.4863 -37.3984 -91.1445 -99.9404 -91.1445h-21.2988c-60.0635 0 -98.5117 40 -127.2 40h-2.67871c-5.74707 -4.95215 -13.5361 -8 -22.1201 -8h-64c-17.6729 0 -32 12.8936 -32 28.7998v230.4c0 15.9062 14.3271 28.7998 32 28.7998h64.001
|
||||
c8.58398 0 16.373 -3.04785 22.1201 -8h2.67871c6.96387 0 14.8623 6.19336 30.1816 23.6689l0.128906 0.148438l0.130859 0.145508c8.85645 9.93652 18.1162 20.8398 25.8506 33.2529c18.7051 30.2471 30.3936 78.7842 75.707 78.7842c56.9277 0 92 -35.2861 92 -83.2002
|
||||
c0 -0.0283203 0 0.0361328 0 0.0078125c0 -7.66602 -0.748047 -15.1582 -2.17578 -22.4072h86.1768zM428.8 192c18.9756 0 35.2002 16.2246 35.2002 35.2002c0 18.7002 -16.7754 35.2002 -35.2002 35.2002h-158.399c0 17.3242 26.3994 35.1992 26.3994 70.3994
|
||||
c0 26.4004 -20.625 35.2002 -44 35.2002c-8.79395 0 -20.4443 -32.7119 -34.9258 -56.0996c-9.07422 -14.5752 -19.5244 -27.2256 -30.7988 -39.875c-16.1094 -18.374 -33.8359 -36.6328 -59.0752 -39.5967v-176.753c42.79 -3.7627 74.5088 -39.6758 120 -39.6758h21.2988
|
||||
c40.5244 0 57.124 22.1973 50.6006 61.3252c14.6113 8.00098 24.1514 33.9785 12.9248 53.625c19.3652 18.2246 17.7871 46.3809 4.9502 61.0498h91.0254zM88 64c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
|
||||
<glyph glyph-name="hand-point-left" unicode=""
|
||||
d="M0 227.2c0 45.0986 38.1006 83.2002 83.2002 83.2002h86.1758c-1.3623 6.91016 -2.17578 14.374 -2.17578 22.3994c0 47.9141 35.0723 83.2002 92 83.2002c45.3135 0 57.002 -48.5371 75.7061 -78.7852c7.73438 -12.4121 16.9951 -23.3154 25.8506 -33.2529
|
||||
l0.130859 -0.145508l0.128906 -0.148438c15.3213 -17.4746 23.2197 -23.668 30.1836 -23.668h2.67871c5.74707 4.95215 13.5361 8 22.1201 8h64c17.6729 0 32 -12.8936 32 -28.7998v-230.4c0 -15.9062 -14.3271 -28.7998 -32 -28.7998h-64
|
||||
c-8.58398 0 -16.373 3.04785 -22.1201 8h-2.67871c-28.6885 0 -67.1367 -40 -127.2 -40h-21.2988c-62.542 0 -98.8008 38.6582 -99.9404 91.1445c-12.4814 17.8135 -18.4922 40.7852 -15.9844 62.791c-3.49414 6.85938 -6.21582 14.3584 -7.92969 22.0645h-35.6465
|
||||
c-45.4355 0 -83.2002 37.584 -83.2002 83.2002zM48 227.2c0 -18.9756 16.2246 -35.2002 35.2002 -35.2002h91.0244c-12.8369 -14.6689 -14.415 -42.8252 4.9502 -61.0498c-11.2256 -19.6465 -1.68652 -45.624 12.9248 -53.625
|
||||
c-6.52246 -39.1279 10.0771 -61.3252 50.6016 -61.3252h21.2988c45.4912 0 77.21 35.9131 120 39.6768v176.752c-25.2393 2.96289 -42.9658 21.2227 -59.0752 39.5967c-11.2744 12.6494 -21.7246 25.2998 -30.7988 39.875
|
||||
c-14.4814 23.3877 -26.1318 56.0996 -34.9258 56.0996c-23.375 0 -44 -8.7998 -44 -35.2002c0 -35.2002 26.3994 -53.0752 26.3994 -70.3994h-158.399c-18.4248 0 -35.2002 -16.5 -35.2002 -35.2002zM448 88c-13.2549 0 -24 -10.7451 -24 -24s10.7451 -24 24 -24
|
||||
s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-up" unicode="" horiz-adv-x="448"
|
||||
d="M105.6 364.8c0 45.0996 38.1016 83.2002 83.2002 83.2002c45.6162 0 83.2002 -37.7646 83.2002 -83.2002v-35.6465c7.70605 -1.71387 15.2051 -4.43555 22.0645 -7.92969c22.0059 2.50684 44.9775 -3.50293 62.791 -15.9844
|
||||
c52.4863 -1.14062 91.1445 -37.3984 91.1445 -99.9404v-21.2988c0 -60.0635 -40 -98.5117 -40 -127.2v-2.67871c4.95215 -5.74707 8 -13.5361 8 -22.1201v-64c0 -17.6729 -12.8936 -32 -28.7998 -32h-230.4c-15.9062 0 -28.7998 14.3271 -28.7998 32v64
|
||||
c0 8.58398 3.04785 16.373 8 22.1201v2.67871c0 6.96387 -6.19336 14.8623 -23.6689 30.1816l-0.148438 0.128906l-0.145508 0.130859c-9.93652 8.85645 -20.8398 18.1162 -33.2529 25.8506c-30.2471 18.7051 -78.7842 30.3936 -78.7842 75.707
|
||||
c0 56.9277 35.2861 92 83.2002 92c0.0283203 0 -0.0361328 0 -0.0078125 0c7.66602 0 15.1582 -0.748047 22.4072 -2.17578v86.1768zM224 364.8c0 18.9756 -16.2246 35.2002 -35.2002 35.2002c-18.7002 0 -35.2002 -16.7754 -35.2002 -35.2002v-158.399
|
||||
c-17.3242 0 -35.1992 26.3994 -70.3994 26.3994c-26.4004 0 -35.2002 -20.625 -35.2002 -44c0 -8.79395 32.7119 -20.4443 56.0996 -34.9258c14.5752 -9.07422 27.2256 -19.5244 39.875 -30.7988c18.374 -16.1094 36.6328 -33.8359 39.5967 -59.0752h176.753
|
||||
c3.7627 42.79 39.6758 74.5088 39.6758 120v21.2988c0 40.5244 -22.1973 57.124 -61.3252 50.6006c-8.00098 14.6113 -33.9785 24.1514 -53.625 12.9248c-18.2246 19.3652 -46.3809 17.7871 -61.0498 4.9502v91.0254zM352 24c-13.2549 0 -24 -10.7451 -24 -24
|
||||
s10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24z" />
|
||||
<glyph glyph-name="hand-point-down" unicode="" horiz-adv-x="448"
|
||||
d="M188.8 -64c-45.0986 0 -83.2002 38.1006 -83.2002 83.2002v86.1758c-6.91016 -1.3623 -14.374 -2.17578 -22.3994 -2.17578c-47.9141 0 -83.2002 35.0723 -83.2002 92c0 45.3135 48.5371 57.002 78.7852 75.707c12.4121 7.73438 23.3154 16.9951 33.2529 25.8506
|
||||
l0.145508 0.130859l0.148438 0.128906c17.4746 15.3213 23.668 23.2197 23.668 30.1836v2.67871c-4.95215 5.74707 -8 13.5361 -8 22.1201v64c0 17.6729 12.8936 32 28.7998 32h230.4c15.9062 0 28.7998 -14.3271 28.7998 -32v-64.001
|
||||
c0 -8.58398 -3.04785 -16.373 -8 -22.1201v-2.67871c0 -28.6885 40 -67.1367 40 -127.2v-21.2988c0 -62.542 -38.6582 -98.8008 -91.1445 -99.9404c-17.8135 -12.4814 -40.7852 -18.4922 -62.791 -15.9844c-6.85938 -3.49414 -14.3584 -6.21582 -22.0645 -7.92969v-35.6465
|
||||
c0 -45.4355 -37.584 -83.2002 -83.2002 -83.2002zM188.8 -16c18.9756 0 35.2002 16.2246 35.2002 35.2002v91.0244c14.6689 -12.8369 42.8252 -14.415 61.0498 4.9502c19.6465 -11.2256 45.624 -1.68652 53.625 12.9248c39.1279 -6.52246 61.3252 10.0771 61.3252 50.6016
|
||||
v21.2988c0 45.4912 -35.9131 77.21 -39.6768 120h-176.752c-2.96289 -25.2393 -21.2227 -42.9658 -39.5967 -59.0752c-12.6494 -11.2744 -25.2998 -21.7246 -39.875 -30.7988c-23.3877 -14.4814 -56.0996 -26.1318 -56.0996 -34.9258c0 -23.375 8.7998 -44 35.2002 -44
|
||||
c35.2002 0 53.0752 26.3994 70.3994 26.3994v-158.399c0 -18.4248 16.5 -35.2002 35.2002 -35.2002zM328 384c0 -13.2549 10.7451 -24 24 -24s24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24z" />
|
||||
<glyph glyph-name="copy" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 382.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-80v-48c0 -26.5098 -21.4902 -48 -48 -48h-224c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h80v48c0 26.5098 21.4902 48 48 48
|
||||
h172.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM266 -16c3.31152 0 6 2.68848 6 6v42h-96c-26.5098 0 -48 21.4902 -48 48v224h-74c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM394 80c3.31152 0 6 2.68848 6 6v202h-88
|
||||
c-13.2549 0 -24 10.7451 -24 24v88h-106c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h212zM400 336v9.63184c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-48.3682 48.3682c-1.12598 1.125 -2.65234 1.75684 -4.24316 1.75684h-9.63184v-64h64z" />
|
||||
<glyph glyph-name="save" unicode="" horiz-adv-x="448"
|
||||
d="M433.941 318.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-268.118c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h268.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM272 368h-128v-80h128v80z
|
||||
M394 16c3.31152 0 6 2.68848 6 6v259.632c0 1.65527 -0.670898 3.15723 -1.75684 4.24316l-78.2432 78.2432v-100.118c0 -13.2549 -10.7451 -24 -24 -24h-176c-13.2549 0 -24 10.7451 -24 24v104h-42c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340z
|
||||
M224 216c48.5234 0 88 -39.4766 88 -88s-39.4766 -88 -88 -88s-88 39.4766 -88 88s39.4766 88 88 88zM224 88c22.0557 0 40 17.9443 40 40s-17.9443 40 -40 40s-40 -17.9443 -40 -40s17.9443 -40 40 -40z" />
|
||||
<glyph glyph-name="square" unicode="" horiz-adv-x="448"
|
||||
d="M400 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352zM394 16c3.2998 0 6 2.7002 6 6v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340z" />
|
||||
<glyph glyph-name="envelope" unicode=""
|
||||
d="M464 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h416zM464 336h-416v-40.8047c22.4248 -18.2627 58.1797 -46.6602 134.587 -106.49
|
||||
c16.834 -13.2422 50.2051 -45.0762 73.4131 -44.7012c23.2119 -0.371094 56.5723 31.4541 73.4131 44.7012c76.4189 59.8389 112.165 88.2305 134.587 106.49v40.8047zM48 48h416v185.601c-22.915 -18.252 -55.4189 -43.8691 -104.947 -82.6523
|
||||
c-22.5439 -17.748 -60.3359 -55.1787 -103.053 -54.9473c-42.9277 -0.231445 -81.2051 37.75 -103.062 54.9551c-49.5293 38.7842 -82.0244 64.3945 -104.938 82.6455v-185.602z" />
|
||||
<glyph glyph-name="lightbulb" unicode="" horiz-adv-x="352"
|
||||
d="M176 368c8.83984 0 16 -7.16016 16 -16s-7.16016 -16 -16 -16c-35.2803 0 -64 -28.7002 -64 -64c0 -8.83984 -7.16016 -16 -16 -16s-16 7.16016 -16 16c0 52.9404 43.0596 96 96 96zM96.0596 -11.1699l-0.0400391 43.1797h159.961l-0.0507812 -43.1797
|
||||
c-0.00976562 -3.13965 -0.939453 -6.21973 -2.67969 -8.83984l-24.5098 -36.8398c-2.95996 -4.45996 -7.95996 -7.14062 -13.3203 -7.14062h-78.8496c-5.35059 0 -10.3506 2.68066 -13.3203 7.14062l-24.5098 36.8398c-1.75 2.62012 -2.68066 5.68945 -2.68066 8.83984z
|
||||
M176 448c97.2002 0 176 -78.7998 176 -176c0 -44.3701 -16.4502 -84.8496 -43.5498 -115.79c-16.6406 -18.9795 -42.7402 -58.79 -52.4199 -92.1602v-0.0498047h-48v0.0996094c0.00488281 4.98145 0.790039 9.78809 2.21973 14.3008
|
||||
c5.67969 17.9893 22.9902 64.8496 62.0996 109.46c20.4102 23.29 31.6504 53.1699 31.6504 84.1396c0 70.5801 -57.4199 128 -128 128c-68.2803 0 -128.15 -54.3604 -127.95 -128c0.0898438 -30.9902 11.0703 -60.71 31.6104 -84.1396
|
||||
c39.3496 -44.9004 56.5801 -91.8604 62.1699 -109.67c1.42969 -4.56055 2.13965 -9.30078 2.15039 -14.0703v-0.120117h-48v0.0595703c-9.68066 33.3604 -35.7803 73.1709 -52.4209 92.1602c-27.1094 30.9307 -43.5596 71.4102 -43.5596 115.78
|
||||
c0 93.0303 73.7197 176 176 176z" />
|
||||
<glyph glyph-name="bell" unicode="" horiz-adv-x="448"
|
||||
d="M439.39 85.71c6 -6.44043 8.66016 -14.1602 8.61035 -21.71c-0.0996094 -16.4004 -12.9805 -32 -32.0996 -32h-383.801c-19.1191 0 -31.9893 15.5996 -32.0996 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c19.3193 20.7598 55.4697 51.9902 55.4697 154.29
|
||||
c0 77.7002 54.4795 139.9 127.939 155.16v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -102.3 36.1504 -133.53 55.4697 -154.29zM67.5303 80h312.939
|
||||
c-21.2197 27.96 -44.4199 74.3203 -44.5293 159.42c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112s-112 -50.1396 -112 -112c0 -0.200195 0.0595703 -0.379883 0.0595703 -0.580078
|
||||
c-0.109375 -85.0898 -23.3096 -131.45 -44.5293 -159.42zM224 -64c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
|
||||
<glyph glyph-name="hospital" unicode="" horiz-adv-x="448"
|
||||
d="M128 204v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12zM268 192c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-40zM192 108c0 -6.62695 -5.37305 -12 -12 -12h-40c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-40zM268 96c-6.62695 0 -12 5.37305 -12 12v40c0 6.62695 5.37305 12 12 12h40
|
||||
c6.62695 0 12 -5.37305 12 -12v-40c0 -6.62695 -5.37305 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.62695 5.37305 12 12 12h19.5v378.965c0 11.6172 10.7451 21.0352 24 21.0352h88.5v40c0 13.2549 10.7451 24 24 24h112c13.2549 0 24 -10.7451 24 -24v-40h88.5
|
||||
c13.2549 0 24 -9.41797 24 -21.0352v-378.965h19.5c6.62695 0 12 -5.37305 12 -12zM79.5 -15h112.5v67c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-67h112.5v351h-64.5v-24c0 -13.2549 -10.7451 -24 -24 -24h-112c-13.2549 0 -24 10.7451 -24 24v24
|
||||
h-64.5v-351zM266 384h-26v26c0 3.31152 -2.68848 6 -6 6h-20c-3.31152 0 -6 -2.68848 -6 -6v-26h-26c-3.31152 0 -6 -2.68848 -6 -6v-20c0 -3.31152 2.68848 -6 6 -6h26v-26c0 -3.31152 2.68848 -6 6 -6h20c3.31152 0 6 2.68848 6 6v26h26c3.31152 0 6 2.68848 6 6v20
|
||||
c0 3.31152 -2.68848 6 -6 6z" />
|
||||
<glyph glyph-name="plus-square" unicode="" horiz-adv-x="448"
|
||||
d="M352 208v-32c0 -6.59961 -5.40039 -12 -12 -12h-88v-88c0 -6.59961 -5.40039 -12 -12 -12h-32c-6.59961 0 -12 5.40039 -12 12v88h-88c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h88v88c0 6.59961 5.40039 12 12 12h32c6.59961 0 12 -5.40039 12 -12
|
||||
v-88h88c6.59961 0 12 -5.40039 12 -12zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340
|
||||
c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="circle" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200z" />
|
||||
<glyph glyph-name="smile" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM332 135.4c8.5 10.1992 23.7002 11.5 33.7998 3.09961c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998
|
||||
c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.0996 8.40039 25.2998 7.09961 33.7998 -3.09961c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004z" />
|
||||
<glyph glyph-name="frown" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 144c40.2002 0 78 -17.7002 103.8 -48.5996c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008
|
||||
c-10.7002 -8.7998 -25.7002 -6.59961 -33.7998 3.10059c-16.6006 20 -41 31.3994 -66.9004 31.3994s-50.2998 -11.5 -66.9004 -31.3994c-8.5 -10.2002 -23.5996 -11.5 -33.7998 -3.10059c-10.2002 8.5 -11.5996 23.6006 -3.09961 33.8008
|
||||
c25.7998 30.8994 63.5996 48.5996 103.8 48.5996z" />
|
||||
<glyph glyph-name="meh" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM336 128c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-176c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h176z
|
||||
" />
|
||||
<glyph glyph-name="keyboard" unicode="" horiz-adv-x="576"
|
||||
d="M528 384c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48h-480c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h480zM536 48v288c0 4.41113 -3.58887 8 -8 8h-480c-4.41113 0 -8 -3.58887 -8 -8v-288c0 -4.41113 3.58887 -8 8 -8
|
||||
h480c4.41113 0 8 3.58887 8 8zM170 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM266 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
|
||||
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM362 178c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM458 178c0 -6.62695 -5.37305 -12 -12 -12h-28
|
||||
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 96c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 96
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM122 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28
|
||||
c6.62695 0 12 -5.37305 12 -12v-28zM218 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM314 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28
|
||||
c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM410 260c0 -6.62695 -5.37305 -12 -12 -12h-28c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM506 260c0 -6.62695 -5.37305 -12 -12 -12h-28
|
||||
c-6.62695 0 -12 5.37305 -12 12v28c0 6.62695 5.37305 12 12 12h28c6.62695 0 12 -5.37305 12 -12v-28zM408 102c0 -6.62695 -5.37305 -12 -12 -12h-216c-6.62695 0 -12 5.37305 -12 12v16c0 6.62695 5.37305 12 12 12h216c6.62695 0 12 -5.37305 12 -12v-16z" />
|
||||
<glyph glyph-name="calendar" unicode="" horiz-adv-x="448"
|
||||
d="M400 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12
|
||||
v-52h48zM394 -16c3.2998 0 6 2.7002 6 6v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340z" />
|
||||
<glyph glyph-name="play-circle" unicode=""
|
||||
d="M371.7 210c16.3994 -9.2002 16.3994 -32.9004 0 -42l-176 -101c-15.9004 -8.7998 -35.7002 2.59961 -35.7002 21v208c0 18.5 19.9004 29.7998 35.7002 21zM504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192
|
||||
c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200z" />
|
||||
<glyph glyph-name="minus-square" unicode="" horiz-adv-x="448"
|
||||
d="M108 164c-6.59961 0 -12 5.40039 -12 12v32c0 6.59961 5.40039 12 12 12h232c6.59961 0 12 -5.40039 12 -12v-32c0 -6.59961 -5.40039 -12 -12 -12h-232zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h352
|
||||
c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="check-square" unicode="" horiz-adv-x="448"
|
||||
d="M400 416c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h352zM400 16v352h-352v-352h352zM364.136 257.724l-172.589 -171.204
|
||||
c-4.70508 -4.66699 -12.3027 -4.63672 -16.9697 0.0683594l-90.7812 91.5156c-4.66699 4.70508 -4.63672 12.3037 0.0693359 16.9717l22.7188 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l59.792 -60.2773l141.353 140.217
|
||||
c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0683594l22.5361 -22.7178c4.66699 -4.70605 4.63672 -12.3047 -0.0683594 -16.9717z" />
|
||||
<glyph glyph-name="share-square" unicode="" horiz-adv-x="576"
|
||||
d="M561.938 289.94c18.75 -18.7402 18.75 -49.1406 0 -67.8809l-143.998 -144c-29.9727 -29.9727 -81.9404 -9.05273 -81.9404 33.9404v53.7998c-101.266 -7.83691 -99.625 -31.6406 -84.1104 -78.7598c14.2285 -43.0889 -33.4736 -79.248 -71.0195 -55.7402
|
||||
c-51.6924 32.3057 -84.8701 83.0635 -84.8701 144.76c0 39.3408 12.2197 72.7402 36.3301 99.3008c19.8398 21.8398 47.7402 38.4697 82.9102 49.4199c36.7295 11.4395 78.3096 16.1094 120.76 17.9893v57.1982c0 42.9355 51.9258 63.9541 81.9404 33.9404zM384 112l144 144
|
||||
l-144 144v-104.09c-110.86 -0.90332 -240 -10.5166 -240 -119.851c0 -52.1396 32.79 -85.6094 62.3096 -104.06c-39.8174 120.65 48.999 141.918 177.69 143.84v-103.84zM408.74 27.5068c7.4375 2.125 14.5508 5.30566 20.9736 9.30273
|
||||
c7.97656 4.95215 18.2861 -0.825195 18.2861 -10.2139v-42.5957c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h132c6.62695 0 12 -5.37305 12 -12v-4.48633c0 -4.91699 -2.9873 -9.36914 -7.56934 -11.1514
|
||||
c-13.7021 -5.33105 -26.3955 -11.5371 -38.0498 -18.585c-1.82715 -1.11523 -3.98633 -1.76953 -6.28027 -1.77734h-86.1006c-3.31152 0 -6 -2.68848 -6 -6v-340c0 -3.31152 2.68848 -6 6 -6h340c3.31152 0 6 2.68848 6 6v25.9658c0 5.37012 3.5791 10.0596 8.74023 11.541z
|
||||
" />
|
||||
<glyph glyph-name="compass" unicode="" horiz-adv-x="496"
|
||||
d="M347.94 318.14c16.6592 7.61035 33.8096 -9.54004 26.1992 -26.1992l-65.9697 -144.341c-3.19238 -6.9834 -8.78613 -12.5771 -15.7695 -15.7695l-144.341 -65.9697c-16.6592 -7.61035 -33.8096 9.5498 -26.1992 26.1992l65.9697 144.341
|
||||
c3.19238 6.9834 8.78613 12.5771 15.7695 15.7695zM270.58 169.42c12.4697 12.4697 12.4697 32.6904 0 45.1602s-32.6904 12.4697 -45.1602 0s-12.4697 -32.6904 0 -45.1602s32.6904 -12.4697 45.1602 0zM248 440c136.97 0 248 -111.03 248 -248s-111.03 -248 -248 -248
|
||||
s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
|
||||
<glyph glyph-name="caret-square-down" unicode="" horiz-adv-x="448"
|
||||
d="M125.1 240h197.801c10.6992 0 16.0996 -13 8.5 -20.5l-98.9004 -98.2998c-4.7002 -4.7002 -12.2002 -4.7002 -16.9004 0l-98.8994 98.2998c-7.7002 7.5 -2.2998 20.5 8.39941 20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="caret-square-up" unicode="" horiz-adv-x="448"
|
||||
d="M322.9 144h-197.801c-10.6992 0 -16.0996 13 -8.5 20.5l98.9004 98.2998c4.7002 4.7002 12.2002 4.7002 16.9004 0l98.8994 -98.2998c7.7002 -7.5 2.2998 -20.5 -8.39941 -20.5zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="caret-square-right" unicode="" horiz-adv-x="448"
|
||||
d="M176 93.0996v197.801c0 10.6992 13 16.0996 20.5 8.5l98.2998 -98.9004c4.7002 -4.7002 4.7002 -12.2002 0 -16.9004l-98.2998 -98.8994c-7.5 -7.7002 -20.5 -2.2998 -20.5 8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="file" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416z" />
|
||||
<glyph glyph-name="file-alt" unicode="" horiz-adv-x="384"
|
||||
d="M288 200v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v28c0 6.59961 5.40039 12 12 12h168c6.59961 0 12 -5.40039 12 -12zM276 128c6.59961 0 12 -5.40039 12 -12v-28c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12
|
||||
v28c0 6.59961 5.40039 12 12 12h168zM384 316.1v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996l83.9004 -83.9004c9 -8.90039 14.0996 -21.2002 14.0996 -33.9004z
|
||||
M256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288z" />
|
||||
<glyph glyph-name="thumbs-up" unicode=""
|
||||
d="M466.27 161.31c4.6748 -22.6465 0.864258 -44.5371 -8.98926 -62.9893c2.95898 -23.8682 -4.02148 -48.5654 -17.3398 -66.9902c-0.954102 -55.9072 -35.8232 -95.3301 -112.94 -95.3301c-7 0 -15 0.00976562 -22.2197 0.00976562
|
||||
c-102.742 0 -133.293 38.9395 -177.803 39.9404c-3.56934 -13.7764 -16.085 -23.9502 -30.9775 -23.9502h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h98.7598c19.1455 16.9531 46.0137 60.6533 68.7598 83.4004
|
||||
c13.667 13.667 10.1533 108.6 71.7607 108.6c57.5801 0 95.2695 -31.9355 95.2695 -104.73c0 -18.4092 -3.92969 -33.7295 -8.84961 -46.5391h36.4795c48.6025 0 85.8203 -41.5654 85.8203 -85.5801c0 -19.1504 -4.95996 -34.9902 -13.7305 -49.8408zM404.52 107.48
|
||||
c21.5811 20.3838 18.6992 51.0645 5.21094 65.6191c9.44922 0 22.3594 18.9102 22.2695 37.8105c-0.0898438 18.9102 -16.71 37.8203 -37.8203 37.8203h-103.989c0 37.8193 28.3594 55.3691 28.3594 94.5391c0 23.75 0 56.7305 -47.2695 56.7305
|
||||
c-18.9102 -18.9102 -9.45996 -66.1797 -37.8203 -94.54c-26.5596 -26.5703 -66.1797 -97.46 -94.54 -97.46h-10.9199v-186.17c53.6113 0 100.001 -37.8203 171.64 -37.8203h37.8203c35.5117 0 60.8203 17.1201 53.1201 65.9004
|
||||
c15.2002 8.16016 26.5 36.4395 13.9395 57.5703zM88 16c0 13.2549 -10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24s24 10.7451 24 24z" />
|
||||
<glyph glyph-name="thumbs-down" unicode=""
|
||||
d="M466.27 222.69c8.77051 -14.8506 13.7305 -30.6904 13.7305 -49.8408c0 -44.0146 -37.2178 -85.5801 -85.8203 -85.5801h-36.4795c4.91992 -12.8096 8.84961 -28.1299 8.84961 -46.5391c0 -72.7949 -37.6895 -104.73 -95.2695 -104.73
|
||||
c-61.6074 0 -58.0938 94.9326 -71.7607 108.6c-22.7461 22.7471 -49.6133 66.4473 -68.7598 83.4004h-7.05176c-5.5332 -9.56152 -15.8662 -16 -27.708 -16h-64c-17.6729 0 -32 14.3271 -32 32v240c0 17.6729 14.3271 32 32 32h64c8.11328 0 15.5146 -3.02539 21.1553 -8
|
||||
h10.8447c40.9971 0 73.1953 39.9902 176.78 39.9902c7.21973 0 15.2197 0.00976562 22.2197 0.00976562c77.1172 0 111.986 -39.4229 112.94 -95.3301c13.3184 -18.4248 20.2979 -43.1221 17.3398 -66.9902c9.85352 -18.4521 13.6641 -40.3428 8.98926 -62.9893zM64 152
|
||||
c13.2549 0 24 10.7451 24 24s-10.7451 24 -24 24s-24 -10.7451 -24 -24s10.7451 -24 24 -24zM394.18 135.27c21.1104 0 37.7305 18.9102 37.8203 37.8203c0.0898438 18.9004 -12.8203 37.8105 -22.2695 37.8105c13.4883 14.5547 16.3701 45.2354 -5.21094 65.6191
|
||||
c12.5605 21.1309 1.26074 49.4102 -13.9395 57.5703c7.7002 48.7803 -17.6084 65.9004 -53.1201 65.9004h-37.8203c-71.6387 0 -118.028 -37.8203 -171.64 -37.8203v-186.17h10.9199c28.3604 0 67.9805 -70.8896 94.54 -97.46
|
||||
c28.3604 -28.3604 18.9102 -75.6299 37.8203 -94.54c47.2695 0 47.2695 32.9805 47.2695 56.7305c0 39.1699 -28.3594 56.7197 -28.3594 94.5391h103.989z" />
|
||||
<glyph glyph-name="sun" unicode=""
|
||||
d="M494.2 226.1c11.2002 -7.59961 17.7998 -20.0996 17.8994 -33.6992c0 -13.4004 -6.69922 -26 -17.7998 -33.5l-59.7998 -40.5l13.7002 -71c2.5 -13.2002 -1.60059 -26.8008 -11.1006 -36.3008s-22.8994 -13.7998 -36.2998 -11.0996l-70.8994 13.7002l-40.4004 -59.9004
|
||||
c-7.5 -11.0996 -20.0996 -17.7998 -33.5 -17.7998s-26 6.7002 -33.5 17.9004l-40.4004 59.8994l-70.7998 -13.7002c-13.3994 -2.59961 -26.7998 1.60059 -36.2998 11.1006s-13.7002 23.0996 -11.0996 36.2998l13.6992 71l-59.7998 40.5
|
||||
c-11.0996 7.5 -17.7998 20 -17.7998 33.5s6.59961 26 17.7998 33.5996l59.7998 40.5l-13.6992 71c-2.60059 13.2002 1.59961 26.7002 11.0996 36.3008c9.5 9.59961 23 13.6992 36.2998 11.1992l70.7998 -13.6992l40.4004 59.8994c15.0996 22.2998 51.9004 22.2998 67 0
|
||||
l40.4004 -59.8994l70.8994 13.6992c13 2.60059 26.6006 -1.59961 36.2002 -11.0996c9.5 -9.59961 13.7002 -23.2002 11.0996 -36.4004l-13.6992 -71zM381.3 140.5l76.7998 52.0996l-76.7998 52l17.6006 91.1006l-91 -17.6006l-51.9004 76.9004l-51.7998 -76.7998
|
||||
l-91 17.5996l17.5996 -91.2002l-76.7998 -52l76.7998 -52l-17.5996 -91.1992l90.8994 17.5996l51.9004 -77l51.9004 76.9004l91 -17.6006zM256 296c57.2998 0 104 -46.7002 104 -104s-46.7002 -104 -104 -104s-104 46.7002 -104 104s46.7002 104 104 104zM256 136
|
||||
c30.9004 0 56 25.0996 56 56s-25.0996 56 -56 56s-56 -25.0996 -56 -56s25.0996 -56 56 -56z" />
|
||||
<glyph glyph-name="moon" unicode=""
|
||||
d="M279.135 -64c-141.424 0 -256 114.64 -256 256c0 141.425 114.641 256 256 256c16.0342 -0.00292969 31.5078 -1.46875 46.7354 -4.27734c44.0205 -8.13086 53.7666 -66.8691 15.0215 -88.9189c-41.374 -23.5439 -67.4336 -67.4121 -67.4336 -115.836
|
||||
c0 -83.5234 75.9238 -146.475 158.272 -130.792c43.6904 8.32129 74.5186 -42.5693 46.248 -77.4004c-47.8613 -58.9717 -120.088 -94.7754 -198.844 -94.7754zM279.135 400c-114.875 0 -208 -93.125 -208 -208s93.125 -208 208 -208
|
||||
c65.2314 0 123.439 30.0361 161.575 77.0244c-111.611 -21.2568 -215.252 64.0957 -215.252 177.943c0 67.5127 36.9326 126.392 91.6934 157.555c-12.3271 2.27637 -25.0312 3.47754 -38.0166 3.47754z" />
|
||||
<glyph glyph-name="caret-square-left" unicode="" horiz-adv-x="448"
|
||||
d="M272 290.9v-197.801c0 -10.6992 -13 -16.0996 -20.5 -8.5l-98.2998 98.9004c-4.7002 4.7002 -4.7002 12.2002 0 16.9004l98.2998 98.8994c7.5 7.7002 20.5 2.2998 20.5 -8.39941zM448 368v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352
|
||||
c0 26.5 21.5 48 48 48h352c26.5 0 48 -21.5 48 -48zM400 22v340c0 3.2998 -2.7002 6 -6 6h-340c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="dot-circle" unicode=""
|
||||
d="M256 392c-110.549 0 -200 -89.4678 -200 -200c0 -110.549 89.4678 -200 200 -200c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200zM256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248z
|
||||
M256 272c44.1826 0 80 -35.8174 80 -80s-35.8174 -80 -80 -80s-80 35.8174 -80 80s35.8174 80 80 80z" />
|
||||
<glyph glyph-name="building" unicode="" horiz-adv-x="448"
|
||||
d="M128 300v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12zM268 288c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40
|
||||
c0 -6.59961 -5.40039 -12 -12 -12h-40zM140 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM268 192c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM192 108c0 -6.59961 -5.40039 -12 -12 -12h-40c-6.59961 0 -12 5.40039 -12 12v40c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40zM268 96c-6.59961 0 -12 5.40039 -12 12v40
|
||||
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-40zM448 -28v-36h-448v36c0 6.59961 5.40039 12 12 12h19.5v440c0 13.2998 10.7002 24 24 24h337c13.2998 0 24 -10.7002 24 -24v-440h19.5
|
||||
c6.59961 0 12 -5.40039 12 -12zM79.5 -15h112.5v67c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-67h112.5v414l-288.5 1z" />
|
||||
<glyph glyph-name="file-pdf" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM298.2 127.7c10.5 -10.5 8 -38.7002 -17.5 -38.7002c-14.7998 0 -36.9004 6.7998 -55.7998 17c-21.6006 -3.59961 -46 -12.7002 -68.4004 -20.0996c-50.0996 -86.4004 -79.4004 -47 -76.0996 -31.2002
|
||||
c4 20 31 35.8994 51 46.2002c10.5 18.3994 25.3994 50.5 35.3994 74.3994c-7.39941 28.6006 -11.3994 51 -7 67.1006c4.7998 17.6992 38.4004 20.2998 42.6006 -5.90039c4.69922 -15.4004 -1.5 -39.9004 -5.40039 -56c8.09961 -21.2998 19.5996 -35.7998 36.7998 -46.2998
|
||||
c17.4004 2.2002 52.2002 5.5 64.4004 -6.5zM100.1 49.9004c0 -0.700195 11.4004 4.69922 30.4004 35c-5.90039 -5.5 -25.2998 -21.3008 -30.4004 -35zM181.7 240.5c-2.5 0 -2.60059 -26.9004 1.7998 -40.7998c4.90039 8.7002 5.59961 40.7998 -1.7998 40.7998zM157.3 103.9
|
||||
c15.9004 6.09961 34 14.8994 54.7998 19.1992c-11.1992 8.30078 -21.7998 20.4004 -30.0996 35.5c-6.7002 -17.6992 -15 -37.7998 -24.7002 -54.6992zM288.9 108.9c3.59961 2.39941 -2.2002 10.3994 -37.3008 7.7998c32.3008 -13.7998 37.3008 -7.7998 37.3008 -7.7998z" />
|
||||
<glyph glyph-name="file-word" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM268.1 192v0.200195h15.8008c7.7998 0 13.5 -7.2998 11.5996 -14.9004c-4.2998 -17 -13.7002 -54.0996 -34.5 -136c-1.2998 -5.39941 -6.09961 -9.09961 -11.5996 -9.09961h-24.7002
|
||||
c-5.5 0 -10.2998 3.7998 -11.6006 9.09961c-5.2998 20.9004 -17.7998 71 -17.8994 71.4004l-2.90039 17.2998c-0.5 -5.2998 -1.5 -11.0996 -3 -17.2998l-17.8994 -71.4004c-1.30078 -5.39941 -6.10059 -9.09961 -11.6006 -9.09961h-25.2002
|
||||
c-5.59961 0 -10.3994 3.7002 -11.6992 9.09961c-6.5 26.5 -25.2002 103.4 -33.2002 136c-1.7998 7.5 3.89941 14.7998 11.7002 14.7998h16.7998c5.7998 0 10.7002 -4.09961 11.7998 -9.69922c5 -25.7002 18.4004 -93.8008 19.0996 -99
|
||||
c0.300781 -1.7002 0.400391 -3.10059 0.5 -4.2002c0.800781 7.5 0.400391 4.7002 24.8008 103.7c1.39941 5.2998 6.19922 9.09961 11.6992 9.09961h13.3008c5.59961 0 10.3994 -3.7998 11.6992 -9.2002c23.9004 -99.7002 22.8008 -94.3994 23.6006 -99.5
|
||||
c0.299805 -1.7002 0.5 -3.09961 0.700195 -4.2998c0.599609 8.09961 0.399414 5.7998 21 103.5c1.09961 5.5 6 9.5 11.6992 9.5z" />
|
||||
<glyph glyph-name="file-excel" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM260 224c9.2002 0 15 -10 10.2998 -18c-16 -27.5 -45.5996 -76.9004 -46.2998 -78l46.4004 -78c4.59961 -8 -1.10059 -18 -10.4004 -18h-28.7998c-4.40039 0 -8.5 2.40039 -10.6006 6.2998
|
||||
c-22.6992 41.7998 -13.6992 27.5 -28.5996 57.7002c-5.59961 -12.7002 -6.90039 -17.7002 -28.5996 -57.7002c-2.10059 -3.89941 -6.10059 -6.2998 -10.5 -6.2998h-28.9004c-9.2998 0 -15.0996 10 -10.4004 18l46.3008 78l-46.3008 78c-4.59961 8 1.10059 18 10.4004 18
|
||||
h28.9004c4.39941 0 8.5 -2.40039 10.5996 -6.2998c21.7002 -40.4004 14.7002 -28.6006 28.5996 -57.7002c6.40039 15.2998 10.6006 24.5996 28.6006 57.7002c2.09961 3.89941 6.09961 6.2998 10.5 6.2998h28.7998z" />
|
||||
<glyph glyph-name="file-powerpoint" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM120 44v168c0 6.59961 5.40039 12 12 12h69.2002c36.7002 0 62.7998 -27 62.7998 -66.2998c0 -74.2998 -68.7002 -66.5 -95.5 -66.5v-47.2002c0 -6.59961 -5.40039 -12 -12 -12h-24.5c-6.59961 0 -12 5.40039 -12 12z
|
||||
M168.5 131.4h23c7.90039 0 13.9004 2.39941 18.0996 7.19922c8.5 9.80078 8.40039 28.5 0.100586 37.8008c-4.10059 4.59961 -9.90039 7 -17.4004 7h-23.8994v-52h0.0996094z" />
|
||||
<glyph glyph-name="file-image" unicode="" horiz-adv-x="384"
|
||||
d="M369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM332.1 320l-76.0996 76.0996v-76.0996h76.0996zM48 -16h288v288
|
||||
h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416zM80 32v64l39.5 39.5c4.7002 4.7002 12.2998 4.7002 17 0l39.5 -39.5l87.5 87.5c4.7002 4.7002 12.2998 4.7002 17 0l23.5 -23.5v-128h-224zM128 272c26.5 0 48 -21.5 48 -48s-21.5 -48 -48 -48s-48 21.5 -48 48
|
||||
s21.5 48 48 48z" />
|
||||
<glyph glyph-name="file-archive" unicode="" horiz-adv-x="384"
|
||||
d="M128.3 288h32v-32h-32v32zM192.3 384v-32h-32v32h32zM128.3 352h32v-32h-32v32zM192.3 320v-32h-32v32h32zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1
|
||||
c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-48.2998v-16h-32v16h-79.7002v-416h288zM194.2 182.3l17.2998 -87.7002c6.40039 -32.3994 -18.4004 -62.5996 -51.5 -62.5996
|
||||
c-33.2002 0 -58 30.4004 -51.4004 62.9004l19.7002 97.0996v32h32v-32h22.1006c5.7998 0 10.6992 -4.09961 11.7998 -9.7002zM160.3 57.9004c17.9004 0 32.4004 12.0996 32.4004 27c0 14.8994 -14.5 27 -32.4004 27c-17.8994 0 -32.3994 -12.1006 -32.3994 -27
|
||||
c0 -14.9004 14.5 -27 32.3994 -27zM192.3 256v-32h-32v32h32z" />
|
||||
<glyph glyph-name="file-audio" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM192 60.0244c0 -10.6914 -12.9258 -16.0459 -20.4854 -8.48535l-35.5146 35.9746h-28c-6.62695 0 -12 5.37305 -12 12v56c0 6.62695 5.37305 12 12 12h28
|
||||
l35.5146 36.9473c7.56055 7.56055 20.4854 2.20605 20.4854 -8.48535v-135.951zM233.201 107.154c9.05078 9.29688 9.05957 24.1328 0.000976562 33.4385c-22.1494 22.752 12.2344 56.2461 34.3945 33.4814c27.1982 -27.9404 27.2119 -72.4443 0.000976562 -100.401
|
||||
c-21.793 -22.3857 -56.9463 10.3154 -34.3965 33.4814z" />
|
||||
<glyph glyph-name="file-video" unicode="" horiz-adv-x="384"
|
||||
d="M369.941 350.059c8.68848 -8.68848 14.0586 -20.6943 14.0586 -33.9404v-332.118c0 -26.5098 -21.4902 -48 -48 -48h-288c-26.5098 0 -48 21.4902 -48 48v416c0 26.5098 21.4902 48 48 48h204.118c13.2461 0 25.252 -5.37012 33.9404 -14.0586zM332.118 320
|
||||
l-76.1182 76.1182v-76.1182h76.1182zM48 -16h288v288h-104c-13.2549 0 -24 10.7451 -24 24v104h-160v-416zM276.687 195.303c10.0049 10.0049 27.3135 2.99707 27.3135 -11.3135v-111.976c0 -14.2939 -17.2959 -21.332 -27.3135 -11.3135l-52.6865 52.6738v-37.374
|
||||
c0 -11.0459 -8.9541 -20 -20 -20h-104c-11.0459 0 -20 8.9541 -20 20v104c0 11.0459 8.9541 20 20 20h104c11.0459 0 20 -8.9541 20 -20v-37.374z" />
|
||||
<glyph glyph-name="file-code" unicode="" horiz-adv-x="384"
|
||||
d="M149.9 98.9004c3.5 -3.30078 3.69922 -8.90039 0.399414 -12.4004l-17.3994 -18.5996c-1.60059 -1.80078 -4 -2.80078 -6.40039 -2.80078c-2.2002 0 -4.40039 0.900391 -6 2.40039l-57.7002 54.0996c-3.7002 3.40039 -3.7002 9.30078 0 12.8008l57.7002 54.0996
|
||||
c3.40039 3.2998 9 3.2002 12.4004 -0.400391l17.3994 -18.5996l0.200195 -0.200195c3.2002 -3.59961 2.7998 -9.2002 -0.799805 -12.3994l-32.7998 -28.9004l32.7998 -28.9004zM369.9 350.1c9 -9 14.0996 -21.2998 14.0996 -34v-332.1c0 -26.5 -21.5 -48 -48 -48h-288
|
||||
c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48.0996h204.1c12.7002 0 24.9004 -5.09961 33.9004 -14.0996zM256 396.1v-76.0996h76.0996zM336 -16v288h-104c-13.2998 0 -24 10.7002 -24 24v104h-160v-416h288zM209.6 234l24.4004 -7
|
||||
c4.7002 -1.2998 7.40039 -6.2002 6 -10.9004l-54.7002 -188.199c-1.2998 -4.60059 -6.2002 -7.40039 -10.8994 -6l-24.4004 7.09961c-4.7002 1.2998 -7.40039 6.2002 -6 10.9004l54.7002 188.1c1.39941 4.7002 6.2002 7.40039 10.8994 6zM234.1 157.1
|
||||
c-3.5 3.30078 -3.69922 8.90039 -0.399414 12.4004l17.3994 18.5996c3.30078 3.60059 8.90039 3.7002 12.4004 0.400391l57.7002 -54.0996c3.7002 -3.40039 3.7002 -9.30078 0 -12.8008l-57.7002 -54.0996c-3.5 -3.2998 -9.09961 -3.09961 -12.4004 0.400391
|
||||
l-17.3994 18.5996l-0.200195 0.200195c-3.2002 3.59961 -2.7998 9.2002 0.799805 12.3994l32.7998 28.9004l-32.7998 28.9004z" />
|
||||
<glyph glyph-name="life-ring" unicode=""
|
||||
d="M256 -56c-136.967 0 -248 111.033 -248 248s111.033 248 248 248s248 -111.033 248 -248s-111.033 -248 -248 -248zM152.602 20.7197c63.2178 -38.3184 143.579 -38.3184 206.797 0l-53.4111 53.4111c-31.8467 -13.5215 -68.168 -13.5059 -99.9746 0zM336 192
|
||||
c0 44.1123 -35.8877 80 -80 80s-80 -35.8877 -80 -80s35.8877 -80 80 -80s80 35.8877 80 80zM427.28 88.6016c38.3184 63.2178 38.3184 143.579 0 206.797l-53.4111 -53.4111c13.5215 -31.8467 13.5049 -68.168 0 -99.9746zM359.397 363.28
|
||||
c-63.2168 38.3184 -143.578 38.3184 -206.796 0l53.4111 -53.4111c31.8457 13.5215 68.167 13.5049 99.9736 0zM84.7197 295.398c-38.3184 -63.2178 -38.3184 -143.579 0 -206.797l53.4111 53.4111c-13.5215 31.8467 -13.5059 68.168 0 99.9746z" />
|
||||
<glyph glyph-name="paper-plane" unicode=""
|
||||
d="M440 441.5c34.5996 19.9004 77.5996 -8.7998 71.5 -48.9004l-59.4004 -387.199c-2.2998 -14.5 -11.0996 -27.3008 -23.8994 -34.5c-7.2998 -4.10059 -15.4004 -6.2002 -23.6006 -6.2002c-6.19922 0 -12.3994 1.2002 -18.2998 3.59961l-111.899 46.2002l-43.8008 -59.0996
|
||||
c-27.3994 -36.9004 -86.5996 -17.8008 -86.5996 28.5996v84.4004l-114.3 47.2998c-36.7998 15.0996 -40.1006 66 -5.7002 85.8994zM192 -16l36.5996 49.5l-36.5996 15.0996v-64.5996zM404.6 12.7002l59.4004 387.3l-416 -240l107.8 -44.5996l211.5 184.3
|
||||
c14.2002 12.2998 34.4004 -5.7002 23.7002 -21.2002l-140.2 -202.3z" />
|
||||
<glyph glyph-name="futbol" unicode="" horiz-adv-x="496"
|
||||
d="M483.8 268.6c42.2998 -130.199 -29 -270.1 -159.2 -312.399c-25.5 -8.2998 -51.2998 -12.2002 -76.6992 -12.2002c-104.5 0 -201.7 66.5996 -235.7 171.4c-42.2998 130.199 29 270.1 159.2 312.399c25.5 8.2998 51.2998 12.2002 76.6992 12.2002
|
||||
c104.5 0 201.7 -66.5996 235.7 -171.4zM409.3 74.9004c6.10059 8.39941 12.1006 16.8994 16.7998 26.1992c14.3008 28.1006 21.5 58.5 21.7002 89.2002l-38.8994 36.4004l-71.1006 -22.1006l-24.3994 -75.1992l43.6992 -60.9004zM409.3 310.3
|
||||
c-24.5 33.4004 -58.7002 58.4004 -97.8994 71.4004l-47.4004 -26.2002v-73.7998l64.2002 -46.5l70.7002 22zM184.9 381.6c-39.9004 -13.2998 -73.5 -38.5 -97.8008 -71.8994l10.1006 -52.5l70.5996 -22l64.2002 46.5v73.7998zM139 68.5l43.5 61.7002l-24.2998 74.2998
|
||||
l-71.1006 22.2002l-39 -36.4004c0.5 -55.7002 23.4004 -95.2002 37.8008 -115.3zM187.2 1.5c64.0996 -20.4004 115.5 -1.7998 121.7 0l22.3994 48.0996l-44.2998 61.7002h-78.5996l-43.6006 -61.7002z" />
|
||||
<glyph glyph-name="newspaper" unicode="" horiz-adv-x="576"
|
||||
d="M552 384c13.2549 0 24 -10.7451 24 -24v-336c0 -13.2549 -10.7451 -24 -24 -24h-496c-30.9277 0 -56 25.0723 -56 56v272c0 13.2549 10.7451 24 24 24h42.752c6.60547 18.623 24.3896 32 45.248 32h440zM48 56c0 -4.41113 3.58887 -8 8 -8s8 3.58887 8 8v248h-16v-248z
|
||||
M528 48v288h-416v-280c0 -2.7168 -0.204102 -5.38574 -0.578125 -8h416.578zM172 168c-6.62695 0 -12 5.37305 -12 12v96c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-96c0 -6.62695 -5.37305 -12 -12 -12h-136zM200 248v-40h80v40h-80zM160 108v24
|
||||
c0 6.62695 5.37305 12 12 12h136c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-136c-6.62695 0 -12 5.37305 -12 12zM352 108v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104
|
||||
c-6.62695 0 -12 5.37305 -12 12zM352 252v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12zM352 180v24c0 6.62695 5.37305 12 12 12h104c6.62695 0 12 -5.37305 12 -12v-24
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-104c-6.62695 0 -12 5.37305 -12 12z" />
|
||||
<glyph glyph-name="bell-slash" unicode="" horiz-adv-x="640"
|
||||
d="M633.99 -23.0195c6.91016 -5.52051 8.01953 -15.5908 2.5 -22.4902l-10 -12.4902c-5.53027 -6.88965 -15.5898 -8.00977 -22.4902 -2.49023l-598 467.51c-6.90039 5.52051 -8.01953 15.5908 -2.49023 22.4902l10 12.4902
|
||||
c5.52051 6.90039 15.5898 8.00977 22.4902 2.49023zM163.53 80h182.84l61.3994 -48h-279.659c-19.1201 0 -31.9902 15.5996 -32.1006 32c-0.0498047 7.5498 2.61035 15.2598 8.61035 21.71c18.3701 19.7402 51.5703 49.6904 54.8398 140.42l45.4697 -35.5498
|
||||
c-6.91992 -54.7803 -24.6895 -88.5498 -41.3994 -110.58zM320 352c-23.3496 0 -45 -7.17969 -62.9404 -19.4004l-38.1699 29.8408c19.6807 15.7793 43.1104 27.3096 69.1299 32.7197v20.8398c0 17.6699 14.3203 32 31.9805 32s31.9805 -14.3301 31.9805 -32v-20.8398
|
||||
c73.46 -15.2598 127.939 -77.46 127.939 -155.16c0 -41.3604 6.03027 -70.7197 14.3398 -92.8496l-59.5293 46.54c-1.63086 13.96 -2.77051 28.8896 -2.79004 45.7295c0 0.200195 0.0595703 0.379883 0.0595703 0.580078c0 61.8604 -50.1396 112 -112 112zM320 -64
|
||||
c-35.3203 0 -63.9697 28.6504 -63.9697 64h127.939c0 -35.3496 -28.6494 -64 -63.9697 -64z" />
|
||||
<glyph glyph-name="copyright" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M363.351 93.0645c-9.61328 -9.71289 -45.5293 -41.3965 -104.064 -41.3965c-82.4297 0 -140.484 61.4248 -140.484 141.567c0 79.1514 60.2754 139.4 139.763 139.4c55.5303 0 88.7373 -26.6201 97.5928 -34.7783c2.37793 -2.1875 3.86914 -5.3252 3.86914 -8.80762
|
||||
c0 -2.39746 -0.717773 -4.64258 -1.93359 -6.51465l-18.1543 -28.1133c-3.8418 -5.9502 -11.9668 -7.28223 -17.499 -2.9209c-8.5957 6.77637 -31.8145 22.5381 -61.708 22.5381c-48.3037 0 -77.916 -35.3301 -77.916 -80.082c0 -41.5889 26.8877 -83.6924 78.2764 -83.6924
|
||||
c32.6572 0 56.8428 19.0391 65.7266 27.2256c5.26953 4.85645 13.5957 4.03906 17.8193 -1.73828l19.8652 -27.1699c1.45996 -1.98145 2.32422 -4.42969 2.32422 -7.07715c0 -3.28809 -1.32422 -6.2793 -3.47656 -8.44043z" />
|
||||
<glyph glyph-name="closed-captioning" unicode=""
|
||||
d="M464 384c26.5 0 48 -21.5 48 -48v-288c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v288c0 26.5 21.5 48 48 48h416zM458 48c3.2998 0 6 2.7002 6 6v276c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-276c0 -3.2998 2.7002 -6 6 -6h404z
|
||||
M246.9 133.7c1.69922 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.6006 -56.7998 -172.801 -32.0996 -172.801 67.9004c0 97.2998 121.7 119.5 172.5 70.0996c2.10059 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.89941 -3.09961 -6.19922 -4 -9.09961 -1.7002
|
||||
c-40.7998 32 -94.5996 14.9004 -94.5996 -31.1992c0 -48 51 -70.5 92.1992 -32.6006c2.80078 2.5 7.10059 2.10059 9.2002 -0.899414zM437.3 133.7c1.7002 -2.40039 1.5 -5.60059 -0.5 -7.7002c-53.5996 -56.9004 -172.8 -32.0996 -172.8 67.9004
|
||||
c0 97.2998 121.7 119.5 172.5 70.0996c2.09961 -2 2.5 -3.2002 1 -5.7002l-17.5 -30.5c-1.90039 -3.09961 -6.2002 -4 -9.09961 -1.7002c-40.8008 32 -94.6006 14.9004 -94.6006 -31.1992c0 -48 51 -70.5 92.2002 -32.6006c2.7998 2.5 7.09961 2.10059 9.2002 -0.899414z
|
||||
" />
|
||||
<glyph glyph-name="object-group" unicode=""
|
||||
d="M500 320h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v256h-12
|
||||
c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM448 384v-32h32v32h-32zM32 384v-32h32v32h-32zM64 0v32
|
||||
h-32v-32h32zM480 0v32h-32v-32h32zM440 64v256h-12c-6.62695 0 -12 5.37305 -12 12v12h-320v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-256h12c6.62695 0 12 -5.37305 12 -12v-12h320v12c0 6.62695 5.37305 12 12 12h12zM404 256c6.62695 0 12 -5.37207 12 -12v-168
|
||||
c0 -6.62793 -5.37305 -12 -12 -12h-200c-6.62695 0 -12 5.37207 -12 12v52h-84c-6.62695 0 -12 5.37207 -12 12v168c0 6.62793 5.37305 12 12 12h200c6.62695 0 12 -5.37207 12 -12v-52h84zM136 280v-112h144v112h-144zM376 104v112h-56v-76
|
||||
c0 -6.62793 -5.37305 -12 -12 -12h-76v-24h144z" />
|
||||
<glyph glyph-name="object-ungroup" unicode="" horiz-adv-x="576"
|
||||
d="M564 224h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v24h-88v-12
|
||||
c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v72c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h72
|
||||
c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-12v-24h88v12c0 6.62695 5.37305 12 12 12h72c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12zM352 384v-32h32v32h-32zM352 128v-32h32v32h-32zM64 96v32h-32v-32h32zM64 352v32
|
||||
h-32v-32h32zM96 136h224v12c0 6.62695 5.37305 12 12 12h12v160h-12c-6.62695 0 -12 5.37305 -12 12v12h-224v-12c0 -6.62695 -5.37305 -12 -12 -12h-12v-160h12c6.62695 0 12 -5.37305 12 -12v-12zM224 0v32h-32v-32h32zM504 64v160h-12c-6.62695 0 -12 5.37305 -12 12v12
|
||||
h-88v-88h12c6.62695 0 12 -5.37305 12 -12v-72c0 -6.62695 -5.37305 -12 -12 -12h-72c-6.62695 0 -12 5.37305 -12 12v12h-88v-24h12c6.62695 0 12 -5.37305 12 -12v-12h224v12c0 6.62695 5.37305 12 12 12h12zM544 0v32h-32v-32h32zM544 256v32h-32v-32h32z" />
|
||||
<glyph glyph-name="sticky-note" unicode="" horiz-adv-x="448"
|
||||
d="M448 99.8936c0 -13.2451 -5.37012 -25.252 -14.0586 -33.9404l-83.8828 -83.8818c-8.68848 -8.68848 -20.6943 -14.0596 -33.9404 -14.0596h-268.118c-26.5098 0 -48 21.4902 -48 48v351.988c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48v-268.106z
|
||||
M320 19.8936l76.1182 76.1182h-76.1182v-76.1182zM400 368h-352v-351.988h224v104c0 13.2549 10.7451 24 24 24h104v223.988z" />
|
||||
<glyph glyph-name="clone" unicode=""
|
||||
d="M464 448c26.5098 0 48 -21.4902 48 -48v-320c0 -26.5098 -21.4902 -48 -48 -48h-48v-48c0 -26.5098 -21.4902 -48 -48 -48h-320c-26.5098 0 -48 21.4902 -48 48v320c0 26.5098 21.4902 48 48 48h48v48c0 26.5098 21.4902 48 48 48h320zM362 -16c3.31152 0 6 2.68848 6 6
|
||||
v42h-224c-26.5098 0 -48 21.4902 -48 48v224h-42c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308zM458 80c3.31152 0 6 2.68848 6 6v308c0 3.31152 -2.68848 6 -6 6h-308c-3.31152 0 -6 -2.68848 -6 -6v-308c0 -3.31152 2.68848 -6 6 -6h308z" />
|
||||
<glyph glyph-name="hourglass" unicode="" horiz-adv-x="384"
|
||||
d="M368 400c0 -80.0996 -31.8984 -165.619 -97.1797 -208c64.9912 -42.1934 97.1797 -127.436 97.1797 -208h4c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-360c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h4
|
||||
c0 80.0996 31.8994 165.619 97.1797 208c-64.9912 42.1934 -97.1797 127.436 -97.1797 208h-4c-6.62695 0 -12 5.37305 -12 12v24c0 6.62695 5.37305 12 12 12h360c6.62695 0 12 -5.37305 12 -12v-24c0 -6.62695 -5.37305 -12 -12 -12h-4zM64 400
|
||||
c0 -101.621 57.3066 -184 128 -184s128 82.3799 128 184h-256zM320 -16c0 101.62 -57.3076 184 -128 184s-128 -82.3799 -128 -184h256z" />
|
||||
<glyph glyph-name="hand-rock" unicode=""
|
||||
d="M408.864 368.948c48.8213 20.751 103.136 -15.0723 103.136 -67.9111v-114.443c0 -15.3955 -3.08887 -30.3906 -9.18262 -44.5674l-42.835 -99.6562c-4.99707 -11.625 -3.98242 -18.8574 -3.98242 -42.3701c0 -17.6729 -14.3271 -32 -32 -32h-252
|
||||
c-17.6729 0 -32 14.3271 -32 32c0 27.3301 1.1416 29.2012 -3.11035 32.9033l-97.71 85.0811c-24.8994 21.6797 -39.1797 52.8926 -39.1797 85.6338v56.9531c0 47.4277 44.8457 82.0215 91.0459 71.1807c1.96094 55.751 63.5107 87.8262 110.671 60.8057
|
||||
c29.1895 31.0713 78.8604 31.4473 108.334 -0.0214844c32.7051 18.6846 76.4121 10.3096 98.8135 -23.5879zM464 186.594v114.445c0 34.29 -52 33.8232 -52 0.676758c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.457 -52 33.707 -52 0.676758v-27.4287c0 -8.83594 -7.16309 -16 -16 -16h-7c-8.83691 0 -16 7.16406 -16 16v40.4658c0 34.3525 -52 33.8115 -52 0.677734v-41.1436c0 -8.83594 -7.16406 -16 -16 -16h-7c-8.83594 0 -16 7.16406 -16 16v26.751
|
||||
c0 34.4023 -52 33.7744 -52 0.676758v-116.571c0 -8.83105 -7.17773 -15.9961 -16.0078 -15.9961c-4.0166 0 -7.68848 1.48242 -10.499 3.92969l-7 6.09473c-3.37012 2.93457 -5.49316 7.25293 -5.49316 12.0674v41.2275c0 34.2148 -52 33.8857 -52 0.677734v-56.9531
|
||||
c0 -18.8555 8.27441 -36.874 22.7002 -49.4365l97.71 -85.0801c12.4502 -10.8398 19.5898 -26.4463 19.5898 -42.8164v-10.2861h220v7.07617c0 13.21 2.65332 26.0791 7.88281 38.25l42.835 99.6553c3.37891 7.82715 5.28223 16.501 5.28223 25.5625v0.0498047z" />
|
||||
<glyph glyph-name="hand-paper" unicode="" horiz-adv-x="448"
|
||||
d="M372.57 335.359c39.9062 5.63281 75.4297 -25.7393 75.4297 -66.3594v-131.564c-0.00292969 -15.7393 -1.80566 -30.9482 -5.19531 -45.666l-30.1836 -130.958c-3.34668 -14.5234 -16.2783 -24.8125 -31.1816 -24.8125h-222.897
|
||||
c-10.7539 0 -20.2588 5.28613 -26.0615 13.4316l-119.97 168.415c-21.2441 29.8203 -14.8047 71.3574 14.5498 93.1533c18.7754 13.9395 42.1309 16.2979 62.083 8.87109v126.13c0 44.0547 41.125 75.5439 82.4053 64.9834c23.8926 48.1963 92.3535 50.2471 117.982 0.74707
|
||||
c42.5186 11.1445 83.0391 -21.9346 83.0391 -65.5469v-10.8242zM399.997 137.437l-0.00195312 131.563c0 24.9492 -36.5703 25.5508 -36.5703 -0.691406v-76.3086c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v154.184
|
||||
c0 25.501 -36.5703 26.3633 -36.5703 0.691406v-154.875c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v188.309c0 25.501 -36.5703 26.3545 -36.5703 0.691406v-189c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16
|
||||
v153.309c0 25.501 -36.5713 26.3359 -36.5713 0.691406v-206.494c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832l-27.1279 38.0791c-14.3711 20.1709 -43.833 -2.33496 -29.3945 -22.6045l115.196 -161.697h201.92l27.3252 118.551
|
||||
c2.63086 11.417 3.96484 23.1553 3.96484 34.8857z" />
|
||||
<glyph glyph-name="hand-scissors" unicode=""
|
||||
d="M256 -32c-44.9561 0 -77.3428 43.2627 -64.0244 85.8535c-21.6484 13.71 -34.0156 38.7617 -30.3408 65.0068h-87.6348c-40.8037 0 -74 32.8105 -74 73.1406c0 40.3291 33.1963 73.1396 74 73.1396l94 -9.14062l-78.8496 18.6787
|
||||
c-38.3076 14.7422 -57.04 57.4707 -41.9424 95.1123c15.0303 37.4736 57.7549 55.7803 95.6416 41.2012l144.929 -55.7568c24.9551 30.5566 57.8086 43.9932 92.2178 24.7324l97.999 -54.8525c20.9746 -11.7393 34.0049 -33.8457 34.0049 -57.6904v-205.702
|
||||
c0 -30.7422 -21.4404 -57.5576 -51.7979 -64.5537l-118.999 -27.4268c-4.97168 -1.14648 -10.0889 -1.72949 -15.2031 -1.72949zM256 16.0127l70 -0.000976562c1.52441 0 2.99707 0.174805 4.42285 0.501953l119.001 27.4277
|
||||
c8.58203 1.97754 14.5762 9.29102 14.5762 17.7812v205.701c0 6.4873 -3.62109 12.542 -9.44922 15.8047l-98 54.8545c-8.13965 4.55566 -18.668 2.61914 -24.4873 -4.50781l-21.7646 -26.6475c-2.93457 -3.59375 -7.40332 -5.87305 -12.4004 -5.87305
|
||||
c-2.02246 0 -3.95703 0.375977 -5.73828 1.06152l-166.549 64.0908c-32.6543 12.5664 -50.7744 -34.5771 -19.2227 -46.7168l155.357 -59.7852c6 -2.30859 10.2539 -8.12402 10.2539 -14.9326v-11.6328c0 -8.83691 -7.16309 -16 -16 -16h-182
|
||||
c-34.375 0 -34.4297 -50.2803 0 -50.2803h182c8.83691 0 16 -7.16309 16 -16v-6.85645c0 -8.83691 -7.16309 -16 -16 -16h-28c-25.1221 0 -25.1592 -36.5674 0 -36.5674h28c8.83691 0 16 -7.16211 16 -16v-6.85547c0 -8.83691 -7.16309 -16 -16 -16
|
||||
c-25.1201 0 -25.1602 -36.5674 0 -36.5674z" />
|
||||
<glyph glyph-name="hand-lizard" unicode="" horiz-adv-x="576"
|
||||
d="M556.686 157.458c12.6357 -19.4863 19.3145 -42.0615 19.3145 -65.2871v-124.171h-224v71.582l-99.751 38.7871c-2.7832 1.08203 -5.70996 1.63086 -8.69727 1.63086h-131.552c-30.8789 0 -56 25.1211 -56 56c0 48.5234 39.4766 88 88 88h113.709l18.333 48h-196.042
|
||||
c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.084 -12.2725 60.4111 -32.8291zM528 16v76.1709c0 0.0166016 -0.0439453 0.106445 -0.0439453 0.12207c0 14.3945 -4.24219 27.8057 -11.5439 39.0498l-146.358 225.715
|
||||
c-4.44336 6.85254 -11.9707 10.9424 -20.1367 10.9424h-293.917c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709
|
||||
c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8h131.552c0.0175781 0 0.0712891 -0.0273438 0.0888672 -0.0273438c9.16992 0 17.9404 -1.72461 26.0039 -4.86621l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
|
||||
<glyph glyph-name="hand-spock" unicode=""
|
||||
d="M501.03 331.824c6.92773 -11.1826 10.9697 -24.4053 10.9697 -38.5146c0 -5.92676 -0.706055 -11.6885 -2.03809 -17.208l-57.623 -241.963c-13.2236 -56.1904 -63.707 -98.1387 -123.908 -98.1387h-0.352539h-107.455
|
||||
c-0.0761719 0 -0.193359 0.00195312 -0.270508 0.00195312c-40.9248 0 -78.1475 15.9814 -105.761 42.0391l-91.3652 85.9766c-14.3076 13.4434 -23.2246 32.5547 -23.2246 53.7168c0 19.5254 7.61035 37.2861 20.0254 50.4766
|
||||
c5.31836 5.66406 29.875 29.3926 68.1152 21.8477l-24.3594 82.1973c-1.97363 6.64844 -2.97656 13.6836 -2.97656 20.9688c0 38.6953 29.8926 70.4639 67.8262 73.4531c-0.246094 2.45117 -0.34082 4.85547 -0.34082 7.37207c0 34.4199 23.585 63.376 55.4619 71.5752
|
||||
c43.248 10.9785 80.5645 -17.7012 89.6602 -53.0723l13.6836 -53.207l4.64648 22.6602c6.99023 33.5186 36.6826 58.8037 72.2373 58.916c8.73438 0 56.625 -3.26953 70.7383 -54.0801c15.0664 0.710938 46.9199 -3.50977 66.3105 -35.0176zM463.271 287.219
|
||||
c7.86914 32.9844 -42.1211 45.2695 -50.0859 11.9219l-24.8008 -104.146c-4.38867 -18.4141 -31.7783 -11.8926 -28.0557 6.2168l28.5479 139.166c7.39844 36.0703 -43.3076 45.0703 -50.1182 11.9629l-31.791 -154.971
|
||||
c-3.54883 -17.3086 -28.2832 -18.0469 -32.7109 -0.804688l-47.3262 184.035c-8.43359 32.8105 -58.3691 20.2676 -49.8652 -12.8359l42.4414 -165.039c4.81641 -18.7207 -23.3711 -26.9121 -28.9648 -8.00781l-31.3438 105.779
|
||||
c-9.6875 32.6465 -59.1191 18.2578 -49.3867 -14.625l36.0137 -121.539c6.59375 -22.2441 10.1777 -45.7803 10.1777 -70.1523c0 -6.54297 -8.05664 -10.9355 -13.4824 -5.82617l-51.123 48.1074c-24.7852 23.4082 -60.0527 -14.1875 -35.2793 -37.4902l91.3691 -85.9805
|
||||
c19.0469 -17.9736 44.75 -28.998 72.9795 -28.998h0.157227h107.455c0.0732422 0 0.138672 0.0429688 0.212891 0.0429688c37.5791 0 69.1016 26.1416 77.3564 61.2168z" />
|
||||
<glyph glyph-name="hand-pointer" unicode="" horiz-adv-x="448"
|
||||
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -5.24023 -0.600586 -10.3037 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286
|
||||
c-21.2588 0 -41.3682 10.4102 -53.791 27.8457l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338
|
||||
c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289c27.1934 12.8467 60.3799 5.66992 79.8721 -19.0986zM80.9854 168.303c-14.4004 20.2119 -43.8008 -2.38281 -29.3945 -22.6055l109.712 -154c3.43457 -4.81934 8.92871 -7.69727 14.6973 -7.69727h178.285
|
||||
c8.49219 0 15.8037 5.99414 17.7822 14.5762l27.4297 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285v84c0 25.1602 -36.5713 25.1211 -36.5713 0c0 -8.83594 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16406 -16 16v21
|
||||
c0 25.1602 -36.5713 25.1201 -36.5713 0v-21c0 -8.83594 -7.16309 -16 -16 -16h-6.85938c-8.83691 0 -16 7.16406 -16 16v35c0 25.1602 -36.5703 25.1201 -36.5703 0v-35c0 -8.83594 -7.16309 -16 -16 -16h-6.85742c-8.83691 0 -16 7.16406 -16 16v175
|
||||
c0 25.1602 -36.5713 25.1201 -36.5713 0v-241.493c0 -15.5703 -20.0352 -21.9092 -29.0303 -9.2832zM176.143 48v96c0 8.83691 6.26855 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM251.571 48v96
|
||||
c0 8.83691 6.26758 16 14 16h6c7.73145 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26855 -16 -14 -16h-6c-7.73242 0 -14 7.16309 -14 16zM327 48v96c0 8.83691 6.26758 16 14 16h6c7.73242 0 14 -7.16309 14 -16v-96c0 -8.83691 -6.26758 -16 -14 -16h-6
|
||||
c-7.73242 0 -14 7.16309 -14 16z" />
|
||||
<glyph glyph-name="hand-peace" unicode="" horiz-adv-x="448"
|
||||
d="M362.146 256.024c42.5908 13.3184 85.8535 -19.0684 85.8535 -64.0244l-0.0117188 -70.001c-0.000976562 -5.24023 -0.600586 -10.3027 -1.72949 -15.2031l-27.4268 -118.999c-6.99707 -30.3564 -33.8105 -51.7969 -64.5547 -51.7969h-205.702
|
||||
c-23.8447 0 -45.9502 13.0303 -57.6904 34.0059l-54.8525 97.999c-19.2607 34.4092 -5.82422 67.2617 24.7324 92.2178l-55.7568 144.928c-14.5791 37.8867 3.72754 80.6113 41.2012 95.6416c37.6406 15.0977 80.3691 -3.63477 95.1123 -41.9424l18.6787 -78.8496
|
||||
l-9.14062 94c0 40.8037 32.8096 74 73.1396 74s73.1406 -33.1963 73.1406 -74v-87.6348c26.2451 3.6748 51.2959 -8.69238 65.0068 -30.3408zM399.987 122l-0.000976562 70c0 25.1602 -36.5674 25.1201 -36.5674 0c0 -8.83691 -7.16309 -16 -16 -16h-6.85547
|
||||
c-8.83789 0 -16 7.16309 -16 16v28c0 25.1592 -36.5674 25.1221 -36.5674 0v-28c0 -8.83691 -7.16309 -16 -16 -16h-6.85645c-8.83691 0 -16 7.16309 -16 16v182c0 34.4297 -50.2803 34.375 -50.2803 0v-182c0 -8.83691 -7.16309 -16 -16 -16h-11.6328
|
||||
c-6.80859 0 -12.624 4.25391 -14.9326 10.2539l-59.7842 155.357c-12.1396 31.5518 -59.2842 13.4326 -46.7168 -19.2227l64.0898 -166.549c0.685547 -1.78125 1.07812 -3.71875 1.07812 -5.74121c0 -4.99707 -2.2959 -9.46289 -5.88965 -12.3975l-26.6475 -21.7646
|
||||
c-7.12695 -5.81934 -9.06445 -16.3467 -4.50781 -24.4873l54.8535 -98c3.26367 -5.82812 9.31934 -9.44922 15.8057 -9.44922h205.701c8.49121 0 15.8037 5.99414 17.7812 14.5762l27.4277 119.001c0.333008 1.44629 0.501953 2.93457 0.501953 4.42285z" />
|
||||
<glyph glyph-name="registered" unicode=""
|
||||
d="M256 440c136.967 0 248 -111.033 248 -248s-111.033 -248 -248 -248s-248 111.033 -248 248s111.033 248 248 248zM256 -8c110.549 0 200 89.4678 200 200c0 110.549 -89.4678 200 -200 200c-110.549 0 -200 -89.4688 -200 -200c0 -110.549 89.4678 -200 200 -200z
|
||||
M366.442 73.791c4.40332 -7.99219 -1.37012 -17.791 -10.5107 -17.791h-42.8096c-0.00488281 0 -0.000976562 -0.0126953 -0.00585938 -0.0126953c-4.58594 0 -8.57422 2.58301 -10.5869 6.37305l-47.5156 89.3027h-31.958v-83.6631c0 -6.61719 -5.38281 -12 -12 -12
|
||||
h-38.5674c-6.61719 0 -12 5.38281 -12 12v248.304c0 6.61719 5.38281 12 12 12h78.667c71.251 0 101.498 -32.749 101.498 -85.252c0 -31.6123 -15.2148 -59.2969 -39.4824 -73.1758c3.02148 -4.61719 0.225586 0.199219 53.2715 -96.085zM256.933 208.094
|
||||
c20.9131 0 32.4307 11.5186 32.4316 32.4316c0 19.5752 -6.5127 31.709 -38.9297 31.709h-27.377v-64.1406h33.875z" />
|
||||
<glyph glyph-name="calendar-plus" unicode="" horiz-adv-x="448"
|
||||
d="M336 156v-24c0 -6.59961 -5.40039 -12 -12 -12h-76v-76c0 -6.59961 -5.40039 -12 -12 -12h-24c-6.59961 0 -12 5.40039 -12 12v76h-76c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h76v76c0 6.59961 5.40039 12 12 12h24c6.59961 0 12 -5.40039 12 -12
|
||||
v-76h76c6.59961 0 12 -5.40039 12 -12zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40
|
||||
c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="calendar-minus" unicode="" horiz-adv-x="448"
|
||||
d="M124 120c-6.59961 0 -12 5.40039 -12 12v24c0 6.59961 5.40039 12 12 12h200c6.59961 0 12 -5.40039 12 -12v-24c0 -6.59961 -5.40039 -12 -12 -12h-200zM448 336v-352c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52
|
||||
c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="calendar-times" unicode="" horiz-adv-x="448"
|
||||
d="M311.7 73.2998l-17 -17c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-53.7002 53.7998l-53.7002 -53.6992c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-17 17c-4.7002 4.69922 -4.7002 12.2998 0 17l53.7002 53.6992l-53.7002 53.7002c-4.7002 4.7002 -4.7002 12.2998 0 17
|
||||
l17 17c4.7002 4.7002 12.2998 4.7002 17 0l53.7002 -53.7002l53.7002 53.7002c4.7002 4.7002 12.2998 4.7002 17 0l17 -17c4.7002 -4.7002 4.7002 -12.2998 0 -17l-53.7998 -53.7998l53.6992 -53.7002c4.80078 -4.7002 4.80078 -12.2998 0.100586 -17zM448 336v-352
|
||||
c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48zM400 -10
|
||||
v298h-352v-298c0 -3.2998 2.7002 -6 6 -6h340c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="calendar-check" unicode="" horiz-adv-x="448"
|
||||
d="M400 384c26.5098 0 48 -21.4902 48 -48v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h48v52c0 6.62695 5.37305 12 12 12h40c6.62695 0 12 -5.37305 12 -12v-52h128v52c0 6.62695 5.37305 12 12 12h40
|
||||
c6.62695 0 12 -5.37305 12 -12v-52h48zM394 -16c3.31152 0 6 2.68848 6 6v298h-352v-298c0 -3.31152 2.68848 -6 6 -6h340zM341.151 184.65l-142.31 -141.169c-4.70508 -4.66699 -12.3027 -4.6377 -16.9707 0.0673828l-75.0908 75.6992
|
||||
c-4.66699 4.70508 -4.6377 12.3027 0.0673828 16.9707l22.7197 22.5361c4.70508 4.66699 12.3027 4.63672 16.9697 -0.0693359l44.1035 -44.4609l111.072 110.182c4.70508 4.66699 12.3027 4.63672 16.9707 -0.0683594l22.5361 -22.7178
|
||||
c4.66699 -4.70508 4.63672 -12.3027 -0.0683594 -16.9697z" />
|
||||
<glyph glyph-name="map" unicode="" horiz-adv-x="576"
|
||||
d="M560.02 416c8.4502 0 15.9805 -6.83008 15.9805 -16.0195v-346.32c0 -13.4707 -8.32422 -24.9951 -20.1201 -29.71l-151.83 -52.8105c-6.23242 -2.02832 -12.9023 -3.12305 -19.8076 -3.12305c-7.07324 0 -13.8799 1.15039 -20.2422 3.27344l-172 60.71l-170.05 -62.8398
|
||||
c-1.99023 -0.790039 -4 -1.16016 -5.95996 -1.16016c-8.45996 0 -15.9902 6.83008 -15.9902 16.0195v346.32c0.00292969 13.4697 8.32617 24.9932 20.1201 29.71l151.83 52.8105c6.43945 2.08984 13.1201 3.13965 19.8096 3.13965
|
||||
c7.06641 -0.00292969 13.8789 -1.16602 20.2402 -3.28027l172 -60.7197h0.00976562l170.05 62.8398c1.98047 0.790039 4 1.16016 5.95996 1.16016zM224 357.58v-285.97l128 -45.1904v285.97zM48 29.9502l127.36 47.0801l0.639648 0.229492v286.2l-128 -44.5303v-288.979z
|
||||
M528 65.0801v288.97l-127.36 -47.0693l-0.639648 -0.240234v-286.19z" />
|
||||
<glyph glyph-name="comment-alt" unicode=""
|
||||
d="M448 448c35.2998 0 64 -28.7002 64 -64v-288c0 -35.2998 -28.7002 -64 -64 -64h-144l-124.9 -93.5996c-2.19922 -1.7002 -4.69922 -2.40039 -7.09961 -2.40039c-6.2002 0 -12 4.90039 -12 12v84h-96c-35.2998 0 -64 28.7002 -64 64v288c0 35.2998 28.7002 64 64 64h384z
|
||||
M464 96v288c0 8.7998 -7.2002 16 -16 16h-384c-8.7998 0 -16 -7.2002 -16 -16v-288c0 -8.7998 7.2002 -16 16 -16h144v-60l67.2002 50.4004l12.7998 9.59961h160c8.7998 0 16 7.2002 16 16z" />
|
||||
<glyph glyph-name="pause-circle" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48
|
||||
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16zM240 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-48c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h48c8.7998 0 16 -7.2002 16 -16z" />
|
||||
<glyph glyph-name="stop-circle" unicode=""
|
||||
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM352 272v-160c0 -8.7998 -7.2002 -16 -16 -16h-160
|
||||
c-8.7998 0 -16 7.2002 -16 16v160c0 8.7998 7.2002 16 16 16h160c8.7998 0 16 -7.2002 16 -16z" />
|
||||
<glyph glyph-name="handshake" unicode="" horiz-adv-x="640"
|
||||
d="M519.2 320.1h120.8v-255.699h-64c-17.5 0 -31.7998 14.1992 -31.9004 31.6992h-57.8994c-1.7998 -8.19922 -5.2998 -16.0996 -10.9004 -23l-26.2002 -32.2998c-15.7998 -19.3994 -41.8994 -25.5 -64 -16.7998c-13.5 -16.5996 -30.5996 -24 -48.7998 -24
|
||||
c-15.0996 0 -28.5996 5.09961 -41.0996 15.9004c-31.7998 -21.9004 -74.7002 -21.3008 -105.601 3.7998l-84.5996 76.3994h-9.09961c-0.100586 -17.5 -14.3008 -31.6992 -31.9004 -31.6992h-64v255.699h118l47.5996 47.6006c10.5 10.3994 24.8008 16.2998 39.6006 16.2998
|
||||
h226.8c15.4326 0 29.4326 -6.22168 39.5996 -16.2998zM48 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16zM438 103.3c2.7002 3.40039 2.2002 8.5 -1.2002 11.2998l-108.2 87.8008l-8.19922 -7.5
|
||||
c-40.3008 -36.8008 -86.7002 -11.8008 -101.5 4.39941c-26.7002 29 -25 74.4004 4.39941 101.3l38.7002 35.5h-56.7002c-2 -0.799805 -3.7002 -1.5 -5.7002 -2.2998l-61.6992 -61.5996h-41.9004v-128.101h27.7002l97.2998 -88
|
||||
c16.0996 -13.0996 41.4004 -10.5 55.2998 6.60059l15.6006 19.2002l36.7998 -31.5c3 -2.40039 12 -4.90039 18 2.39941l30 36.5l23.8994 -19.3994c3.5 -2.80078 8.5 -2.2002 11.3008 1.19922zM544 144.1v128h-44.7002l-61.7002 61.6006
|
||||
c-1.39941 1.5 -3.39941 2.2998 -5.5 2.2998l-83.6992 -0.200195c-10 0 -19.6006 -3.7002 -27 -10.5l-65.6006 -60.0996c-9.7002 -8.7998 -10.5 -24 -1.2002 -33.9004c8.90039 -9.39941 25.1006 -8.7002 34.6006 0l55.2002 50.6006c6.5 5.89941 16.5996 5.5 22.5996 -1
|
||||
l10.9004 -11.7002c6 -6.5 5.5 -16.6006 -1 -22.6006l-12.5 -11.3994l102.699 -83.4004c2.80078 -2.2998 5.40039 -4.89941 7.7002 -7.7002h69.2002zM592 96.4004c8.7998 0 16 7.09961 16 16c0 8.7998 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.80078 7.2002 -16 16 -16z
|
||||
" />
|
||||
<glyph glyph-name="envelope-open" unicode=""
|
||||
d="M494.586 283.484c10.6523 -8.80762 17.4141 -22.1064 17.4141 -36.9932v-262.491c0 -26.5098 -21.4902 -48 -48 -48h-416c-26.5098 0 -48 21.4902 -48 48v262.515c0 14.9355 6.80469 28.2705 17.5146 37.0771c4.08008 3.35449 110.688 89.0996 135.15 108.549
|
||||
c22.6992 18.1426 60.1299 55.8594 103.335 55.8594c43.4365 0 81.2314 -38.1914 103.335 -55.8594c23.5283 -18.707 130.554 -104.773 135.251 -108.656zM464 -10v253.632c0 0.00195312 0.00390625 0.000976562 0.00390625 0.00292969
|
||||
c0 1.88184 -0.869141 3.56152 -2.22754 4.66016c-15.8633 12.8232 -108.793 87.5752 -132.366 106.316c-17.5527 14.0195 -49.7168 45.3887 -73.4102 45.3887c-23.6016 0 -55.2451 -30.8799 -73.4102 -45.3887c-23.5713 -18.7393 -116.494 -93.4795 -132.364 -106.293
|
||||
c-1.40918 -1.13965 -2.22559 -2.85254 -2.22559 -4.66504v-253.653c0 -3.31152 2.68848 -6 6 -6h404c3.31152 0 6 2.68848 6 6zM432.009 177.704c4.24902 -5.15918 3.46484 -12.7949 -1.74512 -16.9814c-28.9746 -23.2822 -59.2734 -47.5967 -70.9287 -56.8623
|
||||
c-22.6992 -18.1436 -60.1299 -55.8604 -103.335 -55.8604c-43.4521 0 -81.2871 38.2373 -103.335 55.8604c-11.2793 8.9668 -41.7441 33.4131 -70.9268 56.8643c-5.20996 4.1875 -5.99316 11.8223 -1.74512 16.9814l15.2578 18.5283
|
||||
c4.17773 5.07227 11.6572 5.84277 16.7793 1.72559c28.6182 -23.001 58.5654 -47.0352 70.5596 -56.5713c17.5527 -14.0195 49.7168 -45.3887 73.4102 -45.3887c23.6016 0 55.2461 30.8799 73.4102 45.3887c11.9941 9.53516 41.9434 33.5703 70.5625 56.5684
|
||||
c5.12207 4.11621 12.6016 3.3457 16.7783 -1.72656z" />
|
||||
<glyph glyph-name="address-book" unicode="" horiz-adv-x="448"
|
||||
d="M436 288h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-64h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12h-20v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48
|
||||
h320c26.5 0 48 -21.5 48 -48v-48h20c6.59961 0 12 -5.40039 12 -12v-40c0 -6.59961 -5.40039 -12 -12 -12zM368 -16v416h-320v-416h320zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM118.4 64
|
||||
c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002
|
||||
h-179.199z" />
|
||||
<glyph glyph-name="address-card" unicode="" horiz-adv-x="576"
|
||||
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v352h-480v-352h480zM208 192c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z
|
||||
M118.4 64c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002
|
||||
c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199zM360 128c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 192c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
|
||||
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 256c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112z" />
|
||||
<glyph glyph-name="user-circle" unicode="" horiz-adv-x="496"
|
||||
d="M248 344c53 0 96 -43 96 -96s-43 -96 -96 -96s-96 43 -96 96s43 96 96 96zM248 200c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
|
||||
c49.7002 0 95.0996 18.2998 130.1 48.4004c-14.8994 23 -40.3994 38.5 -69.5996 39.5c-20.7998 -6.5 -40.5996 -9.60059 -60.5 -9.60059s-39.7002 3.2002 -60.5 9.60059c-29.2002 -0.900391 -54.7002 -16.5 -69.5996 -39.5c35 -30.1006 80.3994 -48.4004 130.1 -48.4004z
|
||||
M410.7 76.0996c23.3994 32.7002 37.2998 72.7002 37.2998 115.9c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -43.2002 13.9004 -83.2002 37.2998 -115.9c24.5 31.4004 62.2002 51.9004 105.101 51.9004c10.1992 0 26.0996 -9.59961 57.5996 -9.59961
|
||||
c31.5996 0 47.4004 9.59961 57.5996 9.59961c43 0 80.7002 -20.5 105.101 -51.9004z" />
|
||||
<glyph glyph-name="id-badge" unicode="" horiz-adv-x="384"
|
||||
d="M336 448c26.5 0 48 -21.5 48 -48v-416c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v416c0 26.5 21.5 48 48 48h288zM336 -16v416h-288v-416h288zM144 336c-8.7998 0 -16 7.2002 -16 16s7.2002 16 16 16h96c8.7998 0 16 -7.2002 16 -16s-7.2002 -16 -16 -16
|
||||
h-96zM192 160c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64zM102.4 32c-12.4004 0 -22.4004 8.59961 -22.4004 19.2002v19.2002c0 31.7998 30.0996 57.5996 67.2002 57.5996c11.3994 0 17.8994 -8 44.7998 -8
|
||||
c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996v-19.2002c0 -10.6006 -10 -19.2002 -22.4004 -19.2002h-179.199z" />
|
||||
<glyph glyph-name="id-card" unicode="" horiz-adv-x="576"
|
||||
d="M528 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-480c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h480zM528 16v288h-480v-288h32.7998c-1 4.5 -0.799805 -3.59961 -0.799805 22.4004c0 31.7998 30.0996 57.5996 67.2002 57.5996
|
||||
c11.3994 0 17.8994 -8 44.7998 -8c26.0996 0 34 8 44.7998 8c37.1006 0 67.2002 -25.7998 67.2002 -57.5996c0 -26 0.0996094 -17.9004 -0.799805 -22.4004h224.8zM360 96c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16
|
||||
c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 160c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM360 224c-4.40039 0 -8 3.59961 -8 8v16c0 4.40039 3.59961 8 8 8h112
|
||||
c4.40039 0 8 -3.59961 8 -8v-16c0 -4.40039 -3.59961 -8 -8 -8h-112zM192 128c-35.2998 0 -64 28.7002 -64 64s28.7002 64 64 64s64 -28.7002 64 -64s-28.7002 -64 -64 -64z" />
|
||||
<glyph glyph-name="window-maximize" unicode=""
|
||||
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v234h-416v-234c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="window-minimize" unicode=""
|
||||
d="M480 -32h-448c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32h448c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
|
||||
<glyph glyph-name="window-restore" unicode=""
|
||||
d="M464 448c26.5 0 48 -21.5 48 -48v-320c0 -26.5 -21.5 -48 -48 -48h-48v-48c0 -26.5 -21.5 -48 -48 -48h-320c-26.5 0 -48 21.5 -48 48v320c0 26.5 21.5 48 48 48h48v48c0 26.5 21.5 48 48 48h320zM368 -16v208h-320v-208h320zM464 80v320h-320v-48h224
|
||||
c26.5 0 48 -21.5 48 -48v-224h48z" />
|
||||
<glyph glyph-name="snowflake" unicode="" horiz-adv-x="448"
|
||||
d="M440.1 92.7998c7.60059 -4.39941 10.1006 -14.2002 5.5 -21.7002l-7.89941 -13.8994c-4.40039 -7.7002 -14 -10.2998 -21.5 -5.90039l-39.2002 23l9.09961 -34.7002c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.5996l-15.2002 -4.09961
|
||||
c-8.39941 -2.30078 -17.0996 2.7998 -19.2998 11.2998l-21.2998 81l-71.9004 42.2002v-84.5l58.2998 -59.3008c6.10059 -6.19922 6.10059 -16.3994 0 -22.5996l-11.0996 -11.2998c-6.09961 -6.2002 -16.0996 -6.2002 -22.2002 0l-24.8994 25.3994v-46.0996
|
||||
c0 -8.7998 -7 -16 -15.7002 -16h-15.7002c-8.7002 0 -15.7002 7.2002 -15.7002 16v45.9004l-24.8994 -25.4004c-6.10059 -6.2002 -16.1006 -6.2002 -22.2002 0l-11.1006 11.2998c-6.09961 6.2002 -6.09961 16.4004 0 22.6006l58.3008 59.2998v84.5l-71.9004 -42.2002
|
||||
l-21.2998 -81c-2.2998 -8.5 -10.9004 -13.5996 -19.2998 -11.2998l-15.2002 4.09961c-8.40039 2.2998 -13.2998 11.1006 -11.1006 19.6006l9.10059 34.6992l-39.2002 -23c-7.5 -4.39941 -17.2002 -1.7998 -21.5 5.90039l-7.90039 13.9004
|
||||
c-4.2998 7.69922 -1.69922 17.5 5.80078 21.8994l39.1992 23l-34.0996 9.2998c-8.40039 2.30078 -13.2998 11.1006 -11.0996 19.6006l4.09961 15.5c2.2998 8.5 10.9004 13.5996 19.2998 11.2998l79.7002 -21.7002l71.9004 42.2002l-71.9004 42.2002l-79.7002 -21.7002
|
||||
c-8.39941 -2.2998 -17.0996 2.7998 -19.2998 11.2998l-4.09961 15.5c-2.30078 8.5 2.69922 17.2998 11.0996 19.6006l34.0996 9.09961l-39.1992 23c-7.60059 4.5 -10.1006 14.2002 -5.80078 21.9004l7.90039 13.8994c4.40039 7.7002 14 10.2998 21.5 5.90039l39.2002 -23
|
||||
l-9.10059 34.7002c-2.2998 8.5 2.7002 17.2998 11.1006 19.5996l15.2002 4.09961c8.39941 2.30078 17.0996 -2.7998 19.2998 -11.2998l21.2998 -81l71.9004 -42.2002v84.5l-58.3008 59.3008c-6.09961 6.19922 -6.09961 16.3994 0 22.5996l11.5 11.2998
|
||||
c6.10059 6.2002 16.1006 6.2002 22.2002 0l24.9004 -25.3994v46.0996c0 8.7998 7 16 15.7002 16h15.6992c8.7002 0 15.7002 -7.2002 15.7002 -16v-45.9004l24.9004 25.4004c6.09961 6.2002 16.0996 6.2002 22.2002 0l11.0996 -11.2998
|
||||
c6.09961 -6.2002 6.09961 -16.4004 0 -22.6006l-58.2998 -59.2998v-84.5l71.8994 42.2002l21.3008 81c2.2998 8.5 10.8994 13.5996 19.2998 11.2998l15.2002 -4.09961c8.39941 -2.2998 13.2998 -11.1006 11.0996 -19.6006l-9.09961 -34.6992l39.1992 23
|
||||
c7.5 4.39941 17.2002 1.7998 21.5 -5.90039l7.90039 -13.9004c4.2998 -7.69922 1.7002 -17.5 -5.7998 -21.8994l-39.2002 -23l34.0996 -9.2998c8.40039 -2.30078 13.3008 -11.1006 11.1006 -19.6006l-4.10059 -15.5c-2.2998 -8.5 -10.8994 -13.5996 -19.2998 -11.2998
|
||||
l-79.7002 21.7002l-71.8994 -42.2002l71.7998 -42.2002l79.7002 21.7002c8.39941 2.2998 17.0996 -2.7998 19.2998 -11.2998l4.09961 -15.5c2.30078 -8.5 -2.69922 -17.2998 -11.0996 -19.6006l-34.0996 -9.2998z" />
|
||||
<glyph glyph-name="trash-alt" unicode="" horiz-adv-x="448"
|
||||
d="M268 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216c0 -6.62305 -5.37695 -12 -12 -12h-24zM432 368c8.83105 0 16 -7.16895 16 -16v-16c0 -8.83105 -7.16895 -16 -16 -16h-16v-336
|
||||
c0 -26.4922 -21.5078 -48 -48 -48h-288c-26.4922 0 -48 21.5078 -48 48v336h-16c-8.83105 0 -16 7.16895 -16 16v16c0 8.83105 7.16895 16 16 16h82.4102l34.0195 56.7002c8.39258 13.9844 23.6777 23.2998 41.1602 23.2998h100.82
|
||||
c0.0078125 0 -0.015625 0.0517578 -0.0078125 0.0517578c17.4824 0 32.7949 -9.36719 41.1875 -23.3516l34 -56.7002h82.4102zM171.84 397.09l-17.4502 -29.0898h139.221l-17.46 29.0898c-1.0498 1.74707 -2.95898 2.91016 -5.14355 2.91016h-0.00683594h-94
|
||||
c-0.00585938 0 -0.00683594 0.00683594 -0.0126953 0.00683594c-2.18457 0 -4.09766 -1.16992 -5.14746 -2.91699zM368 -16v336h-288v-336h288zM156 32c-6.62305 0 -12 5.37695 -12 12v216c0 6.62305 5.37695 12 12 12h24c6.62305 0 12 -5.37695 12 -12v-216
|
||||
c0 -6.62305 -5.37695 -12 -12 -12h-24z" />
|
||||
<glyph glyph-name="images" unicode="" horiz-adv-x="576"
|
||||
d="M480 32v-16c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256c0 26.5098 21.4902 48 48 48h16v-48h-10c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v10h48zM522 368h-372
|
||||
c-3.31152 0 -6 -2.68848 -6 -6v-244c0 -3.31152 2.68848 -6 6 -6h372c3.31152 0 6 2.68848 6 6v244c0 3.31152 -2.68848 6 -6 6zM528 416c26.5098 0 48 -21.4902 48 -48v-256c0 -26.5098 -21.4902 -48 -48 -48h-384c-26.5098 0 -48 21.4902 -48 48v256
|
||||
c0 26.5098 21.4902 48 48 48h384zM264 304c0 -22.0908 -17.9092 -40 -40 -40s-40 17.9092 -40 40s17.9092 40 40 40s40 -17.9092 40 -40zM192 208l39.5146 39.5146c4.68652 4.68652 12.2842 4.68652 16.9717 0l39.5137 -39.5146l103.515 103.515
|
||||
c4.68652 4.68652 12.2842 4.68652 16.9717 0l71.5137 -71.5146v-80h-288v48z" />
|
||||
<glyph glyph-name="clipboard" unicode="" horiz-adv-x="384"
|
||||
d="M336 384c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-288c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h80c0 35.2998 28.7002 64 64 64s64 -28.7002 64 -64h80zM192 408c-13.2998 0 -24 -10.7002 -24 -24s10.7002 -24 24 -24s24 10.7002 24 24
|
||||
s-10.7002 24 -24 24zM336 -10v340c0 3.2998 -2.7002 6 -6 6h-42v-36c0 -6.59961 -5.40039 -12 -12 -12h-168c-6.59961 0 -12 5.40039 -12 12v36h-42c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h276c3.2998 0 6 2.7002 6 6z" />
|
||||
<glyph glyph-name="arrow-alt-circle-down" unicode=""
|
||||
d="M256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM256 -8c110.5 0 200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200zM224 308c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-116
|
||||
h67c10.7002 0 16.0996 -12.9004 8.5 -20.5l-99 -99c-4.7002 -4.7002 -12.2998 -4.7002 -17 0l-99 99c-7.5 7.59961 -2.2002 20.5 8.5 20.5h67v116z" />
|
||||
<glyph glyph-name="arrow-alt-circle-left" unicode=""
|
||||
d="M8 192c0 137 111 248 248 248s248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248zM456 192c0 110.5 -89.5 200 -200 200s-200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200zM384 212v-40c0 -6.59961 -5.40039 -12 -12 -12h-116v-67
|
||||
c0 -10.7002 -12.9004 -16 -20.5 -8.5l-99 99c-4.7002 4.7002 -4.7002 12.2998 0 17l99 99c7.59961 7.59961 20.5 2.2002 20.5 -8.5v-67h116c6.59961 0 12 -5.40039 12 -12z" />
|
||||
<glyph glyph-name="arrow-alt-circle-right" unicode=""
|
||||
d="M504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248s248 -111 248 -248zM56 192c0 -110.5 89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200s-200 -89.5 -200 -200zM128 172v40c0 6.59961 5.40039 12 12 12h116v67
|
||||
c0 10.7002 12.9004 16 20.5 8.5l99 -99c4.7002 -4.7002 4.7002 -12.2998 0 -17l-99 -99c-7.59961 -7.59961 -20.5 -2.2002 -20.5 8.5v67h-116c-6.59961 0 -12 5.40039 -12 12z" />
|
||||
<glyph glyph-name="arrow-alt-circle-up" unicode=""
|
||||
d="M256 -56c-137 0 -248 111 -248 248s111 248 248 248s248 -111 248 -248s-111 -248 -248 -248zM256 392c-110.5 0 -200 -89.5 -200 -200s89.5 -200 200 -200s200 89.5 200 200s-89.5 200 -200 200zM276 64h-40c-6.59961 0 -12 5.40039 -12 12v116h-67
|
||||
c-10.7002 0 -16 12.9004 -8.5 20.5l99 99c4.7002 4.7002 12.2998 4.7002 17 0l99 -99c7.59961 -7.59961 2.2002 -20.5 -8.5 -20.5h-67v-116c0 -6.59961 -5.40039 -12 -12 -12z" />
|
||||
<glyph glyph-name="gem" unicode="" horiz-adv-x="576"
|
||||
d="M464 448c4.09961 0 7.7998 -2 10.0996 -5.40039l99.9004 -147.199c2.90039 -4.40039 2.59961 -10.1006 -0.700195 -14.2002l-276 -340.8c-4.7998 -5.90039 -13.7998 -5.90039 -18.5996 0l-276 340.8c-3.2998 4 -3.60059 9.7998 -0.700195 14.2002l100 147.199
|
||||
c2.2002 3.40039 6 5.40039 10 5.40039h352zM444.7 400h-56.7998l51.6992 -96h68.4004zM242.6 400l-51.5996 -96h194l-51.7002 96h-90.7002zM131.3 400l-63.2998 -96h68.4004l51.6992 96h-56.7998zM88.2998 256l119.7 -160l-68.2998 160h-51.4004zM191.2 256l96.7998 -243.3
|
||||
l96.7998 243.3h-193.6zM368 96l119.6 160h-51.3994z" />
|
||||
<glyph glyph-name="money-bill-alt" unicode="" horiz-adv-x="640"
|
||||
d="M320 304c53.0195 0 96 -50.1396 96 -112c0 -61.8701 -43 -112 -96 -112c-53.0195 0 -96 50.1504 -96 112c0 61.8604 42.9805 112 96 112zM360 136v16c0 4.41992 -3.58008 8 -8 8h-16v88c0 4.41992 -3.58008 8 -8 8h-13.5801
|
||||
c-4.91113 0 -9.50586 -1.49316 -13.3096 -4.03027l-15.3301 -10.2197c-2.15332 -1.43262 -3.55957 -3.88379 -3.55957 -6.66113c0 -1.6377 0.493164 -3.16113 1.33887 -4.42871l8.88086 -13.3105c1.43164 -2.15234 3.88379 -3.55957 6.66113 -3.55957
|
||||
c1.6377 0 3.16016 0.494141 4.42871 1.33984l0.469727 0.310547v-55.4404h-16c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h64c4.41992 0 8 3.58008 8 8zM608 384c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-576
|
||||
c-17.6699 0 -32 14.3301 -32 32v320c0 17.6699 14.3301 32 32 32h576zM592 112v160c-35.3496 0 -64 28.6504 -64 64h-416c0 -35.3496 -28.6504 -64 -64 -64v-160c35.3496 0 64 -28.6504 64 -64h416c0 35.3496 28.6504 64 64 64z" />
|
||||
<glyph glyph-name="window-close" unicode=""
|
||||
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM464 22v340c0 3.2998 -2.7002 6 -6 6h-404c-3.2998 0 -6 -2.7002 -6 -6v-340c0 -3.2998 2.7002 -6 6 -6h404c3.2998 0 6 2.7002 6 6z
|
||||
M356.5 253.4l-61.4004 -61.4004l61.4004 -61.4004c4.59961 -4.59961 4.59961 -12.0996 0 -16.7998l-22.2998 -22.2998c-4.60059 -4.59961 -12.1006 -4.59961 -16.7998 0l-61.4004 61.4004l-61.4004 -61.4004c-4.59961 -4.59961 -12.0996 -4.59961 -16.7998 0
|
||||
l-22.2998 22.2998c-4.59961 4.60059 -4.59961 12.1006 0 16.7998l61.4004 61.4004l-61.4004 61.4004c-4.59961 4.59961 -4.59961 12.0996 0 16.7998l22.2998 22.2998c4.60059 4.59961 12.1006 4.59961 16.7998 0l61.4004 -61.4004l61.4004 61.4004
|
||||
c4.59961 4.59961 12.0996 4.59961 16.7998 0l22.2998 -22.2998c4.7002 -4.60059 4.7002 -12.1006 0 -16.7998z" />
|
||||
<glyph glyph-name="comment-dots" unicode=""
|
||||
d="M144 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM256 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM368 240c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
|
||||
s-32 14.2998 -32 32s14.2998 32 32 32zM256 416c141.4 0 256 -93.0996 256 -208s-114.6 -208 -256 -208c-32.7998 0 -64 5.2002 -92.9004 14.2998c-29.0996 -20.5996 -77.5996 -46.2998 -139.1 -46.2998c-9.59961 0 -18.2998 5.7002 -22.0996 14.5
|
||||
c-3.80078 8.7998 -2 19 4.59961 26c0.5 0.400391 31.5 33.7998 46.4004 73.2002c-33 35.0996 -52.9004 78.7002 -52.9004 126.3c0 114.9 114.6 208 256 208zM256 48c114.7 0 208 71.7998 208 160s-93.2998 160 -208 160s-208 -71.7998 -208 -160
|
||||
c0 -42.2002 21.7002 -74.0996 39.7998 -93.4004l20.6006 -21.7998l-10.6006 -28.0996c-5.5 -14.5 -12.5996 -28.1006 -19.8994 -40.2002c23.5996 7.59961 43.1992 18.9004 57.5 29l19.5 13.7998l22.6992 -7.2002c25.3008 -8 51.7002 -12.0996 78.4004 -12.0996z" />
|
||||
<glyph glyph-name="smile-wink" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM365.8 138.4c10.2002 -8.5 11.6006 -23.6006 3.10059 -33.8008
|
||||
c-30 -36 -74.1006 -56.5996 -120.9 -56.5996s-90.9004 20.5996 -120.9 56.5996c-8.39941 10.2002 -7.09961 25.3008 3.10059 33.8008c10.0996 8.39941 25.2998 7.09961 33.7998 -3.10059c20.7998 -25.0996 51.5 -39.3994 84 -39.3994s63.2002 14.3994 84 39.3994
|
||||
c8.5 10.2002 23.5996 11.6006 33.7998 3.10059zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 268c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008l-9.5 8.5
|
||||
c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996z" />
|
||||
<glyph glyph-name="angry" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 136c33.5996 0 65.2002 -14.7998 86.7998 -40.5996
|
||||
c8.40039 -10.2002 7.10059 -25.3008 -3.09961 -33.8008c-10.6006 -8.89941 -25.7002 -6.69922 -33.7998 3c-24.8008 29.7002 -75 29.7002 -99.8008 0c-8.5 -10.1992 -23.5996 -11.5 -33.7998 -3s-11.5996 23.6006 -3.09961 33.8008
|
||||
c21.5996 25.7998 53.2002 40.5996 86.7998 40.5996zM200 208c0 -17.7002 -14.2998 -32.0996 -32 -32.0996s-32 14.2998 -32 32c0 6.19922 2.2002 11.6992 5.2998 16.5996l-28.2002 8.5c-12.6992 3.7998 -19.8994 17.2002 -16.0996 29.9004
|
||||
c3.7998 12.6992 17.0996 20 29.9004 16.0996l80 -24c12.6992 -3.7998 19.8994 -17.2002 16.0996 -29.9004c-3.09961 -10.3994 -12.7002 -17.0996 -23 -17.0996zM399 262.9c3.7998 -12.7002 -3.40039 -26.1006 -16.0996 -29.8008l-28.2002 -8.5
|
||||
c3.09961 -4.89941 5.2998 -10.3994 5.2998 -16.5996c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32c-10.2998 0 -19.9004 6.7002 -23 17.0996c-3.7998 12.7002 3.40039 26.1006 16.0996 29.9004l80 24c12.8008 3.7998 26.1006 -3.40039 29.9004 -16.0996z" />
|
||||
<glyph glyph-name="dizzy" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM214.2 209.9
|
||||
c-7.90039 -7.90039 -20.5 -7.90039 -28.4004 -0.200195l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998
|
||||
c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.9004c7.7998 7.7998 20.5 7.7998 28.2998 0s7.7998 -20.5 0 -28.2998l-17.9004 -17.9004l17.9004 -17.7998c7.7998 -7.7998 7.7998 -20.5 0 -28.2998zM374.2 302.1
|
||||
c7.7002 -7.7998 7.7002 -20.3994 0 -28.1992l-17.9004 -17.9004l17.7998 -18c7.80078 -7.7998 7.80078 -20.5 0 -28.2998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0l-17.7998 17.7998l-17.7998 -17.7998c-7.7998 -7.7998 -20.5 -7.7998 -28.2998 0
|
||||
c-7.80078 7.7998 -7.80078 20.5 0 28.2998l17.8994 17.9004l-17.8994 17.8994c-7.80078 7.7998 -7.80078 20.5 0 28.2998c7.7998 7.80078 20.5 7.80078 28.2998 0l17.7998 -17.7998l17.9004 17.7998c7.7998 7.80078 20.5 7.80078 28.2998 0zM248 176
|
||||
c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64s-64 28.7002 -64 64s28.7002 64 64 64z" />
|
||||
<glyph glyph-name="flushed" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM344 304c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80
|
||||
s-80 35.7998 -80 80s35.7998 80 80 80zM344 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM344 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM232 224c0 -44.2002 -35.7998 -80 -80 -80
|
||||
s-80 35.7998 -80 80s35.7998 80 80 80s80 -35.7998 80 -80zM152 176c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM152 248c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM312 104
|
||||
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
|
||||
<glyph glyph-name="frown-open" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32
|
||||
s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM248 160c35.5996 0 88.7998 -21.2998 95.7998 -61.2002c2 -11.7998 -9.09961 -21.5996 -20.5 -18.0996
|
||||
c-31.2002 9.59961 -59.3994 15.2998 -75.2998 15.2998s-44.0996 -5.7002 -75.2998 -15.2998c-11.5 -3.40039 -22.5 6.2998 -20.5 18.0996c7 39.9004 60.2002 61.2002 95.7998 61.2002z" />
|
||||
<glyph glyph-name="grimace" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM344 192c26.5 0 48 -21.5 48 -48v-32c0 -26.5 -21.5 -48 -48 -48h-192c-26.5 0 -48 21.5 -48 48v32c0 26.5 21.5 48 48 48
|
||||
h192zM176 96v24h-40v-8c0 -8.7998 7.2002 -16 16 -16h24zM176 136v24h-24c-8.7998 0 -16 -7.2002 -16 -16v-8h40zM240 96v24h-48v-24h48zM240 136v24h-48v-24h48zM304 96v24h-48v-24h48zM304 136v24h-48v-24h48zM360 112v8h-40v-24h24c8.7998 0 16 7.2002 16 16zM360 136v8
|
||||
c0 8.7998 -7.2002 16 -16 16h-24v-24h40z" />
|
||||
<glyph glyph-name="grin" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z" />
|
||||
<glyph glyph-name="grin-alt" unicode="" horiz-adv-x="496"
|
||||
d="M200.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56
|
||||
c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM328.3 200c-7.5 -11.4004 -24.5996 -12 -32.7002 0c-12.3994 18.7002 -15.1992 37.2998 -15.6992 56c0.599609 18.7002 3.2998 37.2998 15.6992 56c7.60059 11.4004 24.7002 12 32.7002 0
|
||||
c12.4004 -18.7002 15.2002 -37.2998 15.7002 -56c-0.599609 -18.7002 -3.2998 -37.2998 -15.7002 -56zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200
|
||||
s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006
|
||||
s79.7002 4.7998 105.6 13.1006z" />
|
||||
<glyph glyph-name="grin-beam" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM117.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
|
||||
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996
|
||||
l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002zM277.7 216.3c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998
|
||||
c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002z" />
|
||||
<glyph glyph-name="grin-beam-sweat" unicode="" horiz-adv-x="496"
|
||||
d="M440 288c-29.5 0 -53.2998 26.2998 -53.2998 58.7002c0 25 31.7002 75.5 46.2002 97.2998c3.5 5.2998 10.5996 5.2998 14.1992 0c14.5 -21.7998 46.2002 -72.2998 46.2002 -97.2998c0 -32.4004 -23.7998 -58.7002 -53.2998 -58.7002zM248 48
|
||||
c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM378.3 216.3
|
||||
c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
|
||||
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM483.6 269.2c8 -24.2998 12.4004 -50.2002 12.4004 -77.2002c0 -137 -111 -248 -248 -248s-248 111 -248 248s111 248 248 248
|
||||
c45.7002 0 88.4004 -12.5996 125.2 -34.2002c-10.9004 -21.5996 -15.5 -36.2002 -17.2002 -45.7002c-31.2002 20.1006 -68.2002 31.9004 -108 31.9004c-110.3 0 -200 -89.7002 -200 -200s89.7002 -200 200 -200s200 89.7002 200 200
|
||||
c0 22.5 -3.90039 44.0996 -10.7998 64.2998c0.399414 0 21.7998 -2.7998 46.3994 12.9004zM168 258.6c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998
|
||||
c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
|
||||
<glyph glyph-name="grin-hearts" unicode="" horiz-adv-x="496"
|
||||
d="M353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM200.8 192.3
|
||||
l-70.2002 18.1006c-20.3994 5.2998 -31.8994 27 -24.1992 47.1992c6.69922 17.7002 26.6992 26.7002 44.8994 22l7.10059 -1.89941l2 7.09961c5.09961 18.1006 22.8994 30.9004 41.5 27.9004c21.3994 -3.40039 34.3994 -24.2002 28.7998 -44.5l-19.4004 -69.9004
|
||||
c-1.2998 -4.5 -6 -7.2002 -10.5 -6zM389.6 257.6c7.7002 -20.1992 -3.7998 -41.7998 -24.1992 -47.0996l-70.2002 -18.2002c-4.60059 -1.2002 -9.2998 1.5 -10.5 6l-19.4004 69.9004c-5.59961 20.2998 7.40039 41.0996 28.7998 44.5c18.7002 3 36.5 -9.7998 41.5 -27.9004
|
||||
l2 -7.09961l7.10059 1.89941c18.2002 4.7002 38.2002 -4.39941 44.8994 -22zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200
|
||||
s89.7002 -200 200 -200z" />
|
||||
<glyph glyph-name="grin-squint" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.9004 -123.3 80c-1.7002 9.90039 7.7998 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM118.9 184.2c-3.80078 4.39941 -3.90039 11 -0.100586 15.5l33.6006 40.2998
|
||||
l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5c3.89941 4.40039 10.1992 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5zM361.8 181.7
|
||||
l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5.10059 2.90039 11.5 1.90039 15.2998 -2.5c3.80078 -4.5 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5
|
||||
c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5z" />
|
||||
<glyph glyph-name="grin-squint-tears" unicode=""
|
||||
d="M117.1 63.9004c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998
|
||||
c16.8994 16.9004 75.0996 26.9004 100.899 30.6006zM75.9004 105.6c-19.6006 -3.89941 -35.1006 -8.09961 -47.3008 -12.1992c-39.2998 90.5996 -22.0996 199.899 52 274c48.5 48.3994 111.9 72.5996 175.4 72.5996c38.9004 0 77.7998 -9.2002 113.2 -27.4004
|
||||
c-4 -12.1992 -8.2002 -28 -12 -48.2998c-30.4004 17.9004 -65 27.7002 -101.2 27.7002c-53.4004 0 -103.6 -20.7998 -141.4 -58.5996c-61.5996 -61.5 -74.2998 -153.4 -38.6992 -227.801zM428.2 293.2c20.2998 3.89941 36.2002 8 48.5 12
|
||||
c47.8994 -93.2002 32.8994 -210.5 -45.2002 -288.601c-48.5 -48.3994 -111.9 -72.5996 -175.4 -72.5996c-33.6992 0 -67.2998 7 -98.6992 20.5996c4.19922 12.2002 8.2998 27.7002 12.1992 47.2002c26.6006 -12.7998 55.9004 -19.7998 86.4004 -19.7998
|
||||
c53.4004 0 103.6 20.7998 141.4 58.5996c65.6992 65.7002 75.7998 166 30.7998 242.601zM394.9 320.1c-6.30078 -0.899414 -11.7002 4.5 -10.9004 10.9004c3.7002 25.7998 13.7002 84 30.5996 100.9c22 21.8994 57.9004 21.5 80.3008 -0.900391
|
||||
c22.3994 -22.4004 22.7998 -58.4004 0.899414 -80.2998c-16.8994 -16.9004 -75.0996 -26.9004 -100.899 -30.6006zM207.9 211.8c3 -3 4.19922 -7.2998 3.19922 -11.5l-22.5996 -90.5c-1.40039 -5.39941 -6.2002 -9.09961 -11.7002 -9.09961h-0.899414
|
||||
c-5.80078 0.5 -10.5 5.09961 -11 10.8994l-4.80078 52.3008l-52.2998 4.7998c-5.7998 0.5 -10.3994 5.2002 -10.8994 11c-0.400391 5.89941 3.39941 11.2002 9.09961 12.5996l90.5 22.7002c4.2002 1 8.40039 -0.200195 11.4004 -3.2002zM247.6 236.9
|
||||
c-0.0996094 0 -6.39941 -1.80078 -11.3994 3.19922c-3 3 -4.2002 7.30078 -3.2002 11.4004l22.5996 90.5c1.40039 5.7002 7 9.2002 12.6006 9.09961c5.7998 -0.5 10.5 -5.09961 11 -10.8994l4.7998 -52.2998l52.2998 -4.80078c5.7998 -0.5 10.4004 -5.19922 10.9004 -11
|
||||
c0.399414 -5.89941 -3.40039 -11.1992 -9.10059 -12.5996zM299.6 148.4c29.1006 29.0996 53 59.5996 65.3008 83.7998c4.89941 9.2998 17.5996 9.89941 23.3994 1.7002c27.7002 -38.9004 6.10059 -106.9 -30.5996 -143.7s-104.8 -58.2998 -143.7 -30.6006
|
||||
c-8.2998 5.90039 -7.5 18.6006 1.7002 23.4004c24.2002 12.5 54.7998 36.2998 83.8994 65.4004z" />
|
||||
<glyph glyph-name="grin-stars" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM353.6 143.4c10 3.09961 19.3008 -5.5 17.7002 -15.3008
|
||||
c-8 -47.0996 -71.2998 -80 -123.3 -80s-115.4 32.8008 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.3008c26 -8.30078 64.3994 -13.1006 105.6 -13.1006s79.7002 4.7998 105.6 13.1006zM125.7 200.9l6.09961 34.8994l-25.3994 24.6006
|
||||
c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006l34.9004 -5c6.19922 -1 8.7998 -8.69922 4.2998 -13.1992l-25.4004 -24.6006l6 -34.8994c1 -6.2002 -5.39941 -11 -11 -7.90039
|
||||
l-31.2998 16.2998l-31.2998 -16.2998c-5.60059 -3.09961 -12 1.7002 -11 7.90039zM385.4 273.6c6.19922 -1 8.89941 -8.59961 4.39941 -13.1992l-25.3994 -24.6006l6 -34.8994c1 -6.2002 -5.40039 -11 -11 -7.90039l-31.3008 16.2998l-31.2998 -16.2998
|
||||
c-5.59961 -3.09961 -12 1.7002 -11 7.90039l6 34.8994l-25.3994 24.6006c-4.60059 4.59961 -1.90039 12.2998 4.2998 13.1992l34.8994 5l15.5 31.6006c2.90039 5.7998 11 5.7998 13.9004 0l15.5 -31.6006z" />
|
||||
<glyph glyph-name="grin-tears" unicode="" horiz-adv-x="640"
|
||||
d="M117.1 191.9c6.30078 0.899414 11.7002 -4.5 10.9004 -10.9004c-3.7002 -25.7998 -13.7002 -84 -30.5996 -100.9c-22 -21.8994 -57.9004 -21.5 -80.3008 0.900391c-22.3994 22.4004 -22.7998 58.4004 -0.899414 80.2998c16.8994 16.9004 75.0996 26.9004 100.899 30.6006
|
||||
zM623.8 161.3c21.9004 -21.8994 21.5 -57.8994 -0.799805 -80.2002c-22.4004 -22.3994 -58.4004 -22.7998 -80.2998 -0.899414c-16.9004 16.8994 -26.9004 75.0996 -30.6006 100.899c-0.899414 6.30078 4.5 11.7002 10.8008 10.8008
|
||||
c25.7998 -3.7002 84 -13.7002 100.899 -30.6006zM497.2 99.5996c12.3994 -37.2998 25.0996 -43.7998 28.2998 -46.5c-44.5996 -65.7998 -120 -109.1 -205.5 -109.1s-160.9 43.2998 -205.5 109.1c3.09961 2.60059 15.7998 9.10059 28.2998 46.5
|
||||
c33.4004 -63.8994 100.3 -107.6 177.2 -107.6s143.8 43.7002 177.2 107.6zM122.7 223.5c-2.40039 0.299805 -5 2.5 -49.5 -6.90039c12.3994 125.4 118.1 223.4 246.8 223.4s234.4 -98 246.8 -223.5c-44.2998 9.40039 -47.3994 7.2002 -49.5 7
|
||||
c-15.2002 95.2998 -97.7998 168.5 -197.3 168.5s-182.1 -73.2002 -197.3 -168.5zM320 48c-51.9004 0 -115.3 32.9004 -123.3 80c-1.7002 10 7.89941 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996
|
||||
c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-8 -47.0996 -71.3994 -80 -123.3 -80zM450.3 216.3c-3.09961 -0.899414 -7.2002 0.100586 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17
|
||||
c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998zM240 258.6
|
||||
c-12.2998 0 -23.7998 -7.7998 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
|
||||
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996z" />
|
||||
<glyph glyph-name="grin-tongue" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
|
||||
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
|
||||
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
|
||||
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32
|
||||
s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
|
||||
<glyph glyph-name="grin-tongue-squint" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0
|
||||
l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200
|
||||
s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996
|
||||
s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5l-33.6006 -40.2998
|
||||
l33.6006 -40.2998c3.7002 -4.5 3.7002 -11 -0.100586 -15.5c-3.59961 -4.2002 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 3 11.5 1.90039 15.2998 -2.5zM214.2 250.3
|
||||
c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998s-2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7002 -1.7002 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7002 4.5 -3.7002 11 0.100586 15.5
|
||||
c3.89941 4.5 10.2998 5.5 15.2998 2.5z" />
|
||||
<glyph glyph-name="grin-tongue-wink" unicode="" horiz-adv-x="496"
|
||||
d="M152 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
|
||||
c-3.7998 -3.39941 -9.2998 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM328 320c44.2002 0 80 -35.7998 80 -80s-35.7998 -80 -80 -80s-80 35.7998 -80 80s35.7998 80 80 80zM328 192
|
||||
c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM328 264c13.2998 0 24 -10.7002 24 -24s-10.7002 -24 -24 -24s-24 10.7002 -24 24s10.7002 24 24 24zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248z
|
||||
M312 40h0.0996094v43.7998l-17.6992 8.7998c-15.1006 7.60059 -31.5 -1.69922 -34.9004 -16.5l-2.7998 -12.0996c-2.10059 -9.2002 -15.2002 -9.2002 -17.2998 0l-2.80078 12.0996c-3.39941 14.8008 -19.8994 24 -34.8994 16.5l-17.7002 -8.7998v-42.7998
|
||||
c0 -35.2002 28 -64.5 63.0996 -65c35.8008 -0.5 64.9004 28.4004 64.9004 64zM340.2 14.7002c64 33.3994 107.8 100.3 107.8 177.3c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -77 43.7998 -143.9 107.8 -177.3
|
||||
c-2.2002 8.09961 -3.7998 16.5 -3.7998 25.2998v43.5c-14.2002 12.4004 -24.4004 27.5 -27.2998 44.5c-1.7002 10 7.7998 18.4004 17.7002 15.2998c26 -8.2998 64.3994 -13.0996 105.6 -13.0996s79.7002 4.7998 105.6 13.0996c10 3.2002 19.4004 -5.39941 17.7002 -15.2998
|
||||
c-2.89941 -17 -13.0996 -32.0996 -27.2998 -44.5v-43.5c0 -8.7998 -1.59961 -17.2002 -3.7998 -25.2998z" />
|
||||
<glyph glyph-name="grin-wink" unicode="" horiz-adv-x="496"
|
||||
d="M328 268c25.6904 0 55.8799 -16.9199 59.8701 -42.1201c1.72949 -11.0898 -11.3506 -18.2695 -19.8301 -10.8398l-9.5498 8.47949c-14.8105 13.1904 -46.1602 13.1904 -60.9707 0l-9.5498 -8.47949c-8.33008 -7.40039 -21.5801 -0.379883 -19.8301 10.8398
|
||||
c3.98047 25.2002 34.1699 42.1201 59.8604 42.1201zM168 208c-17.6699 0 -32 14.3301 -32 32s14.3301 32 32 32s32 -14.3301 32 -32s-14.3301 -32 -32 -32zM353.55 143.36c10.04 3.13965 19.3906 -5.4502 17.71 -15.3408
|
||||
c-7.92969 -47.1494 -71.3193 -80.0195 -123.26 -80.0195s-115.33 32.8701 -123.26 80.0195c-1.69043 9.9707 7.76953 18.4707 17.71 15.3408c25.9297 -8.31055 64.3994 -13.0605 105.55 -13.0605s79.6201 4.75977 105.55 13.0605zM248 440c136.97 0 248 -111.03 248 -248
|
||||
s-111.03 -248 -248 -248s-248 111.03 -248 248s111.03 248 248 248zM248 -8c110.28 0 200 89.7197 200 200s-89.7197 200 -200 200s-200 -89.7197 -200 -200s89.7197 -200 200 -200z" />
|
||||
<glyph glyph-name="kiss" unicode="" horiz-adv-x="496"
|
||||
d="M168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
|
||||
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
|
||||
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM248 440c137 0 248 -111 248 -248
|
||||
s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z
|
||||
" />
|
||||
<glyph glyph-name="kiss-beam" unicode="" horiz-adv-x="496"
|
||||
d="M168 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
|
||||
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004zM248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8
|
||||
c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM304 140c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5
|
||||
c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002
|
||||
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM328 296
|
||||
c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.299805 -3.7998 -2 -7.19922 -5.59961 -8.2998c-3.10059 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996c-12.3008 0 -23.8008 -7.89941 -31.5 -21.5996l-9.5 -17
|
||||
c-1.80078 -3.2002 -5.80078 -4.7002 -9.30078 -3.7002c-3.59961 1.10059 -5.89941 4.60059 -5.59961 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
|
||||
<glyph glyph-name="kiss-wink-heart" unicode="" horiz-adv-x="504"
|
||||
d="M304 139.5c0 -13 -13.4004 -27.2998 -35.0996 -36.4004c21.7998 -8.69922 35.1992 -23 35.1992 -36c0 -19.1992 -28.6992 -41.5 -71.5 -44h-0.5c-3.69922 0 -7 2.60059 -7.7998 6.2002c-0.899414 3.7998 1.10059 7.7002 4.7002 9.2002l17 7.2002
|
||||
c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.2002c-6 2.59961 -5.7002 12.3994 0 14.7998l17 7.2002c12.9004 5.5 20.7002 13.5 20.7002 21.5s-7.7998 16 -20.7998 21.5l-16.9004 7.19922c-3.59961 1.5 -5.59961 5.40039 -4.7002 9.2002
|
||||
c0.799805 3.7998 4.40039 6.60059 8.2002 6.2002c42.7002 -2.5 71.5 -24.7998 71.5 -44zM374.5 223c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-2.5 -2.2998 -7.90039 -4.7002 -13.7002 -1.59961c-4.39941 2.39941 -6.89941 7.39941 -6.09961 12.3994
|
||||
c3.89941 25.2002 34.2002 42.1006 59.7998 42.1006s55.7998 -16.9004 59.7998 -42.1006c0.799805 -5 -1.7002 -10 -6.09961 -12.3994c-4.40039 -2.40039 -9.90039 -1.7002 -13.7002 1.59961zM136 239.5c0 17.7002 14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32
|
||||
s-32 14.2998 -32 32zM501.1 45.5c9.2002 -23.9004 -4.39941 -49.4004 -28.5 -55.7002l-83 -21.5c-5.39941 -1.39941 -10.8994 1.7998 -12.3994 7.10059l-22.9004 82.5996c-6.59961 24 8.7998 48.5996 34 52.5996c22 3.5 43.1006 -11.5996 49 -33l2.2998 -8.39941
|
||||
l8.40039 2.2002c21.5996 5.59961 45.0996 -5.10059 53.0996 -25.9004zM334 11.7002c17.7002 -64 10.9004 -39.5 13.4004 -46.7998c-30.5 -13.4004 -64 -20.9004 -99.4004 -20.9004c-137 0 -248 111 -248 248s111 248 248 248s248 -111 247.9 -248
|
||||
c0 -31.7998 -6.2002 -62.0996 -17.1006 -90c-6 1.5 -12.2002 2.7998 -18.5996 2.90039c-5.60059 9.69922 -13.6006 17.5 -22.6006 23.8994c6.7002 19.9004 10.4004 41.1006 10.4004 63.2002c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200
|
||||
c30.7998 0 59.9004 7.2002 86 19.7002z" />
|
||||
<glyph glyph-name="laugh" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM168 224
|
||||
c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="laugh-beam" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 296c23.7998 0 52.7002 -29.2998 55.7998 -71.4004c0.700195 -8.5 -10.7998 -11.8994 -14.8994 -4.5
|
||||
l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006c-12.3008 0 -23.8008 -7.90039 -31.5 -21.6006l-9.5 -17c-4.10059 -7.39941 -15.6006 -4.09961 -14.9004 4.5c3.2998 42.1006 32.2002 71.4004 56 71.4004zM127 220.1c-4.2002 -7.39941 -15.7002 -4 -15.0996 4.5
|
||||
c3.2998 42.1006 32.1992 71.4004 56 71.4004c23.7998 0 52.6992 -29.2998 56 -71.4004c0.699219 -8.5 -10.8008 -11.8994 -14.9004 -4.5l-9.5 17c-7.7002 13.7002 -19.2002 21.6006 -31.5 21.6006s-23.7998 -7.90039 -31.5 -21.6006zM362.4 160c8.19922 0 14.5 -7 13.5 -15
|
||||
c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="laugh-squint" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM343.6 252l33.6006 -40.2998c8.59961 -10.4004 -3.90039 -24.7998 -15.4004 -18l-80 48
|
||||
c-7.7998 4.7002 -7.7998 15.8994 0 20.5996l80 48c11.6006 6.7998 24 -7.7002 15.4004 -18zM134.2 193.7c-11.6006 -6.7998 -24.1006 7.59961 -15.4004 18l33.6006 40.2998l-33.6006 40.2998c-8.59961 10.2998 3.7998 24.9004 15.4004 18l80 -48
|
||||
c7.7998 -4.7002 7.7998 -15.8994 0 -20.5996zM362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="laugh-wink" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM389.4 50.5996c37.7998 37.8008 58.5996 88 58.5996 141.4s-20.7998 103.6 -58.5996 141.4c-37.8008 37.7998 -88 58.5996 -141.4 58.5996s-103.6 -20.7998 -141.4 -58.5996
|
||||
c-37.7998 -37.8008 -58.5996 -88 -58.5996 -141.4s20.7998 -103.6 58.5996 -141.4c37.8008 -37.7998 88 -58.5996 141.4 -58.5996s103.6 20.7998 141.4 58.5996zM328 284c25.7002 0 55.9004 -16.9004 59.7002 -42.0996c1.7998 -11.1006 -11.2998 -18.2002 -19.7998 -10.8008
|
||||
l-9.5 8.5c-14.8008 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5c-8.30078 -7.39941 -21.5 -0.399414 -19.8008 10.8008c4 25.1992 34.2002 42.0996 59.9004 42.0996zM168 224c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32s-14.2998 -32 -32 -32z
|
||||
M362.4 160c8.19922 0 14.5 -7 13.5 -15c-7.5 -59.2002 -58.9004 -105 -121.101 -105h-13.5996c-62.2002 0 -113.601 45.7998 -121.101 105c-1 8 5.30078 15 13.5 15h228.801z" />
|
||||
<glyph glyph-name="meh-blank" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM168 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32
|
||||
s-32 14.2998 -32 32s14.2998 32 32 32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
|
||||
<glyph glyph-name="meh-rolling-eyes" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM336 296c39.7998 0 72 -32.2002 72 -72s-32.2002 -72 -72 -72
|
||||
s-72 32.2002 -72 72s32.2002 72 72 72zM336 184c22.0996 0 40 17.9004 40 40c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998
|
||||
c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998c0 -22.0996 17.9004 -40 40 -40zM232 224c0 -39.7998 -32.2002 -72 -72 -72s-72 32.2002 -72 72s32.2002 72 72 72s72 -32.2002 72 -72zM120 224c0 -22.0996 17.9004 -40 40 -40s40 17.9004 40 40
|
||||
c0 13.5996 -7.2998 25.0996 -17.7002 32.2998c1 -2.59961 1.7002 -5.39941 1.7002 -8.2998c0 -13.2998 -10.7002 -24 -24 -24s-24 10.7002 -24 24c0 3 0.700195 5.7002 1.7002 8.2998c-10.4004 -7.2002 -17.7002 -18.7002 -17.7002 -32.2998zM312 96
|
||||
c13.2002 0 24 -10.7998 24 -24s-10.7998 -24 -24 -24h-128c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24h128z" />
|
||||
<glyph glyph-name="sad-cry" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM392 53.5996c34.5996 35.9004 56 84.7002 56 138.4c0 110.3 -89.7002 200 -200 200s-200 -89.7002 -200 -200c0 -53.7002 21.4004 -102.4 56 -138.4v114.4
|
||||
c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-151.4c28.5 -15.5996 61.2002 -24.5996 96 -24.5996s67.5 9 96 24.5996v151.4c0 13.2002 10.7998 24 24 24s24 -10.7998 24 -24v-114.4zM205.8 213.5c-5.7998 -3.2002 -11.2002 -0.700195 -13.7002 1.59961l-9.5 8.5
|
||||
c-14.7998 13.2002 -46.1992 13.2002 -61 0l-9.5 -8.5c-3.7998 -3.39941 -9.2998 -4 -13.6992 -1.59961c-4.40039 2.40039 -6.90039 7.40039 -6.10059 12.4004c3.90039 25.1992 34.2002 42.0996 59.7998 42.0996c25.6006 0 55.8008 -16.9004 59.8008 -42.0996
|
||||
c0.799805 -5 -1.7002 -10 -6.10059 -12.4004zM344 268c25.7002 0 55.9004 -16.9004 59.7998 -42.0996c0.799805 -5 -1.7002 -10 -6.09961 -12.4004c-5.7002 -3.09961 -11.2002 -0.599609 -13.7002 1.59961l-9.5 8.5c-14.7998 13.2002 -46.2002 13.2002 -61 0l-9.5 -8.5
|
||||
c-3.7998 -3.39941 -9.2002 -4 -13.7002 -1.59961c-4.39941 2.40039 -6.89941 7.40039 -6.09961 12.4004c3.89941 25.1992 34.0996 42.0996 59.7998 42.0996zM248 176c30.9004 0 56 -28.7002 56 -64s-25.0996 -64 -56 -64s-56 28.7002 -56 64s25.0996 64 56 64z" />
|
||||
<glyph glyph-name="sad-tear" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM256 144c38.0996 0 74 -16.7998 98.5 -46.0996
|
||||
c8.5 -10.2002 7.09961 -25.3008 -3.09961 -33.8008c-10.6006 -8.7998 -25.7002 -6.69922 -33.8008 3.10059c-15.2998 18.2998 -37.7998 28.7998 -61.5996 28.7998c-13.2002 0 -24 10.7998 -24 24s10.7998 24 24 24zM168 208c-17.7002 0 -32 14.2998 -32 32s14.2998 32 32 32
|
||||
s32 -14.2998 32 -32s-14.2998 -32 -32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM162.4 173.2c2.7998 3.7002 8.39941 3.7002 11.1992 0c11.4004 -15.2998 36.4004 -50.6006 36.4004 -68.1006
|
||||
c0 -22.6992 -18.7998 -41.0996 -42 -41.0996s-42 18.4004 -42 41.0996c0 17.5 25 52.8008 36.4004 68.1006z" />
|
||||
<glyph glyph-name="smile-beam" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM332 135.4c8.5 10.1992 23.5996 11.5 33.7998 3.09961
|
||||
c10.2002 -8.5 11.6006 -23.5996 3.10059 -33.7998c-30 -36 -74.1006 -56.6006 -120.9 -56.6006s-90.9004 20.6006 -120.9 56.6006c-8.39941 10.2002 -7.09961 25.2998 3.10059 33.7998c10.2002 8.40039 25.2998 7.09961 33.7998 -3.09961
|
||||
c20.7998 -25.1006 51.5 -39.4004 84 -39.4004s63.2002 14.4004 84 39.4004zM136.5 237l-9.5 -17c-1.90039 -3.2002 -5.90039 -4.7998 -9.2998 -3.7002c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004s52.7002 -29.2998 56 -71.4004
|
||||
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996zM328 296c23.7998 0 52.7002 -29.2998 56 -71.4004
|
||||
c0.299805 -3.7998 -2.09961 -7.19922 -5.7002 -8.2998c-3.09961 -1 -7.2002 0 -9.2998 3.7002l-9.5 17c-7.7002 13.7002 -19.2002 21.5996 -31.5 21.5996s-23.7998 -7.89941 -31.5 -21.5996l-9.5 -17c-1.90039 -3.2002 -5.7998 -4.7998 -9.2998 -3.7002
|
||||
c-3.60059 1.10059 -6 4.60059 -5.7002 8.2998c3.2998 42.1006 32.2002 71.4004 56 71.4004z" />
|
||||
<glyph glyph-name="surprise" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM248 168c35.2998 0 64 -28.7002 64 -64s-28.7002 -64 -64 -64
|
||||
s-64 28.7002 -64 64s28.7002 64 64 64zM200 240c0 -17.7002 -14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32s32 -14.2998 32 -32zM328 272c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32z" />
|
||||
<glyph glyph-name="tired" unicode="" horiz-adv-x="496"
|
||||
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM248 -8c110.3 0 200 89.7002 200 200s-89.7002 200 -200 200s-200 -89.7002 -200 -200s89.7002 -200 200 -200zM377.1 295.8c3.80078 -4.39941 3.90039 -11 0.100586 -15.5
|
||||
l-33.6006 -40.2998l33.6006 -40.2998c3.7998 -4.5 3.7002 -11 -0.100586 -15.5c-3.5 -4.10059 -9.89941 -5.7002 -15.2998 -2.5l-80 48c-3.59961 2.2002 -5.7998 6.09961 -5.7998 10.2998s2.2002 8.09961 5.7998 10.2998l80 48c5 2.90039 11.5 1.90039 15.2998 -2.5z
|
||||
M220 240c0 -4.2002 -2.2002 -8.09961 -5.7998 -10.2998l-80 -48c-5.40039 -3.2002 -11.7998 -1.60059 -15.2998 2.5c-3.80078 4.5 -3.90039 11 -0.100586 15.5l33.6006 40.2998l-33.6006 40.2998c-3.7998 4.5 -3.7002 11 0.100586 15.5
|
||||
c3.7998 4.40039 10.2998 5.5 15.2998 2.5l80 -48c3.59961 -2.2002 5.7998 -6.09961 5.7998 -10.2998zM248 176c45.4004 0 100.9 -38.2998 107.8 -93.2998c1.5 -11.9004 -7 -21.6006 -15.5 -17.9004c-22.7002 9.7002 -56.2998 15.2002 -92.2998 15.2002
|
||||
s-69.5996 -5.5 -92.2998 -15.2002c-8.60059 -3.7002 -17 6.10059 -15.5 17.9004c6.89941 55 62.3994 93.2998 107.8 93.2998z" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 896 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,148 @@
|
||||
|
||||
( function( api, $, _ ) {
|
||||
wp.customize.bind( 'preview-ready', function() {
|
||||
});// 'preview-ready'
|
||||
|
||||
|
||||
|
||||
|
||||
if ( serverPreviewParams && ! serverPreviewParams.preview_ready_event_exists ) {
|
||||
try { api.czr_preview = new api.CZR_preview(); } catch( _er_ ) {
|
||||
console.log( "new api.CZR_preview() => error => ", _er_ );
|
||||
}
|
||||
}
|
||||
else {
|
||||
api.bind( 'preview-ready', function(){
|
||||
api.preview.bind( 'active', function() {
|
||||
try { api.czr_preview = new api.CZR_preview(); } catch( _er_ ) {
|
||||
console.log( "new api.CZR_preview() => error => ", _er_ );
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var czrPreviewConstructor = {
|
||||
setting_cbs : {},
|
||||
subsetting_cbs : {},//nested sub settings
|
||||
input_cbs : {},
|
||||
initialize: function() {
|
||||
var self = this;
|
||||
this.pre_setting_cbs = _.extend( self.pre_setting_cbs, self.getPreSettingCbs() );
|
||||
this.setting_cbs = _.extend( self.setting_cbs, self.getSettingCbs() );
|
||||
this.subsetting_cbs = _.extend( self.subsetting_cbs, self.getSubSettingCbs() );
|
||||
this.input_cbs = _.extend( self.input_cbs, self.getInputCbs() );
|
||||
|
||||
this.syncData();
|
||||
|
||||
this.addCbs();
|
||||
$( 'body' ).removeClass( 'wp-customizer-unloading' );
|
||||
},
|
||||
getPreSettingCbs : function() { return {}; },
|
||||
getSettingCbs : function() { return {}; },
|
||||
getSubSettingCbs : function() { return {}; },
|
||||
getInputCbs : function() { return {}; },
|
||||
syncData : function() {
|
||||
api.preview.send( 'czr-query-data-ready', api.settings.czr_wpQueryInfos );
|
||||
api.preview.send(
|
||||
'czr-partial-refresh-data',
|
||||
typeof( undefined ) === typeof( _customizePartialRefreshExports ) ? {} : _customizePartialRefreshExports.partials
|
||||
);
|
||||
},
|
||||
|
||||
addCbs : function() {
|
||||
var self = this;
|
||||
api.preview.bind( 'pre_setting', function( args ) {
|
||||
args = args || {};
|
||||
var _setId = args.set_id;
|
||||
if ( ! api.has( self._build_setId( _setId ) ) )
|
||||
return;
|
||||
var _opt_name = self._get_option_name( args.set_id );
|
||||
if ( ! _.has( self.pre_setting_cbs, _opt_name ) || ! _.isFunction( self.pre_setting_cbs[ _opt_name ] ) )
|
||||
return;
|
||||
self.pre_setting_cbs[ _opt_name ]( args );
|
||||
});
|
||||
_.each( self.setting_cbs, function( _cb, _setId ) {
|
||||
if ( ! api.has( self._build_setId( _setId ) ) )
|
||||
return;
|
||||
if ( _.isFunction( self.setting_cbs[ _setId ] ) ) {
|
||||
api( self._build_setId(_setId) ).bind( self.setting_cbs[ _setId ] );
|
||||
}
|
||||
} );
|
||||
api.preview.bind( 'sub_setting', function( args ) {
|
||||
var _opt_name = self._get_option_name( args.set_id );
|
||||
if ( ! _.has(self.subsetting_cbs, _opt_name) )
|
||||
return;
|
||||
if ( ! _.has( self.subsetting_cbs[ _opt_name ], args.changed_prop ) )
|
||||
return;
|
||||
self.subsetting_cbs[ _opt_name ][ args.changed_prop ]( args );
|
||||
});
|
||||
api.preview.bind( 'czr_input', function( args ) {
|
||||
var _defaults = {
|
||||
set_id : '',
|
||||
module_id : '',
|
||||
item_id : '',
|
||||
input_id : '',
|
||||
value : null
|
||||
};
|
||||
args = _.extend ( _defaults, args );
|
||||
var _opt_name = self._get_option_name( args.set_id );
|
||||
if ( ! _.has( self.input_cbs, _opt_name ) )
|
||||
return;
|
||||
if ( ! _.has( self.input_cbs[ _opt_name ], args.input_id ) )
|
||||
return;
|
||||
self.input_cbs[ _opt_name ][ args.input_id ]( args );
|
||||
});
|
||||
api.selectiveRefresh.bind( 'partial-content-rendered', function( params ) {
|
||||
if ( ! _.has( params, 'partial' ) || ! _.has( params.partial, 'id' ) )
|
||||
return;
|
||||
var _shortOptName = params.partial.id;
|
||||
api.preview.send( 'czr-partial-refresh-done', { set_id : self._build_setId( params.partial.id ) } );
|
||||
});
|
||||
},
|
||||
_build_setId : function ( name ) {
|
||||
var self = this;
|
||||
if ( _.isEmpty( window.themeServerPreviewParams ) )
|
||||
return name;
|
||||
if ( ! _.isArray( themeServerPreviewParams.wpBuiltinSettings ) || _.contains( themeServerPreviewParams.wpBuiltinSettings, name ) )
|
||||
return name;
|
||||
|
||||
var themeOptionsPrefix = themeServerPreviewParams.themeOptionsPrefix;
|
||||
if ( _.isEmpty( themeOptionsPrefix ) )
|
||||
return name;
|
||||
|
||||
return -1 == name.indexOf( themeOptionsPrefix ) ? [ themeOptionsPrefix + '[' , name , ']' ].join('') : name;
|
||||
},
|
||||
|
||||
_get_option_name : function( name ) {
|
||||
if ( _.isEmpty( window.themeServerPreviewParams ) )
|
||||
return name;
|
||||
|
||||
var themeOptionsPrefix = themeServerPreviewParams.themeOptionsPrefix;
|
||||
if ( _.isEmpty( themeOptionsPrefix ) )
|
||||
return name;
|
||||
|
||||
var self = this;
|
||||
return name.replace(/\[|\]/g, '').replace( themeOptionsPrefix, '');
|
||||
},
|
||||
_is_external : function( _href ) {
|
||||
if ( 'string' !== typeof(_href) )
|
||||
return false;
|
||||
|
||||
var _thisHref = _href.trim(),
|
||||
_main_domain = (location.host).split('.').slice(-2).join('.'),
|
||||
_reg = new RegExp( _main_domain );
|
||||
|
||||
if ( _thisHref !== '' && _thisHref != '#' && _isValidURL( _thisHref ) )
|
||||
return !_reg.test( _thisHref );
|
||||
return false;
|
||||
},
|
||||
_isValidURL : function(_url){
|
||||
var _pattern = /(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
||||
return _pattern.test( _url );
|
||||
}
|
||||
};//czrPreviewConstructor
|
||||
|
||||
api.CZR_preview = api.Class.extend( czrPreviewConstructor );
|
||||
|
||||
|
||||
} )( wp.customize, jQuery, _ );
|
||||
@@ -0,0 +1 @@
|
||||
!function(r,t,s){if(wp.customize.bind("preview-ready",function(){}),serverPreviewParams&&!serverPreviewParams.preview_ready_event_exists)try{r.czr_preview=new r.CZR_preview}catch(e){console.log("new api.CZR_preview() => error => ",e)}else r.bind("preview-ready",function(){r.preview.bind("active",function(){try{r.czr_preview=new r.CZR_preview}catch(e){console.log("new api.CZR_preview() => error => ",e)}})});var e={setting_cbs:{},subsetting_cbs:{},input_cbs:{},initialize:function(){var e=this;this.pre_setting_cbs=s.extend(e.pre_setting_cbs,e.getPreSettingCbs()),this.setting_cbs=s.extend(e.setting_cbs,e.getSettingCbs()),this.subsetting_cbs=s.extend(e.subsetting_cbs,e.getSubSettingCbs()),this.input_cbs=s.extend(e.input_cbs,e.getInputCbs()),this.syncData(),this.addCbs(),t("body").removeClass("wp-customizer-unloading")},getPreSettingCbs:function(){return{}},getSettingCbs:function(){return{}},getSubSettingCbs:function(){return{}},getInputCbs:function(){return{}},syncData:function(){r.preview.send("czr-query-data-ready",r.settings.czr_wpQueryInfos),r.preview.send("czr-partial-refresh-data","undefined"==typeof _customizePartialRefreshExports?{}:_customizePartialRefreshExports.partials)},addCbs:function(){var n=this;r.preview.bind("pre_setting",function(e){var t=(e=e||{}).set_id;if(r.has(n._build_setId(t))){var i=n._get_option_name(e.set_id);s.has(n.pre_setting_cbs,i)&&s.isFunction(n.pre_setting_cbs[i])&&n.pre_setting_cbs[i](e)}}),s.each(n.setting_cbs,function(e,t){r.has(n._build_setId(t))&&s.isFunction(n.setting_cbs[t])&&r(n._build_setId(t)).bind(n.setting_cbs[t])}),r.preview.bind("sub_setting",function(e){var t=n._get_option_name(e.set_id);s.has(n.subsetting_cbs,t)&&s.has(n.subsetting_cbs[t],e.changed_prop)&&n.subsetting_cbs[t][e.changed_prop](e)}),r.preview.bind("czr_input",function(e){e=s.extend({set_id:"",module_id:"",item_id:"",input_id:"",value:null},e);var t=n._get_option_name(e.set_id);s.has(n.input_cbs,t)&&s.has(n.input_cbs[t],e.input_id)&&n.input_cbs[t][e.input_id](e)}),r.selectiveRefresh.bind("partial-content-rendered",function(e){if(s.has(e,"partial")&&s.has(e.partial,"id")){e.partial.id;r.preview.send("czr-partial-refresh-done",{set_id:n._build_setId(e.partial.id)})}})},_build_setId:function(e){if(s.isEmpty(window.themeServerPreviewParams))return e;if(!s.isArray(themeServerPreviewParams.wpBuiltinSettings)||s.contains(themeServerPreviewParams.wpBuiltinSettings,e))return e;var t=themeServerPreviewParams.themeOptionsPrefix;return s.isEmpty(t)?e:-1==e.indexOf(t)?[t+"[",e,"]"].join(""):e},_get_option_name:function(e){if(s.isEmpty(window.themeServerPreviewParams))return e;var t=themeServerPreviewParams.themeOptionsPrefix;if(s.isEmpty(t))return e;return e.replace(/\[|\]/g,"").replace(t,"")},_is_external:function(e){if("string"!=typeof e)return!1;var t=e.trim(),i=location.host.split(".").slice(-2).join("."),n=new RegExp(i);return!(""===t||"#"==t||!_isValidURL(t))&&!n.test(t)},_isValidURL:function(e){return/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(e)}};r.CZR_preview=r.Class.extend(e)}(wp.customize,jQuery,_);
|
||||
@@ -0,0 +1,556 @@
|
||||
<?php
|
||||
namespace Nimble;
|
||||
if ( did_action('nimble_skope_loaded') ) {
|
||||
if ( ( defined( 'CZR_DEV' ) && CZR_DEV ) || ( defined( 'NIMBLE_DEV' ) && NIMBLE_DEV ) ) {
|
||||
error_log( __FILE__ . ' => The skope has already been loaded' );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the namsepace as a global so we can use it when fired from another theme/plugin using the fmk
|
||||
global $czr_skope_namespace;
|
||||
$czr_skope_namespace = __NAMESPACE__ . '\\';
|
||||
|
||||
do_action( 'nimble_skope_loaded' );
|
||||
|
||||
//Creates a new instance
|
||||
function Flat_Skop_Base( $params = array() ) {
|
||||
return Flat_Skop_Base::skp_get_instance( $params );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// <DEFINITIONS>
|
||||
// THE SKOPE MODEL
|
||||
function skp_get_default_skope_model() {
|
||||
return array(
|
||||
'title' => '',
|
||||
'long_title' => '',
|
||||
'ctx_title' => '',
|
||||
'id' => '',
|
||||
'skope' => '',
|
||||
//'level' => '',
|
||||
'obj_id' => '',
|
||||
'skope_id' => '',
|
||||
'values' => ''
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// those contexts have no group
|
||||
function skp_get_no_group_skope_list() {
|
||||
return array( 'home', 'search', '404', 'date' );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// </DEFINITIONS>
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// HELPERS
|
||||
|
||||
function skp_trim_text( $text, $text_length, $more ) {
|
||||
if ( !$text )
|
||||
return '';
|
||||
|
||||
$text = trim( strip_tags( $text ) );
|
||||
|
||||
if ( !$text_length )
|
||||
return $text;
|
||||
|
||||
$end_substr = $_text_length = strlen( $text );
|
||||
|
||||
if ( $_text_length > $text_length ){
|
||||
$end_substr = strpos( $text, ' ' , $text_length);
|
||||
$end_substr = ( $end_substr !== FALSE ) ? $end_substr : $text_length;
|
||||
$text = substr( $text , 0 , $end_substr );
|
||||
}
|
||||
return ( ( $end_substr < $text_length ) && $more ) ? $text : $text . ' ' .$more ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// SKOPE HELPERS
|
||||
/**
|
||||
* Return the current skope
|
||||
* Front / Back agnostic.
|
||||
* @param $_requesting_wot is a string with the following possible values : 'meta_type' (like post) , 'type' (like page), 'id' (like page id)
|
||||
* @param $_return_string string param stating if the return value should be a string or an array
|
||||
* @param $requested_parts is an array of parts looking like
|
||||
* Array
|
||||
* (
|
||||
* [meta_type] => post
|
||||
* [type] => page
|
||||
* [obj_id] => 9
|
||||
* )
|
||||
* USE CASE when $requested_parts is passed : when a post gets deleted, we need to clean any skope posts associated. That's when we invoke skp_get_skope( null, true, $requested_parts )
|
||||
* @return a string of all concatenated ctx parts (default) 0R an array of the ctx parts
|
||||
*/
|
||||
function skp_get_skope( $_requesting_wot = null, $_return_string = true, $requested_parts = array() ) {
|
||||
//skope builder from the wp $query
|
||||
//=> returns :
|
||||
// the meta_type : post, tax, user
|
||||
// the type : post_type, taxonomy name, author
|
||||
// the id : post id, term id, user id
|
||||
|
||||
// if $parts are provided, use them.
|
||||
// Note that the value of skp_get_query_skope() is cached when get the first time for better performance
|
||||
$parts = ( is_array( $requested_parts ) && !empty( $requested_parts ) ) ? $requested_parts : skp_get_query_skope();
|
||||
|
||||
// error_log( '<SKOPE PARTS>' );
|
||||
// error_log( print_r( $parts, true ) );
|
||||
// error_log( '</SKOPE PARTS>' );
|
||||
|
||||
$_return = array();
|
||||
$meta_type = $type = $obj_id = false;
|
||||
|
||||
if ( is_array( $parts ) && !empty( $parts ) ) {
|
||||
$meta_type = isset( $parts['meta_type'] ) ? $parts['meta_type'] : false;
|
||||
$type = isset( $parts['type'] ) ? $parts['type'] : false;
|
||||
$obj_id = isset( $parts['obj_id'] ) ? $parts['obj_id'] : false;
|
||||
}
|
||||
|
||||
switch ( $_requesting_wot ) {
|
||||
case 'meta_type':
|
||||
if ( false !== $meta_type ) {
|
||||
$_return = array( "meta_type" => "{$meta_type}" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'type':
|
||||
if ( false !== $type ) {
|
||||
$_return = array( "type" => "{$type}" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'id':
|
||||
if ( false !== $obj_id ) {
|
||||
$_return = array( "id" => "{$obj_id}" );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//LOCAL
|
||||
//here we don't check if there's a type this is the case where there must be one when a meta type (post, tax, user) is defined.
|
||||
//typically the skope will look like post_page_25
|
||||
if ( false !== $meta_type && false !== $obj_id ) {
|
||||
$_return = array( "meta_type" => "{$meta_type}" , "type" => "{$type}", "id" => "{$obj_id}" );
|
||||
}
|
||||
//GROUP
|
||||
else if ( false !== $meta_type && !$obj_id ) {
|
||||
$_return = array( "meta_type" => "{$meta_type}", "type" => "{$type}" );
|
||||
}
|
||||
//LOCAL WITH NO GROUP : home ( when home displays "Your latests posts" ) , 404, search, date, post type archive
|
||||
else if ( false !== $obj_id ) {
|
||||
$_return = array( "id" => "{$obj_id}" );
|
||||
}
|
||||
else {
|
||||
// don't print the skope error log if not in dev mode
|
||||
// fixes : https://github.com/presscustomizr/czr-skope/issues/1
|
||||
if ( defined( 'NIMBLE_DEV' ) && NIMBLE_DEV ) {
|
||||
// the favicon request break skope building, so skip this case
|
||||
// see https://github.com/presscustomizr/nimble-builder/issues/658
|
||||
if ( '/favicon.ico' !== $_SERVER['REQUEST_URI'] ) {
|
||||
error_log( __FUNCTION__ . ' error when building the local skope, no object_id provided.');
|
||||
error_log( print_r( $parts, true) );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//return the parts array if not a string requested
|
||||
if ( !$_return_string ) {
|
||||
return $_return;
|
||||
}
|
||||
|
||||
//don't go further if not an array or empty
|
||||
if ( !is_array( $_return ) || ( is_array( $_return ) && empty( $_return ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//if a specific part of the ctx is requested, don't concatenate
|
||||
//return the part if exists
|
||||
if ( !is_null( $_requesting_wot ) ) {
|
||||
return isset( $_return[ $_requesting_wot ] ) ? $_return[ $_requesting_wot ] : '';
|
||||
}
|
||||
|
||||
//generate the ctx string from the array of ctx_parts
|
||||
$_concat = "";
|
||||
foreach ( $_return as $_key => $_part ) {
|
||||
if ( empty( $_concat) ) {
|
||||
$_concat .= $_part;
|
||||
} else {
|
||||
$_concat .= '_'. $_part;
|
||||
}
|
||||
}
|
||||
return $_concat;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* skope builder from the wp $query
|
||||
* !!has to be fired after 'template_redirect'
|
||||
* Used on front ( not customizing preview ? => @todo make sure of this )
|
||||
* @return array of ctx parts
|
||||
*/
|
||||
function skp_get_query_skope() {
|
||||
//don't call get_queried_object if the $query is not defined yet
|
||||
global $wp_the_query;
|
||||
if ( !isset( $wp_the_query ) || empty( $wp_the_query ) ) {
|
||||
return array();
|
||||
}
|
||||
// is it cached already ?
|
||||
if ( !empty( Flat_Skop_Base()->query_skope ) ) {
|
||||
return Flat_Skop_Base()->query_skope;
|
||||
}
|
||||
|
||||
$queried_object = get_queried_object();
|
||||
|
||||
// error_log( '<GET QUERIED OBJECT>' . gettype( $queried_object ) );
|
||||
// error_log( print_r( $wp_the_query , true ) );
|
||||
// error_log( '</GET QUERIED OBJECT>' );
|
||||
|
||||
$meta_type = $type = $obj_id = false;
|
||||
|
||||
// The queried object is NULL on
|
||||
// - home when displaying the latest posts
|
||||
// - date archives
|
||||
// - 404 page
|
||||
// - search page
|
||||
if ( !is_null( $queried_object ) && is_object( $queried_object ) ) {
|
||||
//post, custom post types, page
|
||||
if ( isset($queried_object->post_type) ) {
|
||||
$meta_type = 'post';
|
||||
$type = $queried_object->post_type;
|
||||
$obj_id = $queried_object->ID;
|
||||
}
|
||||
|
||||
//taxinomies : tags, categories, custom tax type
|
||||
if ( isset($queried_object->taxonomy) && isset($queried_object->term_id) ) {
|
||||
$meta_type = 'tax';
|
||||
$type = $queried_object->taxonomy;
|
||||
$obj_id = $queried_object->term_id;
|
||||
}
|
||||
}
|
||||
|
||||
//author archive page
|
||||
if ( is_author() ) {
|
||||
$meta_type = 'user';
|
||||
$type = 'author';
|
||||
$obj_id = $wp_the_query->get( 'author' );
|
||||
}
|
||||
|
||||
//SKOPES WITH NO GROUPS
|
||||
//post type archive object
|
||||
if ( is_post_type_archive() ) {
|
||||
$obj_id = 'post_type_archive' . '_'. $wp_the_query->get( 'post_type' );
|
||||
}
|
||||
if ( is_404() ) {
|
||||
$obj_id = '404';
|
||||
}
|
||||
if ( is_search() ) {
|
||||
$obj_id = 'search';
|
||||
}
|
||||
if ( is_date() ) {
|
||||
$obj_id = 'date';
|
||||
}
|
||||
|
||||
if ( skp_is_real_home() ) {
|
||||
$obj_id = 'home';
|
||||
// December 2018
|
||||
// when the home page is a page, the skope now includes the page id, instead of being generic as it was since then : skp__post_page_home
|
||||
// This has been introduced to facilitate the compatibility of Nimble Builder with multilanguage plugins like polylang
|
||||
// => Allows user to create a different home page for each languages
|
||||
//
|
||||
// To summarize,
|
||||
// Before dec 2018 :
|
||||
// - home page is blog page => skope_id = skp___home
|
||||
// - home page is page => skope_id = skp__post_page_home
|
||||
//
|
||||
// After Dec 2018
|
||||
// - hope page is blog page => skope_id is unchanged = skp__home
|
||||
// - home page is a page => skope_id is changed to = skp__post_page_{$static_home_page_id}
|
||||
//
|
||||
// This means that if Nimble sections, or any other contextualizations had been made on home when 'page' === get_option( 'show_on_front' ),
|
||||
// for which the corresponding skope_id was skp__post_page_home,
|
||||
// those settings have to be copied in the skp__post_page_{$static_home_page_id} skope settings
|
||||
|
||||
// If we are on the real home page, but displaying a static page then set the static page id as obj_id
|
||||
if ( !is_home() && 'page' === get_option( 'show_on_front' ) ) {
|
||||
$home_page_id = get_option( 'page_on_front' );
|
||||
if ( 0 < $home_page_id ) {
|
||||
$obj_id = $home_page_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cache now
|
||||
if ( did_action( 'wp' ) ) {
|
||||
Flat_Skop_Base()->query_skope = apply_filters( 'skp_get_query_skope' , array( 'meta_type' => $meta_type , 'type' => $type , 'obj_id' => $obj_id ), $queried_object );
|
||||
}
|
||||
|
||||
return Flat_Skop_Base()->query_skope;
|
||||
}
|
||||
|
||||
|
||||
//@return the skope prefix used both when customizing and on front
|
||||
function skp_get_skope_id( $level = 'local' ) {
|
||||
// CACHE THE SKOPE WHEN 'wp' DONE
|
||||
// the skope id is used when filtering the options, called hundreds of times.
|
||||
// We get higher performances with a cached value instead of using the skp_get_skope_id() function on each call.
|
||||
$new_skope_ids = array( 'local' => '_skope_not_set_', 'group' => '_skope_not_set_' );
|
||||
if ( did_action( 'wp' ) ) {
|
||||
if ( empty( Flat_Skop_Base()->current_skope_ids ) ) {
|
||||
$new_skope_ids['local'] = skp_build_skope_id( array( 'skope_string' => skp_get_skope(), 'skope_level' => 'local' ) );
|
||||
$new_skope_ids['group'] = skp_build_skope_id( array( 'skope_level' => 'group' ) );
|
||||
|
||||
Flat_Skop_Base()->current_skope_ids = $new_skope_ids;
|
||||
|
||||
$skope_id_to_return = $new_skope_ids[ $level ];
|
||||
// error_log('<SKOPE ID cached in skp_get_skope_id>');
|
||||
// error_log( print_r( $new_skope_ids, true ) );
|
||||
// error_log('</SKOPE ID cached in skp_get_skope_id>');
|
||||
} else {
|
||||
$new_skope_ids = Flat_Skop_Base()->current_skope_ids;
|
||||
$skope_id_to_return = $new_skope_ids[ $level ];
|
||||
}
|
||||
} else {
|
||||
$skope_id_to_return = array_key_exists( $level, $new_skope_ids ) ? $new_skope_ids[ $level ] : '_skope_not_set_';
|
||||
}
|
||||
// if ( !(bool)did_action( 'wp' ) ) {
|
||||
// sek_error_log('ACTION WP NOT FIRED', did_action('wp'));
|
||||
// }
|
||||
// Jan 2021, while working on https://github.com/presscustomizr/nimble-builder-pro/issues/81
|
||||
// when customizing and firing this function during ajax calls, the check for did_action('wp') will return 0.
|
||||
// => which will lead to skope_id set to '_skope_not_set_'
|
||||
// in order to prevent this, let's get the skope_id value from the customizer posted value when available.
|
||||
if ( skp_is_customizing() && '_skope_not_set_' === $skope_id_to_return && 'local' === $level && !empty($_POST['local_skope_id']) ) {
|
||||
$skope_id_to_return = sanitize_text_field($_POST['local_skope_id']);
|
||||
}
|
||||
// Feb 2021 => added for https://github.com/presscustomizr/nimble-builder/issues/478
|
||||
if ( skp_is_customizing() && '_skope_not_set_' === $skope_id_to_return && 'group' === $level && !empty($_POST['group_skope_id']) ) {
|
||||
$skope_id_to_return = sanitize_text_field($_POST['group_skope_id']);
|
||||
}
|
||||
|
||||
$skope_id_to_return = apply_filters( 'skp_get_skope_id', $skope_id_to_return, $level );
|
||||
|
||||
// At this point, the skope_id should be set
|
||||
if ( '_skope_not_set_' === $skope_id_to_return ) {
|
||||
//error_log( __FUNCTION__ . ' error => skope_id not set for level ' . $level );
|
||||
}
|
||||
// error_log('$skope_id_to_return => ' . $level . ' ' . $skope_id_to_return );
|
||||
// error_log( print_r( Flat_Skop_Base()->current_skope_ids , true ) );
|
||||
return $skope_id_to_return;
|
||||
}
|
||||
|
||||
//@param args = array(
|
||||
// 'skope_string' => skp_get_skope(),
|
||||
// 'skope_type' => $skp_type,
|
||||
// 'skope_level' => 'local'
|
||||
//)
|
||||
//@return string
|
||||
function skp_build_skope_id( $args = array() ) {
|
||||
$skope_id = '_skope_not_set_';
|
||||
|
||||
// normalizes
|
||||
$args = is_array( $args ) ? $args : array();
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array( 'skope_string' => '', 'skope_type' => '', 'skope_level' => '' )
|
||||
);
|
||||
|
||||
// set params if not provided
|
||||
$args['skope_level'] = empty( $args['skope_level'] ) ? 'local' : $args['skope_level'];
|
||||
$args['skope_string'] = ( 'local' == $args['skope_level'] && empty( $args['skope_string'] ) ) ? skp_get_skope() : $args['skope_string'];
|
||||
$args['skope_type'] = ( 'group' == $args['skope_level'] && empty( $args['skope_type'] ) ) ? skp_get_skope( 'type' ) : $args['skope_type'];
|
||||
|
||||
// generate skope_id for two cases : local or group
|
||||
switch( $args[ 'skope_level'] ) {
|
||||
case 'local' :
|
||||
$skope_id = strtolower( NIMBLE_SKOPE_ID_PREFIX . $args[ 'skope_string' ] );
|
||||
break;
|
||||
case 'group' :
|
||||
if ( !empty( $args[ 'skope_type' ] ) ) {
|
||||
$skope_id = strtolower( NIMBLE_SKOPE_ID_PREFIX . 'all_' . $args[ 'skope_type' ] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $skope_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used when localizing the customizer js params
|
||||
* Can be a post ( post, pages, CPT) , tax(tag, cats, custom taxs), author, date, search page, 404.
|
||||
* @param $args : array(
|
||||
* 'level' => string,
|
||||
* 'meta_type' => string
|
||||
* 'long' => bool
|
||||
* 'is_prefixed' => bool //<= indicated if we should add the "Options for" prefix
|
||||
* )
|
||||
* @return string title of the current ctx if exists. If not => false.
|
||||
*/
|
||||
function skp_get_skope_title( $args = array() ) {
|
||||
$defaults = array(
|
||||
'level' => '',
|
||||
'meta_type' => null,
|
||||
'long' => false,
|
||||
'is_prefixed' => true
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$level = $args['level'];
|
||||
$meta_type = $args['meta_type'];
|
||||
$long = $args['long'];
|
||||
$is_prefixed = $args['is_prefixed'];
|
||||
|
||||
$_dyn_type = ( skp_is_customize_preview_frame() && isset( $_POST['dyn_type']) ) ? sanitize_text_field($_POST['dyn_type']) : '';
|
||||
$type = skp_get_skope('type');
|
||||
$skope = skp_get_skope();
|
||||
$title = '';
|
||||
|
||||
if( 'local' == $level ) {
|
||||
$type = skp_get_skope( 'type' );
|
||||
$title = $is_prefixed ? __( 'Options for', 'text_doma') . ' ' : $title;
|
||||
if ( skp_skope_has_a_group( $meta_type ) ) {
|
||||
$_id = skp_get_skope('id');
|
||||
switch ($meta_type) {
|
||||
case 'post':
|
||||
$type_obj = get_post_type_object( $type );
|
||||
$title .= sprintf( '%1$s "%3$s" (id : %2$s)', strtolower( $type_obj->labels->singular_name ), $_id, get_the_title( $_id ) );
|
||||
break;
|
||||
|
||||
case 'tax':
|
||||
$type_obj = get_taxonomy( $type );
|
||||
$term = get_term( $_id, $type );
|
||||
$title .= sprintf( '%1$s "%3$s" (id : %2$s)', strtolower( $type_obj->labels->singular_name ), $_id, $term->name );
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
$author = get_userdata( $_id );
|
||||
$title .= sprintf( '%1$s "%3$s" (id : %2$s)', __('user', 'text_doma'), $_id, $author->user_login );
|
||||
break;
|
||||
}
|
||||
} else if ( ( 'trans' == $_dyn_type || skp_skope_has_no_group( $skope ) ) ) {
|
||||
if ( is_post_type_archive() ) {
|
||||
global $wp_the_query;
|
||||
$title .= sprintf( __( '%1$s archive page', 'text_doma'), $wp_the_query->get( 'post_type' ) );
|
||||
} else {
|
||||
$title .= strtolower( $skope );
|
||||
}
|
||||
} else {
|
||||
$title .= __( 'Undefined', 'text_doma');
|
||||
}
|
||||
}
|
||||
if ( 'group' == $level || 'special_group' == $level ) {
|
||||
$title = $is_prefixed ? __( 'Options for all', 'text_doma') . ' ' : __( 'All' , 'text_doma' ) . ' ';
|
||||
switch( $meta_type ) {
|
||||
case 'post' :
|
||||
$type_obj = get_post_type_object( $type );
|
||||
$title .= strtolower( $type_obj->labels->name );
|
||||
break;
|
||||
|
||||
case 'tax' :
|
||||
$type_obj = get_taxonomy( $type );
|
||||
$title .= strtolower( $type_obj->labels->name );
|
||||
break;
|
||||
|
||||
case 'user' :
|
||||
$title .= __('users', 'text_doma');
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( 'global' == $level ) {
|
||||
$title = __( 'Sitewide options', 'text_doma');
|
||||
}
|
||||
$title = ucfirst( $title );
|
||||
return skp_trim_text( $title, $long ? 45 : 28, '...');
|
||||
}
|
||||
|
||||
//@return bool
|
||||
//=> tells if the current skope is part of the ones without group
|
||||
function skp_skope_has_no_group( $meta_type ) {
|
||||
return in_array(
|
||||
$meta_type,
|
||||
skp_get_no_group_skope_list()
|
||||
) || is_post_type_archive();
|
||||
}
|
||||
|
||||
//@return bool
|
||||
//Tells if the current skope has a group level
|
||||
function skp_skope_has_a_group( $meta_type ) {
|
||||
return in_array(
|
||||
$meta_type,
|
||||
array('post', 'tax', 'user')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//@return bool
|
||||
function skp_is_real_home() {
|
||||
// Warning : when show_on_front is a page, but no page_on_front has been picked yet, is_home() is true
|
||||
// beware of https://github.com/presscustomizr/nimble-builder/issues/349
|
||||
return ( is_home() && ( 'posts' == get_option( 'show_on_front' ) || '__nothing__' == get_option( 'show_on_front' ) ) )
|
||||
|| ( is_home() && 0 == get_option( 'page_on_front' ) && 'page' == get_option( 'show_on_front' ) )//<= this is the case when the user want to display a page on home but did not pick a page yet
|
||||
|| is_front_page();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a boolean
|
||||
*/
|
||||
function skp_is_customizing() {
|
||||
//checks if is customizing : two contexts, admin and front (preview frame)
|
||||
global $pagenow;
|
||||
$_is_ajaxing_from_customizer = isset( $_POST['customized'] ) || isset( $_POST['wp_customize'] );
|
||||
|
||||
$is_customizing = false;
|
||||
// the check on $pagenow does NOT work on multisite install @see https://github.com/presscustomizr/nimble-builder/issues/240
|
||||
// That's why we also check with other global vars
|
||||
// @see wp-includes/theme.php, _wp_customize_include()
|
||||
$is_customize_php_page = ( is_admin() && 'customize.php' == basename( $_SERVER['PHP_SELF'] ) );
|
||||
$is_customize_admin_page_one = (
|
||||
$is_customize_php_page
|
||||
||
|
||||
( isset( $_REQUEST['wp_customize'] ) && 'on' == sanitize_text_field($_REQUEST['wp_customize']) )
|
||||
||
|
||||
( !empty( $_GET['customize_changeset_uuid'] ) || !empty( $_POST['customize_changeset_uuid'] ) )
|
||||
);
|
||||
$is_customize_admin_page_two = is_admin() && isset( $pagenow ) && 'customize.php' == $pagenow;
|
||||
|
||||
if ( $is_customize_admin_page_one || $is_customize_admin_page_two ) {
|
||||
$is_customizing = true;
|
||||
//hu_is_customize_preview_frame() ?
|
||||
// Note : is_customize_preview() is not able to differentiate when previewing in the customizer and when previewing a changeset draft.
|
||||
// @todo => change this
|
||||
} else if ( is_customize_preview() || ( !is_admin() && isset($_REQUEST['customize_messenger_channel']) ) ) {
|
||||
$is_customizing = true;
|
||||
// hu_doing_customizer_ajax()
|
||||
} else if ( $_is_ajaxing_from_customizer && ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
||||
$is_customizing = true;
|
||||
}
|
||||
return $is_customizing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the customizer preview panel being displayed ?
|
||||
* @return boolean
|
||||
*/
|
||||
function skp_is_customize_preview_frame() {
|
||||
return is_customize_preview() || ( !is_admin() && isset($_REQUEST['customize_messenger_channel']) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
function skp_is_previewing_live_changeset() {
|
||||
return !isset( $_POST['customize_messenger_channel']) && is_customize_preview();
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// FLAT SKOPE BASE
|
||||
if ( !class_exists( 'Flat_Skop_Base' ) ) :
|
||||
class Flat_Skop_Base {
|
||||
static $instance;
|
||||
public $query_skope = array();//<= will cache the query skope ( otherwise called multiple times ) on the first invokation of skp_get_query_skope() IF 'wp' done
|
||||
public $current_skope_ids = array();// will cache the skope ids on the first invokation of skp_get_skope_id, if 'wp' done
|
||||
|
||||
public static function skp_get_instance( $params ) {
|
||||
if ( !isset( self::$instance ) && !( self::$instance instanceof Flat_Skop_Base ) )
|
||||
self::$instance = new Flat_Skope_Clean_Final( $params );
|
||||
return self::$instance;
|
||||
}
|
||||
function __construct( $params = array() ) {
|
||||
$defaults = array(
|
||||
'base_url_path' => ''//NIMBLE_BASE_URL . '/inc/czr-skope/'
|
||||
);
|
||||
$params = wp_parse_args( $params, $defaults );
|
||||
if ( !defined( 'NIMBLE_SKOPE_BASE_URL' ) ) { define( 'NIMBLE_SKOPE_BASE_URL' , $params['base_url_path'] ); }
|
||||
if ( !defined( 'NIMBLE_SKOPE_ID_PREFIX' ) ) { define( 'NIMBLE_SKOPE_ID_PREFIX' , "skp__" ); }
|
||||
|
||||
$this->skp_register_and_load_control_assets();
|
||||
$this->skp_export_skope_data_and_schedule_sending_to_panel();
|
||||
$this->skp_schedule_cleaning_on_object_delete();
|
||||
}//__construct
|
||||
}
|
||||
endif;
|
||||
?>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// PRINT CUSTOMIZER JAVASCRIPT + LOCALIZED DATA
|
||||
if ( !class_exists( 'Flat_Skop_Register_And_Load_Control_Assets' ) ) :
|
||||
class Flat_Skop_Register_And_Load_Control_Assets extends Flat_Skop_Base {
|
||||
// Fired in Flat_Skop_Base::__construct()
|
||||
public function skp_register_and_load_control_assets() {
|
||||
add_action( 'customize_controls_enqueue_scripts', array( $this, 'skp_enqueue_controls_js_css' ), 20 );
|
||||
}
|
||||
|
||||
public function skp_enqueue_controls_js_css() {
|
||||
$_use_unminified = defined('CZR_DEV')
|
||||
&& true === CZR_DEV
|
||||
// && false === strpos( dirname( dirname( dirname (__FILE__) ) ) , 'inc/wfc' )
|
||||
&& file_exists( sprintf( '%s/assets/czr/js/czr-skope-base.js' , dirname( __FILE__ ) ) );
|
||||
|
||||
$_prod_script_path = sprintf(
|
||||
'%1$s/assets/czr/js/%2$s' ,
|
||||
NIMBLE_SKOPE_BASE_URL,
|
||||
$_use_unminified ? 'czr-skope-base.js' : 'czr-skope-base.min.js'
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'czr-skope-base',
|
||||
//dev / debug mode mode?
|
||||
$_prod_script_path,
|
||||
array('customize-controls' , 'jquery', 'underscore'),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : wp_get_theme()->version,
|
||||
$in_footer = true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'czr-skope-base',
|
||||
'FlatSkopeLocalizedData',
|
||||
array(
|
||||
'noGroupSkopeList' => skp_get_no_group_skope_list(),
|
||||
'defaultSkopeModel' => skp_get_default_skope_model(),
|
||||
'i18n' => array()
|
||||
)
|
||||
);
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CUSTOMIZE PREVIEW : export skope data and send skope to the panel
|
||||
/* ------------------------------------------------------------------------- */
|
||||
if ( !class_exists( 'Flat_Export_Skope_Data_And_Send_To_Panel' ) ) :
|
||||
class Flat_Export_Skope_Data_And_Send_To_Panel extends Flat_Skop_Register_And_Load_Control_Assets {
|
||||
// Fired in Flat_Skop_Base::__construct()
|
||||
public function skp_export_skope_data_and_schedule_sending_to_panel() {
|
||||
add_action( 'wp_head', array( $this, 'skp_print_server_skope_data') , 30 );
|
||||
}
|
||||
|
||||
|
||||
//hook : 'wp_footer'
|
||||
public function skp_print_server_skope_data() {
|
||||
if ( !skp_is_customize_preview_frame() )
|
||||
return;
|
||||
|
||||
global $wp_query, $wp_customize;
|
||||
$_meta_type = skp_get_skope( 'meta_type', true );
|
||||
|
||||
// $_czr_scopes = array( );
|
||||
$_czr_skopes = $this->_skp_get_json_export_ready_skopes();
|
||||
$_czr_query_data = $this->_skp_get_json_export_ready_query_data();
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
var _doSend = function() {
|
||||
// December 2020 : it may happen that the 'sync' event was already sent and that we missed it
|
||||
// Typically when the site is slow.
|
||||
// So we need to check if the "sync" event has fired already ( see customize-base.js, ::bind method )
|
||||
// For more security, let's introduce a marker and attempt to re-sent after a moment if needed
|
||||
window.czr_skopes_sent = false;
|
||||
var _send = function() {
|
||||
wp.customize.preview.send( 'czr-new-skopes-synced', {
|
||||
czr_new_skopes : _wpCustomizeSettings.czr_new_skopes || [],
|
||||
czr_stylesheet : _wpCustomizeSettings.czr_stylesheet || '',
|
||||
isChangesetDirty : _wpCustomizeSettings.isChangesetDirty || false,
|
||||
skopeGlobalDBOpt : _wpCustomizeSettings.skopeGlobalDBOpt || [],
|
||||
} );
|
||||
window.czr_skopes_sent = true;
|
||||
};
|
||||
|
||||
jQuery( function() {
|
||||
if ( wp.customize.preview.topics && wp.customize.preview.topics.sync && wp.customize.preview.topics.sync.fired() ) {
|
||||
_send();
|
||||
} else {
|
||||
wp.customize.preview.bind( 'sync', function( events ) {
|
||||
_send();
|
||||
});
|
||||
}
|
||||
setTimeout( function() {
|
||||
if ( !window.czr_skopes_sent ) {
|
||||
_send();
|
||||
}
|
||||
}, 2500 );
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// recursively try to load jquery every 200ms during 6s ( max 30 times )
|
||||
var _doWhenCustomizeSettingsReady = function( attempts ) {
|
||||
attempts = attempts || 0;
|
||||
if ( typeof undefined !== typeof window._wpCustomizeSettings ) {
|
||||
_wpCustomizeSettings.czr_new_skopes = <?php echo wp_json_encode( $_czr_skopes ); ?>;
|
||||
_wpCustomizeSettings.czr_stylesheet = '<?php echo get_stylesheet(); ?>';
|
||||
_wpCustomizeSettings.czr_query_params = <?php echo wp_json_encode($_czr_query_data); ?>;
|
||||
_doSend();
|
||||
} else if ( attempts < 30 ) {
|
||||
setTimeout( function() {
|
||||
attempts++;
|
||||
_doWhenCustomizeSettingsReady( attempts );
|
||||
}, 20 );
|
||||
} else {
|
||||
if ( window.console && window.console.log ) {
|
||||
console.log('Nimble Builder problem : _wpCustomizeSettings is not defined');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_doWhenCustomizeSettingsReady();
|
||||
<?php
|
||||
$script = ob_get_clean();
|
||||
wp_register_script( 'nb_print_skope_data_js', '');
|
||||
wp_enqueue_script( 'nb_print_skope_data_js' );
|
||||
wp_add_inline_script( 'nb_print_skope_data_js', $script );
|
||||
}
|
||||
|
||||
|
||||
// introduced in october 2019 for https://github.com/presscustomizr/nimble-builder/issues/401
|
||||
private function _skp_get_json_export_ready_query_data() {
|
||||
global $wp_query;
|
||||
global $authordata;
|
||||
add_filter('get_the_archive_title_prefix', '__return_false');
|
||||
$archive_title = get_the_archive_title();
|
||||
remove_filter('get_the_archive_title_prefix', '__return_false');
|
||||
return [
|
||||
'is_singular' => $wp_query->is_singular,
|
||||
'is_archive' => $wp_query->is_archive,
|
||||
'is_search' => $wp_query->is_search,
|
||||
'is_attachment' => $wp_query->is_attachment,
|
||||
'is_front_page' => is_front_page(),
|
||||
'the_archive_title' => $archive_title,
|
||||
'the_archive_description' => get_the_archive_description(),
|
||||
'the_previous_post_link' => is_singular() ? get_previous_post_link( $format = '%link' ) : '',
|
||||
'the_next_post_link' => is_singular() ? get_next_post_link( $format = '%link' ) : '',
|
||||
'the_search_query' => get_search_query(),
|
||||
'the_search_results_nb' => (int) $wp_query->found_posts,
|
||||
'the_author_id' => isset( $authordata->ID ) ? $authordata->ID : 0,
|
||||
'post_id' => get_the_ID(),
|
||||
'query_vars' => $wp_query->query_vars
|
||||
];
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CUSTOMIZE PREVIEW : BUILD SKOPES JSON
|
||||
/* ------------------------------------------------------------------------- */
|
||||
//generates the array of available scopes for a given context
|
||||
//ex for a single post tagged #tag1 and #tag2 and categroized #cat1 :
|
||||
//global
|
||||
//all posts
|
||||
//local
|
||||
//posts tagged #tag1
|
||||
//posts tagged #tag2
|
||||
//posts categorized #cat1
|
||||
//@return array()
|
||||
//
|
||||
//skp_get_skope_title() takes the following default args
|
||||
//array(
|
||||
// 'level' => '',
|
||||
// 'meta_type' => null,
|
||||
// 'long' => false,
|
||||
// 'is_prefixed' => true
|
||||
//)
|
||||
private function _skp_get_json_export_ready_skopes() {
|
||||
$skopes = array();
|
||||
$_meta_type = skp_get_skope( 'meta_type', true );
|
||||
|
||||
//default properties of the scope object
|
||||
$defaults = skp_get_default_skope_model();
|
||||
//global and local and always sent
|
||||
$skopes[] = wp_parse_args(
|
||||
array(
|
||||
'title' => skp_get_skope_title( array( 'level' => 'global' ) ),
|
||||
'long_title' => skp_get_skope_title( array( 'level' => 'global', 'meta_type' => null, 'long' => true ) ),
|
||||
'ctx_title' => skp_get_skope_title( array( 'level' => 'global', 'meta_type' => null, 'long' => true, 'is_prefixed' => false ) ),
|
||||
'skope' => 'global',
|
||||
'level' => '_all_'
|
||||
),
|
||||
$defaults
|
||||
);
|
||||
|
||||
|
||||
//SPECIAL GROUPS
|
||||
//@todo
|
||||
|
||||
|
||||
//GROUP
|
||||
//Do we have a group ? => if yes, then there must be a meta type
|
||||
if ( skp_get_skope('meta_type') ) {
|
||||
$skopes[] = wp_parse_args(
|
||||
array(
|
||||
'title' => skp_get_skope_title( array( 'level' => 'group', 'meta_type' => $_meta_type ) ),
|
||||
'long_title' => skp_get_skope_title( array( 'level' => 'group', 'meta_type' => $_meta_type, 'long' => true ) ),
|
||||
'ctx_title' => skp_get_skope_title( array( 'level' => 'group', 'meta_type' => $_meta_type, 'long' => true, 'is_prefixed' => false ) ),
|
||||
'skope' => 'group',
|
||||
'level' => 'all_' . skp_get_skope('type'),
|
||||
'skope_id' => skp_get_skope_id( 'group' )
|
||||
),
|
||||
$defaults
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//LOCAL
|
||||
$skopes[] = wp_parse_args(
|
||||
array(
|
||||
'title' => skp_get_skope_title( array( 'level' => 'local', 'meta_type' => $_meta_type ) ),
|
||||
'long_title' => skp_get_skope_title( array( 'level' => 'local', 'meta_type' => $_meta_type, 'long' => true ) ),
|
||||
'ctx_title' => skp_get_skope_title( array( 'level' => 'local', 'meta_type' => $_meta_type, 'long' => true, 'is_prefixed' => false ) ),
|
||||
'skope' => 'local',
|
||||
'level' => skp_get_skope(),
|
||||
'obj_id' => skp_get_skope('id'),
|
||||
'skope_id' => skp_get_skope_id( 'local' )
|
||||
),
|
||||
$defaults
|
||||
);
|
||||
return apply_filters( 'skp_json_export_ready_skopes', $skopes );
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
if ( !class_exists( 'Flat_Skope_Clean_Final' ) ) :
|
||||
final class Flat_Skope_Clean_Final extends Flat_Export_Skope_Data_And_Send_To_Panel {
|
||||
// Fired in Flat_Skop_Base::__construct()
|
||||
public function skp_schedule_cleaning_on_object_delete() {
|
||||
add_action( 'delete_post', array( $this, 'skp_clean_skopified_posts' ) );
|
||||
add_action( 'delete_term_taxonomy', array( $this, 'skp_clean_skopified_taxonomies' ) );
|
||||
add_action( 'delete_user', array( $this, 'skp_clean_skopified_users' ) );
|
||||
}
|
||||
|
||||
|
||||
// Clean any associated skope post for all public post types : post, page, public cpt
|
||||
// 'delete_post' Fires immediately before a post is deleted from the database.
|
||||
// @see wp-includes/post.php
|
||||
// don't have to return anything
|
||||
public function skp_clean_skopified_posts( $postid ) {
|
||||
$deletion_candidate = get_post( $postid );
|
||||
if ( !$deletion_candidate || !is_object( $deletion_candidate ) )
|
||||
return;
|
||||
|
||||
// Stop here if the post type is not considered "viewable".
|
||||
// For built-in post types such as posts and pages, the 'public' value will be evaluated.
|
||||
// For all others, the 'publicly_queryable' value will be used.
|
||||
// For example, the 'revision' post type, which is purely internal and not skopable, won't pass this test.
|
||||
if ( !is_post_type_viewable( $deletion_candidate->post_type ) )
|
||||
return;
|
||||
|
||||
// Force the skope parts normally retrieved with skp_get_query_skope()
|
||||
$skope_string = skp_get_skope( null, true, array(
|
||||
'meta_type' => 'post',
|
||||
'type' => $deletion_candidate->post_type,
|
||||
'obj_id' => $postid
|
||||
) );
|
||||
|
||||
// build a skope_id with the normalized function
|
||||
$skope_id = skp_build_skope_id( array( 'skope_string' => $skope_string, 'skope_level' => 'local' ) );
|
||||
|
||||
// fetch the skope post id which, if exists, is set as a theme mod
|
||||
$skope_post_id_candidate = get_theme_mod( $skope_id );
|
||||
if ( $skope_post_id_candidate > 0 && get_post( $skope_post_id_candidate ) ) {
|
||||
// permanently delete the skope post from db
|
||||
wp_delete_post( $skope_post_id_candidate );
|
||||
// remove the theme_mod
|
||||
remove_theme_mod( $skope_id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 'delete_term_taxonomy' Fires immediately before a term taxonomy ID is deleted.
|
||||
public function skp_clean_skopified_taxonomies( $term_id ) {
|
||||
$deletion_candidate = get_term( $term_id );
|
||||
if ( !$deletion_candidate || !is_object( $deletion_candidate ) )
|
||||
return;
|
||||
|
||||
//error_log( print_r( $deletion_candidate, true ) );
|
||||
|
||||
// Force the skope parts normally retrieved with skp_get_query_skope()
|
||||
$skope_string = skp_get_skope( null, true, array(
|
||||
'meta_type' => 'tax',
|
||||
'type' => $deletion_candidate->taxonomy,
|
||||
'obj_id' => $term_id
|
||||
) );
|
||||
|
||||
// build a skope_id with the normalized function
|
||||
$skope_id = skp_build_skope_id( array( 'skope_string' => $skope_string, 'skope_level' => 'local' ) );
|
||||
|
||||
// fetch the skope post id which, if exists, is set as a theme mod
|
||||
$skope_post_id_candidate = get_theme_mod( $skope_id );
|
||||
if ( $skope_post_id_candidate > 0 && get_post( $skope_post_id_candidate ) ) {
|
||||
// permanently delete the skope post from db
|
||||
wp_delete_post( $skope_post_id_candidate );
|
||||
// remove the theme_mod
|
||||
remove_theme_mod( $skope_id );
|
||||
//error_log( 'SUCCESSFULLY REMOVED SKOPE POST ID ' . $skope_post_id_candidate . ' AND THEME MOD ' . $skope_id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 'delete_user' Fires immediately before a user is deleted from the database.
|
||||
public function skp_clean_skopified_users( $user_id ) {
|
||||
// Force the skope parts normally retrieved with skp_get_query_skope()
|
||||
$skope_string = skp_get_skope( null, true, array(
|
||||
'meta_type' => 'user',
|
||||
'type' => 'author',
|
||||
'obj_id' => $user_id
|
||||
) );
|
||||
|
||||
// build a skope_id with the normalized function
|
||||
$skope_id = skp_build_skope_id( array( 'skope_string' => $skope_string, 'skope_level' => 'local' ) );
|
||||
|
||||
// fetch the skope post id which, if exists, is set as a theme mod
|
||||
$skope_post_id_candidate = get_theme_mod( $skope_id );
|
||||
if ( $skope_post_id_candidate > 0 && get_post( $skope_post_id_candidate ) ) {
|
||||
// permanently delete the skope post from db
|
||||
wp_delete_post( $skope_post_id_candidate );
|
||||
// remove the theme_mod
|
||||
remove_theme_mod( $skope_id );
|
||||
//error_log( 'SUCCESSFULLY REMOVED SKOPE POST ID ' . $skope_post_id_candidate . ' AND THEME MOD ' . $skope_id );
|
||||
}
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,272 @@
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"accessor-pairs": "error",
|
||||
"array-bracket-newline": "off",
|
||||
"array-bracket-spacing": "off",
|
||||
"array-callback-return": "off",
|
||||
"array-element-newline": "off",
|
||||
"arrow-body-style": "error",
|
||||
"arrow-parens": "error",
|
||||
"arrow-spacing": "error",
|
||||
"block-scoped-var": "off",
|
||||
"block-spacing": "off",
|
||||
"brace-style": "off",
|
||||
"callback-return": "error",
|
||||
"camelcase": "off",
|
||||
"capitalized-comments": "off",
|
||||
"class-methods-use-this": "error",
|
||||
"comma-dangle": "off",
|
||||
"comma-spacing": "off",
|
||||
"comma-style": [
|
||||
"error",
|
||||
"last"
|
||||
],
|
||||
"complexity": "off",
|
||||
"computed-property-spacing": "off",
|
||||
"consistent-return": "off",
|
||||
"consistent-this": "off",
|
||||
"curly": "off",
|
||||
"default-case": "off",
|
||||
"dot-location": "off",
|
||||
"dot-notation": "off",
|
||||
"eol-last": "off",
|
||||
"eqeqeq": "off",
|
||||
"for-direction": "off",
|
||||
"func-call-spacing": "off",
|
||||
"func-name-matching": "error",
|
||||
"func-names": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"func-style": "off",
|
||||
"function-paren-newline": "off",
|
||||
"generator-star-spacing": "error",
|
||||
"getter-return": "error",
|
||||
"global-require": "off",
|
||||
"guard-for-in": "off",
|
||||
"handle-callback-err": "error",
|
||||
"id-blacklist": "error",
|
||||
"id-length": "off",
|
||||
"id-match": "error",
|
||||
"implicit-arrow-linebreak": "error",
|
||||
"indent": "off",
|
||||
"indent-legacy": "off",
|
||||
"init-declarations": "off",
|
||||
"jsx-quotes": "error",
|
||||
"key-spacing": "off",
|
||||
"keyword-spacing": "off",
|
||||
"line-comment-position": "off",
|
||||
"linebreak-style": "off",
|
||||
"lines-around-comment": "off",
|
||||
"lines-around-directive": "off",
|
||||
"lines-between-class-members": "error",
|
||||
"max-depth": "off",
|
||||
"max-len": "off",
|
||||
"max-lines": "off",
|
||||
"max-nested-callbacks": "error",
|
||||
"max-params": "off",
|
||||
"max-statements": "off",
|
||||
"max-statements-per-line": "off",
|
||||
"multiline-comment-style": "off",
|
||||
"multiline-ternary": "off",
|
||||
"new-parens": "off",
|
||||
"newline-after-var": "off",
|
||||
"newline-before-return": "off",
|
||||
"newline-per-chained-call": "off",
|
||||
"no-alert": "error",
|
||||
"no-array-constructor": "error",
|
||||
"no-await-in-loop": "error",
|
||||
"no-bitwise": "off",
|
||||
"no-buffer-constructor": "error",
|
||||
"no-caller": "error",
|
||||
"no-catch-shadow": "off",
|
||||
"no-confusing-arrow": "error",
|
||||
"no-continue": "off",
|
||||
"no-div-regex": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-else-return": "off",
|
||||
"no-empty-function": "off",
|
||||
"no-eq-null": "off",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "off",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-label": "error",
|
||||
"no-extra-parens": "off",
|
||||
"no-floating-decimal": "off",
|
||||
"no-implicit-coercion": [
|
||||
"error",
|
||||
{
|
||||
"boolean": false,
|
||||
"number": false,
|
||||
"string": false
|
||||
}
|
||||
],
|
||||
"no-implicit-globals": "off",
|
||||
"no-implied-eval": "error",
|
||||
"no-inline-comments": "off",
|
||||
"no-inner-declarations": [
|
||||
"error",
|
||||
"functions"
|
||||
],
|
||||
"no-invalid-this": "off",
|
||||
"no-iterator": "error",
|
||||
"no-label-var": "off",
|
||||
"no-labels": "off",
|
||||
"no-lone-blocks": "off",
|
||||
"no-lonely-if": "off",
|
||||
"no-loop-func": "error",
|
||||
"no-magic-numbers": "off",
|
||||
"no-mixed-operators": "off",
|
||||
"no-mixed-requires": "error",
|
||||
"no-multi-assign": "off",
|
||||
"no-multi-spaces": "off",
|
||||
"no-multi-str": "error",
|
||||
"no-multiple-empty-lines": "off",
|
||||
"no-native-reassign": "error",
|
||||
"no-negated-condition": "off",
|
||||
"no-negated-in-lhs": "error",
|
||||
"no-nested-ternary": "off",
|
||||
"no-new": "off",
|
||||
"no-new-func": "error",
|
||||
"no-new-object": "error",
|
||||
"no-new-require": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-param-reassign": "off",
|
||||
"no-path-concat": "error",
|
||||
"no-plusplus": "off",
|
||||
"no-process-env": "error",
|
||||
"no-process-exit": "error",
|
||||
"no-proto": "error",
|
||||
"no-prototype-builtins": "off",
|
||||
"no-restricted-globals": "error",
|
||||
"no-restricted-imports": "error",
|
||||
"no-restricted-modules": "error",
|
||||
"no-restricted-properties": "error",
|
||||
"no-restricted-syntax": "error",
|
||||
"no-return-assign": "off",
|
||||
"no-return-await": "error",
|
||||
"no-script-url": "error",
|
||||
"no-self-assign": [
|
||||
"error",
|
||||
{
|
||||
"props": false
|
||||
}
|
||||
],
|
||||
"no-self-compare": "off",
|
||||
"no-sequences": "off",
|
||||
"no-shadow": "off",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-spaced-func": "off",
|
||||
"no-sync": "error",
|
||||
"no-tabs": "off",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-ternary": "off",
|
||||
"no-throw-literal": "off",
|
||||
"no-undef-init": "error",
|
||||
"no-undefined": "error",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-unneeded-ternary": [
|
||||
"error",
|
||||
{
|
||||
"defaultAssignment": true
|
||||
}
|
||||
],
|
||||
"no-unused-expressions": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-useless-call": "off",
|
||||
"no-useless-computed-key": "error",
|
||||
"no-useless-concat": "off",
|
||||
"no-useless-constructor": "error",
|
||||
"no-useless-rename": "error",
|
||||
"no-useless-return": "off",
|
||||
"no-var": "off",
|
||||
"no-void": "off",
|
||||
"no-warning-comments": "off",
|
||||
"no-whitespace-before-property": "error",
|
||||
"no-with": "error",
|
||||
"nonblock-statement-body-position": [
|
||||
"error",
|
||||
"any"
|
||||
],
|
||||
"object-curly-newline": "off",
|
||||
"object-curly-spacing": "off",
|
||||
"object-property-newline": "off",
|
||||
"object-shorthand": "off",
|
||||
"one-var": "off",
|
||||
"one-var-declaration-per-line": "off",
|
||||
"operator-assignment": "off",
|
||||
"operator-linebreak": [
|
||||
"error",
|
||||
"after"
|
||||
],
|
||||
"padded-blocks": "off",
|
||||
"padding-line-between-statements": "error",
|
||||
"prefer-arrow-callback": "off",
|
||||
"prefer-const": "error",
|
||||
"prefer-destructuring": "off",
|
||||
"prefer-numeric-literals": "error",
|
||||
"prefer-promise-reject-errors": "error",
|
||||
"prefer-reflect": "off",
|
||||
"prefer-rest-params": "off",
|
||||
"prefer-spread": "off",
|
||||
"prefer-template": "off",
|
||||
"quote-props": "off",
|
||||
"quotes": "off",
|
||||
"radix": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"require-await": "error",
|
||||
"require-jsdoc": "off",
|
||||
"rest-spread-spacing": "error",
|
||||
"semi": "off",
|
||||
"semi-spacing": "off",
|
||||
"semi-style": [
|
||||
"error",
|
||||
"last"
|
||||
],
|
||||
"sort-imports": "error",
|
||||
"sort-keys": "off",
|
||||
"sort-vars": "off",
|
||||
"space-before-blocks": "off",
|
||||
"space-before-function-paren": "off",
|
||||
"space-in-parens": "off",
|
||||
"space-infix-ops": "off",
|
||||
"space-unary-ops": "off",
|
||||
"spaced-comment": "off",
|
||||
"strict": "off",
|
||||
"switch-colon-spacing": "off",
|
||||
"symbol-description": "error",
|
||||
"template-curly-spacing": "error",
|
||||
"template-tag-spacing": "error",
|
||||
"unicode-bom": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"valid-jsdoc": "off",
|
||||
"valid-typeof": [
|
||||
"error",
|
||||
{
|
||||
"requireStringLiterals": false
|
||||
}
|
||||
],
|
||||
"vars-on-top": "off",
|
||||
"wrap-iife": "off",
|
||||
"wrap-regex": "off",
|
||||
"yield-star-spacing": "error",
|
||||
"yoda": "off"
|
||||
},
|
||||
"globals": {
|
||||
"wp": true,
|
||||
"jQuery": true,
|
||||
"_":true,
|
||||
'FlatSkopeLocalizedData' : true,
|
||||
'serverControlParams' : true
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,136 @@
|
||||
|
||||
var CZRFlatSkopeModuleMths = CZRFlatSkopeModuleMths || {};
|
||||
|
||||
( function ( api, $, _ ) {
|
||||
$.extend( CZRFlatSkopeModuleMths, {
|
||||
// fired in module::initialize
|
||||
scheduleSkopeReactions : function() {
|
||||
var module = this;
|
||||
|
||||
// @params looks like :
|
||||
// {
|
||||
// newSkopes : newSkopes,
|
||||
// previousSkopes : previousSkopes
|
||||
// }
|
||||
api.bind( 'active-skopes-updated', function( params ) {
|
||||
console.log( 'active-skopes-updated', params, module.SKOPE_LEVEL );
|
||||
params = _.extend( { newSkopes : {}, previousSkopes : {} }, params );
|
||||
if ( ! _.has( params.newSkopes, module.SKOPE_LEVEL ) ) {
|
||||
api.errorLog( 'active-skopes-updated => ' + module.SKOPE_LEVEL + ' was not found in the skope list' );
|
||||
return;
|
||||
} else {
|
||||
module.isReady.then( function() {
|
||||
// Always update the local skope-id in the pre-item
|
||||
if ( module.preItem && ! _.isEmpty( module.preItem.czr_Input ) && module.preItem.czr_Input.has('skope-id') ) {
|
||||
module.preItem.czr_Input( 'skope-id' )( params.newSkopes[ module.SKOPE_LEVEL ] );
|
||||
}
|
||||
// Print the contextual items only
|
||||
//module.refreshContextualItems();
|
||||
|
||||
|
||||
// Display the parent control when relevant
|
||||
module.control.active( '_skope_not_set_' != params.newSkopes[ module.SKOPE_LEVEL ] );
|
||||
});
|
||||
|
||||
// Print a bottom notification in all controls wrapper
|
||||
//module.printSkopeInfoInControls();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//This method react to the skope change
|
||||
// => reinstantiates all items based on the current collection
|
||||
// refreshContextualItems : function() {
|
||||
// var module = this;
|
||||
// //Remove item views and instances
|
||||
// module.czr_Item.each( function( _itm ) {
|
||||
// if ( ! _.isEmpty( _itm.container ) && 0 < _itm.container.length ) {
|
||||
// $.when( _itm.container.remove() ).done( function() {
|
||||
// //Remove item instances
|
||||
// module.czr_Item.remove( _itm.id );
|
||||
// });
|
||||
// } else {
|
||||
// //Remove item instances
|
||||
// module.czr_Item.remove( _itm.id );
|
||||
// }
|
||||
// });
|
||||
|
||||
// // Reset the item collection
|
||||
// // => the collection listeners will be setup after populate, on 'items-collection-populated'
|
||||
// var _collection_ = $.extend( true, [], module.itemCollection() );
|
||||
|
||||
// // reset the collection
|
||||
// module.itemCollection = new api.Value( [] );
|
||||
// module.populateSavedItemCollection( _collection_ );
|
||||
// },
|
||||
|
||||
|
||||
|
||||
// // invoked when module.ready() and api.czr_activeSkopes updated
|
||||
// printSkopeInfoInControls : function() {
|
||||
// var module = this,
|
||||
// _css_class_ = 'skp-note-for-' + module.SKOPE_LEVEL;
|
||||
|
||||
// //This = _ctrl_
|
||||
// var mayBePrintAndSetupCtrlBottomNote = function() {
|
||||
// var _ctrl_ = this,
|
||||
// _skope_title_ = FlatSkopeLocalizedData.i18n[ 'this page' ];
|
||||
|
||||
// if ( 0 < _ctrl_.container.find( '.' + _css_class_ ).length )
|
||||
// return;
|
||||
|
||||
// var currentSkopeObj = _.findWhere( api.czr_currentSkopesCollection(), { skope : module.SKOPE_LEVEL } );
|
||||
// if ( ! _.isEmpty( currentSkopeObj ) ) {
|
||||
// _skope_title_ = currentSkopeObj.ctx_title;
|
||||
// }
|
||||
|
||||
|
||||
// _ctrl_.container.append(
|
||||
// $('<div>', {
|
||||
// class: [ _css_class_ , 'skp-ctrl-bottom-note', 'czr-notice' ].join(' '),
|
||||
// html : [
|
||||
// FlatSkopeLocalizedData.i18n[ 'Can be customized for' ],
|
||||
// '<span class="skp-focus-link"><u>' + _skope_title_ + '</u><span>'
|
||||
// ].join(' ')
|
||||
// })
|
||||
// );
|
||||
|
||||
// api.CZR_Helpers.setupDOMListeners(
|
||||
// [//toggles remove view alert
|
||||
// {
|
||||
// trigger : 'click keydown',
|
||||
// selector : ['.' + _css_class_, '.skp-focus-link'].join(' '),
|
||||
// name : _css_class_,
|
||||
// //data = {
|
||||
// // dom_el,
|
||||
// // dom_event,
|
||||
// // event,
|
||||
// // model
|
||||
// // }
|
||||
// actions : function( data ) {
|
||||
// data.dom_event.preventDefault();
|
||||
// module.control.focus();
|
||||
// }
|
||||
// }//actions to execute
|
||||
// ],
|
||||
// { model: {}, dom_el:_ctrl_.container },//model + dom scope
|
||||
// null //instance where to look for the cb methods
|
||||
|
||||
// );//api.CZR_Helpers.setupDOMListeners
|
||||
// };//mayBePrintAndSetupCtrlBottomNote
|
||||
|
||||
// _.each( api.czr_skopeBase.getSkopableSettings(), function( settingData ) {
|
||||
// //console.log('settingDATA', settingData );
|
||||
// api.control.when( settingData.apiCtrlId, function( _ctrl_ ) {
|
||||
// _ctrl_.deferred.embedded.then( function() {
|
||||
// $.when( _ctrl_.container.find('.' + _css_class_ ).remove() ).done( function() {
|
||||
// if ( module.weHaveASkope() ) {
|
||||
// mayBePrintAndSetupCtrlBottomNote.call( _ctrl_ );
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// } );
|
||||
// });
|
||||
// }//printSkopeInfoInControls
|
||||
});//extend
|
||||
})( wp.customize , jQuery, _ );
|
||||
@@ -0,0 +1,132 @@
|
||||
//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
(function ( api, $, _ ) {
|
||||
$.extend( CZRSkopeBaseMths, {
|
||||
|
||||
initialize: function() {
|
||||
var self = this;
|
||||
///////////////////// DEFINITIONS /////////////////////
|
||||
|
||||
//Store the state of the first skope collection state
|
||||
api.czr_initialSkopeCollectionPopulated = $.Deferred();
|
||||
|
||||
//the czr_skopeCollection stores all skopes instantiated by the user
|
||||
//this collection is not updated directly
|
||||
//=> it's updated on skope() instance change
|
||||
api.czr_skopeCollection = new api.Value([]);//all available skope, including the current skopes
|
||||
//the current skopes collection get updated each time the 'czr-new-skopes-synced' event is triggered on the api by the preview
|
||||
api.czr_currentSkopesCollection = new api.Value([]);
|
||||
|
||||
//the currently active skopes
|
||||
api.czr_activeSkopes = new api.Value( { local : '', group : ''} );
|
||||
|
||||
|
||||
|
||||
///////////////////// SKOPE COLLECTIONS SYNCHRONISATION AND LISTENERS /////////////////////
|
||||
//LISTEN TO SKOPE SYNC => UPDATE SKOPE COLLECTION ON START AND ON EACH REFRESH
|
||||
//the sent data look like :
|
||||
//{
|
||||
// czr_new_skopes : _wpCustomizeSettings.czr_new_skopes || [],
|
||||
// isChangesetDirty : boolean
|
||||
// }
|
||||
api.bind( 'ready' , function() {
|
||||
api.previewer.bind( 'czr-new-skopes-synced', function( skope_server_data ) {
|
||||
if ( serverControlParams.isDevMode ) {
|
||||
api.infoLog( 'API SKOPE SYNCED', skope_server_data );
|
||||
}
|
||||
|
||||
// set the currently active stylesheet
|
||||
if ( ! _.has( skope_server_data, 'czr_stylesheet') ) {
|
||||
api.errorLog( "On 'czr-new-skopes-synced' : missing stylesheet in the server data" );
|
||||
return;
|
||||
}
|
||||
|
||||
api.czr_skopeBase.stylesheet = api.czr_skopeBase.stylesheet || new api.Value( api.settings.theme.stylesheet );
|
||||
api.czr_skopeBase.stylesheet( skope_server_data.czr_stylesheet );
|
||||
|
||||
//api.consoleLog('czr-skopes-ready DATA', skope_server_data );
|
||||
var preview = this,
|
||||
previousSkopeCollection = api.czr_currentSkopesCollection();
|
||||
//initialize skopes with the server sent skope_server_data
|
||||
//if skope has not been initialized yet and the server sent wrong skope_server_data, then reject the skope ready promise()
|
||||
if ( ! _.has( skope_server_data, 'czr_new_skopes') ) {
|
||||
api.errorLog( "On 'czr-new-skopes-synced' : missing skopes in the server data" );
|
||||
return;
|
||||
}
|
||||
|
||||
// If no "group" skope has been sent, check if we should have one
|
||||
// array( 'home', 'search', '404', 'date' ) <= have no group
|
||||
if ( _.isEmpty( _.findWhere( skope_server_data.czr_new_skopes, { skope : 'group' } ) ) ){
|
||||
var _local_ = _.findWhere( skope_server_data.czr_new_skopes, { skope : 'local' } );
|
||||
if ( ! _.isEmpty( _local_ ) && ! _.contains( FlatSkopeLocalizedData.noGroupSkopeList, _local_.level ) ) {
|
||||
api.errorLog( 'No group level skope sent while there should be one' );
|
||||
}
|
||||
}
|
||||
|
||||
//1) Updated the collection with normalized skopes => prepareSkopeForAPI + api.czr_currentSkopesCollection( collection )
|
||||
//2) When the api.czr_currentSkopesCollection() Value is set => instantiates the missing skope
|
||||
//3) Set the skope layout view when the skope embedded promise is resolved
|
||||
if ( serverControlParams.isDevMode ) {
|
||||
api.czr_skopeBase.updateSkopeCollection( skope_server_data.czr_new_skopes , preview.channel() );
|
||||
} else {
|
||||
try {
|
||||
api.czr_skopeBase.updateSkopeCollection( skope_server_data.czr_new_skopes , preview.channel() );
|
||||
} catch ( er ) {
|
||||
console.log('UPDATE SKOPE COLLECTION ERROR', er);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//@return void()
|
||||
// => refresh skope notice below the skope switcher title
|
||||
// => refresh bottom skope infos in the preview
|
||||
// var _refreshSkopeInfosNotices = function() {
|
||||
// console.log('REFRESH SKOPE TITLE IF NEEDED ?');
|
||||
// //WRITE THE CURRENT SKOPE TITLE
|
||||
// //self._writeCurrentSkopeTitle();
|
||||
// };
|
||||
|
||||
//Always wait for the initial collection to be populated
|
||||
api.czr_initialSkopeCollectionPopulated.then( function() {
|
||||
//console.log('INITIAL SKOPE COLLECTION POPULATED');
|
||||
if ( ! _.has( skope_server_data, 'czr_new_skopes' ) || _.isEmpty( skope_server_data.czr_new_skopes ) ) {
|
||||
api.errorLog( 'Missing skope data after refresh', skope_server_data );
|
||||
}
|
||||
|
||||
// set the local and group skope id
|
||||
api.czr_activeSkopes( {
|
||||
'local' : self.getSkopeProperty( 'skope_id', 'local' ),
|
||||
'group' : self.getSkopeProperty( 'skope_id', 'group' )
|
||||
});
|
||||
|
||||
// if ( ! _.isEmpty( previousSkopeCollection ) ) { //Rewrite the title when the local skope has changed
|
||||
// var _prevLoc = _.findWhere( previousSkopeCollection , { skope : 'local' } ).opt_name,
|
||||
// _newLoc =_.findWhere( skope_server_data.czr_new_skopes, { skope : 'local' } ).opt_name;
|
||||
|
||||
// if ( _newLoc !== _prevLoc ) {
|
||||
// //REFRESH SKOPE INFOS IN TITLE AND PREVIEW FRAME
|
||||
// _refreshSkopeInfosNotices();
|
||||
// }
|
||||
// }
|
||||
|
||||
});
|
||||
});//api.previewer.bind
|
||||
});//api.bind( 'ready'
|
||||
|
||||
|
||||
//CURRENT SKOPE COLLECTION LISTENER
|
||||
//The skope collection is set on 'czr-new-skopes-synced' triggered by the preview
|
||||
//setup the callbacks of the skope collection update
|
||||
//on init and on preview change : the collection of skopes is populated with new skopes
|
||||
//=> instanciate the relevant skope object + render them
|
||||
api.czr_currentSkopesCollection.bind( function( to, from ) {
|
||||
return self.currentSkopesCollectionReact( to, from );
|
||||
}, { deferred : true });
|
||||
|
||||
///////////////////// VARIOUS /////////////////////
|
||||
//DECLARE THE LIST OF CONTROL TYPES FOR WHICH THE VIEW IS REFRESHED ON CHANGE
|
||||
//self.refreshedControls = [ 'czr_cropped_image'];// [ 'czr_cropped_image', 'czr_multi_module', 'czr_module' ];
|
||||
api.trigger( 'czr_skopeBase_initialized' );
|
||||
}//initialize
|
||||
});//$.extend()
|
||||
})( wp.customize , jQuery, _);
|
||||
@@ -0,0 +1,49 @@
|
||||
//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
( function ( api, $, _ ) {
|
||||
$.extend( CZRSkopeBaseMths, {
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/// <SKOPE HELPERSS>
|
||||
// @return string
|
||||
getSkopeProperty : function( what, skope_level ) {
|
||||
what = what || 'skope_id';
|
||||
skope_level = skope_level || 'local';
|
||||
var _skope_data = _.findWhere( api.czr_currentSkopesCollection(), { skope : skope_level });
|
||||
if ( _.isEmpty( _skope_data ) ){
|
||||
// display an error message if local skope not found. Should always be defined.
|
||||
if ( 'local' == skope_level ) {
|
||||
api.errorLog( "getSkopeProperty => local skope missing, returning not_set" );
|
||||
}
|
||||
return "_skope_not_set_";//for example when trying to get a group skope_id in a context where there can't be a group skope like home or search.
|
||||
} else if ( !_.has( _skope_data, what ) ) {
|
||||
api.errorLog( "getSkopeProperty => " + what + " property does not exist" );
|
||||
return "_skope_not_set_";
|
||||
} else {
|
||||
return _skope_data[ what ];
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
//@return string
|
||||
firstToUpperCase : function( str ) {
|
||||
return ! _.isString( str ) ? '' : str.substr(0, 1).toUpperCase() + str.substr(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// //@return string
|
||||
// buildSkopeLink : function( skope_id ) {
|
||||
// if ( ! api.czr_skope.has( skope_id ) ) {
|
||||
// api.errorLog( 'buildSkopeLink : the requested skope id is not registered : ' + skope_id );
|
||||
// return '';
|
||||
// }
|
||||
// var _link_title = [ serverControlParams.i18n.skope['Switch to scope'], api.czr_skope( skope_id )().title ].join(' : ');
|
||||
// return [
|
||||
// '<span class="czr-skope-switch" title=" ' + _link_title + '" data-skope-id="' + skope_id + '">',
|
||||
// api.czr_skope( skope_id )().title,
|
||||
// '</span>'
|
||||
// ].join( '' );
|
||||
// },
|
||||
});//$.extend
|
||||
})( wp.customize , jQuery, _ );
|
||||
@@ -0,0 +1,132 @@
|
||||
//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
(function ( api, $, _ ) {
|
||||
$.extend( CZRSkopeBaseMths, {
|
||||
//Fired on 'czr-new-skopes-synced' triggered by the preview, each time the preview is refreshed.
|
||||
//On a Save Action, api.czr_savedDirties has been populated =>
|
||||
// 1) check if the server sends the same saved values
|
||||
// 2) update the skope db properties with the latests saved ones
|
||||
//
|
||||
//A skope candidate is structured this way :
|
||||
//{
|
||||
// id:""
|
||||
// long_title:"Site wide options"
|
||||
// obj_id:""
|
||||
// skope:"global"
|
||||
// title:"Site wide options"
|
||||
//}
|
||||
//@see api_overrides
|
||||
updateSkopeCollection : function( sent_collection ) {
|
||||
var self = this,
|
||||
_api_ready_collection = [];
|
||||
|
||||
//normalize each sent skopes
|
||||
_.each( sent_collection, function( _skope ) {
|
||||
var skope_candidate = $.extend( true, {}, _skope );//deep clone to avoid any shared references
|
||||
_api_ready_collection.push( self.prepareSkopeForAPI( skope_candidate ) );
|
||||
});
|
||||
|
||||
//set the new collection of current skopes
|
||||
//=> this will instantiate the not instantiated skopes
|
||||
api.czr_currentSkopesCollection( _api_ready_collection );
|
||||
|
||||
// set the group skope id
|
||||
//console.log( "SKOPE COLLECTION UPDATED", api.czr_currentSkopesCollection() );
|
||||
},
|
||||
|
||||
|
||||
//@param skope_candidate
|
||||
////A skope candidate is structured this way :
|
||||
//{
|
||||
// id:""
|
||||
// long_title:"Site wide options"
|
||||
// obj_id:""
|
||||
// skope:"global"
|
||||
// title:"Site wide options"
|
||||
//}
|
||||
prepareSkopeForAPI : function( skope_candidate ) {
|
||||
if ( ! _.isObject( skope_candidate ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope must be an object to be API ready');
|
||||
}
|
||||
var api_ready_skope = skope_candidate;
|
||||
|
||||
_.each( FlatSkopeLocalizedData.defaultSkopeModel , function( _value, _key ) {
|
||||
var _candidate_val = skope_candidate[_key];
|
||||
switch( _key ) {
|
||||
case 'title' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope title property must a string');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'long_title' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope title property must a string');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'ctx_title' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope context title property must a string');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'skope' :
|
||||
if ( ! _.isString( _candidate_val ) || _.isEmpty( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope "skope" property must a string not empty');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'obj_id' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : invalid "obj_id" for skope ' + _candidate_val.skope );
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'skope_id' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : invalid "skope_key" for skope ' + _candidate_val.skope );
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'values' :
|
||||
// if ( ! _.isString( _candidate_val ) ) {
|
||||
// throw new Error('prepareSkopeForAPI : invalid "values" for skope ' + _candidate_val.skope );
|
||||
// }
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
default :
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
}//switch
|
||||
});
|
||||
|
||||
//Finally, generate the id and the title
|
||||
api_ready_skope.id = api_ready_skope.skope + '_' + api_ready_skope.skope_id;
|
||||
if ( ! _.isString( api_ready_skope.id ) || _.isEmpty( api_ready_skope.id ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope id must a string not empty');
|
||||
}
|
||||
if ( ! _.isString( api_ready_skope.title ) || _.isEmpty( api_ready_skope.title ) ) {
|
||||
api_ready_skope.title = api_ready_skope.id;
|
||||
api_ready_skope.long_title = api_ready_skope.id;
|
||||
}
|
||||
return api_ready_skope;
|
||||
},
|
||||
|
||||
|
||||
//cb of api.czr_currentSkopesCollection.callbacks
|
||||
//fired in initialize
|
||||
currentSkopesCollectionReact : function( to, from ) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
//ON INITIAL COLLECTION POPULATE, RESOLVE THE DEFERRED STATE
|
||||
//=> this way we can defer earlier actions.
|
||||
//For example when autofocus is requested, the section might be expanded before the initial skope collection is sent from the preview.
|
||||
if ( _.isEmpty( from ) && ! _.isEmpty( to ) ) {
|
||||
api.czr_initialSkopeCollectionPopulated.resolve();
|
||||
}
|
||||
return dfd.resolve( 'changed' ).promise();
|
||||
}//listenToSkopeCollection()
|
||||
|
||||
});//$.extend()
|
||||
})( wp.customize , jQuery, _);
|
||||
@@ -0,0 +1,13 @@
|
||||
//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
(function ( api, $ ) {
|
||||
// Skope
|
||||
$.extend( CZRSkopeBaseMths, api.Events );
|
||||
var CZR_SkopeBase = api.Class.extend( CZRSkopeBaseMths );
|
||||
|
||||
// Schedule skope instantiation on api ready
|
||||
// api.bind( 'ready' , function() {
|
||||
// api.czr_skopeBase = new api.CZR_SkopeBase();
|
||||
// });
|
||||
api.czr_skopeBase = new CZR_SkopeBase();
|
||||
})( wp.customize, jQuery );
|
||||
@@ -0,0 +1,323 @@
|
||||
//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
(function ( api, $, _ ) {
|
||||
$.extend( CZRSkopeBaseMths, {
|
||||
|
||||
initialize: function() {
|
||||
var self = this;
|
||||
///////////////////// DEFINITIONS /////////////////////
|
||||
|
||||
//Store the state of the first skope collection state
|
||||
api.czr_initialSkopeCollectionPopulated = $.Deferred();
|
||||
|
||||
//the czr_skopeCollection stores all skopes instantiated by the user
|
||||
//this collection is not updated directly
|
||||
//=> it's updated on skope() instance change
|
||||
api.czr_skopeCollection = new api.Value([]);//all available skope, including the current skopes
|
||||
//the current skopes collection get updated each time the 'czr-new-skopes-synced' event is triggered on the api by the preview
|
||||
api.czr_currentSkopesCollection = new api.Value([]);
|
||||
|
||||
//the currently active skopes
|
||||
api.czr_activeSkopes = new api.Value( { local : '', group : ''} );
|
||||
|
||||
|
||||
|
||||
///////////////////// SKOPE COLLECTIONS SYNCHRONISATION AND LISTENERS /////////////////////
|
||||
//LISTEN TO SKOPE SYNC => UPDATE SKOPE COLLECTION ON START AND ON EACH REFRESH
|
||||
//the sent data look like :
|
||||
//{
|
||||
// czr_new_skopes : _wpCustomizeSettings.czr_new_skopes || [],
|
||||
// isChangesetDirty : boolean
|
||||
// }
|
||||
api.bind( 'ready' , function() {
|
||||
api.previewer.bind( 'czr-new-skopes-synced', function( skope_server_data ) {
|
||||
if ( serverControlParams.isDevMode ) {
|
||||
api.infoLog( 'API SKOPE SYNCED', skope_server_data );
|
||||
}
|
||||
|
||||
// set the currently active stylesheet
|
||||
if ( ! _.has( skope_server_data, 'czr_stylesheet') ) {
|
||||
api.errorLog( "On 'czr-new-skopes-synced' : missing stylesheet in the server data" );
|
||||
return;
|
||||
}
|
||||
|
||||
api.czr_skopeBase.stylesheet = api.czr_skopeBase.stylesheet || new api.Value( api.settings.theme.stylesheet );
|
||||
api.czr_skopeBase.stylesheet( skope_server_data.czr_stylesheet );
|
||||
|
||||
//api.consoleLog('czr-skopes-ready DATA', skope_server_data );
|
||||
var preview = this,
|
||||
previousSkopeCollection = api.czr_currentSkopesCollection();
|
||||
//initialize skopes with the server sent skope_server_data
|
||||
//if skope has not been initialized yet and the server sent wrong skope_server_data, then reject the skope ready promise()
|
||||
if ( ! _.has( skope_server_data, 'czr_new_skopes') ) {
|
||||
api.errorLog( "On 'czr-new-skopes-synced' : missing skopes in the server data" );
|
||||
return;
|
||||
}
|
||||
|
||||
// If no "group" skope has been sent, check if we should have one
|
||||
// array( 'home', 'search', '404', 'date' ) <= have no group
|
||||
if ( _.isEmpty( _.findWhere( skope_server_data.czr_new_skopes, { skope : 'group' } ) ) ){
|
||||
var _local_ = _.findWhere( skope_server_data.czr_new_skopes, { skope : 'local' } );
|
||||
if ( ! _.isEmpty( _local_ ) && ! _.contains( FlatSkopeLocalizedData.noGroupSkopeList, _local_.level ) ) {
|
||||
api.errorLog( 'No group level skope sent while there should be one' );
|
||||
}
|
||||
}
|
||||
|
||||
//1) Updated the collection with normalized skopes => prepareSkopeForAPI + api.czr_currentSkopesCollection( collection )
|
||||
//2) When the api.czr_currentSkopesCollection() Value is set => instantiates the missing skope
|
||||
//3) Set the skope layout view when the skope embedded promise is resolved
|
||||
if ( serverControlParams.isDevMode ) {
|
||||
api.czr_skopeBase.updateSkopeCollection( skope_server_data.czr_new_skopes , preview.channel() );
|
||||
} else {
|
||||
try {
|
||||
api.czr_skopeBase.updateSkopeCollection( skope_server_data.czr_new_skopes , preview.channel() );
|
||||
} catch ( er ) {
|
||||
console.log('UPDATE SKOPE COLLECTION ERROR', er);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//@return void()
|
||||
// => refresh skope notice below the skope switcher title
|
||||
// => refresh bottom skope infos in the preview
|
||||
// var _refreshSkopeInfosNotices = function() {
|
||||
// console.log('REFRESH SKOPE TITLE IF NEEDED ?');
|
||||
// //WRITE THE CURRENT SKOPE TITLE
|
||||
// //self._writeCurrentSkopeTitle();
|
||||
// };
|
||||
|
||||
//Always wait for the initial collection to be populated
|
||||
api.czr_initialSkopeCollectionPopulated.then( function() {
|
||||
//console.log('INITIAL SKOPE COLLECTION POPULATED');
|
||||
if ( ! _.has( skope_server_data, 'czr_new_skopes' ) || _.isEmpty( skope_server_data.czr_new_skopes ) ) {
|
||||
api.errorLog( 'Missing skope data after refresh', skope_server_data );
|
||||
}
|
||||
|
||||
// set the local and group skope id
|
||||
api.czr_activeSkopes( {
|
||||
'local' : self.getSkopeProperty( 'skope_id', 'local' ),
|
||||
'group' : self.getSkopeProperty( 'skope_id', 'group' )
|
||||
});
|
||||
|
||||
// if ( ! _.isEmpty( previousSkopeCollection ) ) { //Rewrite the title when the local skope has changed
|
||||
// var _prevLoc = _.findWhere( previousSkopeCollection , { skope : 'local' } ).opt_name,
|
||||
// _newLoc =_.findWhere( skope_server_data.czr_new_skopes, { skope : 'local' } ).opt_name;
|
||||
|
||||
// if ( _newLoc !== _prevLoc ) {
|
||||
// //REFRESH SKOPE INFOS IN TITLE AND PREVIEW FRAME
|
||||
// _refreshSkopeInfosNotices();
|
||||
// }
|
||||
// }
|
||||
|
||||
});
|
||||
});//api.previewer.bind
|
||||
});//api.bind( 'ready'
|
||||
|
||||
|
||||
//CURRENT SKOPE COLLECTION LISTENER
|
||||
//The skope collection is set on 'czr-new-skopes-synced' triggered by the preview
|
||||
//setup the callbacks of the skope collection update
|
||||
//on init and on preview change : the collection of skopes is populated with new skopes
|
||||
//=> instanciate the relevant skope object + render them
|
||||
api.czr_currentSkopesCollection.bind( function( to, from ) {
|
||||
return self.currentSkopesCollectionReact( to, from );
|
||||
}, { deferred : true });
|
||||
|
||||
///////////////////// VARIOUS /////////////////////
|
||||
//DECLARE THE LIST OF CONTROL TYPES FOR WHICH THE VIEW IS REFRESHED ON CHANGE
|
||||
//self.refreshedControls = [ 'czr_cropped_image'];// [ 'czr_cropped_image', 'czr_multi_module', 'czr_module' ];
|
||||
api.trigger( 'czr_skopeBase_initialized' );
|
||||
}//initialize
|
||||
});//$.extend()
|
||||
})( wp.customize , jQuery, _);//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
( function ( api, $, _ ) {
|
||||
$.extend( CZRSkopeBaseMths, {
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/// <SKOPE HELPERSS>
|
||||
// @return string
|
||||
getSkopeProperty : function( what, skope_level ) {
|
||||
what = what || 'skope_id';
|
||||
skope_level = skope_level || 'local';
|
||||
var _skope_data = _.findWhere( api.czr_currentSkopesCollection(), { skope : skope_level });
|
||||
if ( _.isEmpty( _skope_data ) ){
|
||||
// display an error message if local skope not found. Should always be defined.
|
||||
if ( 'local' == skope_level ) {
|
||||
api.errorLog( "getSkopeProperty => local skope missing, returning not_set" );
|
||||
}
|
||||
return "_skope_not_set_";//for example when trying to get a group skope_id in a context where there can't be a group skope like home or search.
|
||||
} else if ( !_.has( _skope_data, what ) ) {
|
||||
api.errorLog( "getSkopeProperty => " + what + " property does not exist" );
|
||||
return "_skope_not_set_";
|
||||
} else {
|
||||
return _skope_data[ what ];
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
//@return string
|
||||
firstToUpperCase : function( str ) {
|
||||
return ! _.isString( str ) ? '' : str.substr(0, 1).toUpperCase() + str.substr(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// //@return string
|
||||
// buildSkopeLink : function( skope_id ) {
|
||||
// if ( ! api.czr_skope.has( skope_id ) ) {
|
||||
// api.errorLog( 'buildSkopeLink : the requested skope id is not registered : ' + skope_id );
|
||||
// return '';
|
||||
// }
|
||||
// var _link_title = [ serverControlParams.i18n.skope['Switch to scope'], api.czr_skope( skope_id )().title ].join(' : ');
|
||||
// return [
|
||||
// '<span class="czr-skope-switch" title=" ' + _link_title + '" data-skope-id="' + skope_id + '">',
|
||||
// api.czr_skope( skope_id )().title,
|
||||
// '</span>'
|
||||
// ].join( '' );
|
||||
// },
|
||||
});//$.extend
|
||||
})( wp.customize , jQuery, _ );//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
(function ( api, $, _ ) {
|
||||
$.extend( CZRSkopeBaseMths, {
|
||||
//Fired on 'czr-new-skopes-synced' triggered by the preview, each time the preview is refreshed.
|
||||
//On a Save Action, api.czr_savedDirties has been populated =>
|
||||
// 1) check if the server sends the same saved values
|
||||
// 2) update the skope db properties with the latests saved ones
|
||||
//
|
||||
//A skope candidate is structured this way :
|
||||
//{
|
||||
// id:""
|
||||
// long_title:"Site wide options"
|
||||
// obj_id:""
|
||||
// skope:"global"
|
||||
// title:"Site wide options"
|
||||
//}
|
||||
//@see api_overrides
|
||||
updateSkopeCollection : function( sent_collection ) {
|
||||
var self = this,
|
||||
_api_ready_collection = [];
|
||||
|
||||
//normalize each sent skopes
|
||||
_.each( sent_collection, function( _skope ) {
|
||||
var skope_candidate = $.extend( true, {}, _skope );//deep clone to avoid any shared references
|
||||
_api_ready_collection.push( self.prepareSkopeForAPI( skope_candidate ) );
|
||||
});
|
||||
|
||||
//set the new collection of current skopes
|
||||
//=> this will instantiate the not instantiated skopes
|
||||
api.czr_currentSkopesCollection( _api_ready_collection );
|
||||
|
||||
// set the group skope id
|
||||
//console.log( "SKOPE COLLECTION UPDATED", api.czr_currentSkopesCollection() );
|
||||
},
|
||||
|
||||
|
||||
//@param skope_candidate
|
||||
////A skope candidate is structured this way :
|
||||
//{
|
||||
// id:""
|
||||
// long_title:"Site wide options"
|
||||
// obj_id:""
|
||||
// skope:"global"
|
||||
// title:"Site wide options"
|
||||
//}
|
||||
prepareSkopeForAPI : function( skope_candidate ) {
|
||||
if ( ! _.isObject( skope_candidate ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope must be an object to be API ready');
|
||||
}
|
||||
var api_ready_skope = skope_candidate;
|
||||
|
||||
_.each( FlatSkopeLocalizedData.defaultSkopeModel , function( _value, _key ) {
|
||||
var _candidate_val = skope_candidate[_key];
|
||||
switch( _key ) {
|
||||
case 'title' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope title property must a string');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'long_title' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope title property must a string');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'ctx_title' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope context title property must a string');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'skope' :
|
||||
if ( ! _.isString( _candidate_val ) || _.isEmpty( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope "skope" property must a string not empty');
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'obj_id' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : invalid "obj_id" for skope ' + _candidate_val.skope );
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'skope_id' :
|
||||
if ( ! _.isString( _candidate_val ) ) {
|
||||
throw new Error('prepareSkopeForAPI : invalid "skope_key" for skope ' + _candidate_val.skope );
|
||||
}
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
case 'values' :
|
||||
// if ( ! _.isString( _candidate_val ) ) {
|
||||
// throw new Error('prepareSkopeForAPI : invalid "values" for skope ' + _candidate_val.skope );
|
||||
// }
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
default :
|
||||
api_ready_skope[_key] = _candidate_val;
|
||||
break;
|
||||
}//switch
|
||||
});
|
||||
|
||||
//Finally, generate the id and the title
|
||||
api_ready_skope.id = api_ready_skope.skope + '_' + api_ready_skope.skope_id;
|
||||
if ( ! _.isString( api_ready_skope.id ) || _.isEmpty( api_ready_skope.id ) ) {
|
||||
throw new Error('prepareSkopeForAPI : a skope id must a string not empty');
|
||||
}
|
||||
if ( ! _.isString( api_ready_skope.title ) || _.isEmpty( api_ready_skope.title ) ) {
|
||||
api_ready_skope.title = api_ready_skope.id;
|
||||
api_ready_skope.long_title = api_ready_skope.id;
|
||||
}
|
||||
return api_ready_skope;
|
||||
},
|
||||
|
||||
|
||||
//cb of api.czr_currentSkopesCollection.callbacks
|
||||
//fired in initialize
|
||||
currentSkopesCollectionReact : function( to, from ) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
//ON INITIAL COLLECTION POPULATE, RESOLVE THE DEFERRED STATE
|
||||
//=> this way we can defer earlier actions.
|
||||
//For example when autofocus is requested, the section might be expanded before the initial skope collection is sent from the preview.
|
||||
if ( _.isEmpty( from ) && ! _.isEmpty( to ) ) {
|
||||
api.czr_initialSkopeCollectionPopulated.resolve();
|
||||
}
|
||||
return dfd.resolve( 'changed' ).promise();
|
||||
}//listenToSkopeCollection()
|
||||
|
||||
});//$.extend()
|
||||
})( wp.customize , jQuery, _);//@global serverControlParams
|
||||
var CZRSkopeBaseMths = CZRSkopeBaseMths || {};
|
||||
(function ( api, $ ) {
|
||||
// Skope
|
||||
$.extend( CZRSkopeBaseMths, api.Events );
|
||||
var CZR_SkopeBase = api.Class.extend( CZRSkopeBaseMths );
|
||||
|
||||
// Schedule skope instantiation on api ready
|
||||
// api.bind( 'ready' , function() {
|
||||
// api.czr_skopeBase = new api.CZR_SkopeBase();
|
||||
// });
|
||||
api.czr_skopeBase = new CZR_SkopeBase();
|
||||
})( wp.customize, jQuery );
|
||||
@@ -0,0 +1 @@
|
||||
var CZRSkopeBaseMths=CZRSkopeBaseMths||{};!function(t,e,s){e.extend(CZRSkopeBaseMths,{initialize:function(){var r=this;t.czr_initialSkopeCollectionPopulated=e.Deferred(),t.czr_skopeCollection=new t.Value([]),t.czr_currentSkopesCollection=new t.Value([]),t.czr_activeSkopes=new t.Value({local:"",group:""}),t.bind("ready",function(){t.previewer.bind("czr-new-skopes-synced",function(e){if(serverControlParams.isDevMode&&t.infoLog("API SKOPE SYNCED",e),s.has(e,"czr_stylesheet")){t.czr_skopeBase.stylesheet=t.czr_skopeBase.stylesheet||new t.Value(t.settings.theme.stylesheet),t.czr_skopeBase.stylesheet(e.czr_stylesheet);t.czr_currentSkopesCollection();if(s.has(e,"czr_new_skopes")){if(s.isEmpty(s.findWhere(e.czr_new_skopes,{skope:"group"}))){var o=s.findWhere(e.czr_new_skopes,{skope:"local"});s.isEmpty(o)||s.contains(FlatSkopeLocalizedData.noGroupSkopeList,o.level)||t.errorLog("No group level skope sent while there should be one")}if(serverControlParams.isDevMode)t.czr_skopeBase.updateSkopeCollection(e.czr_new_skopes,this.channel());else try{t.czr_skopeBase.updateSkopeCollection(e.czr_new_skopes,this.channel())}catch(e){return void console.log("UPDATE SKOPE COLLECTION ERROR",e)}t.czr_initialSkopeCollectionPopulated.then(function(){s.has(e,"czr_new_skopes")&&!s.isEmpty(e.czr_new_skopes)||t.errorLog("Missing skope data after refresh",e),t.czr_activeSkopes({local:r.getSkopeProperty("skope_id","local"),group:r.getSkopeProperty("skope_id","group")})})}else t.errorLog("On 'czr-new-skopes-synced' : missing skopes in the server data")}else t.errorLog("On 'czr-new-skopes-synced' : missing stylesheet in the server data")})}),t.czr_currentSkopesCollection.bind(function(e,o){return r.currentSkopesCollectionReact(e,o)},{deferred:!0}),t.trigger("czr_skopeBase_initialized")}})}(wp.customize,jQuery,_);CZRSkopeBaseMths=CZRSkopeBaseMths||{};!function(t,e,s){e.extend(CZRSkopeBaseMths,{getSkopeProperty:function(e,o){e=e||"skope_id",o=o||"local";var r=s.findWhere(t.czr_currentSkopesCollection(),{skope:o});return s.isEmpty(r)?("local"==o&&t.errorLog("getSkopeProperty => local skope missing, returning not_set"),"_skope_not_set_"):s.has(r,e)?r[e]:(t.errorLog("getSkopeProperty => "+e+" property does not exist"),"_skope_not_set_")},firstToUpperCase:function(e){return s.isString(e)?e.substr(0,1).toUpperCase()+e.substr(1):""}})}(wp.customize,jQuery,_);CZRSkopeBaseMths=CZRSkopeBaseMths||{};!function(s,i,p){i.extend(CZRSkopeBaseMths,{updateSkopeCollection:function(e){var r=this,t=[];p.each(e,function(e){var o=i.extend(!0,{},e);t.push(r.prepareSkopeForAPI(o))}),s.czr_currentSkopesCollection(t)},prepareSkopeForAPI:function(t){if(!p.isObject(t))throw new Error("prepareSkopeForAPI : a skope must be an object to be API ready");var s=t;if(p.each(FlatSkopeLocalizedData.defaultSkopeModel,function(e,o){var r=t[o];switch(o){case"title":case"long_title":if(!p.isString(r))throw new Error("prepareSkopeForAPI : a skope title property must a string");s[o]=r;break;case"ctx_title":if(!p.isString(r))throw new Error("prepareSkopeForAPI : a skope context title property must a string");s[o]=r;break;case"skope":if(!p.isString(r)||p.isEmpty(r))throw new Error('prepareSkopeForAPI : a skope "skope" property must a string not empty');s[o]=r;break;case"obj_id":if(!p.isString(r))throw new Error('prepareSkopeForAPI : invalid "obj_id" for skope '+r.skope);s[o]=r;break;case"skope_id":if(!p.isString(r))throw new Error('prepareSkopeForAPI : invalid "skope_key" for skope '+r.skope);s[o]=r;break;case"values":default:s[o]=r}}),s.id=s.skope+"_"+s.skope_id,!p.isString(s.id)||p.isEmpty(s.id))throw new Error("prepareSkopeForAPI : a skope id must a string not empty");return p.isString(s.title)&&!p.isEmpty(s.title)||(s.title=s.id,s.long_title=s.id),s},currentSkopesCollectionReact:function(e,o){var r=i.Deferred();return p.isEmpty(o)&&!p.isEmpty(e)&&s.czr_initialSkopeCollectionPopulated.resolve(),r.resolve("changed").promise()}})}(wp.customize,jQuery,_);CZRSkopeBaseMths=CZRSkopeBaseMths||{};!function(e,o){jQuery.extend(CZRSkopeBaseMths,e.Events);var r=e.Class.extend(CZRSkopeBaseMths);e.czr_skopeBase=new r}(wp.customize);
|
||||
@@ -0,0 +1,924 @@
|
||||
<?php
|
||||
namespace Nimble;
|
||||
if ( did_action('nimble_skope_loaded') ) {
|
||||
if ( ( defined( 'CZR_DEV' ) && CZR_DEV ) || ( defined( 'NIMBLE_DEV' ) && NIMBLE_DEV ) ) {
|
||||
error_log( __FILE__ . ' => The skope has already been loaded' );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the namsepace as a global so we can use it when fired from another theme/plugin using the fmk
|
||||
global $czr_skope_namespace;
|
||||
$czr_skope_namespace = __NAMESPACE__ . '\\';
|
||||
|
||||
do_action( 'nimble_skope_loaded' );
|
||||
|
||||
//Creates a new instance
|
||||
function Flat_Skop_Base( $params = array() ) {
|
||||
return Flat_Skop_Base::skp_get_instance( $params );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// <DEFINITIONS>
|
||||
// THE SKOPE MODEL
|
||||
function skp_get_default_skope_model() {
|
||||
return array(
|
||||
'title' => '',
|
||||
'long_title' => '',
|
||||
'ctx_title' => '',
|
||||
'id' => '',
|
||||
'skope' => '',
|
||||
//'level' => '',
|
||||
'obj_id' => '',
|
||||
'skope_id' => '',
|
||||
'values' => ''
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// those contexts have no group
|
||||
function skp_get_no_group_skope_list() {
|
||||
return array( 'home', 'search', '404', 'date' );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// </DEFINITIONS>
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// HELPERS
|
||||
|
||||
function skp_trim_text( $text, $text_length, $more ) {
|
||||
if ( !$text )
|
||||
return '';
|
||||
|
||||
$text = trim( strip_tags( $text ) );
|
||||
|
||||
if ( !$text_length )
|
||||
return $text;
|
||||
|
||||
$end_substr = $_text_length = strlen( $text );
|
||||
|
||||
if ( $_text_length > $text_length ){
|
||||
$end_substr = strpos( $text, ' ' , $text_length);
|
||||
$end_substr = ( $end_substr !== FALSE ) ? $end_substr : $text_length;
|
||||
$text = substr( $text , 0 , $end_substr );
|
||||
}
|
||||
return ( ( $end_substr < $text_length ) && $more ) ? $text : $text . ' ' .$more ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// SKOPE HELPERS
|
||||
/**
|
||||
* Return the current skope
|
||||
* Front / Back agnostic.
|
||||
* @param $_requesting_wot is a string with the following possible values : 'meta_type' (like post) , 'type' (like page), 'id' (like page id)
|
||||
* @param $_return_string string param stating if the return value should be a string or an array
|
||||
* @param $requested_parts is an array of parts looking like
|
||||
* Array
|
||||
* (
|
||||
* [meta_type] => post
|
||||
* [type] => page
|
||||
* [obj_id] => 9
|
||||
* )
|
||||
* USE CASE when $requested_parts is passed : when a post gets deleted, we need to clean any skope posts associated. That's when we invoke skp_get_skope( null, true, $requested_parts )
|
||||
* @return a string of all concatenated ctx parts (default) 0R an array of the ctx parts
|
||||
*/
|
||||
function skp_get_skope( $_requesting_wot = null, $_return_string = true, $requested_parts = array() ) {
|
||||
//skope builder from the wp $query
|
||||
//=> returns :
|
||||
// the meta_type : post, tax, user
|
||||
// the type : post_type, taxonomy name, author
|
||||
// the id : post id, term id, user id
|
||||
|
||||
// if $parts are provided, use them.
|
||||
// Note that the value of skp_get_query_skope() is cached when get the first time for better performance
|
||||
$parts = ( is_array( $requested_parts ) && !empty( $requested_parts ) ) ? $requested_parts : skp_get_query_skope();
|
||||
|
||||
// error_log( '<SKOPE PARTS>' );
|
||||
// error_log( print_r( $parts, true ) );
|
||||
// error_log( '</SKOPE PARTS>' );
|
||||
|
||||
$_return = array();
|
||||
$meta_type = $type = $obj_id = false;
|
||||
|
||||
if ( is_array( $parts ) && !empty( $parts ) ) {
|
||||
$meta_type = isset( $parts['meta_type'] ) ? $parts['meta_type'] : false;
|
||||
$type = isset( $parts['type'] ) ? $parts['type'] : false;
|
||||
$obj_id = isset( $parts['obj_id'] ) ? $parts['obj_id'] : false;
|
||||
}
|
||||
|
||||
switch ( $_requesting_wot ) {
|
||||
case 'meta_type':
|
||||
if ( false !== $meta_type ) {
|
||||
$_return = array( "meta_type" => "{$meta_type}" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'type':
|
||||
if ( false !== $type ) {
|
||||
$_return = array( "type" => "{$type}" );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'id':
|
||||
if ( false !== $obj_id ) {
|
||||
$_return = array( "id" => "{$obj_id}" );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//LOCAL
|
||||
//here we don't check if there's a type this is the case where there must be one when a meta type (post, tax, user) is defined.
|
||||
//typically the skope will look like post_page_25
|
||||
if ( false !== $meta_type && false !== $obj_id ) {
|
||||
$_return = array( "meta_type" => "{$meta_type}" , "type" => "{$type}", "id" => "{$obj_id}" );
|
||||
}
|
||||
//GROUP
|
||||
else if ( false !== $meta_type && !$obj_id ) {
|
||||
$_return = array( "meta_type" => "{$meta_type}", "type" => "{$type}" );
|
||||
}
|
||||
//LOCAL WITH NO GROUP : home ( when home displays "Your latests posts" ) , 404, search, date, post type archive
|
||||
else if ( false !== $obj_id ) {
|
||||
$_return = array( "id" => "{$obj_id}" );
|
||||
}
|
||||
else {
|
||||
// don't print the skope error log if not in dev mode
|
||||
// fixes : https://github.com/presscustomizr/czr-skope/issues/1
|
||||
if ( defined( 'NIMBLE_DEV' ) && NIMBLE_DEV ) {
|
||||
// the favicon request break skope building, so skip this case
|
||||
// see https://github.com/presscustomizr/nimble-builder/issues/658
|
||||
if ( '/favicon.ico' !== $_SERVER['REQUEST_URI'] ) {
|
||||
error_log( __FUNCTION__ . ' error when building the local skope, no object_id provided.');
|
||||
error_log( print_r( $parts, true) );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//return the parts array if not a string requested
|
||||
if ( !$_return_string ) {
|
||||
return $_return;
|
||||
}
|
||||
|
||||
//don't go further if not an array or empty
|
||||
if ( !is_array( $_return ) || ( is_array( $_return ) && empty( $_return ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
//if a specific part of the ctx is requested, don't concatenate
|
||||
//return the part if exists
|
||||
if ( !is_null( $_requesting_wot ) ) {
|
||||
return isset( $_return[ $_requesting_wot ] ) ? $_return[ $_requesting_wot ] : '';
|
||||
}
|
||||
|
||||
//generate the ctx string from the array of ctx_parts
|
||||
$_concat = "";
|
||||
foreach ( $_return as $_key => $_part ) {
|
||||
if ( empty( $_concat) ) {
|
||||
$_concat .= $_part;
|
||||
} else {
|
||||
$_concat .= '_'. $_part;
|
||||
}
|
||||
}
|
||||
return $_concat;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* skope builder from the wp $query
|
||||
* !!has to be fired after 'template_redirect'
|
||||
* Used on front ( not customizing preview ? => @todo make sure of this )
|
||||
* @return array of ctx parts
|
||||
*/
|
||||
function skp_get_query_skope() {
|
||||
//don't call get_queried_object if the $query is not defined yet
|
||||
global $wp_the_query;
|
||||
if ( !isset( $wp_the_query ) || empty( $wp_the_query ) ) {
|
||||
return array();
|
||||
}
|
||||
// is it cached already ?
|
||||
if ( !empty( Flat_Skop_Base()->query_skope ) ) {
|
||||
return Flat_Skop_Base()->query_skope;
|
||||
}
|
||||
|
||||
$queried_object = get_queried_object();
|
||||
|
||||
// error_log( '<GET QUERIED OBJECT>' . gettype( $queried_object ) );
|
||||
// error_log( print_r( $wp_the_query , true ) );
|
||||
// error_log( '</GET QUERIED OBJECT>' );
|
||||
|
||||
$meta_type = $type = $obj_id = false;
|
||||
|
||||
// The queried object is NULL on
|
||||
// - home when displaying the latest posts
|
||||
// - date archives
|
||||
// - 404 page
|
||||
// - search page
|
||||
if ( !is_null( $queried_object ) && is_object( $queried_object ) ) {
|
||||
//post, custom post types, page
|
||||
if ( isset($queried_object->post_type) ) {
|
||||
$meta_type = 'post';
|
||||
$type = $queried_object->post_type;
|
||||
$obj_id = $queried_object->ID;
|
||||
}
|
||||
|
||||
//taxinomies : tags, categories, custom tax type
|
||||
if ( isset($queried_object->taxonomy) && isset($queried_object->term_id) ) {
|
||||
$meta_type = 'tax';
|
||||
$type = $queried_object->taxonomy;
|
||||
$obj_id = $queried_object->term_id;
|
||||
}
|
||||
}
|
||||
|
||||
//author archive page
|
||||
if ( is_author() ) {
|
||||
$meta_type = 'user';
|
||||
$type = 'author';
|
||||
$obj_id = $wp_the_query->get( 'author' );
|
||||
}
|
||||
|
||||
//SKOPES WITH NO GROUPS
|
||||
//post type archive object
|
||||
if ( is_post_type_archive() ) {
|
||||
$obj_id = 'post_type_archive' . '_'. $wp_the_query->get( 'post_type' );
|
||||
}
|
||||
if ( is_404() ) {
|
||||
$obj_id = '404';
|
||||
}
|
||||
if ( is_search() ) {
|
||||
$obj_id = 'search';
|
||||
}
|
||||
if ( is_date() ) {
|
||||
$obj_id = 'date';
|
||||
}
|
||||
|
||||
if ( skp_is_real_home() ) {
|
||||
$obj_id = 'home';
|
||||
// December 2018
|
||||
// when the home page is a page, the skope now includes the page id, instead of being generic as it was since then : skp__post_page_home
|
||||
// This has been introduced to facilitate the compatibility of Nimble Builder with multilanguage plugins like polylang
|
||||
// => Allows user to create a different home page for each languages
|
||||
//
|
||||
// To summarize,
|
||||
// Before dec 2018 :
|
||||
// - home page is blog page => skope_id = skp___home
|
||||
// - home page is page => skope_id = skp__post_page_home
|
||||
//
|
||||
// After Dec 2018
|
||||
// - hope page is blog page => skope_id is unchanged = skp__home
|
||||
// - home page is a page => skope_id is changed to = skp__post_page_{$static_home_page_id}
|
||||
//
|
||||
// This means that if Nimble sections, or any other contextualizations had been made on home when 'page' === get_option( 'show_on_front' ),
|
||||
// for which the corresponding skope_id was skp__post_page_home,
|
||||
// those settings have to be copied in the skp__post_page_{$static_home_page_id} skope settings
|
||||
|
||||
// If we are on the real home page, but displaying a static page then set the static page id as obj_id
|
||||
if ( !is_home() && 'page' === get_option( 'show_on_front' ) ) {
|
||||
$home_page_id = get_option( 'page_on_front' );
|
||||
if ( 0 < $home_page_id ) {
|
||||
$obj_id = $home_page_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cache now
|
||||
if ( did_action( 'wp' ) ) {
|
||||
Flat_Skop_Base()->query_skope = apply_filters( 'skp_get_query_skope' , array( 'meta_type' => $meta_type , 'type' => $type , 'obj_id' => $obj_id ), $queried_object );
|
||||
}
|
||||
|
||||
return Flat_Skop_Base()->query_skope;
|
||||
}
|
||||
|
||||
|
||||
//@return the skope prefix used both when customizing and on front
|
||||
function skp_get_skope_id( $level = 'local' ) {
|
||||
// CACHE THE SKOPE WHEN 'wp' DONE
|
||||
// the skope id is used when filtering the options, called hundreds of times.
|
||||
// We get higher performances with a cached value instead of using the skp_get_skope_id() function on each call.
|
||||
$new_skope_ids = array( 'local' => '_skope_not_set_', 'group' => '_skope_not_set_' );
|
||||
if ( did_action( 'wp' ) ) {
|
||||
if ( empty( Flat_Skop_Base()->current_skope_ids ) ) {
|
||||
$new_skope_ids['local'] = skp_build_skope_id( array( 'skope_string' => skp_get_skope(), 'skope_level' => 'local' ) );
|
||||
$new_skope_ids['group'] = skp_build_skope_id( array( 'skope_level' => 'group' ) );
|
||||
|
||||
Flat_Skop_Base()->current_skope_ids = $new_skope_ids;
|
||||
|
||||
$skope_id_to_return = $new_skope_ids[ $level ];
|
||||
// error_log('<SKOPE ID cached in skp_get_skope_id>');
|
||||
// error_log( print_r( $new_skope_ids, true ) );
|
||||
// error_log('</SKOPE ID cached in skp_get_skope_id>');
|
||||
} else {
|
||||
$new_skope_ids = Flat_Skop_Base()->current_skope_ids;
|
||||
$skope_id_to_return = $new_skope_ids[ $level ];
|
||||
}
|
||||
} else {
|
||||
$skope_id_to_return = array_key_exists( $level, $new_skope_ids ) ? $new_skope_ids[ $level ] : '_skope_not_set_';
|
||||
}
|
||||
// if ( !(bool)did_action( 'wp' ) ) {
|
||||
// sek_error_log('ACTION WP NOT FIRED', did_action('wp'));
|
||||
// }
|
||||
// Jan 2021, while working on https://github.com/presscustomizr/nimble-builder-pro/issues/81
|
||||
// when customizing and firing this function during ajax calls, the check for did_action('wp') will return 0.
|
||||
// => which will lead to skope_id set to '_skope_not_set_'
|
||||
// in order to prevent this, let's get the skope_id value from the customizer posted value when available.
|
||||
if ( skp_is_customizing() && '_skope_not_set_' === $skope_id_to_return && 'local' === $level && !empty($_POST['local_skope_id']) ) {
|
||||
$skope_id_to_return = sanitize_text_field($_POST['local_skope_id']);
|
||||
}
|
||||
// Feb 2021 => added for https://github.com/presscustomizr/nimble-builder/issues/478
|
||||
if ( skp_is_customizing() && '_skope_not_set_' === $skope_id_to_return && 'group' === $level && !empty($_POST['group_skope_id']) ) {
|
||||
$skope_id_to_return = sanitize_text_field($_POST['group_skope_id']);
|
||||
}
|
||||
|
||||
$skope_id_to_return = apply_filters( 'skp_get_skope_id', $skope_id_to_return, $level );
|
||||
|
||||
// At this point, the skope_id should be set
|
||||
if ( '_skope_not_set_' === $skope_id_to_return ) {
|
||||
//error_log( __FUNCTION__ . ' error => skope_id not set for level ' . $level );
|
||||
}
|
||||
// error_log('$skope_id_to_return => ' . $level . ' ' . $skope_id_to_return );
|
||||
// error_log( print_r( Flat_Skop_Base()->current_skope_ids , true ) );
|
||||
return $skope_id_to_return;
|
||||
}
|
||||
|
||||
//@param args = array(
|
||||
// 'skope_string' => skp_get_skope(),
|
||||
// 'skope_type' => $skp_type,
|
||||
// 'skope_level' => 'local'
|
||||
//)
|
||||
//@return string
|
||||
function skp_build_skope_id( $args = array() ) {
|
||||
$skope_id = '_skope_not_set_';
|
||||
|
||||
// normalizes
|
||||
$args = is_array( $args ) ? $args : array();
|
||||
$args = wp_parse_args(
|
||||
$args,
|
||||
array( 'skope_string' => '', 'skope_type' => '', 'skope_level' => '' )
|
||||
);
|
||||
|
||||
// set params if not provided
|
||||
$args['skope_level'] = empty( $args['skope_level'] ) ? 'local' : $args['skope_level'];
|
||||
$args['skope_string'] = ( 'local' == $args['skope_level'] && empty( $args['skope_string'] ) ) ? skp_get_skope() : $args['skope_string'];
|
||||
$args['skope_type'] = ( 'group' == $args['skope_level'] && empty( $args['skope_type'] ) ) ? skp_get_skope( 'type' ) : $args['skope_type'];
|
||||
|
||||
// generate skope_id for two cases : local or group
|
||||
switch( $args[ 'skope_level'] ) {
|
||||
case 'local' :
|
||||
$skope_id = strtolower( NIMBLE_SKOPE_ID_PREFIX . $args[ 'skope_string' ] );
|
||||
break;
|
||||
case 'group' :
|
||||
if ( !empty( $args[ 'skope_type' ] ) ) {
|
||||
$skope_id = strtolower( NIMBLE_SKOPE_ID_PREFIX . 'all_' . $args[ 'skope_type' ] );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $skope_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used when localizing the customizer js params
|
||||
* Can be a post ( post, pages, CPT) , tax(tag, cats, custom taxs), author, date, search page, 404.
|
||||
* @param $args : array(
|
||||
* 'level' => string,
|
||||
* 'meta_type' => string
|
||||
* 'long' => bool
|
||||
* 'is_prefixed' => bool //<= indicated if we should add the "Options for" prefix
|
||||
* )
|
||||
* @return string title of the current ctx if exists. If not => false.
|
||||
*/
|
||||
function skp_get_skope_title( $args = array() ) {
|
||||
$defaults = array(
|
||||
'level' => '',
|
||||
'meta_type' => null,
|
||||
'long' => false,
|
||||
'is_prefixed' => true
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$level = $args['level'];
|
||||
$meta_type = $args['meta_type'];
|
||||
$long = $args['long'];
|
||||
$is_prefixed = $args['is_prefixed'];
|
||||
|
||||
$_dyn_type = ( skp_is_customize_preview_frame() && isset( $_POST['dyn_type']) ) ? sanitize_text_field($_POST['dyn_type']) : '';
|
||||
$type = skp_get_skope('type');
|
||||
$skope = skp_get_skope();
|
||||
$title = '';
|
||||
|
||||
if( 'local' == $level ) {
|
||||
$type = skp_get_skope( 'type' );
|
||||
$title = $is_prefixed ? __( 'Options for', 'text_doma') . ' ' : $title;
|
||||
if ( skp_skope_has_a_group( $meta_type ) ) {
|
||||
$_id = skp_get_skope('id');
|
||||
switch ($meta_type) {
|
||||
case 'post':
|
||||
$type_obj = get_post_type_object( $type );
|
||||
$title .= sprintf( '%1$s "%3$s" (id : %2$s)', strtolower( $type_obj->labels->singular_name ), $_id, get_the_title( $_id ) );
|
||||
break;
|
||||
|
||||
case 'tax':
|
||||
$type_obj = get_taxonomy( $type );
|
||||
$term = get_term( $_id, $type );
|
||||
$title .= sprintf( '%1$s "%3$s" (id : %2$s)', strtolower( $type_obj->labels->singular_name ), $_id, $term->name );
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
$author = get_userdata( $_id );
|
||||
$title .= sprintf( '%1$s "%3$s" (id : %2$s)', __('user', 'text_doma'), $_id, $author->user_login );
|
||||
break;
|
||||
}
|
||||
} else if ( ( 'trans' == $_dyn_type || skp_skope_has_no_group( $skope ) ) ) {
|
||||
if ( is_post_type_archive() ) {
|
||||
global $wp_the_query;
|
||||
$title .= sprintf( __( '%1$s archive page', 'text_doma'), $wp_the_query->get( 'post_type' ) );
|
||||
} else {
|
||||
$title .= strtolower( $skope );
|
||||
}
|
||||
} else {
|
||||
$title .= __( 'Undefined', 'text_doma');
|
||||
}
|
||||
}
|
||||
if ( 'group' == $level || 'special_group' == $level ) {
|
||||
$title = $is_prefixed ? __( 'Options for all', 'text_doma') . ' ' : __( 'All' , 'text_doma' ) . ' ';
|
||||
switch( $meta_type ) {
|
||||
case 'post' :
|
||||
$type_obj = get_post_type_object( $type );
|
||||
$title .= strtolower( $type_obj->labels->name );
|
||||
break;
|
||||
|
||||
case 'tax' :
|
||||
$type_obj = get_taxonomy( $type );
|
||||
$title .= strtolower( $type_obj->labels->name );
|
||||
break;
|
||||
|
||||
case 'user' :
|
||||
$title .= __('users', 'text_doma');
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( 'global' == $level ) {
|
||||
$title = __( 'Sitewide options', 'text_doma');
|
||||
}
|
||||
$title = ucfirst( $title );
|
||||
return skp_trim_text( $title, $long ? 45 : 28, '...');
|
||||
}
|
||||
|
||||
//@return bool
|
||||
//=> tells if the current skope is part of the ones without group
|
||||
function skp_skope_has_no_group( $meta_type ) {
|
||||
return in_array(
|
||||
$meta_type,
|
||||
skp_get_no_group_skope_list()
|
||||
) || is_post_type_archive();
|
||||
}
|
||||
|
||||
//@return bool
|
||||
//Tells if the current skope has a group level
|
||||
function skp_skope_has_a_group( $meta_type ) {
|
||||
return in_array(
|
||||
$meta_type,
|
||||
array('post', 'tax', 'user')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//@return bool
|
||||
function skp_is_real_home() {
|
||||
// Warning : when show_on_front is a page, but no page_on_front has been picked yet, is_home() is true
|
||||
// beware of https://github.com/presscustomizr/nimble-builder/issues/349
|
||||
return ( is_home() && ( 'posts' == get_option( 'show_on_front' ) || '__nothing__' == get_option( 'show_on_front' ) ) )
|
||||
|| ( is_home() && 0 == get_option( 'page_on_front' ) && 'page' == get_option( 'show_on_front' ) )//<= this is the case when the user want to display a page on home but did not pick a page yet
|
||||
|| is_front_page();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a boolean
|
||||
*/
|
||||
function skp_is_customizing() {
|
||||
//checks if is customizing : two contexts, admin and front (preview frame)
|
||||
global $pagenow;
|
||||
$_is_ajaxing_from_customizer = isset( $_POST['customized'] ) || isset( $_POST['wp_customize'] );
|
||||
|
||||
$is_customizing = false;
|
||||
// the check on $pagenow does NOT work on multisite install @see https://github.com/presscustomizr/nimble-builder/issues/240
|
||||
// That's why we also check with other global vars
|
||||
// @see wp-includes/theme.php, _wp_customize_include()
|
||||
$is_customize_php_page = ( is_admin() && 'customize.php' == basename( $_SERVER['PHP_SELF'] ) );
|
||||
$is_customize_admin_page_one = (
|
||||
$is_customize_php_page
|
||||
||
|
||||
( isset( $_REQUEST['wp_customize'] ) && 'on' == sanitize_text_field($_REQUEST['wp_customize']) )
|
||||
||
|
||||
( !empty( $_GET['customize_changeset_uuid'] ) || !empty( $_POST['customize_changeset_uuid'] ) )
|
||||
);
|
||||
$is_customize_admin_page_two = is_admin() && isset( $pagenow ) && 'customize.php' == $pagenow;
|
||||
|
||||
if ( $is_customize_admin_page_one || $is_customize_admin_page_two ) {
|
||||
$is_customizing = true;
|
||||
//hu_is_customize_preview_frame() ?
|
||||
// Note : is_customize_preview() is not able to differentiate when previewing in the customizer and when previewing a changeset draft.
|
||||
// @todo => change this
|
||||
} else if ( is_customize_preview() || ( !is_admin() && isset($_REQUEST['customize_messenger_channel']) ) ) {
|
||||
$is_customizing = true;
|
||||
// hu_doing_customizer_ajax()
|
||||
} else if ( $_is_ajaxing_from_customizer && ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
||||
$is_customizing = true;
|
||||
}
|
||||
return $is_customizing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the customizer preview panel being displayed ?
|
||||
* @return boolean
|
||||
*/
|
||||
function skp_is_customize_preview_frame() {
|
||||
return is_customize_preview() || ( !is_admin() && isset($_REQUEST['customize_messenger_channel']) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
function skp_is_previewing_live_changeset() {
|
||||
return !isset( $_POST['customize_messenger_channel']) && is_customize_preview();
|
||||
}
|
||||
?><?php
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// FLAT SKOPE BASE
|
||||
if ( !class_exists( 'Flat_Skop_Base' ) ) :
|
||||
class Flat_Skop_Base {
|
||||
static $instance;
|
||||
public $query_skope = array();//<= will cache the query skope ( otherwise called multiple times ) on the first invokation of skp_get_query_skope() IF 'wp' done
|
||||
public $current_skope_ids = array();// will cache the skope ids on the first invokation of skp_get_skope_id, if 'wp' done
|
||||
|
||||
public static function skp_get_instance( $params ) {
|
||||
if ( !isset( self::$instance ) && !( self::$instance instanceof Flat_Skop_Base ) )
|
||||
self::$instance = new Flat_Skope_Clean_Final( $params );
|
||||
return self::$instance;
|
||||
}
|
||||
function __construct( $params = array() ) {
|
||||
$defaults = array(
|
||||
'base_url_path' => ''//NIMBLE_BASE_URL . '/inc/czr-skope/'
|
||||
);
|
||||
$params = wp_parse_args( $params, $defaults );
|
||||
if ( !defined( 'NIMBLE_SKOPE_BASE_URL' ) ) { define( 'NIMBLE_SKOPE_BASE_URL' , $params['base_url_path'] ); }
|
||||
if ( !defined( 'NIMBLE_SKOPE_ID_PREFIX' ) ) { define( 'NIMBLE_SKOPE_ID_PREFIX' , "skp__" ); }
|
||||
|
||||
$this->skp_register_and_load_control_assets();
|
||||
$this->skp_export_skope_data_and_schedule_sending_to_panel();
|
||||
$this->skp_schedule_cleaning_on_object_delete();
|
||||
}//__construct
|
||||
}
|
||||
endif;
|
||||
?><?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// PRINT CUSTOMIZER JAVASCRIPT + LOCALIZED DATA
|
||||
if ( !class_exists( 'Flat_Skop_Register_And_Load_Control_Assets' ) ) :
|
||||
class Flat_Skop_Register_And_Load_Control_Assets extends Flat_Skop_Base {
|
||||
// Fired in Flat_Skop_Base::__construct()
|
||||
public function skp_register_and_load_control_assets() {
|
||||
add_action( 'customize_controls_enqueue_scripts', array( $this, 'skp_enqueue_controls_js_css' ), 20 );
|
||||
}
|
||||
|
||||
public function skp_enqueue_controls_js_css() {
|
||||
$_use_unminified = defined('CZR_DEV')
|
||||
&& true === CZR_DEV
|
||||
// && false === strpos( dirname( dirname( dirname (__FILE__) ) ) , 'inc/wfc' )
|
||||
&& file_exists( sprintf( '%s/assets/czr/js/czr-skope-base.js' , dirname( __FILE__ ) ) );
|
||||
|
||||
$_prod_script_path = sprintf(
|
||||
'%1$s/assets/czr/js/%2$s' ,
|
||||
NIMBLE_SKOPE_BASE_URL,
|
||||
$_use_unminified ? 'czr-skope-base.js' : 'czr-skope-base.min.js'
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'czr-skope-base',
|
||||
//dev / debug mode mode?
|
||||
$_prod_script_path,
|
||||
array('customize-controls' , 'jquery', 'underscore'),
|
||||
( defined('WP_DEBUG') && true === WP_DEBUG ) ? time() : wp_get_theme()->version,
|
||||
$in_footer = true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'czr-skope-base',
|
||||
'FlatSkopeLocalizedData',
|
||||
array(
|
||||
'noGroupSkopeList' => skp_get_no_group_skope_list(),
|
||||
'defaultSkopeModel' => skp_get_default_skope_model(),
|
||||
'i18n' => array()
|
||||
)
|
||||
);
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?><?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CUSTOMIZE PREVIEW : export skope data and send skope to the panel
|
||||
/* ------------------------------------------------------------------------- */
|
||||
if ( !class_exists( 'Flat_Export_Skope_Data_And_Send_To_Panel' ) ) :
|
||||
class Flat_Export_Skope_Data_And_Send_To_Panel extends Flat_Skop_Register_And_Load_Control_Assets {
|
||||
// Fired in Flat_Skop_Base::__construct()
|
||||
public function skp_export_skope_data_and_schedule_sending_to_panel() {
|
||||
add_action( 'wp_head', array( $this, 'skp_print_server_skope_data') , 30 );
|
||||
}
|
||||
|
||||
|
||||
//hook : 'wp_footer'
|
||||
public function skp_print_server_skope_data() {
|
||||
if ( !skp_is_customize_preview_frame() )
|
||||
return;
|
||||
|
||||
global $wp_query, $wp_customize;
|
||||
$_meta_type = skp_get_skope( 'meta_type', true );
|
||||
|
||||
// $_czr_scopes = array( );
|
||||
$_czr_skopes = $this->_skp_get_json_export_ready_skopes();
|
||||
$_czr_query_data = $this->_skp_get_json_export_ready_query_data();
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
var _doSend = function() {
|
||||
// December 2020 : it may happen that the 'sync' event was already sent and that we missed it
|
||||
// Typically when the site is slow.
|
||||
// So we need to check if the "sync" event has fired already ( see customize-base.js, ::bind method )
|
||||
// For more security, let's introduce a marker and attempt to re-sent after a moment if needed
|
||||
window.czr_skopes_sent = false;
|
||||
var _send = function() {
|
||||
wp.customize.preview.send( 'czr-new-skopes-synced', {
|
||||
czr_new_skopes : _wpCustomizeSettings.czr_new_skopes || [],
|
||||
czr_stylesheet : _wpCustomizeSettings.czr_stylesheet || '',
|
||||
isChangesetDirty : _wpCustomizeSettings.isChangesetDirty || false,
|
||||
skopeGlobalDBOpt : _wpCustomizeSettings.skopeGlobalDBOpt || [],
|
||||
} );
|
||||
window.czr_skopes_sent = true;
|
||||
};
|
||||
|
||||
jQuery( function() {
|
||||
if ( wp.customize.preview.topics && wp.customize.preview.topics.sync && wp.customize.preview.topics.sync.fired() ) {
|
||||
_send();
|
||||
} else {
|
||||
wp.customize.preview.bind( 'sync', function( events ) {
|
||||
_send();
|
||||
});
|
||||
}
|
||||
setTimeout( function() {
|
||||
if ( !window.czr_skopes_sent ) {
|
||||
_send();
|
||||
}
|
||||
}, 2500 );
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// recursively try to load jquery every 200ms during 6s ( max 30 times )
|
||||
var _doWhenCustomizeSettingsReady = function( attempts ) {
|
||||
attempts = attempts || 0;
|
||||
if ( typeof undefined !== typeof window._wpCustomizeSettings ) {
|
||||
_wpCustomizeSettings.czr_new_skopes = <?php echo wp_json_encode( $_czr_skopes ); ?>;
|
||||
_wpCustomizeSettings.czr_stylesheet = '<?php echo get_stylesheet(); ?>';
|
||||
_wpCustomizeSettings.czr_query_params = <?php echo wp_json_encode($_czr_query_data); ?>;
|
||||
_doSend();
|
||||
} else if ( attempts < 30 ) {
|
||||
setTimeout( function() {
|
||||
attempts++;
|
||||
_doWhenCustomizeSettingsReady( attempts );
|
||||
}, 20 );
|
||||
} else {
|
||||
if ( window.console && window.console.log ) {
|
||||
console.log('Nimble Builder problem : _wpCustomizeSettings is not defined');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_doWhenCustomizeSettingsReady();
|
||||
<?php
|
||||
$script = ob_get_clean();
|
||||
wp_register_script( 'nb_print_skope_data_js', '');
|
||||
wp_enqueue_script( 'nb_print_skope_data_js' );
|
||||
wp_add_inline_script( 'nb_print_skope_data_js', $script );
|
||||
}
|
||||
|
||||
|
||||
// introduced in october 2019 for https://github.com/presscustomizr/nimble-builder/issues/401
|
||||
private function _skp_get_json_export_ready_query_data() {
|
||||
global $wp_query;
|
||||
global $authordata;
|
||||
add_filter('get_the_archive_title_prefix', '__return_false');
|
||||
$archive_title = get_the_archive_title();
|
||||
remove_filter('get_the_archive_title_prefix', '__return_false');
|
||||
return [
|
||||
'is_singular' => $wp_query->is_singular,
|
||||
'is_archive' => $wp_query->is_archive,
|
||||
'is_search' => $wp_query->is_search,
|
||||
'is_attachment' => $wp_query->is_attachment,
|
||||
'is_front_page' => is_front_page(),
|
||||
'the_archive_title' => $archive_title,
|
||||
'the_archive_description' => get_the_archive_description(),
|
||||
'the_previous_post_link' => is_singular() ? get_previous_post_link( $format = '%link' ) : '',
|
||||
'the_next_post_link' => is_singular() ? get_next_post_link( $format = '%link' ) : '',
|
||||
'the_search_query' => get_search_query(),
|
||||
'the_search_results_nb' => (int) $wp_query->found_posts,
|
||||
'the_author_id' => isset( $authordata->ID ) ? $authordata->ID : 0,
|
||||
'post_id' => get_the_ID(),
|
||||
'query_vars' => $wp_query->query_vars
|
||||
];
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CUSTOMIZE PREVIEW : BUILD SKOPES JSON
|
||||
/* ------------------------------------------------------------------------- */
|
||||
//generates the array of available scopes for a given context
|
||||
//ex for a single post tagged #tag1 and #tag2 and categroized #cat1 :
|
||||
//global
|
||||
//all posts
|
||||
//local
|
||||
//posts tagged #tag1
|
||||
//posts tagged #tag2
|
||||
//posts categorized #cat1
|
||||
//@return array()
|
||||
//
|
||||
//skp_get_skope_title() takes the following default args
|
||||
//array(
|
||||
// 'level' => '',
|
||||
// 'meta_type' => null,
|
||||
// 'long' => false,
|
||||
// 'is_prefixed' => true
|
||||
//)
|
||||
private function _skp_get_json_export_ready_skopes() {
|
||||
$skopes = array();
|
||||
$_meta_type = skp_get_skope( 'meta_type', true );
|
||||
|
||||
//default properties of the scope object
|
||||
$defaults = skp_get_default_skope_model();
|
||||
//global and local and always sent
|
||||
$skopes[] = wp_parse_args(
|
||||
array(
|
||||
'title' => skp_get_skope_title( array( 'level' => 'global' ) ),
|
||||
'long_title' => skp_get_skope_title( array( 'level' => 'global', 'meta_type' => null, 'long' => true ) ),
|
||||
'ctx_title' => skp_get_skope_title( array( 'level' => 'global', 'meta_type' => null, 'long' => true, 'is_prefixed' => false ) ),
|
||||
'skope' => 'global',
|
||||
'level' => '_all_'
|
||||
),
|
||||
$defaults
|
||||
);
|
||||
|
||||
|
||||
//SPECIAL GROUPS
|
||||
//@todo
|
||||
|
||||
|
||||
//GROUP
|
||||
//Do we have a group ? => if yes, then there must be a meta type
|
||||
if ( skp_get_skope('meta_type') ) {
|
||||
$skopes[] = wp_parse_args(
|
||||
array(
|
||||
'title' => skp_get_skope_title( array( 'level' => 'group', 'meta_type' => $_meta_type ) ),
|
||||
'long_title' => skp_get_skope_title( array( 'level' => 'group', 'meta_type' => $_meta_type, 'long' => true ) ),
|
||||
'ctx_title' => skp_get_skope_title( array( 'level' => 'group', 'meta_type' => $_meta_type, 'long' => true, 'is_prefixed' => false ) ),
|
||||
'skope' => 'group',
|
||||
'level' => 'all_' . skp_get_skope('type'),
|
||||
'skope_id' => skp_get_skope_id( 'group' )
|
||||
),
|
||||
$defaults
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//LOCAL
|
||||
$skopes[] = wp_parse_args(
|
||||
array(
|
||||
'title' => skp_get_skope_title( array( 'level' => 'local', 'meta_type' => $_meta_type ) ),
|
||||
'long_title' => skp_get_skope_title( array( 'level' => 'local', 'meta_type' => $_meta_type, 'long' => true ) ),
|
||||
'ctx_title' => skp_get_skope_title( array( 'level' => 'local', 'meta_type' => $_meta_type, 'long' => true, 'is_prefixed' => false ) ),
|
||||
'skope' => 'local',
|
||||
'level' => skp_get_skope(),
|
||||
'obj_id' => skp_get_skope('id'),
|
||||
'skope_id' => skp_get_skope_id( 'local' )
|
||||
),
|
||||
$defaults
|
||||
);
|
||||
return apply_filters( 'skp_json_export_ready_skopes', $skopes );
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?><?php
|
||||
|
||||
if ( !class_exists( 'Flat_Skope_Clean_Final' ) ) :
|
||||
final class Flat_Skope_Clean_Final extends Flat_Export_Skope_Data_And_Send_To_Panel {
|
||||
// Fired in Flat_Skop_Base::__construct()
|
||||
public function skp_schedule_cleaning_on_object_delete() {
|
||||
add_action( 'delete_post', array( $this, 'skp_clean_skopified_posts' ) );
|
||||
add_action( 'delete_term_taxonomy', array( $this, 'skp_clean_skopified_taxonomies' ) );
|
||||
add_action( 'delete_user', array( $this, 'skp_clean_skopified_users' ) );
|
||||
}
|
||||
|
||||
|
||||
// Clean any associated skope post for all public post types : post, page, public cpt
|
||||
// 'delete_post' Fires immediately before a post is deleted from the database.
|
||||
// @see wp-includes/post.php
|
||||
// don't have to return anything
|
||||
public function skp_clean_skopified_posts( $postid ) {
|
||||
$deletion_candidate = get_post( $postid );
|
||||
if ( !$deletion_candidate || !is_object( $deletion_candidate ) )
|
||||
return;
|
||||
|
||||
// Stop here if the post type is not considered "viewable".
|
||||
// For built-in post types such as posts and pages, the 'public' value will be evaluated.
|
||||
// For all others, the 'publicly_queryable' value will be used.
|
||||
// For example, the 'revision' post type, which is purely internal and not skopable, won't pass this test.
|
||||
if ( !is_post_type_viewable( $deletion_candidate->post_type ) )
|
||||
return;
|
||||
|
||||
// Force the skope parts normally retrieved with skp_get_query_skope()
|
||||
$skope_string = skp_get_skope( null, true, array(
|
||||
'meta_type' => 'post',
|
||||
'type' => $deletion_candidate->post_type,
|
||||
'obj_id' => $postid
|
||||
) );
|
||||
|
||||
// build a skope_id with the normalized function
|
||||
$skope_id = skp_build_skope_id( array( 'skope_string' => $skope_string, 'skope_level' => 'local' ) );
|
||||
|
||||
// fetch the skope post id which, if exists, is set as a theme mod
|
||||
$skope_post_id_candidate = get_theme_mod( $skope_id );
|
||||
if ( $skope_post_id_candidate > 0 && get_post( $skope_post_id_candidate ) ) {
|
||||
// permanently delete the skope post from db
|
||||
wp_delete_post( $skope_post_id_candidate );
|
||||
// remove the theme_mod
|
||||
remove_theme_mod( $skope_id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 'delete_term_taxonomy' Fires immediately before a term taxonomy ID is deleted.
|
||||
public function skp_clean_skopified_taxonomies( $term_id ) {
|
||||
$deletion_candidate = get_term( $term_id );
|
||||
if ( !$deletion_candidate || !is_object( $deletion_candidate ) )
|
||||
return;
|
||||
|
||||
//error_log( print_r( $deletion_candidate, true ) );
|
||||
|
||||
// Force the skope parts normally retrieved with skp_get_query_skope()
|
||||
$skope_string = skp_get_skope( null, true, array(
|
||||
'meta_type' => 'tax',
|
||||
'type' => $deletion_candidate->taxonomy,
|
||||
'obj_id' => $term_id
|
||||
) );
|
||||
|
||||
// build a skope_id with the normalized function
|
||||
$skope_id = skp_build_skope_id( array( 'skope_string' => $skope_string, 'skope_level' => 'local' ) );
|
||||
|
||||
// fetch the skope post id which, if exists, is set as a theme mod
|
||||
$skope_post_id_candidate = get_theme_mod( $skope_id );
|
||||
if ( $skope_post_id_candidate > 0 && get_post( $skope_post_id_candidate ) ) {
|
||||
// permanently delete the skope post from db
|
||||
wp_delete_post( $skope_post_id_candidate );
|
||||
// remove the theme_mod
|
||||
remove_theme_mod( $skope_id );
|
||||
//error_log( 'SUCCESSFULLY REMOVED SKOPE POST ID ' . $skope_post_id_candidate . ' AND THEME MOD ' . $skope_id );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 'delete_user' Fires immediately before a user is deleted from the database.
|
||||
public function skp_clean_skopified_users( $user_id ) {
|
||||
// Force the skope parts normally retrieved with skp_get_query_skope()
|
||||
$skope_string = skp_get_skope( null, true, array(
|
||||
'meta_type' => 'user',
|
||||
'type' => 'author',
|
||||
'obj_id' => $user_id
|
||||
) );
|
||||
|
||||
// build a skope_id with the normalized function
|
||||
$skope_id = skp_build_skope_id( array( 'skope_string' => $skope_string, 'skope_level' => 'local' ) );
|
||||
|
||||
// fetch the skope post id which, if exists, is set as a theme mod
|
||||
$skope_post_id_candidate = get_theme_mod( $skope_id );
|
||||
if ( $skope_post_id_candidate > 0 && get_post( $skope_post_id_candidate ) ) {
|
||||
// permanently delete the skope post from db
|
||||
wp_delete_post( $skope_post_id_candidate );
|
||||
// remove the theme_mod
|
||||
remove_theme_mod( $skope_id );
|
||||
//error_log( 'SUCCESSFULLY REMOVED SKOPE POST ID ' . $skope_post_id_candidate . ' AND THEME MOD ' . $skope_id );
|
||||
}
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
// @return void()
|
||||
function nimble_register_location( $location, $params = array() ) {
|
||||
if ( empty( $location ) || !is_string( $location ) )
|
||||
return;
|
||||
\Nimble\register_location( $location, $params );
|
||||
}
|
||||
|
||||
//@param $locations. mixed type
|
||||
//@param $options (array)$options = wp_parse_args( $options, array(
|
||||
// 'fallback_location' => null, // Typically set as 'loop_start' in the nimble templates
|
||||
// ));
|
||||
function render_nimble_locations( $locations, $options = array() ) {
|
||||
\Nimble\render_nimble_locations( $locations, $options );
|
||||
}
|
||||
|
||||
function nimble_get_content_as_json() {
|
||||
$skope_id = \Nimble\skp_get_skope_id();
|
||||
// bail now if called before skope_id is set (before @hook 'wp')
|
||||
if ( empty( $skope_id ) || '_skope_not_set_' === $skope_id )
|
||||
return '{}';
|
||||
|
||||
$global_sections = \Nimble\sek_get_skoped_seks( NIMBLE_GLOBAL_SKOPE_ID );
|
||||
$local_sections = \Nimble\sek_get_skoped_seks( $skope_id );
|
||||
$raw_content = \Nimble\sek_sniff_and_decode_richtext([
|
||||
'local_sections' => $local_sections,
|
||||
'global_sections' => $global_sections
|
||||
]);
|
||||
return wp_json_encode( $raw_content );
|
||||
}
|
||||
|
||||
function nimble_allow_display_attribute( $styles ){
|
||||
$styles[] = 'display';
|
||||
return $styles;
|
||||
}
|
||||
@@ -0,0 +1,935 @@
|
||||
<?php
|
||||
add_action( 'customize_controls_print_footer_scripts', '\Nimble\sek_print_nimble_input_templates' );
|
||||
function sek_print_nimble_input_templates() {
|
||||
|
||||
|
||||
// data structure :
|
||||
// {
|
||||
// input_type : input_type,
|
||||
// input_data : input_data,
|
||||
// input_id : input_id,
|
||||
// item_model : item_model,
|
||||
// input_tmpl : wp.template( 'nimble-input___' + input_type )
|
||||
// }
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input-wrapper">
|
||||
<# var css_attr = serverControlParams.css_attr,
|
||||
input_data = data.input_data,
|
||||
input_type = input_data.input_type,
|
||||
is_width_100 = true === input_data['width-100'];
|
||||
|
||||
|
||||
// some inputs have a width of 100% even if not specified in the input_data
|
||||
if ( _.contains( ['color', 'radio', 'textarea'], input_type ) ) {
|
||||
is_width_100 = true;
|
||||
}
|
||||
var width_100_class = is_width_100 ? 'width-100' : '',
|
||||
hidden_class = 'hidden' === input_type ? 'hidden' : '',
|
||||
data_transport_attr = !_.isEmpty( input_data.transport ) ? 'data-transport="' + input_data.transport + '"' : '',
|
||||
input_width = !_.isEmpty( input_data.input_width ) ? input_data.input_width : '';
|
||||
#>
|
||||
|
||||
<div class="{{css_attr.sub_set_wrapper}} {{width_100_class}} {{hidden_class}}" data-input-type="{{input_type}}" <# print(data_transport_attr); #>>
|
||||
<# if ( input_data.html_before ) { #>
|
||||
<div class="czr-html-before"><# print(input_data.html_before); #></div>
|
||||
<# } #>
|
||||
<# if ( input_data.notice_before_title ) { #>
|
||||
<span class="czr-notice"><# print(input_data.notice_before_title); #></span><br/>
|
||||
<# } #>
|
||||
<# if ( 'hidden' !== input_type ) { #>
|
||||
<# var title_width = !_.isEmpty( input_data.title_width ) ? input_data.title_width : ''; #>
|
||||
<div class="customize-control-title {{title_width}}"><# print( input_data.title ); #></div>
|
||||
<# } #>
|
||||
<# if ( input_data.notice_before ) { #>
|
||||
<span class="czr-notice"><# print(input_data.notice_before); #></span>
|
||||
<# } #>
|
||||
|
||||
<?php // nested template, see https://stackoverflow.com/questions/8938841/underscore-js-nested-templates#13649447 ?>
|
||||
<?php // about print(), see https://underscorejs.org/#template ?>
|
||||
<div class="czr-input {{input_width}}"><# if ( _.isFunction( data.input_tmpl ) ) { print(data.input_tmpl(data)); } #></div>
|
||||
|
||||
<# if ( input_data.notice_after ) { #>
|
||||
<span class="czr-notice"><# print(input_data.notice_after); #></span>
|
||||
<# } #>
|
||||
<# if ( input_data.html_after ) { #>
|
||||
<div class="czr-html-after"><# print(input_data.html_after); #></div>
|
||||
<# } #>
|
||||
</div><?php //css_attr.sub_set_wrapper ?>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* PARTS FOR MULTI-ITEMS MODULES
|
||||
* fixes https://github.com/presscustomizr/nimble-builder/issues/473
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-crud-module-part">
|
||||
<# var css_attr = serverControlParams.css_attr; #>
|
||||
<button class="{{css_attr.open_pre_add_btn}}"><?php _e('Add New', 'text_doma'); ?> <span class="fas fa-plus-square"></span></button>
|
||||
<div class="{{css_attr.pre_add_wrapper}}">
|
||||
<div class="{{css_attr.pre_add_success}}"><p></p></div>
|
||||
<div class="{{css_attr.pre_add_item_content}}">
|
||||
|
||||
<span class="{{css_attr.cancel_pre_add_btn}} button"><?php _e('Cancel', 'text_doma'); ?></span> <span class="{{css_attr.add_new_btn}} button"><?php _e('Add it', 'text_doma'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-rud-item-part">
|
||||
<# var css_attr = serverControlParams.css_attr, is_sortable_class ='';
|
||||
if ( data.is_sortable ) {
|
||||
is_sortable_class = css_attr.item_sort_handle;
|
||||
}
|
||||
#>
|
||||
<div class="{{css_attr.item_header}} {{is_sortable_class}} czr-custom-model">
|
||||
<# if ( ( true === data.is_sortable ) ) { #>
|
||||
<div class="{{css_attr.item_title}} "><h4>{{ data.title }}</h4></div>
|
||||
<# } else { #>
|
||||
<div class="{{css_attr.item_title}}"><h4>{{ data.title }}</h4></div>
|
||||
<# } #>
|
||||
<div class="{{css_attr.item_btns}}">
|
||||
<a title="<?php _e('Edit', 'text_doma'); ?>" href="javascript:void(0);" class="fas fa-pencil-alt {{css_attr.edit_view_btn}}"></a>
|
||||
<# if ( ( true === data.items_are_clonable ) ) { #>
|
||||
<a title="<?php _e('Clone', 'text_doma'); ?>" href="javascript:void(0);" class="far fa-clone czr-clone-item"></a>
|
||||
<# } #>
|
||||
<a title="<?php _e('Remove', 'text_doma'); ?>" href="javascript:void(0);" class="fas fa-trash {{css_attr.display_alert_btn}}"></a>
|
||||
</div>
|
||||
<div class="{{css_attr.remove_alert_wrapper}}"></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SUBTEMPLATES
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-subtemplate___range_number">
|
||||
<?php
|
||||
// we save the int value + unit
|
||||
// we want to keep only the numbers when printing the tmpl
|
||||
// dev note : value.replace(/\D+/g, '') : ''; not working because remove "." which we might use for em for example
|
||||
?>
|
||||
<#
|
||||
var item_model = data.item_model,
|
||||
input_id = data.input_id,
|
||||
rawValue = _.has( item_model, input_id ) ? item_model[input_id] : null,
|
||||
value,
|
||||
unit;
|
||||
|
||||
value = _.isString( rawValue ) ? rawValue.replace(/px|em|%/g,'') : rawValue;
|
||||
unit = _.isString( rawValue ) ? rawValue.replace(/[0-9]|\.|,/g, '') : 'px';
|
||||
unit = _.isEmpty( unit ) ? 'px' : unit;
|
||||
var _step = _.has( data.input_data, 'step' ) ? 'step="' + data.input_data.step + '"' : '',
|
||||
_saved_unit = _.has( item_model, 'unit' ) ? 'data-unit="' + data.input_data.unit + '"' : '',
|
||||
_min = _.has( data.input_data, 'min' ) ? 'min="' + data.input_data.min + '"': '',
|
||||
_max = _.has( data.input_data, 'max' ) ? 'max="' + data.input_data.max + '"': '';
|
||||
#>
|
||||
<div class="sek-range-wrapper">
|
||||
<input data-czrtype="{{input_id}}" type="hidden" data-sek-unit="{{unit}}"/>
|
||||
<input class="sek-range-input" type="range" <# print(_step); #> <# print(_saved_unit); #> <# print(_min); #> <# print(_max); #>/>
|
||||
</div>
|
||||
<div class="sek-number-wrapper">
|
||||
<input class="sek-pm-input" value="{{value}}" type="number" <# print(_step); #> <# print(_min); #> <# print(_max); #> >
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-subtemplate___unit_picker">
|
||||
<div class="sek-unit-wrapper">
|
||||
<div aria-label="<?php _e('unit', 'text_doma'); ?>" class="sek-ui-button-group" role="group"><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('pixels', 'text_doma'); ?>" data-sek-unit="px">px</button><button type="button" aria-pressed="false" class="sek-ui-button" title="em" data-sek-unit="em">em</button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('percents', 'text_doma'); ?>" data-sek-unit="%">%</button></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-subtemplate___number">
|
||||
<div class="sek-simple-number-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" class="sek-pm-input" value="{{value}}" type="number" >
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CODE EDITOR
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<?php
|
||||
// data structure :
|
||||
// {
|
||||
// input_type : input_type,
|
||||
// input_data : input_data,
|
||||
// input_id : input_id,
|
||||
// item_model : item_model,
|
||||
// input_tmpl : wp.template( 'nimble-input___' + input_type )
|
||||
// }
|
||||
?>
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-input___code_editor">
|
||||
<#
|
||||
var item_model = data.item_model,
|
||||
input_id = data.input_id,
|
||||
value = _.has( item_model, input_id ) ? item_model[input_id] : null,
|
||||
code_type = data.input_data.code_type;
|
||||
#>
|
||||
<textarea data-czrtype="{{input_id}}" data-editor-code-type="{{code_type}}" class="width-100" name="textarea" rows="10" cols=""></textarea>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-input___detached_tinymce_editor">
|
||||
<#
|
||||
var input_data = data.input_data,
|
||||
item_model = data.item_model,
|
||||
input_id = data.input_id,
|
||||
value = _.has( item_model, input_id ) ? item_model[input_id] : null,
|
||||
code_type = data.input_data.code_type;
|
||||
#>
|
||||
<button type="button" class="button text_editor-button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{input_id}}" data-czr-action="open-tinymce-editor"><?php _e('Edit', 'text_doma'); ?></button>
|
||||
<button type="button" class="button text_editor-button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{input_id}}" data-czr-action="close-tinymce-editor"><?php _e('Hide editor', 'text_doma'); ?></button>
|
||||
<input data-czrtype="{{input_id}}" type="hidden" value=""/>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-input___nimble_tinymce_editor">
|
||||
<?php
|
||||
// Added an id attribute for https://github.com/presscustomizr/nimble-builder/issues/403
|
||||
// needed to instantiate wp.editor.initialize(...)
|
||||
?>
|
||||
<#
|
||||
var item_model = data.item_model,
|
||||
input_id = data.input_id,
|
||||
value = _.has( item_model, input_id ) ? item_model[input_id] : null;
|
||||
#>
|
||||
<textarea id="textarea-{{input_id}}" data-czrtype="{{input_id}}" class="width-100" name="textarea" rows="10" cols=""></textarea>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-input___h_alignment">
|
||||
<#
|
||||
var input_id = data.input_id;
|
||||
#>
|
||||
<div class="sek-h-align-wrapper">
|
||||
<input data-czrtype="{{input_id}}" type="hidden"/>
|
||||
<div class="sek-align-icons">
|
||||
<div data-sek-align="left" title="<?php _e('Align left', 'text_doma'); ?>"><i class="material-icons">format_align_left</i></div>
|
||||
<div data-sek-align="center" title="<?php _e('Align center', 'text_doma'); ?>"><i class="material-icons">format_align_center</i></div>
|
||||
<div data-sek-align="right" title="<?php _e('Align right', 'text_doma'); ?>"><i class="material-icons">format_align_right</i></div>
|
||||
</div>
|
||||
</div><?php // sek-h-align-wrapper ?>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-input___h_text_alignment">
|
||||
<#
|
||||
var input_id = data.input_id;
|
||||
#>
|
||||
<div class="sek-h-align-wrapper">
|
||||
<input data-czrtype="{{input_id}}" type="hidden"/>
|
||||
<div class="sek-align-icons">
|
||||
<div data-sek-align="left" title="<?php _e('Align left', 'text_doma'); ?>"><i class="material-icons">format_align_left</i></div>
|
||||
<div data-sek-align="center" title="<?php _e('Align center', 'text_doma'); ?>"><i class="material-icons">format_align_center</i></div>
|
||||
<div data-sek-align="right" title="<?php _e('Align right', 'text_doma'); ?>"><i class="material-icons">format_align_right</i></div>
|
||||
<div data-sek-align="justify" title="<?php _e('Justified', 'text_doma'); ?>"><i class="material-icons">format_align_justify</i></div>
|
||||
</div>
|
||||
</div><?php // sek-h-align-wrapper ?>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-input___nimblecheck">
|
||||
<#
|
||||
var input_id = data.input_id,
|
||||
item_model = data.item_model,
|
||||
value = _.has( item_model, input_id ) ? item_model[input_id] : false,
|
||||
_checked = ( false != value ) ? "checked=checked" : '',
|
||||
_uniqueId = wp.customize.czr_sektions.guid();
|
||||
#>
|
||||
<div class="nimblecheck-wrap">
|
||||
<input id="nimblecheck-{{_uniqueId}}" data-czrtype="{{input_id}}" type="checkbox" <# print(_checked); #> class="nimblecheck-input">
|
||||
<label for="nimblecheck-{{_uniqueId}}" class="nimblecheck-label">{{sektionsLocalizedData.i18n['Switch']}}</label>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* ALPHA COLOR
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___wp_color_alpha">
|
||||
<#
|
||||
var item_model = data.item_model,
|
||||
input_id = data.input_id,
|
||||
value = _.has( item_model, input_id ) ? item_model[input_id] : null;
|
||||
#>
|
||||
<input data-czrtype="{{data.input_id}}" class="width-100" data-alpha="true" type="text" value="{{value}}"></input>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SIMPLE SELECT : USED FOR SELECT, FONT PICKER, ICON PICKER, ...
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___simpleselect">
|
||||
<select data-czrtype="{{data.input_id}}"></select>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SIMPLE SELECT WITH DEVICE SWITCHER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___simpleselect_deviceswitcher">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<select></select>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* NUMBER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___number_simple">
|
||||
<#
|
||||
var number_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'number' );
|
||||
if ( _.isFunction( number_tmpl ) ) { print( number_tmpl( data ) ); }
|
||||
#>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* RANGE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___range_simple">
|
||||
<div class="sek-range-with-unit-picker-wrapper sek-no-unit-picker">
|
||||
<#
|
||||
var range_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'range_number' );
|
||||
if ( _.isFunction( range_tmpl ) ) { print( range_tmpl( data ) ); }
|
||||
#>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/html" id="tmpl-nimble-input___range_with_unit_picker">
|
||||
<div class="sek-range-with-unit-picker-wrapper">
|
||||
<#
|
||||
var range_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'range_number' );
|
||||
if ( _.isFunction( range_tmpl ) ) { print( range_tmpl( data ) ); }
|
||||
var unit_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'unit_picker' );
|
||||
if ( _.isFunction( unit_tmpl ) ) { print( unit_tmpl( data ) ); }
|
||||
#>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SPACING
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___spacing">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-spacing-wrapper">
|
||||
<div class="sek-pad-marg-inner">
|
||||
<div class="sek-pm-top-bottom-wrap sek-flex-justify-center">
|
||||
<div class="sek-flex-center-stretch" data-sek-spacing="margin-top" title="<?php _e('Margin top', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sek-pm-middle-wrap sek-flex-justify-center">
|
||||
<div class="sek-flex-center-stretch sek-pm-margin-left" data-sek-spacing="margin-left" title="<?php _e('Margin left', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sek-pm-padding-wrapper">
|
||||
<div class="sek-flex-justify-center">
|
||||
<div class="sek-flex-center-stretch" data-sek-spacing="padding-top" title="<?php _e('Padding top', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sek-flex-justify-center sek-flex-space-between">
|
||||
<div class="sek-flex-center-stretch" data-sek-spacing="padding-left" title="<?php _e('Padding left', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="sek-flex-center-stretch" data-sek-spacing="padding-right" title="<?php _e('Padding right', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sek-flex-justify-center">
|
||||
<div class="sek-flex-center-stretch" data-sek-spacing="padding-bottom" title="<?php _e('Padding bottom', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sek-flex-center-stretch sek-pm-margin-right" data-sek-spacing="margin-right" title="<?php _e('Margin right', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sek-pm-top-bottom-wrap sek-flex-justify-center">
|
||||
<div class="sek-flex-center-stretch" data-sek-spacing="margin-bottom" title="<?php _e('Margin bottom', 'text_doma'); ?>">
|
||||
<div class="sek-pm-input-parent">
|
||||
<input class="sek-pm-input" value="" type="number" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><?php //sek-pad-marg-inner ?>
|
||||
|
||||
<#
|
||||
var unit_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'unit_picker' );
|
||||
if ( _.isFunction( unit_tmpl ) ) { print( unit_tmpl( data ) ); }
|
||||
#>
|
||||
<div class="reset-spacing-wrap"><span class="sek-do-reset"><?php _e('Reset all spacing', 'text_doma' ); ?></span></div>
|
||||
|
||||
</div><?php // sek-spacing-wrapper ?>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* TEXT
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___text">
|
||||
<# var input_data = data.input_data; #>
|
||||
<input data-czrtype="{{data.input_id}}" type="text" value="" placeholder="<# print(input_data.placeholder); #>"></input>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CONTENT PICKER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___content_picker">
|
||||
<span data-czrtype="{{data.input_id}}"></span>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* UPLOAD
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___upload">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="{{serverControlParams.css_attr.img_upload_container}}"></div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* BORDERS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___borders">
|
||||
<div class="sek-borders">
|
||||
<div class="sek-border-type-wrapper">
|
||||
<div aria-label="unit" class="sek-ui-button-group" role="group"><button type="button" aria-pressed="true" class="sek-ui-button is-selected" title="<?php _e('All', 'text_doma'); ?>" data-sek-border-type="_all_"><?php _e('All', 'text_doma'); ?></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Left', 'text_doma'); ?>" data-sek-border-type="left"><?php _e('Left', 'text_doma'); ?></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Top', 'text_doma'); ?>" data-sek-border-type="top"><?php _e('Top', 'text_doma'); ?></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Right', 'text_doma'); ?>" data-sek-border-type="right"><?php _e('Right', 'text_doma'); ?></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Bottom', 'text_doma'); ?>" data-sek-border-type="bottom"><?php _e('Bottom', 'text_doma'); ?></button></div>
|
||||
</div>
|
||||
<div class="sek-range-unit-wrapper">
|
||||
<#
|
||||
var range_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'range_number' );
|
||||
if ( _.isFunction( range_tmpl ) ) { print( range_tmpl( data ) ); }
|
||||
var unit_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'unit_picker' );
|
||||
if ( _.isFunction( unit_tmpl ) ) { print( unit_tmpl( data ) ); }
|
||||
#>
|
||||
</div>
|
||||
<div class="sek-color-wrapper">
|
||||
<div class="sek-color-picker"><input class="sek-alpha-color-input" data-alpha="true" type="text" value=""/></div>
|
||||
<div class="sek-reset-button"><button type="button" class="button sek-reset-button sek-float-right"><?php _e('Reset', 'text_doma'); ?></button></div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* BORDER RADIUS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___border_radius">
|
||||
<div class="sek-borders">
|
||||
<div class="sek-border-type-wrapper">
|
||||
<div aria-label="unit" class="sek-ui-button-group sek-float-left" role="group"><button type="button" aria-pressed="true" class="sek-ui-button is-selected" title="<?php _e('All', 'text_doma'); ?>" data-sek-radius-type="_all_"><?php _e('All', 'text_doma'); ?></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Top left', 'text_doma'); ?>" data-sek-radius-type="top_left"><i class="material-icons">border_style</i></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Top right', 'text_doma'); ?>" data-sek-radius-type="top_right"><i class="material-icons">border_style</i></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Bottom right', 'text_doma'); ?>" data-sek-radius-type="bottom_right"><i class="material-icons">border_style</i></button><button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Bottom left', 'text_doma'); ?>" data-sek-radius-type="bottom_left"><i class="material-icons">border_style</i></button></div>
|
||||
<div class="sek-reset-button"><button type="button" class="button sek-reset-button sek-float-right"><?php _e('Reset', 'text_doma'); ?></button></div>
|
||||
</div>
|
||||
<div class="sek-range-unit-wrapper">
|
||||
<#
|
||||
var range_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'range_number' );
|
||||
if ( _.isFunction( range_tmpl ) ) { print( range_tmpl( data ) ); }
|
||||
var unit_tmpl = wp.customize.CZR_Helpers.getInputSubTemplate( 'unit_picker' );
|
||||
if ( _.isFunction( unit_tmpl ) ) { print( unit_tmpl( data ) ); }
|
||||
#>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* MODULE OPTION SWITCHER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___module_option_switcher">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-content-type-wrapper">
|
||||
<div aria-label="<?php _e('Option type', 'text_doma'); ?>" class="sek-ui-button-group" role="group">
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Module Content', 'text_doma'); ?>" data-sek-option-type="content"><span class="sek-wrap-opt-switch-btn"><i class="material-icons">create</i><span><?php _e('Module Content', 'text_doma'); ?></span></span></button>
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Module Settings', 'text_doma'); ?>" data-sek-option-type="settings"><span class="sek-wrap-opt-switch-btn"><i class="material-icons">tune</i><span><?php _e('Module Settings', 'text_doma'); ?></span></span></button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* CONTENT SWITCHER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___content_type_switcher">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-content-type-wrapper">
|
||||
<div aria-label="<?php _e('Content type', 'text_doma'); ?>" class="sek-ui-button-group" role="group">
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Pick a section', 'text_doma'); ?>" data-sek-content-type="section"><?php _e('Pick a section', 'text_doma'); ?></button>
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Pick a module', 'text_doma'); ?>" data-sek-content-type="module"><?php _e('Pick a module', 'text_doma'); ?></button>
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button" title="<?php _e('Pick a template', 'text_doma'); ?>" data-sek-content-type="template"><?php _e('Pick a template', 'text_doma'); ?> <span class="sek-new-label"><?php _e('New!', 'text_doma'); ?></span></button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* MODULE PICKER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___module_picker">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-content-type-wrapper">
|
||||
<#
|
||||
var icon_img_html = '<i style="color:red">Missing Icon</i>', icon_img_src;
|
||||
|
||||
_.each( sektionsLocalizedData.moduleCollection, function( rawModData ) {
|
||||
//normalizes the module params
|
||||
var modData = jQuery.extend( true, {}, rawModData ),
|
||||
defaultModParams = {
|
||||
'content-type' : 'module',
|
||||
'content-id' : '',
|
||||
'title' : '',
|
||||
'icon' : '',
|
||||
'font_icon' : '',
|
||||
'active' : true,
|
||||
'is_pro' : false
|
||||
},
|
||||
modData = jQuery.extend( defaultModParams, modData );
|
||||
var _assets_version = "<?php echo esc_attr(NIMBLE_ASSETS_VERSION); ?>";
|
||||
if ( !_.isEmpty( modData['icon'] ) ) {
|
||||
if ( 'http' === modData['icon'].substring(0, 4) ) {
|
||||
icon_img_src = modData['icon'];
|
||||
} else {
|
||||
icon_img_src = sektionsLocalizedData.moduleIconPath + modData['icon'];
|
||||
}
|
||||
icon_img_src = icon_img_src + '?v=' + _assets_version;
|
||||
icon_img_html = '<img draggable="false" title="' + modData['title'] + '" alt="' + modData['title'] + '" class="nimble-module-icons" src="' + icon_img_src + '"/>';
|
||||
} else if ( !_.isEmpty( modData['font_icon'] ) ) {
|
||||
icon_img_html = modData['font_icon'];
|
||||
}
|
||||
|
||||
var title_attr = "<?php _e('Drag and drop or double-click to insert in your chosen target element.', 'text_doma'); ?>",
|
||||
font_icon_class = !_.isEmpty( modData['font_icon'] ) ? 'is-font-icon' : '',
|
||||
is_draggable = true !== modData['active'] ? 'false' : 'true',
|
||||
is_pro_module = modData['is_pro'] ? 'yes' : 'no';
|
||||
if ( true !== modData['active'] ) {
|
||||
if ( modData['is_pro'] ) {
|
||||
title_attr = "<?php _e('Pro feature', 'text_doma'); ?>";
|
||||
} else {
|
||||
title_attr = "<?php _e('Available soon ! This module is currently in beta, you can activate it in Site Wide Options > Beta features', 'text_doma'); ?>";
|
||||
}
|
||||
}
|
||||
// "data-sek-eligible-for-module-dropzones" was introduced for https://github.com/presscustomizr/nimble-builder/issues/540
|
||||
#>
|
||||
<div draggable="{{is_draggable}}" data-sek-eligible-for-module-dropzones="true" data-sek-content-type="{{modData['content-type']}}" data-sek-content-id="{{modData['content-id']}}" title="{{title_attr}}" data-sek-is-pro-module="{{is_pro_module}}"><div class="sek-module-icon {{font_icon_class}}"><# print(icon_img_html); #></div><div class="sek-module-title"><div class="sek-centered-module-title">{{modData['title']}}</div></div>
|
||||
<#
|
||||
if ( 'yes' === is_pro_module ) {
|
||||
var pro_img_html = '<div class="sek-is-pro"><img src="' + sektionsLocalizedData.czrAssetsPath + 'sek/img/pro_orange.svg" alt="Pro feature"/></div>';
|
||||
print(pro_img_html);
|
||||
}
|
||||
#>
|
||||
</div>
|
||||
<#
|
||||
});//_.each
|
||||
#>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SECTION PICKER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___section_picker">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-content-type-wrapper">
|
||||
<#
|
||||
// June 2020 : the section collection is passed only when rendering pre-built sections
|
||||
// @see sek_register_prebuilt_section_modules() and sek_get_sections_registration_params()
|
||||
// For user saved sections, the rendering is done in javascript, not here
|
||||
// @see @see _dev_control/modules/ui/_10_0_0_UI_module_and_section_pickers.js
|
||||
var section_collection = ( data.input_data && data.input_data.section_collection ) ? data.input_data.section_collection : [];
|
||||
// if ( _.isEmpty( section_collection ) ) {
|
||||
// wp.customize.errare('Error in js template tmpl-nimble-input___section_picker => missing section collection');
|
||||
// return;
|
||||
// }
|
||||
|
||||
var img_version = sektionsLocalizedData.isDevMode ? Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1) : sektionsLocalizedData.nimbleVersion;
|
||||
// FOR PREBUILT SECTIONS ONLY, user sections are rendered in javascript @see _dev_control/modules/ui/_10_0_0_UI_module_and_section_pickers.js
|
||||
_.each( section_collection, function( rawSecParams ) {
|
||||
//normalizes the params
|
||||
var section_type = 'content',
|
||||
secParams = jQuery.extend( true, {}, rawSecParams ),
|
||||
defaultParams = {
|
||||
'content-id' : '',
|
||||
'thumb' : '',
|
||||
'title' : '',
|
||||
'section_type' : '',
|
||||
'height': '',
|
||||
'active' : true,
|
||||
'is_pro' : false,
|
||||
'demo_url' : false
|
||||
},
|
||||
secParams = jQuery.extend( defaultParams, secParams );
|
||||
|
||||
if ( !_.isEmpty( secParams['section_type'] ) ) {
|
||||
section_type = secParams['section_type'];
|
||||
}
|
||||
|
||||
var thumbUrl = [ sektionsLocalizedData.baseUrl , '/assets/img/section_assets/thumbs/', secParams['thumb'] , '?ver=' , img_version ].join(''),
|
||||
styleAttr = 'background: url(' + thumbUrl + ') 50% 50% / cover no-repeat;',
|
||||
is_draggable = true !== secParams['active'] ? 'false' : 'true',
|
||||
is_pro_section = secParams['is_pro'] ? 'yes' : 'no';
|
||||
|
||||
if ( !_.isEmpty(secParams['height']) ) {
|
||||
styleAttr = styleAttr + 'height:' + secParams['height'] + ';';
|
||||
}
|
||||
|
||||
#>
|
||||
<div draggable="{{is_draggable}}" data-sek-content-type="preset_section" data-sek-content-id="{{secParams['content-id']}}" style="<# print(styleAttr); #>" title="{{secParams['title']}}" data-sek-section-type="{{section_type}}" data-sek-is-pro-section="{{is_pro_section}}"><div class="sek-overlay"></div>
|
||||
<#
|
||||
if ( 'yes' === is_pro_section ) {
|
||||
var pro_img_html = '<div class="sek-is-pro"><img src="' + sektionsLocalizedData.czrAssetsPath + 'sek/img/pro_orange.svg" alt="Pro feature"/></div>';
|
||||
print(pro_img_html);
|
||||
}
|
||||
var demo_title = "<?php _e('View in live demo', 'text_doma'); ?>";
|
||||
if ( secParams['demo_url'] && -1 === secParams['demo_url'].indexOf('http') ) { #>
|
||||
<div class="sek-demo-link"><a href="https://nimblebuilder.com/nimble-builder-sections?utm_source=usersite&utm_medium=link&utm_campaign=section_demos{{secParams['demo_url']}}" target="_blank" rel="noopener noreferrer">{{demo_title}} <i class="fas fa-external-link-alt"></i></a></div>
|
||||
<# } else if ( secParams['demo_url'] ) { #>
|
||||
<div class="sek-demo-link"><a href="{{secParams['demo_url']}}" target="_blank" rel="noopener noreferrer">{{demo_title}} <i class="fas fa-external-link-alt"></i></a></div>
|
||||
<# } #>
|
||||
</div>
|
||||
<#
|
||||
});//_.each
|
||||
#>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* BACKGROUND POSITION INPUT
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___bg_position">
|
||||
<div class="sek-bg-pos-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="top_left">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M14.96 16v-1h-1v-1h-1v-1h-1v-1h-1v-1.001h-1V14h-1v-4-1h5v1h-3v.938h1v.999h1v1h1v1.001h1v1h1V16h-1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="top">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M14.969 12v-1h-1v-1h-1v7h-1v-7h-1v1h-1v1h-1v-1.062h1V9.937h1v-1h1V8h1v.937h1v1h1v1.001h1V12h-1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="top_right">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M9.969 16v-1h1v-1h1v-1h1v-1h1v-1.001h1V14h1v-4-1h-1-4v1h3v.938h-1v.999h-1v1h-1v1.001h-1v1h-1V16h1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="left">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M11.469 9.5h-1v1h-1v1h7v1h-7v1h1v1h1v1h-1.063v-1h-1v-1h-1v-1h-.937v-1h.937v-1h1v-1h1v-1h1.063v1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="center">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M12 9a3 3 0 1 1 0 6 3 3 0 0 1 0-6z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="right">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M12.469 14.5h1v-1h1v-1h-7v-1h7v-1h-1v-1h-1v-1h1.062v1h1v1h1v1h.938v1h-.938v1h-1v1h-1v1h-1.062v-1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="bottom_left">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M14.969 9v1h-1v1h-1v1h-1v1h-1v1.001h-1V11h-1v5h5v-1h-3v-.938h1v-.999h1v-1h1v-1.001h1v-1h1V9h-1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="bottom">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M9.969 13v1h1v1h1V8h1v7h1v-1h1v-1h1v1.063h-1v.999h-1v1.001h-1V17h-1v-.937h-1v-1.001h-1v-.999h-1V13h1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
<label class="sek-bg-pos">
|
||||
<input type="radio" name="sek-bg-pos" value="bottom_right">
|
||||
<span>
|
||||
<svg width="24" height="24">
|
||||
<path id="sek-pth" fill-rule="evenodd" d="M9.969 9v1h1v1h1v1h1v1h1v1.001h1V11h1v5h-1-4v-1h3v-.938h-1v-.999h-1v-1h-1v-1.001h-1v-1h-1V9h1z" class="sek-svg-bg-pos">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
</div><?php // sek-bg-pos-wrapper ?>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* BUTTON CHOICE
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___buttons_choice">
|
||||
<div class="sek-button-choice-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div aria-label="<?php _e('unit', 'text_doma'); ?>" class="sek-ui-button-group sek-float-right" role="group">
|
||||
<#
|
||||
var input_data = data.input_data;
|
||||
if ( _.isEmpty( input_data.choices ) || !_.isObject( input_data.choices ) ) {
|
||||
wp.customize.errare( 'Error in buttons_choice js tmpl => missing or invalid input_data.choices');
|
||||
} else {
|
||||
_.each( input_data.choices, function( label, choice ) {
|
||||
#><button type="button" aria-pressed="false" class="sek-ui-button" title="{{label}}" data-sek-choice="{{choice}}">{{label}}</button><#
|
||||
});
|
||||
}
|
||||
#>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* MULTISELECT, CATEGORY PICKER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___multiselect">
|
||||
<select multiple="multiple" data-czrtype="{{data.input_id}}"></select>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* GRID LAYOUT
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___grid_layout">
|
||||
<div class="sek-grid-layout-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-grid-icons">
|
||||
<div data-sek-grid-layout="list" title="<?php _e('List layout', 'text_doma'); ?>"><i class="material-icons">view_list</i></div>
|
||||
<div data-sek-grid-layout="grid" title="<?php _e('Grid layout', 'text_doma'); ?>"><i class="material-icons">view_module</i></div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* VERTICAL ALIGNMENT
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___v_alignment">
|
||||
<div class="sek-v-align-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-align-icons">
|
||||
<div data-sek-align="top" title="<?php _e('Align top', 'text_doma'); ?>"><i class="material-icons">vertical_align_top</i></div>
|
||||
<div data-sek-align="center" title="<?php _e('Align center', 'text_doma'); ?>"><i class="material-icons">vertical_align_center</i></div>
|
||||
<div data-sek-align="bottom" title="<?php _e('Align bottom', 'text_doma'); ?>"><i class="material-icons">vertical_align_bottom</i></div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REMOVE BUTTON
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___reset_button">
|
||||
<div class="sek-button-choice-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button sek-float-right" title="<?php _e('Remove now', 'text_doma'); ?>" data-sek-reset-scope="{{data.input_data.scope}}"><?php _e('Remove now', 'text_doma'); ?></button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REFRESH PREVIEW BUTTON
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___refresh_preview_button">
|
||||
<div class="sek-button-choice-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<button type="button" aria-pressed="false" class="sek-refresh-button sek-float-right button button-primary" title="<?php _e('Refresh preview', 'text_doma'); ?>"><?php _e('Refresh preview', 'text_doma'); ?></button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REVISION HISTORY / HIDDEN
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___revision_history">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
</script>
|
||||
|
||||
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* IMPORT / EXPORT
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___import_export">
|
||||
<div class="sek-export-btn-wrap">
|
||||
<div class="customize-control-title width-100"><?php //_e('Export', 'text_doma'); ?></div>
|
||||
<button type="button" class="button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{data.input_id}}" data-czr-action="sek-export"><?php _e('Export', 'text_doma' ); ?></button>
|
||||
</div>
|
||||
<div class="sek-import-btn-wrap">
|
||||
<div class="customize-control-title width-100"><?php _e('IMPORT', 'text_doma'); ?></div>
|
||||
<span class="czr-notice"><?php _e('Select the file to import and click on Import button.', 'text_doma' ); ?></span>
|
||||
<span class="czr-notice"><?php _e('Be sure to import a file generated with Nimble Builder export system.', 'text_doma' ); ?></span>
|
||||
<?php // <DIALOG FOR LOCAL IMPORT> ?>
|
||||
<div class="czr-import-dialog czr-local-import notice notice-info">
|
||||
<div class="czr-import-message"><?php _e('Some of the imported sections need a location that is not active on this page. Sections in missing locations will not be rendered. You can continue importing or assign those sections to a contextually active location.', 'text_doma' ); ?></div>
|
||||
<button type="button" class="button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{data.input_id}}" data-czr-action="sek-import-as-is"><?php _e('Import without modification', 'text_doma' ); ?></button>
|
||||
<button type="button" class="button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{data.input_id}}" data-czr-action="sek-import-assign"><?php _e('Import in existing locations', 'text_doma' ); ?></button>
|
||||
<button type="button" class="button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{data.input_id}}" data-czr-action="sek-cancel-import"><?php _e('Cancel import', 'text_doma' ); ?></button>
|
||||
</div>
|
||||
<?php // </DIALOG FOR LOCAL IMPORT> ?>
|
||||
<?php // <DIALOG FOR GLOBAL IMPORT> ?>
|
||||
<div class="czr-import-dialog czr-global-import notice notice-info">
|
||||
<div class="czr-import-message"><?php _e('Some of the imported sections need a location that is not active on this page. For example, if you are importing a global header footer, you need to activate the Nimble site wide header and footer, in "Site wide header and footer" options.', 'text_doma' ); ?></div>
|
||||
<button type="button" class="button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{data.input_id}}" data-czr-action="sek-import-as-is"><?php _e('Import', 'text_doma' ); ?></button>
|
||||
<button type="button" class="button" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{data.input_id}}" data-czr-action="sek-cancel-import"><?php _e('Cancel import', 'text_doma' ); ?></button>
|
||||
</div>
|
||||
<?php // </DIALOG FOR GLOBAL IMPORT> ?>
|
||||
<div class="sek-uploading"><?php _e( 'Uploading...', 'text_doma' ); ?></div>
|
||||
<input type="file" name="sek-import-file" class="sek-import-file" />
|
||||
<input type="hidden" name="sek-skope" value="{{data.input_data.scope}}" />
|
||||
<button type="button" class="button disabled" data-czr-control-id="{{ data.control_id }}" data-czr-input-id="{{data.input_id}}" data-czr-action="sek-pre-import"><?php _e('Import', 'text_doma' ); ?></button>
|
||||
|
||||
</div>
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden" value="{{data.value}}"/>
|
||||
</script>
|
||||
<?php
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* INACTIVE
|
||||
* Sept 2020 introduced an "inactive" input type in order to display pro info for Nimble
|
||||
* this input should be "hidden" type, and should not trigger an API change.
|
||||
* when working on https://github.com/presscustomizr/nimble-builder-pro/issues/67
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___inactive">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
</script>
|
||||
<?php
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SITE TMPL PICKER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
?>
|
||||
<script type="text/html" id="tmpl-nimble-input___site_tmpl_picker">
|
||||
<div class="sek-button-choice-wrapper">
|
||||
<input data-czrtype="{{data.input_id}}" type="hidden"/>
|
||||
<div class="sek-ui-button-group" role="group">
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button sek-remove-site-tmpl" title="<?php _e('Reset to default', 'text_doma'); ?>"><?php _e('Reset to default', 'text_doma'); ?></button>
|
||||
<button type="button" aria-pressed="false" class="sek-ui-button sek-pick-site-tmpl" title="<?php _e('Pick a template', 'text_doma'); ?>" data-sek-group-scope="{{data.input_id}}"><?php _e('Pick a template', 'text_doma'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
}//sek_print_nimble_input_templates() @hook 'customize_controls_print_footer_scripts'
|
||||
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SETUP DYNAMIC SERVER REGISTRATION FOR SETTING
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Fired @'after_setup_theme:20'
|
||||
if ( !class_exists( 'SEK_CZR_Dyn_Register' ) ) :
|
||||
class SEK_CZR_Dyn_Register {
|
||||
static $instance;
|
||||
public $sanitize_callbacks = array();// <= will be populated to cache the callbacks when invoking sek_get_module_sanitize_callbacks().
|
||||
|
||||
public static function get_instance( $params ) {
|
||||
if ( !isset( self::$instance ) && !( self::$instance instanceof SEK_CZR_Dyn_Register ) )
|
||||
self::$instance = new SEK_CZR_Dyn_Register( $params );
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
function __construct( $params = array() ) {
|
||||
// Schedule the loading the skoped settings class
|
||||
add_action( 'customize_register', array( $this, 'load_nimble_setting_class' ) );
|
||||
|
||||
add_filter( 'customize_dynamic_setting_args', array( $this, 'set_dyn_setting_args' ), 10, 2 );
|
||||
add_filter( 'customize_dynamic_setting_class', array( $this, 'set_dyn_setting_class') , 10, 3 );
|
||||
}//__construct
|
||||
|
||||
//@action 'customize_register'
|
||||
function load_nimble_setting_class() {
|
||||
require_once( NIMBLE_BASE_PATH . '/inc/sektions/seks_setting_class.php' );
|
||||
}
|
||||
|
||||
//@filter 'customize_dynamic_setting_args'
|
||||
function set_dyn_setting_args( $setting_args, $setting_id ) {
|
||||
// shall start with "nimble___" or "nimble_global_opts"
|
||||
// those are the setting that will actually be saved in DB :
|
||||
// - sektion collections ( local and global skope )
|
||||
// - global options
|
||||
// - site template options
|
||||
if ( 0 === strpos( $setting_id, NIMBLE_OPT_PREFIX_FOR_SEKTION_COLLECTION ) || 0 === strpos( $setting_id, NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS ) ) {
|
||||
//sek_error_log( 'DYNAMICALLY REGISTERING SEK SETTING => ' . $setting_id, $setting_args);
|
||||
return array(
|
||||
'transport' => 'refresh',
|
||||
'type' => 'option',
|
||||
'default' => array(),
|
||||
// Only the section collections are sanitized on save
|
||||
'sanitize_callback' => 0 === strpos( $setting_id, NIMBLE_OPT_PREFIX_FOR_SEKTION_COLLECTION ) ? '\Nimble\sek_sektion_collection_sanitize_cb' : null
|
||||
//'validate_callback' => '\Nimble\sek_sektion_collection_validate_cb'
|
||||
);
|
||||
} else if ( 0 === strpos( $setting_id, NIMBLE_PREFIX_FOR_SETTING_NOT_SAVED ) ) {
|
||||
//sek_error_log( 'DYNAMICALLY REGISTERING SEK SETTING => ' . $setting_id, $setting_args);
|
||||
return array(
|
||||
'transport' => 'refresh',
|
||||
'type' => '_nimble_ui_',//won't be saved as is,
|
||||
'default' => array(),
|
||||
//'sanitize_callback' => array( $this, 'sanitize_callback' ),
|
||||
//'validate_callback' => '\Nimble\sek_sektion_collection_validate_cb'
|
||||
);
|
||||
}
|
||||
return $setting_args;
|
||||
//return wp_parse_args( array( 'default' => array() ), $setting_args );
|
||||
}
|
||||
|
||||
|
||||
//@filter 'customize_dynamic_setting_class'
|
||||
// We use a custom setting class only for the section collections ( local and global ), not for global options and site template options
|
||||
function set_dyn_setting_class( $class, $setting_id, $args ) {
|
||||
//sek_error_log( 'REGISTERING CLASS DYNAMICALLY for setting =>' . $setting_id );
|
||||
// Setting class for NB global options and Site Template options
|
||||
if ( 0 === strpos( $setting_id, NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS ) ) {
|
||||
return '\Nimble\Nimble_Options_Setting';
|
||||
}
|
||||
|
||||
// Setting class for NB sektion collections => shall start with 'nimble___'
|
||||
if ( 0 === strpos( $setting_id, NIMBLE_OPT_PREFIX_FOR_SEKTION_COLLECTION ) ) {
|
||||
return '\Nimble\Nimble_Collection_Setting';
|
||||
}
|
||||
return $class;
|
||||
}
|
||||
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// GENERIC HELPER FIRED IN ALL AJAX CALLBACKS
|
||||
// @param $params = array('check_nonce' => true )
|
||||
function sek_do_ajax_pre_checks( $params = array() ) {
|
||||
$params = wp_parse_args( $params, array( 'check_nonce' => true ) );
|
||||
if ( $params['check_nonce'] ) {
|
||||
$action = 'save-customize_' . get_stylesheet();
|
||||
if ( !check_ajax_referer( $action, 'nonce', false ) ) {
|
||||
wp_send_json_error( array(
|
||||
'code' => 'invalid_nonce',
|
||||
'message' => __( __CLASS__ . '::' . __FUNCTION__ . ' => check_ajax_referer() failed.' ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !is_user_logged_in() ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => unauthenticated' );
|
||||
}
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => user_cant_edit_theme_options');
|
||||
}
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
status_header( 403 );
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => customize_not_allowed' );
|
||||
} else if ( !isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
|
||||
status_header( 405 );
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => bad_method' );
|
||||
}
|
||||
}//sek_do_ajax_pre_checks()
|
||||
|
||||
|
||||
|
||||
// IMPORT IMG
|
||||
add_action( 'wp_ajax_sek_import_attachment', '\Nimble\sek_ajax_import_attachment' );
|
||||
// Fetches the list of revision for a given skope_id
|
||||
add_action( 'wp_ajax_sek_get_revision_history', '\Nimble\sek_get_revision_history' );
|
||||
// Fetches the revision for a given post id
|
||||
add_action( 'wp_ajax_sek_get_single_revision', '\Nimble\sek_get_single_revision' );
|
||||
// Fetches the category collection to generate the options for a select input
|
||||
// @see api.czrInputMap.category_picker
|
||||
add_action( 'wp_ajax_sek_get_post_categories', '\Nimble\sek_get_post_categories' );
|
||||
|
||||
// Fetches the code editor params to generate the options for a textarea input
|
||||
// @see api.czrInputMap.code_editor
|
||||
add_action( 'wp_ajax_sek_get_code_editor_params', '\Nimble\sek_get_code_editor_params' );
|
||||
|
||||
add_action( 'wp_ajax_sek_postpone_feedback', '\Nimble\sek_postpone_feedback_notification' );
|
||||
|
||||
// <AJAX TO FETCH INPUT COMPONENTS>
|
||||
// this dynamic filter is declared on wp_ajax_ac_get_template in the czr_base_fmk
|
||||
// It allows us to populate the server response with the relevant module html template
|
||||
// $html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl );
|
||||
add_filter( "ac_set_ajax_czr_tmpl___fa_icon_picker_input", '\Nimble\sek_get_fa_icon_list_tmpl', 10, 3 );
|
||||
|
||||
// this dynamic filter is declared on wp_ajax_ac_get_template in the czr_base_fmk
|
||||
// It allows us to populate the server response with the relevant module html template
|
||||
// $html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl );
|
||||
add_filter( "ac_set_ajax_czr_tmpl___font_picker_input", '\Nimble\sek_get_font_list_tmpl', 10, 3 );
|
||||
// </AJAX TO FETCH INPUT COMPONENTS>
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// hook : wp_ajax_sek_import_attachment
|
||||
function sek_ajax_import_attachment() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => false ) );
|
||||
|
||||
if ( !isset( $_POST['img_url'] ) || !is_string($_POST['img_url']) ) {
|
||||
wp_send_json_error( 'missing_or_invalid_img_url_when_importing_image');
|
||||
}
|
||||
|
||||
$id = sek_sideload_img_and_return_attachment_id( sanitize_text_field($_POST['img_url']) );
|
||||
if ( is_wp_error( $id ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => problem when trying to wp_insert_attachment() for img : ' . sanitize_text_field($_POST['img_url']) . ' | SERVER ERROR => ' . json_encode( $id ) );
|
||||
} else {
|
||||
wp_send_json_success([
|
||||
'id' => $id,
|
||||
'url' => wp_get_attachment_url( $id )
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// REVISIONS
|
||||
// Fired in __construct()
|
||||
function sek_get_revision_history() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => missing skope_id' );
|
||||
}
|
||||
$rev_list = sek_get_revision_history_from_posts( sanitize_text_field($_POST['skope_id']) );
|
||||
wp_send_json_success( $rev_list );
|
||||
}
|
||||
|
||||
|
||||
function sek_get_single_revision() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
if ( !isset( $_POST['revision_post_id'] ) || empty( $_POST['revision_post_id'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => missing revision_post_id' );
|
||||
}
|
||||
$revision = sek_get_single_post_revision( sanitize_text_field($_POST['revision_post_id']) );
|
||||
wp_send_json_success( $revision );
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// POST CATEGORIES => to be used in the category picker select input
|
||||
// Fired in __construct()
|
||||
function sek_get_post_categories() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
$raw_cats = get_categories();
|
||||
$raw_cats = is_array( $raw_cats ) ? $raw_cats : array();
|
||||
$cat_collection = array();
|
||||
foreach( $raw_cats as $cat ) {
|
||||
$cat_collection[] = array(
|
||||
'id' => $cat->term_id,
|
||||
'slug' => $cat->slug,
|
||||
'name' => sprintf( '%s (%s %s)', $cat->cat_name, $cat->count, __('posts', 'text_doma') )
|
||||
);
|
||||
}
|
||||
wp_send_json_success( $cat_collection );
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// CODE EDITOR PARAMS => to be used in the code editor input
|
||||
// Fired in __construct()
|
||||
function sek_get_code_editor_params() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
$code_type = isset( $_POST['code_type'] ) ? sanitize_text_field($_POST['code_type']) : 'text/html';
|
||||
$editor_params = nimble_get_code_editor_settings( array(
|
||||
'type' => $code_type
|
||||
));
|
||||
wp_send_json_success( $editor_params );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// POSTPONE FEEDBACK NOTIFICATION IN CUSTOMIZER
|
||||
// INSPIRED FROM CORE DISMISS POINTER MECHANISM
|
||||
// @see wp-admin/includes/ajax-actions.php
|
||||
// Nov 2020 => DEPRECATED https://github.com/presscustomizr/nimble-builder/issues/701
|
||||
function sek_postpone_feedback_notification() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
if ( !isset( $_POST['transient_duration_in_days'] ) ||!is_numeric( $_POST['transient_duration_in_days'] ) ) {
|
||||
$transient_duration = 7 * DAY_IN_SECONDS;
|
||||
} else {
|
||||
$transient_duration = sanitize_text_field($_POST['transient_duration_in_days']) * DAY_IN_SECONDS;
|
||||
}
|
||||
set_transient( NIMBLE_FEEDBACK_NOTICE_ID, 'maybe_later', $transient_duration );
|
||||
wp_die( 1 );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// FETCH FONT AWESOME ICONS
|
||||
// hook : ac_set_ajax_czr_tmpl___czr_tiny_mce_editor_module
|
||||
// this dynamic filter is declared on wp_ajax_ac_get_template
|
||||
// It allows us to populate the server response with the relevant module html template
|
||||
// $html = apply_filters( "ac_set_ajax_czr_tmpl___{$module_type}", '', $tmpl );
|
||||
//
|
||||
// For czr_tiny_mce_editor_module, we request the font_list tmpl
|
||||
function sek_get_fa_icon_list_tmpl( $html, $requested_tmpl = '', $posted_params = array() ) {
|
||||
if ( empty( $requested_tmpl ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . ' => the requested tmpl is empty' );
|
||||
}
|
||||
return wp_json_encode(
|
||||
sek_retrieve_decoded_font_awesome_icons()
|
||||
);//will be sent by wp_send_json_success() in ::ac_set_ajax_czr_tmpl()
|
||||
}
|
||||
|
||||
|
||||
//retrieves faicons:
|
||||
// 1) from faicons.json if needed (transient doesn't exists, or is new version => set in TC_wfc ) and decodes them
|
||||
// otherwise
|
||||
// 2) from the transient set if it exists
|
||||
function sek_retrieve_decoded_font_awesome_icons() {
|
||||
// this file must be generated with: https://github.com/presscustomizr/nimble-builder/issues/57
|
||||
$faicons_json_path = NIMBLE_BASE_PATH . '/assets/faicons.json';
|
||||
$faicons_transient_name = NIMBLE_FAWESOME_TRANSIENT_ID;
|
||||
if ( false == get_transient( $faicons_transient_name ) ) {
|
||||
if ( file_exists( $faicons_json_path ) ) {
|
||||
$faicons_raw = @file_get_contents( $faicons_json_path );
|
||||
|
||||
if ( false === $faicons_raw ) {
|
||||
$faicons_raw = wp_remote_fopen( $faicons_json_path );
|
||||
}
|
||||
|
||||
$faicons_decoded = json_decode( $faicons_raw, true );
|
||||
set_transient( $faicons_transient_name , $faicons_decoded , 60*60*24*3000 );
|
||||
} else {
|
||||
wp_send_json_error( __FUNCTION__ . ' => the file faicons.json is missing' );
|
||||
}
|
||||
}
|
||||
else {
|
||||
$faicons_decoded = get_transient( $faicons_transient_name );
|
||||
}
|
||||
|
||||
return $faicons_decoded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// FETCH FONT LISTS
|
||||
// hook : ac_set_ajax_czr_tmpl___czr_tiny_mce_editor_module
|
||||
// For czr_tiny_mce_editor_module, we request the font_list tmpl
|
||||
function sek_get_font_list_tmpl( $html, $requested_tmpl = '', $posted_params = array() ) {
|
||||
if ( empty( $requested_tmpl ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . ' => the requested tmpl is empty' );
|
||||
}
|
||||
|
||||
return wp_json_encode( array(
|
||||
'cfonts' => sek_get_cfonts(),
|
||||
'gfonts' => sek_get_gfonts(),
|
||||
) );//will be sent by wp_send_json_success() in ::ac_set_ajax_czr_tmpl()
|
||||
}
|
||||
|
||||
|
||||
function sek_get_cfonts() {
|
||||
$cfonts = array();
|
||||
$raw_cfonts = array(
|
||||
'-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue, Arial, sans-serif',
|
||||
'Arial Black,Arial Black,Gadget,sans-serif',
|
||||
'Century Gothic',
|
||||
'Comic Sans MS,Comic Sans MS,cursive',
|
||||
'Courier New,Courier New,Courier,monospace',
|
||||
'Georgia,Georgia,serif',
|
||||
'Helvetica Neue, Helvetica, Arial, sans-serif',
|
||||
'Impact,Charcoal,sans-serif',
|
||||
'Lucida Console,Monaco,monospace',
|
||||
'Lucida Sans Unicode,Lucida Grande,sans-serif',
|
||||
'Palatino Linotype,Book Antiqua,Palatino,serif',
|
||||
'Tahoma,Geneva,sans-serif',
|
||||
'Times New Roman,Times,serif',
|
||||
'Trebuchet MS,Helvetica,sans-serif',
|
||||
'Verdana,Geneva,sans-serif',
|
||||
);
|
||||
foreach ( $raw_cfonts as $font ) {
|
||||
//no subsets for cfonts => epty array()
|
||||
$cfonts[] = array(
|
||||
'name' => $font ,
|
||||
'subsets' => array()
|
||||
);
|
||||
}
|
||||
return apply_filters( 'sek_font_picker_cfonts', $cfonts );
|
||||
}
|
||||
|
||||
|
||||
//retrieves gfonts:
|
||||
// 1) from webfonts.json if needed (transient doesn't exists, or is new version => set in TC_wfc ) and decodes them
|
||||
// otherwise
|
||||
// 2) from the transiet set if it exists
|
||||
//
|
||||
// => Until June 2017, the webfonts have been stored in 'tc_gfonts' transient
|
||||
// => In June 2017, the Google Fonts have been updated with a new webfonts.json
|
||||
// generated from : https://www.googleapis.com/webfonts/v1/webfonts?key=AIzaSyBID8gp8nBOpWyH5MrsF7doP4fczXGaHdA
|
||||
//
|
||||
// => The transient name is now : czr_gfonts_june_2017
|
||||
function sek_retrieve_decoded_gfonts() {
|
||||
if ( false == get_transient( NIMBLE_GFONTS_TRANSIENT_ID ) ) {
|
||||
$gfont_raw = @file_get_contents( NIMBLE_BASE_PATH ."/assets/webfonts.json" );
|
||||
|
||||
if ( $gfont_raw === false ) {
|
||||
$gfont_raw = wp_remote_fopen( NIMBLE_BASE_PATH ."/assets/webfonts.json" );
|
||||
}
|
||||
|
||||
$gfonts_decoded = json_decode( $gfont_raw, true );
|
||||
set_transient( NIMBLE_GFONTS_TRANSIENT_ID , $gfonts_decoded , 60*60*24*3000 );
|
||||
}
|
||||
else {
|
||||
$gfonts_decoded = get_transient( NIMBLE_GFONTS_TRANSIENT_ID );
|
||||
}
|
||||
|
||||
return $gfonts_decoded;
|
||||
}
|
||||
|
||||
//@return the google fonts
|
||||
function sek_get_gfonts( $what = null ) {
|
||||
//checks if transient exists or has expired
|
||||
|
||||
$gfonts_decoded = sek_retrieve_decoded_gfonts();
|
||||
$gfonts = array();
|
||||
//$subsets = array();
|
||||
|
||||
// $subsets['all-subsets'] = sprintf( '%1$s ( %2$s %3$s )',
|
||||
// __( 'All languages' , 'text_doma' ),
|
||||
// count($gfonts_decoded['items']) + count( get_cfonts() ),
|
||||
// __('fonts' , 'text_doma' )
|
||||
// );
|
||||
|
||||
foreach ( $gfonts_decoded['items'] as $font ) {
|
||||
foreach ( $font['variants'] as $variant ) {
|
||||
$name = str_replace( ' ', '+', $font['family'] );
|
||||
$gfonts[] = array(
|
||||
'name' => $name . ':' .$variant
|
||||
//'subsets' => $font['subsets']
|
||||
);
|
||||
}
|
||||
//generates subset list : subset => font number
|
||||
// foreach ( $font['subsets'] as $sub ) {
|
||||
// $subsets[$sub] = isset($subsets[$sub]) ? $subsets[$sub]+1 : 1;
|
||||
// }
|
||||
}
|
||||
|
||||
//finalizes the subset array
|
||||
// foreach ( $subsets as $subset => $font_number ) {
|
||||
// if ( 'all-subsets' == $subset )
|
||||
// continue;
|
||||
// $subsets[$subset] = sprintf('%1$s ( %2$s %3$s )',
|
||||
// $subset,
|
||||
// $font_number,
|
||||
// __('fonts' , 'text_doma' )
|
||||
// );
|
||||
// }
|
||||
|
||||
return ('subsets' == $what) ? apply_filters( 'sek_font_picker_gfonts_subsets ', $subsets ) : apply_filters( 'sek_font_picker_gfonts', $gfonts ) ;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
add_action( 'customize_register', '\Nimble\sek_catch_export_action', PHP_INT_MAX );
|
||||
function sek_catch_export_action( $wp_customize ) {
|
||||
if ( current_user_can( 'customize' ) ) {
|
||||
if ( isset( $_REQUEST['sek_export_nonce'] ) ) {
|
||||
sek_maybe_export();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fire from sek_catch_export_action() @hook 'customize_register'
|
||||
function sek_maybe_export() {
|
||||
$nonce = 'save-customize_' . get_stylesheet();
|
||||
if ( !isset( $_REQUEST['sek_export_nonce'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing nonce.');
|
||||
return;
|
||||
}
|
||||
if ( !isset( $_REQUEST['skope_id']) || empty( $_REQUEST['skope_id'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing or empty skope_id.');
|
||||
return;
|
||||
}
|
||||
if ( !isset( $_REQUEST['active_locations'] ) || empty( $_REQUEST['active_locations'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing active locations param.');
|
||||
return;
|
||||
}
|
||||
if ( !wp_verify_nonce( $_REQUEST['sek_export_nonce'], $nonce ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid none.');
|
||||
return;
|
||||
}
|
||||
if ( !is_user_logged_in() ) {
|
||||
sek_error_log( __FUNCTION__ . ' => user not logged in.');
|
||||
return;
|
||||
}
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing customize capabilities.');
|
||||
return;
|
||||
}
|
||||
|
||||
$seks_data = sek_get_skoped_seks( sanitize_text_field($_REQUEST['skope_id']) );
|
||||
|
||||
//sek_error_log('EXPORT BEFORE FILTER ? ' . $_REQUEST['skope_id'] , $seks_data );
|
||||
// the filter 'nimble_pre_export' is used to :
|
||||
// replace image id by the absolute url
|
||||
// clean level ids and replace them with a placeholder string
|
||||
$seks_data = apply_filters( 'nimble_pre_export', $seks_data );
|
||||
|
||||
// March 2021 : make sure text input are sanitized like in #544 #792
|
||||
//$seks_data = sek_sektion_collection_sanitize_cb( $seks_data );
|
||||
|
||||
$theme_name = sanitize_title_with_dashes( get_stylesheet() );
|
||||
|
||||
//sek_error_log('EXPORT AFTER FILTER ?', $seks_data );
|
||||
$export = array(
|
||||
'data' => $seks_data,
|
||||
'metas' => array(
|
||||
'skope_id' => sanitize_text_field($_REQUEST['skope_id']),
|
||||
'version' => NIMBLE_VERSION,
|
||||
// is sent as a string : "__after_header,__before_main_wrapper,loop_start,__before_footer"
|
||||
'active_locations' => is_string( $_REQUEST['active_locations'] ) ? explode( ',', sanitize_text_field($_REQUEST['active_locations']) ) : array(),
|
||||
'date' => date("Y-m-d"),
|
||||
'theme' => $theme_name
|
||||
)
|
||||
);
|
||||
|
||||
//sek_error_log('$export ?', $export );
|
||||
|
||||
$skope_id = str_replace('skp__', '', sanitize_text_field($_REQUEST['skope_id']) );
|
||||
$filename = $theme_name . '_' . $skope_id . '.nimblebuilder';
|
||||
|
||||
// Set the download headers.
|
||||
header( 'Content-disposition: attachment; filename=' . $filename );
|
||||
header( 'Content-Type: application/octet-stream; charset=' . get_option( 'blog_charset' ) );
|
||||
|
||||
echo wp_json_encode( $export );
|
||||
|
||||
// Start the download.
|
||||
die();
|
||||
}
|
||||
|
||||
// Ajax action before processing the export
|
||||
// control that all required fields are there
|
||||
// This is to avoid a white screen when generating the download window afterwards
|
||||
add_action( 'wp_ajax_sek_pre_export_checks', '\Nimble\sek_ajax_pre_export_checks' );
|
||||
function sek_ajax_pre_export_checks() {
|
||||
//sek_error_log('PRE EXPORT CHECKS ?', $_POST );
|
||||
$action = 'save-customize_' . get_stylesheet();
|
||||
if ( !check_ajax_referer( $action, 'nonce', false ) ) {
|
||||
wp_send_json_error( 'check_ajax_referer_failed' );
|
||||
}
|
||||
if ( !is_user_logged_in() ) {
|
||||
wp_send_json_error( 'user_unauthenticated' );
|
||||
}
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
status_header( 403 );
|
||||
wp_send_json_error( 'customize_not_allowed' );
|
||||
} else if ( !isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
|
||||
status_header( 405 );
|
||||
wp_send_json_error( 'bad_ajax_method' );
|
||||
}
|
||||
if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
wp_send_json_error( 'missing_skope_id' );
|
||||
}
|
||||
if ( !isset( $_POST['active_locations'] ) || empty( $_POST['active_locations'] ) ) {
|
||||
wp_send_json_error( 'no_active_locations_to_export' );
|
||||
}
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// EXPORT FILTER
|
||||
add_filter( 'nimble_pre_export', '\Nimble\sek_parse_img_and_clean_id' );
|
||||
function sek_parse_img_and_clean_id( $seks_data ) {
|
||||
$new_seks_data = array();
|
||||
foreach ( $seks_data as $key => $value ) {
|
||||
if ( is_array($value) ) {
|
||||
$new_seks_data[$key] = sek_parse_img_and_clean_id( $value );
|
||||
} else {
|
||||
switch( $key ) {
|
||||
case 'bg-image' :
|
||||
case 'img' :
|
||||
if ( is_int( $value ) && (int)$value > 0 ) {
|
||||
$value = '__img_url__' . wp_get_attachment_url((int)$value);
|
||||
}
|
||||
break;
|
||||
case 'id' :
|
||||
if ( is_string( $value ) && false !== strpos( $value, '__nimble__' ) ) {
|
||||
$value = '__rep__me__';
|
||||
}
|
||||
break;
|
||||
}
|
||||
$new_seks_data[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $new_seks_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fetch the content from a user imported file
|
||||
add_action( 'wp_ajax_sek_get_manually_imported_file_content', '\Nimble\sek_ajax_get_manually_imported_file_content' );
|
||||
function sek_ajax_get_manually_imported_file_content() {
|
||||
// sek_error_log(__FUNCTION__ . ' AJAX $_POST ?', $_POST );
|
||||
// sek_error_log(__FUNCTION__ . ' AJAX $_FILES ?', $_FILES );
|
||||
// sek_error_log(__FUNCTION__ . ' AJAX $_REQUEST ?', $_REQUEST );
|
||||
|
||||
$action = 'save-customize_' . get_stylesheet();
|
||||
if ( !check_ajax_referer( $action, 'nonce', false ) ) {
|
||||
wp_send_json_error( 'check_ajax_referer_failed' );
|
||||
}
|
||||
if ( !is_user_logged_in() ) {
|
||||
wp_send_json_error( 'user_unauthenticated' );
|
||||
}
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
status_header( 403 );
|
||||
wp_send_json_error( 'customize_not_allowed' );
|
||||
} else if ( !isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
|
||||
status_header( 405 );
|
||||
wp_send_json_error( 'bad_ajax_method' );
|
||||
}
|
||||
if ( !isset( $_FILES['file_candidate'] ) || empty( $_FILES['file_candidate'] ) ) {
|
||||
wp_send_json_error( 'missing_file_candidate' );
|
||||
}
|
||||
if ( !isset( $_POST['skope'] ) || empty( $_POST['skope'] ) ) {
|
||||
wp_send_json_error( 'missing_skope' );
|
||||
}
|
||||
|
||||
// load WP upload if not done yet
|
||||
if ( !function_exists( 'wp_handle_upload' ) ) {
|
||||
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
||||
}
|
||||
|
||||
// @see https://codex.wordpress.org/Function_Reference/wp_handle_upload
|
||||
// Important => always run unlink( $file['file'] ) before sending the json success or error
|
||||
// otherwise WP will write the file in the /wp-content folder
|
||||
$file = wp_handle_upload(
|
||||
$_FILES['file_candidate'],
|
||||
array(
|
||||
'test_form' => false,
|
||||
'test_type' => false,
|
||||
'mimes' => array(
|
||||
'text' => 'text/plain',
|
||||
//'nimblebuilder' => 'text/plain',
|
||||
'json' => 'application/json',
|
||||
'nimblebuilder' => 'application/json'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Make sure we have an uploaded file.
|
||||
if ( isset( $file['error'] ) ) {
|
||||
unlink( $file['file'] );
|
||||
wp_send_json_error( 'import_file_error' );
|
||||
return;
|
||||
}
|
||||
if ( !file_exists( $file['file'] ) ) {
|
||||
unlink( $file['file'] );
|
||||
wp_send_json_error( 'import_file_do_not_exist' );
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the upload data.
|
||||
$raw = file_get_contents( $file['file'] );
|
||||
//$raw_unserialized_data = @unserialize( $raw );
|
||||
$raw_unserialized_data = json_decode( $raw, true );
|
||||
|
||||
// VALIDATE IMPORTED CONTENT
|
||||
// data structure :
|
||||
// $raw_unserialized_data = array(
|
||||
// 'data' => $seks_data,
|
||||
// 'metas' => array(
|
||||
// 'skope_id' => $_REQUEST['skope_id'],
|
||||
// 'version' => NIMBLE_VERSION,
|
||||
// // is sent as a string : "__after_header,__before_main_wrapper,loop_start,__before_footer"
|
||||
// 'active_locations' => is_string( $_REQUEST['active_locations'] ) ? explode( ',', $_REQUEST['active_locations'] ) : array(),
|
||||
// 'date' => date("Y-m-d")
|
||||
// )
|
||||
// );
|
||||
// check import structure
|
||||
if ( !is_array( $raw_unserialized_data ) || empty( $raw_unserialized_data['data']) || !is_array( $raw_unserialized_data['data'] ) || empty( $raw_unserialized_data['metas'] ) || !is_array( $raw_unserialized_data['metas'] ) ) {
|
||||
unlink( $file['file'] );
|
||||
wp_send_json_error( 'invalid_import_content' );
|
||||
return;
|
||||
}
|
||||
// check version
|
||||
// => current Nimble Version must be at least import version
|
||||
if ( !empty( $raw_unserialized_data['metas']['version'] ) && version_compare( NIMBLE_VERSION, $raw_unserialized_data['metas']['version'], '<' ) ) {
|
||||
unlink( $file['file'] );
|
||||
wp_send_json_error( 'nimble_builder_needs_update' );
|
||||
return;
|
||||
}
|
||||
|
||||
$maybe_import_images = true;
|
||||
// in a pre-import-check context, we don't need to sniff and upload images
|
||||
if ( array_key_exists( 'pre_import_check', $_POST ) && true === sek_booleanize_checkbox_val( sanitize_text_field($_POST['pre_import_check']) ) ) {
|
||||
$maybe_import_images = false;
|
||||
}
|
||||
// april 2020 : introduced for https://github.com/presscustomizr/nimble-builder/issues/663
|
||||
if ( array_key_exists( 'import_img', $_POST ) && false === sek_booleanize_checkbox_val( sanitize_text_field($_POST['import_img']) ) ) {
|
||||
$maybe_import_images = false;
|
||||
}
|
||||
|
||||
// Make sure NB decodes encoded rich text before sending to the customizer
|
||||
// see #544 and #791
|
||||
$raw_unserialized_data['data'] = sek_sniff_and_decode_richtext( $raw_unserialized_data['data'] );
|
||||
|
||||
$imported_content = array(
|
||||
//'data' => apply_filters( 'nimble_pre_import', $raw_unserialized_data['data'], $do_import_images ),
|
||||
'data' => sek_maybe_import_imgs( $raw_unserialized_data['data'], $maybe_import_images ),
|
||||
'metas' => $raw_unserialized_data['metas'],
|
||||
// the image import errors won't block the import
|
||||
// they are used when notifying user in the customizer
|
||||
'img_errors' => !empty( Nimble_Manager()->img_import_errors ) ? implode(',', Nimble_Manager()->img_import_errors) : array()
|
||||
);
|
||||
|
||||
// Remove the uploaded file
|
||||
// Important => always run unlink( $file['file'] ) before sending the json success or error
|
||||
// otherwise WP will write the file in the /wp-content folder
|
||||
unlink( $file['file'] );
|
||||
// Send
|
||||
wp_send_json_success( $imported_content );
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,324 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Fetches the user saved templates
|
||||
add_action( 'wp_ajax_sek_get_all_saved_tmpl', '\Nimble\sek_ajax_get_all_saved_templates' );
|
||||
// @hook wp_ajax_sek_get_user_saved_templates
|
||||
function sek_ajax_get_all_saved_templates() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
$decoded_templates = sek_get_all_saved_templates();
|
||||
|
||||
if ( is_array($decoded_templates) ) {
|
||||
wp_send_json_success( $decoded_templates );
|
||||
} else {
|
||||
if ( !empty( $decoded_templates ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => invalid templates returned', $decoded_templates );
|
||||
wp_send_json_error( __FUNCTION__ . ' error => invalid templates returned' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Fetches the api templates
|
||||
add_action( 'wp_ajax_sek_get_all_api_tmpl', '\Nimble\sek_ajax_get_all_api_templates' );
|
||||
// @hook wp_ajax_sek_get_user_saved_templates
|
||||
function sek_ajax_get_all_api_templates() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
$decoded_templates = sek_get_all_api_templates();
|
||||
|
||||
if ( is_array($decoded_templates) ) {
|
||||
wp_send_json_success( $decoded_templates );
|
||||
} else {
|
||||
if ( !empty( $decoded_templates ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => invalid templates returned', $decoded_templates );
|
||||
wp_send_json_error( __FUNCTION__ . ' error => invalid templates returned' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// TEMPLATE GET CONTENT + METAS
|
||||
// Fetches the json of a given user template
|
||||
add_action( 'wp_ajax_sek_get_user_tmpl_json', '\Nimble\sek_ajax_sek_get_user_tmpl_json' );
|
||||
// @hook wp_ajax_sek_get_user_saved_templates
|
||||
function sek_ajax_sek_get_user_tmpl_json() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
// We must have a tmpl_post_name
|
||||
if ( empty( $_POST['tmpl_post_name']) || !is_string( $_POST['tmpl_post_name'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_tmpl_post_name' );
|
||||
}
|
||||
// if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
// wp_send_json_error( __FUNCTION__ . '_missing_skope_id' );
|
||||
// }
|
||||
$tmpl_post = sek_get_saved_tmpl_post( sanitize_text_field($_POST['tmpl_post_name']) );
|
||||
if ( !is_wp_error( $tmpl_post ) && $tmpl_post && is_object( $tmpl_post ) ) {
|
||||
$tmpl_decoded = maybe_unserialize( $tmpl_post->post_content );
|
||||
|
||||
// Structure of $content :
|
||||
// array(
|
||||
// 'data' => $_POST['tmpl_data'],//<= json stringified
|
||||
// 'tmpl_post_name' => ( !empty( $_POST['tmpl_post_name'] ) && is_string( $_POST['tmpl_post_name'] ) ) ? $_POST['tmpl_post_name'] : null,
|
||||
// 'metas' => array(
|
||||
// 'title' => $_POST['tmpl_title'],
|
||||
// 'description' => $_POST['tmpl_description'],
|
||||
// 'skope_id' => $_POST['skope_id'],
|
||||
// 'version' => NIMBLE_VERSION,
|
||||
// // is sent as a string : "__after_header,__before_main_wrapper,loop_start,__before_footer"
|
||||
// 'tmpl_locations' => is_string( $_POST['tmpl_locations'] ) ? explode( ',', $_POST['tmpl_locations'] ) : array(),
|
||||
// 'date' => date("Y-m-d"),
|
||||
// 'theme' => sanitize_title_with_dashes( get_stylesheet() )
|
||||
// )
|
||||
// );
|
||||
if ( is_array( $tmpl_decoded ) && !empty( $tmpl_decoded['data'] ) && is_array( $tmpl_decoded['data'] ) ) {
|
||||
//$tmpl_decoded['data'] = json_decode( wp_unslash( $tmpl_decoded['data'], true ) );
|
||||
$tmpl_decoded['data'] = sek_maybe_import_imgs( $tmpl_decoded['data'], $do_import_images = true );
|
||||
// the image import errors won't block the import
|
||||
// they are used when notifying user in the customizer
|
||||
$tmpl_decoded['img_errors'] = !empty( Nimble_Manager()->img_import_errors ) ? implode(',', Nimble_Manager()->img_import_errors) : array();
|
||||
// Make sure we decode encoded rich text before sending to the customizer
|
||||
// see #544 and #791
|
||||
$tmpl_decoded['data'] = sek_sniff_and_decode_richtext( $tmpl_decoded['data'] );
|
||||
|
||||
// added March 2021 for site templates #478
|
||||
// If property '__inherits_group_skope_tmpl_when_exists__' has been saved by mistake in the template, make sure it's unset now
|
||||
if ( array_key_exists('__inherits_group_skope_tmpl_when_exists__', $tmpl_decoded['data'] ) ) {
|
||||
unset( $tmpl_decoded['data']['__inherits_group_skope_tmpl_when_exists__'] );
|
||||
}
|
||||
wp_send_json_success( $tmpl_decoded );
|
||||
} else {
|
||||
wp_send_json_error( __FUNCTION__ . '_invalid_tmpl_post_data' );
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( __FUNCTION__ . '_tmpl_post_not_found' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
add_action( 'wp_ajax_sek_get_api_tmpl_json', '\Nimble\sek_ajax_sek_get_api_tmpl_json' );
|
||||
// @hook wp_ajax_sek_get_user_saved_templates
|
||||
function sek_ajax_sek_get_api_tmpl_json() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
// We must have a tmpl_post_name
|
||||
if ( empty( $_POST['api_tmpl_name']) || !is_string( $_POST['api_tmpl_name'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_tmpl_post_name' );
|
||||
}
|
||||
$tmpl_name = sanitize_text_field($_POST['api_tmpl_name']);
|
||||
|
||||
// Pro Template case
|
||||
$is_pro_tmpl = array_key_exists('api_tmpl_is_pro', $_POST ) && 'yes' === sanitize_text_field($_POST['api_tmpl_is_pro']);
|
||||
if ( $is_pro_tmpl ) {
|
||||
$pro_key_status = apply_filters( 'nimble_pro_key_status_OK', 'nok' );
|
||||
if ( 'pro_key_status_ok' !== $pro_key_status ) {
|
||||
wp_send_json_error( $pro_key_status );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$raw_tmpl_data = sek_get_single_tmpl_api_data( $tmpl_name, $is_pro_tmpl );// <= returns an unserialized array, in which the template['data'] is NOT a JSON, unlike for user saved templates
|
||||
|
||||
// If the api returned a pro license key problem, bail now and return the api string message
|
||||
if ( $is_pro_tmpl && is_string( $raw_tmpl_data ) && !empty( $raw_tmpl_data ) ) {
|
||||
wp_send_json_error( $raw_tmpl_data );
|
||||
} else if ( !is_array( $raw_tmpl_data) || empty( $raw_tmpl_data ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' problem when getting template : ' . $tmpl_name );
|
||||
wp_send_json_error( __FUNCTION__ . '_invalid_template_'. $tmpl_name );
|
||||
}
|
||||
|
||||
//sek_error_log( __FUNCTION__ . ' api template collection', $raw_tmpl_data );
|
||||
if ( !isset($raw_tmpl_data['data'] ) || empty( $raw_tmpl_data['data'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' problem => missing or invalid data property for template : ' . $tmpl_name, $raw_tmpl_data );
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_data_property_for_template_' . $tmpl_name );
|
||||
} else {
|
||||
// $tmpl_decoded = $raw_tmpl_data;
|
||||
$raw_tmpl_data['data'] = sek_maybe_import_imgs( $raw_tmpl_data['data'], $do_import_images = true );
|
||||
$raw_tmpl_data['img_errors'] = !empty( Nimble_Manager()->img_import_errors ) ? implode(',', Nimble_Manager()->img_import_errors) : array();
|
||||
// Make sure we decode encoded rich text before sending to the customizer
|
||||
// see #544 and #791
|
||||
$raw_tmpl_data['data'] = sek_sniff_and_decode_richtext( $raw_tmpl_data['data'] );
|
||||
|
||||
// added March 2021 for site templates #478
|
||||
// If property '__inherits_group_skope_tmpl_when_exists__' has been saved by mistake in the template, make sure it's unset now
|
||||
if ( array_key_exists('__inherits_group_skope_tmpl_when_exists__', $raw_tmpl_data['data'] ) ) {
|
||||
unset( $raw_tmpl_data['data']['__inherits_group_skope_tmpl_when_exists__'] );
|
||||
}
|
||||
wp_send_json_success( $raw_tmpl_data );
|
||||
}
|
||||
//return [];
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// TEMPLATE SAVE
|
||||
// introduced in april 2020 for https://github.com/presscustomizr/nimble-builder/issues/655
|
||||
add_action( 'wp_ajax_sek_save_user_template', '\Nimble\sek_ajax_save_user_template' );
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// hook : wp_ajax_sek_save_user_template
|
||||
function sek_ajax_save_user_template() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
$is_edit_metas_only_case = isset( $_POST['edit_metas_only'] ) && 'yes' === sanitize_text_field($_POST['edit_metas_only']);
|
||||
|
||||
// TMPL DATA => the nimble content
|
||||
if ( !$is_edit_metas_only_case && empty( $_POST['tmpl_data']) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_template_data' );
|
||||
}
|
||||
if ( !$is_edit_metas_only_case && !is_string( $_POST['tmpl_data'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_template_data_must_be_a_json_stringified' );
|
||||
}
|
||||
|
||||
// TMPL METAS
|
||||
// We must have a title
|
||||
if ( empty( $_POST['tmpl_title']) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_template_title' );
|
||||
}
|
||||
if ( !is_string( $_POST['tmpl_description'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_template_description_must_be_a_string' );
|
||||
}
|
||||
if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_skope_id' );
|
||||
}
|
||||
if ( !isset( $_POST['tmpl_locations'] ) || empty( $_POST['tmpl_locations'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_tmpl_locations' );
|
||||
}
|
||||
|
||||
if ( $is_edit_metas_only_case ) {
|
||||
$tmpl_data = [];
|
||||
} else {
|
||||
// clean level ids and replace them with a placeholder string
|
||||
$tmpl_data = json_decode( wp_unslash( $_POST['tmpl_data'] ), true );
|
||||
$tmpl_data = sek_template_save_clean_id( $tmpl_data );
|
||||
|
||||
// added March 2021 for site templates #478
|
||||
// If property '__inherits_group_skope_tmpl_when_exists__' has been set to the template, make sure it's unset now
|
||||
if ( array_key_exists('__inherits_group_skope_tmpl_when_exists__', $tmpl_data ) ) {
|
||||
unset( $tmpl_data['__inherits_group_skope_tmpl_when_exists__'] );
|
||||
}
|
||||
}
|
||||
|
||||
// make sure description and title are clean before DB
|
||||
$tmpl_title = sek_maybe_encode_richtext( sanitize_text_field($_POST['tmpl_title']) );
|
||||
$tmpl_description = sek_maybe_encode_richtext( sanitize_text_field($_POST['tmpl_description']) );
|
||||
|
||||
// sanitize tmpl_locations
|
||||
$tmpl_locations = [];
|
||||
if ( is_array($_POST['tmpl_locations']) ) {
|
||||
foreach($_POST['tmpl_locations'] as $loc ) {
|
||||
$tmpl_locations[] = sanitize_text_field($loc);
|
||||
}
|
||||
}
|
||||
|
||||
// sek_error_log('json decode ?', json_decode( wp_unslash( $_POST['sek_data'] ), true ) );
|
||||
$template_to_save = array(
|
||||
'data' => $tmpl_data,//<= array
|
||||
'tmpl_post_name' => ( !empty( $_POST['tmpl_post_name'] ) && is_string( $_POST['tmpl_post_name'] ) ) ? sanitize_text_field($_POST['tmpl_post_name']) : null,
|
||||
'metas' => array(
|
||||
'title' => $tmpl_title,
|
||||
'description' => $tmpl_description,
|
||||
'skope_id' => sanitize_text_field($_POST['skope_id']),
|
||||
'version' => NIMBLE_VERSION,
|
||||
// is sent as a string : "__after_header,__before_main_wrapper,loop_start,__before_footer"
|
||||
'tmpl_locations' => $tmpl_locations,
|
||||
'tmpl_header_location' => isset( $_POST['tmpl_header_location'] ) ? sanitize_text_field($_POST['tmpl_header_location']) : '',
|
||||
'tmpl_footer_location' => isset( $_POST['tmpl_footer_location'] ) ? sanitize_text_field($_POST['tmpl_footer_location']) : '',
|
||||
'date' => date("Y-m-d"),
|
||||
'theme' => sanitize_title_with_dashes( get_stylesheet() ),
|
||||
// for api templates
|
||||
'is_pro_tmpl' => false,
|
||||
'thumb_url' => ''
|
||||
)
|
||||
);
|
||||
|
||||
$saved_template_post = sek_update_user_tmpl_post( $template_to_save, $is_edit_metas_only_case );
|
||||
if ( is_wp_error( $saved_template_post ) || is_null($saved_template_post) || empty($saved_template_post) ) {
|
||||
wp_send_json_error( __FUNCTION__ . ' => error when invoking sek_update_user_tmpl_post()' );
|
||||
} else {
|
||||
// sek_error_log( 'ALORS CE POST?', $saved_template_post );
|
||||
wp_send_json_success( [ 'tmpl_post_id' => $saved_template_post->ID ] );
|
||||
}
|
||||
//sek_error_log( __FUNCTION__ . '$_POST' , $_POST);
|
||||
}
|
||||
|
||||
|
||||
// SAVE FILTER
|
||||
function sek_template_save_clean_id( $tmpl_data = array() ) {
|
||||
$new_tmpl_data = array();
|
||||
if ( !is_array( $tmpl_data ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => tmpl_data should be an array');
|
||||
return array();
|
||||
}
|
||||
$level = null;
|
||||
if ( isset($tmpl_data['level'] ) ) {
|
||||
$level = $tmpl_data['level'];
|
||||
}
|
||||
foreach ( $tmpl_data as $key => $value ) {
|
||||
if ( is_array($value) ) {
|
||||
$new_tmpl_data[$key] = sek_template_save_clean_id( $value );
|
||||
} else {
|
||||
switch( $key ) {
|
||||
// we want to replace ids for all levels but locations
|
||||
// only section, columns and modules have an id which starts by __nimble__, for ex : __nimble__2024500518bf
|
||||
// locations id are like : loop_start
|
||||
case 'id' :
|
||||
if ( 'location' !== $level && is_string( $value ) && false !== strpos( $value, '__nimble__' ) ) {
|
||||
$value = '__rep__me__';
|
||||
}
|
||||
break;
|
||||
}
|
||||
$new_tmpl_data[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $new_tmpl_data;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// TEMPLATE REMOVE
|
||||
// introduced in may 2020 for https://github.com/presscustomizr/nimble-builder/issues/655
|
||||
add_action( 'wp_ajax_sek_remove_user_template', '\Nimble\sek_ajax_remove_user_template' );
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// hook : wp_ajax_sek_remove_user_template
|
||||
function sek_ajax_remove_user_template() {
|
||||
//sek_error_log( __FUNCTION__ . ' ALORS YEAH IN REMOVAL ? ?', $_POST );
|
||||
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
// We must have a tmpl_post_name
|
||||
if ( empty( $_POST['tmpl_post_name']) || !is_string( $_POST['tmpl_post_name'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_tmpl_post_name' );
|
||||
}
|
||||
$tmpl_post_name = sanitize_text_field($_POST['tmpl_post_name']);
|
||||
// if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
// wp_send_json_error( __FUNCTION__ . '_missing_skope_id' );
|
||||
// }
|
||||
$tmpl_post_to_remove = sek_get_saved_tmpl_post( $tmpl_post_name );
|
||||
|
||||
//sek_error_log( __FUNCTION__ . ' => so $tmpl_post_to_remove ' . $_POST['tmpl_post_name'], $tmpl_post_to_remove );
|
||||
|
||||
if ( $tmpl_post_to_remove && is_object( $tmpl_post_to_remove ) ) {
|
||||
// the CPT is moved to Trash instead of permanently deleted when using wp_delete_post()
|
||||
$r = wp_trash_post( $tmpl_post_to_remove->ID );
|
||||
if ( is_wp_error( $r ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_removal_error' );
|
||||
}
|
||||
|
||||
// Added April 2021 for stie templates #478
|
||||
do_action('nb_on_remove_saved_tmpl_post', $tmpl_post_name );
|
||||
} else {
|
||||
wp_send_json_error( __FUNCTION__ . '_tmpl_post_not_found' );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $tmpl_post_to_remove ) || is_null($tmpl_post_to_remove) || empty($tmpl_post_to_remove) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_removal_error' );
|
||||
} else {
|
||||
// sek_error_log( 'ALORS CE POST?', $saved_template_post );
|
||||
wp_send_json_success( [ 'tmpl_post_removed' => $tmpl_post_name ] );
|
||||
}
|
||||
//sek_error_log( __FUNCTION__ . '$_POST' , $_POST);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Fetches the user saved sections
|
||||
add_action( 'wp_ajax_sek_get_all_saved_sections', '\Nimble\sek_ajax_get_all_saved_sections' );
|
||||
// @hook wp_ajax_sek_get_user_saved_sections
|
||||
function sek_ajax_get_all_saved_sections() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
$decoded_sections = sek_get_all_saved_sections();
|
||||
|
||||
if ( is_array($decoded_sections) ) {
|
||||
wp_send_json_success( $decoded_sections );
|
||||
} else {
|
||||
if ( !empty( $decoded_sections ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => invalid sections returned', $decoded_sections );
|
||||
wp_send_json_error( __FUNCTION__ . ' error => invalid sections returned' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Fetches the preset_sections
|
||||
add_action( 'wp_ajax_sek_get_single_api_section_data', '\Nimble\sek_ajax_get_single_api_section_data' );
|
||||
////////////////////////////////////////////////////////////////
|
||||
// PRESET SECTIONS
|
||||
// Fired in __construct()
|
||||
// hook : 'wp_ajax_sek_get_preset_sektions'
|
||||
function sek_ajax_get_single_api_section_data() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
// September 2020 => force update every 24 hours so users won't miss a new pre-build section
|
||||
// Note that the refresh should have take place on 'upgrader_process_complete'
|
||||
// always force refresh when developing
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
// We must have a api_section_id
|
||||
if ( empty( $_POST['api_section_id']) || !is_string( $_POST['api_section_id'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_api_section_id' );
|
||||
}
|
||||
$api_section_id = sanitize_text_field($_POST['api_section_id']);
|
||||
|
||||
$is_pro_section_id = sek_is_pro() && is_string($api_section_id) && 'pro_' === substr($api_section_id,0,4);
|
||||
$pro_key_status = apply_filters( 'nimble_pro_key_status_OK', 'nok' );
|
||||
if ( $is_pro_section_id && 'pro_key_status_ok' !== $pro_key_status ) {
|
||||
wp_send_json_error( $pro_key_status );
|
||||
return;
|
||||
}
|
||||
$raw_api_sec_data = sek_api_get_single_section_data( $api_section_id );// <= returns an unserialized array
|
||||
|
||||
// When injecting a pro section, NB checks the validity of the key.
|
||||
// if the api response is not an array, there was a problem when checking the key
|
||||
// and in this case the response is a string like : 'Expired.'
|
||||
if ( $is_pro_section_id && is_string($raw_api_sec_data) && !empty($raw_api_sec_data) ) {
|
||||
wp_send_json_error( $raw_api_sec_data );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !is_array( $raw_api_sec_data) || empty( $raw_api_sec_data ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' problem when getting section : ' . $api_section_id );
|
||||
wp_send_json_error( 'Error : empty or invalid section data : '. $api_section_id );
|
||||
return;
|
||||
}
|
||||
//sek_error_log( __FUNCTION__ . ' api section data', $raw_api_sec_data );
|
||||
if ( !isset($raw_api_sec_data['collection'] ) || empty( $raw_api_sec_data['collection'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' problem => missing or invalid data property for section : ' . $api_section_id, $raw_api_sec_data );
|
||||
wp_send_json_error( 'Error : missing_data_property_for_section : ' . $api_section_id );
|
||||
} else {
|
||||
// $tmpl_decoded = $raw_api_sec_data;
|
||||
$raw_api_sec_data['collection'] = sek_maybe_import_imgs( $raw_api_sec_data['collection'], $do_import_images = true );
|
||||
//$raw_api_sec_data['img_errors'] = !empty( Nimble_Manager()->img_import_errors ) ? implode(',', Nimble_Manager()->img_import_errors) : array();
|
||||
// Make sure we decode encoded rich text before sending to the customizer
|
||||
// see #544 and #791
|
||||
$raw_api_sec_data['collection'] = sek_sniff_and_decode_richtext( $raw_api_sec_data['collection'] );
|
||||
|
||||
wp_send_json_success( $raw_api_sec_data );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// SECTION GET CONTENT + METAS
|
||||
// Fetches the json of a given user section
|
||||
add_action( 'wp_ajax_sek_get_user_section_json', '\Nimble\sek_ajax_sek_get_user_section_json' );
|
||||
// @hook wp_ajax_sek_get_user_saved_sections
|
||||
function sek_ajax_sek_get_user_section_json() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
// We must have a section_post_name
|
||||
if ( empty( $_POST['section_post_name']) || !is_string( $_POST['section_post_name'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_section_post_name' );
|
||||
}
|
||||
// if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
// wp_send_json_error( __FUNCTION__ . '_missing_skope_id' );
|
||||
// }
|
||||
$section_post = sek_get_saved_section_post( sanitize_text_field($_POST['section_post_name']) );
|
||||
if ( !is_wp_error( $section_post ) && $section_post && is_object( $section_post ) ) {
|
||||
$section_decoded = maybe_unserialize( $section_post->post_content );
|
||||
// Structure of $content :
|
||||
// array(
|
||||
// 'data' => $_POST['section_data'],//<= json stringified
|
||||
// 'section_post_name' => ( !empty( $_POST['section_post_name'] ) && is_string( $_POST['section_post_name'] ) ) ? $_POST['section_post_name'] : null,
|
||||
// 'metas' => array(
|
||||
// 'title' => $_POST['section_title'],
|
||||
// 'description' => $_POST['section_description'],
|
||||
// 'skope_id' => $_POST['skope_id'],
|
||||
// 'version' => NIMBLE_VERSION,
|
||||
// // is sent as a string : "__after_header,__before_main_wrapper,loop_start,__before_footer"
|
||||
// 'active_locations' => is_string( $_POST['active_locations'] ) ? explode( ',', $_POST['active_locations'] ) : array(),
|
||||
// 'date' => date("Y-m-d"),
|
||||
// 'theme' => sanitize_title_with_dashes( get_stylesheet() )
|
||||
// )
|
||||
// );
|
||||
if ( is_array( $section_decoded ) && !empty( $section_decoded['data'] ) && is_string( $section_decoded['data'] ) ) {
|
||||
$section_decoded['data'] = json_decode( wp_unslash( $section_decoded['data'], true ) );
|
||||
}
|
||||
// Make sure we decode encoded rich text before sending to the customizer
|
||||
// see #544 and #791
|
||||
$section_decoded['data'] = sek_sniff_and_decode_richtext( $section_decoded['data'] );
|
||||
wp_send_json_success( $section_decoded );
|
||||
} else {
|
||||
wp_send_json_error( __FUNCTION__ . '_section_post_not_found' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// SECTION SAVE
|
||||
// introduced in april 2020 for https://github.com/presscustomizr/nimble-builder/issues/655
|
||||
// ENABLED WHEN CONSTANT NIMBLE_SECTION_SAVE_ENABLED === true
|
||||
add_action( 'wp_ajax_sek_save_user_section', '\Nimble\sek_ajax_save_user_section' );
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// hook : wp_ajax_sek_save_user_section
|
||||
function sek_ajax_save_user_section() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
$is_edit_metas_only_case = isset( $_POST['edit_metas_only'] ) && 'yes' === sanitize_text_field($_POST['edit_metas_only']);
|
||||
// TMPL DATA => the nimble content
|
||||
if ( !$is_edit_metas_only_case && empty( $_POST['section_data']) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_section_data' );
|
||||
}
|
||||
if ( !$is_edit_metas_only_case && !is_string( $_POST['section_data'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_section_data_must_be_a_json_stringified' );
|
||||
}
|
||||
|
||||
// TMPL METAS
|
||||
// We must have a title
|
||||
if ( empty( $_POST['section_title']) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_section_title' );
|
||||
}
|
||||
if ( !is_string( $_POST['section_description'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_section_description_must_be_a_string' );
|
||||
}
|
||||
if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_skope_id' );
|
||||
}
|
||||
// if ( !isset( $_POST['active_locations'] ) || empty( $_POST['active_locations'] ) ) {
|
||||
// wp_send_json_error( __FUNCTION__ . '_missing_active_locations' );
|
||||
// }
|
||||
|
||||
if ( $is_edit_metas_only_case ) {
|
||||
$seks_data = [];
|
||||
} else {
|
||||
// clean level ids and replace them with a placeholder string
|
||||
$seks_data = json_decode( wp_unslash( $_POST['section_data'] ), true );
|
||||
$seks_data = sek_section_save_clean_id( $seks_data );
|
||||
}
|
||||
|
||||
// make sure description and title are clean before DB
|
||||
$sec_title = sek_maybe_encode_richtext( sanitize_text_field($_POST['section_title']) );
|
||||
$sec_description = sek_maybe_encode_richtext( sanitize_text_field($_POST['section_description']) );
|
||||
|
||||
$section_to_save = array(
|
||||
'data' => $seks_data,//<= json stringified
|
||||
// the section post name is provided only when updating
|
||||
'section_post_name' => ( !empty( $_POST['section_post_name'] ) && is_string( $_POST['section_post_name'] ) ) ? sanitize_text_field($_POST['section_post_name']) : null,
|
||||
'metas' => array(
|
||||
'title' => $sec_title,
|
||||
'description' => $sec_description,
|
||||
'skope_id' => sanitize_text_field($_POST['skope_id']),
|
||||
'version' => NIMBLE_VERSION,
|
||||
// is sent as a string : "__after_header,__before_main_wrapper,loop_start,__before_footer"
|
||||
//'active_locations' => is_array( $_POST['active_locations'] ) ? $_POST['active_locations'] : array(),
|
||||
'date' => date("Y-m-d"),
|
||||
'theme' => sanitize_title_with_dashes( get_stylesheet() )
|
||||
)
|
||||
);
|
||||
|
||||
$saved_section_post = sek_update_saved_section_post( $section_to_save, $is_edit_metas_only_case );
|
||||
if ( is_wp_error( $saved_section_post ) || is_null($saved_section_post) || empty($saved_section_post) ) {
|
||||
wp_send_json_error( __FUNCTION__ . ' => error when invoking sek_update_saved_section_post()' );
|
||||
} else {
|
||||
wp_send_json_success( [ 'section_post_id' => $saved_section_post->ID ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SAVE FILTER
|
||||
function sek_section_save_clean_id( $seks_data = array() ) {
|
||||
$new_seks_data = array();
|
||||
if ( !is_array( $seks_data ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => seks_data should be an array');
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ( $seks_data as $key => $value ) {
|
||||
if ( is_array($value) ) {
|
||||
$new_seks_data[$key] = sek_section_save_clean_id( $value );
|
||||
} else {
|
||||
switch( $key ) {
|
||||
case 'id' :
|
||||
if ( is_string( $value ) && false !== strpos( $value, '__nimble__' ) ) {
|
||||
$value = '__rep__me__';
|
||||
}
|
||||
break;
|
||||
}
|
||||
$new_seks_data[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $new_seks_data;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// SECTION REMOVE
|
||||
// introduced in may 2020 for https://github.com/presscustomizr/nimble-builder/issues/655
|
||||
// ENABLED WHEN CONSTANT NIMBLE_SECTION_SAVE_ENABLED === true
|
||||
add_action( 'wp_ajax_sek_remove_user_section', '\Nimble\sek_ajax_remove_user_section' );
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// hook : wp_ajax_sek_remove_user_section
|
||||
function sek_ajax_remove_user_section() {
|
||||
sek_do_ajax_pre_checks( array( 'check_nonce' => true ) );
|
||||
|
||||
// We must have a section_post_name
|
||||
if ( empty( $_POST['section_post_name']) || !is_string( $_POST['section_post_name'] ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_missing_section_post_name' );
|
||||
}
|
||||
// if ( !isset( $_POST['skope_id'] ) || empty( $_POST['skope_id'] ) ) {
|
||||
// wp_send_json_error( __FUNCTION__ . '_missing_skope_id' );
|
||||
// }
|
||||
$section_post_to_remove = sek_get_saved_section_post( sanitize_text_field($_POST['section_post_name']) );
|
||||
|
||||
if ( $section_post_to_remove && is_object( $section_post_to_remove ) ) {
|
||||
// the CPT is moved to Trash instead of permanently deleted when using wp_delete_post()
|
||||
$r = wp_trash_post( $section_post_to_remove->ID );
|
||||
if ( is_wp_error( $r ) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_removal_error' );
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( __FUNCTION__ . '_section_post_not_found' );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $section_post_to_remove ) || is_null($section_post_to_remove) || empty($section_post_to_remove) ) {
|
||||
wp_send_json_error( __FUNCTION__ . '_removal_error' );
|
||||
} else {
|
||||
wp_send_json_success( [ 'section_post_removed' => sanitize_text_field($_POST['section_post_name']) ] );
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
// WP 5.0.0 compat. until the bug is fixed
|
||||
// this hook fires before the customize changeset is inserter / updated in database
|
||||
// Removing the wp_targeted_link_rel callback from the 'content_save_pre' filter prevents corrupting the changeset JSON
|
||||
// more details in this ticket : https://core.trac.wordpress.org/ticket/45292
|
||||
add_action( 'customize_save_validation_before', '\Nimble\sek_remove_callback_wp_targeted_link_rel' );
|
||||
function sek_remove_callback_wp_targeted_link_rel( $wp_customize ) {
|
||||
if ( false !== has_filter( 'content_save_pre', 'wp_targeted_link_rel' ) ) {
|
||||
remove_filter( 'content_save_pre', 'wp_targeted_link_rel' );
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,442 @@
|
||||
<?php
|
||||
////////////////////////////////////////////////////////////////
|
||||
// SEK Front Class
|
||||
if ( !class_exists( 'SEK_Front_Construct' ) ) :
|
||||
class SEK_Front_Construct {
|
||||
static $instance;
|
||||
public $seks_posts = [];// <= march 2020 : used to cache the current local and global sektion posts
|
||||
public $model = array();//<= when rendering, the current level model
|
||||
public $parent_model = array();//<= when rendering, the current parent model
|
||||
public $default_models = array();// <= will be populated to cache the default models when invoking sek_get_default_module_model
|
||||
public $cached_input_lists = array(); // <= will be populated to cache the input_list of each registered module. Useful when we need to get info like css_selector for a particular input type or id.
|
||||
public $ajax_action_map = array();
|
||||
public $default_locations = [
|
||||
'loop_start' => array( 'priority' => 10 ),
|
||||
'before_content' => array(),
|
||||
'after_content' => array(),
|
||||
'loop_end' => array( 'priority' => 10 ),
|
||||
];
|
||||
public $registered_locations = [];
|
||||
// the model used to register a location
|
||||
public $default_registered_location_model = [
|
||||
'priority' => 10,
|
||||
'is_global_location' => false,
|
||||
'is_header_location' => false,
|
||||
'is_footer_location' => false
|
||||
];
|
||||
// the model used when saving a location in db
|
||||
public $default_location_model = [
|
||||
'id' => '',
|
||||
'level' => 'location',
|
||||
'collection' => [],
|
||||
'options' => [],
|
||||
'ver_ini' => NIMBLE_VERSION
|
||||
];
|
||||
public $rendered_levels = [];//<= stores the ids of the level rendered with ::render()
|
||||
|
||||
public static function get_instance( $params ) {
|
||||
if ( !isset( self::$instance ) && !( self::$instance instanceof Sek_Nimble_Manager ) ) {
|
||||
self::$instance = new Sek_Nimble_Manager( $params );
|
||||
|
||||
// this hook is used to add_action( 'nimble_front_classes_ready', array( $this, 'sek_register_nimble_global_locations') );
|
||||
do_action( 'nimble_front_classes_ready', self::$instance );
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
// store the local and global options
|
||||
public $local_options = '_not_cached_yet_';
|
||||
public $local_options_without_tmpl_inheritance = '_not_cached_yet_';//Introduced for site templates, when using function sek_is_inheritance_locally_disabled()
|
||||
public $global_nimble_options = '_not_cached_yet_';
|
||||
|
||||
public $img_smartload_enabled = 'not_cached';
|
||||
public $video_bg_lazyload_enabled = 'not_cached';//<= for https://github.com/presscustomizr/nimble-builder/issues/287
|
||||
|
||||
public $has_local_header_footer = '_not_cached_yet_';//used in sek_maybe_set_local_nimble_header() and sek_maybe_set_local_nimble_footer()
|
||||
public $has_global_header_footer = '_not_cached_yet_';//used in sek_maybe_set_local_nimble_header() and sek_maybe_set_local_nimble_footer()
|
||||
|
||||
public $recaptcha_enabled = '_not_cached_yet_';//enabled in the global options
|
||||
public $recaptcha_badge_displayed = '_not_cached_yet_';//enabled in the global options
|
||||
|
||||
// option key as saved in db => module_type
|
||||
// is used in _1_6_5_sektions_generate_UI_global_options.js and when normalizing the global option in sek_normalize_global_options_with_defaults()
|
||||
public static $global_options_map = [
|
||||
'global_header_footer' => 'sek_global_header_footer',
|
||||
'global_text' => 'sek_global_text',
|
||||
'site_templates' => 'sek_site_tmpl_pickers',
|
||||
'widths' => 'sek_global_widths',
|
||||
'breakpoint' => 'sek_global_breakpoint',
|
||||
'performances' => 'sek_global_performances',
|
||||
'recaptcha' => 'sek_global_recaptcha',
|
||||
'global_revisions' => 'sek_global_revisions',
|
||||
'global_reset' => 'sek_global_reset',
|
||||
'global_imp_exp' => 'sek_global_imp_exp',
|
||||
'beta_features' => 'sek_global_beta_features'// may 2021 not rendered anymore in ::controls customizer
|
||||
];
|
||||
// option key as saved in db => module_type
|
||||
// is used in _1_6_4_sektions_generate_UI_local_skope_options.js and when normalizing the global option in sek_normalize_local_options_with_defaults()
|
||||
public static $local_options_map = [
|
||||
'template' => 'sek_local_template',
|
||||
'local_header_footer' => 'sek_local_header_footer',
|
||||
'widths' => 'sek_local_widths',
|
||||
'custom_css' => 'sek_local_custom_css',
|
||||
'local_performances' => 'sek_local_performances',
|
||||
'local_reset' => 'sek_local_reset',
|
||||
'import_export' => 'sek_local_imp_exp',
|
||||
'local_revisions' => 'sek_local_revisions'
|
||||
];
|
||||
|
||||
// introduced when implementing import/export feature
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/411
|
||||
public $img_import_errors = [];
|
||||
|
||||
// stores the active module collection
|
||||
// @see populated in sek_populate_collection_of_contextually_active_modules()
|
||||
// list of modules displayed on local + global sektions for a givent page.
|
||||
// populated 'wp'@PHP_INT_MAX and used to
|
||||
// 1) determine which module should be registered when not customizing or ajaxing. See sek_register_modules_when_not_customizing_and_not_ajaxing()
|
||||
// 2) determine which assets ( css / js ) is needed for this context. see ::sek_enqueue_front_assets
|
||||
//
|
||||
// updated for https://github.com/presscustomizr/nimble-builder/issues/612
|
||||
public $contextually_active_modules = 'not_set';
|
||||
|
||||
public static $ui_picker_modules = [
|
||||
// UI CONTENT PICKER
|
||||
'sek_content_type_switcher_module',
|
||||
'sek_module_picker_module'
|
||||
];
|
||||
|
||||
// JUNE 2020
|
||||
// PREBUILT AND USER SECTION MODULES ARE REGISTERED IN add_action( 'after_setup_theme', '\Nimble\sek_schedule_module_registration', 50 );
|
||||
// with sek_register_prebuilt_section_modules(); and sek_register_user_sections_module();
|
||||
|
||||
public static $ui_level_modules = [
|
||||
// UI LEVEL MODULES
|
||||
'sek_mod_option_switcher_module',
|
||||
'sek_level_bg_module',
|
||||
'sek_level_text_module',
|
||||
'sek_level_border_module',
|
||||
//'sek_level_section_layout_module',<// deactivated for now. Replaced by sek_level_width_section
|
||||
'sek_level_height_module',
|
||||
'sek_level_spacing_module',
|
||||
'sek_level_spacing_module_for_columns',
|
||||
'sek_level_width_module',
|
||||
'sek_level_width_column',
|
||||
'sek_level_width_section',
|
||||
'sek_level_anchor_module',
|
||||
'sek_level_visibility_module',
|
||||
'sek_level_breakpoint_module'
|
||||
];
|
||||
|
||||
public static $ui_local_global_options_modules = [
|
||||
// local skope options modules
|
||||
'sek_local_template',
|
||||
'sek_local_widths',
|
||||
'sek_local_custom_css',
|
||||
'sek_local_reset',
|
||||
'sek_local_performances',
|
||||
'sek_local_header_footer',
|
||||
'sek_local_revisions',
|
||||
'sek_local_imp_exp',
|
||||
|
||||
// global options modules
|
||||
'sek_global_text',
|
||||
'sek_global_widths',
|
||||
'sek_global_breakpoint',
|
||||
'sek_global_header_footer',
|
||||
'sek_global_performances',
|
||||
'sek_global_recaptcha',
|
||||
'sek_global_revisions',
|
||||
'sek_global_reset',
|
||||
'sek_global_imp_exp',
|
||||
'sek_global_beta_features',
|
||||
|
||||
// site template options module
|
||||
'sek_site_tmpl_pickers'
|
||||
];
|
||||
|
||||
// Is merged with front module when sek_is_header_footer_enabled() === true
|
||||
// @see sek_register_modules_when_customizing_or_ajaxing
|
||||
// and sek_register_modules_when_not_customizing_and_not_ajaxing
|
||||
public static $ui_front_beta_modules = [];
|
||||
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/456
|
||||
public $global_sections_rendered = false;
|
||||
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/494
|
||||
// september 2019
|
||||
// this guid is used to differentiate dynamically rendered content from static content that may include a Nimble generated HTML structure
|
||||
// an attribute "data-sek-preview-level-guid" is added to each rendered level when customizing or ajaxing
|
||||
// @see ::render() method
|
||||
// otherwise the preview UI can be broken
|
||||
public $preview_level_guid = '_preview_level_guid_not_set_';
|
||||
|
||||
// March 2020 : introduction of individual stylesheet for some modules
|
||||
// October 2020 : implementation of dynamic stylesheet concatenation when generating stylesheets
|
||||
public $big_module_stylesheet_map = [
|
||||
'czr_quote_module' => 'quote-module',
|
||||
'czr_icon_module' => 'icon-module',
|
||||
'czr_img_slider_module' => 'img-slider-module',
|
||||
'czr_accordion_module' => 'accordion-module',
|
||||
'czr_menu_module' => 'menu-module',
|
||||
'czr_post_grid_module' => 'post-grid-module',
|
||||
'czr_simple_form_module' => 'simple-form-module',
|
||||
'czr_image_module' => 'image-module',
|
||||
|
||||
'czr_special_img_module' => 'special-image-module',
|
||||
'czr_advanced_list_module' => 'advanced-list-module',
|
||||
|
||||
'czr_social_icons_module' => 'social-icons-module',
|
||||
'czr_button_module' => 'button-module',
|
||||
'czr_heading_module' => 'heading-module',
|
||||
'czr_gallery_module' => 'gallery-module',
|
||||
];
|
||||
|
||||
// March 2020, for https://github.com/presscustomizr/nimble-builder/issues/629
|
||||
public $google_fonts_print_candidates = 'not_set';// will cache the google font candidates to print in ::_setup_hook_for_front_css_printing_or_enqueuing()
|
||||
|
||||
public $css_loader_html = '<div class="sek-css-loader sek-mr-loader"><div></div><div></div><div></div></div>';
|
||||
|
||||
// March 2020, for https://github.com/presscustomizr/nimble-builder/issues/649
|
||||
public $nimble_customizing_or_content_is_printed_on_this_page = false;//<= tells if any Nimble Content has been printed.
|
||||
// October 2020
|
||||
public $page_has_local_or_global_sections = 'not_set';//<= set @wp_enqueue_script, used to determine if we should load css, js and fonts assets or not.
|
||||
// feb 2021, introduced for #478
|
||||
public $page_has_local_sections = 'not_set';
|
||||
public $page_has_global_sections = 'not_set';
|
||||
|
||||
// April 2020 for https://github.com/presscustomizr/nimble-builder/issues/679
|
||||
public $is_content_restricted = false; //<= set at 'wp'
|
||||
|
||||
// May 2020
|
||||
// those location properties are set when walking Nimble content on rendering
|
||||
// @see #705 prevent lazyloading images when in header section.
|
||||
public $current_location_is_header = false;
|
||||
public $current_location_is_footer = false;
|
||||
|
||||
// September 2020 for https://github.com/presscustomizr/nimble-builder-pro/issues/67
|
||||
public $local_levels_custom_css = '';
|
||||
public $global_levels_custom_css = '';
|
||||
|
||||
// October 2020
|
||||
public $rendering = false;//<= set to true when rendering NB content
|
||||
|
||||
// October 2020
|
||||
public $emitted_js_event = [];//<= collection of unique js event emitted with a script like nb_.emit('nb-needs-parallax')
|
||||
|
||||
// October 2020, for https://github.com/presscustomizr/nimble-builder/issues/751
|
||||
public $partial_front_scripts = [
|
||||
'slider-module' => 'nb-needs-swiper',
|
||||
'menu-module' => 'nb-needs-menu-js',
|
||||
'front-parallax' => 'nb-needs-parallax',
|
||||
'accordion-module' => 'nb-needs-accordion'
|
||||
];
|
||||
|
||||
// janv 2021 => will populate the modules stylesheets already concatenated, so that NB doesn't concatenate a module stylesheet twice for the local css and for the global css (if any)
|
||||
// see in inc\sektions\_front_dev_php\dyn_css_builder_and_google_fonts_printer\5_0_1_class-sek-dyn-css-builder.php
|
||||
public $concatenated_module_stylesheets = [];
|
||||
|
||||
// April 2021 => added some properties when implementing late escape for attributes
|
||||
// @see ::render() and base-tmpl PHP files
|
||||
public $level_css_classes;
|
||||
public $level_custom_anchor;
|
||||
public $level_custom_attr;
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// <CONSTRUCTOR>
|
||||
function __construct( $params = array() ) {
|
||||
if ( did_action('nimble_manager_ready') )
|
||||
return;
|
||||
// INITIALIZE THE REGISTERED LOCATIONS WITH THE DEFAULT LOCATIONS
|
||||
$this->registered_locations = $this->default_locations;
|
||||
|
||||
// AJAX
|
||||
$this->_schedule_front_ajax_actions();
|
||||
|
||||
// FRONT ASSETS
|
||||
$this->_schedule_front_assets_printing();
|
||||
// CUSTOOMIZER PREVIEW ASSETS
|
||||
$this->_schedule_preview_assets_printing();
|
||||
// RENDERING
|
||||
$this->_schedule_front_rendering();
|
||||
// RENDERING
|
||||
$this->_setup_hook_for_front_css_printing_or_enqueuing();
|
||||
// LOADS SIMPLE FORM
|
||||
$this->_setup_simple_forms();
|
||||
// REGISTER NIMBLE WIDGET ZONES
|
||||
add_action( 'widgets_init', array( $this, 'sek_nimble_widgets_init' ) );
|
||||
do_action('nimble_manager_ready');
|
||||
|
||||
// MAYBE REGISTER PRO UPSELL MODUlES
|
||||
add_filter('nb_level_module_collection', function( $module_collection ) {
|
||||
if ( is_array($module_collection) && ( sek_is_pro() || sek_is_upsell_enabled() ) ) {
|
||||
array_push($module_collection, 'sek_level_cust_css_level' );
|
||||
array_push($module_collection, 'sek_level_animation_module' );
|
||||
}
|
||||
return $module_collection;
|
||||
});
|
||||
|
||||
// see #838
|
||||
// prevents using persistent cache object systems like Memcached which override the default WP class WP_Object_Cache () which is normally refreshed on each page load )
|
||||
add_action('init', array( $this, 'sek_clear_cached_objects_when_customizing') );
|
||||
|
||||
// FLUSH CACHE OBJECT ON POST SAVE / UPDATE
|
||||
// for https://github.com/presscustomizr/nimble-builder/issues/867
|
||||
add_action( 'save_post', array( $this, 'sek_flush_object_cache_on_post_update') );
|
||||
}//__construct
|
||||
|
||||
// @init
|
||||
public function sek_clear_cached_objects_when_customizing() {
|
||||
if ( skp_is_customizing() ) {
|
||||
// Make sure cached objects are cleaned
|
||||
wp_cache_flush();
|
||||
}
|
||||
}
|
||||
// @save_post
|
||||
function sek_flush_object_cache_on_post_update() {
|
||||
wp_cache_flush();
|
||||
}
|
||||
|
||||
// @fired @hook 'widgets_init'
|
||||
// Creates 10 widget zones
|
||||
public function sek_nimble_widgets_init() {
|
||||
if ( sek_is_widget_module_disabled() )
|
||||
return;
|
||||
|
||||
$number_of_widgets = apply_filters( 'nimble_number_of_wp_widgets', 10 );
|
||||
|
||||
// Header/footer, widgets module, menu module have been beta tested during 5 months and released in June 2019, in version 1.8.0
|
||||
$defaults = array(
|
||||
'name' => '',
|
||||
'id' => '',
|
||||
'description' => '',
|
||||
'class' => '',
|
||||
'before_widget' => '<aside id="%1$s" class="widget %2$s">',
|
||||
'after_widget' => '</aside>',
|
||||
'before_title' => '<h2 class="widget-title">',
|
||||
'after_title' => '</h2>',
|
||||
);
|
||||
for ( $i=1; $i < ( intval( $number_of_widgets) + 1 ); $i++ ) {
|
||||
$args['id'] = NIMBLE_WIDGET_PREFIX . $i;//'nimble-widget-area-'
|
||||
$args['name'] = sprintf( __('Nimble widget area #%1$s', 'text_domain_to_replace' ), $i );
|
||||
$args['description'] = $args['name'];
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
register_sidebar( $args );
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked @'after_setup_theme'
|
||||
static function sek_get_front_module_collection() {
|
||||
$front_module_collection = [
|
||||
// FRONT MODULES
|
||||
'czr_simple_html_module',
|
||||
|
||||
'czr_tiny_mce_editor_module' => array(
|
||||
'czr_tiny_mce_editor_module',
|
||||
'czr_tinymce_child',
|
||||
'czr_font_child'
|
||||
),
|
||||
|
||||
'czr_image_module' => array(
|
||||
'czr_image_module',
|
||||
'czr_image_main_settings_child',
|
||||
'czr_image_borders_corners_child'
|
||||
),
|
||||
|
||||
'czr_heading_module' => array(
|
||||
'czr_heading_module',
|
||||
'czr_heading_child',
|
||||
'czr_heading_spacing_child',
|
||||
'czr_font_child'
|
||||
),
|
||||
|
||||
'czr_spacer_module',
|
||||
'czr_divider_module',
|
||||
|
||||
'czr_icon_module' => array(
|
||||
'czr_icon_module',
|
||||
'czr_icon_settings_child',
|
||||
'czr_icon_spacing_border_child',
|
||||
),
|
||||
|
||||
|
||||
'czr_map_module',
|
||||
|
||||
'czr_quote_module' => array(
|
||||
'czr_quote_module',
|
||||
'czr_quote_quote_child',
|
||||
'czr_quote_cite_child',
|
||||
'czr_quote_design_child',
|
||||
),
|
||||
|
||||
'czr_button_module' => array(
|
||||
'czr_button_module',
|
||||
'czr_btn_content_child',
|
||||
'czr_btn_design_child',
|
||||
'czr_font_child'
|
||||
),
|
||||
|
||||
// simple form father + children
|
||||
'czr_simple_form_module' => array(
|
||||
'czr_simple_form_module',
|
||||
'czr_simple_form_fields_child',
|
||||
'czr_simple_form_button_child',
|
||||
'czr_simple_form_design_child',
|
||||
'czr_simple_form_fonts_child',
|
||||
'czr_simple_form_submission_child'
|
||||
),
|
||||
|
||||
'czr_post_grid_module' => array(
|
||||
'czr_post_grid_module',
|
||||
'czr_post_grid_main_child',
|
||||
'czr_post_grid_thumb_child',
|
||||
'czr_post_grid_metas_child',
|
||||
'czr_post_grid_fonts_child'
|
||||
),
|
||||
|
||||
// widgets module, menu module have been beta tested during 5 months and released in June 2019, in version 1.8.0
|
||||
'czr_menu_module' => array(
|
||||
'czr_menu_module',
|
||||
'czr_menu_content_child',
|
||||
'czr_menu_mobile_options',
|
||||
'czr_font_child'
|
||||
),
|
||||
//'czr_menu_design_child',
|
||||
|
||||
'czr_social_icons_module' => array(
|
||||
'czr_social_icons_module',
|
||||
'czr_social_icons_settings_child',
|
||||
'czr_social_icons_style_child'
|
||||
),
|
||||
|
||||
'czr_img_slider_module' => array(
|
||||
'czr_img_slider_module',
|
||||
'czr_img_slider_collection_child',
|
||||
'czr_img_slider_opts_child'
|
||||
),
|
||||
|
||||
'czr_accordion_module' => array(
|
||||
'czr_accordion_module',
|
||||
'czr_accordion_collection_child',
|
||||
'czr_accordion_opts_child'
|
||||
),
|
||||
|
||||
'czr_gallery_module' => array(
|
||||
'czr_gallery_module',
|
||||
'czr_gallery_collection_child',
|
||||
'czr_gallery_opts_child'
|
||||
),
|
||||
|
||||
'czr_shortcode_module',
|
||||
];
|
||||
|
||||
if ( !sek_is_widget_module_disabled() ) {
|
||||
$front_module_collection[] = 'czr_widget_area_module';
|
||||
}
|
||||
|
||||
return apply_filters( 'sek_get_front_module_collection', $front_module_collection );
|
||||
}
|
||||
|
||||
}//class
|
||||
endif;
|
||||
?>
|
||||
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
if ( !class_exists( 'SEK_Front_Ajax' ) ) :
|
||||
class SEK_Front_Ajax extends SEK_Front_Construct {
|
||||
// Fired in __construct()
|
||||
function _schedule_front_ajax_actions() {
|
||||
add_action( 'wp_ajax_sek_get_content', array( $this, 'sek_get_level_content_for_injection' ) );
|
||||
|
||||
// Returns the customize url for the edit button when using Gutenberg editor
|
||||
// implemented for https://github.com/presscustomizr/nimble-builder/issues/449
|
||||
// @see assets/admin/js/nimble-gutenberg.js
|
||||
add_action( 'wp_ajax_sek_get_customize_url_for_nimble_edit_button', array( $this, 'sek_get_customize_url_for_nimble_edit_button' ) );
|
||||
|
||||
// This is the list of accepted actions
|
||||
$this->ajax_action_map = array(
|
||||
'sek-add-section',
|
||||
'sek-remove-section',
|
||||
'sek-duplicate-section',
|
||||
|
||||
// fired when dropping a module or a preset_section
|
||||
'sek-add-content-in-new-nested-sektion',
|
||||
'sek-add-content-in-new-sektion',
|
||||
|
||||
// add, duplicate, remove column is a re-rendering of the parent sektion collection
|
||||
'sek-add-column',
|
||||
'sek-remove-column',
|
||||
'sek-duplicate-column',
|
||||
'sek-resize-columns',
|
||||
'sek-refresh-columns-in-sektion',
|
||||
|
||||
'sek-add-module',
|
||||
'sek-remove-module',
|
||||
'sek-duplicate-module',
|
||||
'sek-refresh-modules-in-column',
|
||||
|
||||
'sek-refresh-stylesheet',
|
||||
|
||||
'sek-refresh-level'
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// GENERIC HELPER FIRED IN ALL AJAX CALLBACKS
|
||||
// @param $params = array('check_nonce' => true )
|
||||
function sek_do_ajax_pre_checks( $params = array() ) {
|
||||
$params = wp_parse_args( $params, array( 'check_nonce' => true ) );
|
||||
if ( $params['check_nonce'] ) {
|
||||
$action = 'save-customize_' . get_stylesheet();
|
||||
if ( !check_ajax_referer( $action, 'nonce', false ) ) {
|
||||
wp_send_json_error( array(
|
||||
'code' => 'invalid_nonce',
|
||||
'message' => __( __CLASS__ . '::' . __FUNCTION__ . ' => check_ajax_referer() failed.' ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !is_user_logged_in() ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => unauthenticated' );
|
||||
}
|
||||
if ( !current_user_can( 'customize' ) ) {
|
||||
status_header( 403 );
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => customize_not_allowed' );
|
||||
} else if ( !isset( $_SERVER['REQUEST_METHOD'] ) || 'POST' !== $_SERVER['REQUEST_METHOD'] ) {
|
||||
status_header( 405 );
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => bad_method' );
|
||||
}
|
||||
}//sek_do_ajax_pre_checks()
|
||||
|
||||
|
||||
|
||||
// hook : 'wp_ajax_sek_get_html_for_injection'
|
||||
function sek_get_level_content_for_injection( $params ) {
|
||||
$this->sek_do_ajax_pre_checks( array( 'check_nonce' => false ) );
|
||||
|
||||
if ( !isset( $_POST['location_skope_id'] ) || empty( $_POST['location_skope_id'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => missing skope_id' );
|
||||
}
|
||||
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/494
|
||||
// september 2019
|
||||
// this guid is used to differentiate dynamically rendered content from static content that may include a Nimble generated HTML structure
|
||||
// an attribute "data-sek-preview-level-guid" is added to each rendered level when customizing or ajaxing
|
||||
// otherwise the preview UI can be broken
|
||||
if ( !isset( $_POST['preview-level-guid'] ) || empty( $_POST['preview-level-guid'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => missing preview-level-guid' );
|
||||
}
|
||||
|
||||
if ( !isset( $_POST['sek_action'] ) || empty( $_POST['sek_action'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => missing sek_action' );
|
||||
}
|
||||
$sek_action = sanitize_text_field($_POST['sek_action']);
|
||||
|
||||
$exported_setting_validities = array();
|
||||
|
||||
// CHECK THE SETTING VALIDITIES BEFORE RENDERING
|
||||
// When a module has been registered with a sanitize_callback, we can collect the possible problems here before sending the response.
|
||||
// Then, on ajax.done(), in SekPreviewPrototype::schedulePanelMsgReactions, we will send the setting validities object to the panel
|
||||
if ( is_customize_preview() ) {
|
||||
global $wp_customize;
|
||||
// prepare the setting validities so we can pass them when sending the ajax response
|
||||
$setting_validities = $wp_customize->validate_setting_values( $wp_customize->unsanitized_post_values() );
|
||||
$raw_exported_setting_validities = array_map( array( $wp_customize, 'prepare_setting_validity_for_js' ), $setting_validities );
|
||||
|
||||
// filter the setting validity to only keep the __nimble__ prefixed ui settings
|
||||
$exported_setting_validities = array();
|
||||
foreach( $raw_exported_setting_validities as $setting_id => $validity ) {
|
||||
// don't consider the not Nimble UI settings, not starting with __nimble__
|
||||
if ( false === strpos( $setting_id , NIMBLE_PREFIX_FOR_SETTING_NOT_SAVED ) )
|
||||
continue;
|
||||
$exported_setting_validities[ $setting_id ] = $validity;
|
||||
}
|
||||
}
|
||||
|
||||
$html = '';
|
||||
// is this action possible ?
|
||||
if ( in_array( $sek_action, $this->ajax_action_map ) ) {
|
||||
$content_type = null;
|
||||
if ( array_key_exists( 'content_type', $_POST ) && is_string( $_POST['content_type'] ) ) {
|
||||
$content_type = sanitize_text_field($_POST['content_type']);
|
||||
}
|
||||
|
||||
// This 'preset_section' === $content_type statement has been introduced when implementing support for multi-section pre-build sections
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/489
|
||||
if ( 'preset_section' === $content_type ) {
|
||||
switch ( $sek_action ) {
|
||||
// when 'sek-add-content-in-new-sektion' is fired, the section has already been populated with a column and a module
|
||||
case 'sek-add-content-in-new-sektion' :
|
||||
case 'sek-add-content-in-new-nested-sektion' :
|
||||
if ( 'preset_section' === $content_type ) {
|
||||
if ( !array_key_exists( 'collection_of_preset_section_id', $_POST ) || !is_array( $_POST['collection_of_preset_section_id'] ) || empty( $_POST['collection_of_preset_section_id'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => missing param collection_of_preset_section_id when injecting a preset section' );
|
||||
break;
|
||||
}
|
||||
foreach ( $_POST['collection_of_preset_section_id'] as $preset_section_id ) {
|
||||
$html .= $this->sek_ajax_fetch_content( $sek_action, sanitize_text_field($preset_section_id ));
|
||||
}
|
||||
// 'module' === $content_type
|
||||
} else {
|
||||
$html = $this->sek_ajax_fetch_content( $sek_action );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
$html = $this->sek_ajax_fetch_content( $sek_action );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$html = $this->sek_ajax_fetch_content( $sek_action );
|
||||
}
|
||||
|
||||
//sek_error_log(__CLASS__ . '::' . __FUNCTION__ , $html );
|
||||
if ( is_wp_error( $html ) ) {
|
||||
wp_send_json_error( $html );
|
||||
} else {
|
||||
$response = array(
|
||||
'contents' => $html,
|
||||
'setting_validities' => $exported_setting_validities
|
||||
);
|
||||
wp_send_json_success( apply_filters( 'sek_content_results', $response, $sek_action ) );
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => this ajax action ( ' . $sek_action . ' ) is not listed in the map ' );
|
||||
}
|
||||
|
||||
|
||||
}//sek_get_content_for_injection()
|
||||
|
||||
|
||||
// hook : add_filter( "sek_set_ajax_content___{$action}", array( $this, 'sek_ajax_fetch_content' ) );
|
||||
// $_POST looks like Array
|
||||
// (
|
||||
// [action] => sek_get_content
|
||||
// [withNonce] => false
|
||||
// [id] => __nimble__0b7c85561448ab4eb8adb978
|
||||
// [skope_id] => skp__post_page_home
|
||||
// [sek_action] => sek-add-section
|
||||
// [SEKFrontNonce] => 3713b8ac5c
|
||||
// [customized] => {\"nimble___loop_start[skp__post_page_home]\":{...}}
|
||||
// )
|
||||
// @return string
|
||||
// @param $sek_action is $_POST['sek_action']
|
||||
// @param $maybe_preset_section_id is used when injecting a collection of preset sections
|
||||
private function sek_ajax_fetch_content( $sek_action = '', $maybe_preset_section_id = '' ) {
|
||||
//sek_error_log( __CLASS__ . '::' . __FUNCTION__ . ' POST ?', $_POST );
|
||||
// Important Notes :
|
||||
// 1) at this stage => the $_POST['customized'] has already been updated
|
||||
// so invoking sek_get_skoped_seks() will ensure that we get the latest data
|
||||
// How $_POST['customized'] is getting populated without a full refresh of the preview ?
|
||||
// a) Each time the main collection setting id is updated ( @see CZRSeksPrototype::mayBeUpdateSektionsSetting() ), api.Setting.prototype.preview sends a 'setting' event to the preview
|
||||
// ( note that api.Setting.prototype.preview is overriden by NB to send other events )
|
||||
// b) when the core customize-preview receives the event, it updates the customized dirties
|
||||
// c) then when ajaxing, the $_POST['customized'] param is added by WP core with $.ajaxPrefilter() in customize-preview.js
|
||||
//
|
||||
// 2) since 'wp' hook has not been fired yet, we need to use the posted skope_id param.
|
||||
$sektionSettingValue = sek_get_skoped_seks( sanitize_text_field($_POST['location_skope_id']) );
|
||||
if ( !is_array( $sektionSettingValue ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => invalid sektionSettingValue => it should be an array().' );
|
||||
return;
|
||||
}
|
||||
if ( empty( $sek_action ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => invalid sek_action param' );
|
||||
return;
|
||||
}
|
||||
$sektion_collection = array_key_exists('collection', $sektionSettingValue) ? $sektionSettingValue['collection'] : array();
|
||||
if ( !is_array( $sektion_collection ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => invalid sektion_collection => it should be an array().' );
|
||||
return;
|
||||
}
|
||||
|
||||
$candidate_id = '';
|
||||
$collection = array();
|
||||
$level_model = array();
|
||||
|
||||
$is_stylesheet = false;
|
||||
|
||||
switch ( $sek_action ) {
|
||||
case 'sek-add-section' :
|
||||
case 'sek-duplicate-section' :
|
||||
if ( array_key_exists( 'is_nested', $_POST ) && true === json_decode( sanitize_text_field($_POST['is_nested']) ) ) {
|
||||
// we need to set the parent_mode here to access it later in the ::render method to calculate the column width.
|
||||
$this->parent_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_sektion' ]), $sektion_collection );
|
||||
$level_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_column' ]), $sektion_collection );
|
||||
} else {
|
||||
//$level_model = sek_get_level_model( $_POST[ 'id' ], $sektion_collection );
|
||||
$level_model = sek_get_level_model( sanitize_text_field($_POST[ 'id' ]), $sektion_collection );
|
||||
}
|
||||
break;
|
||||
|
||||
// This $content_type var has been introduced when implementing support for multi-section pre-build sections
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/489
|
||||
// when 'sek-add-content-in-new-sektion' is fired, the section has already been populated with a column and a module
|
||||
case 'sek-add-content-in-new-sektion' :
|
||||
case 'sek-add-content-in-new-nested-sektion' :
|
||||
$content_type = null;
|
||||
if ( array_key_exists( 'content_type', $_POST ) && is_string( $_POST['content_type'] ) ) {
|
||||
$content_type = sanitize_text_field($_POST['content_type']);
|
||||
}
|
||||
if ( 'preset_section' === $content_type ) {
|
||||
if ( !array_key_exists( 'collection_of_preset_section_id', $_POST ) || !is_array( $_POST['collection_of_preset_section_id'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => missing param collection_of_preset_section_id when injecting a preset section' );
|
||||
break;
|
||||
}
|
||||
if ( !is_string( $maybe_preset_section_id ) || empty( $maybe_preset_section_id ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => invalid preset section id' );
|
||||
break;
|
||||
}
|
||||
$level_id = $maybe_preset_section_id;
|
||||
// module content type case.
|
||||
// the level id has been passed the regular way
|
||||
} else {
|
||||
$level_id = sanitize_text_field($_POST[ 'id' ]);
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'is_nested', $_POST ) && true === json_decode( sanitize_text_field($_POST['is_nested']) ) ) {
|
||||
// we need to set the parent_mode here to access it later in the ::render method to calculate the column width.
|
||||
$this->parent_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_sektion' ]), $sektion_collection );
|
||||
$level_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_column' ]), $sektion_collection );
|
||||
} else {
|
||||
$level_model = sek_get_level_model( $level_id, $sektion_collection );
|
||||
}
|
||||
break;
|
||||
|
||||
//only used for nested section
|
||||
case 'sek-remove-section' :
|
||||
if ( !array_key_exists( 'is_nested', $_POST ) || true !== json_decode( sanitize_text_field($_POST['is_nested'] )) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => the section must be nested in this ajax action' );
|
||||
break;
|
||||
} else {
|
||||
// we need to set the parent_model here to access it later in the ::render method to calculate the column width.
|
||||
$this->parent_model = sek_get_parent_level_model( sanitize_text_field($_POST[ 'in_column' ]), $sektion_collection );
|
||||
$level_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_column' ]), $sektion_collection );
|
||||
}
|
||||
break;
|
||||
|
||||
// We re-render the entire parent sektion collection in all cases
|
||||
case 'sek-add-column' :
|
||||
case 'sek-remove-column' :
|
||||
case 'sek-duplicate-column' :
|
||||
case 'sek-refresh-columns-in-sektion' :
|
||||
if ( !array_key_exists( 'in_sektion', $_POST ) || empty( $_POST['in_sektion'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => missing in_sektion param' );
|
||||
break;
|
||||
}
|
||||
// sek_error_log('sektion_collection', $sektion_collection );
|
||||
$level_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_sektion' ]), $sektion_collection );
|
||||
break;
|
||||
|
||||
// We re-render the entire parent column collection
|
||||
case 'sek-add-module' :
|
||||
case 'sek-remove-module' :
|
||||
case 'sek-refresh-modules-in-column' :
|
||||
case 'sek-duplicate-module' :
|
||||
if ( !array_key_exists( 'in_column', $_POST ) || empty( $_POST['in_column'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => missing in_column param' );
|
||||
break;
|
||||
}
|
||||
if ( !array_key_exists( 'in_sektion', $_POST ) || empty( $_POST[ 'in_sektion' ] ) ) {
|
||||
$this->parent_model = sek_get_parent_level_model( sanitize_text_field($_POST[ 'in_column' ]), $sektion_collection );
|
||||
} else {
|
||||
$this->parent_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_sektion' ]), $sektion_collection );
|
||||
}
|
||||
$level_model = sek_get_level_model( sanitize_text_field($_POST[ 'in_column' ]), $sektion_collection );
|
||||
break;
|
||||
|
||||
case 'sek-resize-columns' :
|
||||
if ( !array_key_exists( 'resized_column', $_POST ) || empty( $_POST['resized_column'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => missing resized_column' );
|
||||
break;
|
||||
}
|
||||
$is_stylesheet = true;
|
||||
break;
|
||||
|
||||
case 'sek-refresh-stylesheet' :
|
||||
$is_stylesheet = true;
|
||||
break;
|
||||
|
||||
case 'sek-refresh-level' :
|
||||
if ( !array_key_exists( 'id', $_POST ) || empty( $_POST['id'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action .' => missing level id' );
|
||||
break;
|
||||
}
|
||||
if ( !empty( $_POST['level'] ) && 'column' === sanitize_text_field($_POST['level']) ) {
|
||||
// we need to set the parent_mode here to access it later in the ::render method to calculate the column width.
|
||||
$this->parent_model = sek_get_parent_level_model( sanitize_text_field($_POST['id']), $sektion_collection );
|
||||
}
|
||||
$level_model = sek_get_level_model( sanitize_text_field($_POST[ 'id' ]), $sektion_collection );
|
||||
break;
|
||||
}//Switch sek_action
|
||||
|
||||
// sek_error_log('LEVEL MODEL WHEN AJAXING', $level_model );
|
||||
|
||||
ob_start();
|
||||
|
||||
if ( $is_stylesheet ) {
|
||||
$r = $this->print_or_enqueue_seks_style( sanitize_text_field($_POST['location_skope_id']) );
|
||||
} else {
|
||||
if ( 'no_match' == $level_model ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' ' . $sek_action . ' => missing level model' );
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
if ( empty( $level_model ) || !is_array( $level_model ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => empty or invalid $level_model' );
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
// note that in the case of a sektion nested inside a column, the parent_model has been set in the switch{ case : ... } above ,so we can access it in the ::render method to calculate the column width.
|
||||
$r = $this->render( $level_model );
|
||||
}
|
||||
$html = ob_get_clean();
|
||||
if ( is_wp_error( $r ) ) {
|
||||
return $r;
|
||||
} else {
|
||||
// the $html content should not be empty when ajaxing a template
|
||||
// it can be empty when ajaxing a stylesheet
|
||||
if ( !$is_stylesheet && empty( $html ) ) {
|
||||
// return a new WP_Error that will be intercepted in sek_get_level_content_for_injection
|
||||
$html = new \WP_Error( 'ajax_fetch_content_error', __CLASS__ . '::' . __FUNCTION__ . ' => no content returned for sek_action : ' . $sek_action );
|
||||
}
|
||||
return apply_filters( "sek_set_ajax_content", $html, $sek_action );// this is sent with wp_send_json_success( apply_filters( 'sek_content_results', $html, $sek_action ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// USED TO PRINT THE BUTTON EDIT WITH NIMBLE ON POSTS AND PAGES
|
||||
// when using Gutenberg editor
|
||||
// implemented for https://github.com/presscustomizr/nimble-builder/issues/449
|
||||
function sek_get_customize_url_for_nimble_edit_button() {
|
||||
$this->sek_do_ajax_pre_checks( array( 'check_nonce' => false ) );
|
||||
|
||||
if ( !isset( $_POST['nimble_edit_post_id'] ) || empty( $_POST['nimble_edit_post_id'] ) ) {
|
||||
wp_send_json_error( __CLASS__ . '::' . __FUNCTION__ . ' => missing post_id' );
|
||||
}
|
||||
|
||||
$post_id = sanitize_text_field($_POST['nimble_edit_post_id']);
|
||||
|
||||
// Build customize_url
|
||||
// @see function sek_get_customize_url_when_is_admin()
|
||||
$return_url_after_customization = '';//"/wp-admin/post.php?post={$post_id}&action=edit";
|
||||
$customize_url = sek_get_customize_url_for_post_id( $post_id, $return_url_after_customization );
|
||||
wp_send_json_success( $customize_url );
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
?>
|
||||
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
if ( !class_exists( 'SEK_Front_Assets_Customizer_Preview' ) ) :
|
||||
class SEK_Front_Assets_Customizer_Preview extends SEK_Front_Assets {
|
||||
// Fired in __construct()
|
||||
function _schedule_preview_assets_printing() {
|
||||
add_action( 'wp_footer', array( $this, 'sek_customizr_js_stuff' ), PHP_INT_MAX );
|
||||
|
||||
// Load customize preview js
|
||||
add_action( 'customize_preview_init', array( $this, 'sek_schedule_customize_preview_assets' ) );
|
||||
}//_schedule_preview_assets_printing
|
||||
|
||||
// @'wp_footer'
|
||||
function sek_customizr_js_stuff() {
|
||||
if ( !sek_current_user_can_access_nb_ui() )
|
||||
return;
|
||||
if( !skp_is_customizing() )
|
||||
return;
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
(function(w, d){
|
||||
nb_.listenTo( 'nb-app-ready', function() {
|
||||
//PREVIEWED DEVICE ?
|
||||
//Listen to the customizer previewed device
|
||||
var _setPreviewedDevice = function() {
|
||||
wp.customize.preview.bind( 'previewed-device', function( device ) {
|
||||
nb_.previewedDevice = device;// desktop, tablet, mobile
|
||||
});
|
||||
};
|
||||
if ( wp.customize.preview ) {
|
||||
_setPreviewedDevice();
|
||||
} else {
|
||||
wp.customize.bind( 'preview-ready', function() {
|
||||
_setPreviewedDevice();
|
||||
});
|
||||
}
|
||||
// REVEAL BG IMAGE ON CHANGE ?
|
||||
jQuery( function($) {
|
||||
$('body').on( 'sek-level-refreshed', '[data-sek-level="location"]', function( evt, params ) {
|
||||
var matches = document.querySelectorAll('div.sek-has-bg');
|
||||
if ( !nb_.isObject( matches ) || matches.length < 1 )
|
||||
return;
|
||||
|
||||
var imgSrc;
|
||||
matches.forEach( function(el) {
|
||||
if ( !nb_.isObject(el) )
|
||||
return;
|
||||
|
||||
// Maybe reveal BG if lazyload is on
|
||||
if ( nb_.isCustomizing() ) {
|
||||
nb_.mayBeRevealBG.call(el);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}(window, document));
|
||||
<?php
|
||||
$script = ob_get_clean();
|
||||
wp_add_inline_script( 'nb-js-init', $script );
|
||||
}
|
||||
|
||||
// enqueue / print customize preview assets
|
||||
// hook : 'customize_preview_init'
|
||||
function sek_schedule_customize_preview_assets() {
|
||||
if ( !sek_current_user_can_access_nb_ui() )
|
||||
return;
|
||||
|
||||
// we don't need those assets when previewing a customize changeset
|
||||
// added when fixing https://github.com/presscustomizr/nimble-builder/issues/351
|
||||
if ( sek_is_customize_previewing_a_changeset_post() )
|
||||
return;
|
||||
|
||||
// Load preview ui js tmpl
|
||||
add_action( 'wp_footer', array( $this, 'sek_print_ui_tmpl' ) );
|
||||
|
||||
wp_enqueue_style(
|
||||
'sek-preview',
|
||||
sprintf(
|
||||
'%1$s/assets/czr/sek/css/%2$s' ,
|
||||
NIMBLE_BASE_URL,
|
||||
sek_is_dev_mode() ? 'sek-preview.css' : 'sek-preview.min.css'
|
||||
),
|
||||
array( 'sek-base' ),
|
||||
NIMBLE_ASSETS_VERSION,
|
||||
'all'
|
||||
);
|
||||
|
||||
// Communication between preview and customizer panel
|
||||
wp_enqueue_script(
|
||||
'sek-customize-preview',
|
||||
sprintf(
|
||||
'%1$s/assets/czr/sek/js/%2$s' ,
|
||||
NIMBLE_BASE_URL,
|
||||
sek_is_dev_mode() ? 'ccat-sek-preview.js' : 'ccat-sek-preview.min.js'
|
||||
),
|
||||
array( 'customize-preview', 'underscore'),
|
||||
NIMBLE_ASSETS_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'sek-customize-preview',
|
||||
'sekPreviewLocalized',
|
||||
array(
|
||||
'i18n' => array(
|
||||
"You've reached the maximum number of columns allowed in this section." => __( "You've reached the maximum number of columns allowed in this section.", 'text_doma'),
|
||||
"Moving elements between global and local sections is not allowed." => __( "Moving elements between global and local sections is not allowed.", 'text_doma'),
|
||||
'Something went wrong, please refresh this page.' => __('Something went wrong, please refresh this page.', 'text_doma'),
|
||||
'Insert here' => __('Insert here', 'text_doma'),
|
||||
'This content has been created with the WordPress editor.' => __('This content has been created with the WordPress editor.', 'text_domain' ),
|
||||
|
||||
'Insert a new section' => __('Insert a new section', 'text_doma' ),
|
||||
'@location' => __('@location', 'text_domain_to_be'),
|
||||
'Insert a new global section' => __('Insert a new global section', 'text_doma' ),
|
||||
|
||||
'section' => __('section', 'text_doma'),
|
||||
'header section' => __('header section', 'text_doma'),
|
||||
'footer section' => __('footer section', 'text_doma'),
|
||||
'(global)' => __('(global)', 'text_doma'),
|
||||
'nested section' => __('nested section', 'text_doma'),
|
||||
|
||||
'Shift-click to visit the link' => __('Shift-click to visit the link', 'text_doma'),
|
||||
'External links are disabled when customizing' => __('External links are disabled when customizing', 'text_doma'),
|
||||
'Link deactivated while previewing' => __('Link deactivated while previewing', 'text_doma')
|
||||
),
|
||||
'isDevMode' => sek_is_dev_mode(),
|
||||
'isPreviewUIDebugMode' => isset( $_GET['preview_ui_debug'] ) || NIMBLE_IS_PREVIEW_UI_DEBUG_MODE,
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
'frontNonce' => array( 'id' => 'SEKFrontNonce', 'handle' => wp_create_nonce( 'sek-front-nonce' ) ),
|
||||
|
||||
'registeredModules' => CZR_Fmk_Base()->registered_modules,
|
||||
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/494
|
||||
// september 2019
|
||||
// this guid is used to differentiate dynamically rendered content from static content that may include a Nimble generated HTML structure
|
||||
// an attribute "data-sek-preview-level-guid" is added to each rendered level when customizing or ajaxing
|
||||
// when generating the ui, we check if the localized guid matches the one rendered server side
|
||||
// otherwise the preview UI can be broken
|
||||
'previewLevelGuid' => $this->sek_get_preview_level_guid(),
|
||||
|
||||
// Assets id
|
||||
'googleFontsStyleId' => NIMBLE_GOOGLE_FONTS_STYLESHEET_ID,
|
||||
'globalOptionsStyleId' => NIMBLE_GLOBAL_OPTIONS_STYLESHEET_ID
|
||||
)
|
||||
);
|
||||
|
||||
wp_enqueue_script( 'jquery-ui-sortable' );
|
||||
|
||||
wp_enqueue_style(
|
||||
'ui-sortable',
|
||||
'//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css',
|
||||
array(),
|
||||
null,//time(),
|
||||
$media = 'all'
|
||||
);
|
||||
wp_enqueue_script( 'jquery-ui-resizable' );
|
||||
}
|
||||
|
||||
|
||||
//'wp_footer' in the preview frame
|
||||
function sek_print_ui_tmpl() {
|
||||
?>
|
||||
<script type="text/html" id="sek-tmpl-add-content-button">
|
||||
<# //console.log( 'data', data ); #>
|
||||
<div class="sek-add-content-button <# if ( data.is_last ) { #>is_last<# } #>">
|
||||
<div class="sek-add-content-button-wrapper">
|
||||
<# var hook_location = '', btn_title = true !== data.is_global_location ? sekPreviewLocalized.i18n['Insert a new section'] : sekPreviewLocalized.i18n['Insert a new global section'], addContentBtnWidth = true !== data.is_global_location ? '83px' : '113px' #>
|
||||
<# if ( data.location ) {
|
||||
hook_location = ['(' , sekPreviewLocalized.i18n['@location'] , ':"',data.location , '")'].join('');
|
||||
} #>
|
||||
<button title="{{btn_title}} {{hook_location}}" data-sek-click-on="add-content" data-sek-add="section" class="sek-add-content-btn" style="--sek-add-content-btn-width:{{addContentBtnWidth}};">
|
||||
<span class="sek-click-on-button-icon sek-click-on">+</span><span class="action-button-text">{{btn_title}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
$icon_right_side_class = is_rtl() ? 'sek-dyn-left-icons' : 'sek-dyn-right-icons';
|
||||
$icon_left_side_class = is_rtl() ? 'sek-dyn-right-icons' : 'sek-dyn-left-icons';
|
||||
?>
|
||||
|
||||
<script type="text/html" id="sek-dyn-ui-tmpl-section">
|
||||
<?php //<# console.log( 'data', data ); #> ?>
|
||||
<div class="sek-dyn-ui-wrapper sek-section-dyn-ui">
|
||||
<div class="sek-dyn-ui-inner <?php echo esc_attr($icon_left_side_class); ?>">
|
||||
<div class="sek-dyn-ui-icons">
|
||||
|
||||
<?php if ( sek_is_dev_mode() ) : ?>
|
||||
<i class="sek-to-json fas fa-code"></i>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
// Code before implementing https://github.com/presscustomizr/nimble-builder/issues/521 :
|
||||
/* <# if ( true !== data.is_first_section_in_parent ) { #>
|
||||
<i data-sek-click-on="move-section-up" class="material-icons sek-click-on" title="<?php _e( 'Move section up', 'text_domain' ); ?>">keyboard_arrow_up</i>
|
||||
<# } #>
|
||||
<# if ( true !== data.is_last_section_in_parent ) { #>
|
||||
<i data-sek-click-on="move-section-down" class="material-icons sek-click-on" title="<?php _e( 'Move section down', 'text_domain' ); ?>">keyboard_arrow_down</i>
|
||||
<# } #>*/
|
||||
?>
|
||||
<i data-sek-click-on="move-section-up" class="material-icons sek-click-on" title="<?php _e( 'Move section up', 'text_domain' ); ?>">keyboard_arrow_up</i>
|
||||
<i data-sek-click-on="move-section-down" class="material-icons sek-click-on" title="<?php _e( 'Move section down', 'text_domain' ); ?>">keyboard_arrow_down</i>
|
||||
|
||||
|
||||
<?php // if this is a nested section, it has the is_nested property set to true. We don't want to make it draggable for the moment. @todo ?>
|
||||
<# if ( !data.is_nested ) { #>
|
||||
<# if ( true !== data.is_global_location ) { #>
|
||||
<i class="fas fa-arrows-alt sek-move-section" title="<?php _e( 'Drag section', 'text_domain' ); ?>"></i>
|
||||
<# } #>
|
||||
<# } #>
|
||||
<i data-sek-click-on="edit-options" class="material-icons sek-click-on" title="<?php _e( 'Edit section settings', 'text_domain' ); ?>">tune</i>
|
||||
<# if ( data.can_have_more_columns ) { #>
|
||||
<i data-sek-click-on="add-column" class="material-icons sek-click-on" title="<?php _e( 'Add a column', 'text_domain' ); ?>">view_column</i>
|
||||
<# } #>
|
||||
<i data-sek-click-on="duplicate" class="material-icons sek-click-on" title="<?php _e( 'Duplicate section', 'text_domain' ); ?>">filter_none</i>
|
||||
<i data-sek-click-on="toggle-save-section-ui" class="sek-save far fa-save" title="<?php _e( 'Save this section', 'text_domain' ); ?>"></i>
|
||||
<i data-sek-click-on="remove" class="material-icons sek-click-on" title="<?php _e( 'Remove section', 'text_domain' ); ?>">delete_forever</i>
|
||||
</div>
|
||||
</div><?php // .sek-dyn-ui-inner ?>
|
||||
<div class="sek-dyn-ui-location-type" data-sek-click-on="edit-options" title="<?php _e( 'Edit section settings', 'text_domain' ); ?>">
|
||||
<div class="sek-dyn-ui-location-inner">
|
||||
<div class="sek-dyn-ui-hamb-menu-wrapper sek-collapsed">
|
||||
<div class="sek-ham__toggler-spn-wrapper"><span class="line line-1"></span><span class="line line-2"></span><span class="line line-3"></span></div>
|
||||
</div>
|
||||
<#
|
||||
var section_title = true !== data.is_global_location ? sekPreviewLocalized.i18n['section'] : sekPreviewLocalized.i18n['section (global)'];
|
||||
var section_title = !data.is_nested ? sekPreviewLocalized.i18n['section'] : sekPreviewLocalized.i18n['nested section'];
|
||||
if ( true === data.is_header_location && !data.is_nested ) {
|
||||
section_title = sekPreviewLocalized.i18n['header section'];
|
||||
} else if ( true === data.is_footer_location && !data.is_nested ) {
|
||||
section_title = sekPreviewLocalized.i18n['footer section'];
|
||||
}
|
||||
|
||||
section_title = true !== data.is_global_location ? section_title : [ section_title, sekPreviewLocalized.i18n['(global)'] ].join(' ');
|
||||
#>
|
||||
<div class="sek-dyn-ui-level-type">{{section_title}}</div>
|
||||
</div><?php // .sek-dyn-ui-location-inner ?>
|
||||
<div class="sek-minimize-ui" title="<?php _e('Hide this menu if you need to access behind', 'text-domain'); ?>"><i class="far fa-eye-slash"></i></div>
|
||||
</div><?php // .sek-dyn-ui-location-type ?>
|
||||
</div><?php // .sek-dyn-ui-wrapper ?>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="sek-dyn-ui-tmpl-column">
|
||||
<?php //<# console.log( 'data', data ); #> ?>
|
||||
<?php
|
||||
// when a column has nested section(s), its ui might be hidden by deeper columns.
|
||||
// that's why a CSS class is added to position it on the top right corner, instead of bottom right
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/488
|
||||
?>
|
||||
<# var has_nested_section_class = true === data.has_nested_section ? 'sek-col-has-nested-section' : ''; #>
|
||||
<div class="sek-dyn-ui-wrapper sek-column-dyn-ui {{has_nested_section_class}}">
|
||||
<div class="sek-dyn-ui-inner <?php echo esc_attr($icon_right_side_class); ?>">
|
||||
<div class="sek-dyn-ui-icons">
|
||||
<i class="fas fa-arrows-alt sek-move-column" title="<?php _e( 'Move column', 'text_domain' ); ?>"></i>
|
||||
<i data-sek-click-on="edit-options" class="material-icons sek-click-on" title="<?php _e( 'Edit column settings', 'text_domain' ); ?>">tune</i>
|
||||
<# if ( !data.parent_is_last_allowed_nested ) { #>
|
||||
<i data-sek-click-on="add-section" class="material-icons sek-click-on" title="<?php _e( 'Add a nested section', 'text_domain' ); ?>">account_balance_wallet</i>
|
||||
<# } #>
|
||||
<# if ( data.parent_can_have_more_columns ) { #>
|
||||
<i data-sek-click-on="duplicate" class="material-icons sek-click-on" title="<?php _e( 'Duplicate column', 'text_domain' ); ?>">filter_none</i>
|
||||
<# } #>
|
||||
|
||||
<i data-sek-click-on="pick-content" data-sek-content-type="module" class="material-icons sek-click-on" title="<?php _e( 'Add a module', 'text_domain' ); ?>">add_circle_outline</i>
|
||||
<# if ( !data.parent_is_single_column ) { #>
|
||||
<i data-sek-click-on="remove" class="material-icons sek-click-on" title="<?php _e( 'Remove column', 'text_domain' ); ?>">delete_forever</i>
|
||||
<# } #>
|
||||
</div>
|
||||
</div><?php // .sek-dyn-ui-inner ?>
|
||||
|
||||
<div class="sek-dyn-ui-location-type" data-sek-click-on="edit-options" title="<?php _e( 'Edit column settings', 'text_domain' ); ?>">
|
||||
<div class="sek-minimize-ui" title="<?php _e('Hide this menu if you need to access behind', 'text-domain'); ?>"><i class="far fa-eye-slash"></i></div>
|
||||
<div class="sek-dyn-ui-location-inner">
|
||||
<div class="sek-dyn-ui-hamb-menu-wrapper sek-collapsed">
|
||||
<div class="sek-ham__toggler-spn-wrapper"><span class="line line-1"></span><span class="line line-2"></span><span class="line line-3"></span></div>
|
||||
</div>
|
||||
<div class="sek-dyn-ui-level-type"><?php _e( 'column', 'text_domain' ); ?></div>
|
||||
</div><?php // .sek-dyn-ui-location-inner ?>
|
||||
</div><?php // .sek-dyn-ui-location-type ?>
|
||||
</div><?php // .sek-dyn-ui-wrapper ?>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="sek-dyn-ui-tmpl-module">
|
||||
<div class="sek-dyn-ui-wrapper sek-module-dyn-ui">
|
||||
<div class="sek-dyn-ui-inner <?php echo esc_attr($icon_left_side_class); ?>">
|
||||
<div class="sek-dyn-ui-icons">
|
||||
<i class="fas fa-arrows-alt sek-move-module" title="<?php _e( 'Move module', 'text_domain' ); ?>"></i>
|
||||
<i data-sek-click-on="edit-module" class="fas fa-pencil-alt sek-tip sek-click-on" title="<?php _e( 'Edit module content', 'text_domain' ); ?>"></i>
|
||||
<i data-sek-click-on="edit-options" class="material-icons sek-click-on" title="<?php _e( 'Edit module settings', 'text_domain' ); ?>">tune</i>
|
||||
<i data-sek-click-on="duplicate" class="material-icons sek-click-on" title="<?php _e( 'Duplicate module', 'text_domain' ); ?>">filter_none</i>
|
||||
<i data-sek-click-on="remove" class="material-icons sek-click-on" title="<?php _e( 'Remove module', 'text_domain' ); ?>">delete_forever</i>
|
||||
</div>
|
||||
</div><?php // .sek-dyn-ui-inner ?>
|
||||
<#
|
||||
var module_name = !_.isEmpty( data.module_name ) ? data.module_name + ' ' + '<?php _e("module", "text_domain"); ?>' : '<?php _e("module", "text_domain"); ?>';
|
||||
#>
|
||||
<div class="sek-dyn-ui-location-type" data-sek-click-on="edit-module" title="<?php _e( 'Edit module settings', 'text_domain' ); ?>">
|
||||
<div class="sek-dyn-ui-location-inner">
|
||||
<div class="sek-dyn-ui-hamb-menu-wrapper sek-collapsed">
|
||||
<div class="sek-ham__toggler-spn-wrapper"><span class="line line-1"></span><span class="line line-2"></span><span class="line line-3"></span></div>
|
||||
</div>
|
||||
<div class="sek-dyn-ui-level-type">{{module_name}}</div>
|
||||
</div>
|
||||
<div class="sek-minimize-ui" title="<?php _e('Hide this menu if you need to access behind', 'text-domain'); ?>"><i class="far fa-eye-slash"></i></div>
|
||||
</div>
|
||||
</div><?php // .sek-dyn-ui-wrapper ?>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="sek-dyn-ui-tmpl-wp-content">
|
||||
<div class="sek-dyn-ui-wrapper sek-wp-content-dyn-ui">
|
||||
<div class="sek-dyn-ui-inner">
|
||||
<div class="sek-dyn-ui-icons">
|
||||
<i class="fas fa-pencil-alt sek-edit-wp-content" title="<?php _e( 'Edit this WordPress content', 'text_domain' ); ?>"></i>
|
||||
</div>
|
||||
</div><?php // .sek-dyn-ui-inner ?>
|
||||
|
||||
<span class="sek-dyn-ui-location-type" title="<?php _e( 'Edit module settings', 'text_domain' ); ?>">
|
||||
<i class="fab fa-wordpress sek-edit-wp-content" title="<?php _e( 'Edit this WordPress content', 'text_domain' ); ?>"> <?php _e( 'WordPress content', 'text_domain'); ?></i>
|
||||
</span>
|
||||
</div><?php // .sek-dyn-ui-wrapper ?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
?>
|
||||
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
if ( !class_exists( 'SEK_Front_Render_Css' ) ) :
|
||||
class SEK_Front_Render_Css extends SEK_Front_Render {
|
||||
// Fired in __construct()
|
||||
function _setup_hook_for_front_css_printing_or_enqueuing() {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'print_or_enqueue_seks_style'), PHP_INT_MAX );
|
||||
|
||||
// wp_add_inline_style for global CSS
|
||||
add_action( 'wp_head', array( $this, 'sek_enqueue_global_css' ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Can be fired :
|
||||
// 1) on wp_enqueue_scripts or wp_head
|
||||
// 2) when ajaxing, for actions 'sek-resize-columns', 'sek-refresh-stylesheet'
|
||||
function print_or_enqueue_seks_style( $skope_id = null ) {
|
||||
// when this method is fired in a customize preview context :
|
||||
// - the skope_id has to be built. Since we are after 'wp', this is not a problem.
|
||||
// - the css rules are printed inline in the <head>
|
||||
// - we set to hook to wp_head
|
||||
//
|
||||
// when the method is fired in an ajax refresh scenario, like 'sek-refresh-stylesheet'
|
||||
// - the skope_id must be passed as param
|
||||
// - the css rules are printed inline in the <head>
|
||||
// - we set the hook to ''
|
||||
|
||||
// AJAX REQUESTED STYLESHEET
|
||||
if ( ( !is_null( $skope_id ) && !empty( $skope_id ) ) && ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
||||
if ( !isset($_POST['local_skope_id']) ) {
|
||||
sek_error_log( __CLASS__ . '::' . __FUNCTION__ . ' => error missing local_skope_id');
|
||||
return;
|
||||
}
|
||||
$local_skope_id = sanitize_text_field($_POST['local_skope_id']);
|
||||
|
||||
// Feb 2021 => for site template #478
|
||||
$local_skope_id = apply_filters( 'nb_set_skope_id_before_generating_local_front_css', $local_skope_id );
|
||||
|
||||
$css_handler_instance = $this->_instantiate_css_handler( array( 'skope_id' => $skope_id, 'is_global_stylesheet' => NIMBLE_GLOBAL_SKOPE_ID === $skope_id ) );
|
||||
$this->sek_get_global_css_for_ajax();
|
||||
}
|
||||
// in a front normal context, the css is enqueued from the already written file.
|
||||
else {
|
||||
// Feb 2021 => for site template #478
|
||||
$local_skope_id = apply_filters( 'nb_set_skope_id_before_generating_local_front_css', skp_build_skope_id() );
|
||||
|
||||
// LOCAL SECTIONS STYLESHEET
|
||||
$this->_instantiate_css_handler( array( 'skope_id' => $local_skope_id ) );
|
||||
// GLOBAL SECTIONS STYLESHEET
|
||||
// Can hold rules for global sections and global styling
|
||||
$this->_instantiate_css_handler( array( 'skope_id' => NIMBLE_GLOBAL_SKOPE_ID, 'is_global_stylesheet' => true ) );
|
||||
}
|
||||
$google_fonts_print_candidates = $this->sek_get_gfont_print_candidates( $local_skope_id );
|
||||
// GOOGLE FONTS
|
||||
if ( !empty( $google_fonts_print_candidates ) ) {
|
||||
// When customizing we get the google font content
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
||||
$this->sek_get_gfont_in_ajax( $google_fonts_print_candidates );
|
||||
} else {
|
||||
// preload implemented for https://github.com/presscustomizr/nimble-builder/issues/629
|
||||
if ( !skp_is_customizing() && sek_preload_google_fonts_on_front() ) {
|
||||
add_action( 'wp_head', array( $this, 'sek_gfont_print_with_preload') );
|
||||
} else {
|
||||
// March 2020 added param display=swap => Ensure text remains visible during webfont load #572
|
||||
wp_enqueue_style(
|
||||
NIMBLE_GOOGLE_FONTS_STYLESHEET_ID,
|
||||
sprintf( '//fonts.googleapis.com/css?family=%s&display=swap', $google_fonts_print_candidates ),
|
||||
array(),
|
||||
null,
|
||||
'all'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && empty( $local_skope_id ) ) {
|
||||
sek_error_log( __CLASS__ . '::' . __FUNCTION__ . ' => the skope_id should not be empty' );
|
||||
}
|
||||
}//print_or_enqueue_seks_style
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// @param params = array( array( 'skope_id' => NIMBLE_GLOBAL_SKOPE_ID, 'is_global_stylesheet' => true ) )
|
||||
// fired @'wp_enqueue_scripts'
|
||||
private function _instantiate_css_handler( $params = array() ) {
|
||||
$params = wp_parse_args( $params, array( 'skope_id' => '', 'is_global_stylesheet' => false ) );
|
||||
|
||||
// Print inline or enqueue ?
|
||||
$print_mode = Sek_Dyn_CSS_Handler::MODE_FILE;
|
||||
if ( is_customize_preview() ) {
|
||||
$print_mode = Sek_Dyn_CSS_Handler::MODE_INLINE;
|
||||
}
|
||||
// Which hook ?
|
||||
$fire_at_hook = '';
|
||||
if ( !defined( 'DOING_AJAX' ) && is_customize_preview() ) {
|
||||
$fire_at_hook = 'wp_head';
|
||||
}
|
||||
|
||||
$css_handler_instance = new Sek_Dyn_CSS_Handler( array(
|
||||
'id' => $params['skope_id'],
|
||||
'skope_id' => $params['skope_id'],
|
||||
// property "is_global_stylesheet" has been added when fixing https://github.com/presscustomizr/nimble-builder/issues/273
|
||||
'is_global_stylesheet' => $params['is_global_stylesheet'],
|
||||
'mode' => $print_mode,
|
||||
//these are taken in account only when 'mode' is 'file'
|
||||
'force_write' => true, //<- write if the file doesn't exist
|
||||
'force_rewrite' => is_user_logged_in() && current_user_can( 'customize' ), //<- write even if the file exists
|
||||
'hook' => $fire_at_hook
|
||||
));
|
||||
return $css_handler_instance;
|
||||
}
|
||||
|
||||
|
||||
// When ajaxing, the link#sek-gfonts-{$this->id} gets removed from the dom and replaced by this string
|
||||
// March 2020 added param display=swap => Ensure text remains visible during webfont load #572
|
||||
function sek_get_gfont_in_ajax( $print_candidates ) {
|
||||
if ( !empty( $print_candidates ) ) {
|
||||
printf('<link rel="stylesheet" id="%1$s" href="%2$s">',
|
||||
esc_attr(NIMBLE_GOOGLE_FONTS_STYLESHEET_ID),
|
||||
esc_url("//fonts.googleapis.com/css?family={$print_candidates}&display=swap")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// hook : wp_footer
|
||||
// fired on front only when not customizing
|
||||
// March 2020 preload implemented for https://github.com/presscustomizr/nimble-builder/issues/629
|
||||
// March 2020 added param display=swap => Ensure text remains visible during webfont load #572
|
||||
function sek_gfont_print_with_preload( $print_candidates = '' ) {
|
||||
// Check that current page has Nimble content before printing any Google fonts
|
||||
// For https://github.com/presscustomizr/nimble-builder/issues/649
|
||||
if ( !Nimble_Manager()->page_has_local_or_global_sections )
|
||||
return;
|
||||
// print candidates must be fetched when sek_preload_google_fonts_on_front()
|
||||
$print_candidates = $this->sek_get_gfont_print_candidates();
|
||||
|
||||
if ( !empty( $print_candidates ) ) {
|
||||
ob_start();
|
||||
?>
|
||||
nb_.preloadOrDeferAsset( { id : '<?php echo esc_attr(NIMBLE_GOOGLE_FONTS_STYLESHEET_ID); ?>', as : 'style', href : '//fonts.googleapis.com/css?family=<?php echo esc_attr($print_candidates); ?>&display=swap', scriptEl : document.currentScript } );
|
||||
<?php
|
||||
$script = ob_get_clean();
|
||||
wp_register_script( 'nb_preload_gfonts', '');
|
||||
wp_enqueue_script( 'nb_preload_gfonts' );
|
||||
wp_add_inline_script( 'nb_preload_gfonts', $script );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// invoked when ajaxing during customization
|
||||
function sek_get_global_css_for_ajax() {
|
||||
// During customization, always rebuild the css from fresh values instead of relying on the saved option
|
||||
// because on first call we get the customized option value, but on another one quickly after, we get the current option value in the database
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
||||
$global_css = $this->sek_build_global_options_inline_css();
|
||||
if ( is_string( $global_css ) && !empty( $global_css ) ) {
|
||||
printf('<style id="%1$s">%2$s</style>', NIMBLE_GLOBAL_OPTIONS_STYLESHEET_ID, $global_css );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// hook wp_enqueue_script
|
||||
function sek_enqueue_global_css() {
|
||||
$global_css = get_option(NIMBLE_OPT_FOR_GLOBAL_CSS);
|
||||
// following https://developer.wordpress.org/reference/functions/wp_add_inline_script/#comment-5304
|
||||
wp_register_style( NIMBLE_GLOBAL_OPTIONS_STYLESHEET_ID, false );
|
||||
wp_enqueue_style( NIMBLE_GLOBAL_OPTIONS_STYLESHEET_ID );
|
||||
wp_add_inline_style( NIMBLE_GLOBAL_OPTIONS_STYLESHEET_ID, $global_css );
|
||||
}
|
||||
|
||||
|
||||
// Maybe update global inline style with a filter
|
||||
// @return a css string
|
||||
// This CSS is the one generated by global options like global text, global width, global breakpoint
|
||||
function sek_build_global_options_inline_css() {
|
||||
return apply_filters('nimble_set_global_inline_style', '');
|
||||
}
|
||||
|
||||
|
||||
//@return string
|
||||
// sek_model is passed when customizing in SEK_Front_Render_Css::print_or_enqueue_seks_style()
|
||||
function sek_get_gfont_print_candidates( $local_skope_id = null ) {
|
||||
// return the cache version if already set
|
||||
if ( 'not_set' !== Nimble_Manager()->google_fonts_print_candidates )
|
||||
return Nimble_Manager()->google_fonts_print_candidates;
|
||||
|
||||
$local_skope_id = is_null( $local_skope_id ) ? apply_filters( 'maybe_set_skope_id_for_site_template_css', skp_build_skope_id() ) : $local_skope_id;
|
||||
// local sections
|
||||
$local_seks = sek_get_skoped_seks( $local_skope_id );
|
||||
// global sections
|
||||
$global_seks = sek_get_skoped_seks( NIMBLE_GLOBAL_SKOPE_ID );
|
||||
// global options
|
||||
$global_options = get_option( NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS );
|
||||
|
||||
$print_candidates = '';
|
||||
$ffamilies = array();
|
||||
|
||||
// Let's build the collection of google fonts from local sections, global sections, global options
|
||||
if ( is_array( $local_seks ) && !empty( $local_seks['fonts'] ) && is_array( $local_seks['fonts'] ) ) {
|
||||
$ffamilies = $local_seks['fonts'];
|
||||
}
|
||||
if ( is_array( $global_seks ) && !empty( $global_seks['fonts'] ) && is_array( $global_seks['fonts'] ) ) {
|
||||
$ffamilies = array_merge( $ffamilies, $global_seks['fonts'] );
|
||||
}
|
||||
if ( is_array( $global_options ) && !empty( $global_options['fonts'] ) && is_array( $global_options['fonts'] ) ) {
|
||||
$ffamilies = array_merge( $ffamilies, $global_options['fonts'] );
|
||||
}
|
||||
|
||||
// remove duplicate if any
|
||||
$ffamilies = array_unique( $ffamilies );
|
||||
|
||||
if ( !empty( $ffamilies ) ) {
|
||||
$ffamilies = implode( "|", $ffamilies );
|
||||
$print_candidates = str_replace( '|', '%7C', $ffamilies );
|
||||
$print_candidates = str_replace( '[gfont]', '' , $print_candidates );
|
||||
}
|
||||
// cache now
|
||||
Nimble_Manager()->google_fonts_print_candidates = $print_candidates;
|
||||
return Nimble_Manager()->google_fonts_print_candidates;
|
||||
}
|
||||
}//class
|
||||
endif;
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
if ( !class_exists( '\Nimble\Sek_Nimble_Manager' ) ) :
|
||||
final class Sek_Nimble_Manager extends Sek_Simple_Form {}
|
||||
endif;
|
||||
|
||||
function Nimble_Manager( $params = array() ) {
|
||||
return Sek_Nimble_Manager::get_instance( $params );
|
||||
}
|
||||
|
||||
Nimble_Manager();
|
||||
?>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
namespace Nimble;
|
||||
if ( !defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
// @return bool
|
||||
function sek_is_dev_mode() {
|
||||
return ( defined( 'NIMBLE_DEV' ) && NIMBLE_DEV ) || ( defined( 'WP_DEBUG' ) && WP_DEBUG );
|
||||
}
|
||||
// @return bool
|
||||
// Nov 2020 : helper used to display NB CPT in admin
|
||||
function sek_is_cpt_debug_mode() {
|
||||
return isset( $_GET['nimble_cpt_debug'] ) || (defined('NIMBLE_CPT_DEBUG_MODE') && NIMBLE_CPT_DEBUG_MODE);
|
||||
}
|
||||
|
||||
if ( !defined( 'NIMBLE_CPT' ) ) { define( 'NIMBLE_CPT' , 'nimble_post_type' ); }
|
||||
if ( !defined( 'NIMBLE_TEMPLATE_CPT' ) ) { define( 'NIMBLE_TEMPLATE_CPT' , 'nimble_template' ); }
|
||||
if ( !defined( 'NIMBLE_SECTION_CPT' ) ) { define( 'NIMBLE_SECTION_CPT' , 'nimble_section' ); }
|
||||
|
||||
if ( !defined( 'NIMBLE_PREFIX_FOR_SAVED_TMPL' ) ) { define( 'NIMBLE_PREFIX_FOR_SAVED_TMPL' , 'nb_tmpl_' ); }
|
||||
if ( !defined( 'NIMBLE_PREFIX_FOR_SAVED_SECTION' ) ) { define( 'NIMBLE_PREFIX_FOR_SAVED_SECTION' , 'nb_section_' ); }
|
||||
|
||||
if ( !defined( 'NIMBLE_DEPREC_ONE_CSS_FOLDER_NAME' ) ) { define( 'NIMBLE_DEPREC_ONE_CSS_FOLDER_NAME' , 'sek_css' ); }//<= folder name deprecated in july 2020
|
||||
if ( !defined( 'NIMBLE_DEPREC_TWO_CSS_FOLDER_NAME' ) ) { define( 'NIMBLE_DEPREC_TWO_CSS_FOLDER_NAME' , 'nb_css' ); }//<= folder name deprecated in october 2020
|
||||
if ( !defined( 'NIMBLE_CSS_FOLDER_NAME' ) ) { define( 'NIMBLE_CSS_FOLDER_NAME' , 'nimble_css' ); }
|
||||
if ( !defined( 'NIMBLE_OPT_FOR_MODULE_CSS_READING_STATUS' ) ) { define( 'NIMBLE_OPT_FOR_MODULE_CSS_READING_STATUS' , 'nimble_module_css_read_status' ); }
|
||||
|
||||
if ( !defined( 'NIMBLE_OPT_SEKTION_POST_INDEX' ) ) { define( 'NIMBLE_OPT_SEKTION_POST_INDEX' , 'nimble_posts_index' ); }
|
||||
if ( !defined( 'NIMBLE_OPT_PREFIX_FOR_SEKTION_COLLECTION' ) ) { define( 'NIMBLE_OPT_PREFIX_FOR_SEKTION_COLLECTION' , 'nimble___' ); }
|
||||
if ( !defined( 'NIMBLE_GLOBAL_SKOPE_ID' ) ) { define( 'NIMBLE_GLOBAL_SKOPE_ID' , 'skp__global' ); }
|
||||
|
||||
if ( !defined( 'NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS' ) ) { define( 'NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS' , 'nimble_global_opts' ); }// <= name updated in march 2021 was __nimble_options__
|
||||
|
||||
//if ( !defined( 'NIMBLE_OPT_NAME_FOR_SAVED_SEKTIONS' ) ) { define( 'NIMBLE_OPT_NAME_FOR_SAVED_SEKTIONS' , 'nimble_saved_sektions' ); } //<= June 2020 to be removed
|
||||
if ( !defined( 'NIMBLE_OPT_NAME_FOR_MOST_USED_FONTS' ) ) { define( 'NIMBLE_OPT_NAME_FOR_MOST_USED_FONTS' , 'nimble_most_used_fonts' ); }
|
||||
if ( !defined( 'NIMBLE_OPT_FOR_GLOBAL_CSS' ) ) { define( 'NIMBLE_OPT_FOR_GLOBAL_CSS' , 'nimble_global_css' ); }
|
||||
|
||||
if ( !defined( 'NIMBLE_OPT_NAME_FOR_SECTION_JSON' ) ) { define( 'NIMBLE_OPT_NAME_FOR_SECTION_JSON' , 'nimble_prebuild_sections' ); }// <= name updated in march 2021, was nb_prebuild_section_json
|
||||
|
||||
if ( !defined( 'NIMBLE_OPT_NAME_FOR_BACKWARD_FIXES' ) ) { define( 'NIMBLE_OPT_NAME_FOR_BACKWARD_FIXES' , 'nb_backward_fixes' ); }
|
||||
if ( !defined( 'NIMBLE_OPT_NAME_FOR_SHORTCODE_PARSING' ) ) { define( 'NIMBLE_OPT_NAME_FOR_SHORTCODE_PARSING' , 'nb_shortcodes_parsed_in_czr' ); }
|
||||
if ( !defined( 'NIMBLE_OPT_NAME_FOR_DISABLING_WIDGET_MODULE' ) ) { define( 'NIMBLE_OPT_NAME_FOR_DISABLING_WIDGET_MODULE' , 'nb_widgets_disabled_in_czr' ); }
|
||||
if ( !defined( 'NIMBLE_OPT_NAME_FOR_DEBUG_MODE' ) ) { define( 'NIMBLE_OPT_NAME_FOR_DEBUG_MODE' , 'nb_debug_mode_active' ); }
|
||||
|
||||
|
||||
if ( !defined( 'NIMBLE_PREFIX_FOR_SETTING_NOT_SAVED' ) ) { define( 'NIMBLE_PREFIX_FOR_SETTING_NOT_SAVED' , '__nimble__' ); }
|
||||
if ( !defined( 'NIMBLE_WIDGET_PREFIX' ) ) { define( 'NIMBLE_WIDGET_PREFIX' , 'nimble-widget-area-' ); }
|
||||
if ( !defined( 'NIMBLE_ASSETS_VERSION' ) ) { define( 'NIMBLE_ASSETS_VERSION', sek_is_dev_mode() ? time() : NIMBLE_VERSION ); }
|
||||
if ( !defined( 'NIMBLE_MODULE_ICON_PATH' ) ) { define( 'NIMBLE_MODULE_ICON_PATH' , NIMBLE_BASE_URL . '/assets/czr/sek/icons/modules/' ); }
|
||||
if ( !defined( 'NIMBLE_DETACHED_TINYMCE_TEXTAREA_ID') ) { define( 'NIMBLE_DETACHED_TINYMCE_TEXTAREA_ID' , 'czr-customize-content_editor' ); }
|
||||
|
||||
// TRANSIENTS ID
|
||||
if ( !defined( 'NIMBLE_WELCOME_NOTICE_ID' ) ) { define ( 'NIMBLE_WELCOME_NOTICE_ID', 'nimble-welcome-notice-12-2018' ); }
|
||||
//mt_rand(0, 65535) . 'test-nimble-feedback-notice-04-2019'
|
||||
if ( !defined( 'NIMBLE_FEEDBACK_NOTICE_ID' ) ) { define ( 'NIMBLE_FEEDBACK_NOTICE_ID', 'nimble-feedback-notice-01-2022' ); }
|
||||
if ( !defined( 'NIMBLE_FAWESOME_TRANSIENT_ID' ) ) { define ( 'NIMBLE_FAWESOME_TRANSIENT_ID', 'sek_font_awesome_october_2021' ); }
|
||||
if ( !defined( 'NIMBLE_GFONTS_TRANSIENT_ID' ) ) { define ( 'NIMBLE_GFONTS_TRANSIENT_ID', 'sek_gfonts_march_2020' ); }
|
||||
if ( !defined( 'NIMBLE_FEEDBACK_STATUS_TRANSIENT_ID' ) ) { define ( 'NIMBLE_FEEDBACK_STATUS_TRANSIENT_ID', 'nimble_feedback_status' ); }
|
||||
if ( !defined( 'NIMBLE_API_CHECK_TRANSIENT_ID' ) ) { define ( 'NIMBLE_API_CHECK_TRANSIENT_ID', 'nimble_version_check_for_api' ); }
|
||||
|
||||
|
||||
if ( !defined( 'NIMBLE_GOOGLE_FONTS_STYLESHEET_ID' ) ) { define ( 'NIMBLE_GOOGLE_FONTS_STYLESHEET_ID', 'sek-gfonts-local-and-global' ); }
|
||||
if ( !defined( 'NIMBLE_GLOBAL_OPTIONS_STYLESHEET_ID' ) ) { define ( 'NIMBLE_GLOBAL_OPTIONS_STYLESHEET_ID', 'nimble-global-inline-style' ); }
|
||||
|
||||
if ( !defined( "NIMBLE_DATA_API_URL_V2" ) ) { define( "NIMBLE_DATA_API_URL_V2",
|
||||
( defined('NIMBLE_FETCH_API_LOCALLY') && NIMBLE_FETCH_API_LOCALLY && defined('NIMBLE_LOCAL_API_URL') ) ? NIMBLE_LOCAL_API_URL : 'https://api.nimblebuilder.com/wp-json/nimble/v2/cravan'
|
||||
); }
|
||||
if ( !defined( 'NIMBLE_PRO_URL' ) ) { define ( 'NIMBLE_PRO_URL', 'https://presscustomizr.com/nimble-builder-pro' ); }
|
||||
|
||||
// @return bool
|
||||
function sek_is_debug_mode() {
|
||||
return isset( $_GET['nimble_debug'] ) || sek_booleanize_checkbox_val( get_option( NIMBLE_OPT_NAME_FOR_DEBUG_MODE ) );
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* LOCATIONS UTILITIES
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @return array
|
||||
function sek_get_locations() {
|
||||
if ( !is_array( Nimble_Manager()->registered_locations ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => the registered locations must be an array');
|
||||
return Nimble_Manager()->default_locations;
|
||||
}
|
||||
//sek_error_log( __FUNCTION__ .' => locations ?', array_merge( Nimble_Manager()->default_locations, Nimble_Manager()->registered_locations ) );
|
||||
return apply_filters( 'sek_get_locations', Nimble_Manager()->registered_locations );
|
||||
}
|
||||
|
||||
// @return array of "local" content locations => locations with the following characterictics :
|
||||
// - sections in this location are specific to a given skope id
|
||||
// - header and footer locations are excluded
|
||||
function sek_get_local_content_locations() {
|
||||
$locations = array();
|
||||
$all_locations = sek_get_locations();
|
||||
if ( is_array( $all_locations ) ) {
|
||||
foreach ( $all_locations as $loc_id => $loc_data) {
|
||||
// Normalizes with the default model used to register a location
|
||||
// public $default_registered_location_model = [
|
||||
// 'priority' => 10,
|
||||
// 'is_global_location' => false,
|
||||
// 'is_header_location' => false,
|
||||
// 'is_footer_location' => false
|
||||
// ];
|
||||
$loc_data = wp_parse_args( $loc_data, Nimble_Manager()->default_registered_location_model );
|
||||
if ( true === $loc_data['is_header_location'] || true === $loc_data['is_footer_location'] )
|
||||
continue;
|
||||
|
||||
if ( !sek_is_global_location( $loc_id ) ) {
|
||||
$locations[$loc_id] = $loc_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $locations;
|
||||
}
|
||||
|
||||
// DEPRECATED IN V1.4.0.
|
||||
// Kept for retro compatibility
|
||||
function sek_get_local_locations() {
|
||||
return sek_get_local_content_locations();
|
||||
}
|
||||
|
||||
// @return an array of "global" locations => in which the sections are displayed site wide
|
||||
function sek_get_global_locations() {
|
||||
$locations = array();
|
||||
$all_locations = sek_get_locations();
|
||||
if ( is_array( $all_locations ) ) {
|
||||
foreach ( $all_locations as $loc_id => $loc_data) {
|
||||
if ( sek_is_global_location( $loc_id ) ) {
|
||||
$locations[$loc_id] = $loc_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $locations;
|
||||
}
|
||||
|
||||
|
||||
// @param location_id (string)
|
||||
function sek_get_registered_location_property( $location_id, $property_name = '' ) {
|
||||
$all_locations = sek_get_locations();
|
||||
$default_property_val = 'not_set';
|
||||
//sek_error_log( __FUNCTION__ .' => locations ?', $all_locations );
|
||||
if ( !isset( $all_locations[$location_id] ) || !is_array( $all_locations[$location_id] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => the location ' . $location_id . ' is invalid or not registered.');
|
||||
return $default_property_val;
|
||||
}
|
||||
|
||||
if ( empty( $property_name ) || !is_string( $property_name ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => the requested property for location ' . $location_id . ' is invalid');
|
||||
return $default_property_val;
|
||||
}
|
||||
|
||||
$location_params = wp_parse_args( $all_locations[$location_id], Nimble_Manager()->default_registered_location_model );
|
||||
return array_key_exists($property_name, $location_params) ? $location_params[$property_name] : $default_property_val;
|
||||
}
|
||||
|
||||
// @return bool
|
||||
function sek_is_global_location( $location_id ) {
|
||||
if ( !is_string( $location_id ) || empty( $location_id ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error => missing or invalid location_id param' );
|
||||
return false;
|
||||
}
|
||||
$is_global_location = sek_get_registered_location_property( $location_id, 'is_global_location' );
|
||||
return 'not_set' === $is_global_location ? false : true === $is_global_location;
|
||||
}
|
||||
|
||||
// @param $location_id ( string ). Example '__after_header'
|
||||
function register_location( $location_id, $params = array() ) {
|
||||
$params = is_array( $params ) ? $params : array();
|
||||
$params = wp_parse_args( $params, Nimble_Manager()->default_registered_location_model );
|
||||
$registered_locations = Nimble_Manager()->registered_locations;
|
||||
if ( is_array( $registered_locations ) ) {
|
||||
$registered_locations[$location_id] = $params;
|
||||
}
|
||||
Nimble_Manager()->registered_locations = $registered_locations;
|
||||
//sek_error_log( __FUNCTION__ .' => Nimble_Manager()->registered_locations', Nimble_Manager()->registered_locations );
|
||||
}
|
||||
|
||||
|
||||
// @return array
|
||||
// @used when populating the customizer localized params
|
||||
// @param $skope_id optional. Specified when we need to differentiate the local and global locations
|
||||
function sek_get_default_location_model( $skope_id = null ) {
|
||||
$is_global_skope = NIMBLE_GLOBAL_SKOPE_ID === $skope_id;
|
||||
if ( $is_global_skope ) {
|
||||
$defaut_sektions_value = [ 'collection' => [], 'fonts' => [] ];//global_options are saved in a specific option => NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS
|
||||
} else {
|
||||
// March 2021 property '__inherits_group_skope_tmpl_when_exists__' added for site templates #478
|
||||
$defaut_sektions_value = [ 'collection' => [], 'local_options' => [], 'fonts' => [], '__inherits_group_skope_tmpl_when_exists__' => true ];
|
||||
}
|
||||
foreach( sek_get_locations() as $location_id => $params ) {
|
||||
$is_global_location = sek_is_global_location( $location_id );
|
||||
if ( $is_global_skope && !$is_global_location )
|
||||
continue;
|
||||
if ( !$is_global_skope && $is_global_location )
|
||||
continue;
|
||||
|
||||
$location_model = wp_parse_args( [ 'id' => $location_id ], Nimble_Manager()->default_location_model );
|
||||
if ( $is_global_location ) {
|
||||
$location_model[ 'is_global_location' ] = true;
|
||||
}
|
||||
|
||||
$defaut_sektions_value['collection'][] = $location_model;
|
||||
}
|
||||
return $defaut_sektions_value;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
// @return bool
|
||||
// march 2020 introduced for https://github.com/presscustomizr/nimble-builder/issues/629
|
||||
// Firefox doesn not support preload
|
||||
// IE is supposed to support it, but tests show that google fonts may not be loaded on each page refresh
|
||||
function sek_preload_google_fonts_on_front() {
|
||||
// When preload is active, browser support is checked with javascript
|
||||
// with a fallback on regular style fetching
|
||||
// if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE) // 'Internet explorer'
|
||||
// return;
|
||||
// elseif(strpos($_SERVER['HTTP_USER_AGENT'], 'Firefox') !== FALSE) // 'Mozilla Firefox'
|
||||
// return;
|
||||
$glob_perf = sek_get_global_option_value( 'performances' );
|
||||
if ( !is_null( $glob_perf ) && is_array( $glob_perf ) && !empty( $glob_perf['preload_google_fonts'] ) ) {
|
||||
return sek_booleanize_checkbox_val( $glob_perf['preload_google_fonts'] );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// @return bool
|
||||
// march 2020 introduced for https://github.com/presscustomizr/nimble-builder/issues/635
|
||||
function sek_load_front_assets_dynamically() {
|
||||
$glob_perf = sek_get_global_option_value( 'performances' );
|
||||
if ( !is_null( $glob_perf ) && is_array( $glob_perf ) && !empty( $glob_perf['load_assets_in_ajax'] ) ) {
|
||||
return !skp_is_customizing() && sek_booleanize_checkbox_val( $glob_perf['load_assets_in_ajax'] );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Adds defer attribute to enqueued / registered scripts.
|
||||
// fired @wp_enqueue_scripts
|
||||
function sek_defer_script($handle) {
|
||||
// Adds defer attribute to enqueued / registered scripts.
|
||||
wp_script_add_data( $handle, 'defer', true );
|
||||
}
|
||||
|
||||
// oct 2020 => introduction of a normalized way to emit a js event to NB front api
|
||||
// in particular to make sure NB doesn't print a <script> twice to emit the same event
|
||||
function sek_emit_js_event( $event = '', $echo = true ) {
|
||||
$emitted = Nimble_Manager()->emitted_js_event;
|
||||
if ( !is_string($event) || in_array($event, $emitted) )
|
||||
return;
|
||||
$emitted[] = $event;
|
||||
Nimble_Manager()->emitted_js_event = $emitted;
|
||||
|
||||
if ( $echo ) {
|
||||
$html = sprintf('(function(){if(window.nb_){nb_.emit("%1$s");}})();', $event );
|
||||
wp_register_script( 'nb_emit_' . $event, '');
|
||||
wp_enqueue_script( 'nb_emit_' . $event );
|
||||
wp_add_inline_script( 'nb_emit_' . $event, $html );
|
||||
} else {
|
||||
$html = sprintf('<script>(function(){if(window.nb_){nb_.emit("%1$s");}})();</script>', $event );
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* IMAGE HELPER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @see https://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
|
||||
// used in sek_get_select_options_for_input_id()
|
||||
function sek_get_img_sizes() {
|
||||
global $_wp_additional_image_sizes;
|
||||
|
||||
$sizes = array();
|
||||
$to_return = array(
|
||||
'original' => __('Original image dimensions', 'text_doma')
|
||||
);
|
||||
|
||||
foreach ( get_intermediate_image_sizes() as $_size ) {
|
||||
|
||||
$first_to_upper_size = ucfirst(strtolower($_size));
|
||||
$first_to_upper_size = preg_replace_callback( '/[.!?].*?\w/', '\Nimble\sek_img_sizes_preg_replace_callback', $first_to_upper_size );
|
||||
|
||||
if ( in_array( $_size, array('thumbnail', 'medium', 'medium_large', 'large') ) ) {
|
||||
$sizes[ $_size ]['width'] = get_option( "{$_size}_size_w" );
|
||||
$sizes[ $_size ]['height'] = get_option( "{$_size}_size_h" );
|
||||
$sizes[ $_size ]['title'] = $first_to_upper_size;
|
||||
//$sizes[ $_size ]['crop'] = (bool) get_option( "{$_size}_crop" );
|
||||
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
||||
$sizes[ $_size ] = array(
|
||||
'width' => $_wp_additional_image_sizes[ $_size ]['width'],
|
||||
'height' => $_wp_additional_image_sizes[ $_size ]['height'],
|
||||
'title' => $first_to_upper_size
|
||||
//'crop' => $_wp_additional_image_sizes[ $_size ]['crop'],
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach ( $sizes as $_size => $data ) {
|
||||
$to_return[ $_size ] = $data['title'] . ' - ' . $data['width'] . ' x ' . $data['height'];
|
||||
}
|
||||
|
||||
return $to_return;
|
||||
}
|
||||
|
||||
function sek_img_sizes_preg_replace_callback( $matches ) {
|
||||
return strtoupper( $matches[0] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* SMART LOAD HELPER FOR IMAGES AND VIDEOS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/**
|
||||
* callback of preg_replace_callback in SEK_Front_Render::sek_maybe_process_img_for_js_smart_load
|
||||
* @return string
|
||||
*/
|
||||
function nimble_regex_callback( $matches ) {
|
||||
// bail if the img has already been parsed for swiper slider lazyloading ( https://github.com/presscustomizr/nimble-builder/issues/596 )
|
||||
if ( false !== strpos( $matches[0], 'data-srcset' ) || false !== strpos( $matches[0], 'data-src' ) ) {
|
||||
return $matches[0];
|
||||
// bail if already parsed by this regex or if smartload is disabled
|
||||
} else if ( false !== strpos( $matches[0], 'data-sek-src' ) || preg_match('/ data-skip-lazyload *= *"true" */', $matches[0]) ) {
|
||||
return $matches[0];
|
||||
// otherwise go ahead and parse
|
||||
} else {
|
||||
return apply_filters( 'nimble_img_smartloaded',
|
||||
// june 2020 : the spaces before strings to replace ensure we don't replace attributes that include "srcset" or "sizes"
|
||||
// which can happen if another plugin has already added lazy load attributes
|
||||
// see https://github.com/presscustomizr/nimble-builder/issues/723
|
||||
str_replace( array(' srcset=', ' sizes='), array(' data-sek-srcset=', ' data-sek-sizes='),
|
||||
sprintf('<img %1$s src="%2$s" data-sek-src="%3$s" %4$s>',
|
||||
$matches[1],
|
||||
'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
|
||||
$matches[2],
|
||||
$matches[3]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// @return boolean
|
||||
// img smartload can be set globally with 'global-img-smart-load' and locally with 'local-img-smart-load'
|
||||
// the local option wins
|
||||
// if local is set to inherit, return the global option
|
||||
// This option is cached
|
||||
// deactivated when customizing
|
||||
function sek_is_img_smartload_enabled() {
|
||||
// condition added in april 2020 when implementing yoast compat https://github.com/presscustomizr/nimble-builder/issues/657
|
||||
if ( is_admin() && !skp_is_customizing() )
|
||||
return false;
|
||||
|
||||
if ( 'not_cached' !== Nimble_Manager()->img_smartload_enabled ) {
|
||||
return Nimble_Manager()->img_smartload_enabled;
|
||||
}
|
||||
|
||||
$is_img_smartload_enabled = false;
|
||||
// LOCAL OPTION
|
||||
// we use the ajaxily posted skope_id when available <= typically in a customizing ajax action 'sek-refresh-stylesheet'
|
||||
// otherwise we fallback on the normal utility skp_build_skope_id()
|
||||
$local_performances_data = sek_get_local_option_value( 'local_performances' );
|
||||
$local_smartload = 'inherit';
|
||||
if ( !is_null( $local_performances_data ) && is_array( $local_performances_data ) ) {
|
||||
if ( !empty( $local_performances_data['local-img-smart-load'] ) && 'inherit' !== $local_performances_data['local-img-smart-load'] ) {
|
||||
$local_smartload = 'yes' === $local_performances_data['local-img-smart-load'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'inherit' !== $local_smartload ) {
|
||||
$is_img_smartload_enabled = $local_smartload;
|
||||
} else {
|
||||
// GLOBAL OPTION
|
||||
$glob_performances_data = sek_get_global_option_value( 'performances' );
|
||||
if ( !is_null( $glob_performances_data ) && is_array( $glob_performances_data ) && !empty( $glob_performances_data['global-img-smart-load'] ) ) {
|
||||
$is_img_smartload_enabled = sek_booleanize_checkbox_val( $glob_performances_data['global-img-smart-load'] );
|
||||
}
|
||||
}
|
||||
|
||||
// CACHE THE OPTION
|
||||
Nimble_Manager()->img_smartload_enabled = $is_img_smartload_enabled;
|
||||
|
||||
return Nimble_Manager()->img_smartload_enabled;
|
||||
}
|
||||
|
||||
|
||||
// @return boolean
|
||||
// video background lazy load can be set globally with 'global-bg-video-lazy-load'
|
||||
// implemented in nov 2019 for https://github.com/presscustomizr/nimble-builder/issues/287
|
||||
// This option is cached
|
||||
function sek_is_video_bg_lazyload_enabled() {
|
||||
// if ( skp_is_customizing() )
|
||||
// return false;
|
||||
if ( 'not_cached' !== Nimble_Manager()->video_bg_lazyload_enabled ) {
|
||||
return Nimble_Manager()->video_bg_lazyload_enabled;
|
||||
}
|
||||
$is_video_bg_lazyload_enabled = false;
|
||||
$glob_performances_data = sek_get_global_option_value( 'performances' );
|
||||
if ( !is_null( $glob_performances_data ) && is_array( $glob_performances_data ) && !empty( $glob_performances_data['global-bg-video-lazy-load'] ) ) {
|
||||
$is_video_bg_lazyload_enabled = sek_booleanize_checkbox_val( $glob_performances_data['global-bg-video-lazy-load'] );
|
||||
}
|
||||
|
||||
// CACHE THE OPTION
|
||||
Nimble_Manager()->video_bg_lazyload_enabled = $is_video_bg_lazyload_enabled;
|
||||
|
||||
return Nimble_Manager()->video_bg_lazyload_enabled;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* DISABLE SUPPORT FOR BROWSER NATIVE LAZY LOADING
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Disabled when rendering NB content only
|
||||
// attribute loading="lazy" was introduced in WP 5.5, Oct 2020
|
||||
// => see why NB disable it here :https://github.com/presscustomizr/nimble-builder/issues/747
|
||||
add_filter( 'wp_lazy_loading_enabled', function($default) {
|
||||
return Nimble_Manager()->rendering ? false : $default;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* IMPORT IMAGE IF NOT ALREADY IN MEDIA LIB
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @return attachment id or WP_Error
|
||||
// this method uses download_url()
|
||||
// it first checks if the media already exists in the media library
|
||||
function sek_sideload_img_and_return_attachment_id( $img_url ) {
|
||||
// Set variables for storage, fix file filename for query strings.
|
||||
preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $img_url, $matches );
|
||||
$filename = basename( $matches[0] );
|
||||
// prefix with nimble_asset_ if not done yet
|
||||
// for example, when importing a file, the img might already have the nimble_asset_ prefix if it's been uploaded by Nimble
|
||||
if ( 'nimble_asset_' !== substr($filename, 0, strlen('nimble_asset_') ) ) {
|
||||
$filename = 'nimble_asset_' . $filename;
|
||||
}
|
||||
|
||||
// remove the extension
|
||||
$img_title = preg_replace( '/\.[^.]+$/', '', trim( $filename ) );
|
||||
|
||||
//sek_error_log( __FUNCTION__ . ' ALORS img_title?', preg_replace( '/\.[^.]+$/', '', trim( $img_title ) ) );
|
||||
|
||||
// Make sure this img has not already been uploaded
|
||||
// Meta query on the alt property, better than the title
|
||||
// because of https://github.com/presscustomizr/nimble-builder/issues/435
|
||||
$args = array(
|
||||
'posts_per_page' => 1,
|
||||
'post_type' => 'attachment',
|
||||
'post_status' => 'inherit',
|
||||
//'name' => $img_title,
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => '_wp_attachment_image_alt',
|
||||
'value' => $img_title,
|
||||
'compare' => '='
|
||||
),
|
||||
),
|
||||
);
|
||||
$get_attachment = new \WP_Query( $args );
|
||||
|
||||
//error_log( print_r( $get_attachment->posts, true ) );
|
||||
if ( is_array( $get_attachment->posts ) && array_key_exists(0, $get_attachment->posts) ) {
|
||||
//wp_send_json_error( __CLASS__ . '::' . __CLASS__ . '::' . __FUNCTION__ . ' => file already uploaded : ' . $relative_path );
|
||||
$img_id_already_uploaded = $get_attachment->posts[0]->ID;
|
||||
}
|
||||
// stop now and return the id if the attachment was already uploaded
|
||||
if ( isset($img_id_already_uploaded) ) {
|
||||
//sek_error_log( __FUNCTION__ . ' ALREADY UPLOADED ?', $img_id_already_uploaded );
|
||||
return $img_id_already_uploaded;
|
||||
}
|
||||
|
||||
// Insert the media
|
||||
// Prepare the file_array that we will pass to media_handle_sideload()
|
||||
$file_array = array();
|
||||
$file_array['name'] = $filename;
|
||||
|
||||
// Download file to temp location.
|
||||
$file_array['tmp_name'] = download_url( $img_url );
|
||||
|
||||
// If error storing temporarily, return the error.
|
||||
if ( is_wp_error( $file_array['tmp_name'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error when firing download_url() for image : ' . $img_url );
|
||||
return $file_array['tmp_name'];
|
||||
}
|
||||
|
||||
// Do the validation and storage stuff.
|
||||
$id = media_handle_sideload( $file_array, 0 );
|
||||
|
||||
// If error storing permanently, unlink.
|
||||
if ( is_wp_error( $id ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' error when firing media_handle_sideload() for image : ' . $img_url );
|
||||
@unlink( $file_array['tmp_name'] );
|
||||
} else {
|
||||
// Store the title as image alt property
|
||||
// so we can identify it uniquely next time when checking if already uploaded
|
||||
// of course, if the alt property has been manually modified meanwhile, the image will be loaded again
|
||||
// fixes https://github.com/presscustomizr/nimble-builder/issues/435
|
||||
add_post_meta( $id, '_wp_attachment_image_alt', $img_title, true );
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// IMPORT IMG HELPER
|
||||
// recursive
|
||||
//add_filter( 'nimble_pre_import', '\Nimble\sek_maybe_import_imgs' );
|
||||
function sek_maybe_import_imgs( $seks_data, $do_import_images = true ) {
|
||||
$new_seks_data = array();
|
||||
// Reset img_import_errors
|
||||
Nimble_Manager()->img_import_errors = [];
|
||||
foreach ( $seks_data as $key => $value ) {
|
||||
if ( is_array($value) ) {
|
||||
$new_seks_data[$key] = sek_maybe_import_imgs( $value, $do_import_images );
|
||||
} else {
|
||||
if ( is_string( $value ) && false !== strpos( $value, '__img_url__' ) && sek_is_img_url( $value ) ) {
|
||||
$url = str_replace( '__img_url__', '', $value );
|
||||
// april 2020 : new option to skip importing images
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/663
|
||||
if ( !$do_import_images ) {
|
||||
$value = $url;
|
||||
} else {
|
||||
//sek_error_log( __FUNCTION__ . ' URL?', $url );
|
||||
$id = sek_sideload_img_and_return_attachment_id( $url );
|
||||
if ( is_wp_error( $id ) ) {
|
||||
$value = null;
|
||||
$img_errors = Nimble_Manager()->img_import_errors;
|
||||
$img_errors[] = $url;
|
||||
Nimble_Manager()->img_import_errors = $img_errors;
|
||||
} else {
|
||||
$value = $id;
|
||||
}
|
||||
}
|
||||
} else if ( is_string( $value ) && false !== strpos( $value, '__default_img_medium__' ) ) {
|
||||
$value = NIMBLE_BASE_URL . '/assets/img/default-img.png';
|
||||
}
|
||||
$new_seks_data[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $new_seks_data;
|
||||
}
|
||||
|
||||
// @return bool
|
||||
function sek_is_img_url( $url = '' ) {
|
||||
if ( is_string( $url ) ) {
|
||||
if ( preg_match( '/\.(jpg|jpeg|png|gif)/i', $url ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REMOVE IMAGE STYLE ATTRIBUTE
|
||||
* Used in image module, slider module, special image module
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Nov 2020 : removes any additional styles added by a theme ( Twenty Twenty one ) or a plugin to the image
|
||||
// because otherwise it overrides NB builder custom width, height, and custom width when scrolling ( NB Pro )
|
||||
// hook : 'wp_get_attachment_image_attributes'
|
||||
function sek_remove_image_style_attr( $attr ) {
|
||||
if ( is_array($attr) && isset($attr['style']) ) {
|
||||
unset($attr['style']);
|
||||
}
|
||||
return $attr;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Page Menu for menu module
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Display or retrieve list of pages with optional home link.
|
||||
* Modified copy of wp_page_menu()
|
||||
* @return string html menu
|
||||
*/
|
||||
function sek_page_menu_fallback( $args = array() ) {
|
||||
$defaults = array('show_home' => true, 'sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
$args = apply_filters( 'wp_page_menu_args', $args );
|
||||
$menu = '';
|
||||
$list_args = $args;
|
||||
|
||||
// Show Home in the menu
|
||||
if ( !empty($args['show_home']) ) {
|
||||
if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] ) {
|
||||
$text = __('Home' , 'text_domain_to_replace');
|
||||
} else {
|
||||
$text = $args['show_home'];
|
||||
}
|
||||
$class = '';
|
||||
if ( is_front_page() && !is_paged() ) {
|
||||
$class = 'class="current_page_item"';
|
||||
}
|
||||
$menu .= '<li ' . $class . '><a href="' . home_url( '/' ) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
|
||||
// If the front page is a page, add it to the exclude list
|
||||
if (get_option('show_on_front') == 'page') {
|
||||
if ( !empty( $list_args['exclude'] ) ) {
|
||||
$list_args['exclude'] .= ',';
|
||||
} else {
|
||||
$list_args['exclude'] = '';
|
||||
}
|
||||
$list_args['exclude'] .= get_option('page_on_front');
|
||||
}
|
||||
}
|
||||
|
||||
$list_args['echo'] = false;
|
||||
$list_args['title_li'] = '';
|
||||
|
||||
// limit the number of pages displayed, home excluded from the count if included
|
||||
$list_args['number'] = 4;
|
||||
|
||||
$menu .= str_replace( array( "\r", "\n", "\t" ), '', sek_list_pages( $list_args ) );
|
||||
// if ( $menu )
|
||||
// $menu = '<ul>' . $menu . '</ul>';
|
||||
//$menu = '<div class="' . esc_attr($args['menu_class']) . '">' . $menu . "</div>\n";
|
||||
if ( $menu ) {
|
||||
$menu = '<ul class="' . esc_attr( $args['menu_class'] ) . '">' . $menu . '</ul>';
|
||||
}
|
||||
|
||||
//$menu = apply_filters( 'wp_page_menu', $menu, $args );
|
||||
if ( $args['echo'] )
|
||||
echo wp_kses_post($menu);
|
||||
else
|
||||
return $menu;
|
||||
}
|
||||
/**
|
||||
* Retrieve or display list of pages in list (li) format.
|
||||
* Modified copy of wp_list_pages
|
||||
* @return string HTML list of pages.
|
||||
*/
|
||||
function sek_list_pages( $args = '' ) {
|
||||
$defaults = array(
|
||||
'depth' => 0,
|
||||
'show_date' => '',
|
||||
'date_format' => get_option( 'date_format' ),
|
||||
'child_of' => 0,
|
||||
'exclude' => '',
|
||||
'title_li' => __( 'Pages', 'text_domain_to_replace' ),
|
||||
'echo' => 1,
|
||||
'authors' => '',
|
||||
'sort_column' => 'menu_order, post_title',
|
||||
'link_before' => '',
|
||||
'link_after' => '',
|
||||
'walker' => ''
|
||||
);
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
$output = '';
|
||||
$current_page = 0;
|
||||
// sanitize, mostly to keep spaces out
|
||||
$r['exclude'] = preg_replace( '/[^0-9,]/', '', $r['exclude'] );
|
||||
// Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
|
||||
$exclude_array = ( $r['exclude'] ) ? explode( ',', $r['exclude'] ) : array();
|
||||
$r['exclude'] = implode( ',', apply_filters( 'wp_list_pages_excludes', $exclude_array ) );
|
||||
// Query pages.
|
||||
$r['hierarchical'] = 0;
|
||||
$pages = get_pages( $r );
|
||||
if ( !empty( $pages ) ) {
|
||||
if ( $r['title_li'] ) {
|
||||
$output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
|
||||
}
|
||||
global $wp_query;
|
||||
if ( is_page() || is_attachment() || $wp_query->is_posts_page ) {
|
||||
$current_page = get_queried_object_id();
|
||||
} elseif ( is_singular() ) {
|
||||
$queried_object = get_queried_object();
|
||||
if ( is_post_type_hierarchical( $queried_object->post_type ) ) {
|
||||
$current_page = $queried_object->ID;
|
||||
}
|
||||
}
|
||||
$output .= sek_walk_page_tree( $pages, $r['depth'], $current_page, $r );
|
||||
if ( $r['title_li'] ) {
|
||||
$output .= '</ul></li>';
|
||||
}
|
||||
}
|
||||
$html = apply_filters( 'wp_list_pages', $output, $r );
|
||||
if ( $r['echo'] ) {
|
||||
echo wp_kses_post($html);
|
||||
} else {
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve HTML list content for page list.
|
||||
*
|
||||
* @uses Walker_Page to create HTML list content.
|
||||
* @since 2.1.0
|
||||
* @see Walker_Page::walk() for parameters and return description.
|
||||
*/
|
||||
function sek_walk_page_tree( $pages, $depth, $current_page, $r ) {
|
||||
// if ( empty($r['walker']) )
|
||||
// $walker = new Walker_Page;
|
||||
// else
|
||||
// $walker = $r['walker'];
|
||||
$walker = new \Walker_Page;
|
||||
foreach ( (array) $pages as $page ) {
|
||||
if ( $page->post_parent ) {
|
||||
$r['pages_with_children'][ $page->post_parent ] = true;
|
||||
}
|
||||
}
|
||||
$args = array( $pages, $depth, $r, $current_page );
|
||||
return call_user_func_array(array($walker, 'walk'), $args);
|
||||
}
|
||||
|
||||
function sek_get_user_created_menus() {
|
||||
// if ( !skp_is_customizing() )
|
||||
// return array();
|
||||
$all_menus = get_terms( 'nav_menu', array( 'hide_empty' => true ) );
|
||||
$user_menus = array();
|
||||
foreach ( $all_menus as $menu_obj ) {
|
||||
if ( is_string( $menu_obj->slug ) && !empty( $menu_obj->slug ) && !empty( $menu_obj->name ) ) {
|
||||
$user_menus[ $menu_obj->slug ] = $menu_obj->name;
|
||||
}
|
||||
}
|
||||
// sek_error_log( 'sek_get_user_created_menus', array_merge(
|
||||
// array( 'nimble_page_menu' => __('Default page menu', 'text_domain_to_replace') )
|
||||
// , $user_menus ) );
|
||||
return array_merge(
|
||||
array( 'nimble_page_menu' => __('Default page menu', 'text_domain_to_replace') )
|
||||
, $user_menus );
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,748 @@
|
||||
<?php
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* MODULES COLLECTION
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// introduced when implementing the level tree #359
|
||||
function sek_get_module_collection() {
|
||||
return apply_filters( 'sek_get_module_collection', array(
|
||||
array(
|
||||
'content-type' => 'preset_section',
|
||||
'content-id' => 'two_columns',
|
||||
'title' => __( 'Two Columns', 'text_doma' ),
|
||||
'icon' => 'Nimble_2-columns_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'preset_section',
|
||||
'content-id' => 'three_columns',
|
||||
'title' => __( 'Three Columns', 'text_doma' ),
|
||||
'icon' => 'Nimble_3-columns_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'preset_section',
|
||||
'content-id' => 'four_columns',
|
||||
'title' => __( 'Four Columns', 'text_doma' ),
|
||||
'icon' => 'Nimble_4-columns_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_tiny_mce_editor_module',
|
||||
'title' => __( 'Rich Text Editor', 'text_doma' ),
|
||||
'icon' => 'Nimble_rich-text-editor_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_image_module',
|
||||
'title' => __( 'Image', 'text_doma' ),
|
||||
'icon' => 'Nimble__image_icon.svg'
|
||||
),
|
||||
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_gallery_module',
|
||||
'title' => __( 'Image gallery', 'text_doma' ),
|
||||
'icon' => 'Nimble_gallery_icon.svg'
|
||||
),
|
||||
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_heading_module',
|
||||
'title' => __( 'Heading', 'text_doma' ),
|
||||
'icon' => 'Nimble__heading_icon.svg'
|
||||
),
|
||||
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_icon_module',
|
||||
'title' => __( 'Icon', 'text_doma' ),
|
||||
'icon' => 'Nimble__icon_icon.svg'
|
||||
),
|
||||
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_special_img_module',
|
||||
'title' => __( 'Nimble Image', 'text_doma' ),
|
||||
'icon' => 'Nimble_img_icon.svg',
|
||||
'is_pro' => !sek_is_pro(),
|
||||
'active' => sek_is_pro()
|
||||
),
|
||||
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_button_module',
|
||||
'title' => __( 'Button', 'text_doma' ),
|
||||
'icon' => 'Nimble_button_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_img_slider_module',
|
||||
'title' => __( 'Image & Text Carousel', 'text_doma' ),
|
||||
'icon' => 'Nimble_slideshow_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_accordion_module',
|
||||
'title' => __( 'Accordion', 'text_doma' ),
|
||||
'icon' => 'Nimble_accordion_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_advanced_list_module',
|
||||
'title' => __( 'Advanced List', 'text_doma' ),
|
||||
'icon' => 'Nimble__advanced_list_icon.svg',
|
||||
'is_pro' => !sek_is_pro(),
|
||||
'active' => sek_is_pro()
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_simple_html_module',
|
||||
'title' => __( 'Html Content', 'text_doma' ),
|
||||
'icon' => 'Nimble_html_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_post_grid_module',
|
||||
'title' => __( 'Post Grid', 'text_doma' ),
|
||||
'icon' => 'Nimble_posts-list_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_quote_module',
|
||||
'title' => __( 'Quote', 'text_doma' ),
|
||||
'icon' => 'Nimble_quote_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_shortcode_module',
|
||||
'title' => __( 'Shortcode', 'text_doma' ),
|
||||
'icon' => 'Nimble_shortcode_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_spacer_module',
|
||||
'title' => __( 'Spacer', 'text_doma' ),
|
||||
'icon' => 'Nimble__spacer_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_divider_module',
|
||||
'title' => __( 'Divider', 'text_doma' ),
|
||||
'icon' => 'Nimble__divider_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_map_module',
|
||||
'title' => __( 'Map', 'text_doma' ),
|
||||
'icon' => 'Nimble_map_icon.svg'
|
||||
),
|
||||
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_widget_area_module',
|
||||
'title' => __( 'WordPress widget area', 'text_doma' ),
|
||||
'font_icon' => '<i class="fab fa-wordpress-simple"></i>',
|
||||
'active' => !sek_is_widget_module_disabled()
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_social_icons_module',
|
||||
'title' => __( 'Social Profiles', 'text_doma' ),
|
||||
'icon' => 'Nimble_social_icon.svg'
|
||||
),
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_simple_form_module',
|
||||
'title' => __( 'Simple Contact Form', 'text_doma' ),
|
||||
'icon' => 'Nimble_contact-form_icon.svg'
|
||||
),
|
||||
|
||||
array(
|
||||
'content-type' => 'module',
|
||||
'content-id' => 'czr_menu_module',
|
||||
'title' => __( 'Menu', 'text_doma' ),
|
||||
'font_icon' => '<i class="material-icons">menu</i>'
|
||||
//'active' => sek_are_beta_features_enabled()
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// September 2020 : filter the collection of modules
|
||||
// Removes pro upsell modules if sek_is_upsell_enabled() is false
|
||||
// filter declared in inc/sektions/_front_dev_php/_constants_and_helper_functions/0_0_5_modules_helpers.php
|
||||
add_filter('sek_get_module_collection', function( $collection ) {
|
||||
if ( sek_is_upsell_enabled() )
|
||||
return $collection;
|
||||
|
||||
$filtered = [];
|
||||
foreach ($collection as $mod => $mod_data) {
|
||||
if ( array_key_exists('is_pro', $mod_data) && $mod_data['is_pro'] )
|
||||
continue;
|
||||
$filtered[] = $mod_data;
|
||||
}
|
||||
return $filtered;
|
||||
});
|
||||
|
||||
|
||||
// @return void()
|
||||
// Fired in 'wp_enqueue_scripts'
|
||||
// Recursively sniff the local and global sections to populate Nimble_Manager()->contextually_active_modules
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/612
|
||||
function sek_populate_collection_of_contextually_active_modules( $skope_id = '', $recursive_data = null, $module_collection = null ) {
|
||||
|
||||
$skope_id = empty( $skope_id ) ? skp_get_skope_id() : $skope_id;
|
||||
|
||||
if ( is_null( $recursive_data ) ) {
|
||||
$local_skope_settings = sek_get_skoped_seks( $skope_id );
|
||||
$local_collection = ( is_array( $local_skope_settings ) && !empty( $local_skope_settings['collection'] ) ) ? $local_skope_settings['collection'] : array();
|
||||
$global_skope_settings = sek_get_skoped_seks( NIMBLE_GLOBAL_SKOPE_ID );
|
||||
$global_collection = ( is_array( $global_skope_settings ) && !empty( $global_skope_settings['collection'] ) ) ? $global_skope_settings['collection'] : array();
|
||||
|
||||
$recursive_data = array_merge( $local_collection, $global_collection );
|
||||
}
|
||||
if ( is_null( $module_collection ) ) {
|
||||
// make sure Nimble_Manager()->contextually_active_modules is initialized as an array before starting populating it.
|
||||
$module_collection = 'not_set' === Nimble_Manager()->contextually_active_modules ? [] : Nimble_Manager()->contextually_active_modules;
|
||||
}
|
||||
|
||||
foreach ($recursive_data as $key => $value) {
|
||||
if ( is_array( $value ) && array_key_exists('module_type', $value) ) {
|
||||
$module_type = $value['module_type'];
|
||||
if ( !array_key_exists($module_type, $module_collection) ) {
|
||||
$module_collection[$module_type] = [];
|
||||
}
|
||||
if ( !in_array( $value['id'], $module_collection[$module_type] ) ) {
|
||||
$module_collection[$module_type][] = $value['id'];
|
||||
}
|
||||
} else if ( is_array( $value ) ) {
|
||||
$module_collection = sek_populate_collection_of_contextually_active_modules( $skope_id, $value, $module_collection);
|
||||
}
|
||||
}
|
||||
Nimble_Manager()->contextually_active_modules = $module_collection;
|
||||
return Nimble_Manager()->contextually_active_modules;
|
||||
}
|
||||
|
||||
// return the cached collection or build it when needed
|
||||
function sek_get_collection_of_contextually_active_modules( $skope_id = '' ) {
|
||||
$skope_id = empty( $skope_id ) ? skp_get_skope_id() : $skope_id;
|
||||
if ( 'not_set' === Nimble_Manager()->contextually_active_modules ) {
|
||||
return sek_populate_collection_of_contextually_active_modules( $skope_id );
|
||||
}
|
||||
return Nimble_Manager()->contextually_active_modules;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REGISTERED MODULES => GET PROPERTY
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Helper
|
||||
function sek_get_registered_module_type_property( $module_type, $property = '' ) {
|
||||
// check introduced since https://github.com/presscustomizr/nimble-builder/issues/432
|
||||
// may not be mandatory
|
||||
if ( !class_exists('\Nimble\CZR_Fmk_Base') ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => CZR_Fmk_Base not loaded' );
|
||||
return;
|
||||
}
|
||||
// registered modules
|
||||
$registered_modules = CZR_Fmk_Base()->registered_modules;
|
||||
if ( !array_key_exists( $module_type, $registered_modules ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' not registered.' );
|
||||
return;
|
||||
}
|
||||
if ( array_key_exists( $property , $registered_modules[ $module_type ] ) ) {
|
||||
return $registered_modules[ $module_type ][$property];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* GET THE INPUT VALUE OF A GIVEN MODULE MODEL
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// Recursive helper
|
||||
// Handles simple model and multidimensional module model ( father - children ), like
|
||||
// Array
|
||||
// (
|
||||
// [quote_content] => Array
|
||||
// (
|
||||
// [quote_text] => Hey, careful, man, there's a beverage here!
|
||||
// [quote_font_size_css] => Array
|
||||
// (
|
||||
// [desktop] => 29px
|
||||
// [mobile] => 12px
|
||||
// )
|
||||
|
||||
// [quote_letter_spacing_css] => 7
|
||||
// [quote___flag_important] => 1
|
||||
// )
|
||||
|
||||
// [cite_content] => Array
|
||||
// (
|
||||
// [cite_text] => The Dude in <a href="https://www.imdb.com/title/tt0118715/quotes/qt0464770" rel="nofollow noopener noreferrer" target="_blank">The Big Lebowski</a>
|
||||
// [cite_font_style_css] => italic
|
||||
// )
|
||||
|
||||
// [design] => Array
|
||||
// (
|
||||
// [quote_design] => border-before
|
||||
// )
|
||||
// )
|
||||
// Helper
|
||||
// @param $input_id ( string )
|
||||
// @param $module_model ( array )
|
||||
function sek_get_input_value_in_module_model( $input_id, $module_model ) {
|
||||
if ( !is_string( $input_id ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => the $input_id param should be a string', $module_model);
|
||||
return;
|
||||
}
|
||||
if ( !is_array( $module_model ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => the $module_model param should be an array', $module_model );
|
||||
return;
|
||||
}
|
||||
$input_value = '_not_set_';
|
||||
foreach ( $module_model as $key => $data ) {
|
||||
if ( $input_value !== '_not_set_' )
|
||||
break;
|
||||
if ( $input_id === $key ) {
|
||||
$input_value = $data;
|
||||
break;
|
||||
} else {
|
||||
if ( is_array( $data ) ) {
|
||||
$input_value = sek_get_input_value_in_module_model( $input_id, $data );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $input_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REGISTERED MODULES => DEFAULT MODULE MODEL
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @param (string) module_type
|
||||
// Walk the registered modules tree and generates the module default if not already cached
|
||||
// used :
|
||||
// - in sek_normalize_module_value_with_defaults(), when preprocessing the module model before printing the module template. @see SEK_Front::render()
|
||||
// - when setting the css of a level option. @see for example : sek_add_css_rules_for_bg_border_background()
|
||||
// @return array()
|
||||
function sek_get_default_module_model( $module_type = '' ) {
|
||||
$default = array();
|
||||
if ( empty( $module_type ) || is_null( $module_type ) )
|
||||
return $default;
|
||||
|
||||
// check introduced since https://github.com/presscustomizr/nimble-builder/issues/432
|
||||
// may not be mandatory
|
||||
if ( !class_exists('\Nimble\CZR_Fmk_Base') ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => CZR_Fmk_Base not loaded' );
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Did we already cache it ?
|
||||
$default_models = Nimble_Manager()->default_models;
|
||||
if ( !empty( $default_models[ $module_type ] ) ) {
|
||||
$default = $default_models[ $module_type ];
|
||||
} else {
|
||||
$registered_modules = CZR_Fmk_Base()->registered_modules;
|
||||
if ( !array( $registered_modules ) || !CZR_Fmk_Base()->czr_is_module_registered($module_type) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' is not registered in the $CZR_Fmk_Base_fn()->registered_modules;' );
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Is this module a father ?
|
||||
if ( !empty( $registered_modules[ $module_type ]['is_father'] ) && true === $registered_modules[ $module_type ]['is_father'] ) {
|
||||
if ( empty( $registered_modules[ $module_type ][ 'children' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' missing children modules' );
|
||||
return $default;
|
||||
}
|
||||
if ( !is_array( $registered_modules[ $module_type ][ 'children' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' children modules should be an array' );
|
||||
return $default;
|
||||
}
|
||||
|
||||
foreach ( $registered_modules[ $module_type ][ 'children' ] as $opt_group => $child_mod_type ) {
|
||||
if ( empty( $registered_modules[ $child_mod_type ][ 'tmpl' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $child_mod_type . ' => missing "tmpl" property => impossible to build the father default model.' );
|
||||
continue;
|
||||
}
|
||||
$default[$opt_group] = _sek_build_default_model( $registered_modules[ $child_mod_type ][ 'tmpl' ] );
|
||||
}
|
||||
}
|
||||
// Not father module case
|
||||
else {
|
||||
if ( empty( $registered_modules[ $module_type ][ 'tmpl' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' => missing "tmpl" property => impossible to build the default model.' );
|
||||
return $default;
|
||||
}
|
||||
// Build
|
||||
$default = _sek_build_default_model( $registered_modules[ $module_type ][ 'tmpl' ] );
|
||||
}
|
||||
|
||||
// Cache
|
||||
$default_models[ $module_type ] = $default;
|
||||
Nimble_Manager()->default_models = $default_models;
|
||||
//sek_error_log( __FUNCTION__ . ' => $default_models', $default_models );
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
// @return array() default model
|
||||
// Walk recursively the 'tmpl' property of the module
|
||||
// 'tmpl' => array(
|
||||
// 'pre-item' => array(
|
||||
// 'social-icon' => array(
|
||||
// 'input_type' => 'select',
|
||||
// 'title' => __('Select an icon', 'text_doma')
|
||||
// ),
|
||||
// ),
|
||||
// 'mod-opt' => array(
|
||||
// 'social-size' => array(
|
||||
// 'input_type' => 'number',
|
||||
// 'title' => __('Size in px', 'text_doma'),
|
||||
// 'step' => 1,
|
||||
// 'min' => 5,
|
||||
// 'transport' => 'postMessage'
|
||||
// )
|
||||
// ),
|
||||
// 'item-inputs' => array(
|
||||
// 'item-inputs' => array(
|
||||
// 'tabs' => array(
|
||||
// array(
|
||||
// 'title' => __('Content', 'text_doma'),
|
||||
// //'attributes' => 'data-sek-device="desktop"',
|
||||
// 'inputs' => array(
|
||||
// 'content' => array(
|
||||
// 'input_type' => 'detached_tinymce_editor',
|
||||
// 'title' => __('Content', 'text_doma')
|
||||
// ),
|
||||
// 'h_alignment_css' => array(
|
||||
// 'input_type' => 'h_text_alignment',
|
||||
// 'title' => __('Alignment', 'text_doma'),
|
||||
// 'default' => is_rtl() ? 'right' : 'left',
|
||||
// 'refresh_markup' => false,
|
||||
// 'refresh_stylesheet' => true
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
function _sek_build_default_model( $module_tmpl_data, $default_model = null ) {
|
||||
$default_model = is_array( $default_model ) ? $default_model : array();
|
||||
//error_log( print_r( $module_tmpl_data , true ) );
|
||||
foreach( $module_tmpl_data as $key => $data ) {
|
||||
if ( 'pre-item' === $key )
|
||||
continue;
|
||||
if ( is_array( $data ) && array_key_exists( 'input_type', $data ) ) {
|
||||
$default_model[ $key ] = array_key_exists( 'default', $data ) ? $data[ 'default' ] : '';
|
||||
}
|
||||
if ( is_array( $data ) ) {
|
||||
$default_model = _sek_build_default_model( $data, $default_model );
|
||||
}
|
||||
}
|
||||
|
||||
return $default_model;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* REGISTERED MODULES => INPUT LIST
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @param (string) module_type
|
||||
// Walk the registered modules tree and generates the module input list if not already cached
|
||||
// used :
|
||||
// - when filtering 'sek_add_css_rules_for_input_id' @see Sek_Dyn_CSS_Builder::sek_css_rules_sniffer_walker()
|
||||
// @return array()
|
||||
function sek_get_registered_module_input_list( $module_type = '' ) {
|
||||
$input_list = array();
|
||||
if ( empty( $module_type ) || is_null( $module_type ) )
|
||||
return $input_list;
|
||||
|
||||
// check introduced since https://github.com/presscustomizr/nimble-builder/issues/432
|
||||
// may not be mandatory
|
||||
if ( !class_exists('\Nimble\CZR_Fmk_Base') ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => CZR_Fmk_Base not loaded' );
|
||||
return $input_list;
|
||||
}
|
||||
|
||||
// Did we already cache it ?
|
||||
$cached_input_lists = Nimble_Manager()->cached_input_lists;
|
||||
if ( !empty( $cached_input_lists[ $module_type ] ) ) {
|
||||
$input_list = $cached_input_lists[ $module_type ];
|
||||
} else {
|
||||
$registered_modules = CZR_Fmk_Base()->registered_modules;
|
||||
// sek_error_log( __FUNCTION__ . ' => registered_modules', $registered_modules );
|
||||
if ( sek_is_dev_mode() && !array( $registered_modules ) || !array_key_exists( $module_type, $registered_modules ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' is not registered in the $CZR_Fmk_Base_fn()->registered_modules;' );
|
||||
return $input_list;
|
||||
}
|
||||
|
||||
|
||||
// Is this module a father ?
|
||||
if ( !empty( $registered_modules[ $module_type ]['is_father'] ) && true === $registered_modules[ $module_type ]['is_father'] ) {
|
||||
if ( empty( $registered_modules[ $module_type ][ 'children' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' missing children modules' );
|
||||
return $input_list;
|
||||
}
|
||||
if ( !is_array( $registered_modules[ $module_type ][ 'children' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' children modules should be an array' );
|
||||
return $input_list;
|
||||
}
|
||||
$temp = array();
|
||||
foreach ( $registered_modules[ $module_type ][ 'children' ] as $opt_group => $child_mod_type ) {
|
||||
if ( empty( $registered_modules[ $child_mod_type ][ 'tmpl' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $child_mod_type . ' => missing "tmpl" property => impossible to build the master input_list.' );
|
||||
continue;
|
||||
}
|
||||
// $temp[$opt_group] = _sek_build_input_list( $registered_modules[ $child_mod_type ][ 'tmpl' ] );
|
||||
// $input_list = array_merge( $input_list, $temp[$opt_group] );
|
||||
|
||||
$input_list[$opt_group] = _sek_build_input_list( $registered_modules[ $child_mod_type ][ 'tmpl' ] );
|
||||
}
|
||||
} else {
|
||||
if ( empty( $registered_modules[ $module_type ][ 'tmpl' ] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' => missing "tmpl" property => impossible to build the input_list.' );
|
||||
return $input_list;
|
||||
}
|
||||
// Build
|
||||
$input_list = _sek_build_input_list( $registered_modules[ $module_type ][ 'tmpl' ] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// if ( empty( $registered_modules[ $module_type ][ 'tmpl' ] ) ) {
|
||||
// sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' => missing "tmpl" property => impossible to build the input_list.' );
|
||||
// return $input_list;
|
||||
// }
|
||||
|
||||
// // Build
|
||||
// $input_list = _sek_build_input_list( $registered_modules[ $module_type ][ 'tmpl' ] );
|
||||
|
||||
// Cache
|
||||
$cached_input_lists[ $module_type ] = $input_list;
|
||||
Nimble_Manager()->cached_input_lists = $cached_input_lists;
|
||||
// sek_error_log( __FUNCTION__ . ' => $cached_input_lists', $cached_input_lists );
|
||||
}
|
||||
return $input_list;
|
||||
}
|
||||
|
||||
// @return array() default model
|
||||
// Walk recursively the 'tmpl' property of the module
|
||||
// 'tmpl' => array(
|
||||
// 'pre-item' => array(
|
||||
// 'social-icon' => array(
|
||||
// 'input_type' => 'select',
|
||||
// 'title' => __('Select an icon', 'text_doma')
|
||||
// ),
|
||||
// ),
|
||||
// 'mod-opt' => array(
|
||||
// 'social-size' => array(
|
||||
// 'input_type' => 'number',
|
||||
// 'title' => __('Size in px', 'text_doma'),
|
||||
// 'step' => 1,
|
||||
// 'min' => 5,
|
||||
// 'transport' => 'postMessage'
|
||||
// )
|
||||
// ),
|
||||
// 'item-inputs' => array(
|
||||
// 'item-inputs' => array(
|
||||
// 'tabs' => array(
|
||||
// array(
|
||||
// 'title' => __('Content', 'text_doma'),
|
||||
// //'attributes' => 'data-sek-device="desktop"',
|
||||
// 'inputs' => array(
|
||||
// 'content' => array(
|
||||
// 'input_type' => 'detached_tinymce_editor',
|
||||
// 'title' => __('Content', 'text_doma')
|
||||
// ),
|
||||
// 'h_alignment_css' => array(
|
||||
// 'input_type' => 'h_text_alignment',
|
||||
// 'title' => __('Alignment', 'text_doma'),
|
||||
// 'default' => is_rtl() ? 'right' : 'left',
|
||||
// 'refresh_markup' => false,
|
||||
// 'refresh_stylesheet' => true
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
// Build the input list from item-inputs and modop-inputs
|
||||
function _sek_build_input_list( $module_tmpl_data, $input_list = null ) {
|
||||
$input_list = is_array( $input_list ) ? $input_list : array();
|
||||
//sek_error_log( '_sek_build_input_list', print_r( $module_tmpl_data , true ) );
|
||||
foreach( $module_tmpl_data as $key => $data ) {
|
||||
if ( 'pre-item' === $key )
|
||||
continue;
|
||||
if ( is_array( $data ) && array_key_exists( 'input_type', $data ) ) {
|
||||
// each input_id of a module should be unique
|
||||
if ( array_key_exists( $key, $input_list ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => duplicated input_id found => ' . $key );
|
||||
} else {
|
||||
$input_list[ $key ] = $data;
|
||||
}
|
||||
} else if ( is_array( $data ) ) {
|
||||
$input_list = _sek_build_input_list( $data, $input_list );
|
||||
}
|
||||
}
|
||||
|
||||
return $input_list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* NORMALIZE MODULE VALUE WITH DEFAULT
|
||||
* preprocessing the module model before printing the module template.
|
||||
* used before rendering or generating css
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @return array() $normalized_model
|
||||
function sek_normalize_module_value_with_defaults( $raw_module_model ) {
|
||||
$normalized_model = $raw_module_model;
|
||||
if ( empty( $normalized_model['module_type'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing module type', $normalized_model );
|
||||
}
|
||||
$module_type = $normalized_model['module_type'];
|
||||
$is_father = sek_get_registered_module_type_property( $module_type, 'is_father' );
|
||||
|
||||
$raw_module_value = ( !empty( $raw_module_model['value'] ) && is_array( $raw_module_model['value'] ) ) ? $raw_module_model['value'] : array();
|
||||
|
||||
// reset the model value and rewrite it normalized with the defaults
|
||||
$normalized_model['value'] = array();
|
||||
if ( $is_father ) {
|
||||
$children = sek_get_registered_module_type_property( $module_type, 'children' );
|
||||
if ( empty( $children ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' missing children modules' );
|
||||
return $default;
|
||||
}
|
||||
if ( !is_array( $children ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => ' . $module_type . ' children modules should be an array' );
|
||||
return $default;
|
||||
}
|
||||
foreach ( $children as $opt_group => $child_mod_type ) {
|
||||
$children_value = ( !empty( $raw_module_value[$opt_group] ) && is_array( $raw_module_value[$opt_group] ) ) ? $raw_module_value[$opt_group] : array();
|
||||
$normalized_model['value'][ $opt_group ] = _sek_normalize_single_module_values( $children_value, $child_mod_type );
|
||||
}
|
||||
} else {
|
||||
$normalized_model['value'] = _sek_normalize_single_module_values( $raw_module_value, $module_type );
|
||||
}
|
||||
//sek_error_log('sek_normalize_single_module_values for module type ' . $module_type , $normalized_model );
|
||||
return $normalized_model;
|
||||
}
|
||||
|
||||
// @return array()
|
||||
function _sek_normalize_single_module_values( $raw_module_value, $module_type ) {
|
||||
$default_value_model = sek_get_default_module_model( $module_type );//<= walk the registered modules tree and generates the module default if not already cached
|
||||
|
||||
// reset the model value and rewrite it normalized with the defaults
|
||||
$module_values = array();
|
||||
if ( czr_is_multi_item_module( $module_type ) ) {
|
||||
foreach ( $raw_module_value as $item ) {
|
||||
$module_values[] = wp_parse_args( $item, $default_value_model );
|
||||
}
|
||||
} else {
|
||||
$module_values = wp_parse_args( $raw_module_value, $default_value_model );
|
||||
}
|
||||
|
||||
return $module_values;
|
||||
}
|
||||
|
||||
|
||||
// Returns an array of allowed HTML tags and attributes when securing form echoed with wp_kses()
|
||||
function sek_get_allowed_html_in_forms() {
|
||||
$allowed = array(
|
||||
'div' => array(),
|
||||
'span' => array(),
|
||||
'form' => array(
|
||||
'action' => true,
|
||||
'method' => true,
|
||||
'post' => true
|
||||
),
|
||||
'button' => array(
|
||||
'disabled' => true,
|
||||
'name' => true,
|
||||
'type' => true,
|
||||
'value' => true,
|
||||
),
|
||||
'input' => array(
|
||||
'alt' => true,
|
||||
'capture' => true,
|
||||
'checked' => true,
|
||||
'disabled' => true,
|
||||
'list' => true,
|
||||
'name' => true,
|
||||
'placeholder' => true,
|
||||
'readonly' => true,
|
||||
'type' => true,
|
||||
'value' => true,
|
||||
),
|
||||
'label' => array(
|
||||
'for' => true,
|
||||
),
|
||||
'textarea' => array(
|
||||
'cols' => true,
|
||||
'disabled' => true,
|
||||
'maxlength' => true,
|
||||
'minlength' => true,
|
||||
'name' => true,
|
||||
'placeholder' => true,
|
||||
'readonly' => true,
|
||||
'rows' => true,
|
||||
'spellcheck' => true,
|
||||
'wrap' => true,
|
||||
),
|
||||
);
|
||||
|
||||
$allowed = array_map(
|
||||
function ($to_map) {
|
||||
$attr = array(
|
||||
'aria-checked' => true,
|
||||
'aria-describedby' => true,
|
||||
'aria-details' => true,
|
||||
'aria-disabled' => true,
|
||||
'aria-hidden' => true,
|
||||
'aria-invalid' => true,
|
||||
'aria-label' => true,
|
||||
'aria-labelledby' => true,
|
||||
'aria-live' => true,
|
||||
'aria-relevant' => true,
|
||||
'aria-required' => true,
|
||||
'aria-selected' => true,
|
||||
'class' => true,
|
||||
'data-*' => true,
|
||||
'id' => true,
|
||||
'inputmode' => true,
|
||||
'role' => true,
|
||||
'style' => true,
|
||||
'tabindex' => true,
|
||||
'title' => true,
|
||||
);
|
||||
|
||||
return array_merge( $attr, (array) $to_map );
|
||||
},
|
||||
$allowed
|
||||
);
|
||||
return $allowed;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* BREAKPOINTS HELPER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
function sek_get_global_custom_breakpoint() {
|
||||
$global_breakpoint_data = sek_get_global_option_value('breakpoint');
|
||||
if ( is_null( $global_breakpoint_data ) || empty( $global_breakpoint_data['global-custom-breakpoint'] ) )
|
||||
return;
|
||||
|
||||
if ( empty( $global_breakpoint_data[ 'use-custom-breakpoint'] ) || false === sek_booleanize_checkbox_val( $global_breakpoint_data[ 'use-custom-breakpoint'] ) )
|
||||
return;
|
||||
|
||||
return intval( $global_breakpoint_data['global-custom-breakpoint'] );
|
||||
}
|
||||
|
||||
|
||||
// @return bool
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/564
|
||||
// Let us know if we need to apply the user defined custom breakpoint to all by-device customizations, like alignment
|
||||
// false by default.
|
||||
function sek_is_global_custom_breakpoint_applied_to_all_customizations_by_device() {
|
||||
$global_breakpoint_data = sek_get_global_option_value('breakpoint');
|
||||
if ( is_null( $global_breakpoint_data ) || empty( $global_breakpoint_data['global-custom-breakpoint'] ) )
|
||||
return false;
|
||||
|
||||
if ( empty( $global_breakpoint_data[ 'use-custom-breakpoint'] ) || false === sek_booleanize_checkbox_val( $global_breakpoint_data[ 'use-custom-breakpoint'] ) )
|
||||
return false;
|
||||
|
||||
// We need a custom breakpoint > 1
|
||||
if ( intval( $global_breakpoint_data['global-custom-breakpoint'] ) <= 1 )
|
||||
return;
|
||||
|
||||
// apply-to-all option is unchecked by default
|
||||
// returns true when user has checked the apply to all option
|
||||
return array_key_exists('apply-to-all', $global_breakpoint_data ) && sek_booleanize_checkbox_val( $global_breakpoint_data[ 'apply-to-all' ] ) ;
|
||||
}
|
||||
|
||||
|
||||
// invoked when filtering 'sek_add_css_rules_for__section__options'
|
||||
// param 'for_responsive_columns' has been introduced for https://github.com/presscustomizr/nimble-builder/issues/564
|
||||
// so we can differentiate when the custom breakpoint is requested for column responsiveness or for css rules generation
|
||||
// when for columns, we always apply the custom breakpoint defined by the user
|
||||
// otherwise, when generating CSS rules like alignment, the custom breakpoint is applied if user explicitely checked the 'apply_to_all' option
|
||||
// 'for_responsive_columns' is set to true when sek_get_closest_section_custom_breakpoint() is invoked from Nimble_Manager()::render()
|
||||
// @param params array(
|
||||
// 'section_model' => array(),
|
||||
// 'for_responsive_columns' => bool
|
||||
// )
|
||||
function sek_get_section_custom_breakpoint( $params ) {
|
||||
if ( !is_array( $params ) )
|
||||
return;
|
||||
|
||||
$params = wp_parse_args( $params, array(
|
||||
'section_model' => array(),
|
||||
'for_responsive_columns' => false
|
||||
));
|
||||
|
||||
$section = $params['section_model'];
|
||||
|
||||
if ( !is_array( $section ) )
|
||||
return;
|
||||
|
||||
if ( empty($section['id']) )
|
||||
return;
|
||||
|
||||
$options = empty( $section[ 'options' ] ) ? array() : $section['options'];
|
||||
if ( empty( $options[ 'breakpoint' ] ) )
|
||||
return;
|
||||
|
||||
if ( empty( $options[ 'breakpoint' ][ 'use-custom-breakpoint'] ) || false === sek_booleanize_checkbox_val( $options[ 'breakpoint' ][ 'use-custom-breakpoint'] ) )
|
||||
return;
|
||||
|
||||
// assign default value if use-custom-breakpoint is checked but there's no breakpoint set.
|
||||
// this can also occur if the custom breakpoint is left to default in the customizer ( default values are not considered when saving )
|
||||
if ( empty( $options[ 'breakpoint' ][ 'custom-breakpoint' ] ) ) {
|
||||
if ( array_key_exists('custom-breakpoint', $options[ 'breakpoint' ] ) ) {
|
||||
// this is the case when user has emptied the setting
|
||||
$custom_breakpoint = 1;// added when fixing https://github.com/presscustomizr/nimble-builder/issues/623
|
||||
} else {
|
||||
$custom_breakpoint = Sek_Dyn_CSS_Builder::$breakpoints['md'];//768
|
||||
}
|
||||
} else {
|
||||
$custom_breakpoint = intval( $options[ 'breakpoint' ][ 'custom-breakpoint' ] );
|
||||
}
|
||||
|
||||
if ( $custom_breakpoint <= 0 )
|
||||
return 1;
|
||||
|
||||
// 1) When the breakpoint is requested for responsive columns, we always return the custom value
|
||||
if ( $params['for_responsive_columns'] )
|
||||
return $custom_breakpoint;
|
||||
|
||||
// 2) Otherwise ( other CSS rules generation case, like alignment ) we make sure that user want to apply the custom breakpoint also to other by-device customizations
|
||||
return sek_is_section_custom_breakpoint_applied_to_all_customizations_by_device( $options[ 'breakpoint' ] ) ? $custom_breakpoint : null;
|
||||
}
|
||||
|
||||
|
||||
// @return bool
|
||||
// introduced for https://github.com/presscustomizr/nimble-builder/issues/564
|
||||
// Let us know if we need to apply the user defined custom breakpoint to all by-device customizations, like alignment
|
||||
// false by default.
|
||||
// @param $section_breakpoint_options = array(
|
||||
// 'use-custom-breakpoint' => bool
|
||||
// 'custom-breakpoint' => int
|
||||
// 'apply-to-all' => bool
|
||||
// )
|
||||
function sek_is_section_custom_breakpoint_applied_to_all_customizations_by_device( $section_breakpoint_options ) {
|
||||
if ( !is_array( $section_breakpoint_options ) || empty( $section_breakpoint_options ) )
|
||||
return;
|
||||
|
||||
if ( empty( $section_breakpoint_options[ 'use-custom-breakpoint'] ) || false === sek_booleanize_checkbox_val( $section_breakpoint_options[ 'use-custom-breakpoint'] ) )
|
||||
return;
|
||||
|
||||
// We need a custom breakpoint > 1
|
||||
// Make sure the custom breakpoint has not been emptied, otherwise assign a minimal value of 1px
|
||||
// fixes : https://github.com/presscustomizr/nimble-builder/issues/623
|
||||
$custom_breakpoint = empty( $section_breakpoint_options['custom-breakpoint'] ) ? 1 : $section_breakpoint_options['custom-breakpoint'];
|
||||
if ( intval( $custom_breakpoint ) <= 1 )
|
||||
return;
|
||||
|
||||
// apply-to-all option is unchecked by default
|
||||
// returns true when user has checked the apply to all option
|
||||
return array_key_exists('apply-to-all', $section_breakpoint_options ) && sek_booleanize_checkbox_val( $section_breakpoint_options[ 'apply-to-all' ] );
|
||||
}
|
||||
|
||||
|
||||
// Recursive helper
|
||||
// Is also used when building the dyn_css or when firing sek_add_css_rules_for_spacing()
|
||||
// @param id : mandatory
|
||||
// @param collection : optional <= that's why if missing we must walk all collections : local and global
|
||||
function sek_get_closest_section_custom_breakpoint( $params ) {
|
||||
$params = wp_parse_args( $params, array(
|
||||
'searched_level_id' => '',
|
||||
'collection' => 'not_set',
|
||||
'skope_id' => '',
|
||||
|
||||
'last_section_breakpoint_found' => 0,
|
||||
'last_regular_section_breakpoint_found' => 0,
|
||||
'last_nested_section_breakpoint_found' => 0,
|
||||
|
||||
'searched_level_id_found' => false,
|
||||
|
||||
// the 'for_responsive_columns' param has been introduced for https://github.com/presscustomizr/nimble-builder/issues/564
|
||||
// so we can differentiate when the custom breakpoint is requested for column responsiveness or for css rules generation
|
||||
// when for columns, we always apply the custom breakpoint defined by the user
|
||||
// otherwise, when generating CSS rules like alignment, the custom breakpoint is applied if user explicitely checked the 'apply_to_all' option
|
||||
// 'for_responsive_columns' is set to true when sek_get_closest_section_custom_breakpoint() is invoked from Nimble_Manager()::render()
|
||||
'for_responsive_columns' => false
|
||||
) );
|
||||
|
||||
extract( $params, EXTR_OVERWRITE );
|
||||
|
||||
if ( !is_string( $searched_level_id ) || empty( $searched_level_id ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing or invalid child_level_id param.');
|
||||
return $last_section_breakpoint_found;;
|
||||
}
|
||||
if ( $searched_level_id_found ) {
|
||||
return $last_section_breakpoint_found;
|
||||
}
|
||||
|
||||
// When no collection is provided, we must walk all collections, local and global.
|
||||
if ( 'not_set' === $collection ) {
|
||||
if ( empty( $skope_id ) ) {
|
||||
if ( is_array( $_POST ) && !empty( $_POST['location_skope_id'] ) ) {
|
||||
$skope_id = sanitize_text_field($_POST['location_skope_id']);
|
||||
} else {
|
||||
// When fired during an ajax 'customize_save' action, the skp_get_skope_id() is determined with $_POST['local_skope_id']
|
||||
// @see add_filter( 'skp_get_skope_id', '\Nimble\sek_filter_skp_get_skope_id', 10, 2 );
|
||||
$skope_id = skp_get_skope_id();
|
||||
}
|
||||
}
|
||||
if ( empty( $skope_id ) || '_skope_not_set_' === $skope_id ) {
|
||||
sek_error_log( __FUNCTION__ . ' => the skope_id should not be empty.');
|
||||
}
|
||||
$local_skope_settings = sek_get_skoped_seks( $skope_id );
|
||||
$local_collection = ( is_array( $local_skope_settings ) && !empty( $local_skope_settings['collection'] ) ) ? $local_skope_settings['collection'] : array();
|
||||
$global_skope_settings = sek_get_skoped_seks( NIMBLE_GLOBAL_SKOPE_ID );
|
||||
$global_collection = ( is_array( $global_skope_settings ) && !empty( $global_skope_settings['collection'] ) ) ? $global_skope_settings['collection'] : array();
|
||||
|
||||
$collection = array_merge( $local_collection, $global_collection );
|
||||
}
|
||||
|
||||
// Loop collections
|
||||
foreach ( $collection as $level_data ) {
|
||||
//sek_error_log($last_section_breakpoint_found . ' MATCH ? => LEVEL ID AND TYPE => ' . $level_data['level'] . ' | ' . $level_data['id'] );
|
||||
// stop here and return if a match was recursively found
|
||||
if ( $searched_level_id_found )
|
||||
break;
|
||||
|
||||
if ( 'section' == $level_data['level'] ) {
|
||||
$section_maybe_custom_breakpoint = intval( sek_get_section_custom_breakpoint( array( 'section_model' => $level_data, 'for_responsive_columns' => $for_responsive_columns ) ) );
|
||||
|
||||
if ( !empty( $level_data['is_nested'] ) && $level_data['is_nested'] ) {
|
||||
$last_nested_section_breakpoint_found = $section_maybe_custom_breakpoint;
|
||||
} else {
|
||||
$last_nested_section_breakpoint_found = 0;//reset last nested breakpoint
|
||||
$last_regular_section_breakpoint_found = $section_maybe_custom_breakpoint;
|
||||
}
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'id', $level_data ) && $searched_level_id == $level_data['id'] ) {
|
||||
//match found, break this loop
|
||||
if ( $last_nested_section_breakpoint_found >= 1 ) {
|
||||
$last_section_breakpoint_found = $last_nested_section_breakpoint_found;
|
||||
} else if ( $last_regular_section_breakpoint_found >= 1 ) {
|
||||
$last_section_breakpoint_found = $last_regular_section_breakpoint_found;
|
||||
} else {
|
||||
$last_section_breakpoint_found = 0;
|
||||
}
|
||||
|
||||
$searched_level_id_found = true;
|
||||
break;
|
||||
}
|
||||
if ( !$searched_level_id_found && array_key_exists( 'collection', $level_data ) && is_array( $level_data['collection'] ) ) {
|
||||
$collection = $level_data['collection'];
|
||||
|
||||
$recursive_params = compact(
|
||||
'searched_level_id',
|
||||
'collection',
|
||||
'skope_id',
|
||||
'last_section_breakpoint_found',
|
||||
'last_regular_section_breakpoint_found',
|
||||
'last_nested_section_breakpoint_found',
|
||||
'searched_level_id_found',
|
||||
'for_responsive_columns'
|
||||
);
|
||||
$recursive_values = sek_get_closest_section_custom_breakpoint( $recursive_params );
|
||||
|
||||
if ( is_array($recursive_values) ) {
|
||||
extract( $recursive_values );
|
||||
} else {
|
||||
$last_section_breakpoint_found = $recursive_values;
|
||||
$searched_level_id_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a breakpoint int if found or an array
|
||||
// => this way we can determine if we continue or not to walk recursively
|
||||
return $searched_level_id_found ? $last_section_breakpoint_found : compact(
|
||||
'searched_level_id_found',
|
||||
'last_section_breakpoint_found',
|
||||
'last_regular_section_breakpoint_found',
|
||||
'last_nested_section_breakpoint_found'
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* LOCAL OPTIONS HELPERS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @param $option_name = string
|
||||
// 'nimble_front_classes_ready' is fired when Nimble_Manager() is instanciated
|
||||
function sek_get_local_option_value( $option_name = '', $skope_id = null ) {
|
||||
if ( empty($option_name) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid option name' );
|
||||
return array();
|
||||
}
|
||||
if ( !skp_is_customizing() && did_action('nimble_front_classes_ready') && '_not_cached_yet_' !== Nimble_Manager()->local_options ) {
|
||||
$local_options = Nimble_Manager()->local_options;
|
||||
} else {
|
||||
// use the provided skope_id if in the signature
|
||||
$skope_id = ( !empty( $skope_id ) && is_string( $skope_id ))? $skope_id : skp_get_skope_id();
|
||||
$localSkopeNimble = sek_get_skoped_seks( $skope_id );
|
||||
$local_options = ( is_array( $localSkopeNimble ) && !empty( $localSkopeNimble['local_options'] ) && is_array( $localSkopeNimble['local_options'] ) ) ? $localSkopeNimble['local_options'] : array();
|
||||
// Cache only after 'wp' && 'nimble_front_classes_ready'
|
||||
// never cache when doing ajax
|
||||
if ( did_action('nimble_front_classes_ready') && did_action('wp') && !defined('DOING_AJAX') ) {
|
||||
Nimble_Manager()->local_options = $local_options;
|
||||
}
|
||||
}
|
||||
// maybe normalizes with default values
|
||||
$values = ( !empty( $local_options ) && !empty( $local_options[ $option_name ] ) ) ? $local_options[ $option_name ] : null;
|
||||
if ( did_action('nimble_front_classes_ready') ) {
|
||||
$values = sek_normalize_local_options_with_defaults( $option_name, $values );
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
// Introduced for site templates, when using function sek_is_inheritance_locally_disabled()
|
||||
// needed because we can't rely on sek_get_skoped_seks() to get current local sections data, because this function returns the inherited data
|
||||
// @param $option_name = string
|
||||
// 'nimble_front_classes_ready' is fired when Nimble_Manager() is instanciated
|
||||
function sek_get_local_option_value_without_inheritance( $option_name = '', $skope_id = null ) {
|
||||
if ( empty($option_name) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid option name' );
|
||||
return array();
|
||||
}
|
||||
if ( !skp_is_customizing() && did_action('nimble_front_classes_ready') && '_not_cached_yet_' !== Nimble_Manager()->local_options_without_tmpl_inheritance ) {
|
||||
$local_options_without_tmpl_inheritance = Nimble_Manager()->local_options_without_tmpl_inheritance;
|
||||
} else {
|
||||
// use the provided skope_id if in the signature
|
||||
$skope_id = ( !empty( $skope_id ) && is_string( $skope_id ))? $skope_id : skp_get_skope_id();
|
||||
$localSkopeNimble = sek_get_seks_without_group_inheritance( $skope_id );
|
||||
if ( skp_is_customizing() && NIMBLE_GLOBAL_SKOPE_ID != $skope_id ) {
|
||||
// when customizing, let us filter the value with the 'customized' ones
|
||||
$localSkopeNimble = apply_filters(
|
||||
'sek_get_skoped_seks',
|
||||
$localSkopeNimble,
|
||||
$skope_id,
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
$local_options_without_tmpl_inheritance = ( is_array( $localSkopeNimble ) && !empty( $localSkopeNimble['local_options'] ) && is_array( $localSkopeNimble['local_options'] ) ) ? $localSkopeNimble['local_options'] : array();
|
||||
// Cache only after 'wp' && 'nimble_front_classes_ready'
|
||||
// never cache when doing ajax
|
||||
if ( did_action('nimble_front_classes_ready') && did_action('wp') && !defined('DOING_AJAX') ) {
|
||||
Nimble_Manager()->local_options_without_tmpl_inheritance = $local_options_without_tmpl_inheritance;
|
||||
}
|
||||
}
|
||||
// maybe normalizes with default values
|
||||
$values = ( !empty( $local_options_without_tmpl_inheritance ) && !empty( $local_options_without_tmpl_inheritance[ $option_name ] ) ) ? $local_options_without_tmpl_inheritance[ $option_name ] : null;
|
||||
if ( did_action('nimble_front_classes_ready') ) {
|
||||
$values = sek_normalize_local_options_with_defaults( $option_name, $values );
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
|
||||
// @return array() $normalized_values
|
||||
// @see _1_6_4_sektions_generate_UI_local_skope_options.js
|
||||
function sek_normalize_local_options_with_defaults( $option_name, $raw_module_values ) {
|
||||
if ( empty($option_name) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid option name' );
|
||||
return array();
|
||||
}
|
||||
$normalized_values = ( !empty($raw_module_values) && is_array( $raw_module_values ) ) ? $raw_module_values : array();
|
||||
// map the option key as saved in db ( @see _1_6_4_sektions_generate_UI_local_skope_options.js ) and the module type
|
||||
$local_option_map = SEK_Front_Construct::$local_options_map;
|
||||
|
||||
if ( !array_key_exists($option_name, $local_option_map) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid option name', $option_name );
|
||||
return $raw_module_values;
|
||||
} else {
|
||||
$module_type = $local_option_map[$option_name];
|
||||
}
|
||||
|
||||
// normalize with the defaults
|
||||
// class_exists check introduced since https://github.com/presscustomizr/nimble-builder/issues/432
|
||||
// may not be mandatory
|
||||
if ( class_exists('\Nimble\CZR_Fmk_Base') ) {
|
||||
if( CZR_Fmk_Base()->czr_is_module_registered($module_type) ) {
|
||||
$normalized_values = _sek_normalize_single_module_values( $normalized_values, $module_type );
|
||||
}
|
||||
}
|
||||
return $normalized_values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* GLOBAL OPTIONS HELPERS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @param $option_name = string
|
||||
// 'nimble_front_classes_ready' is fired when Nimble_Manager() is instanciated
|
||||
function sek_get_global_option_value( $option_name = '' ) {
|
||||
if ( empty($option_name) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid option name' );
|
||||
return array();
|
||||
}
|
||||
if ( !skp_is_customizing() && did_action('nimble_front_classes_ready') && '_not_cached_yet_' !== Nimble_Manager()->global_nimble_options ) {
|
||||
$global_nimble_options = Nimble_Manager()->global_nimble_options;
|
||||
} else {
|
||||
$global_nimble_options = get_option( NIMBLE_OPT_NAME_FOR_GLOBAL_OPTIONS );
|
||||
//sek_error_log(' SOOO OPTIONS ?', $global_nimble_options );
|
||||
// cache when nimble is ready
|
||||
// this hook is fired when Nimble_Manager() is instanciated
|
||||
// never cache when doing ajax
|
||||
if ( did_action('nimble_front_classes_ready') && !defined('DOING_AJAX') ) {
|
||||
Nimble_Manager()->global_nimble_options = $global_nimble_options;
|
||||
}
|
||||
}
|
||||
// maybe normalizes with default values
|
||||
$values = ( is_array( $global_nimble_options ) && !empty( $global_nimble_options[ $option_name ] ) ) ? $global_nimble_options[ $option_name ] : null;
|
||||
if ( did_action('nimble_front_classes_ready') ) {
|
||||
$values = sek_normalize_global_options_with_defaults( $option_name, $values );
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
|
||||
// @see _1_6_5_sektions_generate_UI_global_options.js
|
||||
// @return array() $normalized_values
|
||||
function sek_normalize_global_options_with_defaults( $option_name, $raw_module_values ) {
|
||||
if ( empty($option_name) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid option name' );
|
||||
return array();
|
||||
}
|
||||
$normalized_values = ( !empty($raw_module_values) && is_array( $raw_module_values ) ) ? $raw_module_values : array();
|
||||
// map the option key as saved in db ( @see _1_6_5_sektions_generate_UI_global_options.js ) and the module type
|
||||
$global_option_map = SEK_Front_Construct::$global_options_map;
|
||||
|
||||
//sek_error_log('SEK_Front_Construct::$global_options_map', SEK_Front_Construct::$global_options_map );
|
||||
|
||||
if ( !array_key_exists($option_name, $global_option_map) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid option name', $option_name );
|
||||
return $raw_module_values;
|
||||
} else {
|
||||
$module_type = $global_option_map[$option_name];
|
||||
}
|
||||
|
||||
// normalize with the defaults
|
||||
// class_exists check introduced since https://github.com/presscustomizr/nimble-builder/issues/432
|
||||
// may not be mandatory
|
||||
if ( class_exists('\Nimble\CZR_Fmk_Base') ) {
|
||||
if( CZR_Fmk_Base()->czr_is_module_registered($module_type) ) {
|
||||
$normalized_values = _sek_normalize_single_module_values( $normalized_values, $module_type );
|
||||
}
|
||||
} else {
|
||||
sek_error_log( __FUNCTION__ . ' => error => CZR_Fmk_Base not loaded' );
|
||||
}
|
||||
return $normalized_values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // @see _1_6_5_sektions_generate_UI_site_tmpl_options.js
|
||||
// // @return array() $normalized_values
|
||||
// function sek_normalize_site_tmpl_options_with_defaults( $option_name, $raw_module_values ) {
|
||||
// if ( empty($option_name) ) {
|
||||
// sek_error_log( __FUNCTION__ . ' => invalid option name' );
|
||||
// return array();
|
||||
// }
|
||||
// $normalized_values = ( !empty($raw_module_values) && is_array( $raw_module_values ) ) ? $raw_module_values : array();
|
||||
// // map the option key as saved in db ( @see _1_6_5_sektions_generate_UI_global_options.js ) and the module type
|
||||
// $site_tmpl_options_map = SEK_Front_Construct::$site_tmpl_options_map;
|
||||
|
||||
// //sek_error_log('SEK_Front_Construct::$global_options_map', SEK_Front_Construct::$global_options_map );
|
||||
|
||||
// if ( !array_key_exists($option_name, $site_tmpl_options_map) ) {
|
||||
// sek_error_log( __FUNCTION__ . ' => invalid option name', $option_name );
|
||||
// return $raw_module_values;
|
||||
// } else {
|
||||
// $module_type = $site_tmpl_options_map[$option_name];
|
||||
// }
|
||||
|
||||
// // normalize with the defaults
|
||||
// // class_exists check introduced since https://github.com/presscustomizr/nimble-builder/issues/432
|
||||
// // may not be mandatory
|
||||
// if ( class_exists('\Nimble\CZR_Fmk_Base') ) {
|
||||
// if( CZR_Fmk_Base()->czr_is_module_registered($module_type) ) {
|
||||
// $normalized_values = _sek_normalize_single_module_values( $normalized_values, $module_type );
|
||||
// }
|
||||
// } else {
|
||||
// sek_error_log( __FUNCTION__ . ' => error => CZR_Fmk_Base not loaded' );
|
||||
// }
|
||||
// return $normalized_values;
|
||||
// }
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,457 @@
|
||||
<?php
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Dynamic variables parsing
|
||||
/* ------------------------------------------------------------------------- */
|
||||
function sek_find_pattern_match($matches) {
|
||||
$replace_values = apply_filters( 'sek_template_tags', array(
|
||||
'home_url' => 'home_url',
|
||||
'year_now' => date("Y"),
|
||||
'site_title' => 'get_bloginfo',
|
||||
'the_title' => 'sek_get_the_title',
|
||||
'the_archive_title' => 'sek_get_the_archive_title',// works for authors, CPT, taxonomies
|
||||
'the_archive_description' => 'sek_get_the_archive_description',// works for authors, CPT, taxonomies
|
||||
'the_content' => 'sek_get_the_content',
|
||||
'the_tags' => 'sek_get_the_tags',
|
||||
'the_categories' => 'sek_get_the_categories',
|
||||
|
||||
'the_author_link' => 'sek_get_the_author_link',
|
||||
'the_author_name' => 'sek_get_the_author_name',
|
||||
'the_author_avatar' => 'sek_get_the_author_avatar',
|
||||
'the_author_bio' => 'sek_get_the_author_bio',
|
||||
|
||||
'the_published_date' => 'sek_get_the_published_date',
|
||||
'the_modified_date' => 'sek_get_the_modified_date',
|
||||
'the_comments' => 'sek_get_the_comments',
|
||||
'the_previous_post_link' => 'sek_get_previous_post_link',
|
||||
'the_next_post_link' => 'sek_get_next_post_link',
|
||||
'the_comment_number' => 'sek_get_the_comment_number',
|
||||
|
||||
'the_search_query' => 'sek_get_search_query',
|
||||
'the_search_results_number' => 'sek_get_search_results_nb'
|
||||
));
|
||||
|
||||
// Are we good after the filter ?
|
||||
if ( !is_array($replace_values) )
|
||||
return;
|
||||
|
||||
//sek_error_log('$matches ??', $matches );
|
||||
if ( !is_array($matches) || empty($matches[1]) )
|
||||
return;
|
||||
|
||||
//$data = html_entity_decode($matches[1], ENT_QUOTES, get_bloginfo( 'charset' ) );
|
||||
$data = explode(' ', $matches[1] );
|
||||
|
||||
// Filter so that {{the_categories sep="/"}} becomes array('the_categories', 'sep="/"' ) with no empty entries
|
||||
// => the first entry is the template tag name, the other entries are the callback arguments ( to implement April 2021 )
|
||||
$new_data = array_filter($data, function($value) {
|
||||
if ( !is_string($value) )
|
||||
return false;
|
||||
$value = ltrim($value);
|
||||
return !is_null($value) && !empty($value) && preg_match("/[a-z]/i", $value) ;
|
||||
});
|
||||
|
||||
if ( isset($new_data[0]) && array_key_exists( $new_data[0], $replace_values ) ) {
|
||||
// @todo => authorize arguments passed as an array
|
||||
$dyn_content = $replace_values[$new_data[0]];
|
||||
$fn_name = $dyn_content;// <= typically not namespaced if WP core function, or function added with a filter from a child theme for example
|
||||
$namespaced_fn_name = __NAMESPACE__ . '\\' . $dyn_content; // <= namespaced if Nimble Builder function, introduced in october 2019 for https://github.com/presscustomizr/nimble-builder/issues/401
|
||||
if ( function_exists( $namespaced_fn_name ) ) {
|
||||
return $namespaced_fn_name();//<= @TODO use call_user_func() here + handle the case when the callback is a method
|
||||
} else if ( function_exists( $fn_name ) ) {
|
||||
return $fn_name();//<= @TODO use call_user_func() here + handle the case when the callback is a method
|
||||
} else if ( is_string($dyn_content) ) {
|
||||
return $dyn_content;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// fired @filter 'nimble_parse_template_tags'
|
||||
function sek_parse_template_tags( $val ) {
|
||||
//the pattern could also be '!\{\{(\w+)\}\}!', but adding \s? allows us to allow spaces around the term inside curly braces
|
||||
//see https://stackoverflow.com/questions/959017/php-regex-templating-find-all-occurrences-of-var#comment71815465_959026
|
||||
//return is_string( $val ) ? preg_replace_callback( '!\{\{\s?(\w+)\s?\}\}!', '\Nimble\sek_find_pattern_match', $val) : $val;
|
||||
return is_string( $val ) ? preg_replace_callback( '!\{\{\s?(.*?)\s?\}\}!', '\Nimble\sek_find_pattern_match', $val) : $val;
|
||||
}
|
||||
add_filter( 'nimble_parse_template_tags', '\Nimble\sek_parse_template_tags' );
|
||||
|
||||
|
||||
|
||||
|
||||
// CALLBACKS WHEN IS_ARCHIVE()
|
||||
function sek_get_the_archive_title() {
|
||||
$is_archive = is_archive();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_archive = sek_get_posted_query_param_when_customizing( 'is_archive' );
|
||||
}
|
||||
if ( !$is_archive ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_archive_title', $msg = __('It can be used in archive pages only.', 'text_doma') );
|
||||
}
|
||||
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$title = sek_get_posted_query_param_when_customizing( 'the_archive_title' );
|
||||
} else {
|
||||
add_filter('get_the_archive_title_prefix', '__return_false');
|
||||
$title = get_the_archive_title();
|
||||
remove_filter('get_the_archive_title_prefix', '__return_false');
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
function sek_get_the_archive_description() {
|
||||
$is_archive = is_archive();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_archive = sek_get_posted_query_param_when_customizing( 'is_archive' );
|
||||
}
|
||||
if ( !$is_archive ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_archive_description', $msg = __('It can be used in archive pages only.', 'text_doma') );
|
||||
}
|
||||
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$title = sek_get_posted_query_param_when_customizing( 'the_archive_description' );
|
||||
} else {
|
||||
$title = get_the_archive_description();
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
|
||||
// CALLBACKS WHEN IS_SINGULAR()
|
||||
function sek_get_next_post_link() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_next_post_link', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$title = sek_get_posted_query_param_when_customizing( 'the_next_post_link' );
|
||||
} else {
|
||||
$title = get_next_post_link( $format = '%link' );
|
||||
}
|
||||
if ( empty( $title ) ) {
|
||||
return '';
|
||||
} else {
|
||||
return sprintf( '<span class="sek-next-post-link">%1$s</span>', $title );
|
||||
}
|
||||
}
|
||||
|
||||
function sek_get_previous_post_link() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_previous_post_link', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$title = sek_get_posted_query_param_when_customizing( 'the_previous_post_link' );
|
||||
} else {
|
||||
$title = get_previous_post_link( $format = '%link' );
|
||||
}
|
||||
if ( empty( $title ) ) {
|
||||
return '';
|
||||
} else {
|
||||
return sprintf( '<span class="sek-previous-post-link">%1$s</span>', $title );
|
||||
}
|
||||
}
|
||||
|
||||
function sek_get_the_comments() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_comments', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
return sprintf('<div class="nimble-notice-in-preview"><i class="fas fa-info-circle"></i> %1$s</div>',
|
||||
__('Comment template can not be refreshed while customizing', 'text_doma')
|
||||
);
|
||||
}
|
||||
|
||||
ob_start();
|
||||
//load_template( $tmpl_path, false );
|
||||
if ( comments_open() || get_comments_number() ) {
|
||||
add_filter('comments_template', '\Nimble\sek_set_nb_comments_template_path');
|
||||
comments_template();
|
||||
remove_filter('comments_template', '\Nimble\sek_set_nb_comments_template_path');
|
||||
}
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
//@filter 'comments_template'
|
||||
function sek_set_nb_comments_template_path( $original_path ) {
|
||||
//@to do => make this path overridable
|
||||
$nb_path = sek_get_templates_dir() . "/wp/comments-template.php";
|
||||
if ( file_exists( $nb_path ) ) {
|
||||
return $nb_path;
|
||||
}
|
||||
return $original_path;
|
||||
}
|
||||
|
||||
function sek_get_the_published_date() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_published_date', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
$post_id = sek_get_post_id_on_front_and_when_customizing();
|
||||
$published_date = get_the_date( get_option('date_format'), $post_id);
|
||||
$machine_readable_published_date = esc_attr( get_the_date( 'c' , $post_id ) );
|
||||
return sprintf( '<time class="sek-published-date" datetime="%1$s">%2$s</time>',
|
||||
$machine_readable_published_date,
|
||||
$published_date
|
||||
);
|
||||
}
|
||||
|
||||
function sek_get_the_modified_date() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_modified_date', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
$post_id = sek_get_post_id_on_front_and_when_customizing();
|
||||
$modified_date = get_the_modified_date( get_option('date_format'), $post_id );
|
||||
$machine_readable_modified_date = esc_attr( get_the_modified_date( 'c' ), $post_id );
|
||||
return sprintf( '<time class="sek-modified-date" datetime="%1$s">%2$s</time>',
|
||||
$machine_readable_modified_date ,
|
||||
$modified_date
|
||||
);
|
||||
}
|
||||
|
||||
function sek_get_the_tags( $separator = ' · ') {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_tags', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
return sprintf( '<span class="sek-post-tags">%1$s</span>', get_the_tag_list( $before = '', $sep = $separator, $after = '', $post_id = sek_get_post_id_on_front_and_when_customizing() ) );
|
||||
}
|
||||
|
||||
|
||||
function sek_get_the_categories( $separator = ' / ') {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_categories', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
return sprintf( '<span class="sek-post-category">%1$s</span>', get_the_category_list( $separator, '', $post_id = sek_get_post_id_on_front_and_when_customizing() ) );
|
||||
}
|
||||
|
||||
function sek_get_the_comment_number() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_comment_number', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
return sprintf( '<span class="sek-post-comment-number">%1$s</span>', get_comments_number_text( $zero = false, $one = false, $more = false, $post_id = sek_get_post_id_on_front_and_when_customizing() ) );
|
||||
}
|
||||
|
||||
|
||||
// AUTHOR DATA
|
||||
// 2 CASES : singular or author archives
|
||||
function sek_get_the_author_link() {
|
||||
$author_id = sek_get_author_id_on_front_and_when_customizing();
|
||||
if ( $author_id ) {
|
||||
$display_name = get_the_author_meta( 'display_name', $author_id );
|
||||
return sprintf(
|
||||
'<a href="%1$s" title="%2$s" class="sek-author-link" rel="author">%3$s</a>',
|
||||
esc_url( get_author_posts_url( $author_id, get_the_author_meta( 'user_nicename', $author_id ) ) ),
|
||||
/* translators: %s: Author's display name. */
|
||||
esc_attr( sprintf( __( 'Posts by %s' ), $display_name ) ),
|
||||
$display_name
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function sek_get_the_author_name() {
|
||||
$author_id = sek_get_author_id_on_front_and_when_customizing();
|
||||
if ( $author_id ) {
|
||||
return sprintf( '<span class="sek-author-name">%1$s</span>', get_the_author_meta( 'display_name', $author_id ) );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function sek_get_the_author_avatar() {
|
||||
$author_id = sek_get_author_id_on_front_and_when_customizing();
|
||||
if ( $author_id ) {
|
||||
return get_avatar( get_the_author_meta( 'ID', $author_id ), '85' );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function sek_get_the_author_bio() {
|
||||
$author_id = sek_get_author_id_on_front_and_when_customizing();
|
||||
if ( $author_id ) {
|
||||
return sprintf( '<span class="sek-author-description">%1$s</span>', get_the_author_meta( 'description', $author_id ) );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// introduced in october 2019 for https://github.com/presscustomizr/nimble-builder/issues/401
|
||||
function sek_get_the_title() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_title', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
return get_the_title( sek_get_post_id_on_front_and_when_customizing() );
|
||||
}
|
||||
|
||||
// introduced in october 2019 for https://github.com/presscustomizr/nimble-builder/issues/401
|
||||
function sek_get_the_content() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( !$is_singular ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_content', $msg = __('It can only be used in single pages or single posts.', 'text_doma') );
|
||||
}
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$post_id = (int)sek_get_posted_query_param_when_customizing( 'post_id' );
|
||||
if ( is_int($post_id) ) {
|
||||
$post_object = get_post( $post_id );
|
||||
return !empty( $post_object ) ? apply_filters( 'the_content', $post_object->post_content ) : null;
|
||||
}
|
||||
} else {
|
||||
$post_object = get_post();
|
||||
return !empty( $post_object ) ? apply_filters( 'the_content', $post_object->post_content ) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// CALLBACKS WHEN IS_SEARCH()
|
||||
function sek_get_search_query() {
|
||||
$is_search = is_search();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_search = sek_get_posted_query_param_when_customizing( 'is_search' );
|
||||
$search_query = sek_get_posted_query_param_when_customizing( 'the_search_query' );
|
||||
} else {
|
||||
$search_query = get_search_query();
|
||||
}
|
||||
if ( !$is_search ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_search_query', $msg = __('It can only be used in search results page.', 'text_doma') );
|
||||
}
|
||||
return sprintf( '<span class="sek-search-query">%1$s</span>', esc_html( $search_query ) );
|
||||
}
|
||||
|
||||
function sek_get_search_results_nb() {
|
||||
$is_search = is_search();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_search = sek_get_posted_query_param_when_customizing( 'is_search' );
|
||||
$search_res_nb = sek_get_posted_query_param_when_customizing( 'the_search_results_nb' );
|
||||
} else {
|
||||
global $wp_query;
|
||||
$search_res_nb = (int)$wp_query->found_posts;
|
||||
}
|
||||
if ( !$is_search ) {
|
||||
return sek_get_tmpl_tag_error( $tag = 'the_search_results_number', $msg = __('It can only be used in search results page.', 'text_doma') );
|
||||
}
|
||||
return sprintf( '<span class="sek-search-results-number">%1$s</span>', esc_html( $search_res_nb ) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
///// HELPERS
|
||||
/////////////////////////////////////////////////
|
||||
function sek_get_author_id_on_front_and_when_customizing() {
|
||||
$is_singular = is_singular();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$is_singular = sek_get_posted_query_param_when_customizing( 'is_singular' );
|
||||
}
|
||||
if ( $is_singular ) {
|
||||
$post_id = sek_get_post_id_on_front_and_when_customizing();
|
||||
$post_object = get_post( $post_id );
|
||||
if ( empty( $post_object ) || !is_object( $post_object ) ) {
|
||||
$author_id = null;
|
||||
}
|
||||
$author_id = $post_object->post_author;
|
||||
} else {
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$author_id = sek_get_posted_query_param_when_customizing( 'the_author_id' );
|
||||
} else {
|
||||
global $authordata;
|
||||
$author_id = isset( $authordata->ID ) ? $authordata->ID : 0;
|
||||
}
|
||||
}
|
||||
return $author_id;
|
||||
}
|
||||
|
||||
// @return the post id in all cases
|
||||
// when performing ajax action, we need the posted query params made available from the ajax params
|
||||
function sek_get_post_id_on_front_and_when_customizing() {
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX && skp_is_customizing() ) {
|
||||
$post_id = (int)sek_get_posted_query_param_when_customizing( 'post_id' );
|
||||
} else {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
return is_int($post_id) ? $post_id : null;
|
||||
}
|
||||
|
||||
// recursively sanitize an array of posted ($_POST) query_params to be used when customzing
|
||||
// @param params (array)
|
||||
function sek_sanitize_query_params_array( $params = array()) {
|
||||
foreach ($params as $prm => $val) {
|
||||
if ( is_array($val) ) {
|
||||
if ( empty($val) ) {
|
||||
$sanitized_query_params[$prm] = [];
|
||||
} else {
|
||||
$sanitized_query_params[$prm] = sek_sanitize_query_params_array($params);
|
||||
}
|
||||
} else {
|
||||
$sanitized_query_params[$prm] = sanitize_text_field($val);
|
||||
}
|
||||
}
|
||||
return $sanitized_query_params;
|
||||
}
|
||||
|
||||
|
||||
// introduced in october 2019 for https://github.com/presscustomizr/nimble-builder/issues/401
|
||||
// Possible params as of October 2019
|
||||
// @see inc/czr-skope/_dev/1_1_0_skop_customizer_preview_load_assets.php::
|
||||
// 'is_singular' => $wp_query->is_singular,
|
||||
// 'post_id' => get_the_ID()
|
||||
function sek_get_posted_query_param_when_customizing( $param ) {
|
||||
if ( isset( $_POST['czr_query_params'] ) ) {
|
||||
$query_params = json_decode( wp_unslash( $_POST['czr_query_params'] ), true );
|
||||
if ( array_key_exists( $param, $query_params ) ) {
|
||||
if ( !is_array($query_params[$param]) ) {
|
||||
return sanitize_text_field($query_params[$param]);
|
||||
} else {
|
||||
return sek_sanitize_query_params_array($query_params[$param]);
|
||||
}
|
||||
} else {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid param requested');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function sek_get_tmpl_tag_error( $tag, $msg ) {
|
||||
if ( !skp_is_customizing() )
|
||||
return;
|
||||
return sprintf('<div class="nimble-notice-in-preview nimble-inline-notice-in-preview"><i class="fas fa-info-circle"></i> %1$s %2$s</div>',
|
||||
'{{' . $tag . '}} ' . __('could not be printed.', 'text_doma'),
|
||||
$msg
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* TEMPLATE OVERRIDE HELPERS
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// TEMPLATES PATH
|
||||
// added for #532, october 2019
|
||||
/**
|
||||
* Returns the path to the NIMBLE templates directory
|
||||
* inspîred from /wp-content/plugins/easy-digital-downloads/includes/template-functions.php
|
||||
*/
|
||||
function sek_get_templates_dir() {
|
||||
return NIMBLE_BASE_PATH . "/tmpl";
|
||||
}
|
||||
|
||||
// added for #532, october 2019
|
||||
/* Returns the template directory name.
|
||||
* inspîred from /wp-content/plugins/easy-digital-downloads/includes/template-functions.php
|
||||
*/
|
||||
function sek_get_theme_template_dir_name() {
|
||||
return trailingslashit( apply_filters( 'nimble_templates_dir', 'nimble_templates' ) );
|
||||
}
|
||||
|
||||
|
||||
// added for #532, october 2019
|
||||
/**
|
||||
* Returns a list of paths to check for template locations
|
||||
* inspîred from /wp-content/plugins/easy-digital-downloads/includes/template-functions.php
|
||||
*/
|
||||
function sek_get_theme_template_base_paths() {
|
||||
|
||||
$template_dir = sek_get_theme_template_dir_name();
|
||||
|
||||
$file_paths = array(
|
||||
1 => trailingslashit( get_stylesheet_directory() ) . $template_dir,
|
||||
10 => trailingslashit( get_template_directory() ) . $template_dir
|
||||
);
|
||||
|
||||
$file_paths = apply_filters( 'nimble_template_paths', $file_paths );
|
||||
|
||||
// sort the file paths based on priority
|
||||
ksort( $file_paths, SORT_NUMERIC );
|
||||
|
||||
return array_map( 'trailingslashit', $file_paths );
|
||||
}
|
||||
|
||||
|
||||
// @return path string
|
||||
// added for #400
|
||||
// @param params = array(
|
||||
// 'file_name' string 'nimble_template.php',
|
||||
// 'folder' => string 'page-templates', 'header', 'footer'
|
||||
// )
|
||||
// @param
|
||||
function sek_maybe_get_overriden_local_template_path( $params = array() ) {
|
||||
if ( empty( $params ) || !is_array( $params ))
|
||||
return;
|
||||
$params = wp_parse_args( $params, array( 'file_name' => '', 'folder' => 'page-templates' ) );
|
||||
|
||||
if ( !in_array( $params['folder'] , array( 'page-templates', 'header', 'footer' ) ) )
|
||||
return;
|
||||
|
||||
$overriden_template_path = '';
|
||||
// try locating this template file by looping through the template paths
|
||||
// inspîred from /wp-content/plugins/easy-digital-downloads/includes/template-functions.php
|
||||
foreach( sek_get_theme_template_base_paths() as $path_candidate ) {
|
||||
if( file_exists( $path_candidate . $params['folder'] . '/' . $params['file_name'] ) ) {
|
||||
$overriden_template_path = $path_candidate . $params['folder'] . '/' . $params['file_name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $overriden_template_path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @return mixed null || string
|
||||
function sek_get_locale_template(){
|
||||
$template_path = null;
|
||||
$local_template_data = sek_get_local_option_value( 'template' );
|
||||
if ( !empty( $local_template_data ) && !empty( $local_template_data['local_template'] ) && 'default' !== $local_template_data['local_template'] ) {
|
||||
$template_file_name = $local_template_data['local_template'];
|
||||
$template_file_name_with_php_extension = $template_file_name . '.php';
|
||||
|
||||
// Set the default template_path first
|
||||
$template_path = sek_get_templates_dir() . "/page-templates/{$template_file_name_with_php_extension}";
|
||||
// Make this filtrable
|
||||
// (this filter is used in Hueman theme to assign a specific template)
|
||||
$template_path = apply_filters( 'nimble_get_locale_template_path', $template_path, $template_file_name );
|
||||
|
||||
// Use an override if any
|
||||
// Default page tmpl path looks like : NIMBLE_BASE_PATH . "/tmpl/page-template/nimble_template.php",
|
||||
$overriden_template_path = sek_maybe_get_overriden_local_template_path( array( 'file_name' => $template_file_name_with_php_extension, 'folder' => 'page-templates' ) );
|
||||
if ( !empty( $overriden_template_path ) ) {
|
||||
$template_path = $overriden_template_path;
|
||||
}
|
||||
|
||||
if ( !file_exists( $template_path ) ) {
|
||||
sek_error_log( __FUNCTION__ .' the custom template does not exist', $template_path );
|
||||
$template_path = null;
|
||||
}
|
||||
}
|
||||
return $template_path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* HEADER FOOTER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// fired by sek_maybe_set_local_nimble_footer() @get_footer()
|
||||
// fired by sek_maybe_set_local_nimble_header() @get_header()
|
||||
function sek_page_uses_nimble_header_footer() {
|
||||
// cache the properties if not done yet
|
||||
Nimble_Manager()->sek_maybe_set_nimble_header_footer();
|
||||
return true === Nimble_Manager()->has_local_header_footer || true === Nimble_Manager()->has_global_header_footer;
|
||||
}
|
||||
|
||||
|
||||
// DEPRECATED SINCE Nimble v1.3.0, november 2018
|
||||
// was used in the Hueman theme before version 3.4.9
|
||||
function render_content_sections_for_nimble_template() {
|
||||
Nimble_Manager()->render_nimble_locations(
|
||||
array_keys( Nimble_Manager()->default_locations ),//array( 'loop_start', 'before_content', 'after_content', 'loop_end'),
|
||||
array( 'fallback_location' => 'loop_start' )
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
// Recursively walk the level tree until a match is found
|
||||
// @param id = the id of the level for which the model shall be returned
|
||||
// @param $collection = sek_get_skoped_seks( $skope_id )['collection']; <= the root collection must always be provided, so we are sure it's
|
||||
function sek_get_level_model( $id, $collection = array() ) {
|
||||
$_data = 'no_match';
|
||||
if ( !is_array( $collection ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid collection param when getting model for id : ' . $id );
|
||||
return $_data;
|
||||
}
|
||||
foreach ( $collection as $level_data ) {
|
||||
// stop here and return if a match was recursively found
|
||||
if ( 'no_match' != $_data )
|
||||
break;
|
||||
if ( array_key_exists( 'id', $level_data ) && $id === $level_data['id'] ) {
|
||||
$_data = $level_data;
|
||||
} else {
|
||||
if ( array_key_exists( 'collection', $level_data ) && is_array( $level_data['collection'] ) ) {
|
||||
$_data = sek_get_level_model( $id, $level_data['collection'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $_data;
|
||||
}
|
||||
|
||||
// Recursive helper
|
||||
// Typically used when ajaxing
|
||||
// Is also used when building the dyn_css or when firing sek_add_css_rules_for_spacing()
|
||||
// @param id : mandatory
|
||||
// @param collection : optional <= that's why if missing we must walk all collections : local and global
|
||||
function sek_get_parent_level_model( $child_level_id = '', $collection = array(), $skope_id = '' ) {
|
||||
$_parent_level_data = 'no_match';
|
||||
if ( !is_string( $child_level_id ) || empty( $child_level_id ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing or invalid child_level_id param.');
|
||||
return $_parent_level_data;
|
||||
}
|
||||
|
||||
// When no collection is provided, we must walk all collections, local and global.
|
||||
if ( empty( $collection ) ) {
|
||||
if ( empty( $skope_id ) ) {
|
||||
if ( is_array( $_POST ) && !empty( $_POST['location_skope_id'] ) ) {
|
||||
$skope_id = sanitize_text_field($_POST['location_skope_id']);
|
||||
} else {
|
||||
// When fired during an ajax 'customize_save' action, the skp_get_skope_id() is determined with $_POST['local_skope_id']
|
||||
// @see add_filter( 'skp_get_skope_id', '\Nimble\sek_filter_skp_get_skope_id', 10, 2 );
|
||||
$skope_id = skp_get_skope_id();
|
||||
}
|
||||
}
|
||||
if ( empty( $skope_id ) || '_skope_not_set_' === $skope_id ) {
|
||||
sek_error_log( __FUNCTION__ . ' => the skope_id should not be empty.');
|
||||
}
|
||||
$local_skope_settings = sek_get_skoped_seks( $skope_id );
|
||||
$local_collection = ( is_array( $local_skope_settings ) && !empty( $local_skope_settings['collection'] ) ) ? $local_skope_settings['collection'] : array();
|
||||
$global_skope_settings = sek_get_skoped_seks( NIMBLE_GLOBAL_SKOPE_ID );
|
||||
$global_collection = ( is_array( $global_skope_settings ) && !empty( $global_skope_settings['collection'] ) ) ? $global_skope_settings['collection'] : array();
|
||||
|
||||
$collection = array_merge( $local_collection, $global_collection );
|
||||
}
|
||||
|
||||
foreach ( $collection as $level_data ) {
|
||||
// stop here and return if a match was recursively found
|
||||
if ( 'no_match' !== $_parent_level_data )
|
||||
break;
|
||||
if ( array_key_exists( 'collection', $level_data ) && is_array( $level_data['collection'] ) ) {
|
||||
foreach ( $level_data['collection'] as $child_level_data ) {
|
||||
if ( array_key_exists( 'id', $child_level_data ) && $child_level_id == $child_level_data['id'] ) {
|
||||
$_parent_level_data = $level_data;
|
||||
//match found, break this loop
|
||||
break;
|
||||
} else {
|
||||
$_parent_level_data = sek_get_parent_level_model( $child_level_id, $level_data['collection'], $skope_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $_parent_level_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Return the skope id in which a level will be rendered
|
||||
// For that, walk the collections local and global to see if there's a match
|
||||
// Fallback skope is local.
|
||||
// used for example in the simple form module to print the hidden skope id, needed on submission.
|
||||
// Recursive helper
|
||||
// @param id : mandatory
|
||||
// @param collection : optional <= that's why if missing we must walk all collections : local and global
|
||||
function sek_get_level_skope_id( $level_id = '' ) {
|
||||
$level_skope_id = skp_get_skope_id();
|
||||
if ( !is_string( $level_id ) || empty( $level_id ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => missing or invalid child_level_id param.');
|
||||
return $level_skope_id;
|
||||
}
|
||||
|
||||
$local_skope_settings = sek_get_skoped_seks( $level_skope_id );
|
||||
$local_collection = ( is_array( $local_skope_settings ) && !empty( $local_skope_settings['collection'] ) ) ? $local_skope_settings['collection'] : array();
|
||||
// if the level id has not been found in the local sections, we know it's a global level.
|
||||
// In dev mode, always make sure that the level id is found in the global locations.
|
||||
if ( 'no_match' === sek_get_level_model( $level_id, $local_collection ) ) {
|
||||
$level_skope_id = NIMBLE_GLOBAL_SKOPE_ID;
|
||||
if ( sek_is_dev_mode() ) {
|
||||
$global_skope_settings = sek_get_skoped_seks( NIMBLE_GLOBAL_SKOPE_ID );
|
||||
$global_collection = ( is_array( $global_skope_settings ) && !empty( $global_skope_settings['collection'] ) ) ? $global_skope_settings['collection'] : array();
|
||||
if ( 'no_match' === sek_get_level_model( $level_id, $global_collection ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => warning, a level id ( ' . $level_id .' ) was not found in local and global sections.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $level_skope_id;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
// return bool
|
||||
// count the number of global section created, no matter if they are header footer or other global locations
|
||||
// can be used to determine if we need to render Nimble Builder assets on front. See ::sek_enqueue_front_assets()
|
||||
function sek_has_global_sections() {
|
||||
if ( skp_is_customizing() )
|
||||
return true;
|
||||
if ( 'not_set' !== Nimble_Manager()->page_has_global_sections )
|
||||
return Nimble_Manager()->page_has_global_sections;
|
||||
|
||||
$maybe_global_sek_post = sek_get_seks_post( NIMBLE_GLOBAL_SKOPE_ID, 'global' );
|
||||
$nb_section_created = 0;
|
||||
if ( is_object($maybe_global_sek_post) ) {
|
||||
$seks_data = maybe_unserialize($maybe_global_sek_post->post_content);
|
||||
$seks_data = is_array( $seks_data ) ? $seks_data : array();
|
||||
$nb_section_created = sek_count_not_empty_sections_in_page( $seks_data );
|
||||
}
|
||||
// cache now
|
||||
Nimble_Manager()->page_has_global_sections = $nb_section_created > 0;
|
||||
return Nimble_Manager()->page_has_global_sections;
|
||||
}
|
||||
|
||||
|
||||
// @return bool
|
||||
// added for https://github.com/presscustomizr/nimble-builder/issues/436
|
||||
// initially used to determine if a post or a page has been customized with Nimble Builder => if so, we add an edit link in the post/page list
|
||||
// when used in admin, the skope_id must be provided
|
||||
// can be used to determine if we need to render Nimble Builder assets on front. See ::sek_enqueue_front_assets()
|
||||
// March 2021 => fixed : function sek_local_skope_has_nimble_sections() => when customzing => seks_data param should be provided after being filtered with customized values
|
||||
function sek_local_skope_has_nimble_sections( $skope_id = '', $seks_data = null ) {
|
||||
$skope_id = empty( $skope_id ) ? skp_get_skope_id() : $skope_id;
|
||||
|
||||
if ( NIMBLE_GLOBAL_SKOPE_ID === $skope_id ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => function should not be used with global skope id' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 'not_set' !== Nimble_Manager()->page_has_local_sections )
|
||||
return Nimble_Manager()->page_has_local_sections;
|
||||
|
||||
$nb_section_created = 0;
|
||||
|
||||
// When the collection is provided use it otherwise get it
|
||||
if ( is_null($seks_data) || !is_array($seks_data) ) {
|
||||
$seks_data = sek_get_skoped_seks( $skope_id );
|
||||
}
|
||||
if ( is_array( $seks_data ) ) {
|
||||
$nb_section_created = sek_count_not_empty_sections_in_page( $seks_data );
|
||||
}
|
||||
// cache now
|
||||
Nimble_Manager()->page_has_local_sections = $nb_section_created > 0;
|
||||
return Nimble_Manager()->page_has_local_sections;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// @return boolean
|
||||
// Indicates if a section level contains at least on module
|
||||
// Used in SEK_Front_Render::render() to maybe print a css class on the section level
|
||||
function sek_section_has_modules( $model, $has_module = null ) {
|
||||
$has_module = is_null( $has_module ) ? false : (bool)$has_module;
|
||||
foreach ( $model as $level_data ) {
|
||||
// stop here and return if a match was recursively found
|
||||
if ( true === $has_module )
|
||||
break;
|
||||
if ( is_array( $level_data ) && array_key_exists( 'collection', $level_data ) && is_array( $level_data['collection'] ) ) {
|
||||
foreach ( $level_data['collection'] as $child_level_data ) {
|
||||
if ( 'module'== $child_level_data['level'] ) {
|
||||
$has_module = true;
|
||||
//match found, break this loop
|
||||
break;
|
||||
} else {
|
||||
$has_module = sek_section_has_modules( $child_level_data, $has_module );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $has_module;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* HAS USER STARTED CREATING SECTIONS ?
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @return a boolean
|
||||
// Used to check if we should render the welcome notice in sek_render_welcome_notice()
|
||||
function sek_site_has_nimble_sections_created() {
|
||||
$sek_post_query_vars = array(
|
||||
'post_type' => NIMBLE_CPT,
|
||||
'post_status' => get_post_stati(),
|
||||
//'name' => sanitize_title(),
|
||||
'posts_per_page' => -1,
|
||||
'no_found_rows' => true,
|
||||
'cache_results' => true,
|
||||
'update_post_meta_cache' => false,
|
||||
'update_post_term_cache' => false,
|
||||
'lazy_load_term_meta' => false,
|
||||
);
|
||||
$query = new \WP_Query( $sek_post_query_vars );
|
||||
//sek_error_log('DO WE HAVE SECTIONS ?', $query );
|
||||
return is_array( $query->posts ) && !empty( $query->posts );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// recursive helper to count the number of sections in a given set of sections data
|
||||
function sek_count_not_empty_sections_in_page( $seks_data, $count = 0 ) {
|
||||
if ( !is_array( $seks_data ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid seks_data param');
|
||||
return $count;
|
||||
}
|
||||
foreach ( $seks_data as $key => $data ) {
|
||||
if ( is_array( $data ) ) {
|
||||
if ( !empty( $data['level'] ) && 'section' === $data['level'] ) {
|
||||
if ( !empty( $data['collection'] ) ) {
|
||||
$count++;
|
||||
}
|
||||
} else {
|
||||
$count = sek_count_not_empty_sections_in_page( $data, $count );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
// /* ------------------------------------------------------------------------- *
|
||||
// * FEEDBACK NOTIF
|
||||
// /* ------------------------------------------------------------------------- */
|
||||
// Invoked when printing the review note in the plugin table, in the 'plugin_row_meta'
|
||||
// Since this is a quite heavy check, NB stores it in a 7 days long transient
|
||||
function sek_get_feedback_notif_status() {
|
||||
if ( sek_feedback_notice_is_dismissed() )
|
||||
return;
|
||||
|
||||
// Check if we already stored the status in a transient first
|
||||
$transient_name = NIMBLE_FEEDBACK_STATUS_TRANSIENT_ID;
|
||||
$transient_value = get_transient( $transient_name );
|
||||
if ( false != $transient_value ) {
|
||||
return $transient_value;
|
||||
}
|
||||
|
||||
// If transient not set or expired, let's set it and return the feedback status
|
||||
// $start_version = get_option( 'nimble_started_with_version', NIMBLE_VERSION );
|
||||
|
||||
// Bail if user started after v2.1.20, October 22nd 2020 ( set on November 23th 2020 )
|
||||
// if ( !version_compare( $start_version, '3.1.12', '<=' ) )
|
||||
// return;
|
||||
|
||||
$sek_post_query_vars = array(
|
||||
'post_type' => NIMBLE_CPT,
|
||||
'post_status' => get_post_stati(),
|
||||
//'name' => sanitize_title(),
|
||||
'posts_per_page' => -1,
|
||||
'no_found_rows' => true,
|
||||
'cache_results' => true,
|
||||
'update_post_meta_cache' => false,
|
||||
'update_post_term_cache' => false,
|
||||
'lazy_load_term_meta' => false,
|
||||
);
|
||||
$query = new \WP_Query( $sek_post_query_vars );
|
||||
if ( !is_array( $query->posts ) || empty( $query->posts ) )
|
||||
return;
|
||||
|
||||
$customized_pages = 0;
|
||||
$nb_section_created = 0;
|
||||
// the global var is easier to handle for array when populated recursively
|
||||
global $modules_used;
|
||||
$module_used = array();
|
||||
|
||||
foreach ( $query->posts as $post_object ) {
|
||||
$seks_data = maybe_unserialize($post_object->post_content);
|
||||
$seks_data = is_array( $seks_data ) ? $seks_data : array();
|
||||
$nb_section_created += sek_count_not_empty_sections_in_page( $seks_data );
|
||||
sek_populate_list_of_modules_used( $seks_data );
|
||||
$customized_pages++;
|
||||
}
|
||||
|
||||
if ( !is_array( $modules_used ) || !is_numeric( $nb_section_created ) || !is_numeric($customized_pages) )
|
||||
return;
|
||||
|
||||
$modules_used = array_unique($modules_used);
|
||||
|
||||
$transient_value = 'not_eligible';
|
||||
// sek_error_log('$section_created ??', $nb_section_created );
|
||||
// sek_error_log('$modules_used ?? ' . count($modules_used), $modules_used );
|
||||
// sek_error_log('$customized_pages ??', $customized_pages );
|
||||
//version_compare( $this->wp_version, '4.1', '>=' )
|
||||
if ( $customized_pages > 1 && $nb_section_created > 1 && count($modules_used) > 1 ) {
|
||||
$transient_value = 'eligible';
|
||||
}
|
||||
set_transient( $transient_name, $transient_value, 7 * DAY_IN_SECONDS );
|
||||
return $transient_value;
|
||||
}
|
||||
|
||||
|
||||
// recursive helper to generate a list of module used in a given set of sections data
|
||||
function sek_populate_list_of_modules_used( $seks_data ) {
|
||||
global $modules_used;
|
||||
if ( !is_array( $seks_data ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid seks_data param');
|
||||
return $count;
|
||||
}
|
||||
foreach ( $seks_data as $key => $data ) {
|
||||
if ( is_array( $data ) ) {
|
||||
if ( !empty( $data['level'] ) && 'module' === $data['level'] && !empty( $data['module_type'] ) ) {
|
||||
$modules_used[] = $data['module_type'];
|
||||
} else {
|
||||
//$modules_used = array_merge( $modules_used, sek_populate_list_of_modules_used( $data, $modules_used ) );
|
||||
sek_populate_list_of_modules_used( $data, $modules_used );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* reCAPTCHA HELPER
|
||||
/* ------------------------------------------------------------------------- */
|
||||
// @return boolean
|
||||
// reCaptcha is enabled globally
|
||||
// deactivated when customizing
|
||||
function sek_is_recaptcha_globally_enabled() {
|
||||
if ( did_action('nimble_front_classes_ready') && '_not_cached_yet_' !== Nimble_Manager()->recaptcha_enabled ) {
|
||||
return Nimble_Manager()->recaptcha_enabled;
|
||||
}
|
||||
$recaptcha_enabled = false;
|
||||
|
||||
$glob_recaptcha_opts = sek_get_global_option_value( 'recaptcha' );
|
||||
|
||||
if ( !is_null( $glob_recaptcha_opts ) && is_array( $glob_recaptcha_opts ) && !empty( $glob_recaptcha_opts['enable'] ) ) {
|
||||
$recaptcha_enabled = sek_booleanize_checkbox_val( $glob_recaptcha_opts['enable'] ) && !empty( $glob_recaptcha_opts['public_key'] ) && !empty($glob_recaptcha_opts['private_key'] );
|
||||
}
|
||||
|
||||
// CACHE when not doing ajax
|
||||
if ( !defined( 'DOING_AJAX') || true !== DOING_AJAX ) {
|
||||
Nimble_Manager()->recaptcha_enabled = $recaptcha_enabled;
|
||||
}
|
||||
|
||||
return $recaptcha_enabled;
|
||||
}
|
||||
|
||||
// @return boolean
|
||||
// reCaptcha is enabled globally
|
||||
// deactivated when customizing
|
||||
function sek_is_recaptcha_badge_globally_displayed() {
|
||||
if ( did_action('nimble_front_classes_ready') && '_not_cached_yet_' !== Nimble_Manager()->recaptcha_badge_displayed ) {
|
||||
return Nimble_Manager()->recaptcha_badge_displayed;
|
||||
}
|
||||
$display_badge = false;//disabled by default @see sek_get_module_params_for_sek_global_recaptcha()
|
||||
|
||||
$glob_recaptcha_opts = sek_get_global_option_value( 'recaptcha' );
|
||||
|
||||
if ( !is_null( $glob_recaptcha_opts ) && is_array( $glob_recaptcha_opts ) && !empty( $glob_recaptcha_opts['badge'] ) ) {
|
||||
$display_badge = sek_booleanize_checkbox_val( $glob_recaptcha_opts['badge'] ) && sek_is_recaptcha_globally_enabled();
|
||||
}
|
||||
|
||||
// CACHE when not doing ajax
|
||||
if ( !defined( 'DOING_AJAX') || true !== DOING_AJAX ) {
|
||||
Nimble_Manager()->recaptcha_badge_displayed = $display_badge;
|
||||
}
|
||||
|
||||
return $display_badge;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @return bool
|
||||
// used to print reCaptcha js for the form module
|
||||
function sek_front_sections_include_a_form( $bool = false, $recursive_data = null ) {
|
||||
if ( !$bool ) {
|
||||
if ( is_null( $recursive_data ) ) {
|
||||
$local_skope_settings = sek_get_skoped_seks( skp_get_skope_id() );
|
||||
$local_collection = ( is_array( $local_skope_settings ) && !empty( $local_skope_settings['collection'] ) ) ? $local_skope_settings['collection'] : array();
|
||||
$global_skope_settings = sek_get_skoped_seks( NIMBLE_GLOBAL_SKOPE_ID );
|
||||
$global_collection = ( is_array( $global_skope_settings ) && !empty( $global_skope_settings['collection'] ) ) ? $global_skope_settings['collection'] : array();
|
||||
|
||||
$recursive_data = array_merge( $local_collection, $global_collection );
|
||||
}
|
||||
|
||||
foreach ($recursive_data as $key => $value) {
|
||||
if ( is_array( $value ) && array_key_exists('module_type', $value) && 'czr_simple_form_module' === $value['module_type'] ) {
|
||||
$bool = true;
|
||||
break;
|
||||
} else if ( is_array( $value ) ) {
|
||||
$bool = sek_front_sections_include_a_form( $bool, $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $bool;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
// /* ------------------------------------------------------------------------- *
|
||||
// * NIMBLE API
|
||||
// /* ------------------------------------------------------------------------- */
|
||||
|
||||
// Nimble api returns a set of value structured as follow
|
||||
// return array(
|
||||
// 'timestamp' => time(),
|
||||
// 'library' => array(
|
||||
// 'sections' => array(
|
||||
// 'registration_params' => sek_get_sections_registration_params(),
|
||||
// 'json_collection' => sek_get_json_collection()
|
||||
// ),
|
||||
// 'templates' => array()
|
||||
// ),
|
||||
// 'latest_posts' => $post_data,
|
||||
// 'cta' => array( 'started_before' => $go_pro_if_started_before, 'html' => $go_pro_html )
|
||||
// // 'testtest' => $_GET,
|
||||
// // 'testreferer' => $_SERVER => to get the
|
||||
// );
|
||||
// @return array|false Info data, or false.
|
||||
// api data is refreshed on plugin update and theme switch
|
||||
// @$what param can be 'latest_posts_and_start_msg', 'templates', 'single_section'
|
||||
function sek_get_nimble_api_data( $params ) {
|
||||
$params = is_array($params) ? $params : [];
|
||||
$params = wp_parse_args( $params, [
|
||||
'what' => '',
|
||||
'tmpl_name' => '',
|
||||
'section_id' => '',
|
||||
'force_update' => false
|
||||
]);
|
||||
$what = $params['what'];
|
||||
$tmpl_name = $params['tmpl_name'];
|
||||
$section_id = $params['section_id'];
|
||||
$force_update = $params['force_update'];
|
||||
$wp_cache_key = 'nimble_api_data_'. $what . $tmpl_name . $section_id;
|
||||
|
||||
// We must have a "what"
|
||||
if ( is_null($what) || !is_string($what) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => $what param not set');
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a single template is requested, a valid template name must be provided
|
||||
if ( 'single_tmpl' === $what && ( empty($tmpl_name) || !is_string($tmpl_name) ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => invalid $tmpl_name param');
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a single section is requested, a valid section id must be provided
|
||||
if ( 'single_section' === $what && ( empty($section_id) || !is_string($section_id) ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => invalid $section_id param');
|
||||
return false;
|
||||
}
|
||||
|
||||
$cached_api_data = wp_cache_get( $wp_cache_key );
|
||||
|
||||
if ( $cached_api_data && is_array($cached_api_data) && !empty($cached_api_data) ) {
|
||||
return $cached_api_data;
|
||||
}
|
||||
|
||||
$transient_name = '';
|
||||
$transient_duration = 7 * DAY_IN_SECONDS;
|
||||
|
||||
switch ( $what ) {
|
||||
case 'latest_posts_and_start_msg':
|
||||
$transient_name = 'nimble_api_posts';
|
||||
$transient_duration = 7 * DAY_IN_SECONDS;
|
||||
break;
|
||||
case 'all_tmpl':
|
||||
$transient_name = 'nimble_api_all_tmpl';
|
||||
$transient_duration = 5 * DAY_IN_SECONDS;
|
||||
break;
|
||||
case 'single_tmpl':
|
||||
$transient_name = 'nimble_api_tmpl_' . $tmpl_name;
|
||||
$transient_duration = 2 * DAY_IN_SECONDS;
|
||||
break;
|
||||
case 'single_section':
|
||||
$transient_name = 'nimble_api_section_' . $section_id;
|
||||
break;
|
||||
default:
|
||||
sek_error_log( __FUNCTION__ . ' => error => invalid $what param => ' . $what );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( empty( $transient_name ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$theme_slug = sek_get_parent_theme_slug();
|
||||
$version_transient_value = get_transient( NIMBLE_API_CHECK_TRANSIENT_ID );
|
||||
$expected_version_transient_value = NIMBLE_VERSION . '_' . $theme_slug;
|
||||
$api_needs_update = $version_transient_value != $expected_version_transient_value;
|
||||
|
||||
$api_transient_data = maybe_unserialize( get_transient( $transient_name ) );
|
||||
|
||||
// set this constant in wp_config.php
|
||||
$force_update = ( defined( 'NIMBLE_FORCE_UPDATE_API_DATA') && NIMBLE_FORCE_UPDATE_API_DATA ) ? true : $force_update;
|
||||
if ( true === $force_update ) {
|
||||
sek_error_log( __FUNCTION__ . ' API is in force update mode. API data requested => ' . $transient_name );
|
||||
}
|
||||
|
||||
$api_data = $api_transient_data;
|
||||
$invalid_transient_data = false;
|
||||
|
||||
// When requesting a single_section with sek_api_get_single_section_data, the expected returned data are formed like
|
||||
// [
|
||||
// [timestamp] => 1621256718
|
||||
// [single_section] => []
|
||||
// ]
|
||||
// When requesting a single_tmpl with sek_get_single_tmpl_api_data, the expected returned data are formed like
|
||||
// [
|
||||
// [timestamp] => 1621256718
|
||||
// [single_tmpl] => []
|
||||
// ]
|
||||
// If a problem occured when getting a pro section or template, single_section or single_tmpl is a string, not an array
|
||||
// in this case, we need to re-connect to the api
|
||||
// see https://github.com/presscustomizr/nimble-builder-pro/issues/193
|
||||
if ( 'single_section' === $what && is_array( $api_data ) && array_key_exists('single_section', $api_data ) && !is_array($api_data['single_section'] ) ) {
|
||||
$invalid_transient_data = true;
|
||||
}
|
||||
if ( 'single_tmpl' === $what && is_array( $api_data ) && array_key_exists('single_tmpl', $api_data ) && !is_array($api_data['single_tmpl'] ) ) {
|
||||
$invalid_transient_data = true;
|
||||
}
|
||||
|
||||
// Connect to remote NB api when :
|
||||
// 1) api data transient is not set or has expired ( false === $api_transient_data )
|
||||
// 2) force_update param is true
|
||||
// 3) NB has been updated to a new version ( $api_needs_update case )
|
||||
// 4) Theme has been changed ( $api_needs_update case )
|
||||
// 5) API DATA is not an array ( for https://github.com/presscustomizr/nimble-builder-pro/issues/193 )
|
||||
// 6) Invalid transient data ( for https://github.com/presscustomizr/nimble-builder-pro/issues/193 )
|
||||
if ( $force_update || false === $api_data || !is_array($api_data) || $api_needs_update || $invalid_transient_data ) {
|
||||
$query_params = apply_filters( 'nimble_api_query_params', [
|
||||
'timeout' => ( $force_update ) ? 25 : 8,
|
||||
'body' => [
|
||||
'api_version' => NIMBLE_VERSION,
|
||||
'site_lang' => get_bloginfo( 'language' ),
|
||||
'what' => $what,// 'single_tmpl', 'all_tmpl', 'latest_posts_and_start_msg', 'single_section'
|
||||
'tmpl_name' => $tmpl_name,
|
||||
'section_id' => $section_id
|
||||
]
|
||||
] );
|
||||
|
||||
//sek_error_log('CALL TO REMOTE API NOW FOR DATA => ' . $transient_name . ' | ' . $force_update . ' | ' . $api_needs_update, $query_params );
|
||||
|
||||
$response = wp_remote_get( NIMBLE_DATA_API_URL_V2, $query_params );
|
||||
|
||||
if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
|
||||
// set the transient to '_api_error_', so that we don't hammer the api if not reachable. next call will be done after transient expiration
|
||||
$api_data = '_api_error_';
|
||||
sek_error_log( __FUNCTION__ . ' error with api response');
|
||||
}
|
||||
|
||||
$api_data = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( empty( $api_data ) || !is_array( $api_data ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' invalid api data after json decode', $api_data );
|
||||
// set the transient to '_api_error_', so that we don't hammer the api if not reachable. next call will be done after transient expiration
|
||||
$api_data = '_api_error_';
|
||||
}
|
||||
// When requesting a single_section with sek_api_get_single_section_data, the expected returned data are formed like
|
||||
// [
|
||||
// [timestamp] => 1621256718
|
||||
// [single_section] => []
|
||||
// ]
|
||||
// When requesting a single_tmpl with sek_get_single_tmpl_api_data, the expected returned data are formed like
|
||||
// [
|
||||
// [timestamp] => 1621256718
|
||||
// [single_tmpl] => []
|
||||
// ]
|
||||
// If a problem occured when getting a pro section or template, single_section or single_tmpl is a string, not an array
|
||||
// in this case, we don't want to sage the api data like this as transient because user will need the transient to expire before getting the correct data ( see https://github.com/presscustomizr/nimble-builder-pro/issues/193 )
|
||||
if ( 'single_section' === $what && array_key_exists('single_section', $api_data ) && !is_array($api_data['single_section'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' invalid single section api data', $api_data);
|
||||
$api_data = '_api_error_';
|
||||
}
|
||||
if ( 'single_tmpl' === $what && array_key_exists('single_tmpl', $api_data ) && !is_array($api_data['single_tmpl'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' invalid single tmpl api data', $api_data);
|
||||
$api_data = '_api_error_';
|
||||
}
|
||||
|
||||
// if the api could not be reached, let's retry in 2 minutes with a short transient duration
|
||||
set_transient( $transient_name, $api_data, '_api_error_' === $api_data ? 2 * MINUTE_IN_SECONDS : $transient_duration );
|
||||
// The api data will be refreshed on next plugin update, or next theme switch. Or if $transient_name has expired.
|
||||
// $expected_version_transient_value = NIMBLE_VERSION . '_' . $theme_slug;
|
||||
set_transient( NIMBLE_API_CHECK_TRANSIENT_ID, $expected_version_transient_value, 100 * DAY_IN_SECONDS );
|
||||
}//if ( $force_update || false === $api_data )
|
||||
|
||||
// if api_error a new api call will be done when the relevant transient will expire
|
||||
if ( '_api_error_' === $api_data ) {
|
||||
sek_error_log( __FUNCTION__ . ' API data value is _api_error_ for transient data : ' . $transient_name );
|
||||
}
|
||||
|
||||
$api_data = '_api_error_' === $api_data ? null : $api_data;
|
||||
wp_cache_set( $wp_cache_key, $api_data );
|
||||
|
||||
//sek_error_log('API DATA for ' . $transient_name, $api_data );
|
||||
|
||||
return $api_data;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/// TEMPLATE DATA
|
||||
function sek_get_all_tmpl_api_data( $force_update = false ) {
|
||||
// set this constant in wp_config.php
|
||||
$force_update = ( defined( 'NIMBLE_FORCE_UPDATE_API_DATA') && NIMBLE_FORCE_UPDATE_API_DATA ) ? true : $force_update;
|
||||
|
||||
// To avoid a possible refresh, hence a reconnection to the api when opening the customizer
|
||||
// Let's use the data saved as options
|
||||
// Those data are updated on plugin install, plugin update( upgrader_process_complete ), theme switch
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/441
|
||||
$api_data = sek_get_nimble_api_data([
|
||||
'what' => 'all_tmpl',
|
||||
'force_update' => $force_update
|
||||
]);
|
||||
|
||||
$api_data = is_array( $api_data ) ? $api_data : [];
|
||||
|
||||
//sek_error_log('TMPL DATA ?', $tmpl_data);
|
||||
if ( empty($api_data) || !array_key_exists('lib', $api_data) || !is_array($api_data['lib']) || empty($api_data['lib']['templates']) || !is_array($api_data['lib']['templates']) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => no json_collection' );
|
||||
return array();
|
||||
}
|
||||
|
||||
//return [];
|
||||
return maybe_unserialize( $api_data['lib']['templates'] );
|
||||
}
|
||||
|
||||
|
||||
function sek_get_single_tmpl_api_data( $tmpl_name, $is_pro_tmpl = false, $force_update = false ) {
|
||||
// set this constant in wp_config.php
|
||||
$force_update = ( defined( 'NIMBLE_FORCE_UPDATE_API_DATA') && NIMBLE_FORCE_UPDATE_API_DATA ) ? true : $force_update;
|
||||
|
||||
// To avoid a possible refresh, hence a reconnection to the api when opening the customizer
|
||||
// Let's use the data saved as options
|
||||
// Those data are updated on plugin install, plugin update( upgrader_process_complete ), theme switch
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/441
|
||||
$api_data = sek_get_nimble_api_data([
|
||||
'what' => 'single_tmpl',
|
||||
'tmpl_name' => $tmpl_name,
|
||||
'force_update' => $force_update
|
||||
]);
|
||||
|
||||
// The api should return an array
|
||||
if ( !is_array( $api_data ) || !array_key_exists( 'single_tmpl', $api_data ) ) {
|
||||
return __('Problem when fetching template');
|
||||
}
|
||||
|
||||
// If the api returned a pro license key problem, bail now and return the api string message
|
||||
if ( $is_pro_tmpl && is_string( $api_data['single_tmpl'] ) ) {
|
||||
return $api_data['single_tmpl'];
|
||||
}
|
||||
|
||||
$api_data = wp_parse_args( $api_data, [
|
||||
'timestamp' => '',
|
||||
'single_tmpl' => null
|
||||
]);
|
||||
//sek_error_log('TMPL DATA ?', $tmpl_data);
|
||||
if ( empty($api_data['single_tmpl']) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => empty template for ' . $tmpl_name );
|
||||
return array();
|
||||
}
|
||||
if ( !is_array( $api_data['single_tmpl'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => invalid template for ' . $tmpl_name );
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( !array_key_exists( 'data', $api_data['single_tmpl'] ) || !array_key_exists( 'metas',$api_data['single_tmpl'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => invalid template data for ' . $tmpl_name );
|
||||
return array();
|
||||
}
|
||||
//return [];
|
||||
return maybe_unserialize( $api_data['single_tmpl'] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/// SINGLE PRESET SECTION DATA
|
||||
function sek_api_get_single_section_data( $api_section_id, $force_update = false ) {
|
||||
// set this constant in wp_config.php
|
||||
$force_update = ( defined( 'NIMBLE_FORCE_UPDATE_API_DATA') && NIMBLE_FORCE_UPDATE_API_DATA ) ? true : $force_update;
|
||||
|
||||
// To avoid a possible refresh, hence a reconnection to the api when opening the customizer
|
||||
// Let's use the data saved as options
|
||||
// Those data are updated on plugin install, plugin update( upgrader_process_complete ), theme switch
|
||||
// @see https://github.com/presscustomizr/nimble-builder/issues/441
|
||||
$api_data = sek_get_nimble_api_data([
|
||||
'what' => 'single_section',
|
||||
'section_id' => $api_section_id,
|
||||
'force_update' => $force_update
|
||||
]);
|
||||
|
||||
$api_data = is_array( $api_data ) ? $api_data : [];
|
||||
$api_data = wp_parse_args( $api_data, [
|
||||
'timestamp' => '',
|
||||
'single_section' => null
|
||||
]);
|
||||
//sek_error_log('SECTION DATA ?', $api_data);
|
||||
if ( empty($api_data['single_section']) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => empty section data for ' . $api_section_id );
|
||||
return array();
|
||||
}
|
||||
|
||||
// if ( !array_key_exists( 'data', $api_data['single_tmpl'] ) || !array_key_exists( 'metas',$api_data['single_tmpl'] ) ) {
|
||||
// sek_error_log( __FUNCTION__ . ' => error => invalid section data for ' . $api_section_id );
|
||||
// return array();
|
||||
// }
|
||||
//return [];
|
||||
return maybe_unserialize( $api_data['single_section'] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
/// LATESTS POSTS
|
||||
// @return array of posts
|
||||
function sek_get_latest_posts_api_data( $force_update = false ) {
|
||||
// set this constant in wp_config.php
|
||||
$force_update = ( defined( 'NIMBLE_FORCE_UPDATE_API_DATA') && NIMBLE_FORCE_UPDATE_API_DATA ) ? true : $force_update;
|
||||
$api_data = sek_get_nimble_api_data([
|
||||
'what' => 'latest_posts_and_start_msg',
|
||||
'force_update' => $force_update
|
||||
]);
|
||||
$api_data = is_array( $api_data ) ? $api_data : [];
|
||||
$api_data = wp_parse_args( $api_data, [
|
||||
'timestamp' => '',
|
||||
'latest_posts' => null
|
||||
]);
|
||||
if ( !is_array( $api_data['latest_posts'] ) || empty( $api_data['latest_posts'] ) ) {
|
||||
sek_error_log( __FUNCTION__ . ' => error => no latest_posts' );
|
||||
return [];
|
||||
}
|
||||
return $api_data['latest_posts'];
|
||||
}
|
||||
|
||||
// @return html string
|
||||
function sek_start_msg_from_api( $theme_name, $force_update = false ) {
|
||||
if ( !sek_is_presscustomizr_theme( $theme_name ) ) {
|
||||
return '';
|
||||
}
|
||||
// set this constant in wp_config.php
|
||||
$force_update = ( defined( 'NIMBLE_FORCE_UPDATE_API_DATA') && NIMBLE_FORCE_UPDATE_API_DATA ) ? true : $force_update;
|
||||
|
||||
$api_data = sek_get_nimble_api_data( [
|
||||
'what' => 'latest_posts_and_start_msg',
|
||||
'force_update' => $force_update
|
||||
]);
|
||||
$api_data = is_array( $api_data ) ? $api_data : [];
|
||||
$api_data = wp_parse_args( $api_data, [
|
||||
'timestamp' => '',
|
||||
'start_msg' => null
|
||||
]);
|
||||
|
||||
$msg = '';
|
||||
$api_msg = isset( $api_data['start_msg'] ) ? $api_data['start_msg'] : null;
|
||||
|
||||
if ( !is_null($api_msg) && is_string($api_msg) ) {
|
||||
$msg = $api_msg;
|
||||
}
|
||||
return $msg;
|
||||
}
|
||||
|
||||
// Attempt to refresh the api template data => will store in a transient if not done yet, to make it faster to render in the customizer
|
||||
// add_action( 'wp_head', '\Nimble\sek_maybe_refresh_nimble_api_tmpl_data');
|
||||
// function sek_maybe_refresh_nimble_api_tmpl_data() {
|
||||
// if ( skp_is_customizing() || false !== get_transient( 'nimble_api_all_tmpl' ) )
|
||||
// return;
|
||||
// sek_get_nimble_api_data(['what' => 'all_tmpl']);
|
||||
// }
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
// This file has been introduced on May 21st 2019 => back to the local data
|
||||
// after problem was reported when fetching data remotely : https://github.com/presscustomizr/nimble-builder/issues/445
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// REGISTRATION PARAMS FOR PRESET SECTIONS
|
||||
// @return array()
|
||||
function sek_get_sections_registration_params( $force_update = false ) {
|
||||
|
||||
// JULY 2020 => not stored in a transient anymore. For https://github.com/presscustomizr/nimble-builder/issues/730
|
||||
// + clean previously created transients
|
||||
$bw_fixes_options = get_option( NIMBLE_OPT_NAME_FOR_BACKWARD_FIXES );
|
||||
$bw_fixes_options = is_array( $bw_fixes_options ) ? $bw_fixes_options : array();
|
||||
if ( !array_key_exists('clean_section_params_transient_0720', $bw_fixes_options ) || 'done' != $bw_fixes_options['clean_section_params_transient_0720'] ) {
|
||||
sek_clean_transients_like( 'section_params_transient' );
|
||||
$bw_fixes_options['clean_section_params_transient_0720'] = 'done';
|
||||
// flag as done
|
||||
update_option( NIMBLE_OPT_NAME_FOR_BACKWARD_FIXES, $bw_fixes_options );
|
||||
}
|
||||
|
||||
// $section_params_transient_name = 'section_params_transient_' . NIMBLE_VERSION;
|
||||
// $registration_params = get_transient( $section_params_transient_name );
|
||||
// // Refresh every 30 days, unless force_update set to true
|
||||
// if ( $force_update || false === $registration_params ) {
|
||||
// $registration_params = sek_get_raw_section_registration_params();
|
||||
// set_transient( $section_params_transient_name, $registration_params, 30 * DAY_IN_SECONDS );
|
||||
// }
|
||||
|
||||
$registration_params = sek_get_raw_section_registration_params();
|
||||
return $registration_params;
|
||||
}
|
||||
|
||||
function sek_get_raw_section_registration_params() {
|
||||
return apply_filters( 'sek_get_raw_section_registration_params', [
|
||||
'sek_intro_sec_picker_module' => [
|
||||
'name' => __('Sections for an introduction', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'intro_three',
|
||||
'title' => __('1 columns, call to action, full-width background', 'text-domain' ),
|
||||
'thumb' => 'intro_three.jpg',
|
||||
'demo_url' => '#intro-one'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'intro_one',
|
||||
'title' => __('1 column, full-width background', 'text-domain' ),
|
||||
'thumb' => 'intro_one.jpg',
|
||||
'demo_url' => '#intro-two'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'intro_two',
|
||||
'title' => __('2 columns, call to action, full-width background', 'text-domain' ),
|
||||
'thumb' => 'intro_two.jpg',
|
||||
'demo_url' => '#intro-three'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'pro_intro_two',
|
||||
'title' => __('3 columns, call to actions', 'text-domain' ),
|
||||
'thumb' => 'pro_intro_two.jpg',
|
||||
'active' => sek_is_pro(),
|
||||
'is_pro' => true,
|
||||
'demo_url' => 'https://nimblebuilder.com/special-image-demo?utm_source=usersite&utm_medium=link&utm_campaign=section_demos'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'pro_intro_one',
|
||||
'title' => __('2 columns, call to actions, image carousel', 'text-domain' ),
|
||||
'thumb' => 'pro_intro_one.jpg',
|
||||
'active' => sek_is_pro(),
|
||||
'is_pro' => true,
|
||||
'demo_url' => '#intro-four'
|
||||
)
|
||||
)
|
||||
],
|
||||
'sek_post_grids_sec_picker_module' => [
|
||||
'name' => __('Post lists sections', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'grid_one',
|
||||
'title' => __('Simple post grid', 'text-domain' ),
|
||||
'thumb' => 'grid_one.jpg',
|
||||
'demo_url' => 'https://nimblebuilder.com/post-grid-sections?utm_source=usersite&utm_medium=link&utm_campaign=section_demos#grid-one'
|
||||
//'height' => '188px'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'grid_two',
|
||||
'title' => __('Posts on two columns', 'text-domain' ),
|
||||
'thumb' => 'grid_two.jpg',
|
||||
'demo_url' => 'https://nimblebuilder.com/post-grid-sections?utm_source=usersite&utm_medium=link&utm_campaign=section_demos#grid-two'
|
||||
//'height' => '188px'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'pro_grid_one',
|
||||
'title' => __('Masonry post grid', 'text-domain' ),
|
||||
'thumb' => 'pro_grid_one.jpg',
|
||||
'demo_url' => 'https://nimblebuilder.com/post-grid-sections?utm_source=usersite&utm_medium=link&utm_campaign=section_demos#pro-grid-one',
|
||||
'active' => sek_is_pro(),
|
||||
'is_pro' => true
|
||||
//'height' => '188px'
|
||||
)
|
||||
)
|
||||
],
|
||||
'sek_features_sec_picker_module' => [
|
||||
'name' => __('Sections for services and features', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'features_one',
|
||||
'title' => __('3 columns with icon and call to action', 'text-domain' ),
|
||||
'thumb' => 'features_one.jpg',
|
||||
'demo_url' => '#service-one'
|
||||
//'height' => '188px'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'features_two',
|
||||
'title' => __('3 columns with icon', 'text-domain' ),
|
||||
'thumb' => 'features_two.jpg',
|
||||
'demo_url' => '#service-two'
|
||||
//'height' => '188px'
|
||||
)
|
||||
)
|
||||
],
|
||||
'sek_about_sec_picker_module' => [
|
||||
'name' => __('About us sections', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'about_one',
|
||||
'title' => __('A simple about us section with 2 columns', 'text-domain' ),
|
||||
'thumb' => 'about_one.jpg',
|
||||
'demo_url' => '#about-one'
|
||||
//'height' => '188px'
|
||||
)
|
||||
)
|
||||
],
|
||||
'sek_contact_sec_picker_module' => [
|
||||
'name' => __('Contact-us sections', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'contact_one',
|
||||
'title' => __('A contact form and a Google map', 'text-domain' ),
|
||||
'thumb' => 'contact_one.jpg',
|
||||
'demo_url' => '#contact-one'
|
||||
//'height' => '188px'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'contact_two',
|
||||
'title' => __('A contact form with an image background', 'text-domain' ),
|
||||
'thumb' => 'contact_two.jpg',
|
||||
'demo_url' => '#contact-two'
|
||||
//'height' => '188px'
|
||||
)
|
||||
)
|
||||
],
|
||||
'sek_team_sec_picker_module' => [
|
||||
'name' => __('Sections for teams', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'team_one',
|
||||
'title' => __('4 column', 'text-domain' ),
|
||||
'thumb' => 'team_one.jpg',
|
||||
'demo_url' => '#team-one'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'team_two',
|
||||
'title' => __('3 columns', 'text-domain' ),
|
||||
'thumb' => 'team_two.jpg',
|
||||
'height' => '180px',
|
||||
'demo_url' => '#team-two'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'pro_team_one',
|
||||
'title' => __('3 columns, call to action', 'text-domain' ),
|
||||
'thumb' => 'pro_team_one.jpg',
|
||||
'active' => sek_is_pro(),
|
||||
'height' => '180px',
|
||||
'is_pro' => true,
|
||||
'demo_url' => '#team-three'
|
||||
)
|
||||
)
|
||||
],
|
||||
'sek_column_layouts_sec_picker_module' => [
|
||||
'name' => __('Empty sections with columns layout', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'two_columns',
|
||||
'title' => __('two columns layout', 'text-domain' ),
|
||||
'thumb' => 'two_columns.jpg'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'three_columns',
|
||||
'title' => __('three columns layout', 'text-domain' ),
|
||||
'thumb' => 'three_columns.jpg'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'four_columns',
|
||||
'title' => __('four columns layout', 'text-domain' ),
|
||||
'thumb' => 'four_columns.jpg'
|
||||
),
|
||||
)
|
||||
],
|
||||
// pre-built sections for header and footer
|
||||
'sek_header_sec_picker_module' => [
|
||||
'name' => __('Header sections', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'header_one',
|
||||
'title' => __('simple header with a logo on the left and a menu on the right', 'text-domain' ),
|
||||
'thumb' => 'header_one.jpg',
|
||||
'height' => '33px',
|
||||
'section_type' => 'header'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'header_two',
|
||||
'title' => __('simple header with a logo on the right and a menu on the left', 'text-domain' ),
|
||||
'thumb' => 'header_two.jpg',
|
||||
'height' => '33px',
|
||||
'section_type' => 'header'
|
||||
)
|
||||
)
|
||||
],
|
||||
'sek_footer_sec_picker_module' => [
|
||||
'name' => __('Footer sections', 'text_doma'),
|
||||
'section_collection' => array(
|
||||
array(
|
||||
'content-id' => 'footer_pro_one',
|
||||
'title' => __('simple 2 columns footer', 'text-domain' ),
|
||||
'thumb' => 'footer_pro_one.jpg',
|
||||
'section_type' => 'footer',
|
||||
'height' => '75px',
|
||||
'active' => sek_is_pro(),
|
||||
'is_pro' => true
|
||||
),
|
||||
array(
|
||||
'content-id' => 'footer_with_social_links_one',
|
||||
'title' => __('footer with dynamic date, site title and social links', 'text-domain' ),
|
||||
'thumb' => 'footer_with_social_links_one.jpg',
|
||||
'section_type' => 'footer',
|
||||
'height' => '51px'
|
||||
),
|
||||
array(
|
||||
'content-id' => 'footer_one',
|
||||
'title' => __('simple 3 columns footer', 'text-domain' ),
|
||||
'thumb' => 'footer_one.jpg',
|
||||
'section_type' => 'footer',
|
||||
'height' => '75px'
|
||||
)
|
||||
)
|
||||
]
|
||||
]);
|
||||
}
|
||||
?>
|
||||